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