1 /* 2 * OHCI HCD (Host Controller Driver) for USB. 3 * 4 * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> 5 * (C) Copyright 2000-2005 David Brownell 6 * (C) Copyright 2002 Hewlett-Packard Company 7 * 8 * OMAP Bus Glue 9 * 10 * Modified for OMAP by Tony Lindgren <tony@atomide.com> 11 * Based on the 2.4 OMAP OHCI driver originally done by MontaVista Software Inc. 12 * and on ohci-sa1111.c by Christopher Hoover <ch@hpl.hp.com> 13 * 14 * This file is licenced under the GPL. 15 */ 16 17 #include <asm/hardware.h> 18 #include <asm/io.h> 19 #include <asm/mach-types.h> 20 21 #include <asm/arch/hardware.h> 22 #include <asm/arch/mux.h> 23 #include <asm/arch/irqs.h> 24 #include <asm/arch/gpio.h> 25 #include <asm/arch/fpga.h> 26 #include <asm/arch/usb.h> 27 #include <asm/hardware/clock.h> 28 29 30 /* OMAP-1510 OHCI has its own MMU for DMA */ 31 #define OMAP1510_LB_MEMSIZE 32 /* Should be same as SDRAM size */ 32 #define OMAP1510_LB_CLOCK_DIV 0xfffec10c 33 #define OMAP1510_LB_MMU_CTL 0xfffec208 34 #define OMAP1510_LB_MMU_LCK 0xfffec224 35 #define OMAP1510_LB_MMU_LD_TLB 0xfffec228 36 #define OMAP1510_LB_MMU_CAM_H 0xfffec22c 37 #define OMAP1510_LB_MMU_CAM_L 0xfffec230 38 #define OMAP1510_LB_MMU_RAM_H 0xfffec234 39 #define OMAP1510_LB_MMU_RAM_L 0xfffec238 40 41 42 #ifndef CONFIG_ARCH_OMAP 43 #error "This file is OMAP bus glue. CONFIG_OMAP must be defined." 44 #endif 45 46 #ifdef CONFIG_TPS65010 47 #include <asm/arch/tps65010.h> 48 #else 49 50 #define LOW 0 51 #define HIGH 1 52 53 #define GPIO1 1 54 55 static inline int tps65010_set_gpio_out_value(unsigned gpio, unsigned value) 56 { 57 return 0; 58 } 59 60 #endif 61 62 extern int usb_disabled(void); 63 extern int ocpi_enable(void); 64 65 static struct clk *usb_host_ck; 66 67 static void omap_ohci_clock_power(int on) 68 { 69 if (on) { 70 clk_enable(usb_host_ck); 71 /* guesstimate for T5 == 1x 32K clock + APLL lock time */ 72 udelay(100); 73 } else { 74 clk_disable(usb_host_ck); 75 } 76 } 77 78 /* 79 * Board specific gang-switched transceiver power on/off. 80 * NOTE: OSK supplies power from DC, not battery. 81 */ 82 static int omap_ohci_transceiver_power(int on) 83 { 84 if (on) { 85 if (machine_is_omap_innovator() && cpu_is_omap1510()) 86 fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) 87 | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), 88 INNOVATOR_FPGA_CAM_USB_CONTROL); 89 else if (machine_is_omap_osk()) 90 tps65010_set_gpio_out_value(GPIO1, LOW); 91 } else { 92 if (machine_is_omap_innovator() && cpu_is_omap1510()) 93 fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) 94 & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), 95 INNOVATOR_FPGA_CAM_USB_CONTROL); 96 else if (machine_is_omap_osk()) 97 tps65010_set_gpio_out_value(GPIO1, HIGH); 98 } 99 100 return 0; 101 } 102 103 /* 104 * OMAP-1510 specific Local Bus clock on/off 105 */ 106 static int omap_1510_local_bus_power(int on) 107 { 108 if (on) { 109 omap_writel((1 << 1) | (1 << 0), OMAP1510_LB_MMU_CTL); 110 udelay(200); 111 } else { 112 omap_writel(0, OMAP1510_LB_MMU_CTL); 113 } 114 115 return 0; 116 } 117 118 /* 119 * OMAP-1510 specific Local Bus initialization 120 * NOTE: This assumes 32MB memory size in OMAP1510LB_MEMSIZE. 121 * See also arch/mach-omap/memory.h for __virt_to_dma() and 122 * __dma_to_virt() which need to match with the physical 123 * Local Bus address below. 124 */ 125 static int omap_1510_local_bus_init(void) 126 { 127 unsigned int tlb; 128 unsigned long lbaddr, physaddr; 129 130 omap_writel((omap_readl(OMAP1510_LB_CLOCK_DIV) & 0xfffffff8) | 0x4, 131 OMAP1510_LB_CLOCK_DIV); 132 133 /* Configure the Local Bus MMU table */ 134 for (tlb = 0; tlb < OMAP1510_LB_MEMSIZE; tlb++) { 135 lbaddr = tlb * 0x00100000 + OMAP1510_LB_OFFSET; 136 physaddr = tlb * 0x00100000 + PHYS_OFFSET; 137 omap_writel((lbaddr & 0x0fffffff) >> 22, OMAP1510_LB_MMU_CAM_H); 138 omap_writel(((lbaddr & 0x003ffc00) >> 6) | 0xc, 139 OMAP1510_LB_MMU_CAM_L); 140 omap_writel(physaddr >> 16, OMAP1510_LB_MMU_RAM_H); 141 omap_writel((physaddr & 0x0000fc00) | 0x300, OMAP1510_LB_MMU_RAM_L); 142 omap_writel(tlb << 4, OMAP1510_LB_MMU_LCK); 143 omap_writel(0x1, OMAP1510_LB_MMU_LD_TLB); 144 } 145 146 /* Enable the walking table */ 147 omap_writel(omap_readl(OMAP1510_LB_MMU_CTL) | (1 << 3), OMAP1510_LB_MMU_CTL); 148 udelay(200); 149 150 return 0; 151 } 152 153 #ifdef CONFIG_USB_OTG 154 155 static void start_hnp(struct ohci_hcd *ohci) 156 { 157 const unsigned port = ohci_to_hcd(ohci)->self.otg_port - 1; 158 unsigned long flags; 159 160 otg_start_hnp(ohci->transceiver); 161 162 local_irq_save(flags); 163 ohci->transceiver->state = OTG_STATE_A_SUSPEND; 164 writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); 165 OTG_CTRL_REG &= ~OTG_A_BUSREQ; 166 local_irq_restore(flags); 167 } 168 169 #endif 170 171 /*-------------------------------------------------------------------------*/ 172 173 static int omap_start_hc(struct ohci_hcd *ohci, struct platform_device *pdev) 174 { 175 struct omap_usb_config *config = pdev->dev.platform_data; 176 int need_transceiver = (config->otg != 0); 177 int ret; 178 179 dev_dbg(&pdev->dev, "starting USB Controller\n"); 180 181 if (config->otg) { 182 ohci_to_hcd(ohci)->self.otg_port = config->otg; 183 /* default/minimum OTG power budget: 8 mA */ 184 ohci_to_hcd(ohci)->power_budget = 8; 185 } 186 187 /* boards can use OTG transceivers in non-OTG modes */ 188 need_transceiver = need_transceiver 189 || machine_is_omap_h2() || machine_is_omap_h3(); 190 191 if (cpu_is_omap16xx()) 192 ocpi_enable(); 193 194 #ifdef CONFIG_ARCH_OMAP_OTG 195 if (need_transceiver) { 196 ohci->transceiver = otg_get_transceiver(); 197 if (ohci->transceiver) { 198 int status = otg_set_host(ohci->transceiver, 199 &ohci_to_hcd(ohci)->self); 200 dev_dbg(&pdev->dev, "init %s transceiver, status %d\n", 201 ohci->transceiver->label, status); 202 if (status) { 203 if (ohci->transceiver) 204 put_device(ohci->transceiver->dev); 205 return status; 206 } 207 } else { 208 dev_err(&pdev->dev, "can't find transceiver\n"); 209 return -ENODEV; 210 } 211 } 212 #endif 213 214 omap_ohci_clock_power(1); 215 216 if (cpu_is_omap1510()) { 217 omap_1510_local_bus_power(1); 218 omap_1510_local_bus_init(); 219 } 220 221 if ((ret = ohci_init(ohci)) < 0) 222 return ret; 223 224 /* board-specific power switching and overcurrent support */ 225 if (machine_is_omap_osk() || machine_is_omap_innovator()) { 226 u32 rh = roothub_a (ohci); 227 228 /* power switching (ganged by default) */ 229 rh &= ~RH_A_NPS; 230 231 /* TPS2045 switch for internal transceiver (port 1) */ 232 if (machine_is_omap_osk()) { 233 ohci_to_hcd(ohci)->power_budget = 250; 234 235 rh &= ~RH_A_NOCP; 236 237 /* gpio9 for overcurrent detction */ 238 omap_cfg_reg(W8_1610_GPIO9); 239 omap_request_gpio(9); 240 omap_set_gpio_direction(9, 1 /* IN */); 241 242 /* for paranoia's sake: disable USB.PUEN */ 243 omap_cfg_reg(W4_USB_HIGHZ); 244 } 245 ohci_writel(ohci, rh, &ohci->regs->roothub.a); 246 distrust_firmware = 0; 247 } 248 249 /* FIXME khubd hub requests should manage power switching */ 250 omap_ohci_transceiver_power(1); 251 252 /* board init will have already handled HMC and mux setup. 253 * any external transceiver should already be initialized 254 * too, so all configured ports use the right signaling now. 255 */ 256 257 return 0; 258 } 259 260 static void omap_stop_hc(struct platform_device *pdev) 261 { 262 dev_dbg(&pdev->dev, "stopping USB Controller\n"); 263 omap_ohci_clock_power(0); 264 } 265 266 267 /*-------------------------------------------------------------------------*/ 268 269 void usb_hcd_omap_remove (struct usb_hcd *, struct platform_device *); 270 271 /* configure so an HC device and id are always provided */ 272 /* always called with process context; sleeping is OK */ 273 274 275 /** 276 * usb_hcd_omap_probe - initialize OMAP-based HCDs 277 * Context: !in_interrupt() 278 * 279 * Allocates basic resources for this USB host controller, and 280 * then invokes the start() method for the HCD associated with it 281 * through the hotplug entry's driver_data. 282 */ 283 int usb_hcd_omap_probe (const struct hc_driver *driver, 284 struct platform_device *pdev) 285 { 286 int retval; 287 struct usb_hcd *hcd = 0; 288 struct ohci_hcd *ohci; 289 290 if (pdev->num_resources != 2) { 291 printk(KERN_ERR "hcd probe: invalid num_resources: %i\n", 292 pdev->num_resources); 293 return -ENODEV; 294 } 295 296 if (pdev->resource[0].flags != IORESOURCE_MEM 297 || pdev->resource[1].flags != IORESOURCE_IRQ) { 298 printk(KERN_ERR "hcd probe: invalid resource type\n"); 299 return -ENODEV; 300 } 301 302 usb_host_ck = clk_get(0, "usb_hhc_ck"); 303 if (IS_ERR(usb_host_ck)) 304 return PTR_ERR(usb_host_ck); 305 306 hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id); 307 if (!hcd) { 308 retval = -ENOMEM; 309 goto err0; 310 } 311 hcd->rsrc_start = pdev->resource[0].start; 312 hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; 313 314 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { 315 dev_dbg(&pdev->dev, "request_mem_region failed\n"); 316 retval = -EBUSY; 317 goto err1; 318 } 319 320 hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start); 321 322 ohci = hcd_to_ohci(hcd); 323 ohci_hcd_init(ohci); 324 325 retval = omap_start_hc(ohci, pdev); 326 if (retval < 0) 327 goto err2; 328 329 retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), SA_INTERRUPT); 330 if (retval == 0) 331 return retval; 332 333 omap_stop_hc(pdev); 334 err2: 335 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 336 err1: 337 usb_put_hcd(hcd); 338 err0: 339 clk_put(usb_host_ck); 340 return retval; 341 } 342 343 344 /* may be called with controller, bus, and devices active */ 345 346 /** 347 * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs 348 * @dev: USB Host Controller being removed 349 * Context: !in_interrupt() 350 * 351 * Reverses the effect of usb_hcd_omap_probe(), first invoking 352 * the HCD's stop() method. It is always called from a thread 353 * context, normally "rmmod", "apmd", or something similar. 354 * 355 */ 356 void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) 357 { 358 usb_remove_hcd(hcd); 359 if (machine_is_omap_osk()) 360 omap_free_gpio(9); 361 omap_stop_hc(pdev); 362 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 363 usb_put_hcd(hcd); 364 clk_put(usb_host_ck); 365 } 366 367 /*-------------------------------------------------------------------------*/ 368 369 static int __devinit 370 ohci_omap_start (struct usb_hcd *hcd) 371 { 372 struct omap_usb_config *config; 373 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 374 int ret; 375 376 config = hcd->self.controller->platform_data; 377 if (config->otg || config->rwc) 378 writel(OHCI_CTRL_RWC, &ohci->regs->control); 379 380 if ((ret = ohci_run (ohci)) < 0) { 381 dev_err(hcd->self.controller, "can't start\n"); 382 ohci_stop (hcd); 383 return ret; 384 } 385 return 0; 386 } 387 388 /*-------------------------------------------------------------------------*/ 389 390 static const struct hc_driver ohci_omap_hc_driver = { 391 .description = hcd_name, 392 .product_desc = "OMAP OHCI", 393 .hcd_priv_size = sizeof(struct ohci_hcd), 394 395 /* 396 * generic hardware linkage 397 */ 398 .irq = ohci_irq, 399 .flags = HCD_USB11 | HCD_MEMORY, 400 401 /* 402 * basic lifecycle operations 403 */ 404 .start = ohci_omap_start, 405 .stop = ohci_stop, 406 407 /* 408 * managing i/o requests and associated device resources 409 */ 410 .urb_enqueue = ohci_urb_enqueue, 411 .urb_dequeue = ohci_urb_dequeue, 412 .endpoint_disable = ohci_endpoint_disable, 413 414 /* 415 * scheduling support 416 */ 417 .get_frame_number = ohci_get_frame, 418 419 /* 420 * root hub support 421 */ 422 .hub_status_data = ohci_hub_status_data, 423 .hub_control = ohci_hub_control, 424 #ifdef CONFIG_USB_SUSPEND 425 .hub_suspend = ohci_hub_suspend, 426 .hub_resume = ohci_hub_resume, 427 #endif 428 .start_port_reset = ohci_start_port_reset, 429 }; 430 431 /*-------------------------------------------------------------------------*/ 432 433 static int ohci_hcd_omap_drv_probe(struct device *dev) 434 { 435 return usb_hcd_omap_probe(&ohci_omap_hc_driver, 436 to_platform_device(dev)); 437 } 438 439 static int ohci_hcd_omap_drv_remove(struct device *dev) 440 { 441 struct platform_device *pdev = to_platform_device(dev); 442 struct usb_hcd *hcd = dev_get_drvdata(dev); 443 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 444 445 usb_hcd_omap_remove(hcd, pdev); 446 if (ohci->transceiver) { 447 (void) otg_set_host(ohci->transceiver, 0); 448 put_device(ohci->transceiver->dev); 449 } 450 dev_set_drvdata(dev, NULL); 451 452 return 0; 453 } 454 455 /*-------------------------------------------------------------------------*/ 456 457 #ifdef CONFIG_PM 458 459 static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level) 460 { 461 struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); 462 int status = -EINVAL; 463 464 if (level != SUSPEND_POWER_DOWN) 465 return 0; 466 467 down(&ohci_to_hcd(ohci)->self.root_hub->serialize); 468 status = ohci_hub_suspend(ohci_to_hcd(ohci)); 469 if (status == 0) { 470 omap_ohci_clock_power(0); 471 ohci_to_hcd(ohci)->self.root_hub->state = 472 USB_STATE_SUSPENDED; 473 ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; 474 dev->power.power_state = PMSG_SUSPEND; 475 } 476 up(&ohci_to_hcd(ohci)->self.root_hub->serialize); 477 return status; 478 } 479 480 static int ohci_omap_resume(struct device *dev, u32 level) 481 { 482 struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); 483 int status = 0; 484 485 if (level != RESUME_POWER_ON) 486 return 0; 487 488 if (time_before(jiffies, ohci->next_statechange)) 489 msleep(5); 490 ohci->next_statechange = jiffies; 491 omap_ohci_clock_power(1); 492 #ifdef CONFIG_USB_SUSPEND 493 /* get extra cleanup even if remote wakeup isn't in use */ 494 status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); 495 #else 496 down(&ohci_to_hcd(ohci)->self.root_hub->serialize); 497 status = ohci_hub_resume(ohci_to_hcd(ohci)); 498 up(&ohci_to_hcd(ohci)->self.root_hub->serialize); 499 #endif 500 if (status == 0) 501 dev->power.power_state = PMSG_ON; 502 return status; 503 } 504 505 #endif 506 507 /*-------------------------------------------------------------------------*/ 508 509 /* 510 * Driver definition to register with the OMAP bus 511 */ 512 static struct device_driver ohci_hcd_omap_driver = { 513 .name = "ohci", 514 .bus = &platform_bus_type, 515 .probe = ohci_hcd_omap_drv_probe, 516 .remove = ohci_hcd_omap_drv_remove, 517 #ifdef CONFIG_PM 518 .suspend = ohci_omap_suspend, 519 .resume = ohci_omap_resume, 520 #endif 521 }; 522 523 static int __init ohci_hcd_omap_init (void) 524 { 525 printk (KERN_DEBUG "%s: " DRIVER_INFO " (OMAP)\n", hcd_name); 526 if (usb_disabled()) 527 return -ENODEV; 528 529 pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name, 530 sizeof (struct ed), sizeof (struct td)); 531 532 return driver_register(&ohci_hcd_omap_driver); 533 } 534 535 static void __exit ohci_hcd_omap_cleanup (void) 536 { 537 driver_unregister(&ohci_hcd_omap_driver); 538 } 539 540 module_init (ohci_hcd_omap_init); 541 module_exit (ohci_hcd_omap_cleanup); 542