bcm53xx: add support for kernel 4.1
[openwrt.git] / target / linux / bcm53xx / patches-4.1 / 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 @@ -37,6 +37,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  };
22  
23  /* Wait for bitmask in a register to get set or cleared.
24 @@ -343,6 +344,215 @@ 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_BCM53018)
59 +               return;
60 +
61 +       arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
62 +       if (!arm_core)
63 +               return;
64 +
65 +       dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
66 +       if (!dmu)
67 +               goto out;
68 +
69 +       /* Check strapping of PCIE/USB3 SEL */
70 +       cru_straps_ctrl = ioread32(dmu + 0x2a0);
71 +       if ((cru_straps_ctrl & 0x10) == 0)
72 +               goto out;
73 +
74 +       /* Perform USB3 system soft reset */
75 +       bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
76 +
77 +       /* Enable MDIO. Setting MDCDIV as 26  */
78 +       iowrite32(0x0000009a, ccb->mii + 0x000);
79 +       udelay(2);
80 +
81 +       switch (chipinfo->id) {
82 +       case BCMA_CHIP_ID_BCM4707:
83 +               if (chipinfo->rev == 4) {
84 +                       /* For NS-B0, USB3 PLL Block */
85 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
86 +                       iowrite32(0x587e8000, ccb->mii + 0x004);
87 +
88 +                       /* Clear ana_pllSeqStart */
89 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
90 +                       iowrite32(0x58061000, ccb->mii + 0x004);
91 +
92 +                       /* CMOS Divider ratio to 25 */
93 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
94 +                       iowrite32(0x582a6400, ccb->mii + 0x004);
95 +
96 +                       /* Asserting PLL Reset */
97 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
98 +                       iowrite32(0x582ec000, ccb->mii + 0x004);
99 +
100 +                       /* Deaaserting PLL Reset */
101 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
102 +                       iowrite32(0x582e8000, ccb->mii + 0x004);
103 +
104 +                       /* Deasserting USB3 system reset */
105 +                       bcma_awrite32(core, BCMA_RESET_CTL, 0);
106 +
107 +                       /* Set ana_pllSeqStart */
108 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
109 +                       iowrite32(0x58069000, ccb->mii + 0x004);
110 +
111 +                       /* RXPMD block */
112 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
113 +                       iowrite32(0x587e8020, ccb->mii + 0x004);
114 +
115 +                       /* CDR int loop locking BW to 1 */
116 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
117 +                       iowrite32(0x58120049, ccb->mii + 0x004);
118 +
119 +                       /* CDR int loop acquisition BW to 1 */
120 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
121 +                       iowrite32(0x580e0049, ccb->mii + 0x004);
122 +
123 +                       /* CDR prop loop BW to 1 */
124 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
125 +                       iowrite32(0x580a005c, ccb->mii + 0x004);
126 +
127 +                       /* Waiting MII Mgt interface idle */
128 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
129 +               } else {
130 +                       /* PLL30 block */
131 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
132 +                       iowrite32(0x587e8000, ccb->mii + 0x004);
133 +
134 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
135 +                       iowrite32(0x582a6400, ccb->mii + 0x004);
136 +
137 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
138 +                       iowrite32(0x587e80e0, ccb->mii + 0x004);
139 +
140 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
141 +                       iowrite32(0x580a009c, ccb->mii + 0x004);
142 +
143 +                       /* Enable SSC */
144 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
145 +                       iowrite32(0x587e8040, ccb->mii + 0x004);
146 +
147 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
148 +                       iowrite32(0x580a21d3, ccb->mii + 0x004);
149 +
150 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
151 +                       iowrite32(0x58061003, ccb->mii + 0x004);
152 +
153 +                       /* Waiting MII Mgt interface idle */
154 +                       bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
155 +
156 +                       /* Deasserting USB3 system reset */
157 +                       bcma_awrite32(core, BCMA_RESET_CTL, 0);
158 +               }
159 +               break;
160 +       case BCMA_CHIP_ID_BCM53018:
161 +               /* USB3 PLL Block */
162 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
163 +               iowrite32(0x587e8000, ccb->mii + 0x004);
164 +
165 +               /* Assert Ana_Pllseq start */
166 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
167 +               iowrite32(0x58061000, ccb->mii + 0x004);
168 +
169 +               /* Assert CML Divider ratio to 26 */
170 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
171 +               iowrite32(0x582a6400, ccb->mii + 0x004);
172 +
173 +               /* Asserting PLL Reset */
174 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
175 +               iowrite32(0x582ec000, ccb->mii + 0x004);
176 +
177 +               /* Deaaserting PLL Reset */
178 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
179 +               iowrite32(0x582e8000, ccb->mii + 0x004);
180 +
181 +               /* Waiting MII Mgt interface idle */
182 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
183 +
184 +               /* Deasserting USB3 system reset */
185 +               bcma_awrite32(core, BCMA_RESET_CTL, 0);
186 +
187 +               /* PLL frequency monitor enable */
188 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
189 +               iowrite32(0x58069000, ccb->mii + 0x004);
190 +
191 +               /* PIPE Block */
192 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
193 +               iowrite32(0x587e8060, ccb->mii + 0x004);
194 +
195 +               /* CMPMAX & CMPMINTH setting */
196 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
197 +               iowrite32(0x580af30d, ccb->mii + 0x004);
198 +
199 +               /* DEGLITCH MIN & MAX setting */
200 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
201 +               iowrite32(0x580e6302, ccb->mii + 0x004);
202 +
203 +               /* TXPMD block */
204 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
205 +               iowrite32(0x587e8040, ccb->mii + 0x004);
206 +
207 +               /* Enabling SSC */
208 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
209 +               iowrite32(0x58061003, ccb->mii + 0x004);
210 +
211 +               /* Waiting MII Mgt interface idle */
212 +               bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
213 +
214 +               break;
215 +       }
216 +out:
217 +       if (dmu)
218 +               iounmap(dmu);
219 +}
220 +
221 +static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd)
222 +{
223 +       struct bcma_device *core = bcma_hcd->core;
224 +
225 +       bcma_core_enable(core, 0);
226 +
227 +       bcma_hcd_usb30_phy_init(bcma_hcd);
228 +
229 +       bcma_hcd->xhci_dev = bcma_hcd_create_pdev(core, "xhci-hcd", core->addr,
230 +                                                 NULL, 0);
231 +       if (IS_ERR(bcma_hcd->ohci_dev))
232 +               return PTR_ERR(bcma_hcd->ohci_dev);
233 +
234 +       return 0;
235 +}
236 +
237  static int bcma_hcd_probe(struct bcma_device *dev)
238  {
239         int err;
240 @@ -365,6 +575,11 @@ static int bcma_hcd_probe(struct bcma_de
241                 if (err)
242                         return err;
243                 break;
244 +       case BCMA_CORE_NS_USB30:
245 +               err = bcma_hcd_usb30_init(usb_dev);
246 +               if (err)
247 +                       return err;
248 +               break;
249         default:
250                 return -ENODEV;
251         }
252 @@ -378,11 +593,14 @@ static void bcma_hcd_remove(struct bcma_
253         struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
254         struct platform_device *ohci_dev = usb_dev->ohci_dev;
255         struct platform_device *ehci_dev = usb_dev->ehci_dev;
256 +       struct platform_device *xhci_dev = usb_dev->xhci_dev;
257  
258         if (ohci_dev)
259                 platform_device_unregister(ohci_dev);
260         if (ehci_dev)
261                 platform_device_unregister(ehci_dev);
262 +       if (xhci_dev)
263 +               platform_device_unregister(xhci_dev);
264  
265         bcma_core_disable(dev, 0);
266  }
267 @@ -419,6 +637,7 @@ static int bcma_hcd_resume(struct bcma_d
268  static const struct bcma_device_id bcma_hcd_table[] = {
269         BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
270         BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
271 +       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB30, BCMA_ANY_REV, BCMA_ANY_CLASS),
272         {},
273  };
274  MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);