Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
[sfrench/cifs-2.6.git] / arch / arm / mach-omap2 / usb-ehci.c
1 /*
2  * linux/arch/arm/mach-omap2/usb-ehci.c
3  *
4  * This file will contain the board specific details for the
5  * Synopsys EHCI host controller on OMAP3430
6  *
7  * Copyright (C) 2007 Texas Instruments
8  * Author: Vikram Pandita <vikram.pandita@ti.com>
9  *
10  * Generalization by:
11  * Felipe Balbi <felipe.balbi@nokia.com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2 as
15  * published by the Free Software Foundation.
16  */
17
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/delay.h>
21 #include <linux/platform_device.h>
22 #include <linux/clk.h>
23 #include <asm/io.h>
24 #include <plat/mux.h>
25
26 #include <mach/hardware.h>
27 #include <mach/irqs.h>
28 #include <plat/usb.h>
29
30 #if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
31
32 static struct resource ehci_resources[] = {
33         {
34                 .start  = OMAP34XX_EHCI_BASE,
35                 .end    = OMAP34XX_EHCI_BASE + SZ_1K - 1,
36                 .flags  = IORESOURCE_MEM,
37         },
38         {
39                 .start  = OMAP34XX_UHH_CONFIG_BASE,
40                 .end    = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1,
41                 .flags  = IORESOURCE_MEM,
42         },
43         {
44                 .start  = OMAP34XX_USBTLL_BASE,
45                 .end    = OMAP34XX_USBTLL_BASE + SZ_4K - 1,
46                 .flags  = IORESOURCE_MEM,
47         },
48         {         /* general IRQ */
49                 .start   = INT_34XX_EHCI_IRQ,
50                 .flags   = IORESOURCE_IRQ,
51         }
52 };
53
54 static u64 ehci_dmamask = ~(u32)0;
55 static struct platform_device ehci_device = {
56         .name           = "ehci-omap",
57         .id             = 0,
58         .dev = {
59                 .dma_mask               = &ehci_dmamask,
60                 .coherent_dma_mask      = 0xffffffff,
61                 .platform_data          = NULL,
62         },
63         .num_resources  = ARRAY_SIZE(ehci_resources),
64         .resource       = ehci_resources,
65 };
66
67 /* MUX settings for EHCI pins */
68 /*
69  * setup_ehci_io_mux - initialize IO pad mux for USBHOST
70  */
71 static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode)
72 {
73         switch (port_mode[0]) {
74         case EHCI_HCD_OMAP_MODE_PHY:
75                 omap_cfg_reg(Y9_3430_USB1HS_PHY_STP);
76                 omap_cfg_reg(Y8_3430_USB1HS_PHY_CLK);
77                 omap_cfg_reg(AA14_3430_USB1HS_PHY_DIR);
78                 omap_cfg_reg(AA11_3430_USB1HS_PHY_NXT);
79                 omap_cfg_reg(W13_3430_USB1HS_PHY_DATA0);
80                 omap_cfg_reg(W12_3430_USB1HS_PHY_DATA1);
81                 omap_cfg_reg(W11_3430_USB1HS_PHY_DATA2);
82                 omap_cfg_reg(Y11_3430_USB1HS_PHY_DATA3);
83                 omap_cfg_reg(W9_3430_USB1HS_PHY_DATA4);
84                 omap_cfg_reg(Y12_3430_USB1HS_PHY_DATA5);
85                 omap_cfg_reg(W8_3430_USB1HS_PHY_DATA6);
86                 omap_cfg_reg(Y13_3430_USB1HS_PHY_DATA7);
87                 break;
88         case EHCI_HCD_OMAP_MODE_TLL:
89                 omap_cfg_reg(Y9_3430_USB1HS_TLL_STP);
90                 omap_cfg_reg(Y8_3430_USB1HS_TLL_CLK);
91                 omap_cfg_reg(AA14_3430_USB1HS_TLL_DIR);
92                 omap_cfg_reg(AA11_3430_USB1HS_TLL_NXT);
93                 omap_cfg_reg(W13_3430_USB1HS_TLL_DATA0);
94                 omap_cfg_reg(W12_3430_USB1HS_TLL_DATA1);
95                 omap_cfg_reg(W11_3430_USB1HS_TLL_DATA2);
96                 omap_cfg_reg(Y11_3430_USB1HS_TLL_DATA3);
97                 omap_cfg_reg(W9_3430_USB1HS_TLL_DATA4);
98                 omap_cfg_reg(Y12_3430_USB1HS_TLL_DATA5);
99                 omap_cfg_reg(W8_3430_USB1HS_TLL_DATA6);
100                 omap_cfg_reg(Y13_3430_USB1HS_TLL_DATA7);
101                 break;
102         case EHCI_HCD_OMAP_MODE_UNKNOWN:
103                 /* FALLTHROUGH */
104         default:
105                 break;
106         }
107
108         switch (port_mode[1]) {
109         case EHCI_HCD_OMAP_MODE_PHY:
110                 omap_cfg_reg(AA10_3430_USB2HS_PHY_STP);
111                 omap_cfg_reg(AA8_3430_USB2HS_PHY_CLK);
112                 omap_cfg_reg(AA9_3430_USB2HS_PHY_DIR);
113                 omap_cfg_reg(AB11_3430_USB2HS_PHY_NXT);
114                 omap_cfg_reg(AB10_3430_USB2HS_PHY_DATA0);
115                 omap_cfg_reg(AB9_3430_USB2HS_PHY_DATA1);
116                 omap_cfg_reg(W3_3430_USB2HS_PHY_DATA2);
117                 omap_cfg_reg(T4_3430_USB2HS_PHY_DATA3);
118                 omap_cfg_reg(T3_3430_USB2HS_PHY_DATA4);
119                 omap_cfg_reg(R3_3430_USB2HS_PHY_DATA5);
120                 omap_cfg_reg(R4_3430_USB2HS_PHY_DATA6);
121                 omap_cfg_reg(T2_3430_USB2HS_PHY_DATA7);
122                 break;
123         case EHCI_HCD_OMAP_MODE_TLL:
124                 omap_cfg_reg(AA10_3430_USB2HS_TLL_STP);
125                 omap_cfg_reg(AA8_3430_USB2HS_TLL_CLK);
126                 omap_cfg_reg(AA9_3430_USB2HS_TLL_DIR);
127                 omap_cfg_reg(AB11_3430_USB2HS_TLL_NXT);
128                 omap_cfg_reg(AB10_3430_USB2HS_TLL_DATA0);
129                 omap_cfg_reg(AB9_3430_USB2HS_TLL_DATA1);
130                 omap_cfg_reg(W3_3430_USB2HS_TLL_DATA2);
131                 omap_cfg_reg(T4_3430_USB2HS_TLL_DATA3);
132                 omap_cfg_reg(T3_3430_USB2HS_TLL_DATA4);
133                 omap_cfg_reg(R3_3430_USB2HS_TLL_DATA5);
134                 omap_cfg_reg(R4_3430_USB2HS_TLL_DATA6);
135                 omap_cfg_reg(T2_3430_USB2HS_TLL_DATA7);
136                 break;
137         case EHCI_HCD_OMAP_MODE_UNKNOWN:
138                 /* FALLTHROUGH */
139         default:
140                 break;
141         }
142
143         switch (port_mode[2]) {
144         case EHCI_HCD_OMAP_MODE_PHY:
145                 printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
146                 break;
147         case EHCI_HCD_OMAP_MODE_TLL:
148                 omap_cfg_reg(AB3_3430_USB3HS_TLL_STP);
149                 omap_cfg_reg(AA6_3430_USB3HS_TLL_CLK);
150                 omap_cfg_reg(AA3_3430_USB3HS_TLL_DIR);
151                 omap_cfg_reg(Y3_3430_USB3HS_TLL_NXT);
152                 omap_cfg_reg(AA5_3430_USB3HS_TLL_DATA0);
153                 omap_cfg_reg(Y4_3430_USB3HS_TLL_DATA1);
154                 omap_cfg_reg(Y5_3430_USB3HS_TLL_DATA2);
155                 omap_cfg_reg(W5_3430_USB3HS_TLL_DATA3);
156                 omap_cfg_reg(AB12_3430_USB3HS_TLL_DATA4);
157                 omap_cfg_reg(AB13_3430_USB3HS_TLL_DATA5);
158                 omap_cfg_reg(AA13_3430_USB3HS_TLL_DATA6);
159                 omap_cfg_reg(AA12_3430_USB3HS_TLL_DATA7);
160                 break;
161         case EHCI_HCD_OMAP_MODE_UNKNOWN:
162                 /* FALLTHROUGH */
163         default:
164                 break;
165         }
166
167         return;
168 }
169
170 void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
171 {
172         platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
173
174         /* Setup Pin IO MUX for EHCI */
175         if (cpu_is_omap34xx())
176                 setup_ehci_io_mux(pdata->port_mode);
177
178         if (platform_device_register(&ehci_device) < 0) {
179                 printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
180                 return;
181         }
182 }
183
184 #else
185
186 void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
187
188 {
189 }
190
191 #endif /* CONFIG_USB_EHCI_HCD */
192