1 From b0c0b66c0b432d3f3a1ae5849298ba9c7f1810c5 Mon Sep 17 00:00:00 2001
2 From: Al Cooper <alcooperx@gmail.com>
3 Date: Fri, 3 Jan 2020 13:18:11 -0500
4 Subject: [PATCH] phy: usb: Add support for wake and USB low power mode for
7 Add support for 7211 USB wake. Disable all possible 7211 USB logic
8 for S2/S5 if USB wake is not enabled.
10 On the 7211, the XHCI wake signal was not connected properly and
11 only goes to the USB1_USB1_CTRL_TP_DIAG1 diagonstic register.
12 The workaround is to have VPU code running that polls for the
13 proper bit in the DIAG register and to wake the system when
16 Signed-off-by: Al Cooper <alcooperx@gmail.com>
17 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
18 Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
20 .../phy/broadcom/phy-brcm-usb-init-synopsys.c | 77 +++++++++++++++++--
21 drivers/phy/broadcom/phy-brcm-usb-init.c | 26 ++++---
22 drivers/phy/broadcom/phy-brcm-usb-init.h | 11 +--
23 drivers/phy/broadcom/phy-brcm-usb.c | 25 ++++--
24 4 files changed, 105 insertions(+), 34 deletions(-)
26 --- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
27 +++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
29 #define PIARBCTL_MISC_CAM1_MEM_PAGE_MASK 0x00000f00
30 #define PIARBCTL_MISC_CAM0_MEM_PAGE_MASK 0x000000f0
31 #define PIARBCTL_MISC_SATA_PRIORITY_MASK 0x0000000f
32 -#define PIARBCTL_USB_M_ASB_CTRL 0x10
34 #define PIARBCTL_MISC_USB_ONLY_MASK \
35 (PIARBCTL_MISC_USB_SELECT_MASK | \
37 #define USB_CTRL_USB_PM_STATUS 0x08
38 #define USB_CTRL_USB_DEVICE_CTL1 0x10
39 #define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK 0x00000003
40 +#define USB_CTRL_TEST_PORT_CTL 0x30
41 +#define USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_MASK 0x000000ff
42 +#define USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_PME_GEN_MASK 0x0000002e
43 +#define USB_CTRL_TP_DIAG1 0x34
44 +#define USB_CTLR_TP_DIAG1_wake_MASK 0x00000002
45 +#define USB_CTRL_CTLR_CSHCR 0x50
46 +#define USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK 0x00040000
48 /* Register definitions for the USB_PHY block in 7211b0 */
49 +#define USB_PHY_PLL_CTL 0x00
50 +#define USB_PHY_PLL_CTL_PLL_RESETB_MASK 0x40000000
51 #define USB_PHY_PLL_LDO_CTL 0x08
52 #define USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK 0x00000004
53 +#define USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK 0x00000002
54 +#define USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK 0x00000001
55 #define USB_PHY_UTMI_CTL_1 0x04
56 #define USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK 0x00000800
57 #define USB_PHY_UTMI_CTL_1_PHY_MODE_MASK 0x0000000c
58 #define USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT 2
59 +#define USB_PHY_IDDQ 0x1c
60 +#define USB_PHY_IDDQ_phy_iddq_MASK 0x00000001
61 #define USB_PHY_STATUS 0x20
62 #define USB_PHY_STATUS_pll_lock_MASK 0x00000001
64 @@ -199,6 +211,17 @@ static void usb_init_common(struct brcm_
68 +static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
71 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
74 + USB_CTRL_SET(ctrl, CTLR_CSHCR, ctl_pme_en);
76 + USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
79 static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
81 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
82 @@ -210,9 +233,27 @@ static void usb_init_common_7211b0(struc
83 if (params->syscon_piarbctl)
84 syscon_piarbctl_init(params->syscon_piarbctl);
86 + USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
88 + usb_wake_enable_7211b0(params, false);
89 + if (!params->wake_enabled) {
91 + /* undo possible suspend settings */
92 + brcm_usb_writel(0, usb_phy + USB_PHY_IDDQ);
93 + reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
94 + reg |= USB_PHY_PLL_CTL_PLL_RESETB_MASK;
95 + brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
97 + /* temporarily enable FSM so PHY comes up properly */
98 + reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
99 + reg |= USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
100 + brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
104 - reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_LDO_CTL);
105 - reg |= USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK;
106 + reg = USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK |
107 + USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK |
108 + USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK;
109 brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
112 @@ -276,12 +317,36 @@ static void usb_uninit_common(struct brc
116 +static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
118 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
119 + void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
122 + pr_debug("%s\n", __func__);
124 + if (params->wake_enabled) {
125 + USB_CTRL_SET(ctrl, TEST_PORT_CTL, TPOUT_SEL_PME_GEN);
126 + usb_wake_enable_7211b0(params, true);
128 + USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
129 + brcm_usb_writel(0, usb_phy + USB_PHY_PLL_LDO_CTL);
130 + reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
131 + reg &= ~USB_PHY_PLL_CTL_PLL_RESETB_MASK;
132 + brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
133 + brcm_usb_writel(USB_PHY_IDDQ_phy_iddq_MASK,
134 + usb_phy + USB_PHY_IDDQ);
139 static void usb_uninit_xhci(struct brcm_usb_init_params *params)
142 pr_debug("%s\n", __func__);
144 - xhci_soft_reset(params, 1);
145 + if (!params->wake_enabled)
146 + xhci_soft_reset(params, 1);
149 static int usb_get_dual_select(struct brcm_usb_init_params *params)
150 @@ -309,7 +374,6 @@ static void usb_set_dual_select(struct b
151 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
155 static const struct brcm_usb_init_ops bcm7216_ops = {
156 .init_ipp = usb_init_ipp,
157 .init_common = usb_init_common,
158 @@ -324,7 +388,7 @@ static const struct brcm_usb_init_ops bc
159 .init_ipp = usb_init_ipp,
160 .init_common = usb_init_common_7211b0,
161 .init_xhci = usb_init_xhci,
162 - .uninit_common = usb_uninit_common,
163 + .uninit_common = usb_uninit_common_7211b0,
164 .uninit_xhci = usb_uninit_xhci,
165 .get_dual_select = usb_get_dual_select,
166 .set_dual_select = usb_set_dual_select,
167 @@ -346,4 +410,5 @@ void brcm_usb_dvr_init_7211b0(struct brc
169 params->family_name = "7211";
170 params->ops = &bcm7211b0_ops;
171 + params->suspend_with_clocks = true;
173 --- a/drivers/phy/broadcom/phy-brcm-usb-init.c
174 +++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
175 @@ -783,12 +783,24 @@ static void usb_init_ipp(struct brcm_usb
179 +static void usb_wake_enable(struct brcm_usb_init_params *params,
182 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
185 + USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
187 + USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
190 static void usb_init_common(struct brcm_usb_init_params *params)
193 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
195 /* Clear any pending wake conditions */
196 + usb_wake_enable(params, false);
197 reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
198 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));
200 @@ -935,6 +947,8 @@ static void usb_uninit_common(struct brc
202 if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN))
203 USB_CTRL_SET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);
204 + if (params->wake_enabled)
205 + usb_wake_enable(params, true);
208 static void usb_uninit_eohci(struct brcm_usb_init_params *params)
209 @@ -978,17 +992,6 @@ static void usb_set_dual_select(struct b
213 -static void usb_wake_enable(struct brcm_usb_init_params *params,
216 - void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
219 - USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
221 - USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
224 static const struct brcm_usb_init_ops bcm7445_ops = {
225 .init_ipp = usb_init_ipp,
226 .init_common = usb_init_common,
227 @@ -999,7 +1002,6 @@ static const struct brcm_usb_init_ops bc
228 .uninit_xhci = usb_uninit_xhci,
229 .get_dual_select = usb_get_dual_select,
230 .set_dual_select = usb_set_dual_select,
231 - .wake_enable = usb_wake_enable,
234 void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params)
235 --- a/drivers/phy/broadcom/phy-brcm-usb-init.h
236 +++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
237 @@ -46,8 +46,6 @@ struct brcm_usb_init_ops {
238 void (*uninit_xhci)(struct brcm_usb_init_params *params);
239 int (*get_dual_select)(struct brcm_usb_init_params *params);
240 void (*set_dual_select)(struct brcm_usb_init_params *params, int mode);
241 - void (*wake_enable)(struct brcm_usb_init_params *params,
245 struct brcm_usb_init_params {
246 @@ -62,6 +60,8 @@ struct brcm_usb_init_params {
247 const u32 *usb_reg_bits_map;
248 const struct brcm_usb_init_ops *ops;
249 struct regmap *syscon_piarbctl;
251 + bool suspend_with_clocks;
254 void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
255 @@ -145,13 +145,6 @@ static inline void brcm_usb_uninit_xhci(
256 ini->ops->uninit_xhci(ini);
259 -static inline void brcm_usb_wake_enable(struct brcm_usb_init_params *ini,
262 - if (ini->ops->wake_enable)
263 - ini->ops->wake_enable(ini, enable);
266 static inline int brcm_usb_get_dual_select(struct brcm_usb_init_params *ini)
268 if (ini->ops->get_dual_select)
269 --- a/drivers/phy/broadcom/phy-brcm-usb.c
270 +++ b/drivers/phy/broadcom/phy-brcm-usb.c
271 @@ -535,16 +535,26 @@ static int brcm_usb_phy_suspend(struct d
272 struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
274 if (priv->init_count) {
275 + priv->ini.wake_enabled = device_may_wakeup(dev);
276 if (priv->phys[BRCM_USB_PHY_3_0].inited)
277 brcm_usb_uninit_xhci(&priv->ini);
278 if (priv->phys[BRCM_USB_PHY_2_0].inited)
279 brcm_usb_uninit_eohci(&priv->ini);
280 brcm_usb_uninit_common(&priv->ini);
281 - brcm_usb_wake_enable(&priv->ini, true);
282 - if (priv->phys[BRCM_USB_PHY_3_0].inited)
283 - clk_disable_unprepare(priv->usb_30_clk);
284 - if (priv->phys[BRCM_USB_PHY_2_0].inited || !priv->has_eohci)
285 - clk_disable_unprepare(priv->usb_20_clk);
288 + * Handle the clocks unless needed for wake. This has
289 + * to work for both older XHCI->3.0-clks, EOHCI->2.0-clks
290 + * and newer XHCI->2.0-clks/3.0-clks.
293 + if (!priv->ini.suspend_with_clocks) {
294 + if (priv->phys[BRCM_USB_PHY_3_0].inited)
295 + clk_disable_unprepare(priv->usb_30_clk);
296 + if (priv->phys[BRCM_USB_PHY_2_0].inited ||
298 + clk_disable_unprepare(priv->usb_20_clk);
300 if (priv->wake_irq >= 0)
301 enable_irq_wake(priv->wake_irq);
303 @@ -557,7 +567,6 @@ static int brcm_usb_phy_resume(struct de
305 clk_prepare_enable(priv->usb_20_clk);
306 clk_prepare_enable(priv->usb_30_clk);
307 - brcm_usb_wake_enable(&priv->ini, false);
308 brcm_usb_init_ipp(&priv->ini);
311 @@ -579,6 +588,8 @@ static int brcm_usb_phy_resume(struct de
312 } else if (priv->has_xhci) {
313 brcm_usb_uninit_xhci(&priv->ini);
314 clk_disable_unprepare(priv->usb_30_clk);
315 + if (!priv->has_eohci)
316 + clk_disable_unprepare(priv->usb_20_clk);
320 @@ -589,7 +600,7 @@ static int brcm_usb_phy_resume(struct de
321 clk_disable_unprepare(priv->usb_20_clk);
322 clk_disable_unprepare(priv->usb_30_clk);
325 + priv->ini.wake_enabled = false;
328 #endif /* CONFIG_PM_SLEEP */