* [PATCH v4 11/16] phy: rockchip: usbdp: Register DP aux bridge
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Add support to use USB-C connectors with the DP altmode helper code on
devicetree based platforms. To get this working there must be a DRM
bridge chain from the DisplayPort controller to the USB-C connector.
E.g. on Rockchip RK3576:
root@rk3576 # cat /sys/kernel/debug/dri/0/encoder-0/bridges
bridge[0]: dw_dp_bridge_funcs
refcount: 7
type: [10] DP
OF: /soc/dp@27e40000:rockchip,rk3576-dp
ops: [0x47] detect edid hpd
bridge[1]: drm_aux_bridge_funcs
refcount: 4
type: [0] Unknown
OF: /soc/phy@2b010000:rockchip,rk3576-usbdp-phy
ops: [0x0]
bridge[2]: drm_aux_hpd_bridge_funcs
refcount: 5
type: [10] DP
OF: /soc/i2c@2ac50000/typec-portc@22/connector:usb-c-connector
ops: [0x4] hpd
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/Kconfig | 2 ++
drivers/phy/rockchip/phy-rockchip-usbdp.c | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 14698571b607..39759bb2fa1d 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -136,8 +136,10 @@ config PHY_ROCKCHIP_USBDP
tristate "Rockchip USBDP COMBO PHY Driver"
depends on ARCH_ROCKCHIP && OF
depends on TYPEC
+ depends on DRM || DRM=n
select GENERIC_PHY
select USB_COMMON
+ select DRM_AUX_BRIDGE if DRM_BRIDGE
help
Enable this to support the Rockchip USB3.0/DP combo PHY with
Samsung IP block. This is required for USB3 support on RK3588.
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index beab20e4c512..77ad2a89d4f2 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -6,6 +6,7 @@
* Copyright (C) 2024 Collabora Ltd
*/
+#include <drm/bridge/aux-bridge.h>
#include <dt-bindings/phy/phy.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
@@ -1434,6 +1435,7 @@ static int rk_udphy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct phy_provider *phy_provider;
+ struct fwnode_handle *dp_aux_ep;
struct resource *res;
struct rk_udphy *udphy;
void __iomem *base;
@@ -1492,6 +1494,18 @@ static int rk_udphy_probe(struct platform_device *pdev)
return ret;
}
+ /*
+ * Only register the DRM bridge, if the DP aux channel is connected.
+ * Some boards use the USBDP PHY only for its USB3 capabilities.
+ */
+ dp_aux_ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 3, 0, 0);
+ if (dp_aux_ep) {
+ ret = drm_aux_bridge_register(dev);
+ fwnode_handle_put(dp_aux_ep);
+ if (ret)
+ return ret;
+ }
+
udphy->phy_u3 = devm_phy_create(dev, dev->of_node, &rk_udphy_usb3_phy_ops);
if (IS_ERR(udphy->phy_u3)) {
ret = PTR_ERR(udphy->phy_u3);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 15/16] phy: rockchip: usbdp: Factor out lane_mux_sel setup
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Avoid describing the USB+DP lane_mux_sel logic twice by introducing
a helper function to reduce code duplication.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 81 +++++++++++++++----------------
1 file changed, 40 insertions(+), 41 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 80fe5993c6c7..17637d92cf9b 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -586,6 +586,42 @@ static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 mode)
udphy->mode = mode;
}
+static void rk_udphy_set_typec_state(struct rk_udphy *udphy, unsigned long state)
+{
+ u8 mode;
+
+ switch (state) {
+ case TYPEC_DP_STATE_C:
+ case TYPEC_DP_STATE_E:
+ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
+ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
+ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
+ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
+ mode = UDPHY_MODE_DP;
+ udphy->dp_lanes = 4;
+ break;
+
+ case TYPEC_DP_STATE_D:
+ default:
+ if (udphy->flip) {
+ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
+ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
+ udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
+ udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
+ } else {
+ udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
+ udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
+ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
+ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
+ }
+ mode = UDPHY_MODE_DP_USB;
+ udphy->dp_lanes = 2;
+ break;
+ }
+
+ rk_udphy_mode_set(udphy, mode);
+}
+
static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
{
if (udphy->flip) {
@@ -593,10 +629,6 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
udphy->dp_lane_sel[1] = 1;
udphy->dp_lane_sel[2] = 3;
udphy->dp_lane_sel[3] = 2;
- udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
- udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_INVERT;
udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_INVERT;
gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 1);
@@ -606,18 +638,14 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
udphy->dp_lane_sel[1] = 3;
udphy->dp_lane_sel[2] = 1;
udphy->dp_lane_sel[3] = 0;
- udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
- udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
- udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_NORMAL;
udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_NORMAL;
gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0);
gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1);
}
- rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB);
- udphy->dp_lanes = 2;
+ /* default to USB3 + DP as 4 lane USB is not supported */
+ rk_udphy_set_typec_state(udphy, TYPEC_DP_STATE_D);
}
static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
@@ -1316,42 +1344,13 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
struct typec_mux_state *state)
{
struct rk_udphy *udphy = typec_mux_get_drvdata(mux);
- u8 mode;
mutex_lock(&udphy->mutex);
- switch (state->mode) {
- case TYPEC_DP_STATE_C:
- case TYPEC_DP_STATE_E:
- udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
- mode = UDPHY_MODE_DP;
- udphy->dp_lanes = 4;
- break;
-
- case TYPEC_DP_STATE_D:
- default:
- if (udphy->flip) {
- udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
- udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
- } else {
- udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
- udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
- udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
- udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
- }
- mode = UDPHY_MODE_DP_USB;
- udphy->dp_lanes = 2;
- break;
- }
-
- rk_udphy_mode_set(udphy, mode);
+ rk_udphy_set_typec_state(udphy, state->mode);
mutex_unlock(&udphy->mutex);
+
return 0;
}
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 14/16] phy: rockchip: usbdp: Re-init the PHY on orientation change
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Changing the cable orientation reconfigures the lane muxing, which
requires re-initializing the PHY. Without this DP functionality
breaks, if the cable is re-plugged with swapped orientation.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 694832cc161e..80fe5993c6c7 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -624,6 +624,7 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
enum typec_orientation orien)
{
struct rk_udphy *udphy = typec_switch_get_drvdata(sw);
+ bool flipped = orien == TYPEC_ORIENTATION_REVERSE;
mutex_lock(&udphy->mutex);
@@ -635,7 +636,10 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
goto unlock_ret;
}
- udphy->flip = orien == TYPEC_ORIENTATION_REVERSE;
+ if (udphy->flip != flipped)
+ udphy->phy_needs_reinit = true;
+
+ udphy->flip = flipped;
rk_udphy_set_typec_default_mapping(udphy);
rk_udphy_usb_bvalid_enable(udphy, true);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 12/16] phy: rockchip: usbdp: Drop DP HPD handling
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Drop the HPD handling logic from the USBDP PHY. The registers involved
require the display controller power domain being enabled and thus the
HPD signal should be handled by the displayport controller itself.
Apart from that the HPD handling as it is done here is incorrect and
misses hotplug events happening after the USB-C connector (e.g. when
a USB-C to HDMI adapter is involved and the HDMI cable is replugged).
Proper USB-C DP HPD support requires some restructuring of the DP
controller driver, which will happen independent of this patch. The
mainline kernel does not yet support USB-C DP AltMode on RK3588 and
RK3576, so it is fine to drop this code without adding the counterpart
in the DRM in an atomic change.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 47 +------------------------------
1 file changed, 1 insertion(+), 46 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 77ad2a89d4f2..3f1233f50686 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -186,8 +186,6 @@ struct rk_udphy {
u32 dp_lane_sel[4];
u32 dp_aux_dout_sel;
u32 dp_aux_din_sel;
- bool dp_sink_hpd_sel;
- bool dp_sink_hpd_cfg;
unsigned int link_rate;
unsigned int lanes;
u8 bw;
@@ -579,19 +577,6 @@ static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
}
-static void rk_udphy_dp_hpd_event_trigger(struct rk_udphy *udphy, bool hpd)
-{
- const struct rk_udphy_cfg *cfg = udphy->cfgs;
-
- udphy->dp_sink_hpd_sel = true;
- udphy->dp_sink_hpd_cfg = hpd;
-
- if (!udphy->dp_in_use)
- return;
-
- rk_udphy_grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd);
-}
-
static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 mode)
{
if (udphy->mode == mode)
@@ -1360,22 +1345,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
break;
}
- if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
- struct typec_displayport_data *data = state->data;
-
- if (!data) {
- rk_udphy_dp_hpd_event_trigger(udphy, false);
- } else if (data->status & DP_STATUS_IRQ_HPD) {
- rk_udphy_dp_hpd_event_trigger(udphy, false);
- usleep_range(750, 800);
- rk_udphy_dp_hpd_event_trigger(udphy, true);
- } else if (data->status & DP_STATUS_HPD_STATE) {
- rk_udphy_mode_set(udphy, mode);
- rk_udphy_dp_hpd_event_trigger(udphy, true);
- } else {
- rk_udphy_dp_hpd_event_trigger(udphy, false);
- }
- }
+ rk_udphy_mode_set(udphy, mode);
mutex_unlock(&udphy->mutex);
return 0;
@@ -1531,20 +1501,6 @@ static int rk_udphy_probe(struct platform_device *pdev)
return 0;
}
-static int __maybe_unused rk_udphy_resume(struct device *dev)
-{
- struct rk_udphy *udphy = dev_get_drvdata(dev);
-
- if (udphy->dp_sink_hpd_sel)
- rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg);
-
- return 0;
-}
-
-static const struct dev_pm_ops rk_udphy_pm_ops = {
- SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, rk_udphy_resume)
-};
-
static const char * const rk_udphy_rst_list[] = {
"init", "cmn", "lane", "pcs_apb", "pma_apb"
};
@@ -1649,7 +1605,6 @@ static struct platform_driver rk_udphy_driver = {
.driver = {
.name = "rockchip-usbdp-phy",
.of_match_table = rk_udphy_dt_match,
- .pm = &rk_udphy_pm_ops,
},
};
module_platform_driver(rk_udphy_driver);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 07/16] phy: rockchip: usbdp: Support single-lane DP
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
From: Zhang Yubing <yubing.zhang@rock-chips.com>
Implement support for using just a single DisplayPort line.
Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 61 +++++++++++++------------------
1 file changed, 25 insertions(+), 36 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index febc148a754e..bf8394174294 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -193,6 +193,7 @@ struct rk_udphy {
int id;
bool dp_in_use;
+ int dp_lanes;
/* PHY const config */
const struct rk_udphy_cfg *cfgs;
@@ -537,6 +538,13 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
* <0 1> dpln0 dpln1 usbrx usbtx
* <2 3> usbrx usbtx dpln0 dpln1
* ---------------------------------------------------------------------------
+ * if 1 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = <x>;
+ * sample as follow:
+ * ---------------------------------------------------------------------------
+ * B11-B10 A2-A3 A11-A10 B2-B3
+ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
+ * <0> dpln0 \ usbrx usbtx
+ * ---------------------------------------------------------------------------
*/
static void rk_udphy_dplane_select(struct rk_udphy *udphy)
@@ -544,18 +552,18 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
const struct rk_udphy_cfg *cfg = udphy->cfgs;
u32 value = 0;
- switch (udphy->mode) {
- case UDPHY_MODE_DP:
- value |= 2 << udphy->dp_lane_sel[2] * 2;
+ switch (udphy->dp_lanes) {
+ case 4:
value |= 3 << udphy->dp_lane_sel[3] * 2;
+ value |= 2 << udphy->dp_lane_sel[2] * 2;
fallthrough;
- case UDPHY_MODE_DP_USB:
- value |= 0 << udphy->dp_lane_sel[0] * 2;
+ case 2:
value |= 1 << udphy->dp_lane_sel[1] * 2;
- break;
+ fallthrough;
- case UDPHY_MODE_USB:
+ case 1:
+ value |= 0 << udphy->dp_lane_sel[0] * 2;
break;
default:
@@ -568,28 +576,6 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
}
-static int rk_udphy_dplane_get(struct rk_udphy *udphy)
-{
- int dp_lanes;
-
- switch (udphy->mode) {
- case UDPHY_MODE_DP:
- dp_lanes = 4;
- break;
-
- case UDPHY_MODE_DP_USB:
- dp_lanes = 2;
- break;
-
- case UDPHY_MODE_USB:
- default:
- dp_lanes = 0;
- break;
- }
-
- return dp_lanes;
-}
-
static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
{
u32 val = 0;
@@ -659,6 +645,7 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
}
rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB);
+ udphy->dp_lanes = 2;
}
static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
@@ -897,7 +884,7 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
return 0;
}
- if (num_lanes != 2 && num_lanes != 4)
+ if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4)
return dev_err_probe(udphy->dev, -EINVAL,
"invalid number of lane mux\n");
@@ -923,7 +910,8 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
}
udphy->mode = UDPHY_MODE_DP;
- if (num_lanes == 2) {
+ udphy->dp_lanes = num_lanes;
+ if (num_lanes == 1 || num_lanes == 2) {
udphy->mode |= UDPHY_MODE_USB;
udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP);
}
@@ -1074,18 +1062,17 @@ static int rk_udphy_dp_phy_exit(struct phy *phy)
static int rk_udphy_dp_phy_power_on(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
- int ret, dp_lanes;
+ int ret;
mutex_lock(&udphy->mutex);
- dp_lanes = rk_udphy_dplane_get(udphy);
- phy_set_bus_width(phy, dp_lanes);
+ phy_set_bus_width(phy, udphy->dp_lanes);
ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
if (ret)
goto unlock;
- rk_udphy_dplane_enable(udphy, dp_lanes);
+ rk_udphy_dplane_enable(udphy, udphy->dp_lanes);
rk_udphy_dplane_select(udphy);
@@ -1365,6 +1352,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
mode = UDPHY_MODE_DP;
+ udphy->dp_lanes = 4;
break;
case TYPEC_DP_STATE_D:
@@ -1381,6 +1369,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
}
mode = UDPHY_MODE_DP_USB;
+ udphy->dp_lanes = 2;
break;
}
@@ -1529,7 +1518,7 @@ static int rk_udphy_probe(struct platform_device *pdev)
ret = PTR_ERR(udphy->phy_dp);
return dev_err_probe(dev, ret, "failed to create DP phy\n");
}
- phy_set_bus_width(udphy->phy_dp, rk_udphy_dplane_get(udphy));
+ phy_set_bus_width(udphy->phy_dp, udphy->dp_lanes);
udphy->phy_dp->attrs.max_link_rate = 8100;
phy_set_drvdata(udphy->phy_dp, udphy);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 09/16] phy: rockchip: usbdp: Use FIELD_PREP_WM16_CONST
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Cleanup code by replacing open-coded version of FIELD_PREP_WM16_CONST
with the existing helper macro.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 6d7ca11b308e..1bfc365e2b2c 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/hw_bitfield.h>
#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
@@ -75,7 +76,6 @@
#define TRSV_LN2_MON_RX_CDR_DONE_OFFSET 0x1b84 /* trsv_reg06E1 */
#define TRSV_LN2_MON_RX_CDR_LOCK_DONE BIT(0)
-#define BIT_WRITEABLE_SHIFT 16
#define PHY_AUX_DP_DATA_POL_NORMAL 0
#define PHY_AUX_DP_DATA_POL_INVERT 1
#define PHY_LANE_MUX_USB 0
@@ -104,8 +104,8 @@ struct rk_udphy_grf_reg {
#define _RK_UDPHY_GEN_GRF_REG(offset, mask, disable, enable) \
{\
offset, \
- FIELD_PREP_CONST(mask, disable) | (mask << BIT_WRITEABLE_SHIFT), \
- FIELD_PREP_CONST(mask, enable) | (mask << BIT_WRITEABLE_SHIFT), \
+ FIELD_PREP_WM16_CONST(mask, disable), \
+ FIELD_PREP_WM16_CONST(mask, enable), \
}
#define RK_UDPHY_GEN_GRF_REG(offset, bitend, bitstart, disable, enable) \
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 16/16] phy: rockchip: usbdp: Use guard functions for mutex
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Convert the driver to use guard functions for mutex handling as
a small cleanup. There is a small functional change in the DP PHY
power up function, which no longer sleeps if the internal powerup
code returns an error. This is not a problem as the sleep is only
relevant for successful power-up.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 60 ++++++++++++++-----------------
1 file changed, 27 insertions(+), 33 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 17637d92cf9b..f318b04c097d 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -10,6 +10,7 @@
#include <dt-bindings/phy/phy.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
@@ -654,14 +655,15 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
struct rk_udphy *udphy = typec_switch_get_drvdata(sw);
bool flipped = orien == TYPEC_ORIENTATION_REVERSE;
- mutex_lock(&udphy->mutex);
+ guard(mutex)(&udphy->mutex);
if (orien == TYPEC_ORIENTATION_NONE) {
gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0);
gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0);
/* unattached */
rk_udphy_usb_bvalid_enable(udphy, false);
- goto unlock_ret;
+
+ return 0;
}
if (udphy->flip != flipped)
@@ -671,8 +673,6 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
rk_udphy_set_typec_default_mapping(udphy);
rk_udphy_usb_bvalid_enable(udphy, true);
-unlock_ret:
- mutex_unlock(&udphy->mutex);
return 0;
}
@@ -1044,12 +1044,10 @@ static int rk_udphy_dp_phy_init(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
- mutex_lock(&udphy->mutex);
+ guard(mutex)(&udphy->mutex);
udphy->dp_in_use = true;
- mutex_unlock(&udphy->mutex);
-
return 0;
}
@@ -1057,9 +1055,10 @@ static int rk_udphy_dp_phy_exit(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
- mutex_lock(&udphy->mutex);
+ guard(mutex)(&udphy->mutex);
+
udphy->dp_in_use = false;
- mutex_unlock(&udphy->mutex);
+
return 0;
}
@@ -1068,26 +1067,25 @@ static int rk_udphy_dp_phy_power_on(struct phy *phy)
struct rk_udphy *udphy = phy_get_drvdata(phy);
int ret;
- mutex_lock(&udphy->mutex);
+ scoped_guard(mutex, &udphy->mutex) {
+ phy_set_bus_width(phy, udphy->dp_lanes);
- phy_set_bus_width(phy, udphy->dp_lanes);
-
- ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
- if (ret)
- goto unlock;
+ ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
+ if (ret)
+ return ret;
- rk_udphy_dp_lane_enable(udphy, udphy->dp_lanes);
+ rk_udphy_dp_lane_enable(udphy, udphy->dp_lanes);
- rk_udphy_dp_lane_select(udphy);
+ rk_udphy_dp_lane_select(udphy);
+ }
-unlock:
- mutex_unlock(&udphy->mutex);
/*
* If data send by aux channel too fast after phy power on,
* the aux may be not ready which will cause aux error. Adding
* delay to avoid this issue.
*/
usleep_range(10000, 11000);
+
return ret;
}
@@ -1095,10 +1093,10 @@ static int rk_udphy_dp_phy_power_off(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
- mutex_lock(&udphy->mutex);
+ guard(mutex)(&udphy->mutex);
+
rk_udphy_dp_lane_enable(udphy, 0);
rk_udphy_power_off(udphy, UDPHY_MODE_DP);
- mutex_unlock(&udphy->mutex);
return 0;
}
@@ -1302,19 +1300,18 @@ static const struct phy_ops rk_udphy_dp_phy_ops = {
static int rk_udphy_usb3_phy_init(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
- int ret = 0;
+ int ret;
+
+ guard(mutex)(&udphy->mutex);
- mutex_lock(&udphy->mutex);
/* DP only or high-speed, disable U3 port */
if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) {
rk_udphy_u3_port_disable(udphy, true);
- goto unlock;
+ return 0;
}
ret = rk_udphy_power_on(udphy, UDPHY_MODE_USB);
-unlock:
- mutex_unlock(&udphy->mutex);
return ret;
}
@@ -1322,15 +1319,14 @@ static int rk_udphy_usb3_phy_exit(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
- mutex_lock(&udphy->mutex);
+ guard(mutex)(&udphy->mutex);
+
/* DP only or high-speed */
if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs)
- goto unlock;
+ return 0;
rk_udphy_power_off(udphy, UDPHY_MODE_USB);
-unlock:
- mutex_unlock(&udphy->mutex);
return 0;
}
@@ -1345,12 +1341,10 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
{
struct rk_udphy *udphy = typec_mux_get_drvdata(mux);
- mutex_lock(&udphy->mutex);
+ guard(mutex)(&udphy->mutex);
rk_udphy_set_typec_state(udphy, state->mode);
- mutex_unlock(&udphy->mutex);
-
return 0;
}
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 13/16] phy: rockchip: usbdp: Rename mode_change to phy_needs_reinit
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Right now the mode_change property is set whenever the mode changes
between USB-only, DP-only and USB-DP. It is needed, because on any
mode change the PHY needs to be re-initialized. Apparently at least
DP also requires a re-init when the cable orientation is changed,
which is currently not being done (except when the orientation switch
also involves a mode change). Prepare for this by renaming mode_change
to phy_needs_reinit.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 3f1233f50686..694832cc161e 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -172,7 +172,7 @@ struct rk_udphy {
/* PHY status management */
bool flip;
- bool mode_change;
+ bool phy_needs_reinit;
u8 mode;
u8 status;
@@ -582,7 +582,7 @@ static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 mode)
if (udphy->mode == mode)
return;
- udphy->mode_change = true;
+ udphy->phy_needs_reinit = true;
udphy->mode = mode;
}
@@ -970,15 +970,15 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
}
if (udphy->status == UDPHY_MODE_NONE) {
- udphy->mode_change = false;
+ udphy->phy_needs_reinit = false;
ret = rk_udphy_setup(udphy);
if (ret)
return ret;
if (udphy->mode & UDPHY_MODE_USB)
rk_udphy_u3_port_disable(udphy, false);
- } else if (udphy->mode_change) {
- udphy->mode_change = false;
+ } else if (udphy->phy_needs_reinit) {
+ udphy->phy_needs_reinit = false;
if (udphy->mode == UDPHY_MODE_DP)
rk_udphy_u3_port_disable(udphy, true);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 08/16] phy: rockchip: usbdp: Rename DP lane functions
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
The common prefix for DisplayPort related functions is rk_udphy_dp_
(with a final _), so update the two DP lane functions to follow that
scheme.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index bf8394174294..6d7ca11b308e 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -547,7 +547,7 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
* ---------------------------------------------------------------------------
*/
-static void rk_udphy_dplane_select(struct rk_udphy *udphy)
+static void rk_udphy_dp_lane_select(struct rk_udphy *udphy)
{
const struct rk_udphy_cfg *cfg = udphy->cfgs;
u32 value = 0;
@@ -576,7 +576,7 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
}
-static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
+static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
{
u32 val = 0;
int i;
@@ -1072,9 +1072,9 @@ static int rk_udphy_dp_phy_power_on(struct phy *phy)
if (ret)
goto unlock;
- rk_udphy_dplane_enable(udphy, udphy->dp_lanes);
+ rk_udphy_dp_lane_enable(udphy, udphy->dp_lanes);
- rk_udphy_dplane_select(udphy);
+ rk_udphy_dp_lane_select(udphy);
unlock:
mutex_unlock(&udphy->mutex);
@@ -1092,7 +1092,7 @@ static int rk_udphy_dp_phy_power_off(struct phy *phy)
struct rk_udphy *udphy = phy_get_drvdata(phy);
mutex_lock(&udphy->mutex);
- rk_udphy_dplane_enable(udphy, 0);
+ rk_udphy_dp_lane_enable(udphy, 0);
rk_udphy_power_off(udphy, UDPHY_MODE_DP);
mutex_unlock(&udphy->mutex);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 04/16] phy: rockchip: usbdp: Amend SSC modulation deviation
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
From: Frank Wang <frank.wang@rock-chips.com>
Move SSC modulation deviation into private config of clock
- 24M: 0x00d4[5:0] = 0x30
- 26M: 0x00d4[5:0] = 0x33
Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
[Taken over from rockchip's kernel tree; register 0x00d4 is not
described in the TRM]
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 98562a888b42..1f686844c337 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -350,7 +350,8 @@ static const struct reg_sequence rk_udphy_24m_refclk_cfg[] = {
{0x0a64, 0xa8}, {0x1a3c, 0xd0},
{0x1a44, 0xd0}, {0x1a48, 0x01},
{0x1a4c, 0x0d}, {0x1a54, 0xe0},
- {0x1a5c, 0xe0}, {0x1a64, 0xa8}
+ {0x1a5c, 0xe0}, {0x1a64, 0xa8},
+ {0x00d4, 0x30}
};
static const struct reg_sequence rk_udphy_26m_refclk_cfg[] = {
@@ -377,7 +378,7 @@ static const struct reg_sequence rk_udphy_26m_refclk_cfg[] = {
{0x0c30, 0x0e}, {0x0c48, 0x06},
{0x1c30, 0x0e}, {0x1c48, 0x06},
{0x028c, 0x18}, {0x0af0, 0x00},
- {0x1af0, 0x00}
+ {0x1af0, 0x00}, {0x00d4, 0x33}
};
static const struct reg_sequence rk_udphy_init_sequence[] = {
@@ -412,8 +413,7 @@ static const struct reg_sequence rk_udphy_init_sequence[] = {
{0x0070, 0x7d}, {0x0074, 0x68},
{0x0af4, 0x1a}, {0x1af4, 0x1a},
{0x0440, 0x3f}, {0x10d4, 0x08},
- {0x20d4, 0x08}, {0x00d4, 0x30},
- {0x0024, 0x6e},
+ {0x20d4, 0x08}, {0x0024, 0x6e}
};
static inline int rk_udphy_grfreg_write(struct regmap *base,
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 03/16] phy: rockchip: usbdp: Keep clocks running on PHY re-init
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
When a mode change is required rk_udphy_power_on() disables
the clocks and then calls rk_udphy_setup(), which then enables
all the clocks again before continuing with rk_udphy_init().
Considering that rk_udphy_init() does assert the reset lines,
re-enabling the clocks is just delaying things. Avoid it by
directly calling rk_udphy_init().
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 744cc7c642f4..98562a888b42 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1012,8 +1012,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
if (udphy->mode == UDPHY_MODE_DP)
rk_udphy_u3_port_disable(udphy, true);
- rk_udphy_disable(udphy);
- ret = rk_udphy_setup(udphy);
+ ret = rk_udphy_init(udphy);
if (ret)
return ret;
}
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 06/16] phy: rockchip: usbdp: Add missing mode_change update
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
rk_udphy_set_typec_default_mapping() updates the available modes,
but does not set the mode_change as required. This results in
missing re-initialization and thus non-working DisplayPort.
Fix this issue by introducing a new helper to update the available
modes.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 97e53b933225..febc148a754e 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -619,6 +619,15 @@ static void rk_udphy_dp_hpd_event_trigger(struct rk_udphy *udphy, bool hpd)
rk_udphy_grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd);
}
+static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 mode)
+{
+ if (udphy->mode == mode)
+ return;
+
+ udphy->mode_change = true;
+ udphy->mode = mode;
+}
+
static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
{
if (udphy->flip) {
@@ -649,7 +658,7 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1);
}
- udphy->mode = UDPHY_MODE_DP_USB;
+ rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB);
}
static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
@@ -1385,10 +1394,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
usleep_range(750, 800);
rk_udphy_dp_hpd_event_trigger(udphy, true);
} else if (data->status & DP_STATUS_HPD_STATE) {
- if (udphy->mode != mode) {
- udphy->mode = mode;
- udphy->mode_change = true;
- }
+ rk_udphy_mode_set(udphy, mode);
rk_udphy_dp_hpd_event_trigger(udphy, true);
} else {
rk_udphy_dp_hpd_event_trigger(udphy, false);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 05/16] phy: rockchip: usbdp: Fix LFPS detect threshold control
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, William Wu
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
From: William Wu <william.wu@rock-chips.com>
According to the LFPS Tx Low Power/LFPS Rx Detect Threshold [1],
the device under test(DUT) must not respond if LFPS below the
minimum LFPS Rx Detect Threshold 100mV. Test fail on Rockchip
platforms, because the default LFPS detect threshold is set to
65mV.
The USBDP PHY LFPS detect threshold voltage could be set to
30mV ~ 140mV, and since there could be 10-20% PVT variation,
we set LFPS detect threshold voltage to 110mV.
[1] https://compliance.usb.org/resources/LFPS_Rx_Tx_Low_Power_Compliance_Update_Rev5.pdf
Signed-off-by: William Wu <william.wu@rock-chips.com>
[Taken over from rockchip's kernel tree; the registers are not described
in the TRM]
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 1f686844c337..97e53b933225 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -413,7 +413,8 @@ static const struct reg_sequence rk_udphy_init_sequence[] = {
{0x0070, 0x7d}, {0x0074, 0x68},
{0x0af4, 0x1a}, {0x1af4, 0x1a},
{0x0440, 0x3f}, {0x10d4, 0x08},
- {0x20d4, 0x08}, {0x0024, 0x6e}
+ {0x20d4, 0x08}, {0x0024, 0x6e},
+ {0x09c0, 0x0a}, {0x19c0, 0x0a}
};
static inline int rk_udphy_grfreg_write(struct regmap *base,
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 10/16] phy: rockchip: usbdp: Cleanup DP lane selection function
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Use FIELD_PREP_WM16() helpers to simplify the DP lane selection
logic.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 28 +++++++---------------------
1 file changed, 7 insertions(+), 21 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 1bfc365e2b2c..beab20e4c512 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -550,30 +550,16 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
static void rk_udphy_dp_lane_select(struct rk_udphy *udphy)
{
const struct rk_udphy_cfg *cfg = udphy->cfgs;
- u32 value = 0;
-
- switch (udphy->dp_lanes) {
- case 4:
- value |= 3 << udphy->dp_lane_sel[3] * 2;
- value |= 2 << udphy->dp_lane_sel[2] * 2;
- fallthrough;
-
- case 2:
- value |= 1 << udphy->dp_lane_sel[1] * 2;
- fallthrough;
+ u32 value = FIELD_PREP_WM16(DP_LANE_SEL_ALL, 0);
+ int i;
- case 1:
- value |= 0 << udphy->dp_lane_sel[0] * 2;
- break;
+ for (i = 0; i < udphy->dp_lanes; i++)
+ value |= field_prep(DP_LANE_SEL_N(udphy->dp_lane_sel[i]), i);
- default:
- break;
- }
+ value |= FIELD_PREP_WM16(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel);
+ value |= FIELD_PREP_WM16(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel);
- regmap_write(udphy->vogrf, cfg->vogrfcfg[udphy->id].dp_lane_reg,
- ((DP_AUX_DIN_SEL | DP_AUX_DOUT_SEL | DP_LANE_SEL_ALL) << 16) |
- FIELD_PREP(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel) |
- FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
+ regmap_write(udphy->vogrf, cfg->vogrfcfg[udphy->id].dp_lane_reg, value);
}
static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 00/16] phy: rockchip: usbdp: Fixes, DP 1-lane support and cleanups
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, William Wu
This series overhauls the Rockchip USBDP driver; apart from a
a bunch of cleanups and small improvements the main goal is to
get the driver ready for proper USB-C DP AltMode support.
Once this series has landed, it unblocks enabling proper USB-C
DP AltMode on the RK3588 and RK3576 platforms incl. runtime PM
for the Synopsys DesignWare DisplayPort controller.
Apart from this series, further changes are required on the
DRM side. There are no compile-time dependencies between the
DRM side and the PHY side, but the PHY side must be applied
to avoid SErrors once runtime PM is added to the DisplayPort
controller driver. Thus it would be really good to land this
series in the next merge window.
Changes in v4:
- Link to v3: https://lore.kernel.org/r/20260313-rockchip-usbdp-cleanup-v3-0-3e8fe89a35b5@collabora.com
- rebased to v7.1-rc1 (no changes)
- Update DRM bridge registration patch to avoid registration when DP aux
port is not connected to anything, since this results in errors and some
boards use USBDP instances for USB3 only.
- Add patch renaming mode_change into phy_needs_reinit
- Add patch to re-init PHY on orientation change
- Add patch to factor out lane_mux_sel setup
- Add patch to handle mutex via guard functions
Changes in v3:
- Link to v2: https://lore.kernel.org/r/20260213-rockchip-usbdp-cleanup-v2-0-b67ec225f96e@collabora.com
- Add patch to register the USBDP PHY as DRM bridge
- Add patch to describe ports in DT binding (used by the DRM bridge)
- Add patch to drop HPD handling from the PHY
Changes in v2:
- Link to v1: https://lore.kernel.org/r/20260203-rockchip-usbdp-cleanup-v1-0-16a6f92ed176@collabora.com
- Added new patches to fix USB3 SError
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
Frank Wang (1):
phy: rockchip: usbdp: Amend SSC modulation deviation
Sebastian Reichel (13):
dt-bindings: phy: rockchip-usbdp: add improved ports scheme
phy: rockchip: usbdp: Do not loose USB3 PHY status
phy: rockchip: usbdp: Keep clocks running on PHY re-init
phy: rockchip: usbdp: Add missing mode_change update
phy: rockchip: usbdp: Rename DP lane functions
phy: rockchip: usbdp: Use FIELD_PREP_WM16_CONST
phy: rockchip: usbdp: Cleanup DP lane selection function
phy: rockchip: usbdp: Register DP aux bridge
phy: rockchip: usbdp: Drop DP HPD handling
phy: rockchip: usbdp: Rename mode_change to phy_needs_reinit
phy: rockchip: usbdp: Re-init the PHY on orientation change
phy: rockchip: usbdp: Factor out lane_mux_sel setup
phy: rockchip: usbdp: Use guard functions for mutex
William Wu (1):
phy: rockchip: usbdp: Fix LFPS detect threshold control
Zhang Yubing (1):
phy: rockchip: usbdp: Support single-lane DP
.../bindings/phy/phy-rockchip-usbdp.yaml | 23 ++
drivers/phy/rockchip/Kconfig | 2 +
drivers/phy/rockchip/phy-rockchip-usbdp.c | 302 +++++++++------------
3 files changed, 149 insertions(+), 178 deletions(-)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260203-rockchip-usbdp-cleanup-5b59dfb561a3
Best regards,
--
Sebastian Reichel <sebastian.reichel@collabora.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v4 01/16] dt-bindings: phy: rockchip-usbdp: add improved ports scheme
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
Currently the Rockchip USBDP PHY is missing a documented port scheme.
Meanwhile upstream RK3588 DTS files are a bit messy and use different
port schemes. The upstream USBDP PHY Linux kernel driver does not yet
parse the ports at all and thus does not create any implicit ABI either.
But with the current mess it is not possible to properly support USB-C
DP AltMode. Thus this introduces a proper port scheme following roughly
the ports design of the Qualcomm QMP USB4-USB3-DP PHY controller binding
with a slight difference that there is an additional port for the
USB-C SBU port as the Rockchip USB-DP PHY also contains the SBU mux.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
.../bindings/phy/phy-rockchip-usbdp.yaml | 23 ++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
index 8b7059d5b182..f728acf057e4 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
@@ -114,6 +114,29 @@ properties:
A port node to link the PHY to a TypeC controller for the purpose of
handling orientation switching.
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ Output endpoint of the PHY for USB (or DP when configured into 4 lane
+ mode), which should point to the superspeed port of a USB connector.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Incoming endpoint from the USB controller
+
+ port@2:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Incoming endpoint from the DisplayPort controller
+
+ port@3:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ Output endpoint of the PHY for DP, which should either point to the
+ SBU port of a USB-C connector or a DisplayPort connector input port.
+
required:
- compatible
- reg
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v4 02/16] phy: rockchip: usbdp: Do not loose USB3 PHY status
From: Sebastian Reichel @ 2026-04-28 16:13 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com>
By default (i.e. without manually enabling runtime PM) DWC3 requests the
USB3 PHY once and keeps it enabled all the time. When DisplayPort is
being requested later on, a mode change is needed. This re-initializes
the PHY. During re-initialization the status variable has incorrectly
been cleared, which means the tracking information for USB3 ist lost.
This is not an immediate problem, since the DP side keeps the PHY
enabled. But once DP is toggled off, the whole PHY will be disabled.
This is a problem, because the USB side still needs it powered.
Fix things by not clearing the status flags.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index fba35510d88c..744cc7c642f4 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1009,7 +1009,6 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
rk_udphy_u3_port_disable(udphy, false);
} else if (udphy->mode_change) {
udphy->mode_change = false;
- udphy->status = UDPHY_MODE_NONE;
if (udphy->mode == UDPHY_MODE_DP)
rk_udphy_u3_port_disable(udphy, true);
--
2.53.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v22 5/8] dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
From: Luca Ceresoli @ 2026-04-28 12:21 UTC (permalink / raw)
To: Laurentiu Palcu
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, dri-devel, devicetree, linux-kernel, linux-phy,
imx, linux-arm-kernel, linux, Alexander Stein, Ying Liu
In-Reply-To: <f6rf5d6nhglkwendf5yvaklfn2ovlwkqstsz7vvl5zefibtiun@wic7bchohmwv>
Hello Laurentiu,
On Mon Apr 27, 2026 at 4:35 PM CEST, Laurentiu Palcu wrote:
> Hi Luca,
>
> On Mon, Apr 27, 2026 at 02:59:47PM +0200, Luca Ceresoli wrote:
>> Hello Laurentiu,
>>
>> On Fri Apr 24, 2026 at 1:07 PM CEST, Laurentiu Palcu wrote:
>> > From: Sandor Yu <Sandor.yu@nxp.com>
>> >
>> > Add bindings for Freescale iMX8MQ DP and HDMI PHY.
>> >
>> > Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
>> > Signed-off-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
>> > ---
>> > .../bindings/phy/fsl,imx8mq-hdptx-phy.yaml | 80 ++++++++++++++++++++++
>> > 1 file changed, 80 insertions(+)
>> >
>> > diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-hdptx-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-hdptx-phy.yaml
>> > new file mode 100644
>> > index 0000000000000..a24435139b8b3
>> > --- /dev/null
>> > +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-hdptx-phy.yaml
>> > @@ -0,0 +1,80 @@
>> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> > +%YAML 1.2
>> > +---
>> > +$id: http://devicetree.org/schemas/phy/fsl,imx8mq-hdptx-phy.yaml#
>> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> > +
>> > +title: Cadence HDP-TX DP/HDMI PHY for Freescale i.MX8MQ SoC
>> > +
>> > +maintainers:
>> > + - Sandor Yu <sandor.yu@nxp.com>
>>
>> Based on what you said in the cover, I guess this line will have to be
>> changed. Are you willing to maintain this binding?
>
> Yes, I'll update it in the next iteration.
>
>>
>> > +description:
>> > + The Cadence HDP-TX DP/HDMI PHY is a child node of the MHDP8501 bridge,
>> > + sharing the same MMIO region as the parent bridge node.
>> > +
>> > +properties:
>> > + compatible:
>> > + const: fsl,imx8mq-hdptx-phy
>> > +
>> > + clocks:
>> > + items:
>> > + - description: PHY reference clock.
>> > + - description: APB clock.
>> > +
>> > + clock-names:
>> > + items:
>> > + - const: ref
>> > + - const: apb
>> > +
>> > + "#phy-cells":
>> > + const: 0
>> > +
>> > +required:
>> > + - compatible
>> > + - clocks
>> > + - clock-names
>> > + - "#phy-cells"
>> > +
>> > +additionalProperties: false
>> > +
>> > +examples:
>> > + - |
>> > + #include <dt-bindings/clock/imx8mq-clock.h>
>> > + #include <dt-bindings/interrupt-controller/arm-gic.h>
>> > +
>> > + display-bridge@32c00000 {
>> > + compatible = "fsl,imx8mq-mhdp8501";
>> > + reg = <0x32c00000 0x100000>;
>> > + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
>> > + <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
>> > + interrupt-names = "plug_in", "plug_out";
>> > + clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
>> > + phys = <&dp_phy>;
>> > +
>> > + ports {
>> > + #address-cells = <1>;
>> > + #size-cells = <0>;
>>
>> The ports are not mentioned in the properties. I'm not a DT maintainer, but
>> I think they should, e.g. to mention which port is the input and which is
>> the output.
>>
>> > +
>> > + port@0 {
>> > + reg = <0>;
>> > + endpoint {
>> > + remote-endpoint = <&dcss_out>;
>> > + };
>> > + };
>> > +
>> > + port@1 {
>> > + reg = <1>;
>> > + endpoint {
>> > + data-lanes = <2 1 0 3>;
>>
>> Having a remote-endpoint property would be nice here, to make the example
>> more complete.
>
> The ports and the remote endpoints are documented in the bridge binding...
Ah, my bad, I reviewed too quickly and mixed the phy and bridge bindings in
my mind, sorry.
>
> However, I believe I screwed this example up by adding the entire bridge node,
> instead of just a simple:
>
> mhdp {
> phy {
> compatible = "fsl,imx8mq-hdptx-phy";
> #phy-cells = <0>;
> clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
> clock-names = "ref", "apb";
> };
> };
>
> I'll simplify the example in the next iteration.
Yes, I think it would make sense to do it.
Thanks,
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 4/4] phy: qualcomm: qmp-combo: Add support for Hawi SoC
From: Dmitry Baryshkov @ 2026-04-28 11:40 UTC (permalink / raw)
To: Ronak Raheja
Cc: vkoul, krzk+dt, conor+dt, robh, neil.armstrong, gregkh,
konrad.dybcio, abel.vesa, wesley.cheng, krzysztof.kozlowski,
linux-arm-msm, linux-phy, devicetree, linux-usb, linux-kernel
In-Reply-To: <20260427214217.2735240-5-ronak.raheja@oss.qualcomm.com>
On Mon, Apr 27, 2026 at 02:42:17PM -0700, Ronak Raheja wrote:
> Add support for the USB3-DP combo PHY found on Hawi platform.
>
> The QMP PHY for Hawi uses QSERDES V10 register layouts. Add the required
> PHY sequences from the hardware programming guide and new V10 register
> header files. Also add a new v10 offset structure to incorporate the new
> COM AON register module.
Was this tested with the DP too or did you test only the USB part?
>
> Signed-off-by: Ronak Raheja <ronak.raheja@oss.qualcomm.com>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> ---
> .../phy/qualcomm/phy-qcom-qmp-com-aon-v10.h | 15 ++
> drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 231 +++++++++++++++++-
> .../phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h | 15 ++
> .../phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h | 13 +
> .../phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h | 19 ++
> drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h | 34 +++
> .../qualcomm/phy-qcom-qmp-qserdes-com-v10.h | 89 +++++++
> .../qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h | 89 +++++++
> drivers/phy/qualcomm/phy-qcom-qmp.h | 5 +
> 9 files changed, 506 insertions(+), 4 deletions(-)
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-com-aon-v10.h
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h
>
> @@ -2198,6 +2368,7 @@ struct qmp_combo_offsets {
> u16 dp_txa;
> u16 dp_txb;
> u16 dp_dp_phy;
> + u16 aon_toggle;
Are there (or will there) be any other regs? Is it just one-register
space?
> };
>
> struct qmp_phy_cfg {
> @@ -2705,6 +2895,27 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = {
> .regs = qmp_v6_n4_usb3phy_regs_layout,
> };
>
> +static const struct qmp_phy_cfg hawi_usb3dpphy_cfg = {
> + .offsets = &qmp_combo_offsets_v10,
> +
> + .serdes_tbl = hawi_usb3_serdes_tbl,
> + .serdes_tbl_num = ARRAY_SIZE(hawi_usb3_serdes_tbl),
> + .tx_tbl = hawi_usb3_tx_tbl,
> + .tx_tbl_num = ARRAY_SIZE(hawi_usb3_tx_tbl),
> + .rx_tbl = hawi_usb3_rx_tbl,
> + .rx_tbl_num = ARRAY_SIZE(hawi_usb3_rx_tbl),
> + .pcs_tbl = hawi_usb3_pcs_tbl,
> + .pcs_tbl_num = ARRAY_SIZE(hawi_usb3_pcs_tbl),
> + .pcs_usb_tbl = hawi_usb3_pcs_usb_tbl,
> + .pcs_usb_tbl_num = ARRAY_SIZE(hawi_usb3_pcs_usb_tbl),
> +
> + .regs = qmp_v10_usb3phy_regs_layout,
> + .reset_list = msm8996_usb3phy_reset_l,
> + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
> + .vreg_list = qmp_phy_vreg_l,
> + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
No DP counterpart and no mention of it in the commit message.
> +};
> +
> static const struct qmp_phy_cfg sm6350_usb3dpphy_cfg = {
> .offsets = &qmp_combo_offsets_v3,
>
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
From: Biju Das @ 2026-04-28 9:38 UTC (permalink / raw)
To: Ovidiu Panait, vkoul@kernel.org, neil.armstrong@linaro.org
Cc: linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <TY7P301MB198432F1681EFA444D16F824D3372@TY7P301MB1984.JPNP301.PROD.OUTLOOK.COM>
Hi Ovidiu,
> -----Original Message-----
> From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> Sent: 28 April 2026 10:21
> Subject: RE: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
>
> Hi Biju,
>
> >
> > Hi Ovidiu,
> >
> > Thanks for the patch
> >
> > > -----Original Message-----
> > > From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> > > Sent: 27 April 2026 20:48
> > > Subject: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM
> > > underflow
> > during suspend
> > >
> > > On the Renesas RZ/V2H platform, if the xhcd driver is unbound and
> > > the
> > system is suspended afterwards, a
> > > PM underflow error will occur:
> > >
> > > # echo 15850000.usb >
> > > /sys/bus/platform/drivers/xhci-renesas-hcd/unbind
> > > # systemctl suspend
> > > 15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq
> > > returns -
> > 13
> > > 15870000.usb-phy: PM: failed to resume noirq: error -13
> > > 15870000.usb-phy: Runtime PM usage count underflow!
> > >
> > > Since the PHY framework is managing the runtime PM of the PHY via
> > phy_power_on()/phy_power_off(), there
> > > is no need for the PHY driver to manipulate the runtime PM state
> > > during
> > suspend.
> > >
> > > To fix this, remove the runtime PM calls from the suspend/resume
> > > paths
> > and add a get/put pair inside
> > > rzg3e_phy_usb3_init_helper() to make sure the clock is enabled
> > > during
> > init, even when there is no
> > > consumer for the PHY.
> > >
> > > Also, change the suspend ops from NOIRQ_SYSTEM_SLEEP_PM_OPS to
> > SYSTEM_SLEEP_PM_OPS because runtime PM
> > > is disabled during the noirq phase and pm_runtime_resume_and_get()
> > > would
> > not actually enable the device
> > > clock.
> > >
> > > Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY
> > driver")
> > > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> > > ---
> > > drivers/phy/renesas/phy-rzg3e-usb3.c | 31
> > > ++++++++++++++++------------
> > > 1 file changed, 18 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c
> > b/drivers/phy/renesas/phy-rzg3e-usb3.c
> > > index 6b3453ea0004..055775e1a0f7 100644
> > > --- a/drivers/phy/renesas/phy-rzg3e-usb3.c
> > > +++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
> > > @@ -64,6 +64,7 @@
> > > #define USB3_TEST_LANECONFIG0_DEFAULT (0xd)
> > >
> > > struct rz_usb3 {
> > > + struct device *dev;
> >
> > Do you need dev as struct phy has dev member [1]?
> >
> > [1]
> > https://elixir.bootlin.com/linux/v6.0-
> > rc4/source/include/linux/phy/phy.h#L153
> >
> > > void __iomem *base;
> > > struct reset_control *rstc;
> > > bool skip_reinit;
> > > @@ -130,11 +131,21 @@ static int rzg3e_phy_usb3test_phy_init(void
> > __iomem *base)
> > > return 0;
> > > }
> > >
> > > -static int rzg3e_phy_usb3_init_helper(void __iomem *base)
> >
> > you can add one more function parameter dev here.
> >
> > static int rzg3e_phy_usb3_init_helper(struct device *dev, void __iomem
> > *base)
> >
> > > +static int rzg3e_phy_usb3_init_helper(struct rz_usb3 *r)
> > > {
> > > - rzg3e_phy_usb2test_phy_init(base);
> > > + int ret;
> > > +
> > > + ret = pm_runtime_resume_and_get(r->dev);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + rzg3e_phy_usb2test_phy_init(r->base);
> > >
> > > - return rzg3e_phy_usb3test_phy_init(base);
> > > + ret = rzg3e_phy_usb3test_phy_init(r->base);
> > > +
> > > + pm_runtime_put_sync(r->dev);
> > > +
> > > + return ret;
> > > }
> > >
> > > static int rzg3e_phy_usb3_init(struct phy *p) @@ -143,7 +154,7 @@
> > static int
> > > rzg3e_phy_usb3_init(struct phy *p)
> > > int ret = 0;
> > >
> > > if (!r->skip_reinit)
> > > - ret = rzg3e_phy_usb3_init_helper(r->base);
> > > + ret = rzg3e_phy_usb3_init_helper(r);
> >
> > ret = rzg3e_phy_usb3_init_helper(&p->dev, r->base);
> >
> > >
> > > return ret;
> > > }
> > > @@ -187,6 +198,7 @@ static int rzg3e_phy_usb3_probe(struct
> > platform_device *pdev)
> > >
> > > platform_set_drvdata(pdev, r);
> >
> > > phy_set_drvdata(phy, r);
> > > + r->dev = dev;
> >
> > Drop this.
> >
> > >
> > > provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > > if (IS_ERR(provider))
> > > @@ -199,7 +211,6 @@ static int rzg3e_phy_usb3_suspend(struct device
> > *dev) {
> > > struct rz_usb3 *r = dev_get_drvdata(dev);
> > >
> > > - pm_runtime_put(dev);
> > > reset_control_assert(r->rstc);
> > > r->skip_reinit = false;
> > >
> > > @@ -215,27 +226,21 @@ static int rzg3e_phy_usb3_resume(struct device
> > *dev)
> > > if (ret)
> > > return ret;
> > >
> > > - ret = pm_runtime_resume_and_get(dev);
> > > + ret = rzg3e_phy_usb3_init_helper(r);
> >
> > ret = rzg3e_phy_usb3_init_helper(dev, r->base);
>
> "dev" is the platform device, which is different from phy->dev. Phy->dev is a child of the platform
> device.
You are correct. I missed that.
>
> We could be referencing the platform device from phy->dev with &phy->dev.parent, but I don't think that
> will make the code cleaner.
Thought of avoiding another global variable that saves 4 bytes.
Changing "&phy->dev"->""&phy->dev.parent" is not making the code cleaner
then leave as it is.
Cheers,
Biju
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
From: Ovidiu Panait @ 2026-04-28 9:21 UTC (permalink / raw)
To: Biju Das, vkoul@kernel.org, neil.armstrong@linaro.org
Cc: linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <TY3PR01MB11346819FE6253E90C7B4F88486372@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi Biju,
>
> Hi Ovidiu,
>
> Thanks for the patch
>
> > -----Original Message-----
> > From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> > Sent: 27 April 2026 20:48
> > Subject: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow
> during suspend
> >
> > On the Renesas RZ/V2H platform, if the xhcd driver is unbound and the
> system is suspended afterwards, a
> > PM underflow error will occur:
> >
> > # echo 15850000.usb > /sys/bus/platform/drivers/xhci-renesas-hcd/unbind
> > # systemctl suspend
> > 15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq returns -
> 13
> > 15870000.usb-phy: PM: failed to resume noirq: error -13
> > 15870000.usb-phy: Runtime PM usage count underflow!
> >
> > Since the PHY framework is managing the runtime PM of the PHY via
> phy_power_on()/phy_power_off(), there
> > is no need for the PHY driver to manipulate the runtime PM state during
> suspend.
> >
> > To fix this, remove the runtime PM calls from the suspend/resume paths
> and add a get/put pair inside
> > rzg3e_phy_usb3_init_helper() to make sure the clock is enabled during
> init, even when there is no
> > consumer for the PHY.
> >
> > Also, change the suspend ops from NOIRQ_SYSTEM_SLEEP_PM_OPS to
> SYSTEM_SLEEP_PM_OPS because runtime PM
> > is disabled during the noirq phase and pm_runtime_resume_and_get() would
> not actually enable the device
> > clock.
> >
> > Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY
> driver")
> > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> > ---
> > drivers/phy/renesas/phy-rzg3e-usb3.c | 31 ++++++++++++++++------------
> > 1 file changed, 18 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c
> b/drivers/phy/renesas/phy-rzg3e-usb3.c
> > index 6b3453ea0004..055775e1a0f7 100644
> > --- a/drivers/phy/renesas/phy-rzg3e-usb3.c
> > +++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
> > @@ -64,6 +64,7 @@
> > #define USB3_TEST_LANECONFIG0_DEFAULT (0xd)
> >
> > struct rz_usb3 {
> > + struct device *dev;
>
> Do you need dev as struct phy has dev member [1]?
>
> [1]
> https://elixir.bootlin.com/linux/v6.0-
> rc4/source/include/linux/phy/phy.h#L153
>
> > void __iomem *base;
> > struct reset_control *rstc;
> > bool skip_reinit;
> > @@ -130,11 +131,21 @@ static int rzg3e_phy_usb3test_phy_init(void
> __iomem *base)
> > return 0;
> > }
> >
> > -static int rzg3e_phy_usb3_init_helper(void __iomem *base)
>
> you can add one more function parameter dev here.
>
> static int rzg3e_phy_usb3_init_helper(struct device *dev, void __iomem
> *base)
>
> > +static int rzg3e_phy_usb3_init_helper(struct rz_usb3 *r)
> > {
> > - rzg3e_phy_usb2test_phy_init(base);
> > + int ret;
> > +
> > + ret = pm_runtime_resume_and_get(r->dev);
> > + if (ret)
> > + return ret;
> > +
> > + rzg3e_phy_usb2test_phy_init(r->base);
> >
> > - return rzg3e_phy_usb3test_phy_init(base);
> > + ret = rzg3e_phy_usb3test_phy_init(r->base);
> > +
> > + pm_runtime_put_sync(r->dev);
> > +
> > + return ret;
> > }
> >
> > static int rzg3e_phy_usb3_init(struct phy *p) @@ -143,7 +154,7 @@
> static int
> > rzg3e_phy_usb3_init(struct phy *p)
> > int ret = 0;
> >
> > if (!r->skip_reinit)
> > - ret = rzg3e_phy_usb3_init_helper(r->base);
> > + ret = rzg3e_phy_usb3_init_helper(r);
>
> ret = rzg3e_phy_usb3_init_helper(&p->dev, r->base);
>
> >
> > return ret;
> > }
> > @@ -187,6 +198,7 @@ static int rzg3e_phy_usb3_probe(struct
> platform_device *pdev)
> >
> > platform_set_drvdata(pdev, r);
>
> > phy_set_drvdata(phy, r);
> > + r->dev = dev;
>
> Drop this.
>
> >
> > provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > if (IS_ERR(provider))
> > @@ -199,7 +211,6 @@ static int rzg3e_phy_usb3_suspend(struct device
> *dev) {
> > struct rz_usb3 *r = dev_get_drvdata(dev);
> >
> > - pm_runtime_put(dev);
> > reset_control_assert(r->rstc);
> > r->skip_reinit = false;
> >
> > @@ -215,27 +226,21 @@ static int rzg3e_phy_usb3_resume(struct device
> *dev)
> > if (ret)
> > return ret;
> >
> > - ret = pm_runtime_resume_and_get(dev);
> > + ret = rzg3e_phy_usb3_init_helper(r);
>
> ret = rzg3e_phy_usb3_init_helper(dev, r->base);
"dev" is the platform device, which is different from phy->dev. Phy->dev
is a child of the platform device.
We could be referencing the platform device from phy->dev with &phy->dev.parent,
but I don't think that will make the code cleaner.
Considering this, I think the current implementation is fine.
Ovidiu
>
> With the above addressed,
>
> Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
>
> Cheers,
> Biju
>
> > if (ret)
> > goto reset_assert;
> >
> > - ret = rzg3e_phy_usb3_init_helper(r->base);
> > - if (ret)
> > - goto pm_put;
> > -
> > r->skip_reinit = true;
> >
> > return 0;
> >
> > -pm_put:
> > - pm_runtime_put(dev);
> > reset_assert:
> > reset_control_assert(r->rstc);
> > return ret;
> > }
> >
> > static const struct dev_pm_ops rzg3e_phy_usb3_pm = {
> > - NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend,
> rzg3e_phy_usb3_resume)
> > + SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
> > };
> >
> > static const struct of_device_id rzg3e_phy_usb3_match_table[] = {
> > --
> > 2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 4/4] phy: qualcomm: qmp-combo: Add support for Hawi SoC
From: Abel Vesa @ 2026-04-28 8:32 UTC (permalink / raw)
To: Ronak Raheja
Cc: vkoul, krzk+dt, conor+dt, robh, neil.armstrong, gregkh,
dmitry.baryshkov, konrad.dybcio, wesley.cheng,
krzysztof.kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-usb, linux-kernel
In-Reply-To: <20260427214217.2735240-5-ronak.raheja@oss.qualcomm.com>
On 26-04-27 14:42:17, Ronak Raheja wrote:
> Add support for the USB3-DP combo PHY found on Hawi platform.
>
> The QMP PHY for Hawi uses QSERDES V10 register layouts. Add the required
> PHY sequences from the hardware programming guide and new V10 register
> header files. Also add a new v10 offset structure to incorporate the new
> COM AON register module.
>
> Signed-off-by: Ronak Raheja <ronak.raheja@oss.qualcomm.com>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2] dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: Document Nord QMP UFS PHY
From: Krzysztof Kozlowski @ 2026-04-28 6:23 UTC (permalink / raw)
To: Shawn Guo
Cc: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Konrad Dybcio, Dmitry Baryshkov, Bartosz Golaszewski,
Deepti Jaggi, linux-phy, devicetree, linux-arm-msm, linux-kernel
In-Reply-To: <20260427012732.231611-1-shengchao.guo@oss.qualcomm.com>
On Mon, Apr 27, 2026 at 09:27:32AM +0800, Shawn Guo wrote:
> Document QMP UFS PHY on Qualcomm Nord SoC which is compatible with
> 'qcom,sm8650-qmp-ufs-phy'.
Why are you naming compatibles not devices in the commit msgs? We never
used, never asked for it, there are basically no such commits. git log
can help here, for example last commit from Abel looks reasonable
(although repeating "so use fallback" is redundant - it's obvious).
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
From: Biju Das @ 2026-04-28 6:17 UTC (permalink / raw)
To: Ovidiu Panait, vkoul@kernel.org, neil.armstrong@linaro.org
Cc: linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, Ovidiu Panait
In-Reply-To: <20260427194741.161533-1-ovidiu.panait.rb@renesas.com>
Hi Ovidiu,
Thanks for the patch
> -----Original Message-----
> From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> Sent: 27 April 2026 20:48
> Subject: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
>
> On the Renesas RZ/V2H platform, if the xhcd driver is unbound and the system is suspended afterwards, a
> PM underflow error will occur:
>
> # echo 15850000.usb > /sys/bus/platform/drivers/xhci-renesas-hcd/unbind
> # systemctl suspend
> 15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq returns -13
> 15870000.usb-phy: PM: failed to resume noirq: error -13
> 15870000.usb-phy: Runtime PM usage count underflow!
>
> Since the PHY framework is managing the runtime PM of the PHY via phy_power_on()/phy_power_off(), there
> is no need for the PHY driver to manipulate the runtime PM state during suspend.
>
> To fix this, remove the runtime PM calls from the suspend/resume paths and add a get/put pair inside
> rzg3e_phy_usb3_init_helper() to make sure the clock is enabled during init, even when there is no
> consumer for the PHY.
>
> Also, change the suspend ops from NOIRQ_SYSTEM_SLEEP_PM_OPS to SYSTEM_SLEEP_PM_OPS because runtime PM
> is disabled during the noirq phase and pm_runtime_resume_and_get() would not actually enable the device
> clock.
>
> Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY driver")
> Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> ---
> drivers/phy/renesas/phy-rzg3e-usb3.c | 31 ++++++++++++++++------------
> 1 file changed, 18 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c b/drivers/phy/renesas/phy-rzg3e-usb3.c
> index 6b3453ea0004..055775e1a0f7 100644
> --- a/drivers/phy/renesas/phy-rzg3e-usb3.c
> +++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
> @@ -64,6 +64,7 @@
> #define USB3_TEST_LANECONFIG0_DEFAULT (0xd)
>
> struct rz_usb3 {
> + struct device *dev;
Do you need dev as struct phy has dev member [1]?
[1]
https://elixir.bootlin.com/linux/v6.0-rc4/source/include/linux/phy/phy.h#L153
> void __iomem *base;
> struct reset_control *rstc;
> bool skip_reinit;
> @@ -130,11 +131,21 @@ static int rzg3e_phy_usb3test_phy_init(void __iomem *base)
> return 0;
> }
>
> -static int rzg3e_phy_usb3_init_helper(void __iomem *base)
you can add one more function parameter dev here.
static int rzg3e_phy_usb3_init_helper(struct device *dev, void __iomem *base)
> +static int rzg3e_phy_usb3_init_helper(struct rz_usb3 *r)
> {
> - rzg3e_phy_usb2test_phy_init(base);
> + int ret;
> +
> + ret = pm_runtime_resume_and_get(r->dev);
> + if (ret)
> + return ret;
> +
> + rzg3e_phy_usb2test_phy_init(r->base);
>
> - return rzg3e_phy_usb3test_phy_init(base);
> + ret = rzg3e_phy_usb3test_phy_init(r->base);
> +
> + pm_runtime_put_sync(r->dev);
> +
> + return ret;
> }
>
> static int rzg3e_phy_usb3_init(struct phy *p) @@ -143,7 +154,7 @@ static int
> rzg3e_phy_usb3_init(struct phy *p)
> int ret = 0;
>
> if (!r->skip_reinit)
> - ret = rzg3e_phy_usb3_init_helper(r->base);
> + ret = rzg3e_phy_usb3_init_helper(r);
ret = rzg3e_phy_usb3_init_helper(&p->dev, r->base);
>
> return ret;
> }
> @@ -187,6 +198,7 @@ static int rzg3e_phy_usb3_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, r);
> phy_set_drvdata(phy, r);
> + r->dev = dev;
Drop this.
>
> provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> if (IS_ERR(provider))
> @@ -199,7 +211,6 @@ static int rzg3e_phy_usb3_suspend(struct device *dev) {
> struct rz_usb3 *r = dev_get_drvdata(dev);
>
> - pm_runtime_put(dev);
> reset_control_assert(r->rstc);
> r->skip_reinit = false;
>
> @@ -215,27 +226,21 @@ static int rzg3e_phy_usb3_resume(struct device *dev)
> if (ret)
> return ret;
>
> - ret = pm_runtime_resume_and_get(dev);
> + ret = rzg3e_phy_usb3_init_helper(r);
ret = rzg3e_phy_usb3_init_helper(dev, r->base);
With the above addressed,
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Cheers,
Biju
> if (ret)
> goto reset_assert;
>
> - ret = rzg3e_phy_usb3_init_helper(r->base);
> - if (ret)
> - goto pm_put;
> -
> r->skip_reinit = true;
>
> return 0;
>
> -pm_put:
> - pm_runtime_put(dev);
> reset_assert:
> reset_control_assert(r->rstc);
> return ret;
> }
>
> static const struct dev_pm_ops rzg3e_phy_usb3_pm = {
> - NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
> + SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
> };
>
> static const struct of_device_id rzg3e_phy_usb3_match_table[] = {
> --
> 2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH 4/4] phy: qualcomm: qmp-combo: Add support for Hawi SoC
From: Ronak Raheja @ 2026-04-27 21:42 UTC (permalink / raw)
To: vkoul, krzk+dt, conor+dt, robh, neil.armstrong, gregkh
Cc: dmitry.baryshkov, konrad.dybcio, abel.vesa, wesley.cheng,
krzysztof.kozlowski, ronak.raheja, linux-arm-msm, linux-phy,
devicetree, linux-usb, linux-kernel
In-Reply-To: <20260427214217.2735240-1-ronak.raheja@oss.qualcomm.com>
Add support for the USB3-DP combo PHY found on Hawi platform.
The QMP PHY for Hawi uses QSERDES V10 register layouts. Add the required
PHY sequences from the hardware programming guide and new V10 register
header files. Also add a new v10 offset structure to incorporate the new
COM AON register module.
Signed-off-by: Ronak Raheja <ronak.raheja@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
---
.../phy/qualcomm/phy-qcom-qmp-com-aon-v10.h | 15 ++
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 231 +++++++++++++++++-
.../phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h | 15 ++
.../phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h | 13 +
.../phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h | 19 ++
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h | 34 +++
.../qualcomm/phy-qcom-qmp-qserdes-com-v10.h | 89 +++++++
.../qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h | 89 +++++++
drivers/phy/qualcomm/phy-qcom-qmp.h | 5 +
9 files changed, 506 insertions(+), 4 deletions(-)
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-com-aon-v10.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-com-aon-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-com-aon-v10.h
new file mode 100644
index 000000000000..6542b586be89
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-com-aon-v10.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_COM_AON_V10_H_
+#define QCOM_PHY_QMP_COM_AON_V10_H_
+
+/* Only for QMP V10 PHY - COM AON registers */
+
+#define QPHY_V10_COM_AON_USB3_AON_TOGGLE_ENABLE 0x00
+#define QPHY_V10_COM_AON_DP_AON_TOGGLE_ENABLE 0x04
+#define QPHY_V10_COM_AON_DUMMY_STATUS 0x08
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 93f1aa10d400..53b709ea93d5 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -32,6 +32,7 @@
#include "phy-qcom-qmp.h"
#include "phy-qcom-qmp-pcs-aon-v6.h"
#include "phy-qcom-qmp-pcs-aon-v8.h"
+#include "phy-qcom-qmp-pcs-aon-v10.h"
#include "phy-qcom-qmp-pcs-misc-v3.h"
#include "phy-qcom-qmp-pcs-misc-v4.h"
#include "phy-qcom-qmp-pcs-misc-v5.h"
@@ -40,6 +41,7 @@
#include "phy-qcom-qmp-pcs-usb-v5.h"
#include "phy-qcom-qmp-pcs-usb-v6.h"
#include "phy-qcom-qmp-pcs-usb-v8.h"
+#include "phy-qcom-qmp-pcs-usb-v10.h"
#include "phy-qcom-qmp-dp-com-v3.h"
@@ -49,9 +51,12 @@
#include "phy-qcom-qmp-dp-phy-v5.h"
#include "phy-qcom-qmp-dp-phy-v6.h"
#include "phy-qcom-qmp-dp-phy-v8.h"
+#include "phy-qcom-qmp-dp-phy-v10.h"
#include "phy-qcom-qmp-usb43-pcs-v8.h"
+#include "phy-qcom-qmp-com-aon-v10.h"
+
/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
/* DP PHY soft reset */
#define SW_DPPHY_RESET BIT(0)
@@ -268,6 +273,36 @@ static const unsigned int qmp_v8_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_TX_TRANSCEIVER_BIAS_EN,
};
+static const unsigned int qmp_v10_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_SW_RESET] = QPHY_V10_PCS_SW_RESET,
+ [QPHY_START_CTRL] = QPHY_V10_PCS_START_CONTROL,
+ [QPHY_PCS_STATUS] = QPHY_V10_PCS_PCS_STATUS1,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V10_PCS_POWER_DOWN_CONTROL,
+
+ /* In PCS_USB */
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V10_PCS_USB3_AUTONOMOUS_MODE_CTRL,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V10_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
+
+ [QPHY_PCS_CLAMP_ENABLE] = QPHY_V10_PCS_AON_CLAMP_ENABLE,
+
+ [QPHY_AON_TOGGLE_ENABLE] = QPHY_V10_COM_AON_USB3_AON_TOGGLE_ENABLE,
+ [QPHY_DP_AON_TOGGLE_ENABLE] = QPHY_V10_COM_AON_DP_AON_TOGGLE_ENABLE,
+
+ [QPHY_COM_RESETSM_CNTRL] = QSERDES_V10_COM_RESETSM_CNTRL,
+ [QPHY_COM_C_READY_STATUS] = QSERDES_V10_COM_C_READY_STATUS,
+ [QPHY_COM_CMN_STATUS] = QSERDES_V10_COM_CMN_STATUS,
+ [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V10_COM_BIAS_EN_CLKBUFLR_EN,
+
+ [QPHY_DP_PHY_STATUS] = QSERDES_V10_DP_PHY_STATUS,
+ [QPHY_DP_PHY_VCO_DIV] = QSERDES_V10_DP_PHY_VCO_DIV,
+
+ [QPHY_TX_TX_POL_INV] = QSERDES_V10_TX_TX_POL_INV,
+ [QPHY_TX_TX_DRV_LVL] = QSERDES_V10_TX_TX_DRV_LVL,
+ [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V10_TX_TX_EMP_POST1_LVL,
+ [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V10_TX_HIGHZ_DRVR_EN,
+ [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V10_TX_TRANSCEIVER_BIAS_EN,
+};
+
static const unsigned int qmp_v8_n3_usb43dpphy_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_SW_RESET] = QPHY_V8_USB43_PCS_SW_RESET,
[QPHY_START_CTRL] = QPHY_V8_USB43_PCS_START_CONTROL,
@@ -2058,6 +2093,141 @@ static const struct qmp_phy_init_tbl x1e80100_usb43dp_pcs_usb_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
};
+static const struct qmp_phy_init_tbl hawi_usb3_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE1, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORECLK_DIV_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE1, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE1, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MSB_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE1, 0x75),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_HSCLK_SEL_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE1_MODE1, 0x25),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE2_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE0, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE0, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE0, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MSB_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE0, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE0, 0x75),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE1_MODE0, 0x25),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER1, 0x62),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER2, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYSCLK_BUF_ENABLE, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYSCLK_EN_SEL, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP_CFG, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORE_CLK_EN, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_3, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V10_COM_ADDITIONAL_MISC, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl hawi_usb3_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_TX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_RX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_1, 0xe5),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_2, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_3, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_4, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_5, 0x5d),
+ QMP_PHY_INIT_CFG(QSERDES_V10_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V10_TX_PI_QEC_CTRL, 0x21, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V10_TX_PI_QEC_CTRL, 0x05, 2),
+};
+
+static const struct qmp_phy_init_tbl hawi_usb3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FO_GAIN, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SO_GAIN, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_PI_CONTROLS, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_GAIN1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_GAIN2, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_AUX_DATA_TCOARSE_TFINE, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_VGA_CAL_CNTRL1, 0x54),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_VGA_CAL_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_GM_CAL, 0x13),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_IDAC_TSETTLE_LOW, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_ENABLES, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CNTRL, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_LOW, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH2, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH3, 0xdf),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH4, 0xed),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_LOW, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH2, 0x91),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH3, 0xb7),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH4, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_DCC_CTRL1, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_VTH_CODE, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CAL_CTRL1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CAL_TRIM, 0x08),
+};
+
+static const struct qmp_phy_init_tbl hawi_usb3_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG1, 0xc4),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG2, 0x89),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG3, 0x20),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG6, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_REFGEN_REQ_CONFIG1, 0x21),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_RX_SIGDET_LVL, 0x55),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_RX_CONFIG, 0x0a),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_ALIGN_DETECT_CONFIG1, 0x88),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_ALIGN_DETECT_CONFIG2, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_PCS_TX_RX_CONFIG, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_PCS_TX_RX_CONFIG2, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_EQ_CONFIG1, 0x4b),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_EQ_CONFIG5, 0x10),
+};
+
+static const struct qmp_phy_init_tbl hawi_usb3_pcs_usb_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
+};
+
/* list of regulators */
static struct regulator_bulk_data qmp_phy_vreg_l[] = {
{ .supply = "vdda-phy", .init_load_uA = 21800, },
@@ -2198,6 +2368,7 @@ struct qmp_combo_offsets {
u16 dp_txa;
u16 dp_txb;
u16 dp_dp_phy;
+ u16 aon_toggle;
};
struct qmp_phy_cfg {
@@ -2270,6 +2441,7 @@ struct qmp_combo {
const struct qmp_phy_cfg *cfg;
void __iomem *com;
+ void __iomem *aon_toggle;
void __iomem *serdes;
void __iomem *tx;
@@ -2416,6 +2588,24 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = {
.dp_dp_phy = 0x3c00,
};
+static const struct qmp_combo_offsets qmp_combo_offsets_v10 = {
+ .com = 0x0000,
+ .aon_toggle = 0x0400,
+ .txa = 0x1400,
+ .rxa = 0x1600,
+ .txb = 0x1800,
+ .rxb = 0x1a00,
+ .usb3_serdes = 0x1000,
+ .usb3_pcs_misc = 0x1c00,
+ .usb3_pcs = 0x1e00,
+ .usb3_pcs_aon = 0x2000,
+ .usb3_pcs_usb = 0x2100,
+ .dp_serdes = 0x3000,
+ .dp_txa = 0x3400,
+ .dp_txb = 0x3800,
+ .dp_dp_phy = 0x3c00,
+};
+
static const struct qmp_combo_offsets qmp_combo_usb43dp_offsets_v8 = {
.com = 0x0000,
.usb3_pcs_aon = 0x0100,
@@ -2705,6 +2895,27 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = {
.regs = qmp_v6_n4_usb3phy_regs_layout,
};
+static const struct qmp_phy_cfg hawi_usb3dpphy_cfg = {
+ .offsets = &qmp_combo_offsets_v10,
+
+ .serdes_tbl = hawi_usb3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(hawi_usb3_serdes_tbl),
+ .tx_tbl = hawi_usb3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(hawi_usb3_tx_tbl),
+ .rx_tbl = hawi_usb3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(hawi_usb3_rx_tbl),
+ .pcs_tbl = hawi_usb3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(hawi_usb3_pcs_tbl),
+ .pcs_usb_tbl = hawi_usb3_pcs_usb_tbl,
+ .pcs_usb_tbl_num = ARRAY_SIZE(hawi_usb3_pcs_usb_tbl),
+
+ .regs = qmp_v10_usb3phy_regs_layout,
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+};
+
static const struct qmp_phy_cfg sm6350_usb3dpphy_cfg = {
.offsets = &qmp_combo_offsets_v3,
@@ -3662,13 +3873,18 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
void __iomem *com = qmp->com;
- void __iomem *pcs_aon = qmp->pcs_aon;
+ void __iomem *aon_toggle;
int ret;
u32 val;
if (!force && qmp->init_count++)
return 0;
+ if (qmp->aon_toggle)
+ aon_toggle = qmp->aon_toggle;
+ else
+ aon_toggle = qmp->pcs_aon;
+
ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
if (ret) {
dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
@@ -3699,9 +3915,9 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
/* override hardware control for reset of qmp phy */
- if (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) {
- qphy_clrbits(pcs_aon, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1);
- qphy_clrbits(pcs_aon, cfg->regs[QPHY_DP_AON_TOGGLE_ENABLE], 0x1);
+ if (aon_toggle && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) {
+ qphy_clrbits(aon_toggle, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1);
+ qphy_clrbits(aon_toggle, cfg->regs[QPHY_DP_AON_TOGGLE_ENABLE], 0x1);
}
/* Use software based port select and switch on typec orientation */
@@ -4733,6 +4949,9 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp)
}
qmp->dp_dp_phy = base + offs->dp_dp_phy;
+ if (offs->aon_toggle)
+ qmp->aon_toggle = base + offs->aon_toggle;
+
ret = qmp_combo_clk_init(qmp);
if (ret)
return ret;
@@ -4986,6 +5205,10 @@ static const struct of_device_id qmp_combo_of_match_table[] = {
.compatible = "qcom,glymur-qmp-usb3-dp-phy",
.data = &glymur_usb3dpphy_cfg,
},
+ {
+ .compatible = "qcom,hawi-qmp-usb3-dp-phy",
+ .data = &hawi_usb3dpphy_cfg,
+ },
{
.compatible = "qcom,sar2130p-qmp-usb3-dp-phy",
.data = &sar2130p_usb3dpphy_cfg,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h
new file mode 100644
index 000000000000..6f3ea7d13556
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_DP_PHY_V10_H_
+#define QCOM_PHY_QMP_DP_PHY_V10_H_
+
+/* Only for QMP V10 PHY - DP PHY registers */
+
+#define QSERDES_V10_DP_PHY_VCO_DIV 0x070
+#define QSERDES_V10_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0
+#define QSERDES_V10_DP_PHY_STATUS 0x0e4
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h
new file mode 100644
index 000000000000..b858381bc238
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_AON_V10_H_
+#define QCOM_PHY_QMP_PCS_AON_V10_H_
+
+/* Only for QMP V10 PHY - PCS AON registers */
+
+#define QPHY_V10_PCS_AON_CLAMP_ENABLE 0x00
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h
new file mode 100644
index 000000000000..0cc25e6acf58
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_USB_V10_H_
+#define QCOM_PHY_QMP_PCS_USB_V10_H_
+
+/* Only for QMP V10 PHY - USB PCS registers */
+
+#define QPHY_V10_PCS_USB3_POWER_STATE_CONFIG1 0x00
+#define QPHY_V10_PCS_USB3_AUTONOMOUS_MODE_CTRL 0x08
+#define QPHY_V10_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR 0x14
+#define QPHY_V10_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL 0x18
+#define QPHY_V10_PCS_USB3_RXEQTRAINING_DFE_TIME_S2 0x3c
+#define QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x40
+#define QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_H 0x44
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h
new file mode 100644
index 000000000000..ac0fc434984b
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V10_H_
+#define QCOM_PHY_QMP_PCS_V10_H_
+
+/* Only for QMP V10 PHY - PCS registers */
+
+#define QPHY_V10_PCS_SW_RESET 0x000
+#define QPHY_V10_PCS_PCS_STATUS1 0x014
+#define QPHY_V10_PCS_POWER_DOWN_CONTROL 0x040
+#define QPHY_V10_PCS_START_CONTROL 0x044
+#define QPHY_V10_PCS_POWER_STATE_CONFIG1 0x090
+#define QPHY_V10_PCS_LOCK_DETECT_CONFIG1 0x0c4
+#define QPHY_V10_PCS_LOCK_DETECT_CONFIG2 0x0c8
+#define QPHY_V10_PCS_LOCK_DETECT_CONFIG3 0x0cc
+#define QPHY_V10_PCS_LOCK_DETECT_CONFIG6 0x0d8
+#define QPHY_V10_PCS_REFGEN_REQ_CONFIG1 0x0dc
+#define QPHY_V10_PCS_RX_SIGDET_LVL 0x188
+#define QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_L 0x190
+#define QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
+#define QPHY_V10_PCS_RATE_SLEW_CNTRL1 0x198
+#define QPHY_V10_PCS_RX_CONFIG 0x1b0
+#define QPHY_V10_PCS_ALIGN_DETECT_CONFIG1 0x1c0
+#define QPHY_V10_PCS_ALIGN_DETECT_CONFIG2 0x1c4
+#define QPHY_V10_PCS_PCS_TX_RX_CONFIG 0x1d0
+#define QPHY_V10_PCS_PCS_TX_RX_CONFIG2 0x1d4
+#define QPHY_V10_PCS_EQ_CONFIG1 0x1e0
+#define QPHY_V10_PCS_EQ_CONFIG2 0x1e4
+#define QPHY_V10_PCS_EQ_CONFIG5 0x1f0
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h
new file mode 100644
index 000000000000..92fbde7c9c7c
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_COM_V10_H_
+#define QCOM_PHY_QMP_QSERDES_COM_V10_H_
+
+/* Only for QMP V10 PHY - QSERDES COM registers */
+
+#define QSERDES_V10_COM_SSC_STEP_SIZE1_MODE1 0x00
+#define QSERDES_V10_COM_SSC_STEP_SIZE2_MODE1 0x04
+#define QSERDES_V10_COM_CP_CTRL_MODE1 0x10
+#define QSERDES_V10_COM_PLL_RCTRL_MODE1 0x14
+#define QSERDES_V10_COM_PLL_CCTRL_MODE1 0x18
+#define QSERDES_V10_COM_CORECLK_DIV_MODE1 0x1c
+#define QSERDES_V10_COM_LOCK_CMP1_MODE1 0x20
+#define QSERDES_V10_COM_LOCK_CMP2_MODE1 0x24
+#define QSERDES_V10_COM_DEC_START_MODE1 0x28
+#define QSERDES_V10_COM_DEC_START_MSB_MODE1 0x2c
+#define QSERDES_V10_COM_DIV_FRAC_START1_MODE1 0x30
+#define QSERDES_V10_COM_DIV_FRAC_START2_MODE1 0x34
+#define QSERDES_V10_COM_DIV_FRAC_START3_MODE1 0x38
+#define QSERDES_V10_COM_HSCLK_SEL_1 0x3c
+#define QSERDES_V10_COM_INTEGLOOP_GAIN0_MODE1 0x40
+#define QSERDES_V10_COM_INTEGLOOP_GAIN1_MODE1 0x44
+#define QSERDES_V10_COM_VCO_TUNE1_MODE1 0x48
+#define QSERDES_V10_COM_VCO_TUNE2_MODE1 0x4c
+#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x50
+#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x54
+#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x58
+#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x5c
+#define QSERDES_V10_COM_SSC_STEP_SIZE1_MODE0 0x60
+#define QSERDES_V10_COM_SSC_STEP_SIZE2_MODE0 0x64
+#define QSERDES_V10_COM_CP_CTRL_MODE0 0x70
+#define QSERDES_V10_COM_PLL_RCTRL_MODE0 0x74
+#define QSERDES_V10_COM_PLL_CCTRL_MODE0 0x78
+#define QSERDES_V10_COM_PLL_CORE_CLK_DIV_MODE0 0x7c
+#define QSERDES_V10_COM_LOCK_CMP1_MODE0 0x80
+#define QSERDES_V10_COM_LOCK_CMP2_MODE0 0x84
+#define QSERDES_V10_COM_DEC_START_MODE0 0x88
+#define QSERDES_V10_COM_DEC_START_MSB_MODE0 0x8c
+#define QSERDES_V10_COM_DIV_FRAC_START1_MODE0 0x90
+#define QSERDES_V10_COM_DIV_FRAC_START2_MODE0 0x94
+#define QSERDES_V10_COM_DIV_FRAC_START3_MODE0 0x98
+#define QSERDES_V10_COM_HSCLK_HS_SWITCH_SEL_1 0x9c
+#define QSERDES_V10_COM_INTEGLOOP_GAIN0_MODE0 0xa0
+#define QSERDES_V10_COM_INTEGLOOP_GAIN1_MODE0 0xa4
+#define QSERDES_V10_COM_VCO_TUNE1_MODE0 0xa8
+#define QSERDES_V10_COM_VCO_TUNE2_MODE0 0xac
+#define QSERDES_V10_COM_BG_TIMER 0xbc
+#define QSERDES_V10_COM_SSC_EN_CENTER 0xc0
+#define QSERDES_V10_COM_SSC_ADJ_PER1 0xc4
+#define QSERDES_V10_COM_SSC_PER1 0xcc
+#define QSERDES_V10_COM_SSC_PER2 0xd0
+#define QSERDES_V10_COM_POST_DIV_MUX 0xd8
+#define QSERDES_V10_COM_BIAS_EN_CLKBUFLR_EN 0xdc
+#define QSERDES_V10_COM_CLK_ENABLE1 0xe0
+#define QSERDES_V10_COM_SYS_CLK_CTRL 0xe4
+#define QSERDES_V10_COM_SYSCLK_BUF_ENABLE 0xe8
+#define QSERDES_V10_COM_PLL_IVCO 0xf4
+#define QSERDES_V10_COM_PLL_IVCO_MODE1 0xf8
+#define QSERDES_V10_COM_CMN_IETRIM 0xfc
+#define QSERDES_V10_COM_CMN_IPTRIM 0x100
+#define QSERDES_V10_COM_SYSCLK_EN_SEL 0x110
+#define QSERDES_V10_COM_RESETSM_CNTRL 0x118
+#define QSERDES_V10_COM_LOCK_CMP_EN 0x120
+#define QSERDES_V10_COM_LOCK_CMP_CFG 0x124
+#define QSERDES_V10_COM_VCO_TUNE_CTRL 0x13c
+#define QSERDES_V10_COM_VCO_TUNE_MAP 0x140
+#define QSERDES_V10_COM_VCO_TUNE_INITVAL2 0x148
+#define QSERDES_V10_COM_VCO_TUNE_MAXVAL2 0x158
+#define QSERDES_V10_COM_CLK_SELECT 0x164
+#define QSERDES_V10_COM_CORE_CLK_EN 0x170
+#define QSERDES_V10_COM_CMN_CONFIG_1 0x174
+#define QSERDES_V10_COM_SVS_MODE_CLK_SEL 0x17c
+#define QSERDES_V10_COM_CMN_MISC_1 0x184
+#define QSERDES_V10_COM_CMN_MODE 0x188
+#define QSERDES_V10_COM_PLL_VCO_DC_LEVEL_CTRL 0x198
+#define QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4
+#define QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8
+#define QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
+#define QSERDES_V10_COM_ADDITIONAL_MISC 0x1b4
+#define QSERDES_V10_COM_ADDITIONAL_MISC_2 0x1b8
+#define QSERDES_V10_COM_ADDITIONAL_MISC_3 0x1bc
+#define QSERDES_V10_COM_CMN_STATUS 0x2c8
+#define QSERDES_V10_COM_C_READY_STATUS 0x2f0
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h
new file mode 100644
index 000000000000..84f1adee5ff7
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V10_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_V10_H_
+
+/* Only for QMP V10 PHY - QSERDES TX/RX registers */
+
+/* TX registers */
+#define QSERDES_V10_TX_CLKBUF_ENABLE 0x08
+#define QSERDES_V10_TX_TX_EMP_POST1_LVL 0x0c
+#define QSERDES_V10_TX_TX_DRV_LVL 0x14
+#define QSERDES_V10_TX_RESET_TSYNC_EN 0x1c
+#define QSERDES_V10_TX_PRE_STALL_LDO_BOOST_EN 0x20
+#define QSERDES_V10_TX_TX_BAND 0x24
+#define QSERDES_V10_TX_INTERFACE_SELECT 0x2c
+#define QSERDES_V10_TX_RES_CODE_LANE_TX 0x34
+#define QSERDES_V10_TX_RES_CODE_LANE_RX 0x38
+#define QSERDES_V10_TX_RES_CODE_LANE_OFFSET_TX 0x3c
+#define QSERDES_V10_TX_RES_CODE_LANE_OFFSET_RX 0x40
+#define QSERDES_V10_TX_TRANSCEIVER_BIAS_EN 0x54
+#define QSERDES_V10_TX_HIGHZ_DRVR_EN 0x58
+#define QSERDES_V10_TX_TX_POL_INV 0x5c
+#define QSERDES_V10_TX_PARRATE_REC_DETECT_IDLE_EN 0x60
+#define QSERDES_V10_TX_BIST_PATTERN7 0x7c
+#define QSERDES_V10_TX_LANE_MODE_1 0x84
+#define QSERDES_V10_TX_LANE_MODE_2 0x88
+#define QSERDES_V10_TX_LANE_MODE_3 0x8c
+#define QSERDES_V10_TX_LANE_MODE_4 0x90
+#define QSERDES_V10_TX_LANE_MODE_5 0x94
+#define QSERDES_V10_TX_RCV_DETECT_LVL_2 0xa4
+#define QSERDES_V10_TX_TRAN_DRVR_EMP_EN 0xc0
+#define QSERDES_V10_TX_TX_INTERFACE_MODE 0xc4
+#define QSERDES_V10_TX_VMODE_CTRL1 0xc8
+#define QSERDES_V10_TX_PI_QEC_CTRL 0xe4
+
+/* RX registers */
+#define QSERDES_V10_RX_UCDR_FO_GAIN 0x08
+#define QSERDES_V10_RX_UCDR_SO_GAIN 0x14
+#define QSERDES_V10_RX_UCDR_FASTLOCK_FO_GAIN 0x30
+#define QSERDES_V10_RX_UCDR_SO_SATURATION_AND_ENABLE 0x34
+#define QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_LOW 0x3c
+#define QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_HIGH 0x40
+#define QSERDES_V10_RX_UCDR_PI_CONTROLS 0x44
+#define QSERDES_V10_RX_UCDR_SB2_THRESH1 0x4c
+#define QSERDES_V10_RX_UCDR_SB2_THRESH2 0x50
+#define QSERDES_V10_RX_UCDR_SB2_GAIN1 0x54
+#define QSERDES_V10_RX_UCDR_SB2_GAIN2 0x58
+#define QSERDES_V10_RX_AUX_DATA_TCOARSE_TFINE 0x60
+#define QSERDES_V10_RX_TX_ADAPT_POST_THRESH 0xcc
+#define QSERDES_V10_RX_VGA_CAL_CNTRL1 0xd4
+#define QSERDES_V10_RX_VGA_CAL_CNTRL2 0xd8
+#define QSERDES_V10_RX_GM_CAL 0xdc
+#define QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL2 0xec
+#define QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL3 0xf0
+#define QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL4 0xf4
+#define QSERDES_V10_RX_RX_IDAC_TSETTLE_LOW 0xf8
+#define QSERDES_V10_RX_RX_IDAC_TSETTLE_HIGH 0xfc
+#define QSERDES_V10_RX_RX_IDAC_ENABLES 0x100
+#define QSERDES_V10_RX_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x104
+#define QSERDES_V10_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
+#define QSERDES_V10_RX_SIGDET_ENABLES 0x118
+#define QSERDES_V10_RX_SIGDET_CNTRL 0x11c
+#define QSERDES_V10_RX_SIGDET_DEGLITCH_CNTRL 0x124
+#define QSERDES_V10_RX_RX_MODE_00_LOW 0x15c
+#define QSERDES_V10_RX_RX_MODE_00_HIGH 0x160
+#define QSERDES_V10_RX_RX_MODE_00_HIGH2 0x164
+#define QSERDES_V10_RX_RX_MODE_00_HIGH3 0x168
+#define QSERDES_V10_RX_RX_MODE_00_HIGH4 0x16c
+#define QSERDES_V10_RX_RX_MODE_01_LOW 0x170
+#define QSERDES_V10_RX_RX_MODE_01_HIGH 0x174
+#define QSERDES_V10_RX_RX_MODE_01_HIGH2 0x178
+#define QSERDES_V10_RX_RX_MODE_01_HIGH3 0x17c
+#define QSERDES_V10_RX_RX_MODE_01_HIGH4 0x180
+#define QSERDES_V10_RX_RX_MODE_10_LOW 0x184
+#define QSERDES_V10_RX_RX_MODE_10_HIGH 0x188
+#define QSERDES_V10_RX_RX_MODE_10_HIGH2 0x18c
+#define QSERDES_V10_RX_RX_MODE_10_HIGH3 0x190
+#define QSERDES_V10_RX_RX_MODE_10_HIGH4 0x194
+#define QSERDES_V10_RX_DFE_EN_TIMER 0x1a0
+#define QSERDES_V10_RX_DFE_CTLE_POST_CAL_OFFSET 0x1a4
+#define QSERDES_V10_RX_DCC_CTRL1 0x1a8
+#define QSERDES_V10_RX_VTH_CODE 0x1b0
+#define QSERDES_V10_RX_SIGDET_CAL_CTRL1 0x1e4
+#define QSERDES_V10_RX_SIGDET_CAL_TRIM 0x1f8
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index a873bdd7bffe..7af77572970e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -39,6 +39,9 @@
#include "phy-qcom-qmp-qserdes-txrx-v8.h"
#include "phy-qcom-qmp-qserdes-lalb-v8.h"
+#include "phy-qcom-qmp-qserdes-com-v10.h"
+#include "phy-qcom-qmp-qserdes-txrx-v10.h"
+
#include "phy-qcom-qmp-qserdes-pll.h"
#include "phy-qcom-qmp-pcs-v2.h"
@@ -65,6 +68,8 @@
#include "phy-qcom-qmp-pcs-v8_50.h"
+#include "phy-qcom-qmp-pcs-v10.h"
+
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
/* QPHY_POWER_DOWN_CONTROL */
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox