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