hm60x/hm801: Buttons rework.
[maemo-rb.git] / firmware / target / arm / usb-s3c6400x.c
blob7bcfcedc892de042c79d7ef473896c03a53f4f31
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2009 by Michael Sparmann
11 * Copyright © 2010 Amaury Pouly
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
23 #include "config.h"
24 #include "usb.h"
25 #include "usb_drv.h"
27 #include "cpu.h"
28 #include "system.h"
29 #include "kernel.h"
30 #include "panic.h"
32 #include "usb-s3c6400x.h"
34 #include "usb_ch9.h"
35 #include "usb_core.h"
36 #include <inttypes.h>
37 #include "power.h"
39 //#define LOGF_ENABLE
40 #include "logf.h"
42 /* store per endpoint, per direction, information */
43 struct ep_type
45 unsigned int size; /* length of the data buffer */
46 struct semaphore complete; /* wait object */
47 int8_t status; /* completion status (0 for success) */
48 bool active; /* true is endpoint has been requested (true for EP0) */
49 bool done; /* transfer completed */
50 bool busy; /* true is a transfer is pending */
53 bool usb_drv_stalled(int endpoint, bool in)
55 return DEPCTL(endpoint, !in) & DEPCTL_stall;
58 void usb_drv_stall(int endpoint, bool stall, bool in)
60 if (stall)
61 DEPCTL(endpoint, !in) |= DEPCTL_stall;
62 else
63 DEPCTL(endpoint, !in) &= ~DEPCTL_stall;
66 void usb_drv_set_address(int address)
68 (void)address;
69 /* Ignored intentionally, because the controller requires us to set the
70 new address before sending the response for some reason. So we'll
71 already set it when the control request arrives, before passing that
72 into the USB core, which will then call this dummy function. */
75 static void ep_transfer(int ep, void *ptr, int length, bool out);
76 int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
78 ep_transfer(EP_NUM(endpoint), ptr, length, false);
79 return 0;
82 int usb_drv_recv(int endpoint, void* ptr, int length)
84 ep_transfer(EP_NUM(endpoint), ptr, length, true);
85 return 0;
88 int usb_drv_port_speed(void)
90 static const uint8_t speed[4] = {
91 [DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = 1,
92 [DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = 0,
93 [DSTS_ENUMSPD_FS_PHY_48MHZ] = 0,
94 [DSTS_ENUMSPD_LS_PHY_6MHZ] = 0,
97 unsigned enumspd = extract(DSTS, enumspd);
99 if(enumspd == DSTS_ENUMSPD_LS_PHY_6MHZ)
100 panicf("usb-drv: LS is not supported");
102 return speed[enumspd & 3];
105 void usb_drv_set_test_mode(int mode)
107 /* there is a perfect matching between usb test mode code
108 * and the register field value */
109 DCTL = (DCTL & ~bitm(DCTL, tstctl)) | (mode << DCTL_tstctl_bitp);
112 #if CONFIG_CPU == AS3525v2 /* FIXME FIXME FIXME */
113 static const uint8_t in_ep_list[] = {0, 1, 3, 5};
114 static const uint8_t out_ep_list[] = {0, 2, 4};
116 /* state of EP0 (to correctly schedule setup packet enqueing) */
117 enum ep0state
119 /* Setup packet is enqueud, waiting for actual data */
120 EP0_WAIT_SETUP = 0,
121 /* Waiting for ack (either IN or OUT) */
122 EP0_WAIT_ACK = 1,
123 /* Ack complete, waiting for data (either IN or OUT)
124 * This state is necessary because if both ack and data complete in the
125 * same interrupt, we might process data completion before ack completion
126 * so we need this bizarre state */
127 EP0_WAIT_DATA = 2,
128 /* Setup packet complete, waiting for ack and data */
129 EP0_WAIT_DATA_ACK = 3,
132 /* endpoints[ep_num][DIR_IN/DIR_OUT] */
133 static struct ep_type endpoints[USB_NUM_ENDPOINTS][2];
134 /* setup packet for EP0 */
136 /* USB control requests may be up to 64 bytes in size.
137 Even though we never use anything more than the 8 header bytes,
138 we are required to accept request packets of up to 64 bytes size.
139 Provide buffer space for these additional payload bytes so that
140 e.g. write descriptor requests (which are rejected by us, but the
141 payload is transferred anyway) do not cause memory corruption.
142 Fixes FS#12310. -- Michael Sparmann (theseven) */
143 static union {
144 struct usb_ctrlrequest header; /* 8 bytes */
145 unsigned char payload[64];
146 } _ep0_setup_pkt USB_DEVBSS_ATTR;
148 static struct usb_ctrlrequest *ep0_setup_pkt = AS3525_UNCACHED_ADDR(&_ep0_setup_pkt.header);
150 /* state of EP0 */
151 static enum ep0state ep0_state;
153 void usb_attach(void)
155 /* Nothing to do */
158 static void prepare_setup_ep0(void)
160 DEPDMA(0, true) = (void*)AS3525_PHYSICAL_ADDR(&_ep0_setup_pkt);
161 DEPTSIZ(0, true) = (1 << DEPTSIZ0_supcnt_bitp)
162 | (1 << DEPTSIZ0_pkcnt_bitp)
163 | 8;
164 DEPCTL(0, true) |= DEPCTL_epena | DEPCTL_cnak;
166 ep0_state = EP0_WAIT_SETUP;
169 static size_t num_eps(bool out)
171 return out ? sizeof(out_ep_list) : sizeof(in_ep_list);
174 static void reset_endpoints(void)
176 for (int dir = 0; dir < 2; dir++)
178 bool out = dir == DIR_OUT;
179 for (unsigned i = 0; i < num_eps(dir == DIR_OUT); i++)
181 int ep = ((dir == DIR_IN) ? in_ep_list : out_ep_list)[i];
182 struct ep_type *endpoint = &endpoints[ep][out];
183 endpoint->active = false;
184 endpoint->busy = false;
185 endpoint->status = -1;
186 endpoint->done = false;
187 semaphore_release(&endpoint->complete);
189 if (i != 0)
190 DEPCTL(ep, out) = DEPCTL_setd0pid;
192 DEPCTL(0, out) = /*(DEPCTL_MPS_64 << DEPCTL_mps_bitp) | */ DEPCTL_usbactep;
195 /* Setup next chain for IN eps */
196 for (unsigned i = 0; i < num_eps(false); i++)
198 int ep = in_ep_list[i];
199 int next_ep = in_ep_list[(i + 1) % num_eps(false)];
200 DEPCTL(ep, false) |= next_ep << DEPCTL_nextep_bitp;
203 prepare_setup_ep0();
206 static void cancel_all_transfers(bool cancel_ep0)
208 int flags = disable_irq_save();
210 for (int dir = 0; dir < 2; dir++)
211 for (unsigned i = !!cancel_ep0; i < num_eps(dir == DIR_OUT); i++)
213 int ep = ((dir == DIR_IN) ? in_ep_list : out_ep_list)[i];
214 struct ep_type *endpoint = &endpoints[ep][dir == DIR_OUT];
215 endpoint->status = -1;
216 endpoint->busy = false;
217 endpoint->done = false;
218 semaphore_release(&endpoint->complete);
219 DEPCTL(ep, dir) = (DEPCTL(ep, dir) & ~DEPCTL_usbactep);
222 restore_irq(flags);
225 void usb_drv_init(void)
227 for (int i = 0; i < USB_NUM_ENDPOINTS; i++)
228 for (int dir = 0; dir < 2; dir++)
229 semaphore_init(&endpoints[i][dir].complete, 1, 0);
231 bitset32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
232 CCU_USB = (CCU_USB & ~(3<<24)) | (1 << 24); /* ?? */
233 /* PHY clock */
234 CGU_USB = 1<<5 /* enable */
235 | 0 << 2
236 | 0; /* source = ? (24MHz crystal?) */
238 PCGCCTL = 0;
239 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
241 GRSTCTL = GRSTCTL_csftrst;
242 while (GRSTCTL & GRSTCTL_csftrst); /* Wait for OTG to ack reset */
243 while (!(GRSTCTL & GRSTCTL_ahbidle)); /* Wait for OTG AHB master idle */
245 GRXFSIZ = 512;
246 GNPTXFSIZ = MAKE_FIFOSIZE_DATA(512);
248 /* FIXME: the current code is for internal DMA only, the clip+ architecture
249 * defines the internal DMA model */
250 GAHBCFG = (GAHBCFG_INT_DMA_BURST_INCR << GAHBCFG_hburstlen_bitp)
251 | GAHBCFG_dma_enable | GAHBCFG_glblintrmsk;
253 /* Select UTMI+ 16 */
254 GUSBCFG = GUSBCFG_force_device_mode | GUSBCFG_phy_if | 7 << GUSBCFG_toutcal_bitp;
256 /* Do something that is probably CCU related but undocumented*/
257 CCU_USB |= 0x1000;
258 CCU_USB &= ~0x300000;
260 DCFG = DCFG_nzstsouthshk | DCFG_devspd_hs_phy_hs; /* Address 0, high speed */
261 DCTL = DCTL_pwronprgdone;
263 /* Check hardware capabilities */
264 if(extract(GHWCFG2, arch) != GHWCFG2_ARCH_INTERNAL_DMA)
265 panicf("usb-drv: wrong architecture (%ld)", extract(GHWCFG2, arch));
266 if(extract(GHWCFG2, hs_phy_type) != GHWCFG2_PHY_TYPE_UTMI)
267 panicf("usb-drv: wrong HS phy type (%ld)", extract(GHWCFG2, hs_phy_type));
268 if(extract(GHWCFG2, fs_phy_type) != GHWCFG2_PHY_TYPE_UNSUPPORTED)
269 panicf("usb-drv: wrong FS phy type (%ld)", extract(GHWCFG2, fs_phy_type));
270 if(extract(GHWCFG4, utmi_phy_data_width) != 0x2)
271 panicf("usb-drv: wrong utmi data width (%ld)", extract(GHWCFG4, utmi_phy_data_width));
272 if(!(GHWCFG4 & GHWCFG4_ded_fifo_en)) /* it seems to be multiple tx fifo support */
273 panicf("usb-drv: no multiple tx fifo");
275 if(USB_NUM_ENDPOINTS != extract(GHWCFG2, num_ep))
276 panicf("usb-drv: wrong endpoint number");
278 for (int dir = 0; dir < 2; dir++)
279 for (unsigned i = 0; i < num_eps(dir == DIR_OUT); i++)
281 int ep = ((dir == DIR_IN) ? in_ep_list : out_ep_list)[i];
282 int type = (GHWCFG1 >> GHWCFG1_epdir_bitp(ep)) & GHWCFG1_epdir_bits;
283 int flag = (dir == DIR_IN) ? GHWCFG1_EPDIR_IN : GHWCFG1_EPDIR_OUT;
284 if(type != GHWCFG1_EPDIR_BIDIR && type != flag)
285 panicf("usb-drv: EP%d not in correct direction", ep);
288 DOEPMSK = DEPINT_xfercompl | DEPINT_ahberr | DOEPINT_setup;
289 DIEPMSK = DEPINT_xfercompl | DEPINT_ahberr | DIEPINT_timeout;
290 DAINTMSK = 0xffffffff;
292 reset_endpoints();
294 GINTMSK = GINTMSK_usbreset
295 | GINTMSK_enumdone
296 | GINTMSK_inepintr
297 | GINTMSK_outepintr
298 | GINTMSK_disconnect;
300 VIC_INT_ENABLE = INTERRUPT_USB;
303 void usb_drv_exit(void)
305 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
307 VIC_INT_EN_CLEAR = INTERRUPT_USB;
309 sleep(HZ/20);
311 CGU_USB = 0;
312 bitclr32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
315 static void handle_ep_int(int ep, bool out)
317 unsigned long sts = DEPINT(ep, out);
318 logf("%s(%d %s): sts = 0x%lx", __func__, ep, out?"OUT":"IN", sts);
320 if(sts & DEPINT_ahberr)
321 panicf("usb-drv: ahb error on EP%d %s", ep, out ? "OUT" : "IN");
323 if(sts & DEPINT_xfercompl)
325 struct ep_type *endpoint = &endpoints[ep][out ? DIR_OUT : DIR_IN];
326 if(endpoint->busy)
328 endpoint->busy = false;
329 endpoint->status = 0;
330 /* works even for EP0 */
331 int size = (DEPTSIZ(ep, out) & DEPTSIZ_xfersize_bits);
332 int transfered = endpoint->size - size;
333 if(ep == 0)
335 bool is_ack = endpoint->size == 0;
336 switch(ep0_state)
338 case EP0_WAIT_SETUP:
339 panicf("usb-drv: EP0 completion while waiting for SETUP");
340 case EP0_WAIT_DATA_ACK:
341 ep0_state = is_ack ? EP0_WAIT_DATA : EP0_WAIT_ACK;
342 break;
343 case EP0_WAIT_ACK:
344 case EP0_WAIT_DATA:
345 if((!is_ack && ep0_state == EP0_WAIT_ACK) || (is_ack && ep0_state == EP0_WAIT_DATA))
346 panicf("usb-drv: bad EP0 state");
348 prepare_setup_ep0();
349 break;
352 if (!out)
353 endpoint->size = size;
354 usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, transfered);
355 endpoint->done = true;
356 semaphore_release(&endpoint->complete);
360 if(!out && (sts & DIEPINT_timeout))
361 panicf("usb-drv: timeout on EP%d IN", ep);
363 if(out && (sts & DOEPINT_setup))
365 if(ep != 0)
366 panicf("usb-drv: setup not on EP0, this is impossible");
367 if((DEPTSIZ(ep, true) & DEPTSIZ_xfersize_bits) != 0)
369 logf("usb-drv: ignore spurious setup (xfersize=%ld)", DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits);
370 prepare_setup_ep0();
372 else
374 if(ep0_state == EP0_WAIT_SETUP)
376 bool data_phase = ep0_setup_pkt->wLength != 0;
377 ep0_state = data_phase ? EP0_WAIT_DATA_ACK : EP0_WAIT_ACK;
380 logf(" rt=%x r=%x", ep0_setup_pkt->bRequestType, ep0_setup_pkt->bRequest);
382 if(ep0_setup_pkt->bRequestType == USB_TYPE_STANDARD &&
383 ep0_setup_pkt->bRequest == USB_REQ_SET_ADDRESS)
384 DCFG = (DCFG & ~bitm(DCFG, devadr)) | (ep0_setup_pkt->wValue << DCFG_devadr_bitp);
386 usb_core_control_request(ep0_setup_pkt);
390 DEPINT(ep, out) = sts;
393 void INT_USB(void)
395 /* some bits in GINTSTS can be set even though we didn't enable the interrupt source
396 * so AND it with the actual mask */
397 unsigned long sts = GINTSTS & GINTMSK;
398 logf("usb-drv: INT 0x%lx", sts);
400 if(sts & GINTMSK_usbreset)
402 DCFG &= ~bitm(DCFG, devadr); /* Address 0 */
403 reset_endpoints();
404 usb_core_bus_reset();
407 if(sts & GINTMSK_enumdone) /* enumeration done, we now know the speed */
409 /* Set up the maximum packet sizes accordingly */
410 uint32_t maxpacket = (usb_drv_port_speed() ? 512 : 64) << DEPCTL_mps_bitp;
411 for (int dir = 0; dir < 2; dir++)
413 bool out = dir == DIR_OUT;
414 for (unsigned i = 1; i < num_eps(out); i++)
416 int ep = (out ? out_ep_list : in_ep_list)[i];
417 DEPCTL(ep, out) &= ~(DEPCTL_mps_bits << DEPCTL_mps_bitp);
418 DEPCTL(ep, out) |= maxpacket;
423 if(sts & (GINTMSK_outepintr | GINTMSK_inepintr))
425 unsigned long daint = DAINT;
427 for (int i = 0; i < USB_NUM_ENDPOINTS; i++)
429 if (daint & DAINT_IN_EP(i))
430 handle_ep_int(i, false);
431 if (daint & DAINT_OUT_EP(i))
432 handle_ep_int(i, true);
435 DAINT = daint;
438 if(sts & GINTMSK_disconnect)
439 cancel_all_transfers(true);
441 GINTSTS = sts;
444 int usb_drv_request_endpoint(int type, int dir)
446 bool out = dir == USB_DIR_OUT;
447 for (unsigned i = 1; i < num_eps(out); i++)
449 int ep = (out ? out_ep_list : in_ep_list)[i];
450 bool *active = &endpoints[ep][out ? DIR_OUT : DIR_IN].active;
451 if(*active)
452 continue;
453 *active = true;
454 DEPCTL(ep, out) = (DEPCTL(ep, out) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp))
455 | DEPCTL_setd0pid | (type << DEPCTL_eptype_bitp) | DEPCTL_usbactep;
456 return ep | dir;
459 return -1;
462 void usb_drv_release_endpoint(int ep)
464 endpoints[EP_NUM(ep)][EP_DIR(ep)].active = false;
467 void usb_drv_cancel_all_transfers()
469 cancel_all_transfers(false);
472 static void ep_transfer(int ep, void *ptr, int len, bool out)
474 /* disable interrupts to avoid any race */
475 int oldlevel = disable_irq_save();
477 struct ep_type *endpoint = &endpoints[ep][out ? DIR_OUT : DIR_IN];
478 endpoint->busy = true;
479 endpoint->size = len;
480 endpoint->status = -1;
482 if (out)
483 DEPCTL(ep, out) &= ~DEPCTL_stall;
485 int mps = usb_drv_port_speed() ? 512 : 64;
486 int nb_packets = (len + mps - 1) / mps;
487 if (nb_packets == 0)
488 nb_packets = 1;
490 DEPDMA(ep, out) = len ? (void*)AS3525_PHYSICAL_ADDR(ptr) : NULL;
491 DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
492 if(out)
493 discard_dcache_range(ptr, len);
494 else
495 commit_dcache_range(ptr, len);
497 logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out));
499 // if (!out) while (((GNPTXSTS & 0xffff) << 2) < MIN(mps, length));
501 DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak;
503 restore_irq(oldlevel);
506 int usb_drv_send(int ep, void *ptr, int len)
508 ep = EP_NUM(ep);
509 struct ep_type *endpoint = &endpoints[ep][1];
510 endpoint->done = false;
511 ep_transfer(ep, ptr, len, false);
512 while (endpoint->busy && !endpoint->done)
513 semaphore_wait(&endpoint->complete, TIMEOUT_BLOCK);
514 return endpoint->status;
516 #else
518 static struct ep_type endpoints[USB_NUM_ENDPOINTS][2];
520 /* USB control requests may be up to 64 bytes in size.
521 Even though we never use anything more than the 8 header bytes,
522 we are required to accept request packets of up to 64 bytes size.
523 Provide buffer space for these additional payload bytes so that
524 e.g. write descriptor requests (which are rejected by us, but the
525 payload is transferred anyway) do not cause memory corruption.
526 Fixes FS#12310. -- Michael Sparmann (theseven) */
527 static union
529 struct usb_ctrlrequest header; /* 8 bytes */
530 unsigned char payload[64];
531 } ctrlreq USB_DEVBSS_ATTR;
533 static volatile bool inflight = false;
534 static volatile bool plugged = false;
536 static void reset_endpoints(int reinit)
538 for (unsigned i = 0; i < sizeof(endpoints)/(2*sizeof(struct ep_type)); i++)
539 for (unsigned dir = 0; dir < 2; dir++)
541 if (reinit) endpoints[i][dir].active = false;
542 endpoints[i][dir].busy = false;
543 endpoints[i][dir].status = -1;
544 endpoints[i][dir].done = true;
545 semaphore_release(&endpoints[i][dir].complete);
548 DEPCTL(0, false) = DEPCTL_usbactep | (1 << DEPCTL_nextep_bitp);
549 DEPCTL(0, true) = DEPCTL_usbactep;
550 DEPTSIZ(0, true) = (1 << DEPTSIZ_pkcnt_bitp) | (1 << DEPTSIZ0_supcnt_bitp) | 64;
552 DEPDMA(0, true) = &ctrlreq;
553 DEPCTL(0, true) |= DEPCTL_epena | DEPCTL_cnak;
554 /* HACK: Enable all endpoints here, because we have no other chance to do it */
555 if (reinit)
557 /* The size is getting set to zero, because we don't know
558 whether we are Full Speed or High Speed at this stage */
559 DEPCTL(1, false) = DEPCTL_usbactep | DEPCTL_setd0pid | (3 << DEPCTL_nextep_bitp);
560 DEPCTL(2, true) = DEPCTL_usbactep | DEPCTL_setd0pid;
561 DEPCTL(3, false) = DEPCTL_usbactep | DEPCTL_setd0pid | (0 << DEPCTL_nextep_bitp);
562 DEPCTL(4, true) = DEPCTL_usbactep | DEPCTL_setd0pid;
564 else
566 DEPCTL(1, false) = DEPCTL(1, false) | DEPCTL_usbactep | DEPCTL_setd0pid;
567 DEPCTL(2, true) = DEPCTL(2, true) | DEPCTL_usbactep | DEPCTL_setd0pid;
568 DEPCTL(3, false) = DEPCTL(3, false) | DEPCTL_usbactep | DEPCTL_setd0pid;
569 DEPCTL(4, true) = DEPCTL(4, true) | DEPCTL_usbactep | DEPCTL_setd0pid;
571 DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all EPs */
572 inflight = false;
575 int usb_drv_request_endpoint(int type, int dir)
577 bool out = dir == USB_DIR_OUT;
578 for(size_t ep = out ? 2 : 1; ep < USB_NUM_ENDPOINTS; ep += 2) {
579 if (!endpoints[ep][out ? DIR_OUT : DIR_IN].active)
581 endpoints[ep][out ? DIR_OUT : DIR_IN].active = true;
582 DEPCTL(ep, out) = (DEPCTL(ep, out) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp)) |
583 (type << DEPCTL_eptype_bitp);
584 return ep | dir;
588 return -1;
591 void usb_drv_release_endpoint(int ep)
593 bool out = !(ep & USB_DIR_IN);
594 ep = ep & 0x7f;
596 if (ep < 1 || ep > USB_NUM_ENDPOINTS)
597 return;
599 endpoints[ep][out ? DIR_OUT : DIR_IN].active = false;
602 static void usb_reset(void)
604 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
606 OPHYPWR = 0; /* PHY: Power up */
607 udelay(10);
608 OPHYUNK1 = 1;
609 OPHYUNK2 = 0xE3F;
610 ORSTCON = 1; /* PHY: Assert Software Reset */
611 udelay(10);
612 ORSTCON = 0; /* PHY: Deassert Software Reset */
613 OPHYUNK3 = 0x600;
614 OPHYCLK = SYNOPSYSOTG_CLOCK;
615 udelay(400);
617 GRSTCTL = GRSTCTL_csftrst; /* OTG: Assert Software Reset */
618 while (GRSTCTL & GRSTCTL_csftrst); /* Wait for OTG to ack reset */
619 while (!(GRSTCTL & GRSTCTL_ahbidle)); /* Wait for OTG AHB master idle */
621 GRXFSIZ = 1024;
622 GNPTXFSIZ = (256 << 16) | 1024;
624 GAHBCFG = SYNOPSYSOTG_AHBCFG;
625 GUSBCFG = (1 << 12) | (1 << 10) | GUSBCFG_phy_if; /* OTG: 16bit PHY and some reserved bits */
627 DCFG = DCFG_nzstsouthshk; /* Address 0 */
628 DCTL = DCTL_pwronprgdone; /* Soft Reconnect */
629 DIEPMSK = DIEPINT_timeout | DEPINT_ahberr | DEPINT_xfercompl;
630 DOEPMSK = DOEPINT_setup | DEPINT_ahberr | DEPINT_xfercompl;
631 DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all endpoints */
632 GINTMSK = GINTMSK_outepintr | GINTMSK_inepintr | GINTMSK_usbreset | GINTMSK_enumdone;
634 reset_endpoints(1);
637 static void handle_ep_int(bool out)
639 static const uint8_t eps[2][3] = { /* IN */ {0, 1, 3}, /* OUT */ {0, 2, 4}};
640 for (int i = 0; i < 3; i++)
642 int ep = eps[!!out][i];
643 uint32_t epints = DEPINT(ep, out);
644 if (!epints)
645 continue;
647 if (epints & DEPINT_xfercompl)
649 if (!out) inflight = false;
650 commit_discard_dcache();
651 int bytes = endpoints[ep][out ? DIR_OUT : DIR_IN].size - (DEPTSIZ(ep, out) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp));
652 if (endpoints[ep][out ? DIR_OUT : DIR_IN].busy)
654 endpoints[ep][out ? DIR_OUT : DIR_IN].busy = false;
655 endpoints[ep][out ? DIR_OUT : DIR_IN].status = 0;
656 endpoints[ep][out ? DIR_OUT : DIR_IN].done = true;
657 usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, bytes);
658 semaphore_release(&endpoints[ep][out ? DIR_OUT : DIR_IN].complete);
662 if (epints & DEPINT_ahberr)
663 panicf("USB: AHB error on EP%d (dir %d)", ep, out);
665 if (!out && (epints & DIEPINT_timeout))
667 if (endpoints[ep][out ? DIR_OUT : DIR_IN].busy)
669 endpoints[ep][out ? DIR_OUT : DIR_IN].busy = false;
670 endpoints[ep][out ? DIR_OUT : DIR_IN].status = 1;
671 endpoints[ep][out ? DIR_OUT : DIR_IN].done = true;
672 semaphore_release(&endpoints[ep][out ? DIR_OUT : DIR_IN].complete);
676 if (out && (epints & DOEPINT_setup))
678 commit_discard_dcache();
679 if (ep != 0)
680 panicf("USB: SETUP done on OUT EP%d!?", ep);
682 /* Set the new address here, before passing the packet to the core.
683 See usb_drv_set_address() for details. */
684 if (ctrlreq.header.bRequest == USB_REQ_SET_ADDRESS)
685 DCFG = (DCFG & ~(DCFG_devadr_bits << DCFG_devadr_bitp))
686 | (ctrlreq.header.wValue << DCFG_devadr_bitp);
688 usb_core_control_request(&ctrlreq.header);
691 /* Make sure EP0 OUT is set up to accept the next request */
692 if (out && ep == 0)
694 DEPTSIZ(0, true) = (1 << DEPTSIZ0_supcnt_bitp) | (1 << DEPTSIZ0_pkcnt_bitp) | 64;
695 DEPDMA(0, true) = &ctrlreq;
696 DEPCTL(0, true) |= DEPCTL_epena | DEPCTL_cnak;
698 DEPINT(ep, out) = epints;
702 /* IRQ handler */
703 void INT_USB_FUNC(void)
705 uint32_t ints = GINTSTS;
706 if (ints & GINTMSK_usbreset)
708 DCFG = DCFG_nzstsouthshk; /* Address 0 */
709 reset_endpoints(1);
710 usb_core_bus_reset();
713 if (ints & GINTMSK_enumdone) /* enumeration done, we now know the speed */
715 /* Set up the maximum packet sizes accordingly */
716 uint32_t maxpacket = (usb_drv_port_speed() ? 512 : 64) << DEPCTL_mps_bitp;
717 DEPCTL(1, false) = (DEPCTL(1, false) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket;
718 DEPCTL(2, true) = (DEPCTL(2, true) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket;
719 DEPCTL(3, false) = (DEPCTL(3, false) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket;
720 DEPCTL(4, true) = (DEPCTL(4, true) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket;
723 if (ints & GINTMSK_inepintr)
724 handle_ep_int(false);
726 if (ints & GINTMSK_outepintr)
727 handle_ep_int(true);
729 GINTSTS = ints;
732 static void ep_transfer(int ep, void *ptr, int len, bool out)
734 while (!out && inflight && plugged);
735 if (!plugged) return;
737 /* disable interrupts to avoid any race */
738 int oldlevel = disable_irq_save();
739 if (!out) inflight = true;
740 endpoints[ep][out ? DIR_OUT : DIR_IN].busy = true;
741 endpoints[ep][out ? DIR_OUT : DIR_IN].size = len;
743 if (out) DEPCTL(ep, out) &= ~DEPCTL_stall;
746 int mps = usb_drv_port_speed() ? 512 : 64;
747 int nb_packets = (len + mps - 1) / mps;
748 if (nb_packets == 0)
749 nb_packets = 1;
751 DEPDMA(ep, out) = len ? ptr : NULL;
752 DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
754 if(out) discard_dcache_range(ptr, len);
755 else commit_dcache_range(ptr, len);
757 logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out));
759 DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak;
761 restore_irq(oldlevel);
764 int usb_drv_send(int endpoint, void *ptr, int length)
766 endpoint = EP_NUM(endpoint);
767 endpoints[endpoint][1].done = false;
768 ep_transfer(endpoint, ptr, length, false);
769 while (!endpoints[endpoint][1].done && endpoints[endpoint][1].busy)
770 semaphore_wait(&endpoints[endpoint][1].complete, TIMEOUT_BLOCK);
771 return endpoints[endpoint][1].status;
774 void usb_drv_cancel_all_transfers(void)
776 int flags = disable_irq_save();
777 reset_endpoints(0);
778 restore_irq(flags);
781 void usb_drv_init(void)
783 for (unsigned i = 0; i < sizeof(endpoints)/(2*sizeof(struct ep_type)); i++)
784 for (unsigned dir = 0; dir < 2; dir++)
785 semaphore_init(&endpoints[i][dir].complete, 1, 0);
787 /* Enable USB clock */
788 #if CONFIG_CPU==S5L8701
789 PWRCON &= ~0x4000;
790 PWRCONEXT &= ~0x800;
791 INTMSK |= INTMSK_USB_OTG;
792 #elif CONFIG_CPU==S5L8702
793 PWRCON(0) &= ~0x4;
794 PWRCON(1) &= ~0x8;
795 VIC0INTENABLE |= 1 << 19;
796 #endif
797 PCGCCTL = 0;
799 /* reset the beast */
800 plugged = true;
801 usb_reset();
804 void usb_drv_exit(void)
806 plugged = false;
807 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
809 OPHYPWR = 0xF; /* PHY: Power down */
810 udelay(10);
811 ORSTCON = 7; /* Put the PHY into reset (needed to get current down) */
812 udelay(10);
813 PCGCCTL = 1; /* Shut down PHY clock */
815 #if CONFIG_CPU==S5L8701
816 PWRCON |= 0x4000;
817 PWRCONEXT |= 0x800;
818 #elif CONFIG_CPU==S5L8702
819 PWRCON(0) |= 0x4;
820 PWRCON(1) |= 0x8;
821 #endif
824 void usb_attach(void)
826 usb_enable(true);
828 #endif // CONFIG_CPU == AS3525v2 /* FIXME FIXME FIXME */