CC: upgrade kernel to 3.18.68
[15.05/openwrt.git] / target / linux / bcm53xx / patches-3.18 / 812-USB-bcma-add-USB-3.0-support.patch
1 From 12c6932caa6b1fce44d0f0c68ec77d4c00ac0be7 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
3 Date: Tue, 16 Jun 2015 17:14:26 +0200
4 Subject: [PATCH] USB: bcma: add USB 3.0 support
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
10 ---
11  drivers/usb/host/bcma-hcd.c | 219 ++++++++++++++++++++++++++++++++++++++++++++
12  1 file changed, 219 insertions(+)
13
14 --- a/drivers/usb/host/bcma-hcd.c
15 +++ b/drivers/usb/host/bcma-hcd.c
16 @@ -38,6 +38,7 @@ struct bcma_hcd_device {
17         struct bcma_device *core;
18         struct platform_device *ehci_dev;
19         struct platform_device *ohci_dev;
20 +       struct platform_device *xhci_dev;
21         struct gpio_desc *gpio_desc;
22  };
23  
24 @@ -338,6 +339,166 @@ err_unregister_ohci_dev:
25         return err;
26  }
27  
28 +static bool bcma_wait_reg(struct bcma_bus *bus, void __iomem *addr, u32 mask,
29 +                         u32 value, int timeout)
30 +{
31 +       unsigned long deadline = jiffies + timeout;
32 +       u32 val;
33 +
34 +       do {
35 +               val = readl(addr);
36 +               if ((val & mask) == value)
37 +                       return true;
38 +               cpu_relax();
39 +               udelay(10);
40 +       } while (!time_after_eq(jiffies, deadline));
41 +
42 +       pr_err("Timeout waiting for register %p\n", addr);
43 +
44 +       return false;
45 +}
46 +
47 +static void bcma_hcd_usb30_phy_init(struct bcma_hcd_device *bcma_hcd)
48 +{
49 +       struct bcma_device *core = bcma_hcd->core;
50 +       struct bcma_bus *bus = core->bus;
51 +       struct bcma_chipinfo *chipinfo = &bus->chipinfo;
52 +       struct bcma_drv_cc_b *ccb = &bus->drv_cc_b;
53 +       struct bcma_device *arm_core;
54 +       void __iomem *dmu = NULL;
55 +       u32 cru_straps_ctrl;
56 +
57 +       if (chipinfo->id != BCMA_CHIP_ID_BCM4707 &&
58 +           chipinfo->id != BCMA_CHIP_ID_BCM47094 &&
59 +           chipinfo->id != BCMA_CHIP_ID_BCM53018)
60 +               return;
61 +
62 +       arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
63 +       if (!arm_core)
64 +               return;
65 +
66 +       dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
67 +       if (!dmu)
68 +               goto out;
69 +
70 +       /* Check strapping of PCIE/USB3 SEL */
71 +       cru_straps_ctrl = ioread32(dmu + 0x2a0);
72 +       if ((cru_straps_ctrl & 0x10) == 0)
73 +               goto out;
74 +
75 +       /* Perform USB3 system soft reset */
76 +       bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
77 +
78 +       /* Enable MDIO. Setting MDCDIV as 26  */
79 +       iowrite32(0x0000009a, ccb->mii + 0x000);
80 +       udelay(2);
81 +
82 +       if (chipinfo->id == BCMA_CHIP_ID_BCM53018 ||
83 +           (chipinfo->id == BCMA_CHIP_ID_BCM4707 && (chipinfo->rev == 4 || chipinfo->rev == 6)) ||
84 +           chipinfo->id == BCMA_CHIP_ID_BCM47094) {
85 +                       /* For NS-B0, USB3 PLL Block */
86 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
87 +                       iowrite32(0x587e8000, ccb->mii + 0x004);
88 +
89 +                       /* Clear ana_pllSeqStart */
90 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
91 +                       iowrite32(0x58061000, ccb->mii + 0x004);
92 +
93 +                       /* CMOS Divider ratio to 25 */
94 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
95 +                       iowrite32(0x582a6400, ccb->mii + 0x004);
96 +
97 +                       /* Asserting PLL Reset */
98 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
99 +                       iowrite32(0x582ec000, ccb->mii + 0x004);
100 +
101 +                       /* Deaaserting PLL Reset */
102 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
103 +                       iowrite32(0x582e8000, ccb->mii + 0x004);
104 +
105 +                       /* Waiting MII Mgt interface idle */
106 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
107 +
108 +                       /* Deasserting USB3 system reset */
109 +                       bcma_awrite32(core, BCMA_RESET_CTL, 0);
110 +
111 +                       /* PLL frequency monitor enable */
112 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
113 +                       iowrite32(0x58069000, ccb->mii + 0x004);
114 +
115 +                       /* PIPE Block */
116 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
117 +                       iowrite32(0x587e8060, ccb->mii + 0x004);
118 +
119 +                       /* CMPMAX & CMPMINTH setting */
120 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
121 +                       iowrite32(0x580af30d, ccb->mii + 0x004);
122 +
123 +                       /* DEGLITCH MIN & MAX setting */
124 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
125 +                       iowrite32(0x580e6302, ccb->mii + 0x004);
126 +
127 +                       /* TXPMD block */
128 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
129 +                       iowrite32(0x587e8040, ccb->mii + 0x004);
130 +
131 +                       /* Enabling SSC */
132 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
133 +                       iowrite32(0x58061003, ccb->mii + 0x004);
134 +
135 +                       /* Waiting MII Mgt interface idle */
136 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
137 +       } else if (chipinfo->id == BCMA_CHIP_ID_BCM4707) {
138 +                       /* PLL30 block */
139 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
140 +                       iowrite32(0x587e8000, ccb->mii + 0x004);
141 +
142 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
143 +                       iowrite32(0x582a6400, ccb->mii + 0x004);
144 +
145 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
146 +                       iowrite32(0x587e80e0, ccb->mii + 0x004);
147 +
148 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
149 +                       iowrite32(0x580a009c, ccb->mii + 0x004);
150 +
151 +                       /* Enable SSC */
152 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
153 +                       iowrite32(0x587e8040, ccb->mii + 0x004);
154 +
155 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
156 +                       iowrite32(0x580a21d3, ccb->mii + 0x004);
157 +
158 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
159 +                       iowrite32(0x58061003, ccb->mii + 0x004);
160 +
161 +                       /* Waiting MII Mgt interface idle */
162 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
163 +
164 +                       /* Deasserting USB3 system reset */
165 +                       bcma_awrite32(core, BCMA_RESET_CTL, 0);
166 +       }
167 +out:
168 +       if (dmu)
169 +               iounmap(dmu);
170 +}
171 +
172 +static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd)
173 +{
174 +       struct bcma_device *core = bcma_hcd->core;
175 +
176 +       bcma_core_enable(core, 0);
177 +
178 +       bcma_hcd_usb30_phy_init(bcma_hcd);
179 +
180 +       bcma_hcd->xhci_dev = bcma_hcd_create_pdev(core, "xhci-hcd", core->addr,
181 +                                                 NULL, 0);
182 +       if (IS_ERR(bcma_hcd->ohci_dev))
183 +               return PTR_ERR(bcma_hcd->ohci_dev);
184 +
185 +       return 0;
186 +}
187 +
188  static int bcma_hcd_probe(struct bcma_device *core)
189  {
190         int err;
191 @@ -362,6 +523,11 @@ static int bcma_hcd_probe(struct bcma_de
192                 if (err)
193                         return err;
194                 break;
195 +       case BCMA_CORE_NS_USB30:
196 +               err = bcma_hcd_usb30_init(usb_dev);
197 +               if (err)
198 +                       return err;
199 +               break;
200         default:
201                 return -ENODEV;
202         }
203 @@ -375,11 +541,14 @@ static void bcma_hcd_remove(struct bcma_
204         struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
205         struct platform_device *ohci_dev = usb_dev->ohci_dev;
206         struct platform_device *ehci_dev = usb_dev->ehci_dev;
207 +       struct platform_device *xhci_dev = usb_dev->xhci_dev;
208  
209         if (ohci_dev)
210                 platform_device_unregister(ohci_dev);
211         if (ehci_dev)
212                 platform_device_unregister(ehci_dev);
213 +       if (xhci_dev)
214 +               platform_device_unregister(xhci_dev);
215  
216         bcma_core_disable(dev, 0);
217  }
218 @@ -416,6 +585,7 @@ static int bcma_hcd_resume(struct bcma_d
219  static const struct bcma_device_id bcma_hcd_table[] = {
220         BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
221         BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
222 +       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB30, BCMA_ANY_REV, BCMA_ANY_CLASS),
223         BCMA_CORETABLE_END
224  };
225  MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);