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 <linux/dma-mapping.h> 24 25#include <asm/io.h> 26 27#include <mach/hardware.h> 28#include <mach/irqs.h> 29#include <plat/usb.h> 30 31#include "mux.h" 32 33#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE) 34 35static struct resource ehci_resources[] = { 36 { 37 .start = OMAP34XX_EHCI_BASE, 38 .end = OMAP34XX_EHCI_BASE + SZ_1K - 1, 39 .flags = IORESOURCE_MEM, 40 }, 41 { 42 .start = OMAP34XX_UHH_CONFIG_BASE, 43 .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1, 44 .flags = IORESOURCE_MEM, 45 }, 46 { 47 .start = OMAP34XX_USBTLL_BASE, 48 .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1, 49 .flags = IORESOURCE_MEM, 50 }, 51 { /* general IRQ */ 52 .start = INT_34XX_EHCI_IRQ, 53 .flags = IORESOURCE_IRQ, 54 } 55}; 56 57static u64 ehci_dmamask = ~(u32)0; 58static struct platform_device ehci_device = { 59 .name = "ehci-omap", 60 .id = 0, 61 .dev = { 62 .dma_mask = &ehci_dmamask, 63 .coherent_dma_mask = 0xffffffff, 64 .platform_data = NULL, 65 }, 66 .num_resources = ARRAY_SIZE(ehci_resources), 67 .resource = ehci_resources, 68}; 69 70/* MUX settings for EHCI pins */ 71/* 72 * setup_ehci_io_mux - initialize IO pad mux for USBHOST 73 */ 74static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) 75{ 76 switch (port_mode[0]) { 77 case EHCI_HCD_OMAP_MODE_PHY: 78 omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT); 79 omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT); 80 omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN); 81 omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN); 82 omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN); 83 omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN); 84 omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN); 85 omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN); 86 omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN); 87 omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN); 88 omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN); 89 omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN); 90 break; 91 case EHCI_HCD_OMAP_MODE_TLL: 92 omap_mux_init_signal("hsusb1_tll_stp", 93 OMAP_PIN_INPUT_PULLUP); 94 omap_mux_init_signal("hsusb1_tll_clk", 95 OMAP_PIN_INPUT_PULLDOWN); 96 omap_mux_init_signal("hsusb1_tll_dir", 97 OMAP_PIN_INPUT_PULLDOWN); 98 omap_mux_init_signal("hsusb1_tll_nxt", 99 OMAP_PIN_INPUT_PULLDOWN); 100 omap_mux_init_signal("hsusb1_tll_data0", 101 OMAP_PIN_INPUT_PULLDOWN); 102 omap_mux_init_signal("hsusb1_tll_data1", 103 OMAP_PIN_INPUT_PULLDOWN); 104 omap_mux_init_signal("hsusb1_tll_data2", 105 OMAP_PIN_INPUT_PULLDOWN); 106 omap_mux_init_signal("hsusb1_tll_data3", 107 OMAP_PIN_INPUT_PULLDOWN); 108 omap_mux_init_signal("hsusb1_tll_data4", 109 OMAP_PIN_INPUT_PULLDOWN); 110 omap_mux_init_signal("hsusb1_tll_data5", 111 OMAP_PIN_INPUT_PULLDOWN); 112 omap_mux_init_signal("hsusb1_tll_data6", 113 OMAP_PIN_INPUT_PULLDOWN); 114 omap_mux_init_signal("hsusb1_tll_data7", 115 OMAP_PIN_INPUT_PULLDOWN); 116 break; 117 case EHCI_HCD_OMAP_MODE_UNKNOWN: 118 /* FALLTHROUGH */ 119 default: 120 break; 121 } 122 123 switch (port_mode[1]) { 124 case EHCI_HCD_OMAP_MODE_PHY: 125 omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT); 126 omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT); 127 omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN); 128 omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN); 129 omap_mux_init_signal("hsusb2_data0", 130 OMAP_PIN_INPUT_PULLDOWN); 131 omap_mux_init_signal("hsusb2_data1", 132 OMAP_PIN_INPUT_PULLDOWN); 133 omap_mux_init_signal("hsusb2_data2", 134 OMAP_PIN_INPUT_PULLDOWN); 135 omap_mux_init_signal("hsusb2_data3", 136 OMAP_PIN_INPUT_PULLDOWN); 137 omap_mux_init_signal("hsusb2_data4", 138 OMAP_PIN_INPUT_PULLDOWN); 139 omap_mux_init_signal("hsusb2_data5", 140 OMAP_PIN_INPUT_PULLDOWN); 141 omap_mux_init_signal("hsusb2_data6", 142 OMAP_PIN_INPUT_PULLDOWN); 143 omap_mux_init_signal("hsusb2_data7", 144 OMAP_PIN_INPUT_PULLDOWN); 145 break; 146 case EHCI_HCD_OMAP_MODE_TLL: 147 omap_mux_init_signal("hsusb2_tll_stp", 148 OMAP_PIN_INPUT_PULLUP); 149 omap_mux_init_signal("hsusb2_tll_clk", 150 OMAP_PIN_INPUT_PULLDOWN); 151 omap_mux_init_signal("hsusb2_tll_dir", 152 OMAP_PIN_INPUT_PULLDOWN); 153 omap_mux_init_signal("hsusb2_tll_nxt", 154 OMAP_PIN_INPUT_PULLDOWN); 155 omap_mux_init_signal("hsusb2_tll_data0", 156 OMAP_PIN_INPUT_PULLDOWN); 157 omap_mux_init_signal("hsusb2_tll_data1", 158 OMAP_PIN_INPUT_PULLDOWN); 159 omap_mux_init_signal("hsusb2_tll_data2", 160 OMAP_PIN_INPUT_PULLDOWN); 161 omap_mux_init_signal("hsusb2_tll_data3", 162 OMAP_PIN_INPUT_PULLDOWN); 163 omap_mux_init_signal("hsusb2_tll_data4", 164 OMAP_PIN_INPUT_PULLDOWN); 165 omap_mux_init_signal("hsusb2_tll_data5", 166 OMAP_PIN_INPUT_PULLDOWN); 167 omap_mux_init_signal("hsusb2_tll_data6", 168 OMAP_PIN_INPUT_PULLDOWN); 169 omap_mux_init_signal("hsusb2_tll_data7", 170 OMAP_PIN_INPUT_PULLDOWN); 171 break; 172 case EHCI_HCD_OMAP_MODE_UNKNOWN: 173 /* FALLTHROUGH */ 174 default: 175 break; 176 } 177 178 switch (port_mode[2]) { 179 case EHCI_HCD_OMAP_MODE_PHY: 180 printk(KERN_WARNING "Port3 can't be used in PHY mode\n"); 181 break; 182 case EHCI_HCD_OMAP_MODE_TLL: 183 omap_mux_init_signal("hsusb3_tll_stp", 184 OMAP_PIN_INPUT_PULLUP); 185 omap_mux_init_signal("hsusb3_tll_clk", 186 OMAP_PIN_INPUT_PULLDOWN); 187 omap_mux_init_signal("hsusb3_tll_dir", 188 OMAP_PIN_INPUT_PULLDOWN); 189 omap_mux_init_signal("hsusb3_tll_nxt", 190 OMAP_PIN_INPUT_PULLDOWN); 191 omap_mux_init_signal("hsusb3_tll_data0", 192 OMAP_PIN_INPUT_PULLDOWN); 193 omap_mux_init_signal("hsusb3_tll_data1", 194 OMAP_PIN_INPUT_PULLDOWN); 195 omap_mux_init_signal("hsusb3_tll_data2", 196 OMAP_PIN_INPUT_PULLDOWN); 197 omap_mux_init_signal("hsusb3_tll_data3", 198 OMAP_PIN_INPUT_PULLDOWN); 199 omap_mux_init_signal("hsusb3_tll_data4", 200 OMAP_PIN_INPUT_PULLDOWN); 201 omap_mux_init_signal("hsusb3_tll_data5", 202 OMAP_PIN_INPUT_PULLDOWN); 203 omap_mux_init_signal("hsusb3_tll_data6", 204 OMAP_PIN_INPUT_PULLDOWN); 205 omap_mux_init_signal("hsusb3_tll_data7", 206 OMAP_PIN_INPUT_PULLDOWN); 207 break; 208 case EHCI_HCD_OMAP_MODE_UNKNOWN: 209 /* FALLTHROUGH */ 210 default: 211 break; 212 } 213 214 return; 215} 216 217void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) 218{ 219 platform_device_add_data(&ehci_device, pdata, sizeof(*pdata)); 220 221 /* Setup Pin IO MUX for EHCI */ 222 if (cpu_is_omap34xx()) 223 setup_ehci_io_mux(pdata->port_mode); 224 225 if (platform_device_register(&ehci_device) < 0) { 226 printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n"); 227 return; 228 } 229} 230 231#else 232 233void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) 234 235{ 236} 237 238#endif /* CONFIG_USB_EHCI_HCD */ 239 240#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 241 242static struct resource ohci_resources[] = { 243 { 244 .start = OMAP34XX_OHCI_BASE, 245 .end = OMAP34XX_OHCI_BASE + SZ_1K - 1, 246 .flags = IORESOURCE_MEM, 247 }, 248 { 249 .start = OMAP34XX_UHH_CONFIG_BASE, 250 .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1, 251 .flags = IORESOURCE_MEM, 252 }, 253 { 254 .start = OMAP34XX_USBTLL_BASE, 255 .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1, 256 .flags = IORESOURCE_MEM, 257 }, 258 { /* general IRQ */ 259 .start = INT_34XX_OHCI_IRQ, 260 .flags = IORESOURCE_IRQ, 261 } 262}; 263 264static u64 ohci_dmamask = DMA_BIT_MASK(32); 265 266static struct platform_device ohci_device = { 267 .name = "ohci-omap3", 268 .id = 0, 269 .dev = { 270 .dma_mask = &ohci_dmamask, 271 .coherent_dma_mask = 0xffffffff, 272 }, 273 .num_resources = ARRAY_SIZE(ohci_resources), 274 .resource = ohci_resources, 275}; 276 277static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode) 278{ 279 switch (port_mode[0]) { 280 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: 281 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: 282 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: 283 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: 284 omap_mux_init_signal("mm1_rxdp", 285 OMAP_PIN_INPUT_PULLDOWN); 286 omap_mux_init_signal("mm1_rxdm", 287 OMAP_PIN_INPUT_PULLDOWN); 288 /* FALLTHROUGH */ 289 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: 290 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: 291 omap_mux_init_signal("mm1_rxrcv", 292 OMAP_PIN_INPUT_PULLDOWN); 293 /* FALLTHROUGH */ 294 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: 295 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: 296 omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT); 297 /* FALLTHROUGH */ 298 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: 299 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: 300 omap_mux_init_signal("mm1_txse0", 301 OMAP_PIN_INPUT_PULLDOWN); 302 omap_mux_init_signal("mm1_txdat", 303 OMAP_PIN_INPUT_PULLDOWN); 304 break; 305 case OMAP_OHCI_PORT_MODE_UNUSED: 306 /* FALLTHROUGH */ 307 default: 308 break; 309 } 310 switch (port_mode[1]) { 311 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: 312 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: 313 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: 314 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: 315 omap_mux_init_signal("mm2_rxdp", 316 OMAP_PIN_INPUT_PULLDOWN); 317 omap_mux_init_signal("mm2_rxdm", 318 OMAP_PIN_INPUT_PULLDOWN); 319 /* FALLTHROUGH */ 320 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: 321 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: 322 omap_mux_init_signal("mm2_rxrcv", 323 OMAP_PIN_INPUT_PULLDOWN); 324 /* FALLTHROUGH */ 325 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: 326 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: 327 omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT); 328 /* FALLTHROUGH */ 329 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: 330 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: 331 omap_mux_init_signal("mm2_txse0", 332 OMAP_PIN_INPUT_PULLDOWN); 333 omap_mux_init_signal("mm2_txdat", 334 OMAP_PIN_INPUT_PULLDOWN); 335 break; 336 case OMAP_OHCI_PORT_MODE_UNUSED: 337 /* FALLTHROUGH */ 338 default: 339 break; 340 } 341 switch (port_mode[2]) { 342 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: 343 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: 344 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: 345 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: 346 omap_mux_init_signal("mm3_rxdp", 347 OMAP_PIN_INPUT_PULLDOWN); 348 omap_mux_init_signal("mm3_rxdm", 349 OMAP_PIN_INPUT_PULLDOWN); 350 /* FALLTHROUGH */ 351 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: 352 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: 353 omap_mux_init_signal("mm3_rxrcv", 354 OMAP_PIN_INPUT_PULLDOWN); 355 /* FALLTHROUGH */ 356 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: 357 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: 358 omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT); 359 /* FALLTHROUGH */ 360 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: 361 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: 362 omap_mux_init_signal("mm3_txse0", 363 OMAP_PIN_INPUT_PULLDOWN); 364 omap_mux_init_signal("mm3_txdat", 365 OMAP_PIN_INPUT_PULLDOWN); 366 break; 367 case OMAP_OHCI_PORT_MODE_UNUSED: 368 /* FALLTHROUGH */ 369 default: 370 break; 371 } 372} 373 374void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata) 375{ 376 platform_device_add_data(&ohci_device, pdata, sizeof(*pdata)); 377 378 /* Setup Pin IO MUX for OHCI */ 379 if (cpu_is_omap34xx()) 380 setup_ohci_io_mux(pdata->port_mode); 381 382 if (platform_device_register(&ohci_device) < 0) { 383 pr_err("Unable to register FS-USB (OHCI) device\n"); 384 return; 385 } 386} 387 388#else 389 390void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata) 391{ 392} 393 394#endif /* CONFIG_USB_OHCI_HCD */ 395