2 * Copyright (c) 2007-2008, Juniper Networks, Inc.
3 * Copyright (c) 2008, Excito Elektronik i Skåne AB
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2 of
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 #include <asm/byteorder.h>
30 struct ehci_hccr *hccr; /* R/O registers, not need for volatile */
31 volatile struct ehci_hcor *hcor;
33 static uint16_t portreset;
34 static struct QH qh_list __attribute__((aligned(32)));
36 static struct descriptor {
37 struct usb_hub_descriptor hub;
38 struct usb_device_descriptor device;
39 struct usb_linux_config_descriptor config;
40 struct usb_linux_interface_descriptor interface;
41 struct usb_endpoint_descriptor endpoint;
42 } __attribute__ ((packed)) descriptor = {
44 0x8, /* bDescLength */
45 0x29, /* bDescriptorType: hub descriptor */
46 2, /* bNrPorts -- runtime modified */
47 0, /* wHubCharacteristics */
48 0xff, /* bPwrOn2PwrGood */
49 0, /* bHubCntrCurrent */
50 {}, /* Device removable */
51 {} /* at most 7 ports! XXX */
55 1, /* bDescriptorType: UDESC_DEVICE */
56 0x0002, /* bcdUSB: v2.0 */
57 9, /* bDeviceClass: UDCLASS_HUB */
58 0, /* bDeviceSubClass: UDSUBCLASS_HUB */
59 1, /* bDeviceProtocol: UDPROTO_HSHUBSTT */
60 64, /* bMaxPacketSize: 64 bytes */
61 0x0000, /* idVendor */
62 0x0000, /* idProduct */
63 0x0001, /* bcdDevice */
64 1, /* iManufacturer */
66 0, /* iSerialNumber */
67 1 /* bNumConfigurations: 1 */
71 2, /* bDescriptorType: UDESC_CONFIG */
73 1, /* bNumInterface */
74 1, /* bConfigurationValue */
75 0, /* iConfiguration */
76 0x40, /* bmAttributes: UC_SELF_POWER */
81 4, /* bDescriptorType: UDESC_INTERFACE */
82 0, /* bInterfaceNumber */
83 0, /* bAlternateSetting */
84 1, /* bNumEndpoints */
85 9, /* bInterfaceClass: UICLASS_HUB */
86 0, /* bInterfaceSubClass: UISUBCLASS_HUB */
87 0, /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
92 5, /* bDescriptorType: UDESC_ENDPOINT */
93 0x81, /* bEndpointAddress:
94 * UE_DIR_IN | EHCI_INTR_ENDPT
96 3, /* bmAttributes: UE_INTERRUPT */
97 8, 0, /* wMaxPacketSize */
102 static void ehci_free (void *p, size_t sz)
106 static void *ehci_alloc(size_t sz, size_t align)
108 static struct QH qh __attribute__((aligned(32)));
109 static struct qTD td[3] __attribute__((aligned (32)));
114 case sizeof(struct QH):
118 case sizeof(struct qTD):
120 debug("out of TDs\n");
127 debug("unknown allocation size\n");
135 static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
137 uint32_t addr, delta, next;
140 addr = (uint32_t) buf;
143 td->qt_buffer[idx] = cpu_to_hc32(addr);
144 next = (addr + 4096) & ~4095;
154 debug("out of buffer pointers (%u bytes left)\n", sz);
162 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
163 int length, struct devrequest *req)
167 volatile struct qTD *vtd;
170 uint32_t endpt, token, usbsts;
174 debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
175 buffer, length, req);
177 debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n",
178 req->request, req->request,
179 req->requesttype, req->requesttype,
180 le16_to_cpu(req->value), le16_to_cpu(req->value),
181 le16_to_cpu(req->index));
183 qh = ehci_alloc(sizeof(struct QH), 32);
185 debug("unable to allocate QH\n");
188 qh->qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
189 c = (usb_pipespeed(pipe) != USB_SPEED_HIGH &&
190 usb_pipeendpoint(pipe) == 0) ? 1 : 0;
193 (usb_maxpacket(dev, pipe) << 16) |
196 (usb_pipespeed(pipe) << 12) |
197 (usb_pipeendpoint(pipe) << 8) |
198 (0 << 7) | (usb_pipedevice(pipe) << 0);
199 qh->qh_endpt1 = cpu_to_hc32(endpt);
201 (dev->portnr << 23) |
202 (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
203 qh->qh_endpt2 = cpu_to_hc32(endpt);
204 qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
205 qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
208 tdp = &qh->qh_overlay.qt_next;
211 usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
214 td = ehci_alloc(sizeof(struct qTD), 32);
216 debug("unable to allocate SETUP td\n");
219 td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
220 td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
222 (sizeof(*req) << 16) |
223 (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0);
224 td->qt_token = cpu_to_hc32(token);
225 if (ehci_td_buffer(td, req, sizeof(*req)) != 0) {
226 debug("unable construct SETUP td\n");
227 ehci_free(td, sizeof(*td));
230 *tdp = cpu_to_hc32((uint32_t) td);
235 if (length > 0 || req == NULL) {
236 td = ehci_alloc(sizeof(struct qTD), 32);
238 debug("unable to allocate DATA td\n");
241 td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
242 td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
243 token = (toggle << 31) |
245 ((req == NULL ? 1 : 0) << 15) |
248 ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0);
249 td->qt_token = cpu_to_hc32(token);
250 if (ehci_td_buffer(td, buffer, length) != 0) {
251 debug("unable construct DATA td\n");
252 ehci_free(td, sizeof(*td));
255 *tdp = cpu_to_hc32((uint32_t) td);
260 td = ehci_alloc(sizeof(struct qTD), 32);
262 debug("unable to allocate ACK td\n");
265 td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
266 td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
267 token = (toggle << 31) |
272 ((usb_pipein(pipe) ? 0 : 1) << 8) | (0x80 << 0);
273 td->qt_token = cpu_to_hc32(token);
274 *tdp = cpu_to_hc32((uint32_t) td);
278 qh_list.qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
280 usbsts = ehci_readl(hcor->or_usbsts);
281 ehci_writel(hcor->or_usbsts, (usbsts & 0x3f));
283 /* Enable async. schedule. */
284 cmd = ehci_readl(hcor->or_usbcmd);
285 hcor->or_usbcmd |= CMD_ASE;
286 ehci_writel(hcor->or_usbcmd, cmd);
288 while ((ehci_readl(hcor->or_usbsts) & STD_ASS) == 0)
291 /* Wait for TDs to be processed. */
295 token = hc32_to_cpu(vtd->qt_token);
298 } while (get_timer(ts) < CONFIG_SYS_HZ);
300 /* Disable async schedule. */
301 cmd = ehci_readl(hcor->or_usbcmd);
303 ehci_writel(hcor->or_usbcmd, cmd);
304 while ((ehci_readl(hcor->or_usbsts) & STD_ASS) != 0)
307 qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
309 token = hc32_to_cpu(qh->qh_overlay.qt_token);
310 if (!(token & 0x80)) {
311 debug("TOKEN=%#x\n", token);
312 switch (token & 0xfc) {
314 toggle = token >> 31;
315 usb_settoggle(dev, usb_pipeendpoint(pipe),
316 usb_pipeout(pipe), toggle);
320 dev->status = USB_ST_STALLED;
324 dev->status = USB_ST_BUF_ERR;
328 dev->status = USB_ST_BABBLE_DET;
331 dev->status = USB_ST_CRC_ERR;
334 dev->act_len = length - ((token >> 16) & 0x7fff);
337 debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
338 dev->devnum, ehci_readl(hcor->or_usbsts),
339 ehci_readl(hcor->or_portsc[0]),
340 ehci_readl(hcor->or_portsc[1]));
343 return (dev->status != USB_ST_NOT_PROC) ? 0 : -1;
346 td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
347 while (td != (void *)QT_NEXT_TERMINATE) {
348 qh->qh_overlay.qt_next = td->qt_next;
349 ehci_free(td, sizeof(*td));
350 td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
352 ehci_free(qh, sizeof(*qh));
356 static inline int min3(int a, int b, int c)
367 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
368 int length, struct devrequest *req)
378 debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
379 req->request, req->request,
380 req->requesttype, req->requesttype,
381 le16_to_cpu(req->value), le16_to_cpu(req->index));
383 typeReq = req->request << 8 | req->requesttype;
385 switch (le16_to_cpu(typeReq)) {
386 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
387 switch (le16_to_cpu(req->value) >> 8) {
389 debug("USB_DT_DEVICE request\n");
390 srcptr = &descriptor.device;
394 debug("USB_DT_CONFIG config\n");
395 srcptr = &descriptor.config;
399 debug("USB_DT_STRING config\n");
400 switch (le16_to_cpu(req->value) & 0xff) {
401 case 0: /* Language */
406 srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
409 case 2: /* Product */
410 srcptr = "\52\3E\0H\0C\0I\0 "
412 "\0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
416 debug("unknown value DT_STRING %x\n",
417 le16_to_cpu(req->value));
422 debug("unknown value %x\n", le16_to_cpu(req->value));
426 case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
427 switch (le16_to_cpu(req->value) >> 8) {
429 debug("USB_DT_HUB config\n");
430 srcptr = &descriptor.hub;
434 debug("unknown value %x\n", le16_to_cpu(req->value));
438 case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
439 debug("USB_REQ_SET_ADDRESS\n");
440 rootdev = le16_to_cpu(req->value);
442 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
443 debug("USB_REQ_SET_CONFIGURATION\n");
446 case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8):
447 tmpbuf[0] = 1; /* USB_STATUS_SELFPOWERED */
452 case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
453 memset(tmpbuf, 0, 4);
454 reg = ehci_readl(hcor->or_portsc[le16_to_cpu(req->index)
456 if (reg & EHCI_PS_CS)
457 tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
458 if (reg & EHCI_PS_PE)
459 tmpbuf[0] |= USB_PORT_STAT_ENABLE;
460 if (reg & EHCI_PS_SUSP)
461 tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
462 if (reg & EHCI_PS_OCA)
463 tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
464 if (reg & EHCI_PS_PR)
465 tmpbuf[0] |= USB_PORT_STAT_RESET;
466 if (reg & EHCI_PS_PP)
467 tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
468 tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
470 if (reg & EHCI_PS_CSC)
471 tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
472 if (reg & EHCI_PS_PEC)
473 tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
474 if (reg & EHCI_PS_OCC)
475 tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
476 if (portreset & (1 << le16_to_cpu(req->index)))
477 tmpbuf[2] |= USB_PORT_STAT_C_RESET;
481 case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
482 reg = ehci_readl(hcor->or_portsc[le16_to_cpu(req->index) - 1]);
483 reg &= ~EHCI_PS_CLEAR;
484 switch (le16_to_cpu(req->value)) {
485 case USB_PORT_FEAT_POWER:
488 case USB_PORT_FEAT_RESET:
489 debug("USB FEAT RESET\n");
490 if (EHCI_PS_IS_LOWSPEED(reg)) {
491 /* Low speed device, give up ownership. */
495 /* Start reset sequence. */
498 ehci_writel(hcor->or_portsc[
499 le16_to_cpu(req->index) - 1], reg);
500 /* Wait for reset to complete. */
502 /* Terminate reset sequence. */
504 /* TODO: is it only fsl chip that requires this
505 * manual setting of port enable?
508 ehci_writel(hcor->or_portsc[
509 le16_to_cpu(req->index) - 1], reg);
510 /* Wait for HC to complete reset. */
513 ehci_readl(hcor->or_portsc[le16_to_cpu(req->index)
515 reg &= ~EHCI_PS_CLEAR;
516 if ((reg & EHCI_PS_PE) == 0) {
517 /* Not a high speed device, give up
522 portreset |= 1 << le16_to_cpu(req->index);
525 debug("unknown feature %x\n", le16_to_cpu(req->value));
528 ehci_writel(hcor->or_portsc[le16_to_cpu(req->index) - 1], reg);
530 case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
531 reg = ehci_readl(hcor->or_portsc[le16_to_cpu(req->index) - 1]);
532 reg &= ~EHCI_PS_CLEAR;
533 switch (le16_to_cpu(req->value)) {
534 case USB_PORT_FEAT_ENABLE:
537 case USB_PORT_FEAT_C_CONNECTION:
540 case USB_PORT_FEAT_C_RESET:
541 portreset &= ~(1 << le16_to_cpu(req->index));
544 debug("unknown feature %x\n", le16_to_cpu(req->value));
547 ehci_writel(hcor->or_portsc[le16_to_cpu(req->index) - 1], reg);
550 debug("Unknown request\n");
555 len = min3(srclen, le16_to_cpu(req->length), length);
556 if (srcptr != NULL && len > 0)
557 memcpy(buffer, srcptr, len);
566 debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x\n",
567 req->requesttype, req->request, le16_to_cpu(req->value),
568 le16_to_cpu(req->index), le16_to_cpu(req->length));
571 dev->status = USB_ST_STALLED;
575 int usb_lowlevel_stop(void)
577 return ehci_hcd_stop();
580 int usb_lowlevel_init(void)
585 if (ehci_hcd_init() != 0)
588 /* Set head of reclaim list */
589 memset(&qh_list, 0, sizeof(qh_list));
590 qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
591 qh_list.qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
592 qh_list.qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
593 qh_list.qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
594 qh_list.qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
595 qh_list.qh_overlay.qt_token = cpu_to_hc32(0x40);
597 /* Set async. queue head pointer. */
598 ehci_writel(hcor->or_asynclistaddr, (uint32_t)&qh_list);
600 reg = ehci_readl(hccr->cr_hcsparams);
601 descriptor.hub.bNbrPorts = reg & 0xf;
602 printf("NbrPorts %x\n", descriptor.hub.bNbrPorts);
603 if (reg & 0x10000) /* Port Indicators */
604 descriptor.hub.wHubCharacteristics |= 0x80;
605 if (reg & 0x10) /* Port Power Control */
606 descriptor.hub.wHubCharacteristics |= 0x01;
608 /* take control over the ports */
609 cmd = ehci_readl(hcor->or_configflag);
611 ehci_writel(hcor->or_configflag, cmd);
613 /* Start the host controller. */
614 cmd = ehci_readl(hcor->or_configflag);
616 ehci_writel(hcor->or_usbcmd, cmd);
624 submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
628 if (usb_pipetype(pipe) != PIPE_BULK) {
629 debug("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
632 return ehci_submit_async(dev, pipe, buffer, length, NULL);
636 submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
637 int length, struct devrequest *setup)
640 if (usb_pipetype(pipe) != PIPE_CONTROL) {
641 debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
645 if (usb_pipedevice(pipe) == rootdev) {
647 dev->speed = USB_SPEED_HIGH;
648 return ehci_submit_root(dev, pipe, buffer, length, setup);
650 return ehci_submit_async(dev, pipe, buffer, length, setup);
654 submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
655 int length, int interval)
658 debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
659 dev, pipe, buffer, length, interval);