1 /* 2 * Broadcom specific Advanced Microcontroller Bus 3 * Broadcom USB-core driver (BCMA bus glue) 4 * 5 * Copyright 2011-2015 Hauke Mehrtens <hauke@hauke-m.de> 6 * Copyright 2015 Felix Fietkau <nbd@openwrt.org> 7 * 8 * Based on ssb-ohci driver 9 * Copyright 2007 Michael Buesch <m@bues.ch> 10 * 11 * Derived from the OHCI-PCI driver 12 * Copyright 1999 Roman Weissgaerber 13 * Copyright 2000-2002 David Brownell 14 * Copyright 1999 Linus Torvalds 15 * Copyright 1999 Gregory P. Smith 16 * 17 * Derived from the USBcore related parts of Broadcom-SB 18 * Copyright 2005-2011 Broadcom Corporation 19 * 20 * Licensed under the GNU/GPL. See COPYING for details. 21 */ 22 #include <linux/bcma/bcma.h> 23 #include <linux/delay.h> 24 #include <linux/gpio/consumer.h> 25 #include <linux/platform_device.h> 26 #include <linux/module.h> 27 #include <linux/slab.h> 28 #include <linux/of.h> 29 #include <linux/of_gpio.h> 30 #include <linux/usb/ehci_pdriver.h> 31 #include <linux/usb/ohci_pdriver.h> 32 33 MODULE_AUTHOR("Hauke Mehrtens"); 34 MODULE_DESCRIPTION("Common USB driver for BCMA Bus"); 35 MODULE_LICENSE("GPL"); 36 37 struct bcma_hcd_device { 38 struct bcma_device *core; 39 struct platform_device *ehci_dev; 40 struct platform_device *ohci_dev; 41 struct gpio_desc *gpio_desc; 42 }; 43 44 /* Wait for bitmask in a register to get set or cleared. 45 * timeout is in units of ten-microseconds. 46 */ 47 static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask, 48 int timeout) 49 { 50 int i; 51 u32 val; 52 53 for (i = 0; i < timeout; i++) { 54 val = bcma_read32(dev, reg); 55 if ((val & bitmask) == bitmask) 56 return 0; 57 udelay(10); 58 } 59 60 return -ETIMEDOUT; 61 } 62 63 static void bcma_hcd_4716wa(struct bcma_device *dev) 64 { 65 #ifdef CONFIG_BCMA_DRIVER_MIPS 66 /* Work around for 4716 failures. */ 67 if (dev->bus->chipinfo.id == 0x4716) { 68 u32 tmp; 69 70 tmp = bcma_cpu_clock(&dev->bus->drv_mips); 71 if (tmp >= 480000000) 72 tmp = 0x1846b; /* set CDR to 0x11(fast) */ 73 else if (tmp == 453000000) 74 tmp = 0x1046b; /* set CDR to 0x10(slow) */ 75 else 76 tmp = 0; 77 78 /* Change Shim mdio control reg to fix host not acking at 79 * high frequencies 80 */ 81 if (tmp) { 82 bcma_write32(dev, 0x524, 0x1); /* write sel to enable */ 83 udelay(500); 84 85 bcma_write32(dev, 0x524, tmp); 86 udelay(500); 87 bcma_write32(dev, 0x524, 0x4ab); 88 udelay(500); 89 bcma_read32(dev, 0x528); 90 bcma_write32(dev, 0x528, 0x80000000); 91 } 92 } 93 #endif /* CONFIG_BCMA_DRIVER_MIPS */ 94 } 95 96 /* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */ 97 static void bcma_hcd_init_chip_mips(struct bcma_device *dev) 98 { 99 u32 tmp; 100 101 /* 102 * USB 2.0 special considerations: 103 * 104 * 1. Since the core supports both OHCI and EHCI functions, it must 105 * only be reset once. 106 * 107 * 2. In addition to the standard SI reset sequence, the Host Control 108 * Register must be programmed to bring the USB core and various 109 * phy components out of reset. 110 */ 111 if (!bcma_core_is_enabled(dev)) { 112 bcma_core_enable(dev, 0); 113 mdelay(10); 114 if (dev->id.rev >= 5) { 115 /* Enable Misc PLL */ 116 tmp = bcma_read32(dev, 0x1e0); 117 tmp |= 0x100; 118 bcma_write32(dev, 0x1e0, tmp); 119 if (bcma_wait_bits(dev, 0x1e0, 1 << 24, 100)) 120 printk(KERN_EMERG "Failed to enable misc PPL!\n"); 121 122 /* Take out of resets */ 123 bcma_write32(dev, 0x200, 0x4ff); 124 udelay(25); 125 bcma_write32(dev, 0x200, 0x6ff); 126 udelay(25); 127 128 /* Make sure digital and AFE are locked in USB PHY */ 129 bcma_write32(dev, 0x524, 0x6b); 130 udelay(50); 131 tmp = bcma_read32(dev, 0x524); 132 udelay(50); 133 bcma_write32(dev, 0x524, 0xab); 134 udelay(50); 135 tmp = bcma_read32(dev, 0x524); 136 udelay(50); 137 bcma_write32(dev, 0x524, 0x2b); 138 udelay(50); 139 tmp = bcma_read32(dev, 0x524); 140 udelay(50); 141 bcma_write32(dev, 0x524, 0x10ab); 142 udelay(50); 143 tmp = bcma_read32(dev, 0x524); 144 145 if (bcma_wait_bits(dev, 0x528, 0xc000, 10000)) { 146 tmp = bcma_read32(dev, 0x528); 147 printk(KERN_EMERG 148 "USB20H mdio_rddata 0x%08x\n", tmp); 149 } 150 bcma_write32(dev, 0x528, 0x80000000); 151 tmp = bcma_read32(dev, 0x314); 152 udelay(265); 153 bcma_write32(dev, 0x200, 0x7ff); 154 udelay(10); 155 156 /* Take USB and HSIC out of non-driving modes */ 157 bcma_write32(dev, 0x510, 0); 158 } else { 159 bcma_write32(dev, 0x200, 0x7ff); 160 161 udelay(1); 162 } 163 164 bcma_hcd_4716wa(dev); 165 } 166 } 167 168 static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev) 169 { 170 struct bcma_device *arm_core; 171 void __iomem *dmu; 172 173 arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9); 174 if (!arm_core) { 175 dev_err(&dev->dev, "can not find ARM Cortex A9 ihost core\n"); 176 return; 177 } 178 179 dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000); 180 if (!dmu) { 181 dev_err(&dev->dev, "can not map ARM Cortex A9 ihost core\n"); 182 return; 183 } 184 185 /* Unlock DMU PLL settings */ 186 iowrite32(0x0000ea68, dmu + 0x180); 187 188 /* Write USB 2.0 PLL control setting */ 189 iowrite32(0x00dd10c3, dmu + 0x164); 190 191 /* Lock DMU PLL settings */ 192 iowrite32(0x00000000, dmu + 0x180); 193 194 iounmap(dmu); 195 } 196 197 static void bcma_hcd_init_chip_arm_hc(struct bcma_device *dev) 198 { 199 u32 val; 200 201 /* 202 * Delay after PHY initialized to ensure HC is ready to be configured 203 */ 204 usleep_range(1000, 2000); 205 206 /* Set packet buffer OUT threshold */ 207 val = bcma_read32(dev, 0x94); 208 val &= 0xffff; 209 val |= 0x80 << 16; 210 bcma_write32(dev, 0x94, val); 211 212 /* Enable break memory transfer */ 213 val = bcma_read32(dev, 0x9c); 214 val |= 1; 215 bcma_write32(dev, 0x9c, val); 216 } 217 218 static void bcma_hcd_init_chip_arm(struct bcma_device *dev) 219 { 220 bcma_core_enable(dev, 0); 221 222 if (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4707 || 223 dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM53018) { 224 if (dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4707 || 225 dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4708) 226 bcma_hcd_init_chip_arm_phy(dev); 227 228 bcma_hcd_init_chip_arm_hc(dev); 229 } 230 } 231 232 static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val) 233 { 234 struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev); 235 236 if (IS_ERR_OR_NULL(usb_dev->gpio_desc)) 237 return; 238 239 gpiod_set_value(usb_dev->gpio_desc, val); 240 } 241 242 static const struct usb_ehci_pdata ehci_pdata = { 243 }; 244 245 static const struct usb_ohci_pdata ohci_pdata = { 246 }; 247 248 static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, 249 const char *name, u32 addr, 250 const void *data, 251 size_t size) 252 { 253 struct platform_device *hci_dev; 254 struct resource hci_res[2]; 255 int ret; 256 257 memset(hci_res, 0, sizeof(hci_res)); 258 259 hci_res[0].start = addr; 260 hci_res[0].end = hci_res[0].start + 0x1000 - 1; 261 hci_res[0].flags = IORESOURCE_MEM; 262 263 hci_res[1].start = dev->irq; 264 hci_res[1].flags = IORESOURCE_IRQ; 265 266 hci_dev = platform_device_alloc(name, 0); 267 if (!hci_dev) 268 return ERR_PTR(-ENOMEM); 269 270 hci_dev->dev.parent = &dev->dev; 271 hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask; 272 273 ret = platform_device_add_resources(hci_dev, hci_res, 274 ARRAY_SIZE(hci_res)); 275 if (ret) 276 goto err_alloc; 277 if (data) 278 ret = platform_device_add_data(hci_dev, data, size); 279 if (ret) 280 goto err_alloc; 281 ret = platform_device_add(hci_dev); 282 if (ret) 283 goto err_alloc; 284 285 return hci_dev; 286 287 err_alloc: 288 platform_device_put(hci_dev); 289 return ERR_PTR(ret); 290 } 291 292 static int bcma_hcd_usb20_init(struct bcma_hcd_device *usb_dev) 293 { 294 struct bcma_device *dev = usb_dev->core; 295 struct bcma_chipinfo *chipinfo = &dev->bus->chipinfo; 296 u32 ohci_addr; 297 int err; 298 299 if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32))) 300 return -EOPNOTSUPP; 301 302 switch (dev->id.id) { 303 case BCMA_CORE_NS_USB20: 304 bcma_hcd_init_chip_arm(dev); 305 break; 306 case BCMA_CORE_USB20_HOST: 307 bcma_hcd_init_chip_mips(dev); 308 break; 309 default: 310 return -ENODEV; 311 } 312 313 /* In AI chips EHCI is addrspace 0, OHCI is 1 */ 314 ohci_addr = dev->addr_s[0]; 315 if ((chipinfo->id == BCMA_CHIP_ID_BCM5357 || 316 chipinfo->id == BCMA_CHIP_ID_BCM4749) 317 && chipinfo->rev == 0) 318 ohci_addr = 0x18009000; 319 320 usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, "ohci-platform", 321 ohci_addr, &ohci_pdata, 322 sizeof(ohci_pdata)); 323 if (IS_ERR(usb_dev->ohci_dev)) 324 return PTR_ERR(usb_dev->ohci_dev); 325 326 usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, "ehci-platform", 327 dev->addr, &ehci_pdata, 328 sizeof(ehci_pdata)); 329 if (IS_ERR(usb_dev->ehci_dev)) { 330 err = PTR_ERR(usb_dev->ehci_dev); 331 goto err_unregister_ohci_dev; 332 } 333 334 return 0; 335 336 err_unregister_ohci_dev: 337 platform_device_unregister(usb_dev->ohci_dev); 338 return err; 339 } 340 341 static int bcma_hcd_probe(struct bcma_device *core) 342 { 343 int err; 344 struct bcma_hcd_device *usb_dev; 345 346 /* TODO: Probably need checks here; is the core connected? */ 347 348 usb_dev = devm_kzalloc(&core->dev, sizeof(struct bcma_hcd_device), 349 GFP_KERNEL); 350 if (!usb_dev) 351 return -ENOMEM; 352 usb_dev->core = core; 353 354 if (core->dev.of_node) 355 usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc", 356 GPIOD_OUT_HIGH); 357 358 switch (core->id.id) { 359 case BCMA_CORE_USB20_HOST: 360 case BCMA_CORE_NS_USB20: 361 err = bcma_hcd_usb20_init(usb_dev); 362 if (err) 363 return err; 364 break; 365 default: 366 return -ENODEV; 367 } 368 369 bcma_set_drvdata(core, usb_dev); 370 return 0; 371 } 372 373 static void bcma_hcd_remove(struct bcma_device *dev) 374 { 375 struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev); 376 struct platform_device *ohci_dev = usb_dev->ohci_dev; 377 struct platform_device *ehci_dev = usb_dev->ehci_dev; 378 379 if (ohci_dev) 380 platform_device_unregister(ohci_dev); 381 if (ehci_dev) 382 platform_device_unregister(ehci_dev); 383 384 bcma_core_disable(dev, 0); 385 } 386 387 static void bcma_hcd_shutdown(struct bcma_device *dev) 388 { 389 bcma_hci_platform_power_gpio(dev, false); 390 bcma_core_disable(dev, 0); 391 } 392 393 #ifdef CONFIG_PM 394 395 static int bcma_hcd_suspend(struct bcma_device *dev) 396 { 397 bcma_hci_platform_power_gpio(dev, false); 398 bcma_core_disable(dev, 0); 399 400 return 0; 401 } 402 403 static int bcma_hcd_resume(struct bcma_device *dev) 404 { 405 bcma_hci_platform_power_gpio(dev, true); 406 bcma_core_enable(dev, 0); 407 408 return 0; 409 } 410 411 #else /* !CONFIG_PM */ 412 #define bcma_hcd_suspend NULL 413 #define bcma_hcd_resume NULL 414 #endif /* CONFIG_PM */ 415 416 static const struct bcma_device_id bcma_hcd_table[] = { 417 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS), 418 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS), 419 {}, 420 }; 421 MODULE_DEVICE_TABLE(bcma, bcma_hcd_table); 422 423 static struct bcma_driver bcma_hcd_driver = { 424 .name = KBUILD_MODNAME, 425 .id_table = bcma_hcd_table, 426 .probe = bcma_hcd_probe, 427 .remove = bcma_hcd_remove, 428 .shutdown = bcma_hcd_shutdown, 429 .suspend = bcma_hcd_suspend, 430 .resume = bcma_hcd_resume, 431 }; 432 433 static int __init bcma_hcd_init(void) 434 { 435 return bcma_driver_register(&bcma_hcd_driver); 436 } 437 module_init(bcma_hcd_init); 438 439 static void __exit bcma_hcd_exit(void) 440 { 441 bcma_driver_unregister(&bcma_hcd_driver); 442 } 443 module_exit(bcma_hcd_exit); 444