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,
28 struct ehci_hccr *hccr; /* R/O registers, not need for volatile */
29 volatile struct ehci_hcor *hcor;
31 static uint16_t portreset;
32 static struct QH qh_list __attribute__((aligned(32)));
34 struct usb_device_descriptor device = {
35 sizeof(struct usb_device_descriptor), /* bLength */
36 1, /* bDescriptorType: UDESC_DEVICE */
37 0x0002, /* bcdUSB: v2.0 */
38 9, /* bDeviceClass: UDCLASS_HUB */
39 0, /* bDeviceSubClass: UDSUBCLASS_HUB */
40 1, /* bDeviceProtocol: UDPROTO_HSHUBSTT */
41 64, /* bMaxPacketSize: 64 bytes */
42 0x0000, /* idVendor */
43 0x0000, /* idProduct */
44 0x0001, /* bcdDevice */
45 1, /* iManufacturer */
47 0, /* iSerialNumber */
48 1 /* bNumConfigurations: 1 */
51 struct usb_config_descriptor config = {
52 sizeof(struct usb_config_descriptor),
53 2, /* bDescriptorType: UDESC_CONFIG */
54 sizeof(struct usb_config_descriptor) +
55 sizeof(struct usb_interface_descriptor) +
56 sizeof(struct usb_endpoint_descriptor),
58 1, /* bNumInterface */
59 1, /* bConfigurationValue */
60 0, /* iConfiguration */
61 0x40, /* bmAttributes: UC_SELF_POWER */
65 struct usb_interface_descriptor interface = {
66 sizeof(struct usb_interface_descriptor), /* bLength */
67 4, /* bDescriptorType: UDESC_INTERFACE */
68 0, /* bInterfaceNumber */
69 0, /* bAlternateSetting */
70 1, /* bNumEndpoints */
71 9, /* bInterfaceClass: UICLASS_HUB */
72 0, /* bInterfaceSubClass: UISUBCLASS_HUB */
73 0, /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
77 struct usb_endpoint_descriptor endpoint = {
78 sizeof(struct usb_endpoint_descriptor), /* bLength */
79 5, /* bDescriptorType: UDESC_ENDPOINT */
80 0x81, /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
81 3, /* bmAttributes: UE_INTERRUPT */
82 8, 0, /* wMaxPacketSize */
86 struct usb_hub_descriptor hub = {
87 sizeof(struct usb_hub_descriptor), /* bDescLength */
88 0x29, /* bDescriptorType: hub descriptor */
89 2, /* bNrPorts -- runtime modified */
90 0, 0, /* wHubCharacteristics */
91 0xff, /* bPwrOn2PwrGood */
92 {}, /* bHubCntrCurrent */
93 {} /* at most 7 ports! XXX */
96 static void *ehci_alloc(size_t sz, size_t align)
98 static struct QH qh __attribute__((aligned(32)));
99 static struct qTD td[3] __attribute__((aligned (32)));
104 case sizeof(struct QH):
108 case sizeof(struct qTD):
117 debug("unknown allocation size");
125 static void ehci_free(void *p, size_t sz)
129 static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
131 uint32_t addr, delta, next;
134 addr = (uint32_t) buf;
137 td->qt_buffer[idx] = cpu_to_le32(addr);
138 next = (addr + 4096) & ~4095;
148 debug("out of buffer pointers (%u bytes left)", sz);
156 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
157 int length, struct devrequest *req)
161 volatile struct qTD *vtd;
164 uint32_t endpt, token, usbsts;
167 debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p", dev, pipe,
168 buffer, length, req);
170 debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u",
171 req->request, req->request,
172 req->requesttype, req->requesttype,
173 le16_to_cpu(req->value), le16_to_cpu(req->value),
174 le16_to_cpu(req->index), le16_to_cpu(req->index));
176 qh = ehci_alloc(sizeof(struct QH), 32);
178 debug("unable to allocate QH");
181 qh->qh_link = cpu_to_le32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
182 c = (usb_pipespeed(pipe) != USB_SPEED_HIGH &&
183 usb_pipeendpoint(pipe) == 0) ? 1 : 0;
186 (usb_maxpacket(dev, pipe) << 16) |
189 (usb_pipespeed(pipe) << 12) |
190 (usb_pipeendpoint(pipe) << 8) |
191 (0 << 7) | (usb_pipedevice(pipe) << 0);
192 qh->qh_endpt1 = cpu_to_le32(endpt);
194 (dev->portnr << 23) |
195 (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
196 qh->qh_endpt2 = cpu_to_le32(endpt);
197 qh->qh_overlay.qt_next = cpu_to_le32(QT_NEXT_TERMINATE);
198 qh->qh_overlay.qt_altnext = cpu_to_le32(QT_NEXT_TERMINATE);
201 tdp = &qh->qh_overlay.qt_next;
204 usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
207 td = ehci_alloc(sizeof(struct qTD), 32);
209 debug("unable to allocate SETUP td");
212 td->qt_next = cpu_to_le32(QT_NEXT_TERMINATE);
213 td->qt_altnext = cpu_to_le32(QT_NEXT_TERMINATE);
215 (sizeof(*req) << 16) |
216 (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0);
217 td->qt_token = cpu_to_le32(token);
218 if (ehci_td_buffer(td, req, sizeof(*req)) != 0) {
219 debug("unable construct SETUP td");
220 ehci_free(td, sizeof(*td));
223 *tdp = cpu_to_le32((uint32_t) td);
228 if (length > 0 || req == NULL) {
229 td = ehci_alloc(sizeof(struct qTD), 32);
231 debug("unable to allocate DATA td");
234 td->qt_next = cpu_to_le32(QT_NEXT_TERMINATE);
235 td->qt_altnext = cpu_to_le32(QT_NEXT_TERMINATE);
236 token = (toggle << 31) |
238 ((req == NULL ? 1 : 0) << 15) |
241 ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0);
242 td->qt_token = cpu_to_le32(token);
243 if (ehci_td_buffer(td, buffer, length) != 0) {
244 debug("unable construct DATA td");
245 ehci_free(td, sizeof(*td));
248 *tdp = cpu_to_le32((uint32_t) td);
253 td = ehci_alloc(sizeof(struct qTD), 32);
255 debug("unable to allocate ACK td");
258 td->qt_next = cpu_to_le32(QT_NEXT_TERMINATE);
259 td->qt_altnext = cpu_to_le32(QT_NEXT_TERMINATE);
260 token = (toggle << 31) |
265 ((usb_pipein(pipe) ? 0 : 1) << 8) | (0x80 << 0);
266 td->qt_token = cpu_to_le32(token);
267 *tdp = cpu_to_le32((uint32_t) td);
271 qh_list.qh_link = cpu_to_le32((uint32_t) qh | QH_LINK_TYPE_QH);
273 usbsts = le32_to_cpu(hcor->or_usbsts);
274 hcor->or_usbsts = cpu_to_le32(usbsts & 0x3f);
276 /* Enable async. schedule. */
277 hcor->or_usbcmd |= cpu_to_le32(0x20);
278 while ((hcor->or_usbsts & cpu_to_le32(0x8000)) == 0)
281 /* Wait for TDs to be processed. */
285 token = le32_to_cpu(vtd->qt_token);
288 } while (get_timer(ts) < CONFIG_SYS_HZ);
290 /* Disable async schedule. */
291 hcor->or_usbcmd &= ~cpu_to_le32(0x20);
292 while ((hcor->or_usbsts & cpu_to_le32(0x8000)) != 0)
295 qh_list.qh_link = cpu_to_le32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
297 token = le32_to_cpu(qh->qh_overlay.qt_token);
298 if (!(token & 0x80)) {
299 debug("TOKEN=%#x", token);
300 switch (token & 0xfc) {
302 toggle = token >> 31;
303 usb_settoggle(dev, usb_pipeendpoint(pipe),
304 usb_pipeout(pipe), toggle);
308 dev->status = USB_ST_STALLED;
312 dev->status = USB_ST_BUF_ERR;
316 dev->status = USB_ST_BABBLE_DET;
319 dev->status = USB_ST_CRC_ERR;
322 dev->act_len = length - ((token >> 16) & 0x7fff);
325 debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x",
326 dev->devnum, le32_to_cpu(hcor->or_usbsts),
327 le32_to_cpu(hcor->or_portsc[0]),
328 le32_to_cpu(hcor->or_portsc[1]));
331 return (dev->status != USB_ST_NOT_PROC) ? 0 : -1;
334 td = (void *)le32_to_cpu(qh->qh_overlay.qt_next);
335 while (td != (void *)QT_NEXT_TERMINATE) {
336 qh->qh_overlay.qt_next = td->qt_next;
337 ehci_free(td, sizeof(*td));
338 td = (void *)le32_to_cpu(qh->qh_overlay.qt_next);
340 ehci_free(qh, sizeof(*qh));
344 static inline int min3(int a, int b, int c)
354 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
355 int length, struct devrequest *req)
366 debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
367 req->request, req->request,
368 req->requesttype, req->requesttype,
369 le16_to_cpu(req->value), le16_to_cpu(req->index));
371 typeReq = req->request << 8 | req->requesttype;
374 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
375 switch (le16_to_cpu(req->value) >> 8) {
378 srclen = sizeof(struct usb_device_descriptor);
382 srclen = sizeof(config) +
383 sizeof(struct usb_interface_descriptor) +
384 sizeof(struct usb_hub_descriptor);
387 switch (le16_to_cpu(req->value) & 0xff) {
388 case 0: /* Language */
393 srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
396 case 2: /* Product */
397 srcptr = "\52\3E\0H\0C\0I\0 "
399 "\0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
407 debug("unknown value %x", le16_to_cpu(req->value));
411 case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
412 switch (le16_to_cpu(req->value) >> 8) {
415 srclen = sizeof(hub);
418 debug("unknown value %x", le16_to_cpu(req->value));
422 case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
423 rootdev = le16_to_cpu(req->value);
425 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
428 case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8):
429 tmpbuf[0] = 1; /* USB_STATUS_SELFPOWERED */
434 case DeviceRequest | USB_REQ_GET_STATUS:
435 memset(tmpbuf, 0, 4);
436 reg = le32_to_cpu(hcor->or_portsc[le16_to_cpu(req->index)
438 if (reg & EHCI_PS_CS)
439 tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
440 if (reg & EHCI_PS_PE)
441 tmpbuf[0] |= USB_PORT_STAT_ENABLE;
442 if (reg & EHCI_PS_SUSP)
443 tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
444 if (reg & EHCI_PS_OCA)
445 tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
446 if (reg & EHCI_PS_PR)
447 tmpbuf[0] |= USB_PORT_STAT_RESET;
448 if (reg & EHCI_PS_PP)
449 tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
450 tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
452 if (reg & EHCI_PS_CSC)
453 tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
454 if (reg & EHCI_PS_PEC)
455 tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
456 if (reg & EHCI_PS_OCC)
457 tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
458 if (portreset & (1 << le16_to_cpu(req->index)))
459 tmpbuf[2] |= USB_PORT_STAT_C_RESET;
463 case DeviceOutRequest | USB_REQ_SET_FEATURE:
464 reg = le32_to_cpu(hcor->or_portsc[le16_to_cpu(req->index) - 1]);
465 reg &= ~EHCI_PS_CLEAR;
466 switch (le16_to_cpu(req->value)) {
467 case USB_PORT_FEAT_POWER:
470 case USB_PORT_FEAT_RESET:
471 if (EHCI_PS_IS_LOWSPEED(reg)) {
472 /* Low speed device, give up ownership. */
476 /* Start reset sequence. */
479 hcor->or_portsc[le16_to_cpu(req->index) - 1] =
481 /* Wait for reset to complete. */
483 /* Terminate reset sequence. */
485 /* TODO: is it only fsl chip that requires this
486 * manual setting of port enable?
489 hcor->or_portsc[le16_to_cpu(req->index) - 1] =
491 /* Wait for HC to complete reset. */
494 le32_to_cpu(hcor->or_portsc[le16_to_cpu(req->index)
496 reg &= ~EHCI_PS_CLEAR;
497 if ((reg & EHCI_PS_PE) == 0) {
498 /* Not a high speed device, give up
503 portreset |= 1 << le16_to_cpu(req->index);
506 debug("unknown feature %x", le16_to_cpu(req->value));
509 hcor->or_portsc[le16_to_cpu(req->index) - 1] =
512 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
513 reg = le32_to_cpu(hcor->or_portsc[le16_to_cpu(req->index) - 1]);
514 reg &= ~EHCI_PS_CLEAR;
515 switch (le16_to_cpu(req->value)) {
516 case USB_PORT_FEAT_ENABLE:
519 case USB_PORT_FEAT_C_CONNECTION:
522 case USB_PORT_FEAT_C_RESET:
523 portreset &= ~(1 << le16_to_cpu(req->index));
526 debug("unknown feature %x", le16_to_cpu(req->value));
529 hcor->or_portsc[le16_to_cpu(req->index) - 1] =
533 debug("Unknown request");
537 len = min3(srclen, le16_to_cpu(req->length), length);
538 if (srcptr != NULL && len > 0)
539 memcpy(buffer, srcptr, len);
545 debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x",
546 req->requesttype, req->request, le16_to_cpu(req->value),
547 le16_to_cpu(req->index), le16_to_cpu(req->length));
550 dev->status = USB_ST_STALLED;
554 int usb_lowlevel_stop(void)
556 return ehci_hcd_stop();
559 int usb_lowlevel_init(void)
563 if (ehci_hcd_init() != 0)
566 /* Set head of reclaim list */
567 memset(&qh_list, 0, sizeof(qh_list));
568 qh_list.qh_link = cpu_to_le32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
569 qh_list.qh_endpt1 = cpu_to_le32((1 << 15) | (USB_SPEED_HIGH << 12));
570 qh_list.qh_curtd = cpu_to_le32(QT_NEXT_TERMINATE);
571 qh_list.qh_overlay.qt_next = cpu_to_le32(QT_NEXT_TERMINATE);
572 qh_list.qh_overlay.qt_altnext = cpu_to_le32(QT_NEXT_TERMINATE);
573 qh_list.qh_overlay.qt_token = cpu_to_le32(0x40);
575 /* Set async. queue head pointer. */
576 hcor->or_asynclistaddr = cpu_to_le32((uint32_t)&qh_list);
578 reg = le32_to_cpu(hccr->cr_hcsparams);
579 hub.bNbrPorts = reg & 0xf;
580 if (reg & 0x10000) /* Port Indicators */
581 hub.wHubCharacteristics |= 0x80;
582 if (reg & 0x10) /* Port Power Control */
583 hub.wHubCharacteristics |= 0x01;
585 /* take control over the ports */
586 hcor->or_configflag |= cpu_to_le32(1);
588 /* Start the host controller. */
589 hcor->or_usbcmd |= cpu_to_le32(1);
597 submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
601 if (usb_pipetype(pipe) != PIPE_BULK) {
602 debug("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
605 return ehci_submit_async(dev, pipe, buffer, length, NULL);
609 submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
610 int length, struct devrequest *setup)
613 if (usb_pipetype(pipe) != PIPE_CONTROL) {
614 debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
618 if (usb_pipedevice(pipe) == rootdev) {
620 dev->speed = USB_SPEED_HIGH;
621 return ehci_submit_root(dev, pipe, buffer, length, setup);
623 return ehci_submit_async(dev, pipe, buffer, length, setup);
627 submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
628 int length, int interval)
631 debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
632 dev, pipe, buffer, length, interval);