mediatek: Add support for Xiaomi Redmi Router AX6S
[openwrt/openwrt.git] / target / linux / bcm4908 / patches-5.4 / 084-v5.6-0008-phy-usb-Add-support-for-new-Synopsys-USB-controller-.patch
1 From 9d5f51dcdb646c2ed21649d379fbb703994f1ec9 Mon Sep 17 00:00:00 2001
2 From: Al Cooper <alcooperx@gmail.com>
3 Date: Fri, 3 Jan 2020 13:18:06 -0500
4 Subject: [PATCH] phy: usb: Add support for new Synopsys USB controller on the
5 7211b0
6
7 The 7211b0 has added the STB XHCI Synopsys controller and it
8 will be used instead of the RPi based DWC USB controller. The new
9 Synopsys XHCI controller core is the same one that is used on the
10 7216, but because of the way the STB USB PHY is used on both the A0
11 and B0, some of the PHY control is different.
12
13 Signed-off-by: Al Cooper <alcooperx@gmail.com>
14 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
15 Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
16 ---
17 .../phy/broadcom/phy-brcm-usb-init-synopsys.c | 163 +++++++++++++++++-
18 drivers/phy/broadcom/phy-brcm-usb-init.c | 31 ++--
19 drivers/phy/broadcom/phy-brcm-usb-init.h | 17 +-
20 drivers/phy/broadcom/phy-brcm-usb.c | 162 +++++++++++------
21 4 files changed, 295 insertions(+), 78 deletions(-)
22
23 --- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
24 +++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
25 @@ -12,10 +12,33 @@
26 #include <linux/soc/brcmstb/brcmstb.h>
27 #include "phy-brcm-usb-init.h"
28
29 +#define PHY_LOCK_TIMEOUT_MS 200
30 +
31 +/* Register definitions for syscon piarbctl registers */
32 +#define PIARBCTL_CAM 0x00
33 +#define PIARBCTL_SPLITTER 0x04
34 +#define PIARBCTL_MISC 0x08
35 +#define PIARBCTL_MISC_SECURE_MASK 0x80000000
36 +#define PIARBCTL_MISC_USB_SELECT_MASK 0x40000000
37 +#define PIARBCTL_MISC_USB_4G_SDRAM_MASK 0x20000000
38 +#define PIARBCTL_MISC_USB_PRIORITY_MASK 0x000f0000
39 +#define PIARBCTL_MISC_USB_MEM_PAGE_MASK 0x0000f000
40 +#define PIARBCTL_MISC_CAM1_MEM_PAGE_MASK 0x00000f00
41 +#define PIARBCTL_MISC_CAM0_MEM_PAGE_MASK 0x000000f0
42 +#define PIARBCTL_MISC_SATA_PRIORITY_MASK 0x0000000f
43 +#define PIARBCTL_USB_M_ASB_CTRL 0x10
44 +
45 +#define PIARBCTL_MISC_USB_ONLY_MASK \
46 + (PIARBCTL_MISC_USB_SELECT_MASK | \
47 + PIARBCTL_MISC_USB_4G_SDRAM_MASK | \
48 + PIARBCTL_MISC_USB_PRIORITY_MASK | \
49 + PIARBCTL_MISC_USB_MEM_PAGE_MASK)
50 +
51 /* Register definitions for the USB CTRL block */
52 #define USB_CTRL_SETUP 0x00
53 #define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK 0x02000000
54 #define USB_CTRL_SETUP_SCB2_EN_MASK 0x00008000
55 +#define USB_CTRL_SETUP_tca_drv_sel_MASK 0x01000000
56 #define USB_CTRL_SETUP_SCB1_EN_MASK 0x00004000
57 #define USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK 0x00000200
58 #define USB_CTRL_SETUP_IPP_MASK 0x00000020
59 @@ -29,11 +52,73 @@
60 #define USB_CTRL_USB_DEVICE_CTL1 0x10
61 #define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK 0x00000003
62
63 +/* Register definitions for the USB_PHY block in 7211b0 */
64 +#define USB_PHY_PLL_LDO_CTL 0x08
65 +#define USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK 0x00000004
66 +#define USB_PHY_UTMI_CTL_1 0x04
67 +#define USB_PHY_UTMI_CTL_1_PHY_MODE_MASK 0x0000000c
68 +#define USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT 2
69 +#define USB_PHY_STATUS 0x20
70 +#define USB_PHY_STATUS_pll_lock_MASK 0x00000001
71 +
72 +/* Register definitions for the MDIO registers in the DWC2 block of
73 + * the 7211b0.
74 + * NOTE: The PHY's MDIO registers are only accessible through the
75 + * legacy DesignWare USB controller even though it's not being used.
76 + */
77 +#define USB_GMDIOCSR 0
78 +#define USB_GMDIOGEN 4
79 +
80 +
81 +static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
82 + uint8_t addr, uint16_t data)
83 +{
84 + void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
85 +
86 + addr &= 0x1f; /* 5-bit address */
87 + brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
88 + while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
89 + ;
90 + brcm_usb_writel(0x59020000 | (addr << 18) | data,
91 + usb_mdio + USB_GMDIOGEN);
92 + while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
93 + ;
94 + brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
95 + while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
96 + ;
97 +}
98 +
99 +static uint16_t __maybe_unused usb_mdio_read_7211b0(
100 + struct brcm_usb_init_params *params, uint8_t addr)
101 +{
102 + void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
103 +
104 + addr &= 0x1f; /* 5-bit address */
105 + brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
106 + while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
107 + ;
108 + brcm_usb_writel(0x69020000 | (addr << 18), usb_mdio + USB_GMDIOGEN);
109 + while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
110 + ;
111 + brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
112 + while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
113 + ;
114 + return brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & 0xffff;
115 +}
116 +
117 +static void usb2_eye_fix_7211b0(struct brcm_usb_init_params *params)
118 +{
119 + /* select bank */
120 + usb_mdio_write_7211b0(params, 0x1f, 0x80a0);
121 +
122 + /* Set the eye */
123 + usb_mdio_write_7211b0(params, 0x0a, 0xc6a0);
124 +}
125
126 static void xhci_soft_reset(struct brcm_usb_init_params *params,
127 int on_off)
128 {
129 - void __iomem *ctrl = params->ctrl_regs;
130 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
131
132 /* Assert reset */
133 if (on_off)
134 @@ -45,7 +130,7 @@ static void xhci_soft_reset(struct brcm_
135
136 static void usb_init_ipp(struct brcm_usb_init_params *params)
137 {
138 - void __iomem *ctrl = params->ctrl_regs;
139 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
140 u32 reg;
141 u32 orig_reg;
142
143 @@ -72,10 +157,18 @@ static void usb_init_ipp(struct brcm_usb
144 msleep(50);
145 }
146
147 +static void syscon_piarbctl_init(struct regmap *rmap)
148 +{
149 + /* Switch from legacy USB OTG controller to new STB USB controller */
150 + regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK,
151 + PIARBCTL_MISC_USB_SELECT_MASK |
152 + PIARBCTL_MISC_USB_4G_SDRAM_MASK);
153 +}
154 +
155 static void usb_init_common(struct brcm_usb_init_params *params)
156 {
157 u32 reg;
158 - void __iomem *ctrl = params->ctrl_regs;
159 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
160
161 pr_debug("%s\n", __func__);
162
163 @@ -100,6 +193,45 @@ static void usb_init_common(struct brcm_
164 }
165 }
166
167 +static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
168 +{
169 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
170 + void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
171 + int timeout_ms = PHY_LOCK_TIMEOUT_MS;
172 + u32 reg;
173 +
174 + if (params->syscon_piarbctl)
175 + syscon_piarbctl_init(params->syscon_piarbctl);
176 +
177 + /* Init the PHY */
178 + reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_LDO_CTL);
179 + reg |= USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK;
180 + brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
181 +
182 + /* wait for lock */
183 + while (timeout_ms-- > 0) {
184 + reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS);
185 + if (reg & USB_PHY_STATUS_pll_lock_MASK)
186 + break;
187 + usleep_range(1000, 2000);
188 + }
189 +
190 + /* Set the PHY_MODE */
191 + reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
192 + reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK;
193 + reg |= params->mode << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT;
194 + brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
195 +
196 + /* Fix the incorrect default */
197 + reg = brcm_usb_readl(ctrl + USB_CTRL_SETUP);
198 + reg &= ~USB_CTRL_SETUP_tca_drv_sel_MASK;
199 + brcm_usb_writel(reg, ctrl + USB_CTRL_SETUP);
200 +
201 + usb_init_common(params);
202 +
203 + usb2_eye_fix_7211b0(params);
204 +}
205 +
206 static void usb_init_xhci(struct brcm_usb_init_params *params)
207 {
208 pr_debug("%s\n", __func__);
209 @@ -109,7 +241,7 @@ static void usb_init_xhci(struct brcm_us
210
211 static void usb_uninit_common(struct brcm_usb_init_params *params)
212 {
213 - void __iomem *ctrl = params->ctrl_regs;
214 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
215
216 pr_debug("%s\n", __func__);
217
218 @@ -127,7 +259,7 @@ static void usb_uninit_xhci(struct brcm_
219
220 static int usb_get_dual_select(struct brcm_usb_init_params *params)
221 {
222 - void __iomem *ctrl = params->ctrl_regs;
223 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
224 u32 reg = 0;
225
226 pr_debug("%s\n", __func__);
227 @@ -139,7 +271,7 @@ static int usb_get_dual_select(struct br
228
229 static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
230 {
231 - void __iomem *ctrl = params->ctrl_regs;
232 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
233 u32 reg;
234
235 pr_debug("%s\n", __func__);
236 @@ -161,6 +293,16 @@ static const struct brcm_usb_init_ops bc
237 .set_dual_select = usb_set_dual_select,
238 };
239
240 +static const struct brcm_usb_init_ops bcm7211b0_ops = {
241 + .init_ipp = usb_init_ipp,
242 + .init_common = usb_init_common_7211b0,
243 + .init_xhci = usb_init_xhci,
244 + .uninit_common = usb_uninit_common,
245 + .uninit_xhci = usb_uninit_xhci,
246 + .get_dual_select = usb_get_dual_select,
247 + .set_dual_select = usb_set_dual_select,
248 +};
249 +
250 void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
251 {
252
253 @@ -169,3 +311,12 @@ void brcm_usb_dvr_init_7216(struct brcm_
254 params->family_name = "7216";
255 params->ops = &bcm7216_ops;
256 }
257 +
258 +void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
259 +{
260 +
261 + pr_debug("%s\n", __func__);
262 +
263 + params->family_name = "7211";
264 + params->ops = &bcm7211b0_ops;
265 +}
266 --- a/drivers/phy/broadcom/phy-brcm-usb-init.c
267 +++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
268 @@ -401,7 +401,7 @@ void usb_ctrl_unset_family(struct brcm_u
269 u32 mask;
270
271 mask = params->usb_reg_bits_map[field];
272 - brcm_usb_ctrl_unset(params->ctrl_regs + reg_offset, mask);
273 + brcm_usb_ctrl_unset(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
274 };
275
276 static inline
277 @@ -411,7 +411,7 @@ void usb_ctrl_set_family(struct brcm_usb
278 u32 mask;
279
280 mask = params->usb_reg_bits_map[field];
281 - brcm_usb_ctrl_set(params->ctrl_regs + reg_offset, mask);
282 + brcm_usb_ctrl_set(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
283 };
284
285 static u32 brcmusb_usb_mdio_read(void __iomem *ctrl_base, u32 reg, int mode)
286 @@ -544,7 +544,7 @@ static void brcmusb_usb3_pll_54mhz(struc
287 {
288 u32 ofs;
289 int ii;
290 - void __iomem *ctrl_base = params->ctrl_regs;
291 + void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
292
293 /*
294 * On newer B53 based SoC's, the reference clock for the
295 @@ -625,7 +625,7 @@ static void brcmusb_usb3_ssc_enable(void
296
297 static void brcmusb_usb3_phy_workarounds(struct brcm_usb_init_params *params)
298 {
299 - void __iomem *ctrl_base = params->ctrl_regs;
300 + void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
301
302 brcmusb_usb3_pll_fix(ctrl_base);
303 brcmusb_usb3_pll_54mhz(params);
304 @@ -667,7 +667,7 @@ static void brcmusb_memc_fix(struct brcm
305
306 static void brcmusb_usb3_otp_fix(struct brcm_usb_init_params *params)
307 {
308 - void __iomem *xhci_ec_base = params->xhci_ec_regs;
309 + void __iomem *xhci_ec_base = params->regs[BRCM_REGS_XHCI_EC];
310 u32 val;
311
312 if (params->family_id != 0x74371000 || !xhci_ec_base)
313 @@ -680,8 +680,8 @@ static void brcmusb_usb3_otp_fix(struct
314 brcm_usb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
315
316 /* Reset USB 3.0 PHY for workaround to take effect */
317 - USB_CTRL_UNSET(params->ctrl_regs, USB30_CTL1, PHY3_RESETB);
318 - USB_CTRL_SET(params->ctrl_regs, USB30_CTL1, PHY3_RESETB);
319 + USB_CTRL_UNSET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
320 + USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
321 }
322
323 static void brcmusb_xhci_soft_reset(struct brcm_usb_init_params *params,
324 @@ -740,7 +740,7 @@ static enum brcm_family_type get_family_
325
326 static void usb_init_ipp(struct brcm_usb_init_params *params)
327 {
328 - void __iomem *ctrl = params->ctrl_regs;
329 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
330 u32 reg;
331 u32 orig_reg;
332
333 @@ -786,7 +786,7 @@ static void usb_init_ipp(struct brcm_usb
334 static void usb_init_common(struct brcm_usb_init_params *params)
335 {
336 u32 reg;
337 - void __iomem *ctrl = params->ctrl_regs;
338 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
339
340 /* Clear any pending wake conditions */
341 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
342 @@ -866,7 +866,7 @@ static void usb_init_common(struct brcm_
343 static void usb_init_eohci(struct brcm_usb_init_params *params)
344 {
345 u32 reg;
346 - void __iomem *ctrl = params->ctrl_regs;
347 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
348
349 if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB))
350 USB_CTRL_SET_FAMILY(params, USB_PM, USB20_HC_RESETB);
351 @@ -902,7 +902,7 @@ static void usb_init_eohci(struct brcm_u
352
353 static void usb_init_xhci(struct brcm_usb_init_params *params)
354 {
355 - void __iomem *ctrl = params->ctrl_regs;
356 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
357
358 USB_CTRL_UNSET(ctrl, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
359 /* 1 millisecond - for USB clocks to settle down */
360 @@ -944,12 +944,13 @@ static void usb_uninit_eohci(struct brcm
361 static void usb_uninit_xhci(struct brcm_usb_init_params *params)
362 {
363 brcmusb_xhci_soft_reset(params, 1);
364 - USB_CTRL_SET(params->ctrl_regs, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
365 + USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_PCTL,
366 + PHY3_IDDQ_OVERRIDE);
367 }
368
369 static int usb_get_dual_select(struct brcm_usb_init_params *params)
370 {
371 - void __iomem *ctrl = params->ctrl_regs;
372 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
373 u32 reg = 0;
374
375 pr_debug("%s\n", __func__);
376 @@ -963,7 +964,7 @@ static int usb_get_dual_select(struct br
377
378 static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
379 {
380 - void __iomem *ctrl = params->ctrl_regs;
381 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
382 u32 reg;
383
384 pr_debug("%s\n", __func__);
385 @@ -980,7 +981,7 @@ static void usb_set_dual_select(struct b
386 static void usb_wake_enable(struct brcm_usb_init_params *params,
387 int enable)
388 {
389 - void __iomem *ctrl = params->ctrl_regs;
390 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
391
392 if (enable)
393 USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
394 --- a/drivers/phy/broadcom/phy-brcm-usb-init.h
395 +++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
396 @@ -6,12 +6,21 @@
397 #ifndef _USB_BRCM_COMMON_INIT_H
398 #define _USB_BRCM_COMMON_INIT_H
399
400 +#include <linux/regmap.h>
401 +
402 #define USB_CTLR_MODE_HOST 0
403 #define USB_CTLR_MODE_DEVICE 1
404 #define USB_CTLR_MODE_DRD 2
405 #define USB_CTLR_MODE_TYPEC_PD 3
406
407 -struct brcm_usb_init_params;
408 +enum brcmusb_reg_sel {
409 + BRCM_REGS_CTRL = 0,
410 + BRCM_REGS_XHCI_EC,
411 + BRCM_REGS_XHCI_GBL,
412 + BRCM_REGS_USB_PHY,
413 + BRCM_REGS_USB_MDIO,
414 + BRCM_REGS_MAX
415 +};
416
417 #define USB_CTRL_REG(base, reg) ((void __iomem *)base + USB_CTRL_##reg)
418 #define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
419 @@ -41,9 +50,7 @@ struct brcm_usb_init_ops {
420 };
421
422 struct brcm_usb_init_params {
423 - void __iomem *ctrl_regs;
424 - void __iomem *xhci_ec_regs;
425 - void __iomem *xhci_gbl_regs;
426 + void __iomem *regs[BRCM_REGS_MAX];
427 int ioc;
428 int ipp;
429 int mode;
430 @@ -53,10 +60,12 @@ struct brcm_usb_init_params {
431 const char *family_name;
432 const u32 *usb_reg_bits_map;
433 const struct brcm_usb_init_ops *ops;
434 + struct regmap *syscon_piarbctl;
435 };
436
437 void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
438 void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
439 +void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params);
440
441 static inline u32 brcm_usb_readl(void __iomem *addr)
442 {
443 --- a/drivers/phy/broadcom/phy-brcm-usb.c
444 +++ b/drivers/phy/broadcom/phy-brcm-usb.c
445 @@ -16,6 +16,7 @@
446 #include <linux/interrupt.h>
447 #include <linux/soc/brcmstb/brcmstb.h>
448 #include <dt-bindings/phy/phy.h>
449 +#include <linux/mfd/syscon.h>
450
451 #include "phy-brcm-usb-init.h"
452
453 @@ -32,6 +33,11 @@ struct value_to_name_map {
454 const char *name;
455 };
456
457 +struct match_chip_info {
458 + void *init_func;
459 + u8 required_regs[BRCM_REGS_MAX + 1];
460 +};
461 +
462 static struct value_to_name_map brcm_dr_mode_to_name[] = {
463 { USB_CTLR_MODE_HOST, "host" },
464 { USB_CTLR_MODE_DEVICE, "peripheral" },
465 @@ -64,6 +70,10 @@ struct brcm_usb_phy_data {
466 struct brcm_usb_phy phys[BRCM_USB_PHY_ID_MAX];
467 };
468
469 +static s8 *node_reg_names[BRCM_REGS_MAX] = {
470 + "crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio"
471 +};
472 +
473 static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
474 {
475 struct phy *gphy = dev_id;
476 @@ -241,15 +251,86 @@ static const struct attribute_group brcm
477 .attrs = brcm_usb_phy_attrs,
478 };
479
480 +static struct match_chip_info chip_info_7216 = {
481 + .init_func = &brcm_usb_dvr_init_7216,
482 + .required_regs = {
483 + BRCM_REGS_CTRL,
484 + BRCM_REGS_XHCI_EC,
485 + BRCM_REGS_XHCI_GBL,
486 + -1,
487 + },
488 +};
489 +
490 +static struct match_chip_info chip_info_7211b0 = {
491 + .init_func = &brcm_usb_dvr_init_7211b0,
492 + .required_regs = {
493 + BRCM_REGS_CTRL,
494 + BRCM_REGS_XHCI_EC,
495 + BRCM_REGS_XHCI_GBL,
496 + BRCM_REGS_USB_PHY,
497 + BRCM_REGS_USB_MDIO,
498 + -1,
499 + },
500 +};
501 +
502 +static struct match_chip_info chip_info_7445 = {
503 + .init_func = &brcm_usb_dvr_init_7445,
504 + .required_regs = {
505 + BRCM_REGS_CTRL,
506 + BRCM_REGS_XHCI_EC,
507 + -1,
508 + },
509 +};
510 +
511 static const struct of_device_id brcm_usb_dt_ids[] = {
512 {
513 .compatible = "brcm,bcm7216-usb-phy",
514 - .data = &brcm_usb_dvr_init_7216,
515 + .data = &chip_info_7216,
516 + },
517 + {
518 + .compatible = "brcm,bcm7211-usb-phy",
519 + .data = &chip_info_7211b0,
520 + },
521 + {
522 + .compatible = "brcm,brcmstb-usb-phy",
523 + .data = &chip_info_7445,
524 },
525 - { .compatible = "brcm,brcmstb-usb-phy" },
526 { /* sentinel */ }
527 };
528
529 +static int brcm_usb_get_regs(struct platform_device *pdev,
530 + enum brcmusb_reg_sel regs,
531 + struct brcm_usb_init_params *ini)
532 +{
533 + struct resource *res;
534 +
535 + /* Older DT nodes have ctrl and optional xhci_ec by index only */
536 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
537 + node_reg_names[regs]);
538 + if (res == NULL) {
539 + if (regs == BRCM_REGS_CTRL) {
540 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
541 + } else if (regs == BRCM_REGS_XHCI_EC) {
542 + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
543 + /* XHCI_EC registers are optional */
544 + if (res == NULL)
545 + return 0;
546 + }
547 + if (res == NULL) {
548 + dev_err(&pdev->dev, "can't get %s base address\n",
549 + node_reg_names[regs]);
550 + return 1;
551 + }
552 + }
553 + ini->regs[regs] = devm_ioremap_resource(&pdev->dev, res);
554 + if (IS_ERR(ini->regs[regs])) {
555 + dev_err(&pdev->dev, "can't map %s register space\n",
556 + node_reg_names[regs]);
557 + return 1;
558 + }
559 + return 0;
560 +}
561 +
562 static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
563 struct brcm_usb_phy_data *priv,
564 struct device_node *dn)
565 @@ -325,9 +406,6 @@ static int brcm_usb_phy_dvr_init(struct
566
567 static int brcm_usb_phy_probe(struct platform_device *pdev)
568 {
569 - struct resource *res_ctrl;
570 - struct resource *res_xhciec = NULL;
571 - struct resource *res_xhcigbl = NULL;
572 struct device *dev = &pdev->dev;
573 struct brcm_usb_phy_data *priv;
574 struct phy_provider *phy_provider;
575 @@ -335,6 +413,10 @@ static int brcm_usb_phy_probe(struct pla
576 int err;
577 const char *mode;
578 const struct of_device_id *match;
579 + void (*dvr_init)(struct brcm_usb_init_params *params);
580 + const struct match_chip_info *info;
581 + struct regmap *rmap;
582 + int x;
583
584 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
585 if (!priv)
586 @@ -345,58 +427,13 @@ static int brcm_usb_phy_probe(struct pla
587 priv->ini.product_id = brcmstb_get_product_id();
588
589 match = of_match_node(brcm_usb_dt_ids, dev->of_node);
590 - if (match && match->data) {
591 - void (*dvr_init)(struct brcm_usb_init_params *params);
592 -
593 - dvr_init = match->data;
594 - (*dvr_init)(&priv->ini);
595 - } else {
596 - brcm_usb_dvr_init_7445(&priv->ini);
597 - }
598 + info = match->data;
599 + dvr_init = info->init_func;
600 + (*dvr_init)(&priv->ini);
601
602 dev_dbg(dev, "Best mapping table is for %s\n",
603 priv->ini.family_name);
604
605 - /* Newer DT node has reg-names. xhci_ec and xhci_gbl are optional. */
606 - res_ctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
607 - if (res_ctrl != NULL) {
608 - res_xhciec = platform_get_resource_byname(pdev,
609 - IORESOURCE_MEM,
610 - "xhci_ec");
611 - res_xhcigbl = platform_get_resource_byname(pdev,
612 - IORESOURCE_MEM,
613 - "xhci_gbl");
614 - } else {
615 - /* Older DT node without reg-names, use index */
616 - res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 0);
617 - if (res_ctrl == NULL) {
618 - dev_err(dev, "can't get CTRL base address\n");
619 - return -EINVAL;
620 - }
621 - res_xhciec = platform_get_resource(pdev, IORESOURCE_MEM, 1);
622 - }
623 - priv->ini.ctrl_regs = devm_ioremap_resource(dev, res_ctrl);
624 - if (IS_ERR(priv->ini.ctrl_regs)) {
625 - dev_err(dev, "can't map CTRL register space\n");
626 - return -EINVAL;
627 - }
628 - if (res_xhciec) {
629 - priv->ini.xhci_ec_regs =
630 - devm_ioremap_resource(dev, res_xhciec);
631 - if (IS_ERR(priv->ini.xhci_ec_regs)) {
632 - dev_err(dev, "can't map XHCI EC register space\n");
633 - return -EINVAL;
634 - }
635 - }
636 - if (res_xhcigbl) {
637 - priv->ini.xhci_gbl_regs =
638 - devm_ioremap_resource(dev, res_xhcigbl);
639 - if (IS_ERR(priv->ini.xhci_gbl_regs)) {
640 - dev_err(dev, "can't map XHCI Global register space\n");
641 - return -EINVAL;
642 - }
643 - }
644 -
645 of_property_read_u32(dn, "brcm,ipp", &priv->ini.ipp);
646 of_property_read_u32(dn, "brcm,ioc", &priv->ini.ioc);
647
648 @@ -412,6 +449,16 @@ static int brcm_usb_phy_probe(struct pla
649 if (of_property_read_bool(dn, "brcm,has-eohci"))
650 priv->has_eohci = true;
651
652 + for (x = 0; x < BRCM_REGS_MAX; x++) {
653 + if (info->required_regs[x] >= BRCM_REGS_MAX)
654 + break;
655 +
656 + err = brcm_usb_get_regs(pdev, info->required_regs[x],
657 + &priv->ini);
658 + if (err)
659 + return -EINVAL;
660 + }
661 +
662 err = brcm_usb_phy_dvr_init(pdev, priv, dn);
663 if (err)
664 return err;
665 @@ -431,6 +478,15 @@ static int brcm_usb_phy_probe(struct pla
666 if (err)
667 dev_warn(dev, "Error creating sysfs attributes\n");
668
669 + /* Get piarbctl syscon if it exists */
670 + rmap = syscon_regmap_lookup_by_phandle(dev->of_node,
671 + "syscon-piarbctl");
672 + if (IS_ERR(rmap))
673 + rmap = syscon_regmap_lookup_by_phandle(dev->of_node,
674 + "brcm,syscon-piarbctl");
675 + if (!IS_ERR(rmap))
676 + priv->ini.syscon_piarbctl = rmap;
677 +
678 /* start with everything off */
679 if (priv->has_xhci)
680 brcm_usb_uninit_xhci(&priv->ini);