blob: e14ff835706eb387d1515445e9ca2eb02d535e25 [file] [log] [blame]
huang lin365250e2014-08-06 16:43:43 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Rockchip Electronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <libpayload.h>
21#include <arch/cache.h>
22
23#include "dwc2.h"
24#include "dwc2_private.h"
25
26static void dummy(hci_t *controller)
27{
28}
29
30static void dwc2_reinit(hci_t *controller)
31{
32 dwc2_reg_t *reg = DWC2_REG(controller);
33 gusbcfg_t gusbcfg = { .d32 = 0 };
34 grstctl_t grstctl = { .d32 = 0 };
35 gintsts_t gintsts = { .d32 = 0 };
36 gahbcfg_t gahbcfg = { .d32 = 0 };
37 grxfsiz_t grxfsiz = { .d32 = 0 };
huang lin8b52c932014-12-04 18:25:47 +080038 ghwcfg3_t hwcfg3 = { .d32 = 0 };
huang lin365250e2014-08-06 16:43:43 +080039 hcintmsk_t hcintmsk = { .d32 = 0 };
40 gnptxfsiz_t gnptxfsiz = { .d32 = 0 };
41
42 const int timeout = 10000;
huang lin8b52c932014-12-04 18:25:47 +080043 int i, fifo_blocks, tx_blocks;
huang lin365250e2014-08-06 16:43:43 +080044
45 /* Wait for AHB idle */
46 for (i = 0; i < timeout; i++) {
47 udelay(1);
48 grstctl.d32 = readl(&reg->core.grstctl);
49 if (grstctl.ahbidle)
50 break;
51 }
52 if (i == timeout)
53 fatal("DWC2 Init error AHB Idle\n");
54
55 /* Restart the Phy Clock */
56 writel(0x0, &reg->pcgr.pcgcctl);
57 /* Core soft reset */
58 grstctl.csftrst = 1;
59 writel(grstctl.d32, &reg->core.grstctl);
60 for (i = 0; i < timeout; i++) {
61 udelay(1);
62 grstctl.d32 = readl(&reg->core.grstctl);
63 if (!grstctl.csftrst)
64 break;
65 }
66 if (i == timeout)
67 fatal("DWC2 Init error reset fail\n");
68
69 /* Set 16bit PHY if & Force host mode */
70 gusbcfg.d32 = readl(&reg->core.gusbcfg);
71 gusbcfg.phyif = 1;
72 gusbcfg.forcehstmode = 1;
73 gusbcfg.forcedevmode = 0;
74 writel(gusbcfg.d32, &reg->core.gusbcfg);
75 /* Wait for force host mode effect, it may takes 100ms */
76 for (i = 0; i < timeout; i++) {
77 udelay(10);
78 gintsts.d32 = readl(&reg->core.gintsts);
79 if (gintsts.curmod)
80 break;
81 }
82 if (i == timeout)
83 fatal("DWC2 Init error force host mode fail\n");
84
85 /*
86 * Config FIFO
87 * The non-periodic tx fifo and rx fifo share one continuous
88 * piece of IP-internal SRAM.
89 */
huang lin8b52c932014-12-04 18:25:47 +080090
91 /*
92 * Read total data FIFO depth from HWCFG3
93 * this value is in terms of 32-bit words
94 */
95 hwcfg3.d32 = readl(&reg->core.ghwcfg3);
96 /*
97 * Reserve 2 spaces for the status entries of received packets
98 * and 2 spaces for bulk and control OUT endpoints. Calculate how
99 * many blocks can be alloted, assume largest packet size is 512.
100 */
101 fifo_blocks = (hwcfg3.dfifodepth - 4) / (512 / 4);
102 tx_blocks = fifo_blocks / 2;
103
104 grxfsiz.rxfdep = (fifo_blocks - tx_blocks) * (512 / 4) + 4;
huang lin365250e2014-08-06 16:43:43 +0800105 writel(grxfsiz.d32, &reg->core.grxfsiz);
huang lin8b52c932014-12-04 18:25:47 +0800106 gnptxfsiz.nptxfstaddr = grxfsiz.rxfdep;
107 gnptxfsiz.nptxfdep = tx_blocks * (512 / 4);
huang lin365250e2014-08-06 16:43:43 +0800108 writel(gnptxfsiz.d32, &reg->core.gnptxfsiz);
109
110 /* Init host channels */
111 hcintmsk.xfercomp = 1;
112 hcintmsk.xacterr = 1;
113 hcintmsk.stall = 1;
114 hcintmsk.chhltd = 1;
115 hcintmsk.bblerr = 1;
116 for (i = 0; i < MAX_EPS_CHANNELS; i++)
117 writel(hcintmsk.d32, &reg->host.hchn[i].hcintmaskn);
118
119 /* Unmask interrupt and configure DMA mode */
120 gahbcfg.glblintrmsk = 1;
121 gahbcfg.hbstlen = DMA_BURST_INCR8;
122 gahbcfg.dmaen = 1;
123 writel(gahbcfg.d32, &reg->core.gahbcfg);
124
125 DWC2_INST(controller)->hprt0 = &reg->host.hprt;
126
127 usb_debug("DWC2 init finished!\n");
128}
129
130static void dwc2_shutdown(hci_t *controller)
131{
132 detach_controller(controller);
133 free(DWC2_INST(controller)->dma_buffer);
134 free(DWC2_INST(controller));
135 free(controller);
136}
137
138/*
139 * This function returns the actual transfer length when the transfer succeeded
140 * or an error code if the transfer failed
141 */
142static int
143wait_for_complete(endpoint_t *ep, uint32_t ch_num)
144{
145 hcint_t hcint;
146 hcchar_t hcchar;
147 hctsiz_t hctsiz;
148 dwc2_reg_t *reg = DWC2_REG(ep->dev->controller);
149 int timeout = 600000; /* time out after 600000 * 5us == 3s */
150
151 /*
152 * TODO: We should take care of up to three times of transfer error
153 * retry here, according to the USB 2.0 spec 4.5.2
154 */
155 do {
156 udelay(5);
157 hcint.d32 = readl(&reg->host.hchn[ch_num].hcintn);
158 hctsiz.d32 = readl(&reg->host.hchn[ch_num].hctsizn);
159
160 if (hcint.chhltd) {
161 writel(hcint.d32, &reg->host.hchn[ch_num].hcintn);
162
163 if (hcint.xfercomp)
164 return hctsiz.xfersize;
165 else if (hcint.xacterr)
166 return -HCSTAT_XFERERR;
167 else if (hcint.bblerr)
168 return -HCSTAT_BABBLE;
169 else if (hcint.stall)
170 return -HCSTAT_STALL;
171 else
172 return -HCSTAT_UNKNOW;
173 }
174 } while (timeout--);
175
176 /* Release the channel on timeout */
177 hcchar.d32 = readl(&reg->host.hchn[ch_num].hccharn);
178 if (hcchar.chen) {
179 /*
180 * Programming the HCCHARn register with the chdis and
181 * chena bits set to 1 at the same time to disable the
182 * channel and the core will generate a channel halted
183 * interrupt.
184 */
185 hcchar.chdis = 1;
186 writel(hcchar.d32, &reg->host.hchn[ch_num].hccharn);
187 do {
188 hcchar.d32 = readl(&reg->host.hchn[ch_num].hccharn);
189 } while (hcchar.chen);
190
191 }
192
193 /* Clear all pending interrupt flags */
194 hcint.d32 = ~0;
195 writel(hcint.d32, &reg->host.hchn[ch_num].hcintn);
196
197 return -HCSTAT_TIMEOUT;
198}
199
200static int
201dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir,
202 uint32_t ch_num, u8 *data_buf)
203{
204 uint32_t do_copy;
205 int ret;
206 uint32_t packet_cnt;
207 uint32_t packet_size;
208 uint32_t transferred = 0;
209 uint32_t inpkt_length;
210 hctsiz_t hctsiz = { .d32 = 0 };
211 hcchar_t hcchar = { .d32 = 0 };
212 void *aligned_buf;
213 dwc2_reg_t *reg = DWC2_REG(ep->dev->controller);
214
215 packet_size = ep->maxpacketsize;
216 packet_cnt = ALIGN_UP(size, packet_size) / packet_size;
217 inpkt_length = packet_cnt * packet_size;
218 /* At least 1 packet should be programed */
219 packet_cnt = (packet_cnt == 0) ? 1 : packet_cnt;
220
221 /*
222 * For an IN, this field is the buffer size that the application has
223 * reserved for the transfer. The application should program this field
224 * as integer multiple of the maximum packet size for IN transactions.
225 */
226 hctsiz.xfersize = (dir == EPDIR_OUT) ? size : inpkt_length;
227 hctsiz.pktcnt = packet_cnt;
228 hctsiz.pid = pid;
229
230 hcchar.mps = packet_size;
231 hcchar.epnum = ep->endpoint & 0xf;
232 hcchar.epdir = dir;
233 hcchar.eptype = ep->type;
234 hcchar.multicnt = 1;
235 hcchar.devaddr = ep->dev->address;
236 hcchar.chdis = 0;
237 hcchar.chen = 1;
238
239 if (size > DMA_SIZE) {
240 usb_debug("Transfer too large: %d\n", size);
241 return -1;
242 }
243
244 /*
245 * Check the buffer address which should be 4-byte aligned and DMA
246 * coherent
247 */
248 do_copy = !dma_coherent(data_buf) || ((uintptr_t)data_buf & 0x3);
249 aligned_buf = do_copy ? DWC2_INST(ep->dev->controller)->dma_buffer :
250 data_buf;
251
252 if (do_copy && (dir == EPDIR_OUT))
253 memcpy(aligned_buf, data_buf, size);
254
255 writel(hctsiz.d32, &reg->host.hchn[ch_num].hctsizn);
Ionela Voinescufa143852015-02-02 15:35:44 +0000256 writel((uint32_t)virt_to_bus(aligned_buf),
257 &reg->host.hchn[ch_num].hcdman);
huang lin365250e2014-08-06 16:43:43 +0800258 writel(hcchar.d32, &reg->host.hchn[ch_num].hccharn);
259
260 ret = wait_for_complete(ep, ch_num);
261
262 if (ret >= 0) {
263 /* Calculate actual transferred length */
264 transferred = (dir == EPDIR_IN) ? inpkt_length - ret : ret;
265
266 if (do_copy && (dir == EPDIR_IN))
267 memcpy(data_buf, aligned_buf, transferred);
268 }
269
270 /* Save data toggle */
271 hctsiz.d32 = readl(&reg->host.hchn[ch_num].hctsizn);
272 ep->toggle = hctsiz.pid;
273
274 if (ret < 0) {
275 usb_debug("%s Transfer stop code: %x\n", __func__, ret);
276 return ret;
277 }
278 return transferred;
279}
280
281static int
282dwc2_bulk(endpoint_t *ep, int size, u8 *src, int finalize)
283{
284 ep_dir_t data_dir;
285
286 if (ep->direction == IN)
287 data_dir = EPDIR_IN;
288 else if (ep->direction == OUT)
289 data_dir = EPDIR_OUT;
290 else
291 return -1;
292
293 return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src);
294}
295
296static int
297dwc2_control(usbdev_t *dev, direction_t dir, int drlen, void *setup,
298 int dalen, u8 *src)
299{
300 int ret = 0;
301
302 ep_dir_t data_dir;
303
304 if (dir == IN)
305 data_dir = EPDIR_IN;
306 else if (dir == OUT)
307 data_dir = EPDIR_OUT;
308 else
309 return -1;
310
311 /* Setup Phase */
312 if (dwc2_transfer(&dev->endpoints[0], drlen, PID_SETUP, EPDIR_OUT, 0,
313 setup) < 0)
314 return -1;
315 /* Data Phase */
316 if (dalen > 0) {
317 ret = dwc2_transfer(&dev->endpoints[0], dalen, PID_DATA1,
318 data_dir, 0, src);
319 if (ret < 0)
320 return -1;
321 }
322 /* Status Phase */
323 if (dwc2_transfer(&dev->endpoints[0], 0, PID_DATA1, !data_dir, 0,
324 NULL) < 0)
325 return -1;
326
327 return ret;
328}
329
330hci_t *dwc2_init(void *bar)
331{
332 hci_t *controller = new_controller();
333 controller->instance = xzalloc(sizeof(dwc_ctrl_t));
334
335 DWC2_INST(controller)->dma_buffer = dma_malloc(DMA_SIZE);
336 if (!DWC2_INST(controller)->dma_buffer) {
337 usb_debug("Not enough DMA memory for DWC2 bounce buffer\n");
338 goto free_dwc2;
339 }
340
341 controller->type = DWC2;
342 controller->start = dummy;
343 controller->stop = dummy;
344 controller->reset = dummy;
345 controller->init = dwc2_reinit;
346 controller->shutdown = dwc2_shutdown;
347 controller->bulk = dwc2_bulk;
348 controller->control = dwc2_control;
349 controller->set_address = generic_set_address;
350 controller->finish_device_config = NULL;
351 controller->destroy_device = NULL;
352 controller->create_intr_queue = NULL;
353 controller->destroy_intr_queue = NULL;
354 controller->poll_intr_queue = NULL;
355 controller->reg_base = (uintptr_t)bar;
356 init_device_entry(controller, 0);
357
358 /* Init controller */
359 controller->init(controller);
360
361 /* Setup up root hub */
362 controller->devices[0]->controller = controller;
363 controller->devices[0]->init = dwc2_rh_init;
364 controller->devices[0]->init(controller->devices[0]);
365 return controller;
366
367free_dwc2:
368 detach_controller(controller);
369 free(DWC2_INST(controller));
370 free(controller);
371 return NULL;
372}