Root/
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/types.h> |
24 | #include <linux/errno.h> |
25 | #include <linux/init.h> |
26 | #include <linux/platform_device.h> |
27 | #include <linux/clk.h> |
28 | #include <linux/err.h> |
29 | |
30 | #include <asm/irq.h> |
31 | |
32 | #include <plat/usb.h> |
33 | #include <plat/board.h> |
34 | |
35 | #include "control.h" |
36 | #include "mux.h" |
37 | |
38 | #define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN |
39 | #define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO |
40 | #define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO |
41 | #define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN |
42 | #define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG |
43 | |
44 | #if defined(CONFIG_ARCH_OMAP2) |
45 | |
46 | #ifdef CONFIG_USB_GADGET_OMAP |
47 | |
48 | static struct resource udc_resources[] = { |
49 | /* order is significant! */ |
50 | { /* registers */ |
51 | .start = UDC_BASE, |
52 | .end = UDC_BASE + 0xff, |
53 | .flags = IORESOURCE_MEM, |
54 | }, { /* general IRQ */ |
55 | .start = INT_USB_IRQ_GEN, |
56 | .flags = IORESOURCE_IRQ, |
57 | }, { /* PIO IRQ */ |
58 | .start = INT_USB_IRQ_NISO, |
59 | .flags = IORESOURCE_IRQ, |
60 | }, { /* SOF IRQ */ |
61 | .start = INT_USB_IRQ_ISO, |
62 | .flags = IORESOURCE_IRQ, |
63 | }, |
64 | }; |
65 | |
66 | static u64 udc_dmamask = ~(u32)0; |
67 | |
68 | static struct platform_device udc_device = { |
69 | .name = "omap_udc", |
70 | .id = -1, |
71 | .dev = { |
72 | .dma_mask = &udc_dmamask, |
73 | .coherent_dma_mask = 0xffffffff, |
74 | }, |
75 | .num_resources = ARRAY_SIZE(udc_resources), |
76 | .resource = udc_resources, |
77 | }; |
78 | |
79 | static inline void udc_device_init(struct omap_usb_config *pdata) |
80 | { |
81 | pdata->udc_device = &udc_device; |
82 | } |
83 | |
84 | #else |
85 | |
86 | static inline void udc_device_init(struct omap_usb_config *pdata) |
87 | { |
88 | } |
89 | |
90 | #endif |
91 | |
92 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
93 | |
94 | /* The dmamask must be set for OHCI to work */ |
95 | static u64 ohci_dmamask = ~(u32)0; |
96 | |
97 | static struct resource ohci_resources[] = { |
98 | { |
99 | .start = OMAP_OHCI_BASE, |
100 | .end = OMAP_OHCI_BASE + 0xff, |
101 | .flags = IORESOURCE_MEM, |
102 | }, |
103 | { |
104 | .start = INT_USB_IRQ_HGEN, |
105 | .flags = IORESOURCE_IRQ, |
106 | }, |
107 | }; |
108 | |
109 | static struct platform_device ohci_device = { |
110 | .name = "ohci", |
111 | .id = -1, |
112 | .dev = { |
113 | .dma_mask = &ohci_dmamask, |
114 | .coherent_dma_mask = 0xffffffff, |
115 | }, |
116 | .num_resources = ARRAY_SIZE(ohci_resources), |
117 | .resource = ohci_resources, |
118 | }; |
119 | |
120 | static inline void ohci_device_init(struct omap_usb_config *pdata) |
121 | { |
122 | pdata->ohci_device = &ohci_device; |
123 | } |
124 | |
125 | #else |
126 | |
127 | static inline void ohci_device_init(struct omap_usb_config *pdata) |
128 | { |
129 | } |
130 | |
131 | #endif |
132 | |
133 | #if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) |
134 | |
135 | static struct resource otg_resources[] = { |
136 | /* order is significant! */ |
137 | { |
138 | .start = OTG_BASE, |
139 | .end = OTG_BASE + 0xff, |
140 | .flags = IORESOURCE_MEM, |
141 | }, { |
142 | .start = INT_USB_IRQ_OTG, |
143 | .flags = IORESOURCE_IRQ, |
144 | }, |
145 | }; |
146 | |
147 | static struct platform_device otg_device = { |
148 | .name = "omap_otg", |
149 | .id = -1, |
150 | .num_resources = ARRAY_SIZE(otg_resources), |
151 | .resource = otg_resources, |
152 | }; |
153 | |
154 | static inline void otg_device_init(struct omap_usb_config *pdata) |
155 | { |
156 | pdata->otg_device = &otg_device; |
157 | } |
158 | |
159 | #else |
160 | |
161 | static inline void otg_device_init(struct omap_usb_config *pdata) |
162 | { |
163 | } |
164 | |
165 | #endif |
166 | |
167 | static void omap2_usb_devconf_clear(u8 port, u32 mask) |
168 | { |
169 | u32 r; |
170 | |
171 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); |
172 | r &= ~USBTXWRMODEI(port, mask); |
173 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); |
174 | } |
175 | |
176 | static void omap2_usb_devconf_set(u8 port, u32 mask) |
177 | { |
178 | u32 r; |
179 | |
180 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); |
181 | r |= USBTXWRMODEI(port, mask); |
182 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); |
183 | } |
184 | |
185 | static void omap2_usb2_disable_5pinbitll(void) |
186 | { |
187 | u32 r; |
188 | |
189 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); |
190 | r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI); |
191 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); |
192 | } |
193 | |
194 | static void omap2_usb2_enable_5pinunitll(void) |
195 | { |
196 | u32 r; |
197 | |
198 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); |
199 | r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI; |
200 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); |
201 | } |
202 | |
203 | static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device) |
204 | { |
205 | u32 syscon1 = 0; |
206 | |
207 | omap2_usb_devconf_clear(0, USB_BIDIR_TLL); |
208 | |
209 | if (nwires == 0) |
210 | return 0; |
211 | |
212 | if (is_device) |
213 | omap_mux_init_signal("usb0_puen", 0); |
214 | |
215 | omap_mux_init_signal("usb0_dat", 0); |
216 | omap_mux_init_signal("usb0_txen", 0); |
217 | omap_mux_init_signal("usb0_se0", 0); |
218 | if (nwires != 3) |
219 | omap_mux_init_signal("usb0_rcv", 0); |
220 | |
221 | switch (nwires) { |
222 | case 3: |
223 | syscon1 = 2; |
224 | omap2_usb_devconf_set(0, USB_BIDIR); |
225 | break; |
226 | case 4: |
227 | syscon1 = 1; |
228 | omap2_usb_devconf_set(0, USB_BIDIR); |
229 | break; |
230 | case 6: |
231 | syscon1 = 3; |
232 | omap_mux_init_signal("usb0_vp", 0); |
233 | omap_mux_init_signal("usb0_vm", 0); |
234 | omap2_usb_devconf_set(0, USB_UNIDIR); |
235 | break; |
236 | default: |
237 | printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", |
238 | 0, nwires); |
239 | } |
240 | |
241 | return syscon1 << 16; |
242 | } |
243 | |
244 | static u32 __init omap2_usb1_init(unsigned nwires) |
245 | { |
246 | u32 syscon1 = 0; |
247 | |
248 | omap2_usb_devconf_clear(1, USB_BIDIR_TLL); |
249 | |
250 | if (nwires == 0) |
251 | return 0; |
252 | |
253 | /* NOTE: board-specific code must set up pin muxing for usb1, |
254 | * since each signal could come out on either of two balls. |
255 | */ |
256 | |
257 | switch (nwires) { |
258 | case 2: |
259 | /* NOTE: board-specific code must override this setting if |
260 | * this TLL link is not using DP/DM |
261 | */ |
262 | syscon1 = 1; |
263 | omap2_usb_devconf_set(1, USB_BIDIR_TLL); |
264 | break; |
265 | case 3: |
266 | syscon1 = 2; |
267 | omap2_usb_devconf_set(1, USB_BIDIR); |
268 | break; |
269 | case 4: |
270 | syscon1 = 1; |
271 | omap2_usb_devconf_set(1, USB_BIDIR); |
272 | break; |
273 | case 6: |
274 | default: |
275 | printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", |
276 | 1, nwires); |
277 | } |
278 | |
279 | return syscon1 << 20; |
280 | } |
281 | |
282 | static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup) |
283 | { |
284 | u32 syscon1 = 0; |
285 | |
286 | omap2_usb2_disable_5pinbitll(); |
287 | alt_pingroup = 0; |
288 | |
289 | /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ |
290 | if (alt_pingroup || nwires == 0) |
291 | return 0; |
292 | |
293 | omap_mux_init_signal("usb2_dat", 0); |
294 | omap_mux_init_signal("usb2_se0", 0); |
295 | if (nwires > 2) |
296 | omap_mux_init_signal("usb2_txen", 0); |
297 | if (nwires > 3) |
298 | omap_mux_init_signal("usb2_rcv", 0); |
299 | |
300 | switch (nwires) { |
301 | case 2: |
302 | /* NOTE: board-specific code must override this setting if |
303 | * this TLL link is not using DP/DM |
304 | */ |
305 | syscon1 = 1; |
306 | omap2_usb_devconf_set(2, USB_BIDIR_TLL); |
307 | break; |
308 | case 3: |
309 | syscon1 = 2; |
310 | omap2_usb_devconf_set(2, USB_BIDIR); |
311 | break; |
312 | case 4: |
313 | syscon1 = 1; |
314 | omap2_usb_devconf_set(2, USB_BIDIR); |
315 | break; |
316 | case 5: |
317 | /* NOTE: board-specific code must mux this setting depending |
318 | * on TLL link using DP/DM. Something must also |
319 | * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} |
320 | * 2420: hdq_sio.usb2_tllse0 or vlynq_rx0.usb2_tllse0 |
321 | * 2430: hdq_sio.usb2_tllse0 or sdmmc2_dat0.usb2_tllse0 |
322 | */ |
323 | |
324 | syscon1 = 3; |
325 | omap2_usb2_enable_5pinunitll(); |
326 | break; |
327 | case 6: |
328 | default: |
329 | printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", |
330 | 2, nwires); |
331 | } |
332 | |
333 | return syscon1 << 24; |
334 | } |
335 | |
336 | void __init omap2_usbfs_init(struct omap_usb_config *pdata) |
337 | { |
338 | struct clk *ick; |
339 | |
340 | if (!cpu_is_omap24xx()) |
341 | return; |
342 | |
343 | ick = clk_get(NULL, "usb_l4_ick"); |
344 | if (IS_ERR(ick)) |
345 | return; |
346 | |
347 | clk_enable(ick); |
348 | pdata->usb0_init = omap2_usb0_init; |
349 | pdata->usb1_init = omap2_usb1_init; |
350 | pdata->usb2_init = omap2_usb2_init; |
351 | udc_device_init(pdata); |
352 | ohci_device_init(pdata); |
353 | otg_device_init(pdata); |
354 | omap_otg_init(pdata); |
355 | clk_disable(ick); |
356 | clk_put(ick); |
357 | } |
358 | |
359 | #endif |
360 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9