Loading...
Note: File does not exist in v3.1.
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2018, Broadcom */
3
4/*
5 * This module contains USB PHY initialization for power up and S3 resume
6 * for newer Synopsys based USB hardware first used on the bcm7216.
7 */
8
9#include <linux/delay.h>
10#include <linux/io.h>
11
12#include <linux/soc/brcmstb/brcmstb.h>
13#include "phy-brcm-usb-init.h"
14
15#define PHY_LOCK_TIMEOUT_MS 200
16
17/* Register definitions for syscon piarbctl registers */
18#define PIARBCTL_CAM 0x00
19#define PIARBCTL_SPLITTER 0x04
20#define PIARBCTL_MISC 0x08
21#define PIARBCTL_MISC_SATA_PRIORITY_MASK GENMASK(3, 0)
22#define PIARBCTL_MISC_CAM0_MEM_PAGE_MASK GENMASK(7, 4)
23#define PIARBCTL_MISC_CAM1_MEM_PAGE_MASK GENMASK(11, 8)
24#define PIARBCTL_MISC_USB_MEM_PAGE_MASK GENMASK(15, 12)
25#define PIARBCTL_MISC_USB_PRIORITY_MASK GENMASK(19, 16)
26#define PIARBCTL_MISC_USB_4G_SDRAM_MASK BIT(29)
27#define PIARBCTL_MISC_USB_SELECT_MASK BIT(30)
28#define PIARBCTL_MISC_SECURE_MASK BIT(31)
29
30#define PIARBCTL_MISC_USB_ONLY_MASK \
31 (PIARBCTL_MISC_USB_SELECT_MASK | \
32 PIARBCTL_MISC_USB_4G_SDRAM_MASK | \
33 PIARBCTL_MISC_USB_PRIORITY_MASK | \
34 PIARBCTL_MISC_USB_MEM_PAGE_MASK)
35
36/* Register definitions for the USB CTRL block */
37#define USB_CTRL_SETUP 0x00
38#define USB_CTRL_SETUP_IOC_MASK BIT(4)
39#define USB_CTRL_SETUP_IPP_MASK BIT(5)
40#define USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK BIT(9)
41#define USB_CTRL_SETUP_SCB1_EN_MASK BIT(14)
42#define USB_CTRL_SETUP_SCB2_EN_MASK BIT(15)
43#define USB_CTRL_SETUP_tca_drv_sel_MASK BIT(24)
44#define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK BIT(25)
45#define USB_CTRL_USB_PM 0x04
46#define USB_CTRL_USB_PM_XHC_S2_CLK_SWITCH_EN_MASK BIT(3)
47#define USB_CTRL_USB_PM_XHC_PME_EN_MASK BIT(4)
48#define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK BIT(22)
49#define USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK BIT(23)
50#define USB_CTRL_USB_PM_SOFT_RESET_MASK BIT(30)
51#define USB_CTRL_USB_PM_USB_PWRDN_MASK BIT(31)
52#define USB_CTRL_USB_PM_STATUS 0x08
53#define USB_CTRL_USB_DEVICE_CTL1 0x10
54#define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK GENMASK(1, 0)
55#define USB_CTRL_TEST_PORT_CTL 0x30
56#define USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_MASK GENMASK(7, 0)
57#define USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_PME_GEN_MASK 0x0000002e
58#define USB_CTRL_TP_DIAG1 0x34
59#define USB_CTLR_TP_DIAG1_wake_MASK BIT(1)
60#define USB_CTRL_CTLR_CSHCR 0x50
61#define USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK BIT(18)
62#define USB_CTRL_P0_U2PHY_CFG1 0x68
63#define USB_CTRL_P0_U2PHY_CFG1_COMMONONN_MASK BIT(10)
64
65/* Register definitions for the USB_PHY block in 7211b0 */
66#define USB_PHY_PLL_CTL 0x00
67#define USB_PHY_PLL_CTL_PLL_SUSPEND_MASK BIT(27)
68#define USB_PHY_PLL_CTL_PLL_RESETB_MASK BIT(30)
69#define USB_PHY_PLL_LDO_CTL 0x08
70#define USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK BIT(0)
71#define USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK BIT(1)
72#define USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK BIT(2)
73#define USB_PHY_UTMI_CTL_1 0x04
74#define USB_PHY_UTMI_CTL_1_PHY_MODE_MASK GENMASK(3, 2)
75#define USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT 2
76#define USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK BIT(11)
77#define USB_PHY_IDDQ 0x1c
78#define USB_PHY_IDDQ_phy_iddq_MASK BIT(0)
79#define USB_PHY_STATUS 0x20
80#define USB_PHY_STATUS_pll_lock_MASK BIT(0)
81
82/* Register definitions for the MDIO registers in the DWC2 block of
83 * the 7211b0.
84 * NOTE: The PHY's MDIO registers are only accessible through the
85 * legacy DesignWare USB controller even though it's not being used.
86 */
87#define USB_GMDIOCSR 0
88#define USB_GMDIOGEN 4
89
90/* Register definitions for the BDC EC block in 7211b0 */
91#define BDC_EC_AXIRDA 0x0c
92#define BDC_EC_AXIRDA_RTS_MASK GENMASK(31, 28)
93#define BDC_EC_AXIRDA_RTS_SHIFT 28
94
95#define USB_XHCI_GBL_GUSB2PHYCFG 0x100
96#define USB_XHCI_GBL_GUSB2PHYCFG_U2_FREECLK_EXISTS_MASK BIT(30)
97
98static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
99 uint8_t addr, uint16_t data)
100{
101 void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
102
103 addr &= 0x1f; /* 5-bit address */
104 brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
105 while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
106 ;
107 brcm_usb_writel(0x59020000 | (addr << 18) | data,
108 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}
115
116static uint16_t __maybe_unused usb_mdio_read_7211b0(
117 struct brcm_usb_init_params *params, uint8_t addr)
118{
119 void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
120
121 addr &= 0x1f; /* 5-bit address */
122 brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
123 while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
124 ;
125 brcm_usb_writel(0x69020000 | (addr << 18), usb_mdio + USB_GMDIOGEN);
126 while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
127 ;
128 brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
129 while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
130 ;
131 return brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & 0xffff;
132}
133
134static void usb2_eye_fix_7211b0(struct brcm_usb_init_params *params)
135{
136 /* select bank */
137 usb_mdio_write_7211b0(params, 0x1f, 0x80a0);
138
139 /* Set the eye */
140 usb_mdio_write_7211b0(params, 0x0a, 0xc6a0);
141}
142
143static void xhci_soft_reset(struct brcm_usb_init_params *params,
144 int on_off)
145{
146 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
147 void __iomem *xhci_gbl = params->regs[BRCM_REGS_XHCI_GBL];
148
149 /* Assert reset */
150 if (on_off) {
151 USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB);
152 /* De-assert reset */
153 } else {
154 USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB);
155 /* Required for COMMONONN to be set */
156 if (params->supported_port_modes != USB_CTLR_MODE_DRD)
157 USB_XHCI_GBL_UNSET(xhci_gbl, GUSB2PHYCFG,
158 U2_FREECLK_EXISTS);
159 }
160}
161
162static void usb_init_ipp(struct brcm_usb_init_params *params)
163{
164 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
165 u32 reg;
166 u32 orig_reg;
167
168 pr_debug("%s\n", __func__);
169
170 orig_reg = reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
171 if (params->ipp != 2)
172 /* override ipp strap pin (if it exits) */
173 reg &= ~(USB_CTRL_MASK(SETUP, STRAP_IPP_SEL));
174
175 /* Override the default OC and PP polarity */
176 reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
177 if (params->ioc)
178 reg |= USB_CTRL_MASK(SETUP, IOC);
179 if (params->ipp == 1)
180 reg |= USB_CTRL_MASK(SETUP, IPP);
181 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
182
183 /*
184 * If we're changing IPP, make sure power is off long enough
185 * to turn off any connected devices.
186 */
187 if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
188 msleep(50);
189}
190
191static void syscon_piarbctl_init(struct regmap *rmap)
192{
193 /* Switch from legacy USB OTG controller to new STB USB controller */
194 regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK,
195 PIARBCTL_MISC_USB_SELECT_MASK |
196 PIARBCTL_MISC_USB_4G_SDRAM_MASK);
197}
198
199static void usb_init_common(struct brcm_usb_init_params *params)
200{
201 u32 reg;
202 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
203
204 pr_debug("%s\n", __func__);
205
206 if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) {
207 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
208 reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
209 reg |= params->port_mode;
210 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
211 }
212 switch (params->supported_port_modes) {
213 case USB_CTLR_MODE_HOST:
214 USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
215 break;
216 default:
217 USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
218 USB_CTRL_SET(ctrl, USB_PM, BDC_SOFT_RESETB);
219 break;
220 }
221}
222
223static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
224 bool enable)
225{
226 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
227
228 if (enable)
229 USB_CTRL_SET(ctrl, CTLR_CSHCR, ctl_pme_en);
230 else
231 USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
232}
233
234static void usb_wake_enable_7216(struct brcm_usb_init_params *params,
235 bool enable)
236{
237 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
238
239 if (enable)
240 USB_CTRL_SET(ctrl, USB_PM, XHC_PME_EN);
241 else
242 USB_CTRL_UNSET(ctrl, USB_PM, XHC_PME_EN);
243}
244
245static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
246{
247 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
248 void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
249 void __iomem *bdc_ec = params->regs[BRCM_REGS_BDC_EC];
250 int timeout_ms = PHY_LOCK_TIMEOUT_MS;
251 u32 reg;
252
253 if (params->syscon_piarbctl)
254 syscon_piarbctl_init(params->syscon_piarbctl);
255
256 USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
257
258 usb_wake_enable_7211b0(params, false);
259 if (!params->wake_enabled) {
260
261 /* undo possible suspend settings */
262 brcm_usb_writel(0, usb_phy + USB_PHY_IDDQ);
263 reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
264 reg |= USB_PHY_PLL_CTL_PLL_RESETB_MASK;
265 brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
266
267 /* temporarily enable FSM so PHY comes up properly */
268 reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
269 reg |= USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
270 brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
271 }
272
273 /* Disable PLL auto suspend */
274 reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
275 reg |= USB_PHY_PLL_CTL_PLL_SUSPEND_MASK;
276 brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
277
278 /* Init the PHY */
279 reg = USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK |
280 USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK |
281 USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK;
282 brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
283
284 /* wait for lock */
285 while (timeout_ms-- > 0) {
286 reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS);
287 if (reg & USB_PHY_STATUS_pll_lock_MASK)
288 break;
289 usleep_range(1000, 2000);
290 }
291
292 /* Set the PHY_MODE */
293 reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
294 reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK;
295 reg |= params->supported_port_modes << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT;
296 brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
297
298 usb_init_common(params);
299
300 /*
301 * The BDC controller will get occasional failures with
302 * the default "Read Transaction Size" of 6 (1024 bytes).
303 * Set it to 4 (256 bytes).
304 */
305 if ((params->supported_port_modes != USB_CTLR_MODE_HOST) && bdc_ec) {
306 reg = brcm_usb_readl(bdc_ec + BDC_EC_AXIRDA);
307 reg &= ~BDC_EC_AXIRDA_RTS_MASK;
308 reg |= (0x4 << BDC_EC_AXIRDA_RTS_SHIFT);
309 brcm_usb_writel(reg, bdc_ec + BDC_EC_AXIRDA);
310 }
311
312 /*
313 * Disable FSM, otherwise the PHY will auto suspend when no
314 * device is connected and will be reset on resume.
315 */
316 reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
317 reg &= ~USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
318 brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
319
320 usb2_eye_fix_7211b0(params);
321}
322
323static void usb_init_common_7216(struct brcm_usb_init_params *params)
324{
325 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
326
327 USB_CTRL_UNSET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
328
329 /*
330 * The PHY might be in a bad state if it is already powered
331 * up. Toggle the power just in case.
332 */
333 USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
334 USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
335
336 /* 1 millisecond - for USB clocks to settle down */
337 usleep_range(1000, 2000);
338
339 /*
340 * Disable PHY when port is suspended
341 * Does not work in DRD mode
342 */
343 if (params->supported_port_modes != USB_CTLR_MODE_DRD)
344 USB_CTRL_SET(ctrl, P0_U2PHY_CFG1, COMMONONN);
345
346 usb_wake_enable_7216(params, false);
347 usb_init_common(params);
348}
349
350static void usb_init_xhci(struct brcm_usb_init_params *params)
351{
352 pr_debug("%s\n", __func__);
353
354 xhci_soft_reset(params, 0);
355}
356
357static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
358{
359 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
360
361 pr_debug("%s\n", __func__);
362
363 if (params->wake_enabled) {
364 /* Switch to using slower clock during suspend to save power */
365 USB_CTRL_SET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
366 usb_wake_enable_7216(params, true);
367 } else {
368 USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
369 }
370}
371
372static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
373{
374 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
375 void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
376 u32 reg;
377
378 pr_debug("%s\n", __func__);
379
380 if (params->wake_enabled) {
381 USB_CTRL_SET(ctrl, TEST_PORT_CTL, TPOUT_SEL_PME_GEN);
382 usb_wake_enable_7211b0(params, true);
383 } else {
384 USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
385 brcm_usb_writel(0, usb_phy + USB_PHY_PLL_LDO_CTL);
386 reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
387 reg &= ~USB_PHY_PLL_CTL_PLL_RESETB_MASK;
388 brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
389 brcm_usb_writel(USB_PHY_IDDQ_phy_iddq_MASK,
390 usb_phy + USB_PHY_IDDQ);
391 }
392
393}
394
395static void usb_uninit_xhci(struct brcm_usb_init_params *params)
396{
397
398 pr_debug("%s\n", __func__);
399
400 if (!params->wake_enabled)
401 xhci_soft_reset(params, 1);
402}
403
404static int usb_get_dual_select(struct brcm_usb_init_params *params)
405{
406 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
407 u32 reg = 0;
408
409 pr_debug("%s\n", __func__);
410
411 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
412 reg &= USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
413 return reg;
414}
415
416static void usb_set_dual_select(struct brcm_usb_init_params *params)
417{
418 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
419 u32 reg;
420
421 pr_debug("%s\n", __func__);
422
423 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
424 reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
425 reg |= params->port_mode;
426 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
427}
428
429static const struct brcm_usb_init_ops bcm7216_ops = {
430 .init_ipp = usb_init_ipp,
431 .init_common = usb_init_common_7216,
432 .init_xhci = usb_init_xhci,
433 .uninit_common = usb_uninit_common_7216,
434 .uninit_xhci = usb_uninit_xhci,
435 .get_dual_select = usb_get_dual_select,
436 .set_dual_select = usb_set_dual_select,
437};
438
439static const struct brcm_usb_init_ops bcm7211b0_ops = {
440 .init_ipp = usb_init_ipp,
441 .init_common = usb_init_common_7211b0,
442 .init_xhci = usb_init_xhci,
443 .uninit_common = usb_uninit_common_7211b0,
444 .uninit_xhci = usb_uninit_xhci,
445 .get_dual_select = usb_get_dual_select,
446 .set_dual_select = usb_set_dual_select,
447};
448
449void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
450{
451
452 pr_debug("%s\n", __func__);
453
454 params->family_name = "7216";
455 params->ops = &bcm7216_ops;
456}
457
458void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
459{
460
461 pr_debug("%s\n", __func__);
462
463 params->family_name = "7211";
464 params->ops = &bcm7211b0_ops;
465}