Prepare new maemo release
[maemo-rb.git] / firmware / target / arm / usb-s3c6400x.c
blob48521aa622f24bc8653e219aac2b686422296038
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 #if CONFIG_CPU == AS3525v2
43 #define UNCACHED_ADDR AS3525_UNCACHED_ADDR
44 #define PHYSICAL_ADDR AS3525_PHYSICAL_ADDR
45 static inline void discard_dma_buffer_cache(void) {}
46 #else
47 #define UNCACHED_ADDR
48 #define PHYSICAL_ADDR
49 static inline void discard_dma_buffer_cache(void) { commit_discard_dcache(); }
50 #endif
52 /* store per endpoint, per direction, information */
53 struct ep_type
55 unsigned int size; /* length of the data buffer */
56 struct semaphore complete; /* wait object */
57 int8_t status; /* completion status (0 for success) */
58 bool active; /* true is endpoint has been requested (true for EP0) */
59 bool done; /* transfer completed */
60 bool busy; /* true is a transfer is pending */
63 static const uint8_t in_ep_list[] = {0, 1, 3, 5};
64 static const uint8_t out_ep_list[] = {0, 2, 4};
66 /* state of EP0 (to correctly schedule setup packet enqueing) */
67 enum ep0state
69 /* Setup packet is enqueud, waiting for actual data */
70 EP0_WAIT_SETUP = 0,
71 /* Waiting for ack (either IN or OUT) */
72 EP0_WAIT_ACK = 1,
73 /* Ack complete, waiting for data (either IN or OUT)
74 * This state is necessary because if both ack and data complete in the
75 * same interrupt, we might process data completion before ack completion
76 * so we need this bizarre state */
77 EP0_WAIT_DATA = 2,
78 /* Setup packet complete, waiting for ack and data */
79 EP0_WAIT_DATA_ACK = 3,
82 /* endpoints[ep_num][DIR_IN/DIR_OUT] */
83 static struct ep_type endpoints[USB_NUM_ENDPOINTS][2];
84 /* setup packet for EP0 */
86 /* USB control requests may be up to 64 bytes in size.
87 Even though we never use anything more than the 8 header bytes,
88 we are required to accept request packets of up to 64 bytes size.
89 Provide buffer space for these additional payload bytes so that
90 e.g. write descriptor requests (which are rejected by us, but the
91 payload is transferred anyway) do not cause memory corruption.
92 Fixes FS#12310. -- Michael Sparmann (theseven) */
93 static union {
94 struct usb_ctrlrequest header; /* 8 bytes */
95 unsigned char payload[64];
96 } _ep0_setup_pkt USB_DEVBSS_ATTR;
98 static struct usb_ctrlrequest *ep0_setup_pkt = UNCACHED_ADDR(&_ep0_setup_pkt.header);
100 /* state of EP0 */
101 static enum ep0state ep0_state;
103 bool usb_drv_stalled(int endpoint, bool in)
105 return DEPCTL(endpoint, !in) & DEPCTL_stall;
108 void usb_drv_stall(int endpoint, bool stall, bool in)
110 if (stall)
111 DEPCTL(endpoint, !in) |= DEPCTL_stall;
112 else
113 DEPCTL(endpoint, !in) &= ~DEPCTL_stall;
116 void usb_drv_set_address(int address)
118 (void)address;
119 /* Ignored intentionally, because the controller requires us to set the
120 new address before sending the response for some reason. So we'll
121 already set it when the control request arrives, before passing that
122 into the USB core, which will then call this dummy function. */
125 static void ep_transfer(int ep, void *ptr, int len, bool out)
127 /* disable interrupts to avoid any race */
128 int oldlevel = disable_irq_save();
130 struct ep_type *endpoint = &endpoints[ep][out ? DIR_OUT : DIR_IN];
131 endpoint->busy = true;
132 endpoint->size = len;
133 endpoint->status = -1;
135 if (out)
136 DEPCTL(ep, out) &= ~DEPCTL_stall;
138 int mps = usb_drv_port_speed() ? 512 : 64;
139 int nb_packets = (len + mps - 1) / mps;
140 if (nb_packets == 0)
141 nb_packets = 1;
143 DEPDMA(ep, out) = len ? (void*)PHYSICAL_ADDR(ptr) : NULL;
144 DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
145 if(out)
146 discard_dcache_range(ptr, len);
147 else
148 commit_dcache_range(ptr, len);
150 logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out));
152 // if (!out) while (((GNPTXSTS & 0xffff) << 2) < MIN(mps, length));
154 DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak;
156 restore_irq(oldlevel);
159 int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
161 ep_transfer(EP_NUM(endpoint), ptr, length, false);
162 return 0;
165 int usb_drv_recv(int endpoint, void* ptr, int length)
167 ep_transfer(EP_NUM(endpoint), ptr, length, true);
168 return 0;
171 int usb_drv_port_speed(void)
173 static const uint8_t speed[4] = {
174 [DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = 1,
175 [DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = 0,
176 [DSTS_ENUMSPD_FS_PHY_48MHZ] = 0,
177 [DSTS_ENUMSPD_LS_PHY_6MHZ] = 0,
180 unsigned enumspd = extract(DSTS, enumspd);
182 if(enumspd == DSTS_ENUMSPD_LS_PHY_6MHZ)
183 panicf("usb-drv: LS is not supported");
185 return speed[enumspd & 3];
188 void usb_drv_set_test_mode(int mode)
190 /* there is a perfect matching between usb test mode code
191 * and the register field value */
192 DCTL = (DCTL & ~bitm(DCTL, tstctl)) | (mode << DCTL_tstctl_bitp);
195 void usb_attach(void)
197 usb_enable(true); // s5l only ?
198 /* Nothing to do */
201 static void prepare_setup_ep0(void)
203 DEPDMA(0, true) = (void*)PHYSICAL_ADDR(&_ep0_setup_pkt);
204 DEPTSIZ(0, true) = (1 << DEPTSIZ0_supcnt_bitp)
205 | (1 << DEPTSIZ0_pkcnt_bitp)
206 | 8;
207 DEPCTL(0, true) |= DEPCTL_epena | DEPCTL_cnak;
209 ep0_state = EP0_WAIT_SETUP;
212 static size_t num_eps(bool out)
214 return out ? sizeof(out_ep_list) : sizeof(in_ep_list);
217 static void reset_endpoints(void)
219 for (int dir = 0; dir < 2; dir++)
221 bool out = dir == DIR_OUT;
222 for (unsigned i = 0; i < num_eps(dir == DIR_OUT); i++)
224 int ep = ((dir == DIR_IN) ? in_ep_list : out_ep_list)[i];
225 struct ep_type *endpoint = &endpoints[ep][out];
226 endpoint->active = false;
227 endpoint->busy = false;
228 endpoint->status = -1;
229 endpoint->done = true;
230 semaphore_release(&endpoint->complete);
232 if (i != 0)
233 DEPCTL(ep, out) = DEPCTL_setd0pid;
235 DEPCTL(0, out) = /*(DEPCTL_MPS_64 << DEPCTL_mps_bitp) | */ DEPCTL_usbactep;
238 /* Setup next chain for IN eps */
239 for (unsigned i = 0; i < num_eps(false); i++)
241 int ep = in_ep_list[i];
242 int next_ep = in_ep_list[(i + 1) % num_eps(false)];
243 DEPCTL(ep, false) |= next_ep << DEPCTL_nextep_bitp;
246 prepare_setup_ep0();
249 static void cancel_all_transfers(bool cancel_ep0)
251 int flags = disable_irq_save();
253 for (int dir = 0; dir < 2; dir++)
254 for (unsigned i = !!cancel_ep0; i < num_eps(dir == DIR_OUT); i++)
256 int ep = ((dir == DIR_IN) ? in_ep_list : out_ep_list)[i];
257 struct ep_type *endpoint = &endpoints[ep][dir == DIR_OUT];
258 endpoint->status = -1;
259 endpoint->busy = false;
260 endpoint->done = false;
261 semaphore_release(&endpoint->complete);
262 DEPCTL(ep, dir) = (DEPCTL(ep, dir) & ~DEPCTL_usbactep);
265 restore_irq(flags);
268 #if CONFIG_CPU == AS3525v2
269 void usb_drv_init(void)
271 for (int i = 0; i < USB_NUM_ENDPOINTS; i++)
272 for (int dir = 0; dir < 2; dir++)
273 semaphore_init(&endpoints[i][dir].complete, 1, 0);
275 bitset32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
276 CCU_USB = (CCU_USB & ~(3<<24)) | (1 << 24); /* ?? */
277 /* PHY clock */
278 CGU_USB = 1<<5 /* enable */
279 | 0 << 2
280 | 0; /* source = ? (24MHz crystal?) */
282 PCGCCTL = 0;
283 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
285 GRSTCTL = GRSTCTL_csftrst;
286 while (GRSTCTL & GRSTCTL_csftrst); /* Wait for OTG to ack reset */
287 while (!(GRSTCTL & GRSTCTL_ahbidle)); /* Wait for OTG AHB master idle */
289 GRXFSIZ = 512;
290 GNPTXFSIZ = MAKE_FIFOSIZE_DATA(512);
292 /* FIXME: the current code is for internal DMA only, the clip+ architecture
293 * defines the internal DMA model */
294 GAHBCFG = (GAHBCFG_INT_DMA_BURST_INCR << GAHBCFG_hburstlen_bitp)
295 | GAHBCFG_dma_enable | GAHBCFG_glblintrmsk;
297 /* Select UTMI+ 16 */
298 GUSBCFG = GUSBCFG_force_device_mode | GUSBCFG_phy_if | 7 << GUSBCFG_toutcal_bitp;
300 /* Do something that is probably CCU related but undocumented*/
301 CCU_USB |= 0x1000;
302 CCU_USB &= ~0x300000;
304 DCFG = DCFG_nzstsouthshk | DCFG_devspd_hs_phy_hs; /* Address 0, high speed */
305 DCTL = DCTL_pwronprgdone;
307 /* Check hardware capabilities */
308 if(extract(GHWCFG2, arch) != GHWCFG2_ARCH_INTERNAL_DMA)
309 panicf("usb-drv: wrong architecture (%ld)", extract(GHWCFG2, arch));
310 if(extract(GHWCFG2, hs_phy_type) != GHWCFG2_PHY_TYPE_UTMI)
311 panicf("usb-drv: wrong HS phy type (%ld)", extract(GHWCFG2, hs_phy_type));
312 if(extract(GHWCFG2, fs_phy_type) != GHWCFG2_PHY_TYPE_UNSUPPORTED)
313 panicf("usb-drv: wrong FS phy type (%ld)", extract(GHWCFG2, fs_phy_type));
314 if(extract(GHWCFG4, utmi_phy_data_width) != 0x2)
315 panicf("usb-drv: wrong utmi data width (%ld)", extract(GHWCFG4, utmi_phy_data_width));
316 if(!(GHWCFG4 & GHWCFG4_ded_fifo_en)) /* it seems to be multiple tx fifo support */
317 panicf("usb-drv: no multiple tx fifo");
319 if(USB_NUM_ENDPOINTS != extract(GHWCFG2, num_ep))
320 panicf("usb-drv: wrong endpoint number");
322 for (int dir = 0; dir < 2; dir++)
323 for (unsigned i = 0; i < num_eps(dir == DIR_OUT); i++)
325 int ep = ((dir == DIR_IN) ? in_ep_list : out_ep_list)[i];
326 int type = (GHWCFG1 >> GHWCFG1_epdir_bitp(ep)) & GHWCFG1_epdir_bits;
327 int flag = (dir == DIR_IN) ? GHWCFG1_EPDIR_IN : GHWCFG1_EPDIR_OUT;
328 if(type != GHWCFG1_EPDIR_BIDIR && type != flag)
329 panicf("usb-drv: EP%d not in correct direction", ep);
332 DOEPMSK = DEPINT_xfercompl | DEPINT_ahberr | DOEPINT_setup;
333 DIEPMSK = DEPINT_xfercompl | DEPINT_ahberr | DIEPINT_timeout;
334 DAINTMSK = 0xffffffff;
336 reset_endpoints();
338 GINTMSK = GINTMSK_usbreset
339 | GINTMSK_enumdone
340 | GINTMSK_inepintr
341 | GINTMSK_outepintr
342 | GINTMSK_disconnect;
344 VIC_INT_ENABLE = INTERRUPT_USB;
347 void usb_drv_exit(void)
349 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
351 VIC_INT_EN_CLEAR = INTERRUPT_USB;
353 sleep(HZ/20);
355 CGU_USB = 0;
356 bitclr32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
358 #elif CONFIG_CPU == S5L8701 || CONFIG_CPU == S5L8702
359 static void usb_reset(void)
361 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
363 OPHYPWR = 0; /* PHY: Power up */
364 udelay(10);
365 OPHYUNK1 = 1;
366 OPHYUNK2 = 0xE3F;
367 ORSTCON = 1; /* PHY: Assert Software Reset */
368 udelay(10);
369 ORSTCON = 0; /* PHY: Deassert Software Reset */
370 OPHYUNK3 = 0x600;
371 OPHYCLK = SYNOPSYSOTG_CLOCK;
372 udelay(400);
374 GRSTCTL = GRSTCTL_csftrst; /* OTG: Assert Software Reset */
375 while (GRSTCTL & GRSTCTL_csftrst); /* Wait for OTG to ack reset */
376 while (!(GRSTCTL & GRSTCTL_ahbidle)); /* Wait for OTG AHB master idle */
378 GRXFSIZ = 1024;
379 GNPTXFSIZ = (256 << 16) | 1024;
381 GAHBCFG = SYNOPSYSOTG_AHBCFG;
382 GUSBCFG = (1 << 12) | (1 << 10) | GUSBCFG_phy_if; /* OTG: 16bit PHY and some reserved bits */
384 DCFG = DCFG_nzstsouthshk; /* Address 0 */
385 DCTL = DCTL_pwronprgdone; /* Soft Reconnect */
386 DIEPMSK = DIEPINT_timeout | DEPINT_ahberr | DEPINT_xfercompl;
387 DOEPMSK = DOEPINT_setup | DEPINT_ahberr | DEPINT_xfercompl;
388 DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all endpoints */
389 GINTMSK = GINTMSK_outepintr | GINTMSK_inepintr | GINTMSK_usbreset | GINTMSK_enumdone;
391 reset_endpoints();
394 void usb_drv_init(void)
396 for (unsigned i = 0; i < sizeof(endpoints)/(2*sizeof(struct ep_type)); i++)
397 for (unsigned dir = 0; dir < 2; dir++)
398 semaphore_init(&endpoints[i][dir].complete, 1, 0);
400 /* Enable USB clock */
401 #if CONFIG_CPU==S5L8701
402 PWRCON &= ~0x4000;
403 PWRCONEXT &= ~0x800;
404 INTMSK |= INTMSK_USB_OTG;
405 #elif CONFIG_CPU==S5L8702
406 PWRCON(0) &= ~0x4;
407 PWRCON(1) &= ~0x8;
408 VIC0INTENABLE |= 1 << 19;
409 #endif
410 PCGCCTL = 0;
412 /* reset the beast */
413 usb_reset();
416 void usb_drv_exit(void)
418 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
420 OPHYPWR = 0xF; /* PHY: Power down */
421 udelay(10);
422 ORSTCON = 7; /* Put the PHY into reset (needed to get current down) */
423 udelay(10);
424 PCGCCTL = 1; /* Shut down PHY clock */
426 #if CONFIG_CPU==S5L8701
427 PWRCON |= 0x4000;
428 PWRCONEXT |= 0x800;
429 #elif CONFIG_CPU==S5L8702
430 PWRCON(0) |= 0x4;
431 PWRCON(1) |= 0x8;
432 #endif
434 #endif
436 static void handle_ep_int(int ep, bool out)
438 unsigned long sts = DEPINT(ep, out);
439 struct ep_type *endpoint = &endpoints[ep][out ? DIR_OUT : DIR_IN];
441 logf("%s(%d %s): sts = 0x%lx", __func__, ep, out?"OUT":"IN", sts);
443 if(sts & DEPINT_ahberr)
444 panicf("usb-drv: ahb error on EP%d %s", ep, out ? "OUT" : "IN");
446 if(sts & DEPINT_xfercompl)
448 discard_dma_buffer_cache();
449 if(endpoint->busy)
451 endpoint->busy = false;
452 endpoint->status = 0;
453 /* works even for EP0 */
454 int size = (DEPTSIZ(ep, out) & DEPTSIZ_xfersize_bits);
455 int transfered = endpoint->size - size;
456 if(ep == 0)
458 bool is_ack = endpoint->size == 0;
459 switch(ep0_state)
461 case EP0_WAIT_SETUP:
462 panicf("usb-drv: EP0 completion while waiting for SETUP");
463 case EP0_WAIT_DATA_ACK:
464 ep0_state = is_ack ? EP0_WAIT_DATA : EP0_WAIT_ACK;
465 break;
466 case EP0_WAIT_ACK:
467 case EP0_WAIT_DATA:
468 if((!is_ack && ep0_state == EP0_WAIT_ACK) || (is_ack && ep0_state == EP0_WAIT_DATA))
469 panicf("usb-drv: bad EP0 state");
471 prepare_setup_ep0();
472 break;
475 if (!out)
476 endpoint->size = size;
477 usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, transfered);
478 endpoint->done = true;
479 semaphore_release(&endpoint->complete);
483 if(!out && (sts & DIEPINT_timeout)) {
484 if (endpoint->busy)
486 endpoint->busy = false;
487 endpoint->status = 1;
488 endpoint->done = true;
489 semaphore_release(&endpoint->complete);
493 if(out && (sts & DOEPINT_setup))
495 discard_dma_buffer_cache();
496 if(ep != 0)
497 panicf("usb-drv: setup not on EP0, this is impossible");
498 if((DEPTSIZ(ep, true) & DEPTSIZ_xfersize_bits) != 0)
500 logf("usb-drv: ignore spurious setup (xfersize=%ld)", DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits);
501 prepare_setup_ep0();
503 else
505 if(ep0_state == EP0_WAIT_SETUP)
507 bool data_phase = ep0_setup_pkt->wLength != 0;
508 ep0_state = data_phase ? EP0_WAIT_DATA_ACK : EP0_WAIT_ACK;
511 logf(" rt=%x r=%x", ep0_setup_pkt->bRequestType, ep0_setup_pkt->bRequest);
513 if(ep0_setup_pkt->bRequestType == USB_TYPE_STANDARD &&
514 ep0_setup_pkt->bRequest == USB_REQ_SET_ADDRESS)
515 DCFG = (DCFG & ~bitm(DCFG, devadr)) | (ep0_setup_pkt->wValue << DCFG_devadr_bitp);
517 usb_core_control_request(ep0_setup_pkt);
521 DEPINT(ep, out) = sts;
524 void INT_USB_FUNC(void)
526 /* some bits in GINTSTS can be set even though we didn't enable the interrupt source
527 * so AND it with the actual mask */
528 unsigned long sts = GINTSTS & GINTMSK;
529 logf("usb-drv: INT 0x%lx", sts);
531 if(sts & GINTMSK_usbreset)
533 DCFG &= ~bitm(DCFG, devadr); /* Address 0 */
534 reset_endpoints();
535 usb_core_bus_reset();
538 if(sts & GINTMSK_enumdone) /* enumeration done, we now know the speed */
540 /* Set up the maximum packet sizes accordingly */
541 uint32_t maxpacket = (usb_drv_port_speed() ? 512 : 64) << DEPCTL_mps_bitp;
542 for (int dir = 0; dir < 2; dir++)
544 bool out = dir == DIR_OUT;
545 for (unsigned i = 1; i < num_eps(out); i++)
547 int ep = (out ? out_ep_list : in_ep_list)[i];
548 DEPCTL(ep, out) &= ~(DEPCTL_mps_bits << DEPCTL_mps_bitp);
549 DEPCTL(ep, out) |= maxpacket;
554 if(sts & (GINTMSK_outepintr | GINTMSK_inepintr))
556 unsigned long daint = DAINT;
558 for (int i = 0; i < USB_NUM_ENDPOINTS; i++)
560 if (daint & DAINT_IN_EP(i))
561 handle_ep_int(i, false);
562 if (daint & DAINT_OUT_EP(i))
563 handle_ep_int(i, true);
566 DAINT = daint;
569 if(sts & GINTMSK_disconnect)
570 cancel_all_transfers(true);
572 GINTSTS = sts;
575 int usb_drv_request_endpoint(int type, int dir)
577 bool out = dir == USB_DIR_OUT;
578 for (unsigned i = 1; i < num_eps(out); i++)
580 int ep = (out ? out_ep_list : in_ep_list)[i];
581 bool *active = &endpoints[ep][out ? DIR_OUT : DIR_IN].active;
582 if(*active)
583 continue;
584 *active = true;
585 DEPCTL(ep, out) = (DEPCTL(ep, out) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp))
586 | DEPCTL_setd0pid | (type << DEPCTL_eptype_bitp) | DEPCTL_usbactep;
587 return ep | dir;
590 return -1;
593 void usb_drv_release_endpoint(int ep)
595 if ((ep & 0x7f) == 0)
596 return;
597 endpoints[EP_NUM(ep)][EP_DIR(ep)].active = false;
600 void usb_drv_cancel_all_transfers()
602 cancel_all_transfers(false);
606 int usb_drv_send(int ep, void *ptr, int len)
608 ep = EP_NUM(ep);
609 struct ep_type *endpoint = &endpoints[ep][1];
610 endpoint->done = false;
611 ep_transfer(ep, ptr, len, false);
612 while (endpoint->busy && !endpoint->done)
613 semaphore_wait(&endpoint->complete, TIMEOUT_BLOCK);
614 return endpoint->status;