]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/isp116x-hcd.c
Fix: TFTP is not working on little endian systems
[karo-tx-uboot.git] / drivers / isp116x-hcd.c
1 /*
2  * ISP116x HCD (Host Controller Driver) for u-boot.
3  *
4  * Copyright (C) 2006-2007 Rodolfo Giometti <giometti@linux.it>
5  * Copyright (C) 2006-2007 Eurotech S.p.A. <info@eurotech.it>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  *
22  *
23  * Derived in part from the SL811 HCD driver "u-boot/drivers/sl811_usb.c"
24  * (original copyright message follows):
25  *
26  *    (C) Copyright 2004
27  *    Wolfgang Denk, DENX Software Engineering, wd@denx.de.
28  *
29  *    This code is based on linux driver for sl811hs chip, source at
30  *    drivers/usb/host/sl811.c:
31  *
32  *    SL811 Host Controller Interface driver for USB.
33  *
34  *    Copyright (c) 2003/06, Courage Co., Ltd.
35  *
36  *    Based on:
37  *         1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
38  *           Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
39  *           Adam Richter, Gregory P. Smith;
40  *         2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
41  *         3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
42  *
43  *    [[GNU/GPL disclaimer]]
44  *
45  * and in part from AU1x00 OHCI HCD driver "u-boot/cpu/mips/au1x00_usb_ohci.c"
46  * (original copyright message follows):
47  *
48  *    URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.
49  *
50  *    (C) Copyright 2003
51  *    Gary Jennejohn, DENX Software Engineering <gj@denx.de>
52  *
53  *    [[GNU/GPL disclaimer]]
54  *
55  *    Note: Part of this code has been derived from linux
56  */
57
58 #include <common.h>
59
60 #ifdef CONFIG_USB_ISP116X_HCD
61 #include <asm/io.h>
62 #include <usb.h>
63 #include <malloc.h>
64 #include <linux/list.h>
65
66 /*
67  * ISP116x chips require certain delays between accesses to its
68  * registers. The following timing options exist.
69  *
70  * 1. Configure your memory controller (the best)
71  * 2. Use ndelay (easiest, poorest). For that, enable the following macro.
72  *
73  * Value is in microseconds.
74  */
75 #ifdef ISP116X_HCD_USE_UDELAY
76 #define UDELAY          1
77 #endif
78
79 /*
80  * On some (slowly?) machines an extra delay after data packing into
81  * controller's FIFOs is required, * otherwise you may get the following
82  * error:
83  *
84  *   uboot> usb start
85  *   (Re)start USB...
86  *   USB:   scanning bus for devices... isp116x: isp116x_submit_job: CTL:TIMEOUT
87  *   isp116x: isp116x_submit_job: ****** FIFO not ready! ******
88  *
89  *         USB device not responding, giving up (status=4)
90  *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
91  *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
92  *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
93  *         3 USB Device(s) found
94  *                scanning bus for storage devices... 0 Storage Device(s) found
95  *
96  * Value is in milliseconds.
97  */
98 #ifdef ISP116X_HCD_USE_EXTRA_DELAY
99 #define EXTRA_DELAY     2
100 #endif
101
102 /*
103  * Enable the following defines if you wish enable debugging messages.
104  */
105 #undef DEBUG                    /* enable debugging messages */
106 #undef TRACE                    /* enable tracing code */
107 #undef VERBOSE                  /* verbose debugging messages */
108
109 #include "isp116x.h"
110
111 #define DRIVER_VERSION  "08 Jan 2007"
112 static const char hcd_name[] = "isp116x-hcd";
113
114 struct isp116x isp116x_dev;
115 struct isp116x_platform_data isp116x_board;
116 int got_rhsc = 0;               /* root hub status change */
117 struct usb_device *devgone;     /* device which was disconnected */
118 int rh_devnum = 0;              /* address of Root Hub endpoint */
119
120 /* ------------------------------------------------------------------------- */
121
122 #define ALIGN(x,a)      (((x)+(a)-1UL)&~((a)-1UL))
123 #define min_t(type,x,y) \
124         ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; })
125
126 /* ------------------------------------------------------------------------- */
127
128 static int isp116x_reset(struct isp116x *isp116x);
129
130 /* --- Debugging functions ------------------------------------------------- */
131
132 #define isp116x_show_reg(d, r) {                                \
133         if ((r) < 0x20) {                                       \
134                 DBG("%-12s[%02x]: %08x", #r,                    \
135                         r, isp116x_read_reg32(d, r));           \
136         } else {                                                \
137                 DBG("%-12s[%02x]:     %04x", #r,                \
138                         r, isp116x_read_reg16(d, r));           \
139         }                                                       \
140 }
141
142 #define isp116x_show_regs(d) {                                  \
143         isp116x_show_reg(d, HCREVISION);                        \
144         isp116x_show_reg(d, HCCONTROL);                         \
145         isp116x_show_reg(d, HCCMDSTAT);                         \
146         isp116x_show_reg(d, HCINTSTAT);                         \
147         isp116x_show_reg(d, HCINTENB);                          \
148         isp116x_show_reg(d, HCFMINTVL);                         \
149         isp116x_show_reg(d, HCFMREM);                           \
150         isp116x_show_reg(d, HCFMNUM);                           \
151         isp116x_show_reg(d, HCLSTHRESH);                        \
152         isp116x_show_reg(d, HCRHDESCA);                         \
153         isp116x_show_reg(d, HCRHDESCB);                         \
154         isp116x_show_reg(d, HCRHSTATUS);                        \
155         isp116x_show_reg(d, HCRHPORT1);                         \
156         isp116x_show_reg(d, HCRHPORT2);                         \
157         isp116x_show_reg(d, HCHWCFG);                           \
158         isp116x_show_reg(d, HCDMACFG);                          \
159         isp116x_show_reg(d, HCXFERCTR);                         \
160         isp116x_show_reg(d, HCuPINT);                           \
161         isp116x_show_reg(d, HCuPINTENB);                        \
162         isp116x_show_reg(d, HCCHIPID);                          \
163         isp116x_show_reg(d, HCSCRATCH);                         \
164         isp116x_show_reg(d, HCITLBUFLEN);                       \
165         isp116x_show_reg(d, HCATLBUFLEN);                       \
166         isp116x_show_reg(d, HCBUFSTAT);                         \
167         isp116x_show_reg(d, HCRDITL0LEN);                       \
168         isp116x_show_reg(d, HCRDITL1LEN);                       \
169 }
170
171 #if defined(TRACE)
172
173 static int isp116x_get_current_frame_number(struct usb_device *usb_dev)
174 {
175         struct isp116x *isp116x = &isp116x_dev;
176
177         return isp116x_read_reg32(isp116x, HCFMNUM);
178 }
179
180 static void dump_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
181                      int len, char *str)
182 {
183 #if defined(VERBOSE)
184         int i;
185 #endif
186
187         DBG("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d stat:%#lx",
188             str,
189             isp116x_get_current_frame_number(dev),
190             usb_pipedevice(pipe),
191             usb_pipeendpoint(pipe),
192             usb_pipeout(pipe) ? 'O' : 'I',
193             usb_pipetype(pipe) < 2 ?
194             (usb_pipeint(pipe) ?
195              "INTR" : "ISOC") :
196             (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), len, dev->status);
197 #if defined(VERBOSE)
198         if (len > 0 && buffer) {
199                 printf(__FILE__ ": data(%d):", len);
200                 for (i = 0; i < 16 && i < len; i++)
201                         printf(" %02x", ((__u8 *) buffer)[i]);
202                 printf("%s\n", i < len ? "..." : "");
203         }
204 #endif
205 }
206
207 #define PTD_DIR_STR(ptd)  ({char __c;           \
208         switch(PTD_GET_DIR(ptd)){               \
209         case 0:  __c = 's'; break;              \
210         case 1:  __c = 'o'; break;              \
211         default: __c = 'i'; break;              \
212         }; __c;})
213
214 /*
215   Dump PTD info. The code documents the format
216   perfectly, right :)
217 */
218 static inline void dump_ptd(struct ptd *ptd)
219 {
220 #if defined(VERBOSE)
221         int k;
222 #endif
223
224         DBG("PTD(ext) : cc:%x %d%c%d %d,%d,%d t:%x %x%x%x",
225             PTD_GET_CC(ptd),
226             PTD_GET_FA(ptd), PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
227             PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
228             PTD_GET_TOGGLE(ptd),
229             PTD_GET_ACTIVE(ptd), PTD_GET_SPD(ptd), PTD_GET_LAST(ptd));
230 #if defined(VERBOSE)
231         printf("isp116x: %s: PTD(byte): ", __FUNCTION__);
232         for (k = 0; k < sizeof(struct ptd); ++k)
233                 printf("%02x ", ((u8 *) ptd)[k]);
234         printf("\n");
235 #endif
236 }
237
238 static inline void dump_ptd_data(struct ptd *ptd, u8 * buf, int type)
239 {
240 #if defined(VERBOSE)
241         int k;
242
243         if (type == 0 /* 0ut data */ ) {
244                 printf("isp116x: %s: out data: ", __FUNCTION__);
245                 for (k = 0; k < PTD_GET_LEN(ptd); ++k)
246                         printf("%02x ", ((u8 *) buf)[k]);
247                 printf("\n");
248         }
249         if (type == 1 /* 1n data */ ) {
250                 printf("isp116x: %s: in data: ", __FUNCTION__);
251                 for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
252                         printf("%02x ", ((u8 *) buf)[k]);
253                 printf("\n");
254         }
255
256         if (PTD_GET_LAST(ptd))
257                 DBG("--- last PTD ---");
258 #endif
259 }
260
261 #else
262
263 #define dump_msg(dev, pipe, buffer, len, str)                   do { } while (0)
264 #define dump_pkt(dev, pipe, buffer, len, setup, str, small)     do {} while (0)
265
266 #define dump_ptd(ptd)                   do {} while (0)
267 #define dump_ptd_data(ptd, buf, type)   do {} while (0)
268
269 #endif
270
271 /* --- Virtual Root Hub ---------------------------------------------------- */
272
273 /* Device descriptor */
274 static __u8 root_hub_dev_des[] = {
275         0x12,                   /*  __u8  bLength; */
276         0x01,                   /*  __u8  bDescriptorType; Device */
277         0x10,                   /*  __u16 bcdUSB; v1.1 */
278         0x01,
279         0x09,                   /*  __u8  bDeviceClass; HUB_CLASSCODE */
280         0x00,                   /*  __u8  bDeviceSubClass; */
281         0x00,                   /*  __u8  bDeviceProtocol; */
282         0x08,                   /*  __u8  bMaxPacketSize0; 8 Bytes */
283         0x00,                   /*  __u16 idVendor; */
284         0x00,
285         0x00,                   /*  __u16 idProduct; */
286         0x00,
287         0x00,                   /*  __u16 bcdDevice; */
288         0x00,
289         0x00,                   /*  __u8  iManufacturer; */
290         0x01,                   /*  __u8  iProduct; */
291         0x00,                   /*  __u8  iSerialNumber; */
292         0x01                    /*  __u8  bNumConfigurations; */
293 };
294
295 /* Configuration descriptor */
296 static __u8 root_hub_config_des[] = {
297         0x09,                   /*  __u8  bLength; */
298         0x02,                   /*  __u8  bDescriptorType; Configuration */
299         0x19,                   /*  __u16 wTotalLength; */
300         0x00,
301         0x01,                   /*  __u8  bNumInterfaces; */
302         0x01,                   /*  __u8  bConfigurationValue; */
303         0x00,                   /*  __u8  iConfiguration; */
304         0x40,                   /*  __u8  bmAttributes;
305                                    Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
306         0x00,                   /*  __u8  MaxPower; */
307
308         /* interface */
309         0x09,                   /*  __u8  if_bLength; */
310         0x04,                   /*  __u8  if_bDescriptorType; Interface */
311         0x00,                   /*  __u8  if_bInterfaceNumber; */
312         0x00,                   /*  __u8  if_bAlternateSetting; */
313         0x01,                   /*  __u8  if_bNumEndpoints; */
314         0x09,                   /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
315         0x00,                   /*  __u8  if_bInterfaceSubClass; */
316         0x00,                   /*  __u8  if_bInterfaceProtocol; */
317         0x00,                   /*  __u8  if_iInterface; */
318
319         /* endpoint */
320         0x07,                   /*  __u8  ep_bLength; */
321         0x05,                   /*  __u8  ep_bDescriptorType; Endpoint */
322         0x81,                   /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
323         0x03,                   /*  __u8  ep_bmAttributes; Interrupt */
324         0x00,                   /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
325         0x02,
326         0xff                    /*  __u8  ep_bInterval; 255 ms */
327 };
328
329 static unsigned char root_hub_str_index0[] = {
330         0x04,                   /*  __u8  bLength; */
331         0x03,                   /*  __u8  bDescriptorType; String-descriptor */
332         0x09,                   /*  __u8  lang ID */
333         0x04,                   /*  __u8  lang ID */
334 };
335
336 static unsigned char root_hub_str_index1[] = {
337         0x22,                   /*  __u8  bLength; */
338         0x03,                   /*  __u8  bDescriptorType; String-descriptor */
339         'I',                    /*  __u8  Unicode */
340         0,                      /*  __u8  Unicode */
341         'S',                    /*  __u8  Unicode */
342         0,                      /*  __u8  Unicode */
343         'P',                    /*  __u8  Unicode */
344         0,                      /*  __u8  Unicode */
345         '1',                    /*  __u8  Unicode */
346         0,                      /*  __u8  Unicode */
347         '1',                    /*  __u8  Unicode */
348         0,                      /*  __u8  Unicode */
349         '6',                    /*  __u8  Unicode */
350         0,                      /*  __u8  Unicode */
351         'x',                    /*  __u8  Unicode */
352         0,                      /*  __u8  Unicode */
353         ' ',                    /*  __u8  Unicode */
354         0,                      /*  __u8  Unicode */
355         'R',                    /*  __u8  Unicode */
356         0,                      /*  __u8  Unicode */
357         'o',                    /*  __u8  Unicode */
358         0,                      /*  __u8  Unicode */
359         'o',                    /*  __u8  Unicode */
360         0,                      /*  __u8  Unicode */
361         't',                    /*  __u8  Unicode */
362         0,                      /*  __u8  Unicode */
363         ' ',                    /*  __u8  Unicode */
364         0,                      /*  __u8  Unicode */
365         'H',                    /*  __u8  Unicode */
366         0,                      /*  __u8  Unicode */
367         'u',                    /*  __u8  Unicode */
368         0,                      /*  __u8  Unicode */
369         'b',                    /*  __u8  Unicode */
370         0,                      /*  __u8  Unicode */
371 };
372
373 /*
374  * Hub class-specific descriptor is constructed dynamically
375  */
376
377 /* --- Virtual root hub management functions ------------------------------- */
378
379 static int rh_check_port_status(struct isp116x *isp116x)
380 {
381         u32 temp, ndp, i;
382         int res;
383
384         res = -1;
385         temp = isp116x_read_reg32(isp116x, HCRHSTATUS);
386         ndp = (temp & RH_A_NDP);
387         for (i = 0; i < ndp; i++) {
388                 temp = isp116x_read_reg32(isp116x, HCRHPORT1 + i);
389                 /* check for a device disconnect */
390                 if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
391                      (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
392                         res = i;
393                         break;
394                 }
395         }
396         return res;
397 }
398
399 /* --- HC management functions --------------------------------------------- */
400
401 /* Write len bytes to fifo, pad till 32-bit boundary
402  */
403 static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
404 {
405         u8 *dp = (u8 *) buf;
406         u16 *dp2 = (u16 *) buf;
407         u16 w;
408         int quot = len % 4;
409
410         if ((unsigned long)dp2 & 1) {
411                 /* not aligned */
412                 for (; len > 1; len -= 2) {
413                         w = *dp++;
414                         w |= *dp++ << 8;
415                         isp116x_raw_write_data16(isp116x, w);
416                 }
417                 if (len)
418                         isp116x_write_data16(isp116x, (u16) * dp);
419         } else {
420                 /* aligned */
421                 for (; len > 1; len -= 2)
422                         isp116x_raw_write_data16(isp116x, *dp2++);
423                 if (len)
424                         isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
425         }
426         if (quot == 1 || quot == 2)
427                 isp116x_raw_write_data16(isp116x, 0);
428 }
429
430 /* Read len bytes from fifo and then read till 32-bit boundary
431  */
432 static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
433 {
434         u8 *dp = (u8 *) buf;
435         u16 *dp2 = (u16 *) buf;
436         u16 w;
437         int quot = len % 4;
438
439         if ((unsigned long)dp2 & 1) {
440                 /* not aligned */
441                 for (; len > 1; len -= 2) {
442                         w = isp116x_raw_read_data16(isp116x);
443                         *dp++ = w & 0xff;
444                         *dp++ = (w >> 8) & 0xff;
445                 }
446                 if (len)
447                         *dp = 0xff & isp116x_read_data16(isp116x);
448         } else {
449                 /* aligned */
450                 for (; len > 1; len -= 2)
451                         *dp2++ = isp116x_raw_read_data16(isp116x);
452                 if (len)
453                         *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
454         }
455         if (quot == 1 || quot == 2)
456                 isp116x_raw_read_data16(isp116x);
457 }
458
459 /* Write PTD's and data for scheduled transfers into the fifo ram.
460  * Fifo must be empty and ready */
461 static void pack_fifo(struct isp116x *isp116x, struct usb_device *dev,
462                       unsigned long pipe, struct ptd *ptd, int n, void *data,
463                       int len)
464 {
465         int buflen = n * sizeof(struct ptd) + len;
466         int i, done;
467
468         DBG("--- pack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
469
470         isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
471         isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
472         isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
473
474         done = 0;
475         for (i = 0; i < n; i++) {
476                 DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
477
478                 dump_ptd(&ptd[i]);
479                 isp116x_write_data16(isp116x, ptd[i].count);
480                 isp116x_write_data16(isp116x, ptd[i].mps);
481                 isp116x_write_data16(isp116x, ptd[i].len);
482                 isp116x_write_data16(isp116x, ptd[i].faddr);
483
484                 dump_ptd_data(&ptd[i], (__u8 *) data + done, 0);
485                 write_ptddata_to_fifo(isp116x,
486                                       (__u8 *) data + done,
487                                       PTD_GET_LEN(&ptd[i]));
488
489                 done += PTD_GET_LEN(&ptd[i]);
490         }
491 }
492
493 /* Read the processed PTD's and data from fifo ram back to URBs' buffers.
494  * Fifo must be full and done */
495 static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
496                        unsigned long pipe, struct ptd *ptd, int n, void *data,
497                        int len)
498 {
499         int buflen = n * sizeof(struct ptd) + len;
500         int i, done, cc, ret;
501
502         isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
503         isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
504         isp116x_write_addr(isp116x, HCATLPORT);
505
506         ret = TD_CC_NOERROR;
507         done = 0;
508         for (i = 0; i < n; i++) {
509                 DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
510
511                 ptd[i].count = isp116x_read_data16(isp116x);
512                 ptd[i].mps = isp116x_read_data16(isp116x);
513                 ptd[i].len = isp116x_read_data16(isp116x);
514                 ptd[i].faddr = isp116x_read_data16(isp116x);
515                 dump_ptd(&ptd[i]);
516
517                 read_ptddata_from_fifo(isp116x,
518                                        (__u8 *) data + done,
519                                        PTD_GET_LEN(&ptd[i]));
520                 dump_ptd_data(&ptd[i], (__u8 *) data + done, 1);
521
522                 done += PTD_GET_LEN(&ptd[i]);
523
524                 cc = PTD_GET_CC(&ptd[i]);
525                 if (cc == TD_DATAUNDERRUN) {    /* underrun is no error... */
526                         DBG("allowed data underrun");
527                         cc = TD_CC_NOERROR;
528                 }
529                 if (cc != TD_CC_NOERROR && ret == TD_CC_NOERROR)
530                         ret = cc;
531         }
532
533         DBG("--- unpack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
534
535         return ret;
536 }
537
538 /* Interrupt handling
539  */
540 static int isp116x_interrupt(struct isp116x *isp116x)
541 {
542         u16 irqstat;
543         u32 intstat;
544         int ret = 0;
545
546         isp116x_write_reg16(isp116x, HCuPINTENB, 0);
547         irqstat = isp116x_read_reg16(isp116x, HCuPINT);
548         isp116x_write_reg16(isp116x, HCuPINT, irqstat);
549         DBG(">>>>>> irqstat %x <<<<<<", irqstat);
550
551         if (irqstat & HCuPINT_ATL) {
552                 DBG(">>>>>> HCuPINT_ATL <<<<<<");
553                 udelay(500);
554                 ret = 1;
555         }
556
557         if (irqstat & HCuPINT_OPR) {
558                 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
559                 isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
560                 DBG(">>>>>> HCuPINT_OPR %x <<<<<<", intstat);
561
562                 if (intstat & HCINT_UE) {
563                         ERR("unrecoverable error, controller disabled");
564
565                         /* FIXME: be optimistic, hope that bug won't repeat
566                          * often. Make some non-interrupt context restart the
567                          * controller. Count and limit the retries though;
568                          * either hardware or software errors can go forever...
569                          */
570                         isp116x_reset(isp116x);
571                         ret = -1;
572                         return -1;
573                 }
574
575                 if (intstat & HCINT_RHSC) {
576                         got_rhsc = 1;
577                         ret = 1;
578                         /* When root hub or any of its ports is going
579                            to come out of suspend, it may take more
580                            than 10ms for status bits to stabilize. */
581                         wait_ms(20);
582                 }
583
584                 if (intstat & HCINT_SO) {
585                         ERR("schedule overrun");
586                         ret = -1;
587                 }
588
589                 irqstat &= ~HCuPINT_OPR;
590         }
591
592         return ret;
593 }
594
595 #define PTD_NUM                 64      /* it should be enougth... */
596 struct ptd ptd[PTD_NUM];
597 static inline int max_transfer_len(struct usb_device *dev, unsigned long pipe)
598 {
599         return min(PTD_NUM * usb_maxpacket(dev, pipe), PTD_NUM * 16);
600 }
601
602 /* Do an USB transfer
603  */
604 static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
605                               int dir, void *buffer, int len)
606 {
607         struct isp116x *isp116x = &isp116x_dev;
608         int type = usb_pipetype(pipe);
609         int epnum = usb_pipeendpoint(pipe);
610         int max = usb_maxpacket(dev, pipe);
611         int dir_out = usb_pipeout(pipe);
612         int speed_low = usb_pipeslow(pipe);
613         int i, done, stat, timeout, cc;
614         int retries = 10;
615
616         DBG("------------------------------------------------");
617         dump_msg(dev, pipe, buffer, len, "SUBMIT");
618         DBG("------------------------------------------------");
619
620         if (isp116x->disabled) {
621                 ERR("EPIPE");
622                 dev->status = USB_ST_CRC_ERR;
623                 return -1;
624         }
625
626         /* device pulled? Shortcut the action. */
627         if (devgone == dev) {
628                 ERR("ENODEV");
629                 dev->status = USB_ST_CRC_ERR;
630                 return USB_ST_CRC_ERR;
631         }
632
633         if (!max) {
634                 ERR("pipesize for pipe %lx is zero", pipe);
635                 dev->status = USB_ST_CRC_ERR;
636                 return -1;
637         }
638
639         if (type == PIPE_ISOCHRONOUS) {
640                 ERR("isochronous transfers not supported");
641                 dev->status = USB_ST_CRC_ERR;
642                 return -1;
643         }
644
645         /* FIFO not empty? */
646         if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL) {
647                 ERR("****** FIFO not empty! ******");
648                 dev->status = USB_ST_BUF_ERR;
649                 return -1;
650         }
651
652       retry:
653         isp116x_write_reg32(isp116x, HCINTSTAT, 0xff);
654
655         /* Prepare the PTD data */
656         done = 0;
657         i = 0;
658         do {
659                 ptd[i].count = PTD_CC_MSK | PTD_ACTIVE_MSK |
660                     PTD_TOGGLE(usb_gettoggle(dev, epnum, dir_out));
661                 ptd[i].mps = PTD_MPS(max) | PTD_SPD(speed_low) | PTD_EP(epnum);
662                 ptd[i].len = PTD_LEN(max > len - done ? len - done : max) |
663                     PTD_DIR(dir);
664                 ptd[i].faddr = PTD_FA(usb_pipedevice(pipe));
665
666                 usb_dotoggle(dev, epnum, dir_out);
667                 done += PTD_GET_LEN(&ptd[i]);
668                 i++;
669                 if (i >= PTD_NUM) {
670                         ERR("****** Cannot pack buffer! ******");
671                         dev->status = USB_ST_BUF_ERR;
672                         return -1;
673                 }
674         } while (done < len);
675         ptd[i - 1].mps |= PTD_LAST_MSK;
676
677         /* Pack data into FIFO ram */
678         pack_fifo(isp116x, dev, pipe, ptd, i, buffer, len);
679 #ifdef EXTRA_DELAY
680         wait_ms(EXTRA_DELAY);
681 #endif
682
683         /* Start the data transfer */
684
685         /* Allow more time for a BULK device to react - some are slow */
686         if (usb_pipetype(pipe) == PIPE_BULK)
687                 timeout = 5000;
688         else
689                 timeout = 100;
690
691         /* Wait for it to complete */
692         for (;;) {
693                 /* Check whether the controller is done */
694                 stat = isp116x_interrupt(isp116x);
695
696                 if (stat < 0) {
697                         dev->status = USB_ST_CRC_ERR;
698                         break;
699                 }
700                 if (stat > 0)
701                         break;
702
703                 /* Check the timeout */
704                 if (--timeout)
705                         udelay(1);
706                 else {
707                         ERR("CTL:TIMEOUT ");
708                         stat = USB_ST_CRC_ERR;
709                         break;
710                 }
711         }
712
713         /* We got an Root Hub Status Change interrupt */
714         if (got_rhsc) {
715                 isp116x_show_regs(isp116x);
716
717                 got_rhsc = 0;
718
719                 /* Abuse timeout */
720                 timeout = rh_check_port_status(isp116x);
721                 if (timeout >= 0) {
722                         /*
723                          * FIXME! NOTE! AAAARGH!
724                          * This is potentially dangerous because it assumes
725                          * that only one device is ever plugged in!
726                          */
727                         devgone = dev;
728                 }
729         }
730
731         /* Ok, now we can read transfer status */
732
733         /* FIFO not ready? */
734         if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE)) {
735                 ERR("****** FIFO not ready! ******");
736                 dev->status = USB_ST_BUF_ERR;
737                 return -1;
738         }
739
740         /* Unpack data from FIFO ram */
741         cc = unpack_fifo(isp116x, dev, pipe, ptd, i, buffer, len);
742
743         /* Mmm... sometime we get 0x0f as cc which is a non sense!
744          * Just retry the transfer...
745          */
746         if (cc == 0x0f && retries-- > 0) {
747                 usb_dotoggle(dev, epnum, dir_out);
748                 goto retry;
749         }
750
751         if (cc != TD_CC_NOERROR) {
752                 DBG("****** completition code error %x ******", cc);
753                 switch (cc) {
754                 case TD_CC_BITSTUFFING:
755                         dev->status = USB_ST_BIT_ERR;
756                         break;
757                 case TD_CC_STALL:
758                         dev->status = USB_ST_STALLED;
759                         break;
760                 case TD_BUFFEROVERRUN:
761                 case TD_BUFFERUNDERRUN:
762                         dev->status = USB_ST_BUF_ERR;
763                         break;
764                 default:
765                         dev->status = USB_ST_CRC_ERR;
766                 }
767                 return -cc;
768         }
769
770         dump_msg(dev, pipe, buffer, len, "SUBMIT(ret)");
771
772         dev->status = 0;
773         return done;
774 }
775
776 /* Adapted from au1x00_usb_ohci.c
777  */
778 static int isp116x_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
779                                  void *buffer, int transfer_len,
780                                  struct devrequest *cmd)
781 {
782         struct isp116x *isp116x = &isp116x_dev;
783         u32 tmp = 0;
784
785         int leni = transfer_len;
786         int len = 0;
787         int stat = 0;
788         u32 datab[4];
789         u8 *data_buf = (u8 *) datab;
790         u16 bmRType_bReq;
791         u16 wValue;
792         u16 wIndex;
793         u16 wLength;
794
795         if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
796                 INFO("Root-Hub submit IRQ: NOT implemented");
797                 return 0;
798         }
799
800         bmRType_bReq = cmd->requesttype | (cmd->request << 8);
801         wValue = swap_16(cmd->value);
802         wIndex = swap_16(cmd->index);
803         wLength = swap_16(cmd->length);
804
805         DBG("--- HUB ----------------------------------------");
806         DBG("submit rh urb, req=%x val=%#x index=%#x len=%d",
807             bmRType_bReq, wValue, wIndex, wLength);
808         dump_msg(dev, pipe, buffer, transfer_len, "RH");
809         DBG("------------------------------------------------");
810
811         switch (bmRType_bReq) {
812         case RH_GET_STATUS:
813                 DBG("RH_GET_STATUS");
814
815                 *(__u16 *) data_buf = swap_16(1);
816                 len = 2;
817                 break;
818
819         case RH_GET_STATUS | RH_INTERFACE:
820                 DBG("RH_GET_STATUS | RH_INTERFACE");
821
822                 *(__u16 *) data_buf = swap_16(0);
823                 len = 2;
824                 break;
825
826         case RH_GET_STATUS | RH_ENDPOINT:
827                 DBG("RH_GET_STATUS | RH_ENDPOINT");
828
829                 *(__u16 *) data_buf = swap_16(0);
830                 len = 2;
831                 break;
832
833         case RH_GET_STATUS | RH_CLASS:
834                 DBG("RH_GET_STATUS | RH_CLASS");
835
836                 tmp = isp116x_read_reg32(isp116x, HCRHSTATUS);
837
838                 *(__u32 *) data_buf = swap_32(tmp & ~(RH_HS_CRWE | RH_HS_DRWE));
839                 len = 4;
840                 break;
841
842         case RH_GET_STATUS | RH_OTHER | RH_CLASS:
843                 DBG("RH_GET_STATUS | RH_OTHER | RH_CLASS");
844
845                 tmp = isp116x_read_reg32(isp116x, HCRHPORT1 + wIndex - 1);
846                 *(__u32 *) data_buf = swap_32(tmp);
847                 isp116x_show_regs(isp116x);
848                 len = 4;
849                 break;
850
851         case RH_CLEAR_FEATURE | RH_ENDPOINT:
852                 DBG("RH_CLEAR_FEATURE | RH_ENDPOINT");
853
854                 switch (wValue) {
855                 case RH_ENDPOINT_STALL:
856                         DBG("C_HUB_ENDPOINT_STALL");
857                         len = 0;
858                         break;
859                 }
860                 break;
861
862         case RH_CLEAR_FEATURE | RH_CLASS:
863                 DBG("RH_CLEAR_FEATURE | RH_CLASS");
864
865                 switch (wValue) {
866                 case RH_C_HUB_LOCAL_POWER:
867                         DBG("C_HUB_LOCAL_POWER");
868                         len = 0;
869                         break;
870
871                 case RH_C_HUB_OVER_CURRENT:
872                         DBG("C_HUB_OVER_CURRENT");
873                         isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
874                         len = 0;
875                         break;
876                 }
877                 break;
878
879         case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
880                 DBG("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS");
881
882                 switch (wValue) {
883                 case RH_PORT_ENABLE:
884                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
885                                             RH_PS_CCS);
886                         len = 0;
887                         break;
888
889                 case RH_PORT_SUSPEND:
890                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
891                                             RH_PS_POCI);
892                         len = 0;
893                         break;
894
895                 case RH_PORT_POWER:
896                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
897                                             RH_PS_LSDA);
898                         len = 0;
899                         break;
900
901                 case RH_C_PORT_CONNECTION:
902                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
903                                             RH_PS_CSC);
904                         len = 0;
905                         break;
906
907                 case RH_C_PORT_ENABLE:
908                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
909                                             RH_PS_PESC);
910                         len = 0;
911                         break;
912
913                 case RH_C_PORT_SUSPEND:
914                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
915                                             RH_PS_PSSC);
916                         len = 0;
917                         break;
918
919                 case RH_C_PORT_OVER_CURRENT:
920                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
921                                             RH_PS_POCI);
922                         len = 0;
923                         break;
924
925                 case RH_C_PORT_RESET:
926                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
927                                             RH_PS_PRSC);
928                         len = 0;
929                         break;
930
931                 default:
932                         ERR("invalid wValue");
933                         stat = USB_ST_STALLED;
934                 }
935
936                 isp116x_show_regs(isp116x);
937
938                 break;
939
940         case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
941                 DBG("RH_SET_FEATURE | RH_OTHER | RH_CLASS");
942
943                 switch (wValue) {
944                 case RH_PORT_SUSPEND:
945                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
946                                             RH_PS_PSS);
947                         len = 0;
948                         break;
949
950                 case RH_PORT_RESET:
951                         /* Spin until any current reset finishes */
952                         while (1) {
953                                 tmp =
954                                     isp116x_read_reg32(isp116x,
955                                                        HCRHPORT1 + wIndex - 1);
956                                 if (!(tmp & RH_PS_PRS))
957                                         break;
958                                 wait_ms(1);
959                         }
960                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
961                                             RH_PS_PRS);
962                         wait_ms(10);
963
964                         len = 0;
965                         break;
966
967                 case RH_PORT_POWER:
968                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
969                                             RH_PS_PPS);
970                         len = 0;
971                         break;
972
973                 case RH_PORT_ENABLE:
974                         isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
975                                             RH_PS_PES);
976                         len = 0;
977                         break;
978
979                 default:
980                         ERR("invalid wValue");
981                         stat = USB_ST_STALLED;
982                 }
983
984                 isp116x_show_regs(isp116x);
985
986                 break;
987
988         case RH_SET_ADDRESS:
989                 DBG("RH_SET_ADDRESS");
990
991                 rh_devnum = wValue;
992                 len = 0;
993                 break;
994
995         case RH_GET_DESCRIPTOR:
996                 DBG("RH_GET_DESCRIPTOR: %x, %d", wValue, wLength);
997
998                 switch (wValue) {
999                 case (USB_DT_DEVICE << 8):      /* device descriptor */
1000                         len = min_t(unsigned int,
1001                                     leni, min_t(unsigned int,
1002                                                 sizeof(root_hub_dev_des),
1003                                                 wLength));
1004                         data_buf = root_hub_dev_des;
1005                         break;
1006
1007                 case (USB_DT_CONFIG << 8):      /* configuration descriptor */
1008                         len = min_t(unsigned int,
1009                                     leni, min_t(unsigned int,
1010                                                 sizeof(root_hub_config_des),
1011                                                 wLength));
1012                         data_buf = root_hub_config_des;
1013                         break;
1014
1015                 case ((USB_DT_STRING << 8) | 0x00):     /* string 0 descriptors */
1016                         len = min_t(unsigned int,
1017                                     leni, min_t(unsigned int,
1018                                                 sizeof(root_hub_str_index0),
1019                                                 wLength));
1020                         data_buf = root_hub_str_index0;
1021                         break;
1022
1023                 case ((USB_DT_STRING << 8) | 0x01):     /* string 1 descriptors */
1024                         len = min_t(unsigned int,
1025                                     leni, min_t(unsigned int,
1026                                                 sizeof(root_hub_str_index1),
1027                                                 wLength));
1028                         data_buf = root_hub_str_index1;
1029                         break;
1030
1031                 default:
1032                         ERR("invalid wValue");
1033                         stat = USB_ST_STALLED;
1034                 }
1035
1036                 break;
1037
1038         case RH_GET_DESCRIPTOR | RH_CLASS:
1039                 DBG("RH_GET_DESCRIPTOR | RH_CLASS");
1040
1041                 tmp = isp116x_read_reg32(isp116x, HCRHDESCA);
1042
1043                 data_buf[0] = 0x09;     /* min length; */
1044                 data_buf[1] = 0x29;
1045                 data_buf[2] = tmp & RH_A_NDP;
1046                 data_buf[3] = 0;
1047                 if (tmp & RH_A_PSM)     /* per-port power switching? */
1048                         data_buf[3] |= 0x01;
1049                 if (tmp & RH_A_NOCP)    /* no overcurrent reporting? */
1050                         data_buf[3] |= 0x10;
1051                 else if (tmp & RH_A_OCPM)       /* per-port overcurrent rep? */
1052                         data_buf[3] |= 0x08;
1053
1054                 /* Corresponds to data_buf[4-7] */
1055                 datab[1] = 0;
1056                 data_buf[5] = (tmp & RH_A_POTPGT) >> 24;
1057
1058                 tmp = isp116x_read_reg32(isp116x, HCRHDESCB);
1059
1060                 data_buf[7] = tmp & RH_B_DR;
1061                 if (data_buf[2] < 7)
1062                         data_buf[8] = 0xff;
1063                 else {
1064                         data_buf[0] += 2;
1065                         data_buf[8] = (tmp & RH_B_DR) >> 8;
1066                         data_buf[10] = data_buf[9] = 0xff;
1067                 }
1068
1069                 len = min_t(unsigned int, leni,
1070                             min_t(unsigned int, data_buf[0], wLength));
1071                 break;
1072
1073         case RH_GET_CONFIGURATION:
1074                 DBG("RH_GET_CONFIGURATION");
1075
1076                 *(__u8 *) data_buf = 0x01;
1077                 len = 1;
1078                 break;
1079
1080         case RH_SET_CONFIGURATION:
1081                 DBG("RH_SET_CONFIGURATION");
1082
1083                 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPSC);
1084                 len = 0;
1085                 break;
1086
1087         default:
1088                 ERR("*** *** *** unsupported root hub command *** *** ***");
1089                 stat = USB_ST_STALLED;
1090         }
1091
1092         len = min_t(int, len, leni);
1093         if (buffer != data_buf)
1094                 memcpy(buffer, data_buf, len);
1095
1096         dev->act_len = len;
1097         dev->status = stat;
1098         DBG("dev act_len %d, status %d", dev->act_len, dev->status);
1099
1100         dump_msg(dev, pipe, buffer, transfer_len, "RH(ret)");
1101
1102         return stat;
1103 }
1104
1105 /* --- Transfer functions -------------------------------------------------- */
1106
1107 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1108                    int len, int interval)
1109 {
1110         DBG("dev=%p pipe=%#lx buf=%p size=%d int=%d",
1111             dev, pipe, buffer, len, interval);
1112
1113         return -1;
1114 }
1115
1116 int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1117                        int len, struct devrequest *setup)
1118 {
1119         int devnum = usb_pipedevice(pipe);
1120         int epnum = usb_pipeendpoint(pipe);
1121         int max = max_transfer_len(dev, pipe);
1122         int dir_in = usb_pipein(pipe);
1123         int done, ret;
1124
1125         /* Control message is for the HUB? */
1126         if (devnum == rh_devnum)
1127                 return isp116x_submit_rh_msg(dev, pipe, buffer, len, setup);
1128
1129         /* Ok, no HUB message so send the message to the device */
1130
1131         /* Setup phase */
1132         DBG("--- SETUP PHASE --------------------------------");
1133         usb_settoggle(dev, epnum, 1, 0);
1134         ret = isp116x_submit_job(dev, pipe,
1135                                  PTD_DIR_SETUP,
1136                                  setup, sizeof(struct devrequest));
1137         if (ret < 0) {
1138                 DBG("control setup phase error (ret = %d", ret);
1139                 return -1;
1140         }
1141
1142         /* Data phase */
1143         DBG("--- DATA PHASE ---------------------------------");
1144         done = 0;
1145         usb_settoggle(dev, epnum, !dir_in, 1);
1146         while (done < len) {
1147                 ret = isp116x_submit_job(dev, pipe,
1148                                          dir_in ? PTD_DIR_IN : PTD_DIR_OUT,
1149                                          (__u8 *) buffer + done,
1150                                          max > len - done ? len - done : max);
1151                 if (ret < 0) {
1152                         DBG("control data phase error (ret = %d)", ret);
1153                         return -1;
1154                 }
1155                 done += ret;
1156
1157                 if (dir_in && ret < max)        /* short packet */
1158                         break;
1159         }
1160
1161         /* Status phase */
1162         DBG("--- STATUS PHASE -------------------------------");
1163         usb_settoggle(dev, epnum, !dir_in, 1);
1164         ret = isp116x_submit_job(dev, pipe,
1165                                  !dir_in ? PTD_DIR_IN : PTD_DIR_OUT, NULL, 0);
1166         if (ret < 0) {
1167                 DBG("control status phase error (ret = %d", ret);
1168                 return -1;
1169         }
1170
1171         dev->act_len = done;
1172
1173         dump_msg(dev, pipe, buffer, len, "DEV(ret)");
1174
1175         return done;
1176 }
1177
1178 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1179                     int len)
1180 {
1181         int dir_out = usb_pipeout(pipe);
1182         int max = max_transfer_len(dev, pipe);
1183         int done, ret;
1184
1185         DBG("--- BULK ---------------------------------------");
1186         DBG("dev=%ld pipe=%ld buf=%p size=%d dir_out=%d",
1187             usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
1188
1189         done = 0;
1190         while (done < len) {
1191                 ret = isp116x_submit_job(dev, pipe,
1192                                          !dir_out ? PTD_DIR_IN : PTD_DIR_OUT,
1193                                          (__u8 *) buffer + done,
1194                                          max > len - done ? len - done : max);
1195                 if (ret < 0) {
1196                         DBG("error on bulk message (ret = %d)", ret);
1197                         return -1;
1198                 }
1199
1200                 done += ret;
1201
1202                 if (!dir_out && ret < max)      /* short packet */
1203                         break;
1204         }
1205
1206         dev->act_len = done;
1207
1208         return 0;
1209 }
1210
1211 /* --- Basic functions ----------------------------------------------------- */
1212
1213 static int isp116x_sw_reset(struct isp116x *isp116x)
1214 {
1215         int retries = 15;
1216         int ret = 0;
1217
1218         DBG("");
1219
1220         isp116x->disabled = 1;
1221
1222         isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
1223         isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
1224         while (--retries) {
1225                 /* It usually resets within 1 ms */
1226                 wait_ms(1);
1227                 if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
1228                         break;
1229         }
1230         if (!retries) {
1231                 ERR("software reset timeout");
1232                 ret = -1;
1233         }
1234         return ret;
1235 }
1236
1237 static int isp116x_reset(struct isp116x *isp116x)
1238 {
1239         unsigned long t;
1240         u16 clkrdy = 0;
1241         int ret, timeout = 15 /* ms */ ;
1242
1243         DBG("");
1244
1245         ret = isp116x_sw_reset(isp116x);
1246         if (ret)
1247                 return ret;
1248
1249         for (t = 0; t < timeout; t++) {
1250                 clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
1251                 if (clkrdy)
1252                         break;
1253                 wait_ms(1);
1254         }
1255         if (!clkrdy) {
1256                 ERR("clock not ready after %dms", timeout);
1257                 /* After sw_reset the clock won't report to be ready, if
1258                    H_WAKEUP pin is high. */
1259                 ERR("please make sure that the H_WAKEUP pin is pulled low!");
1260                 ret = -1;
1261         }
1262         return ret;
1263 }
1264
1265 static void isp116x_stop(struct isp116x *isp116x)
1266 {
1267         u32 val;
1268
1269         DBG("");
1270
1271         isp116x_write_reg16(isp116x, HCuPINTENB, 0);
1272
1273         /* Switch off ports' power, some devices don't come up
1274            after next 'start' without this */
1275         val = isp116x_read_reg32(isp116x, HCRHDESCA);
1276         val &= ~(RH_A_NPS | RH_A_PSM);
1277         isp116x_write_reg32(isp116x, HCRHDESCA, val);
1278         isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
1279
1280         isp116x_sw_reset(isp116x);
1281 }
1282
1283 /*
1284  *  Configure the chip. The chip must be successfully reset by now.
1285  */
1286 static int isp116x_start(struct isp116x *isp116x)
1287 {
1288         struct isp116x_platform_data *board = isp116x->board;
1289         u32 val;
1290
1291         DBG("");
1292
1293         /* Clear interrupt status and disable all interrupt sources */
1294         isp116x_write_reg16(isp116x, HCuPINT, 0xff);
1295         isp116x_write_reg16(isp116x, HCuPINTENB, 0);
1296
1297         isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
1298         isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
1299
1300         /* Hardware configuration */
1301         val = HCHWCFG_DBWIDTH(1);
1302         if (board->sel15Kres)
1303                 val |= HCHWCFG_15KRSEL;
1304         /* Remote wakeup won't work without working clock */
1305         if (board->remote_wakeup_enable)
1306                 val |= HCHWCFG_CLKNOTSTOP;
1307         if (board->oc_enable)
1308                 val |= HCHWCFG_ANALOG_OC;
1309         isp116x_write_reg16(isp116x, HCHWCFG, val);
1310
1311         /* --- Root hub configuration */
1312         val = (25 << 24) & RH_A_POTPGT;
1313         /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
1314            be always set. Yet, instead, we request individual port
1315            power switching. */
1316         val |= RH_A_PSM;
1317         /* Report overcurrent per port */
1318         val |= RH_A_OCPM;
1319         isp116x_write_reg32(isp116x, HCRHDESCA, val);
1320         isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
1321
1322         val = RH_B_PPCM;
1323         isp116x_write_reg32(isp116x, HCRHDESCB, val);
1324         isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
1325
1326         val = 0;
1327         if (board->remote_wakeup_enable)
1328                 val |= RH_HS_DRWE;
1329         isp116x_write_reg32(isp116x, HCRHSTATUS, val);
1330         isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
1331
1332         isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
1333
1334         /* Go operational */
1335         val = HCCONTROL_USB_OPER;
1336         if (board->remote_wakeup_enable)
1337                 val |= HCCONTROL_RWE;
1338         isp116x_write_reg32(isp116x, HCCONTROL, val);
1339
1340         /* Disable ports to avoid race in device enumeration */
1341         isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
1342         isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
1343
1344         isp116x_show_regs(isp116x);
1345
1346         isp116x->disabled = 0;
1347
1348         return 0;
1349 }
1350
1351 /* --- Init functions ------------------------------------------------------ */
1352
1353 int isp116x_check_id(struct isp116x *isp116x)
1354 {
1355         int val;
1356
1357         val = isp116x_read_reg16(isp116x, HCCHIPID);
1358         if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
1359                 ERR("invalid chip ID %04x", val);
1360                 return -1;
1361         }
1362
1363         return 0;
1364 }
1365
1366 int usb_lowlevel_init(void)
1367 {
1368         struct isp116x *isp116x = &isp116x_dev;
1369
1370         DBG("");
1371
1372         /* Init device registers addr */
1373         isp116x->addr_reg = (u16 *) ISP116X_HCD_ADDR;
1374         isp116x->data_reg = (u16 *) ISP116X_HCD_DATA;
1375
1376         /* Setup specific board settings */
1377 #ifdef ISP116X_HCD_SEL15kRES
1378         isp116x_board.sel15Kres = 1;
1379 #endif
1380 #ifdef ISP116X_HCD_OC_ENABLE
1381         isp116x_board.oc_enable = 1;
1382 #endif
1383 #ifdef ISP116X_HCD_REMOTE_WAKEUP_ENABLE
1384         isp116x_board.remote_wakeup_enable = 1;
1385 #endif
1386         isp116x->board = &isp116x_board;
1387
1388         /* Try to get ISP116x silicon chip ID */
1389         if (isp116x_check_id(isp116x) < 0)
1390                 return -1;
1391
1392         isp116x->disabled = 1;
1393         isp116x->sleeping = 0;
1394
1395         isp116x_reset(isp116x);
1396         isp116x_start(isp116x);
1397
1398         return 0;
1399 }
1400
1401 int usb_lowlevel_stop(void)
1402 {
1403         struct isp116x *isp116x = &isp116x_dev;
1404
1405         DBG("");
1406
1407         if (!isp116x->disabled)
1408                 isp116x_stop(isp116x);
1409
1410         return 0;
1411 }
1412
1413 #endif                          /* CONFIG_USB_ISP116X_HCD */