blob: ab0638208748073b1eace38dc1787f770c62d1c2 [file] [log] [blame]
Felipe Balbi58a54912009-11-22 10:11:01 -08001/*
Felipe Balbia8480ea2011-03-01 20:08:15 +05302 * usb-host.c - OMAP USB Host
Felipe Balbi58a54912009-11-22 10:11:01 -08003 *
4 * This file will contain the board specific details for the
Felipe Balbia8480ea2011-03-01 20:08:15 +05305 * Synopsys EHCI/OHCI host controller on OMAP3430 and onwards
Felipe Balbi58a54912009-11-22 10:11:01 -08006 *
Felipe Balbia8480ea2011-03-01 20:08:15 +05307 * Copyright (C) 2007-2011 Texas Instruments
Felipe Balbi58a54912009-11-22 10:11:01 -08008 * Author: Vikram Pandita <vikram.pandita@ti.com>
Keshava Munegowda22363962011-03-01 20:08:18 +05309 * Author: Keshava Munegowda <keshava_mgowda@ti.com>
Felipe Balbi58a54912009-11-22 10:11:01 -080010 *
11 * Generalization by:
Felipe Balbia8480ea2011-03-01 20:08:15 +053012 * Felipe Balbi <balbi@ti.com>
Felipe Balbi58a54912009-11-22 10:11:01 -080013 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/delay.h>
22#include <linux/platform_device.h>
Keshava Munegowda22363962011-03-01 20:08:18 +053023#include <linux/slab.h>
Amit Kucheriabfb01192010-06-09 13:53:05 +030024#include <linux/dma-mapping.h>
25
Felipe Balbi58a54912009-11-22 10:11:01 -080026#include <asm/io.h>
Felipe Balbi58a54912009-11-22 10:11:01 -080027
28#include <mach/hardware.h>
29#include <mach/irqs.h>
30#include <plat/usb.h>
31
Tony Lindgren4896e392009-12-11 16:16:32 -080032#include "mux.h"
33
Keshava Munegowda22363962011-03-01 20:08:18 +053034#ifdef CONFIG_MFD_OMAP_USB_HOST
Felipe Balbi58a54912009-11-22 10:11:01 -080035
36static struct resource ehci_resources[] = {
37 {
Felipe Balbi58a54912009-11-22 10:11:01 -080038 .flags = IORESOURCE_MEM,
39 },
40 {
Felipe Balbi58a54912009-11-22 10:11:01 -080041 .flags = IORESOURCE_MEM,
42 },
43 {
Felipe Balbi58a54912009-11-22 10:11:01 -080044 .flags = IORESOURCE_MEM,
45 },
46 { /* general IRQ */
Felipe Balbi58a54912009-11-22 10:11:01 -080047 .flags = IORESOURCE_IRQ,
48 }
49};
50
51static u64 ehci_dmamask = ~(u32)0;
52static struct platform_device ehci_device = {
53 .name = "ehci-omap",
54 .id = 0,
55 .dev = {
56 .dma_mask = &ehci_dmamask,
57 .coherent_dma_mask = 0xffffffff,
58 .platform_data = NULL,
59 },
60 .num_resources = ARRAY_SIZE(ehci_resources),
61 .resource = ehci_resources,
62};
63
64/* MUX settings for EHCI pins */
65/*
66 * setup_ehci_io_mux - initialize IO pad mux for USBHOST
67 */
Keshava Munegowda181b2502011-03-01 20:08:16 +053068static void setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Felipe Balbi58a54912009-11-22 10:11:01 -080069{
70 switch (port_mode[0]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +053071 case OMAP_EHCI_PORT_MODE_PHY:
Tony Lindgren4896e392009-12-11 16:16:32 -080072 omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
73 omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
74 omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
75 omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
76 omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
77 omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
78 omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
79 omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
80 omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
81 omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
82 omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
83 omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -080084 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +053085 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -080086 omap_mux_init_signal("hsusb1_tll_stp",
87 OMAP_PIN_INPUT_PULLUP);
88 omap_mux_init_signal("hsusb1_tll_clk",
89 OMAP_PIN_INPUT_PULLDOWN);
90 omap_mux_init_signal("hsusb1_tll_dir",
91 OMAP_PIN_INPUT_PULLDOWN);
92 omap_mux_init_signal("hsusb1_tll_nxt",
93 OMAP_PIN_INPUT_PULLDOWN);
94 omap_mux_init_signal("hsusb1_tll_data0",
95 OMAP_PIN_INPUT_PULLDOWN);
96 omap_mux_init_signal("hsusb1_tll_data1",
97 OMAP_PIN_INPUT_PULLDOWN);
98 omap_mux_init_signal("hsusb1_tll_data2",
99 OMAP_PIN_INPUT_PULLDOWN);
100 omap_mux_init_signal("hsusb1_tll_data3",
101 OMAP_PIN_INPUT_PULLDOWN);
102 omap_mux_init_signal("hsusb1_tll_data4",
103 OMAP_PIN_INPUT_PULLDOWN);
104 omap_mux_init_signal("hsusb1_tll_data5",
105 OMAP_PIN_INPUT_PULLDOWN);
106 omap_mux_init_signal("hsusb1_tll_data6",
107 OMAP_PIN_INPUT_PULLDOWN);
108 omap_mux_init_signal("hsusb1_tll_data7",
109 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800110 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530111 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -0800112 /* FALLTHROUGH */
113 default:
114 break;
115 }
116
117 switch (port_mode[1]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530118 case OMAP_EHCI_PORT_MODE_PHY:
Tony Lindgren4896e392009-12-11 16:16:32 -0800119 omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
120 omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
121 omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
122 omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
123 omap_mux_init_signal("hsusb2_data0",
124 OMAP_PIN_INPUT_PULLDOWN);
125 omap_mux_init_signal("hsusb2_data1",
126 OMAP_PIN_INPUT_PULLDOWN);
127 omap_mux_init_signal("hsusb2_data2",
128 OMAP_PIN_INPUT_PULLDOWN);
129 omap_mux_init_signal("hsusb2_data3",
130 OMAP_PIN_INPUT_PULLDOWN);
131 omap_mux_init_signal("hsusb2_data4",
132 OMAP_PIN_INPUT_PULLDOWN);
133 omap_mux_init_signal("hsusb2_data5",
134 OMAP_PIN_INPUT_PULLDOWN);
135 omap_mux_init_signal("hsusb2_data6",
136 OMAP_PIN_INPUT_PULLDOWN);
137 omap_mux_init_signal("hsusb2_data7",
138 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800139 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530140 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -0800141 omap_mux_init_signal("hsusb2_tll_stp",
142 OMAP_PIN_INPUT_PULLUP);
143 omap_mux_init_signal("hsusb2_tll_clk",
144 OMAP_PIN_INPUT_PULLDOWN);
145 omap_mux_init_signal("hsusb2_tll_dir",
146 OMAP_PIN_INPUT_PULLDOWN);
147 omap_mux_init_signal("hsusb2_tll_nxt",
148 OMAP_PIN_INPUT_PULLDOWN);
149 omap_mux_init_signal("hsusb2_tll_data0",
150 OMAP_PIN_INPUT_PULLDOWN);
151 omap_mux_init_signal("hsusb2_tll_data1",
152 OMAP_PIN_INPUT_PULLDOWN);
153 omap_mux_init_signal("hsusb2_tll_data2",
154 OMAP_PIN_INPUT_PULLDOWN);
155 omap_mux_init_signal("hsusb2_tll_data3",
156 OMAP_PIN_INPUT_PULLDOWN);
157 omap_mux_init_signal("hsusb2_tll_data4",
158 OMAP_PIN_INPUT_PULLDOWN);
159 omap_mux_init_signal("hsusb2_tll_data5",
160 OMAP_PIN_INPUT_PULLDOWN);
161 omap_mux_init_signal("hsusb2_tll_data6",
162 OMAP_PIN_INPUT_PULLDOWN);
163 omap_mux_init_signal("hsusb2_tll_data7",
164 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800165 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530166 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -0800167 /* FALLTHROUGH */
168 default:
169 break;
170 }
171
172 switch (port_mode[2]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530173 case OMAP_EHCI_PORT_MODE_PHY:
Felipe Balbi58a54912009-11-22 10:11:01 -0800174 printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
175 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530176 case OMAP_EHCI_PORT_MODE_TLL:
Tony Lindgren4896e392009-12-11 16:16:32 -0800177 omap_mux_init_signal("hsusb3_tll_stp",
178 OMAP_PIN_INPUT_PULLUP);
179 omap_mux_init_signal("hsusb3_tll_clk",
180 OMAP_PIN_INPUT_PULLDOWN);
181 omap_mux_init_signal("hsusb3_tll_dir",
182 OMAP_PIN_INPUT_PULLDOWN);
183 omap_mux_init_signal("hsusb3_tll_nxt",
184 OMAP_PIN_INPUT_PULLDOWN);
185 omap_mux_init_signal("hsusb3_tll_data0",
186 OMAP_PIN_INPUT_PULLDOWN);
187 omap_mux_init_signal("hsusb3_tll_data1",
188 OMAP_PIN_INPUT_PULLDOWN);
189 omap_mux_init_signal("hsusb3_tll_data2",
190 OMAP_PIN_INPUT_PULLDOWN);
191 omap_mux_init_signal("hsusb3_tll_data3",
192 OMAP_PIN_INPUT_PULLDOWN);
193 omap_mux_init_signal("hsusb3_tll_data4",
194 OMAP_PIN_INPUT_PULLDOWN);
195 omap_mux_init_signal("hsusb3_tll_data5",
196 OMAP_PIN_INPUT_PULLDOWN);
197 omap_mux_init_signal("hsusb3_tll_data6",
198 OMAP_PIN_INPUT_PULLDOWN);
199 omap_mux_init_signal("hsusb3_tll_data7",
200 OMAP_PIN_INPUT_PULLDOWN);
Felipe Balbi58a54912009-11-22 10:11:01 -0800201 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530202 case OMAP_USBHS_PORT_MODE_UNUSED:
Felipe Balbi58a54912009-11-22 10:11:01 -0800203 /* FALLTHROUGH */
204 default:
205 break;
206 }
207
208 return;
209}
210
Keshava Munegowda181b2502011-03-01 20:08:16 +0530211static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530212{
213 switch (port_mode[0]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530214 case OMAP_EHCI_PORT_MODE_PHY:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530215 omap_mux_init_signal("usbb1_ulpiphy_stp",
216 OMAP_PIN_OUTPUT);
217 omap_mux_init_signal("usbb1_ulpiphy_clk",
218 OMAP_PIN_INPUT_PULLDOWN);
219 omap_mux_init_signal("usbb1_ulpiphy_dir",
220 OMAP_PIN_INPUT_PULLDOWN);
221 omap_mux_init_signal("usbb1_ulpiphy_nxt",
222 OMAP_PIN_INPUT_PULLDOWN);
223 omap_mux_init_signal("usbb1_ulpiphy_dat0",
224 OMAP_PIN_INPUT_PULLDOWN);
225 omap_mux_init_signal("usbb1_ulpiphy_dat1",
226 OMAP_PIN_INPUT_PULLDOWN);
227 omap_mux_init_signal("usbb1_ulpiphy_dat2",
228 OMAP_PIN_INPUT_PULLDOWN);
229 omap_mux_init_signal("usbb1_ulpiphy_dat3",
230 OMAP_PIN_INPUT_PULLDOWN);
231 omap_mux_init_signal("usbb1_ulpiphy_dat4",
232 OMAP_PIN_INPUT_PULLDOWN);
233 omap_mux_init_signal("usbb1_ulpiphy_dat5",
234 OMAP_PIN_INPUT_PULLDOWN);
235 omap_mux_init_signal("usbb1_ulpiphy_dat6",
236 OMAP_PIN_INPUT_PULLDOWN);
237 omap_mux_init_signal("usbb1_ulpiphy_dat7",
238 OMAP_PIN_INPUT_PULLDOWN);
239 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530240 case OMAP_EHCI_PORT_MODE_TLL:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530241 omap_mux_init_signal("usbb1_ulpitll_stp",
242 OMAP_PIN_INPUT_PULLUP);
243 omap_mux_init_signal("usbb1_ulpitll_clk",
244 OMAP_PIN_INPUT_PULLDOWN);
245 omap_mux_init_signal("usbb1_ulpitll_dir",
246 OMAP_PIN_INPUT_PULLDOWN);
247 omap_mux_init_signal("usbb1_ulpitll_nxt",
248 OMAP_PIN_INPUT_PULLDOWN);
249 omap_mux_init_signal("usbb1_ulpitll_dat0",
250 OMAP_PIN_INPUT_PULLDOWN);
251 omap_mux_init_signal("usbb1_ulpitll_dat1",
252 OMAP_PIN_INPUT_PULLDOWN);
253 omap_mux_init_signal("usbb1_ulpitll_dat2",
254 OMAP_PIN_INPUT_PULLDOWN);
255 omap_mux_init_signal("usbb1_ulpitll_dat3",
256 OMAP_PIN_INPUT_PULLDOWN);
257 omap_mux_init_signal("usbb1_ulpitll_dat4",
258 OMAP_PIN_INPUT_PULLDOWN);
259 omap_mux_init_signal("usbb1_ulpitll_dat5",
260 OMAP_PIN_INPUT_PULLDOWN);
261 omap_mux_init_signal("usbb1_ulpitll_dat6",
262 OMAP_PIN_INPUT_PULLDOWN);
263 omap_mux_init_signal("usbb1_ulpitll_dat7",
264 OMAP_PIN_INPUT_PULLDOWN);
265 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530266 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530267 default:
268 break;
269 }
270 switch (port_mode[1]) {
Keshava Munegowda181b2502011-03-01 20:08:16 +0530271 case OMAP_EHCI_PORT_MODE_PHY:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530272 omap_mux_init_signal("usbb2_ulpiphy_stp",
273 OMAP_PIN_OUTPUT);
274 omap_mux_init_signal("usbb2_ulpiphy_clk",
275 OMAP_PIN_INPUT_PULLDOWN);
276 omap_mux_init_signal("usbb2_ulpiphy_dir",
277 OMAP_PIN_INPUT_PULLDOWN);
278 omap_mux_init_signal("usbb2_ulpiphy_nxt",
279 OMAP_PIN_INPUT_PULLDOWN);
280 omap_mux_init_signal("usbb2_ulpiphy_dat0",
281 OMAP_PIN_INPUT_PULLDOWN);
282 omap_mux_init_signal("usbb2_ulpiphy_dat1",
283 OMAP_PIN_INPUT_PULLDOWN);
284 omap_mux_init_signal("usbb2_ulpiphy_dat2",
285 OMAP_PIN_INPUT_PULLDOWN);
286 omap_mux_init_signal("usbb2_ulpiphy_dat3",
287 OMAP_PIN_INPUT_PULLDOWN);
288 omap_mux_init_signal("usbb2_ulpiphy_dat4",
289 OMAP_PIN_INPUT_PULLDOWN);
290 omap_mux_init_signal("usbb2_ulpiphy_dat5",
291 OMAP_PIN_INPUT_PULLDOWN);
292 omap_mux_init_signal("usbb2_ulpiphy_dat6",
293 OMAP_PIN_INPUT_PULLDOWN);
294 omap_mux_init_signal("usbb2_ulpiphy_dat7",
295 OMAP_PIN_INPUT_PULLDOWN);
296 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530297 case OMAP_EHCI_PORT_MODE_TLL:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530298 omap_mux_init_signal("usbb2_ulpitll_stp",
299 OMAP_PIN_INPUT_PULLUP);
300 omap_mux_init_signal("usbb2_ulpitll_clk",
301 OMAP_PIN_INPUT_PULLDOWN);
302 omap_mux_init_signal("usbb2_ulpitll_dir",
303 OMAP_PIN_INPUT_PULLDOWN);
304 omap_mux_init_signal("usbb2_ulpitll_nxt",
305 OMAP_PIN_INPUT_PULLDOWN);
306 omap_mux_init_signal("usbb2_ulpitll_dat0",
307 OMAP_PIN_INPUT_PULLDOWN);
308 omap_mux_init_signal("usbb2_ulpitll_dat1",
309 OMAP_PIN_INPUT_PULLDOWN);
310 omap_mux_init_signal("usbb2_ulpitll_dat2",
311 OMAP_PIN_INPUT_PULLDOWN);
312 omap_mux_init_signal("usbb2_ulpitll_dat3",
313 OMAP_PIN_INPUT_PULLDOWN);
314 omap_mux_init_signal("usbb2_ulpitll_dat4",
315 OMAP_PIN_INPUT_PULLDOWN);
316 omap_mux_init_signal("usbb2_ulpitll_dat5",
317 OMAP_PIN_INPUT_PULLDOWN);
318 omap_mux_init_signal("usbb2_ulpitll_dat6",
319 OMAP_PIN_INPUT_PULLDOWN);
320 omap_mux_init_signal("usbb2_ulpitll_dat7",
321 OMAP_PIN_INPUT_PULLDOWN);
322 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530323 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530324 default:
325 break;
326 }
327}
328
Keshava Munegowda181b2502011-03-01 20:08:16 +0530329void __init usb_ehci_init(const struct usbhs_omap_board_data *pdata)
Felipe Balbi58a54912009-11-22 10:11:01 -0800330{
331 platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
332
333 /* Setup Pin IO MUX for EHCI */
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530334 if (cpu_is_omap34xx()) {
335 ehci_resources[0].start = OMAP34XX_EHCI_BASE;
336 ehci_resources[0].end = OMAP34XX_EHCI_BASE + SZ_1K - 1;
337 ehci_resources[1].start = OMAP34XX_UHH_CONFIG_BASE;
338 ehci_resources[1].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
339 ehci_resources[2].start = OMAP34XX_USBTLL_BASE;
340 ehci_resources[2].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
341 ehci_resources[3].start = INT_34XX_EHCI_IRQ;
Felipe Balbi58a54912009-11-22 10:11:01 -0800342 setup_ehci_io_mux(pdata->port_mode);
Anand Gadiyarbecf0732010-11-21 23:23:41 +0530343 } else if (cpu_is_omap44xx()) {
344 ehci_resources[0].start = OMAP44XX_HSUSB_EHCI_BASE;
345 ehci_resources[0].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
346 ehci_resources[1].start = OMAP44XX_UHH_CONFIG_BASE;
347 ehci_resources[1].end = OMAP44XX_UHH_CONFIG_BASE + SZ_2K - 1;
348 ehci_resources[2].start = OMAP44XX_USBTLL_BASE;
349 ehci_resources[2].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
350 ehci_resources[3].start = OMAP44XX_IRQ_EHCI;
351 setup_4430ehci_io_mux(pdata->port_mode);
352 }
Felipe Balbi58a54912009-11-22 10:11:01 -0800353
Felipe Balbia9031e52011-03-01 20:08:13 +0530354 ehci_resources[0].name = "ehci";
355 ehci_resources[1].name = "uhh";
356 ehci_resources[2].name = "tll";
357 ehci_resources[3].name = "irq";
358
Felipe Balbi58a54912009-11-22 10:11:01 -0800359 if (platform_device_register(&ehci_device) < 0) {
360 printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
361 return;
362 }
363}
364
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530365static struct resource ohci_resources[] = {
366 {
Felipe Balbia9031e52011-03-01 20:08:13 +0530367 .name = "ohci",
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530368 .start = OMAP34XX_OHCI_BASE,
369 .end = OMAP34XX_OHCI_BASE + SZ_1K - 1,
370 .flags = IORESOURCE_MEM,
371 },
372 {
Felipe Balbia9031e52011-03-01 20:08:13 +0530373 .name = "uhh",
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530374 .start = OMAP34XX_UHH_CONFIG_BASE,
375 .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1,
376 .flags = IORESOURCE_MEM,
377 },
378 {
Felipe Balbia9031e52011-03-01 20:08:13 +0530379 .name = "tll",
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530380 .start = OMAP34XX_USBTLL_BASE,
381 .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1,
382 .flags = IORESOURCE_MEM,
383 },
384 { /* general IRQ */
Felipe Balbia9031e52011-03-01 20:08:13 +0530385 .name = "irq",
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530386 .start = INT_34XX_OHCI_IRQ,
387 .flags = IORESOURCE_IRQ,
388 }
389};
390
391static u64 ohci_dmamask = DMA_BIT_MASK(32);
392
393static struct platform_device ohci_device = {
394 .name = "ohci-omap3",
395 .id = 0,
396 .dev = {
397 .dma_mask = &ohci_dmamask,
398 .coherent_dma_mask = 0xffffffff,
399 },
400 .num_resources = ARRAY_SIZE(ohci_resources),
401 .resource = ohci_resources,
402};
403
Keshava Munegowda181b2502011-03-01 20:08:16 +0530404static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530405{
406 switch (port_mode[0]) {
407 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
408 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
409 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
410 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
411 omap_mux_init_signal("mm1_rxdp",
412 OMAP_PIN_INPUT_PULLDOWN);
413 omap_mux_init_signal("mm1_rxdm",
414 OMAP_PIN_INPUT_PULLDOWN);
415 /* FALLTHROUGH */
416 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
417 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
418 omap_mux_init_signal("mm1_rxrcv",
419 OMAP_PIN_INPUT_PULLDOWN);
420 /* FALLTHROUGH */
421 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
422 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
423 omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
424 /* FALLTHROUGH */
425 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
426 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
427 omap_mux_init_signal("mm1_txse0",
428 OMAP_PIN_INPUT_PULLDOWN);
429 omap_mux_init_signal("mm1_txdat",
430 OMAP_PIN_INPUT_PULLDOWN);
431 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530432 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530433 /* FALLTHROUGH */
434 default:
435 break;
436 }
437 switch (port_mode[1]) {
438 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
439 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
440 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
441 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
442 omap_mux_init_signal("mm2_rxdp",
443 OMAP_PIN_INPUT_PULLDOWN);
444 omap_mux_init_signal("mm2_rxdm",
445 OMAP_PIN_INPUT_PULLDOWN);
446 /* FALLTHROUGH */
447 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
448 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
449 omap_mux_init_signal("mm2_rxrcv",
450 OMAP_PIN_INPUT_PULLDOWN);
451 /* FALLTHROUGH */
452 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
453 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
454 omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
455 /* FALLTHROUGH */
456 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
457 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
458 omap_mux_init_signal("mm2_txse0",
459 OMAP_PIN_INPUT_PULLDOWN);
460 omap_mux_init_signal("mm2_txdat",
461 OMAP_PIN_INPUT_PULLDOWN);
462 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530463 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530464 /* FALLTHROUGH */
465 default:
466 break;
467 }
468 switch (port_mode[2]) {
469 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
470 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
471 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
472 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
473 omap_mux_init_signal("mm3_rxdp",
474 OMAP_PIN_INPUT_PULLDOWN);
475 omap_mux_init_signal("mm3_rxdm",
476 OMAP_PIN_INPUT_PULLDOWN);
477 /* FALLTHROUGH */
478 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
479 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
480 omap_mux_init_signal("mm3_rxrcv",
481 OMAP_PIN_INPUT_PULLDOWN);
482 /* FALLTHROUGH */
483 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
484 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
485 omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
486 /* FALLTHROUGH */
487 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
488 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
489 omap_mux_init_signal("mm3_txse0",
490 OMAP_PIN_INPUT_PULLDOWN);
491 omap_mux_init_signal("mm3_txdat",
492 OMAP_PIN_INPUT_PULLDOWN);
493 break;
Keshava Munegowda181b2502011-03-01 20:08:16 +0530494 case OMAP_USBHS_PORT_MODE_UNUSED:
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530495 /* FALLTHROUGH */
496 default:
497 break;
498 }
499}
500
Keshava Munegowda22363962011-03-01 20:08:18 +0530501static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
502{
503 switch (port_mode[0]) {
504 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
505 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
506 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
507 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
508 omap_mux_init_signal("usbb1_mm_rxdp",
509 OMAP_PIN_INPUT_PULLDOWN);
510 omap_mux_init_signal("usbb1_mm_rxdm",
511 OMAP_PIN_INPUT_PULLDOWN);
512
513 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
514 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
515 omap_mux_init_signal("usbb1_mm_rxrcv",
516 OMAP_PIN_INPUT_PULLDOWN);
517
518 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
519 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
520 omap_mux_init_signal("usbb1_mm_txen",
521 OMAP_PIN_INPUT_PULLDOWN);
522
523
524 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
525 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
526 omap_mux_init_signal("usbb1_mm_txdat",
527 OMAP_PIN_INPUT_PULLDOWN);
528 omap_mux_init_signal("usbb1_mm_txse0",
529 OMAP_PIN_INPUT_PULLDOWN);
530 break;
531
532 case OMAP_USBHS_PORT_MODE_UNUSED:
533 default:
534 break;
535 }
536
537 switch (port_mode[1]) {
538 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
539 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
540 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
541 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
542 omap_mux_init_signal("usbb2_mm_rxdp",
543 OMAP_PIN_INPUT_PULLDOWN);
544 omap_mux_init_signal("usbb2_mm_rxdm",
545 OMAP_PIN_INPUT_PULLDOWN);
546
547 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
548 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
549 omap_mux_init_signal("usbb2_mm_rxrcv",
550 OMAP_PIN_INPUT_PULLDOWN);
551
552 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
553 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
554 omap_mux_init_signal("usbb2_mm_txen",
555 OMAP_PIN_INPUT_PULLDOWN);
556
557
558 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
559 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
560 omap_mux_init_signal("usbb2_mm_txdat",
561 OMAP_PIN_INPUT_PULLDOWN);
562 omap_mux_init_signal("usbb2_mm_txse0",
563 OMAP_PIN_INPUT_PULLDOWN);
564 break;
565
566 case OMAP_USBHS_PORT_MODE_UNUSED:
567 default:
568 break;
569 }
570}
571
Keshava Munegowda181b2502011-03-01 20:08:16 +0530572void __init usb_ohci_init(const struct usbhs_omap_board_data *pdata)
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530573{
574 platform_device_add_data(&ohci_device, pdata, sizeof(*pdata));
575
576 /* Setup Pin IO MUX for OHCI */
577 if (cpu_is_omap34xx())
578 setup_ohci_io_mux(pdata->port_mode);
579
580 if (platform_device_register(&ohci_device) < 0) {
581 pr_err("Unable to register FS-USB (OHCI) device\n");
582 return;
583 }
584}
585
Keshava Munegowda22363962011-03-01 20:08:18 +0530586#define OMAP_USBHS_DEVICE "usbhs-omap"
587
588static struct resource usbhs_resources[] = {
589 {
590 .name = "uhh",
591 .flags = IORESOURCE_MEM,
592 },
593 {
594 .name = "tll",
595 .flags = IORESOURCE_MEM,
596 },
597 {
598 .name = "ehci",
599 .flags = IORESOURCE_MEM,
600 },
601 {
602 .name = "ehci-irq",
603 .flags = IORESOURCE_IRQ,
604 },
605 {
606 .name = "ohci",
607 .flags = IORESOURCE_MEM,
608 },
609 {
610 .name = "ohci-irq",
611 .flags = IORESOURCE_IRQ,
612 }
613};
614
615static struct platform_device usbhs_device = {
616 .name = OMAP_USBHS_DEVICE,
617 .id = 0,
618 .num_resources = ARRAY_SIZE(usbhs_resources),
619 .resource = usbhs_resources,
620};
621
622static struct usbhs_omap_platform_data usbhs_data;
623static struct ehci_hcd_omap_platform_data ehci_data;
624static struct ohci_hcd_omap_platform_data ohci_data;
625
626void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
627{
628 int i;
629
630 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
631 usbhs_data.port_mode[i] = pdata->port_mode[i];
632 ohci_data.port_mode[i] = pdata->port_mode[i];
633 ehci_data.port_mode[i] = pdata->port_mode[i];
634 ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i];
635 ehci_data.regulator[i] = pdata->regulator[i];
636 }
637 ehci_data.phy_reset = pdata->phy_reset;
638 ohci_data.es2_compatibility = pdata->es2_compatibility;
639 usbhs_data.ehci_data = &ehci_data;
640 usbhs_data.ohci_data = &ohci_data;
641
642 if (cpu_is_omap34xx()) {
643 usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE;
644 usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
645 usbhs_resources[1].start = OMAP34XX_USBTLL_BASE;
646 usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
647 usbhs_resources[2].start = OMAP34XX_EHCI_BASE;
648 usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1;
649 usbhs_resources[3].start = INT_34XX_EHCI_IRQ;
650 usbhs_resources[4].start = OMAP34XX_OHCI_BASE;
651 usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1;
652 usbhs_resources[5].start = INT_34XX_OHCI_IRQ;
653 setup_ehci_io_mux(pdata->port_mode);
654 setup_ohci_io_mux(pdata->port_mode);
655 } else if (cpu_is_omap44xx()) {
656 usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE;
657 usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1;
658 usbhs_resources[1].start = OMAP44XX_USBTLL_BASE;
659 usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
660 usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE;
661 usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
662 usbhs_resources[3].start = OMAP44XX_IRQ_EHCI;
663 usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE;
664 usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1;
665 usbhs_resources[5].start = OMAP44XX_IRQ_OHCI;
666 setup_4430ehci_io_mux(pdata->port_mode);
667 setup_4430ohci_io_mux(pdata->port_mode);
668 }
669
670 if (platform_device_add_data(&usbhs_device,
671 &usbhs_data, sizeof(usbhs_data)) < 0) {
672 printk(KERN_ERR "USBHS platform_device_add_data failed\n");
673 goto init_end;
674 }
675
676 if (platform_device_register(&usbhs_device) < 0)
677 printk(KERN_ERR "USBHS platform_device_register failed\n");
678
679init_end:
680 return;
681}
682
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530683#else
684
Keshava Munegowda22363962011-03-01 20:08:18 +0530685void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
686{
687}
688
Keshava Munegowda181b2502011-03-01 20:08:16 +0530689void __init usb_ohci_init(const struct usbhs_omap_board_data *pdata)
Anand Gadiyar95344fc2010-05-10 21:56:10 +0530690{
691}
692
Keshava Munegowda22363962011-03-01 20:08:18 +0530693void __init usb_ehci_init(const struct usbhs_omap_board_data *pdata)
694{
695}
696#endif
697
698