2 * Kirkwood-specific code for
3 * USB Enhanced Host Controller Interface (EHCI) driver
8 #include "../port/lib.h"
13 #include "../port/error.h"
14 #include "../port/usb.h"
17 #define WINTARG(ctl) (((ctl) >> 4) & 017)
18 #define WINATTR(ctl) (((ctl) >> 8) & 0377)
19 #define WIN64KSIZE(ctl) (((ctl) >> 16) + 1)
21 #define SIZETO64KSIZE(size) ((size) / (64*1024) - 1)
27 typedef struct Kwusb Kwusb;
28 typedef struct Kwusbtt Kwusbtt;
29 typedef struct Usbwin Usbwin;
31 /* kirkwood usb transaction translator registers? (undocumented) */
32 struct Kwusbtt { /* at soc.ehci */
43 /* kirkwood usb bridge & phy registers */
44 struct Kwusb { /* at offset 0x300 from soc.ehci */
45 ulong bcs; /* bridge ctl & sts */
46 uchar _pad0[0x310-0x304];
48 ulong bic; /* bridge intr. cause */
49 ulong bim; /* bridge intr. mask */
51 ulong bea; /* bridge error addr. */
53 ulong ctl; /* see Winenable in io.h */
57 ulong phycfg; /* phy config. */
58 uchar _pad3[0x400-0x364];
60 ulong pwrctl; /* power control */
61 uchar _pad4[0x410-0x404];
62 ulong phypll; /* phy pll control */
63 uchar _pad5[0x420-0x414];
64 ulong phytxctl; /* phy transmit control */
65 uchar _pad6[0x430-0x424];
66 ulong phyrxctl; /* phy receive control */
67 uchar _pad7[0x440-0x434];
68 ulong phyivref; /* phy ivref control */
71 static Ctlr* ctlrs[Nhcis];
77 ulong ctl, targ, attr, size64k;
83 map = (Kwusb *)(soc.ehci + 0x300);
84 for (i = 0; i < nelem(map->win); i++) {
87 if (ctl & Winenable) {
90 size64k = WIN64KSIZE(ctl);
91 print("usbehci: address map window %d: "
92 "targ %ld attr %#lux size %,ld addr %#lux\n",
93 i, targ, attr, size64k * 64*1024, win->base);
98 /* assumes ctlr is ilocked */
100 ctlrreset(Ctlr *ctlr)
106 opio->cmd |= Chcreset;
108 /* wait for it to come out of reset */
109 for(i = 0; i < 100 && opio->cmd & Chcreset; i++)
112 print("ehci %#p controller reset timed out\n", ctlr->capio);
114 * Marvell errata FE-USB-340 workaround: 1 << 4 magic:
115 * disable streaming. Magic 3 (usb host mode) from the linux driver
116 * makes it work. Ick.
118 opio->usbmode |= 1 << 4 | 3;
123 * configure window `win' as 256MB dram with attribute `attr' and
127 setaddrwin(Kwusb *kw, int win, int attr, ulong base)
129 kw->win[win].ctl = Winenable | Targdram << 4 | attr << 8 |
130 SIZETO64KSIZE(256*MB) << 16;
131 kw->win[win].base = base;
135 ehcireset(Ctlr *ctlr)
143 dprint("ehci %#p reset\n", ctlr->capio);
146 kw = (Kwusb *)(soc.ehci + 0x300);
148 kw->bim = (1<<4) - 1; /* enable all defined intrs */
152 * clear high 32 bits of address signals if it's 64 bits capable.
153 * This is probably not needed but it does not hurt and others do it.
155 if((ctlr->capio->capparms & C64) != 0){
156 dprint("ehci: 64 bits\n");
160 /* requesting more interrupts per µframe may miss interrupts */
161 opio->cmd |= Citc8; /* 1 intr. per ms */
162 switch(opio->cmd & Cflsmask){
164 ctlr->nframes = 1024;
173 panic("ehci: unknown fls %ld", opio->cmd & Cflsmask);
175 dprint("ehci: %d frames\n", ctlr->nframes);
178 * set up the USB address map (bridge address decoding)
180 for (i = 0; i < nelem(kw->win); i++)
181 kw->win[i].ctl = kw->win[i].base = 0;
184 setaddrwin(kw, 0, Attrcs0, 0);
185 setaddrwin(kw, 1, Attrcs1, 256*MB);
189 if (kw->bcs & (1 << 4))
190 print("usbehci: not swapping bytes\n");
192 print("usbehci: swapping bytes\n");
193 addrmapdump(); /* verify sanity */
195 kw->pwrctl |= 1 << 0 | 1 << 1; /* Pu | PuPll */
199 * Marvell guideline GL-USB-160.
201 kw->phypll |= 1 << 21; /* VCOCAL_START: PLL calibration */
204 kw->phypll &= ~(1 << 21);
206 v = kw->phytxctl & ~(017 << 27 | 7); /* REG_EXT_FS_RCALL & AMP_2_0 */
209 print("usbehci: bad 6281 soc rev %d\n", m->socrev);
220 /* REG_EXT_FS_RCALL_EN | REG_RCAL_START | AMP_2_0 */
221 kw->phytxctl = v | 1 << 26 | 1 << 12 | amp;
224 kw->phytxctl &= ~(1 << 12);
226 v = kw->phyrxctl & ~(3 << 2 | 017 << 4); /* LPF_COEF_1_0 & SQ_THRESH_3_0 */
227 kw->phyrxctl = v | 1 << 2 | 8 << 4;
229 v = kw->phyivref & ~(3 << 8); /* TXVDD12 */
230 kw->phyivref = v | txvdd << 8;
240 setdebug(Hci*, int d)
265 findehcis(void) /* actually just use fixed addresses on sheeva */
269 static int already = 0;
275 ctlr = smalloc(sizeof(Ctlr));
276 /* the sheeva's usb 2.0 otg uses a superset of the ehci registers */
277 ctlr->capio = (Ecapio *)(soc.ehci + 0x100);
278 ctlr->opio = (Eopio *) (soc.ehci + 0x140);
279 dprint("usbehci: port %#p\n", ctlr->capio);
281 for(i = 0; i < Nhcis; i++)
287 print("ehci: bug: more than %d controllers\n", Nhcis);
293 static Lock resetlck;
302 * Any adapter matches if no hp->port is supplied,
303 * otherwise the ports must match.
306 for(i = 0; i < Nhcis && ctlrs[i] != nil; i++){
308 if(ctlr->active == 0)
309 if(hp->port == 0 || hp->port == (uintptr)ctlr->capio){
315 if(ctlrs[i] == nil || i == Nhcis)
319 hp->port = (uintptr)ctlr->capio;
324 hp->nports = capio->parms & Cnports;
326 ddprint("echi: %s, ncc %lud npcc %lud\n",
327 capio->parms & 0x10000 ? "leds" : "no leds",
328 (capio->parms >> 12) & 0xf, (capio->parms >> 8) & 0xf);
329 ddprint("ehci: routing %s, %sport power ctl, %d ports\n",
330 capio->parms & 0x40 ? "explicit" : "automatic",
331 capio->parms & 0x10 ? "" : "no ", hp->nports);
333 ctlr->tdalloc = ucallocalign;
334 ctlr->dmaalloc = ucalloc;
335 ctlr->dmafree = ucfree;
341 * Linkage to the generic HCI driver.
344 hp->shutdown = shutdown;
345 hp->debug = setdebug;
347 intrenable(Irqlo, hp->irq, hp->interrupt, hp, hp->type);
355 addhcitype("ehci", reset);