ARM: OMAP1: OHCI: use platform_data fn ptr to enable OCPI bus
[pandora-kernel.git] / arch / arm / mach-omap1 / usb.c
1 /*
2  * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx
3  *
4  * Copyright (C) 2004 Texas Instruments, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/init.h>
24 #include <linux/platform_device.h>
25 #include <linux/io.h>
26
27 #include <asm/irq.h>
28
29 #include <plat/mux.h>
30 #include <plat/usb.h>
31
32 #include "common.h"
33
34 /* These routines should handle the standard chip-specific modes
35  * for usb0/1/2 ports, covering basic mux and transceiver setup.
36  *
37  * Some board-*.c files will need to set up additional mux options,
38  * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
39  */
40
41 /* TESTED ON:
42  *  - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables
43  *  - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables
44  *  - 5912 OSK UDC, with *nonstandard* A-to-A cable
45  *  - 1510 Innovator UDC with bundled usb0 cable
46  *  - 1510 Innovator OHCI with bundled usb1/usb2 cable
47  *  - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS
48  *  - 1710 custom development board using alternate pin group
49  *  - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables
50  */
51
52 #define INT_USB_IRQ_GEN         IH2_BASE + 20
53 #define INT_USB_IRQ_NISO        IH2_BASE + 30
54 #define INT_USB_IRQ_ISO         IH2_BASE + 29
55 #define INT_USB_IRQ_HGEN        INT_USB_HHC_1
56 #define INT_USB_IRQ_OTG         IH2_BASE + 8
57
58 #ifdef  CONFIG_USB_GADGET_OMAP
59
60 static struct resource udc_resources[] = {
61         /* order is significant! */
62         {               /* registers */
63                 .start          = UDC_BASE,
64                 .end            = UDC_BASE + 0xff,
65                 .flags          = IORESOURCE_MEM,
66         }, {            /* general IRQ */
67                 .start          = INT_USB_IRQ_GEN,
68                 .flags          = IORESOURCE_IRQ,
69         }, {            /* PIO IRQ */
70                 .start          = INT_USB_IRQ_NISO,
71                 .flags          = IORESOURCE_IRQ,
72         }, {            /* SOF IRQ */
73                 .start          = INT_USB_IRQ_ISO,
74                 .flags          = IORESOURCE_IRQ,
75         },
76 };
77
78 static u64 udc_dmamask = ~(u32)0;
79
80 static struct platform_device udc_device = {
81         .name           = "omap_udc",
82         .id             = -1,
83         .dev = {
84                 .dma_mask               = &udc_dmamask,
85                 .coherent_dma_mask      = 0xffffffff,
86         },
87         .num_resources  = ARRAY_SIZE(udc_resources),
88         .resource       = udc_resources,
89 };
90
91 static inline void udc_device_init(struct omap_usb_config *pdata)
92 {
93         /* IRQ numbers for omap7xx */
94         if(cpu_is_omap7xx()) {
95                 udc_resources[1].start = INT_7XX_USB_GENI;
96                 udc_resources[2].start = INT_7XX_USB_NON_ISO;
97                 udc_resources[3].start = INT_7XX_USB_ISO;
98         }
99         pdata->udc_device = &udc_device;
100 }
101
102 #else
103
104 static inline void udc_device_init(struct omap_usb_config *pdata)
105 {
106 }
107
108 #endif
109
110 #if     defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
111
112 /* The dmamask must be set for OHCI to work */
113 static u64 ohci_dmamask = ~(u32)0;
114
115 static struct resource ohci_resources[] = {
116         {
117                 .start  = OMAP_OHCI_BASE,
118                 .end    = OMAP_OHCI_BASE + 0xff,
119                 .flags  = IORESOURCE_MEM,
120         },
121         {
122                 .start  = INT_USB_IRQ_HGEN,
123                 .flags  = IORESOURCE_IRQ,
124         },
125 };
126
127 static struct platform_device ohci_device = {
128         .name                   = "ohci",
129         .id                     = -1,
130         .dev = {
131                 .dma_mask               = &ohci_dmamask,
132                 .coherent_dma_mask      = 0xffffffff,
133         },
134         .num_resources  = ARRAY_SIZE(ohci_resources),
135         .resource               = ohci_resources,
136 };
137
138 static inline void ohci_device_init(struct omap_usb_config *pdata)
139 {
140         if (cpu_is_omap7xx())
141                 ohci_resources[1].start = INT_7XX_USB_HHC_1;
142         pdata->ohci_device = &ohci_device;
143         pdata->ocpi_enable = &ocpi_enable;
144 }
145
146 #else
147
148 static inline void ohci_device_init(struct omap_usb_config *pdata)
149 {
150 }
151
152 #endif
153
154 #if     defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
155
156 static struct resource otg_resources[] = {
157         /* order is significant! */
158         {
159                 .start          = OTG_BASE,
160                 .end            = OTG_BASE + 0xff,
161                 .flags          = IORESOURCE_MEM,
162         }, {
163                 .start          = INT_USB_IRQ_OTG,
164                 .flags          = IORESOURCE_IRQ,
165         },
166 };
167
168 static struct platform_device otg_device = {
169         .name           = "omap_otg",
170         .id             = -1,
171         .num_resources  = ARRAY_SIZE(otg_resources),
172         .resource       = otg_resources,
173 };
174
175 static inline void otg_device_init(struct omap_usb_config *pdata)
176 {
177         if (cpu_is_omap7xx())
178                 otg_resources[1].start = INT_7XX_USB_OTG;
179         pdata->otg_device = &otg_device;
180 }
181
182 #else
183
184 static inline void otg_device_init(struct omap_usb_config *pdata)
185 {
186 }
187
188 #endif
189
190 u32 __init omap1_usb0_init(unsigned nwires, unsigned is_device)
191 {
192         u32     syscon1 = 0;
193
194         if (nwires == 0) {
195                 if (!cpu_is_omap15xx()) {
196                         u32 l;
197
198                         /* pulldown D+/D- */
199                         l = omap_readl(USB_TRANSCEIVER_CTRL);
200                         l &= ~(3 << 1);
201                         omap_writel(l, USB_TRANSCEIVER_CTRL);
202                 }
203                 return 0;
204         }
205
206         if (is_device) {
207                 if (cpu_is_omap7xx()) {
208                         omap_cfg_reg(AA17_7XX_USB_DM);
209                         omap_cfg_reg(W16_7XX_USB_PU_EN);
210                         omap_cfg_reg(W17_7XX_USB_VBUSI);
211                         omap_cfg_reg(W18_7XX_USB_DMCK_OUT);
212                         omap_cfg_reg(W19_7XX_USB_DCRST);
213                 } else
214                         omap_cfg_reg(W4_USB_PUEN);
215         }
216
217         if (nwires == 2) {
218                 u32 l;
219
220                 // omap_cfg_reg(P9_USB_DP);
221                 // omap_cfg_reg(R8_USB_DM);
222
223                 if (cpu_is_omap15xx()) {
224                         /* This works on 1510-Innovator */
225                         return 0;
226                 }
227
228                 /* NOTES:
229                  *  - peripheral should configure VBUS detection!
230                  *  - only peripherals may use the internal D+/D- pulldowns
231                  *  - OTG support on this port not yet written
232                  */
233
234                 /* Don't do this for omap7xx -- it causes USB to not work correctly */
235                 if (!cpu_is_omap7xx()) {
236                         l = omap_readl(USB_TRANSCEIVER_CTRL);
237                         l &= ~(7 << 4);
238                         if (!is_device)
239                                 l |= (3 << 1);
240                         omap_writel(l, USB_TRANSCEIVER_CTRL);
241                 }
242
243                 return 3 << 16;
244         }
245
246         /* alternate pin config, external transceiver */
247         if (cpu_is_omap15xx()) {
248                 printk(KERN_ERR "no usb0 alt pin config on 15xx\n");
249                 return 0;
250         }
251
252         omap_cfg_reg(V6_USB0_TXD);
253         omap_cfg_reg(W9_USB0_TXEN);
254         omap_cfg_reg(W5_USB0_SE0);
255         if (nwires != 3)
256                 omap_cfg_reg(Y5_USB0_RCV);
257
258         /* NOTE:  SPEED and SUSP aren't configured here.  OTG hosts
259          * may be able to use I2C requests to set those bits along
260          * with VBUS switching and overcurrent detection.
261          */
262
263         if (nwires != 6) {
264                 u32 l;
265
266                 l = omap_readl(USB_TRANSCEIVER_CTRL);
267                 l &= ~CONF_USB2_UNI_R;
268                 omap_writel(l, USB_TRANSCEIVER_CTRL);
269         }
270
271         switch (nwires) {
272         case 3:
273                 syscon1 = 2;
274                 break;
275         case 4:
276                 syscon1 = 1;
277                 break;
278         case 6:
279                 syscon1 = 3;
280                 {
281                         u32 l;
282
283                         omap_cfg_reg(AA9_USB0_VP);
284                         omap_cfg_reg(R9_USB0_VM);
285                         l = omap_readl(USB_TRANSCEIVER_CTRL);
286                         l |= CONF_USB2_UNI_R;
287                         omap_writel(l, USB_TRANSCEIVER_CTRL);
288                 }
289                 break;
290         default:
291                 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
292                         0, nwires);
293         }
294
295         return syscon1 << 16;
296 }
297
298 u32 __init omap1_usb1_init(unsigned nwires)
299 {
300         u32     syscon1 = 0;
301
302         if (!cpu_is_omap15xx() && nwires != 6) {
303                 u32 l;
304
305                 l = omap_readl(USB_TRANSCEIVER_CTRL);
306                 l &= ~CONF_USB1_UNI_R;
307                 omap_writel(l, USB_TRANSCEIVER_CTRL);
308         }
309         if (nwires == 0)
310                 return 0;
311
312         /* external transceiver */
313         omap_cfg_reg(USB1_TXD);
314         omap_cfg_reg(USB1_TXEN);
315         if (nwires != 3)
316                 omap_cfg_reg(USB1_RCV);
317
318         if (cpu_is_omap15xx()) {
319                 omap_cfg_reg(USB1_SEO);
320                 omap_cfg_reg(USB1_SPEED);
321                 // SUSP
322         } else if (cpu_is_omap1610() || cpu_is_omap5912()) {
323                 omap_cfg_reg(W13_1610_USB1_SE0);
324                 omap_cfg_reg(R13_1610_USB1_SPEED);
325                 // SUSP
326         } else if (cpu_is_omap1710()) {
327                 omap_cfg_reg(R13_1710_USB1_SE0);
328                 // SUSP
329         } else {
330                 pr_debug("usb%d cpu unrecognized\n", 1);
331                 return 0;
332         }
333
334         switch (nwires) {
335         case 2:
336                 goto bad;
337         case 3:
338                 syscon1 = 2;
339                 break;
340         case 4:
341                 syscon1 = 1;
342                 break;
343         case 6:
344                 syscon1 = 3;
345                 omap_cfg_reg(USB1_VP);
346                 omap_cfg_reg(USB1_VM);
347                 if (!cpu_is_omap15xx()) {
348                         u32 l;
349
350                         l = omap_readl(USB_TRANSCEIVER_CTRL);
351                         l |= CONF_USB1_UNI_R;
352                         omap_writel(l, USB_TRANSCEIVER_CTRL);
353                 }
354                 break;
355         default:
356 bad:
357                 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
358                         1, nwires);
359         }
360
361         return syscon1 << 20;
362 }
363
364 u32 __init omap1_usb2_init(unsigned nwires, unsigned alt_pingroup)
365 {
366         u32     syscon1 = 0;
367
368         /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
369         if (alt_pingroup || nwires == 0)
370                 return 0;
371
372         if (!cpu_is_omap15xx() && nwires != 6) {
373                 u32 l;
374
375                 l = omap_readl(USB_TRANSCEIVER_CTRL);
376                 l &= ~CONF_USB2_UNI_R;
377                 omap_writel(l, USB_TRANSCEIVER_CTRL);
378         }
379
380         /* external transceiver */
381         if (cpu_is_omap15xx()) {
382                 omap_cfg_reg(USB2_TXD);
383                 omap_cfg_reg(USB2_TXEN);
384                 omap_cfg_reg(USB2_SEO);
385                 if (nwires != 3)
386                         omap_cfg_reg(USB2_RCV);
387                 /* there is no USB2_SPEED */
388         } else if (cpu_is_omap16xx()) {
389                 omap_cfg_reg(V6_USB2_TXD);
390                 omap_cfg_reg(W9_USB2_TXEN);
391                 omap_cfg_reg(W5_USB2_SE0);
392                 if (nwires != 3)
393                         omap_cfg_reg(Y5_USB2_RCV);
394                 // FIXME omap_cfg_reg(USB2_SPEED);
395         } else {
396                 pr_debug("usb%d cpu unrecognized\n", 1);
397                 return 0;
398         }
399
400         // omap_cfg_reg(USB2_SUSP);
401
402         switch (nwires) {
403         case 2:
404                 goto bad;
405         case 3:
406                 syscon1 = 2;
407                 break;
408         case 4:
409                 syscon1 = 1;
410                 break;
411         case 5:
412                 goto bad;
413         case 6:
414                 syscon1 = 3;
415                 if (cpu_is_omap15xx()) {
416                         omap_cfg_reg(USB2_VP);
417                         omap_cfg_reg(USB2_VM);
418                 } else {
419                         u32 l;
420
421                         omap_cfg_reg(AA9_USB2_VP);
422                         omap_cfg_reg(R9_USB2_VM);
423                         l = omap_readl(USB_TRANSCEIVER_CTRL);
424                         l |= CONF_USB2_UNI_R;
425                         omap_writel(l, USB_TRANSCEIVER_CTRL);
426                 }
427                 break;
428         default:
429 bad:
430                 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
431                         2, nwires);
432         }
433
434         return syscon1 << 24;
435 }
436
437 #ifdef  CONFIG_ARCH_OMAP15XX
438
439 /* ULPD_DPLL_CTRL */
440 #define DPLL_IOB                (1 << 13)
441 #define DPLL_PLL_ENABLE         (1 << 4)
442 #define DPLL_LOCK               (1 << 0)
443
444 /* ULPD_APLL_CTRL */
445 #define APLL_NDPLL_SWITCH       (1 << 0)
446
447 static void __init omap_1510_usb_init(struct omap_usb_config *config)
448 {
449         unsigned int val;
450         u16 w;
451
452         config->usb0_init(config->pins[0], is_usb0_device(config));
453         config->usb1_init(config->pins[1]);
454         config->usb2_init(config->pins[2], 0);
455
456         val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
457         val |= (config->hmc_mode << 1);
458         omap_writel(val, MOD_CONF_CTRL_0);
459
460         printk("USB: hmc %d", config->hmc_mode);
461         if (config->pins[0])
462                 printk(", usb0 %d wires%s", config->pins[0],
463                         is_usb0_device(config) ? " (dev)" : "");
464         if (config->pins[1])
465                 printk(", usb1 %d wires", config->pins[1]);
466         if (config->pins[2])
467                 printk(", usb2 %d wires", config->pins[2]);
468         printk("\n");
469
470         /* use DPLL for 48 MHz function clock */
471         pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL),
472                         omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ));
473
474         w = omap_readw(ULPD_APLL_CTRL);
475         w &= ~APLL_NDPLL_SWITCH;
476         omap_writew(w, ULPD_APLL_CTRL);
477
478         w = omap_readw(ULPD_DPLL_CTRL);
479         w |= DPLL_IOB | DPLL_PLL_ENABLE;
480         omap_writew(w, ULPD_DPLL_CTRL);
481
482         w = omap_readw(ULPD_SOFT_REQ);
483         w |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
484         omap_writew(w, ULPD_SOFT_REQ);
485
486         while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK))
487                 cpu_relax();
488
489 #ifdef  CONFIG_USB_GADGET_OMAP
490         if (config->register_dev) {
491                 int status;
492
493                 udc_device.dev.platform_data = config;
494                 status = platform_device_register(&udc_device);
495                 if (status)
496                         pr_debug("can't register UDC device, %d\n", status);
497                 /* udc driver gates 48MHz by D+ pullup */
498         }
499 #endif
500
501 #if     defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
502         if (config->register_host) {
503                 int status;
504
505                 ohci_device.dev.platform_data = config;
506                 status = platform_device_register(&ohci_device);
507                 if (status)
508                         pr_debug("can't register OHCI device, %d\n", status);
509                 /* hcd explicitly gates 48MHz */
510         }
511 #endif
512 }
513
514 #else
515 static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
516 #endif
517
518 void __init omap1_usb_init(struct omap_usb_config *pdata)
519 {
520         pdata->usb0_init = omap1_usb0_init;
521         pdata->usb1_init = omap1_usb1_init;
522         pdata->usb2_init = omap1_usb2_init;
523         udc_device_init(pdata);
524         ohci_device_init(pdata);
525         otg_device_init(pdata);
526
527         if (cpu_is_omap7xx() || cpu_is_omap16xx())
528                 omap_otg_init(pdata);
529         else if (cpu_is_omap15xx())
530                 omap_1510_usb_init(pdata);
531         else
532                 printk(KERN_ERR "USB: No init for your chip yet\n");
533 }