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