Skip to content

Commit d0178cb

Browse files
alcoopergregkh
authored andcommitted
phy: usb: Add "wake on" functionality for newer Synopsis XHCI controllers
[ Upstream commit ae532b2 ] Add "wake on" support for the newer Synopsis based XHCI only controller. This works on the 72165 and 72164 and newer chips and does not work on 7216 based systems. Also switch the USB sysclk to a slower clock on suspend to save additional power in S2. The clock switch will only save power on the 72165b0 and newer chips and is a nop on older chips. Signed-off-by: Al Cooper <alcooperx@gmail.com> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Link: https://lore.kernel.org/r/20220215032422.5179-1-f.fainelli@gmail.com Signed-off-by: Vinod Koul <vkoul@kernel.org> Stable-dep-of: 0a92ea8 ("phy: usb: Toggle the PHY power during init") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent b2cec0d commit d0178cb

1 file changed

Lines changed: 38 additions & 8 deletions

File tree

drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#define USB_CTRL_USB_PM_SOFT_RESET_MASK 0x40000000
4848
#define USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK 0x00800000
4949
#define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK 0x00400000
50+
#define USB_CTRL_USB_PM_XHC_PME_EN_MASK 0x00000010
51+
#define USB_CTRL_USB_PM_XHC_S2_CLK_SWITCH_EN_MASK 0x00000008
5052
#define USB_CTRL_USB_PM_STATUS 0x08
5153
#define USB_CTRL_USB_DEVICE_CTL1 0x10
5254
#define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK 0x00000003
@@ -190,10 +192,6 @@ static void usb_init_common(struct brcm_usb_init_params *params)
190192

191193
pr_debug("%s\n", __func__);
192194

193-
USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
194-
/* 1 millisecond - for USB clocks to settle down */
195-
usleep_range(1000, 2000);
196-
197195
if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) {
198196
reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
199197
reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
@@ -222,6 +220,17 @@ static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
222220
USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
223221
}
224222

223+
static void usb_wake_enable_7216(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, USB_PM, XHC_PME_EN);
230+
else
231+
USB_CTRL_UNSET(ctrl, USB_PM, XHC_PME_EN);
232+
}
233+
225234
static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
226235
{
227236
void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
@@ -295,21 +304,41 @@ static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
295304
usb2_eye_fix_7211b0(params);
296305
}
297306

307+
static void usb_init_common_7216(struct brcm_usb_init_params *params)
308+
{
309+
void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
310+
311+
USB_CTRL_UNSET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
312+
USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
313+
314+
/* 1 millisecond - for USB clocks to settle down */
315+
usleep_range(1000, 2000);
316+
317+
usb_wake_enable_7216(params, false);
318+
usb_init_common(params);
319+
}
320+
298321
static void usb_init_xhci(struct brcm_usb_init_params *params)
299322
{
300323
pr_debug("%s\n", __func__);
301324

302325
xhci_soft_reset(params, 0);
303326
}
304327

305-
static void usb_uninit_common(struct brcm_usb_init_params *params)
328+
static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
306329
{
307330
void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
308331

309332
pr_debug("%s\n", __func__);
310333

311-
USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
334+
if (!params->wake_enabled) {
335+
USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
312336

337+
/* Switch to using slower clock during suspend to save power */
338+
USB_CTRL_SET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
339+
} else {
340+
usb_wake_enable_7216(params, true);
341+
}
313342
}
314343

315344
static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
@@ -371,9 +400,9 @@ static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
371400

372401
static const struct brcm_usb_init_ops bcm7216_ops = {
373402
.init_ipp = usb_init_ipp,
374-
.init_common = usb_init_common,
403+
.init_common = usb_init_common_7216,
375404
.init_xhci = usb_init_xhci,
376-
.uninit_common = usb_uninit_common,
405+
.uninit_common = usb_uninit_common_7216,
377406
.uninit_xhci = usb_uninit_xhci,
378407
.get_dual_select = usb_get_dual_select,
379408
.set_dual_select = usb_set_dual_select,
@@ -396,6 +425,7 @@ void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
396425

397426
params->family_name = "7216";
398427
params->ops = &bcm7216_ops;
428+
params->suspend_with_clocks = true;
399429
}
400430

401431
void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)

0 commit comments

Comments
 (0)