[PATCH v9 38/38] phy: rockchip: usbdp: Power optimizations
Sebastian Reichel
sebastian.reichel at collabora.com
Wed Jul 1 16:36:16 PDT 2026
Right now the initialization routine enables power for all modes
currently supported by the hardware instead of the combination of
hardware supported mode + software requestes modes. This wastes
some power for some use cases like having a USB-C hub plugged in
without the DP (or HDMI) port being used. Fix this by requesting
power for software requested modes, which are currently supported
by the hardware.
Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index d056da53cb1c..7f90f666076c 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -771,21 +771,21 @@ static int rk_udphy_status_check(struct rk_udphy *udphy)
return 0;
}
-static int rk_udphy_init(struct rk_udphy *udphy)
+static int rk_udphy_init(struct rk_udphy *udphy, u8 mode)
{
const struct rk_udphy_cfg *cfg = udphy->cfgs;
int ret;
dev_dbg(udphy->dev, "reinit PHY with USB=%s and DP=%s (%u lanes) flipped=%s\n",
- str_enabled_disabled(udphy->hw_mode & UDPHY_MODE_USB),
- str_enabled_disabled(udphy->hw_mode & UDPHY_MODE_DP),
+ str_enabled_disabled(mode & UDPHY_MODE_USB),
+ str_enabled_disabled(mode & UDPHY_MODE_DP),
udphy->dp_lanes, str_yes_no(udphy->flip));
rk_udphy_reset_assert_all(udphy);
usleep_range(10000, 11000);
/* enable rx lfps for usb */
- if (udphy->hw_mode & UDPHY_MODE_USB)
+ if (mode & UDPHY_MODE_USB)
rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.rx_lfps, true);
/* Step 1: power on pma and deassert apb rstn */
@@ -822,13 +822,13 @@ static int rk_udphy_init(struct rk_udphy *udphy)
FIELD_PREP(CMN_DP_LANE_EN_ALL, 0));
/* Step 4: deassert init rstn and wait for 200ns from datasheet */
- if (udphy->hw_mode & UDPHY_MODE_USB) {
+ if (mode & UDPHY_MODE_USB) {
ret = rk_udphy_reset_deassert(udphy, "init");
if (ret)
goto assert_resets;
}
- if (udphy->hw_mode & UDPHY_MODE_DP) {
+ if (mode & UDPHY_MODE_DP) {
regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
CMN_DP_INIT_RSTN,
FIELD_PREP(CMN_DP_INIT_RSTN, 0x1));
@@ -837,7 +837,7 @@ static int rk_udphy_init(struct rk_udphy *udphy)
udelay(1);
/* Step 5: deassert cmn/lane rstn */
- if (udphy->hw_mode & UDPHY_MODE_USB) {
+ if (mode & UDPHY_MODE_USB) {
ret = rk_udphy_reset_deassert(udphy, "cmn");
if (ret)
goto assert_resets;
@@ -860,7 +860,7 @@ static int rk_udphy_init(struct rk_udphy *udphy)
return ret;
}
-static int rk_udphy_setup(struct rk_udphy *udphy)
+static int rk_udphy_setup(struct rk_udphy *udphy, u8 mode)
{
int ret;
@@ -872,7 +872,7 @@ static int rk_udphy_setup(struct rk_udphy *udphy)
return ret;
}
- ret = rk_udphy_init(udphy);
+ ret = rk_udphy_init(udphy, mode);
if (ret) {
dev_err(udphy->dev, "failed to init combophy\n");
clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks);
@@ -1039,7 +1039,7 @@ static int rk_udphy_update_power_state(struct rk_udphy *udphy)
if (udphy->status == UDPHY_MODE_NONE) {
/* Power up (incl. clocks) */
- ret = rk_udphy_setup(udphy);
+ ret = rk_udphy_setup(udphy, target_mode);
if (ret) {
phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
return ret;
@@ -1049,7 +1049,7 @@ static int rk_udphy_update_power_state(struct rk_udphy *udphy)
rk_udphy_disable(udphy);
} else {
/* Mode change => re-init */
- ret = rk_udphy_init(udphy);
+ ret = rk_udphy_init(udphy, target_mode);
if (ret) {
phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
return ret;
--
2.53.0
More information about the linux-arm-kernel
mailing list