usbehcikw.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Kirkwood-specific code for
  3. * USB Enhanced Host Controller Interface (EHCI) driver
  4. * High speed USB 2.0.
  5. */
  6. #include "u.h"
  7. #include "../port/lib.h"
  8. #include "mem.h"
  9. #include "dat.h"
  10. #include "fns.h"
  11. #include "io.h"
  12. #include "../port/error.h"
  13. #include "../port/usb.h"
  14. #include "usbehci.h"
  15. //#include "uncached.h"
  16. #define WINTARG(ctl) (((ctl) >> 4) & 017)
  17. #define WINATTR(ctl) (((ctl) >> 8) & 0377)
  18. #define WIN64KSIZE(ctl) (((ctl) >> 16) + 1)
  19. #define SIZETO64KSIZE(size) ((size) / (64*1024) - 1)
  20. enum {
  21. Debug = 0,
  22. };
  23. typedef struct Kwusb Kwusb;
  24. typedef struct Kwusbtt Kwusbtt;
  25. typedef struct Usbwin Usbwin;
  26. /* kirkwood usb transaction translator registers? (undocumented) */
  27. struct Kwusbtt { /* at soc.ehci */
  28. ulong id;
  29. ulong hwgeneral;
  30. ulong hwhost;
  31. ulong hwdevice;
  32. ulong hwtxbuf;
  33. ulong hwrxbuf;
  34. ulong hwtttxbuf;
  35. ulong hwttrxbuf;
  36. };
  37. /* kirkwood usb bridge & phy registers */
  38. struct Kwusb { /* at offset 0x300 from soc.ehci */
  39. ulong bcs; /* bridge ctl & sts */
  40. uchar _pad0[0x310-0x304];
  41. ulong bic; /* bridge intr. cause */
  42. ulong bim; /* bridge intr. mask */
  43. ulong _pad1;
  44. ulong bea; /* bridge error addr. */
  45. struct Usbwin {
  46. ulong ctl; /* see Winenable in io.h */
  47. ulong base;
  48. ulong _pad2[2];
  49. } win[4];
  50. ulong phycfg; /* phy config. */
  51. uchar _pad3[0x400-0x364];
  52. ulong pwrctl; /* power control */
  53. uchar _pad4[0x410-0x404];
  54. ulong phypll; /* phy pll control */
  55. uchar _pad5[0x420-0x414];
  56. ulong phytxctl; /* phy transmit control */
  57. uchar _pad6[0x430-0x424];
  58. ulong phyrxctl; /* phy receive control */
  59. uchar _pad7[0x440-0x434];
  60. ulong phyivref; /* phy ivref control */
  61. };
  62. static Ctlr* ctlrs[Nhcis];
  63. static void
  64. addrmapdump(void)
  65. {
  66. int i;
  67. ulong ctl, targ, attr, size64k;
  68. Kwusb *map;
  69. Usbwin *win;
  70. if (!Debug)
  71. return;
  72. map = (Kwusb *)(soc.ehci + 0x300);
  73. for (i = 0; i < nelem(map->win); i++) {
  74. win = &map->win[i];
  75. ctl = win->ctl;
  76. if (ctl & Winenable) {
  77. targ = WINTARG(ctl);
  78. attr = WINATTR(ctl);
  79. size64k = WIN64KSIZE(ctl);
  80. print("usbehci: address map window %d: "
  81. "targ %ld attr %#lux size %,ld addr %#lux\n",
  82. i, targ, attr, size64k * 64*1024, win->base);
  83. }
  84. }
  85. }
  86. /* assumes ctlr is ilocked */
  87. static void
  88. ctlrreset(Ctlr *ctlr)
  89. {
  90. int i;
  91. Eopio *opio;
  92. opio = ctlr->opio;
  93. opio->cmd |= Chcreset;
  94. coherence();
  95. /* wait for it to come out of reset */
  96. for(i = 0; i < 100 && opio->cmd & Chcreset; i++)
  97. delay(1);
  98. if(i >= 100)
  99. print("ehci %#p controller reset timed out\n", ctlr->capio);
  100. /*
  101. * Marvell errata FE-USB-340 workaround: 1 << 4 magic:
  102. * disable streaming. Magic 3 (usb host mode) from the linux driver
  103. * makes it work. Ick.
  104. */
  105. opio->usbmode |= 1 << 4 | 3;
  106. coherence();
  107. }
  108. /*
  109. * configure window `win' as 256MB dram with attribute `attr' and
  110. * base address
  111. */
  112. static void
  113. setaddrwin(Kwusb *kw, int win, int attr, ulong base)
  114. {
  115. kw->win[win].ctl = Winenable | Targdram << 4 | attr << 8 |
  116. SIZETO64KSIZE(256*MB) << 16;
  117. kw->win[win].base = base;
  118. }
  119. static void
  120. ehcireset(Ctlr *ctlr)
  121. {
  122. int i, amp, txvdd;
  123. ulong v;
  124. Eopio *opio;
  125. Kwusb *kw;
  126. ilock(ctlr);
  127. dprint("ehci %#p reset\n", ctlr->capio);
  128. opio = ctlr->opio;
  129. kw = (Kwusb *)(soc.ehci + 0x300);
  130. kw->bic = 0;
  131. kw->bim = (1<<4) - 1; /* enable all defined intrs */
  132. ctlrreset(ctlr);
  133. /*
  134. * clear high 32 bits of address signals if it's 64 bits capable.
  135. * This is probably not needed but it does not hurt and others do it.
  136. */
  137. if((ctlr->capio->capparms & C64) != 0){
  138. dprint("ehci: 64 bits\n");
  139. opio->seg = 0;
  140. }
  141. /* requesting more interrupts per µframe may miss interrupts */
  142. opio->cmd |= Citc8; /* 1 intr. per ms */
  143. switch(opio->cmd & Cflsmask){
  144. case Cfls1024:
  145. ctlr->nframes = 1024;
  146. break;
  147. case Cfls512:
  148. ctlr->nframes = 512;
  149. break;
  150. case Cfls256:
  151. ctlr->nframes = 256;
  152. break;
  153. default:
  154. panic("ehci: unknown fls %ld", opio->cmd & Cflsmask);
  155. }
  156. dprint("ehci: %d frames\n", ctlr->nframes);
  157. /*
  158. * set up the USB address map (bridge address decoding)
  159. */
  160. for (i = 0; i < nelem(kw->win); i++)
  161. kw->win[i].ctl = kw->win[i].base = 0;
  162. coherence();
  163. setaddrwin(kw, 0, Attrcs0, 0);
  164. setaddrwin(kw, 1, Attrcs1, 256*MB);
  165. coherence();
  166. if (Debug)
  167. if (kw->bcs & (1 << 4))
  168. print("usbehci: not swapping bytes\n");
  169. else
  170. print("usbehci: swapping bytes\n");
  171. addrmapdump(); /* verify sanity */
  172. kw->pwrctl |= 1 << 0 | 1 << 1; /* Pu | PuPll */
  173. coherence();
  174. /*
  175. * Marvell guideline GL-USB-160.
  176. */
  177. kw->phypll |= 1 << 21; /* VCOCAL_START: PLL calibration */
  178. coherence();
  179. microdelay(100);
  180. kw->phypll &= ~(1 << 21);
  181. v = kw->phytxctl & ~(017 << 27 | 7); /* REG_EXT_FS_RCALL & AMP_2_0 */
  182. switch (m->socrev) {
  183. default:
  184. print("usbehci: bad 6281 soc rev %d\n", m->socrev);
  185. /* fall through */
  186. case Socreva0:
  187. amp = 4;
  188. txvdd = 1;
  189. break;
  190. case Socreva1:
  191. amp = 3;
  192. txvdd = 3;
  193. break;
  194. }
  195. /* REG_EXT_FS_RCALL_EN | REG_RCAL_START | AMP_2_0 */
  196. kw->phytxctl = v | 1 << 26 | 1 << 12 | amp;
  197. coherence();
  198. microdelay(100);
  199. kw->phytxctl &= ~(1 << 12);
  200. v = kw->phyrxctl & ~(3 << 2 | 017 << 4); /* LPF_COEF_1_0 & SQ_THRESH_3_0 */
  201. kw->phyrxctl = v | 1 << 2 | 8 << 4;
  202. v = kw->phyivref & ~(3 << 8); /* TXVDD12 */
  203. kw->phyivref = v | txvdd << 8;
  204. coherence();
  205. ehcirun(ctlr, 0);
  206. ctlrreset(ctlr);
  207. iunlock(ctlr);
  208. }
  209. static void
  210. setdebug(Hci*, int d)
  211. {
  212. ehcidebug = d;
  213. }
  214. static void
  215. shutdown(Hci *hp)
  216. {
  217. Ctlr *ctlr;
  218. Eopio *opio;
  219. ctlr = hp->aux;
  220. ilock(ctlr);
  221. ctlrreset(ctlr);
  222. delay(100);
  223. ehcirun(ctlr, 0);
  224. opio = ctlr->opio;
  225. opio->frbase = 0;
  226. coherence();
  227. iunlock(ctlr);
  228. }
  229. static void
  230. findehcis(void) /* actually just use fixed addresses on sheeva */
  231. {
  232. int i;
  233. Ctlr *ctlr;
  234. static int already = 0;
  235. if(already)
  236. return;
  237. already = 1;
  238. ctlr = mallocz(sizeof(Ctlr), 1);
  239. /* the sheeva's usb 2.0 otg uses a superset of the ehci registers */
  240. ctlr->capio = (Ecapio *)(soc.ehci + 0x100);
  241. ctlr->opio = (Eopio *) (soc.ehci + 0x140);
  242. dprint("usbehci: port %#p\n", ctlr->capio);
  243. for(i = 0; i < Nhcis; i++)
  244. if(ctlrs[i] == nil){
  245. ctlrs[i] = ctlr;
  246. break;
  247. }
  248. if(i == Nhcis)
  249. print("ehci: bug: more than %d controllers\n", Nhcis);
  250. }
  251. static int
  252. reset(Hci *hp)
  253. {
  254. static Lock resetlck;
  255. int i;
  256. Ctlr *ctlr;
  257. Ecapio *capio;
  258. ilock(&resetlck);
  259. findehcis();
  260. /*
  261. * Any adapter matches if no hp->port is supplied,
  262. * otherwise the ports must match.
  263. */
  264. ctlr = nil;
  265. for(i = 0; i < Nhcis && ctlrs[i] != nil; i++){
  266. ctlr = ctlrs[i];
  267. if(ctlr->active == 0)
  268. if(hp->port == 0 || hp->port == (uintptr)ctlr->capio){
  269. ctlr->active = 1;
  270. break;
  271. }
  272. }
  273. iunlock(&resetlck);
  274. if(ctlrs[i] == nil || i == Nhcis)
  275. return -1;
  276. hp->aux = ctlr;
  277. hp->port = (uintptr)ctlr->capio;
  278. hp->irq = IRQ0usb0;
  279. hp->tbdf = 0;
  280. capio = ctlr->capio;
  281. hp->nports = capio->parms & Cnports;
  282. ddprint("echi: %s, ncc %lud npcc %lud\n",
  283. capio->parms & 0x10000 ? "leds" : "no leds",
  284. (capio->parms >> 12) & 0xf, (capio->parms >> 8) & 0xf);
  285. ddprint("ehci: routing %s, %sport power ctl, %d ports\n",
  286. capio->parms & 0x40 ? "explicit" : "automatic",
  287. capio->parms & 0x10 ? "" : "no ", hp->nports);
  288. ehcireset(ctlr);
  289. ehcimeminit(ctlr);
  290. /*
  291. * Linkage to the generic HCI driver.
  292. */
  293. ehcilinkage(hp);
  294. hp->shutdown = shutdown;
  295. hp->debug = setdebug;
  296. return 0;
  297. }
  298. void
  299. usbehcilink(void)
  300. {
  301. addhcitype("ehci", reset);
  302. }