]> git.sur5r.net Git - u-boot/blob - drivers/usb/host/ehci-hcd.c
USB: Drop cache flush bloat in EHCI-HCD
[u-boot] / drivers / usb / host / ehci-hcd.c
1 /*-
2  * Copyright (c) 2007-2008, Juniper Networks, Inc.
3  * Copyright (c) 2008, Excito Elektronik i Skåne AB
4  * Copyright (c) 2008, Michael Trimarchi <trimarchimichael@yahoo.it>
5  *
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation version 2 of
11  * the License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 #include <common.h>
24 #include <asm/byteorder.h>
25 #include <usb.h>
26 #include <asm/io.h>
27 #include <malloc.h>
28 #include <watchdog.h>
29
30 #include "ehci.h"
31
32 int rootdev;
33 struct ehci_hccr *hccr; /* R/O registers, not need for volatile */
34 volatile struct ehci_hcor *hcor;
35
36 static uint16_t portreset;
37 static struct QH qh_list __attribute__((aligned(32)));
38
39 static struct descriptor {
40         struct usb_hub_descriptor hub;
41         struct usb_device_descriptor device;
42         struct usb_linux_config_descriptor config;
43         struct usb_linux_interface_descriptor interface;
44         struct usb_endpoint_descriptor endpoint;
45 }  __attribute__ ((packed)) descriptor = {
46         {
47                 0x8,            /* bDescLength */
48                 0x29,           /* bDescriptorType: hub descriptor */
49                 2,              /* bNrPorts -- runtime modified */
50                 0,              /* wHubCharacteristics */
51                 10,             /* bPwrOn2PwrGood */
52                 0,              /* bHubCntrCurrent */
53                 {},             /* Device removable */
54                 {}              /* at most 7 ports! XXX */
55         },
56         {
57                 0x12,           /* bLength */
58                 1,              /* bDescriptorType: UDESC_DEVICE */
59                 cpu_to_le16(0x0200), /* bcdUSB: v2.0 */
60                 9,              /* bDeviceClass: UDCLASS_HUB */
61                 0,              /* bDeviceSubClass: UDSUBCLASS_HUB */
62                 1,              /* bDeviceProtocol: UDPROTO_HSHUBSTT */
63                 64,             /* bMaxPacketSize: 64 bytes */
64                 0x0000,         /* idVendor */
65                 0x0000,         /* idProduct */
66                 cpu_to_le16(0x0100), /* bcdDevice */
67                 1,              /* iManufacturer */
68                 2,              /* iProduct */
69                 0,              /* iSerialNumber */
70                 1               /* bNumConfigurations: 1 */
71         },
72         {
73                 0x9,
74                 2,              /* bDescriptorType: UDESC_CONFIG */
75                 cpu_to_le16(0x19),
76                 1,              /* bNumInterface */
77                 1,              /* bConfigurationValue */
78                 0,              /* iConfiguration */
79                 0x40,           /* bmAttributes: UC_SELF_POWER */
80                 0               /* bMaxPower */
81         },
82         {
83                 0x9,            /* bLength */
84                 4,              /* bDescriptorType: UDESC_INTERFACE */
85                 0,              /* bInterfaceNumber */
86                 0,              /* bAlternateSetting */
87                 1,              /* bNumEndpoints */
88                 9,              /* bInterfaceClass: UICLASS_HUB */
89                 0,              /* bInterfaceSubClass: UISUBCLASS_HUB */
90                 0,              /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
91                 0               /* iInterface */
92         },
93         {
94                 0x7,            /* bLength */
95                 5,              /* bDescriptorType: UDESC_ENDPOINT */
96                 0x81,           /* bEndpointAddress:
97                                  * UE_DIR_IN | EHCI_INTR_ENDPT
98                                  */
99                 3,              /* bmAttributes: UE_INTERRUPT */
100                 8,              /* wMaxPacketSize */
101                 255             /* bInterval */
102         },
103 };
104
105 #if defined(CONFIG_EHCI_IS_TDI)
106 #define ehci_is_TDI()   (1)
107 #else
108 #define ehci_is_TDI()   (0)
109 #endif
110
111 void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
112 {
113         mdelay(50);
114 }
115
116 void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
117         __attribute__((weak, alias("__ehci_powerup_fixup")));
118
119 static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
120 {
121         uint32_t result;
122         do {
123                 result = ehci_readl(ptr);
124                 udelay(5);
125                 if (result == ~(uint32_t)0)
126                         return -1;
127                 result &= mask;
128                 if (result == done)
129                         return 0;
130                 usec--;
131         } while (usec > 0);
132         return -1;
133 }
134
135 static int ehci_reset(void)
136 {
137         uint32_t cmd;
138         uint32_t tmp;
139         uint32_t *reg_ptr;
140         int ret = 0;
141
142         cmd = ehci_readl(&hcor->or_usbcmd);
143         cmd = (cmd & ~CMD_RUN) | CMD_RESET;
144         ehci_writel(&hcor->or_usbcmd, cmd);
145         ret = handshake((uint32_t *)&hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000);
146         if (ret < 0) {
147                 printf("EHCI fail to reset\n");
148                 goto out;
149         }
150
151         if (ehci_is_TDI()) {
152                 reg_ptr = (uint32_t *)((u8 *)hcor + USBMODE);
153                 tmp = ehci_readl(reg_ptr);
154                 tmp |= USBMODE_CM_HC;
155 #if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
156                 tmp |= USBMODE_BE;
157 #endif
158                 ehci_writel(reg_ptr, tmp);
159         }
160
161 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
162         cmd = ehci_readl(&hcor->or_txfilltuning);
163         cmd &= ~TXFIFO_THRESH(0x3f);
164         cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH);
165         ehci_writel(&hcor->or_txfilltuning, cmd);
166 #endif
167 out:
168         return ret;
169 }
170
171 static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
172 {
173         uint32_t delta, next;
174         uint32_t addr = (uint32_t)buf;
175         size_t rsz = roundup(sz, 32);
176         int idx;
177
178         if (sz != rsz)
179                 debug("EHCI-HCD: Misaligned buffer size (%08x)\n", sz);
180
181         if (addr & 31)
182                 debug("EHCI-HCD: Misaligned buffer address (%p)\n", buf);
183
184         idx = 0;
185         while (idx < 5) {
186                 flush_dcache_range(addr, addr + rsz);
187                 td->qt_buffer[idx] = cpu_to_hc32(addr);
188                 td->qt_buffer_hi[idx] = 0;
189                 next = (addr + 4096) & ~4095;
190                 delta = next - addr;
191                 if (delta >= sz)
192                         break;
193                 sz -= delta;
194                 addr = next;
195                 idx++;
196         }
197
198         if (idx == 5) {
199                 debug("out of buffer pointers (%u bytes left)\n", sz);
200                 return -1;
201         }
202
203         return 0;
204 }
205
206 static int
207 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
208                    int length, struct devrequest *req)
209 {
210         static struct QH qh __attribute__((aligned(32)));
211         static struct qTD qtd[3] __attribute__((aligned (32)));
212         int qtd_counter = 0;
213
214         volatile struct qTD *vtd;
215         unsigned long ts;
216         uint32_t *tdp;
217         uint32_t endpt, token, usbsts;
218         uint32_t c, toggle;
219         uint32_t cmd;
220         int timeout;
221         int ret = 0;
222
223         debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
224               buffer, length, req);
225         if (req != NULL)
226                 debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n",
227                       req->request, req->request,
228                       req->requesttype, req->requesttype,
229                       le16_to_cpu(req->value), le16_to_cpu(req->value),
230                       le16_to_cpu(req->index));
231
232         memset(&qh, 0, sizeof(struct QH));
233         memset(qtd, 0, sizeof(qtd));
234
235         toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
236
237         qh.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
238         c = (usb_pipespeed(pipe) != USB_SPEED_HIGH &&
239              usb_pipeendpoint(pipe) == 0) ? 1 : 0;
240         endpt = (8 << 28) |
241             (c << 27) |
242             (usb_maxpacket(dev, pipe) << 16) |
243             (0 << 15) |
244             (1 << 14) |
245             (usb_pipespeed(pipe) << 12) |
246             (usb_pipeendpoint(pipe) << 8) |
247             (0 << 7) | (usb_pipedevice(pipe) << 0);
248         qh.qh_endpt1 = cpu_to_hc32(endpt);
249         endpt = (1 << 30) |
250             (dev->portnr << 23) |
251             (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
252         qh.qh_endpt2 = cpu_to_hc32(endpt);
253         qh.qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
254
255         tdp = &qh.qh_overlay.qt_next;
256
257         if (req != NULL) {
258                 qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
259                 qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
260                 token = (0 << 31) |
261                     (sizeof(*req) << 16) |
262                     (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0);
263                 qtd[qtd_counter].qt_token = cpu_to_hc32(token);
264                 if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req)) != 0) {
265                         debug("unable construct SETUP td\n");
266                         goto fail;
267                 }
268                 *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
269                 tdp = &qtd[qtd_counter++].qt_next;
270                 toggle = 1;
271         }
272
273         if (length > 0 || req == NULL) {
274                 qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
275                 qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
276                 token = (toggle << 31) |
277                     (length << 16) |
278                     ((req == NULL ? 1 : 0) << 15) |
279                     (0 << 12) |
280                     (3 << 10) |
281                     ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0);
282                 qtd[qtd_counter].qt_token = cpu_to_hc32(token);
283                 if (ehci_td_buffer(&qtd[qtd_counter], buffer, length) != 0) {
284                         debug("unable construct DATA td\n");
285                         goto fail;
286                 }
287                 *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
288                 tdp = &qtd[qtd_counter++].qt_next;
289         }
290
291         if (req != NULL) {
292                 qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
293                 qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
294                 token = (toggle << 31) |
295                     (0 << 16) |
296                     (1 << 15) |
297                     (0 << 12) |
298                     (3 << 10) |
299                     ((usb_pipein(pipe) ? 0 : 1) << 8) | (0x80 << 0);
300                 qtd[qtd_counter].qt_token = cpu_to_hc32(token);
301                 *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
302                 tdp = &qtd[qtd_counter++].qt_next;
303         }
304
305         qh_list.qh_link = cpu_to_hc32((uint32_t)&qh | QH_LINK_TYPE_QH);
306
307         /* Flush dcache */
308         flush_dcache_range((uint32_t)&qh_list,
309                 (uint32_t)&qh_list + sizeof(struct QH));
310         flush_dcache_range((uint32_t)&qh, (uint32_t)&qh + sizeof(struct QH));
311         flush_dcache_range((uint32_t)qtd, (uint32_t)qtd + sizeof(qtd));
312
313         usbsts = ehci_readl(&hcor->or_usbsts);
314         ehci_writel(&hcor->or_usbsts, (usbsts & 0x3f));
315
316         /* Enable async. schedule. */
317         cmd = ehci_readl(&hcor->or_usbcmd);
318         cmd |= CMD_ASE;
319         ehci_writel(&hcor->or_usbcmd, cmd);
320
321         ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, STD_ASS,
322                         100 * 1000);
323         if (ret < 0) {
324                 printf("EHCI fail timeout STD_ASS set\n");
325                 goto fail;
326         }
327
328         /* Wait for TDs to be processed. */
329         ts = get_timer(0);
330         vtd = &qtd[qtd_counter - 1];
331         timeout = USB_TIMEOUT_MS(pipe);
332         do {
333                 /* Invalidate dcache */
334                 invalidate_dcache_range((uint32_t)&qh_list,
335                         (uint32_t)&qh_list + sizeof(struct QH));
336                 invalidate_dcache_range((uint32_t)&qh,
337                         (uint32_t)&qh + sizeof(struct QH));
338                 invalidate_dcache_range((uint32_t)qtd,
339                         (uint32_t)qtd + sizeof(qtd));
340
341                 token = hc32_to_cpu(vtd->qt_token);
342                 if (!(token & 0x80))
343                         break;
344                 WATCHDOG_RESET();
345         } while (get_timer(ts) < timeout);
346
347         /* Invalidate the memory area occupied by buffer */
348         invalidate_dcache_range(((uint32_t)buffer & ~31),
349                 ((uint32_t)buffer & ~31) + roundup(length, 32));
350
351         /* Check that the TD processing happened */
352         if (token & 0x80) {
353                 printf("EHCI timed out on TD - token=%#x\n", token);
354         }
355
356         /* Disable async schedule. */
357         cmd = ehci_readl(&hcor->or_usbcmd);
358         cmd &= ~CMD_ASE;
359         ehci_writel(&hcor->or_usbcmd, cmd);
360
361         ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, 0,
362                         100 * 1000);
363         if (ret < 0) {
364                 printf("EHCI fail timeout STD_ASS reset\n");
365                 goto fail;
366         }
367
368         qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
369
370         token = hc32_to_cpu(qh.qh_overlay.qt_token);
371         if (!(token & 0x80)) {
372                 debug("TOKEN=%#x\n", token);
373                 switch (token & 0xfc) {
374                 case 0:
375                         toggle = token >> 31;
376                         usb_settoggle(dev, usb_pipeendpoint(pipe),
377                                        usb_pipeout(pipe), toggle);
378                         dev->status = 0;
379                         break;
380                 case 0x40:
381                         dev->status = USB_ST_STALLED;
382                         break;
383                 case 0xa0:
384                 case 0x20:
385                         dev->status = USB_ST_BUF_ERR;
386                         break;
387                 case 0x50:
388                 case 0x10:
389                         dev->status = USB_ST_BABBLE_DET;
390                         break;
391                 default:
392                         dev->status = USB_ST_CRC_ERR;
393                         if ((token & 0x40) == 0x40)
394                                 dev->status |= USB_ST_STALLED;
395                         break;
396                 }
397                 dev->act_len = length - ((token >> 16) & 0x7fff);
398         } else {
399                 dev->act_len = 0;
400                 debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
401                       dev->devnum, ehci_readl(&hcor->or_usbsts),
402                       ehci_readl(&hcor->or_portsc[0]),
403                       ehci_readl(&hcor->or_portsc[1]));
404         }
405
406         return (dev->status != USB_ST_NOT_PROC) ? 0 : -1;
407
408 fail:
409         return -1;
410 }
411
412 static inline int min3(int a, int b, int c)
413 {
414
415         if (b < a)
416                 a = b;
417         if (c < a)
418                 a = c;
419         return a;
420 }
421
422 int
423 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
424                  int length, struct devrequest *req)
425 {
426         uint8_t tmpbuf[4];
427         u16 typeReq;
428         void *srcptr = NULL;
429         int len, srclen;
430         uint32_t reg;
431         uint32_t *status_reg;
432
433         if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
434                 printf("The request port(%d) is not configured\n",
435                         le16_to_cpu(req->index) - 1);
436                 return -1;
437         }
438         status_reg = (uint32_t *)&hcor->or_portsc[
439                                                 le16_to_cpu(req->index) - 1];
440         srclen = 0;
441
442         debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
443               req->request, req->request,
444               req->requesttype, req->requesttype,
445               le16_to_cpu(req->value), le16_to_cpu(req->index));
446
447         typeReq = req->request | req->requesttype << 8;
448
449         switch (typeReq) {
450         case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
451                 switch (le16_to_cpu(req->value) >> 8) {
452                 case USB_DT_DEVICE:
453                         debug("USB_DT_DEVICE request\n");
454                         srcptr = &descriptor.device;
455                         srclen = 0x12;
456                         break;
457                 case USB_DT_CONFIG:
458                         debug("USB_DT_CONFIG config\n");
459                         srcptr = &descriptor.config;
460                         srclen = 0x19;
461                         break;
462                 case USB_DT_STRING:
463                         debug("USB_DT_STRING config\n");
464                         switch (le16_to_cpu(req->value) & 0xff) {
465                         case 0: /* Language */
466                                 srcptr = "\4\3\1\0";
467                                 srclen = 4;
468                                 break;
469                         case 1: /* Vendor */
470                                 srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
471                                 srclen = 14;
472                                 break;
473                         case 2: /* Product */
474                                 srcptr = "\52\3E\0H\0C\0I\0 "
475                                          "\0H\0o\0s\0t\0 "
476                                          "\0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
477                                 srclen = 42;
478                                 break;
479                         default:
480                                 debug("unknown value DT_STRING %x\n",
481                                         le16_to_cpu(req->value));
482                                 goto unknown;
483                         }
484                         break;
485                 default:
486                         debug("unknown value %x\n", le16_to_cpu(req->value));
487                         goto unknown;
488                 }
489                 break;
490         case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
491                 switch (le16_to_cpu(req->value) >> 8) {
492                 case USB_DT_HUB:
493                         debug("USB_DT_HUB config\n");
494                         srcptr = &descriptor.hub;
495                         srclen = 0x8;
496                         break;
497                 default:
498                         debug("unknown value %x\n", le16_to_cpu(req->value));
499                         goto unknown;
500                 }
501                 break;
502         case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
503                 debug("USB_REQ_SET_ADDRESS\n");
504                 rootdev = le16_to_cpu(req->value);
505                 break;
506         case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
507                 debug("USB_REQ_SET_CONFIGURATION\n");
508                 /* Nothing to do */
509                 break;
510         case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8):
511                 tmpbuf[0] = 1;  /* USB_STATUS_SELFPOWERED */
512                 tmpbuf[1] = 0;
513                 srcptr = tmpbuf;
514                 srclen = 2;
515                 break;
516         case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
517                 memset(tmpbuf, 0, 4);
518                 reg = ehci_readl(status_reg);
519                 if (reg & EHCI_PS_CS)
520                         tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
521                 if (reg & EHCI_PS_PE)
522                         tmpbuf[0] |= USB_PORT_STAT_ENABLE;
523                 if (reg & EHCI_PS_SUSP)
524                         tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
525                 if (reg & EHCI_PS_OCA)
526                         tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
527                 if (reg & EHCI_PS_PR)
528                         tmpbuf[0] |= USB_PORT_STAT_RESET;
529                 if (reg & EHCI_PS_PP)
530                         tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
531
532                 if (ehci_is_TDI()) {
533                         switch ((reg >> 26) & 3) {
534                         case 0:
535                                 break;
536                         case 1:
537                                 tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
538                                 break;
539                         case 2:
540                         default:
541                                 tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
542                                 break;
543                         }
544                 } else {
545                         tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
546                 }
547
548                 if (reg & EHCI_PS_CSC)
549                         tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
550                 if (reg & EHCI_PS_PEC)
551                         tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
552                 if (reg & EHCI_PS_OCC)
553                         tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
554                 if (portreset & (1 << le16_to_cpu(req->index)))
555                         tmpbuf[2] |= USB_PORT_STAT_C_RESET;
556
557                 srcptr = tmpbuf;
558                 srclen = 4;
559                 break;
560         case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
561                 reg = ehci_readl(status_reg);
562                 reg &= ~EHCI_PS_CLEAR;
563                 switch (le16_to_cpu(req->value)) {
564                 case USB_PORT_FEAT_ENABLE:
565                         reg |= EHCI_PS_PE;
566                         ehci_writel(status_reg, reg);
567                         break;
568                 case USB_PORT_FEAT_POWER:
569                         if (HCS_PPC(ehci_readl(&hccr->cr_hcsparams))) {
570                                 reg |= EHCI_PS_PP;
571                                 ehci_writel(status_reg, reg);
572                         }
573                         break;
574                 case USB_PORT_FEAT_RESET:
575                         if ((reg & (EHCI_PS_PE | EHCI_PS_CS)) == EHCI_PS_CS &&
576                             !ehci_is_TDI() &&
577                             EHCI_PS_IS_LOWSPEED(reg)) {
578                                 /* Low speed device, give up ownership. */
579                                 debug("port %d low speed --> companion\n",
580                                       req->index - 1);
581                                 reg |= EHCI_PS_PO;
582                                 ehci_writel(status_reg, reg);
583                                 break;
584                         } else {
585                                 int ret;
586
587                                 reg |= EHCI_PS_PR;
588                                 reg &= ~EHCI_PS_PE;
589                                 ehci_writel(status_reg, reg);
590                                 /*
591                                  * caller must wait, then call GetPortStatus
592                                  * usb 2.0 specification say 50 ms resets on
593                                  * root
594                                  */
595                                 ehci_powerup_fixup(status_reg, &reg);
596
597                                 ehci_writel(status_reg, reg & ~EHCI_PS_PR);
598                                 /*
599                                  * A host controller must terminate the reset
600                                  * and stabilize the state of the port within
601                                  * 2 milliseconds
602                                  */
603                                 ret = handshake(status_reg, EHCI_PS_PR, 0,
604                                                 2 * 1000);
605                                 if (!ret)
606                                         portreset |=
607                                                 1 << le16_to_cpu(req->index);
608                                 else
609                                         printf("port(%d) reset error\n",
610                                         le16_to_cpu(req->index) - 1);
611                         }
612                         break;
613                 default:
614                         debug("unknown feature %x\n", le16_to_cpu(req->value));
615                         goto unknown;
616                 }
617                 /* unblock posted writes */
618                 (void) ehci_readl(&hcor->or_usbcmd);
619                 break;
620         case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
621                 reg = ehci_readl(status_reg);
622                 switch (le16_to_cpu(req->value)) {
623                 case USB_PORT_FEAT_ENABLE:
624                         reg &= ~EHCI_PS_PE;
625                         break;
626                 case USB_PORT_FEAT_C_ENABLE:
627                         reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_PE;
628                         break;
629                 case USB_PORT_FEAT_POWER:
630                         if (HCS_PPC(ehci_readl(&hccr->cr_hcsparams)))
631                                 reg = reg & ~(EHCI_PS_CLEAR | EHCI_PS_PP);
632                 case USB_PORT_FEAT_C_CONNECTION:
633                         reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_CSC;
634                         break;
635                 case USB_PORT_FEAT_OVER_CURRENT:
636                         reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_OCC;
637                         break;
638                 case USB_PORT_FEAT_C_RESET:
639                         portreset &= ~(1 << le16_to_cpu(req->index));
640                         break;
641                 default:
642                         debug("unknown feature %x\n", le16_to_cpu(req->value));
643                         goto unknown;
644                 }
645                 ehci_writel(status_reg, reg);
646                 /* unblock posted write */
647                 (void) ehci_readl(&hcor->or_usbcmd);
648                 break;
649         default:
650                 debug("Unknown request\n");
651                 goto unknown;
652         }
653
654         mdelay(1);
655         len = min3(srclen, le16_to_cpu(req->length), length);
656         if (srcptr != NULL && len > 0)
657                 memcpy(buffer, srcptr, len);
658         else
659                 debug("Len is 0\n");
660
661         dev->act_len = len;
662         dev->status = 0;
663         return 0;
664
665 unknown:
666         debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x\n",
667               req->requesttype, req->request, le16_to_cpu(req->value),
668               le16_to_cpu(req->index), le16_to_cpu(req->length));
669
670         dev->act_len = 0;
671         dev->status = USB_ST_STALLED;
672         return -1;
673 }
674
675 int usb_lowlevel_stop(void)
676 {
677         return ehci_hcd_stop();
678 }
679
680 int usb_lowlevel_init(void)
681 {
682         uint32_t reg;
683         uint32_t cmd;
684
685         if (ehci_hcd_init() != 0)
686                 return -1;
687
688         /* EHCI spec section 4.1 */
689         if (ehci_reset() != 0)
690                 return -1;
691
692 #if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
693         if (ehci_hcd_init() != 0)
694                 return -1;
695 #endif
696
697         /* Set head of reclaim list */
698         memset(&qh_list, 0, sizeof(qh_list));
699         qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
700         qh_list.qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
701         qh_list.qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
702         qh_list.qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
703         qh_list.qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
704         qh_list.qh_overlay.qt_token = cpu_to_hc32(0x40);
705
706         /* Set async. queue head pointer. */
707         ehci_writel(&hcor->or_asynclistaddr, (uint32_t)&qh_list);
708
709         reg = ehci_readl(&hccr->cr_hcsparams);
710         descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
711         printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
712         /* Port Indicators */
713         if (HCS_INDICATOR(reg))
714                 descriptor.hub.wHubCharacteristics |= 0x80;
715         /* Port Power Control */
716         if (HCS_PPC(reg))
717                 descriptor.hub.wHubCharacteristics |= 0x01;
718
719         /* Start the host controller. */
720         cmd = ehci_readl(&hcor->or_usbcmd);
721         /*
722          * Philips, Intel, and maybe others need CMD_RUN before the
723          * root hub will detect new devices (why?); NEC doesn't
724          */
725         cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
726         cmd |= CMD_RUN;
727         ehci_writel(&hcor->or_usbcmd, cmd);
728
729         /* take control over the ports */
730         cmd = ehci_readl(&hcor->or_configflag);
731         cmd |= FLAG_CF;
732         ehci_writel(&hcor->or_configflag, cmd);
733         /* unblock posted write */
734         cmd = ehci_readl(&hcor->or_usbcmd);
735         mdelay(5);
736         reg = HC_VERSION(ehci_readl(&hccr->cr_capbase));
737         printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
738
739         rootdev = 0;
740
741         return 0;
742 }
743
744 int
745 submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
746                 int length)
747 {
748
749         if (usb_pipetype(pipe) != PIPE_BULK) {
750                 debug("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
751                 return -1;
752         }
753         return ehci_submit_async(dev, pipe, buffer, length, NULL);
754 }
755
756 int
757 submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
758                    int length, struct devrequest *setup)
759 {
760
761         if (usb_pipetype(pipe) != PIPE_CONTROL) {
762                 debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
763                 return -1;
764         }
765
766         if (usb_pipedevice(pipe) == rootdev) {
767                 if (rootdev == 0)
768                         dev->speed = USB_SPEED_HIGH;
769                 return ehci_submit_root(dev, pipe, buffer, length, setup);
770         }
771         return ehci_submit_async(dev, pipe, buffer, length, setup);
772 }
773
774 int
775 submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
776                int length, int interval)
777 {
778
779         debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
780               dev, pipe, buffer, length, interval);
781         return ehci_submit_async(dev, pipe, buffer, length, NULL);
782 }