* [PATCH v5 11/18] phy: rockchip: usbdp: Register DP aux bridge
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
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 v5 14/18] phy: rockchip: usbdp: Re-init the PHY on orientation change
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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 a3b4e2e0f578..89a08267611c 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -622,6 +622,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);
@@ -633,7 +634,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 v5 09/18] phy: rockchip: usbdp: Use FIELD_PREP_WM16_CONST
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com>
Cleanup code by replacing open-coded version of FIELD_PREP_WM16_CONST
with the existing helper macro.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
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 v5 10/18] phy: rockchip: usbdp: Cleanup DP lane selection function
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com>
Use FIELD_PREP_WM16() helpers to simplify the DP lane selection
logic.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
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 v5 05/18] phy: rockchip: usbdp: Fix LFPS detect threshold control
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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]
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
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 v5 08/18] phy: rockchip: usbdp: Rename DP lane functions
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
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 v5 01/18] dt-bindings: phy: rockchip-usbdp: add improved ports scheme
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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.
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
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 v5 04/18] phy: rockchip: usbdp: Amend SSC modulation deviation
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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]
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
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 v5 02/18] phy: rockchip: usbdp: Do not lose USB3 PHY status
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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 is 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.
Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
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
* [PATCH v5 00/18] phy: rockchip: usbdp: Fixes, DP 1-lane support and cleanups
From: Sebastian Reichel @ 2026-06-12 16:21 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. At
the moment it only contains a semi-working state.
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 ASAP as it blocks the DRM side.
Changes in v5:
- Link to v4: https://lore.kernel.org/r/20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com
- Picked up Acked-by from Rob Herring for DT binding
- Fix typos in commit messages/comments
- Add Fixes tag to "Do not looe USB3 PHY status" patch
- Collect Reviewed-by: Neil Armstrong for multiple patches
- Drop now unused code from "Drop DP HPD handling" patch (Sashiko)
- Ignore mux events not involving DP AltMode (Sashiko)
- Add new patch to support going back from DP only mode to USB combo
mode; technically this is a fix, but DP mode does not yet work
upstream, so it does not matter (Sashiko)
- Add new patch adding a few debug messages, which are useful
to investigate potential hotplug issues in the future
- Sashiko comments about the DT binding and property usage
are wrong as the first port is for the superspeed lanes
used for DP and USB, while the last port is just about
DP aux. I ignored them.
- There is a pre-existing bug, that can already be hit with the
upstream kernel and that the series doesn't fix properly:
Accessing the USB3 controller registers requires the USB PHY
running, since it provides a clock. Re-initializing the PHY
means there is a race-condition - if the system tries to access
the USB3 controller in parallel to the re-init, the system will
hang and/or fail with an SError. By keeping the clocks running
and only asserting the resets this time is minimized by this
series. A proper fix for this will be looked into independently
from this series.
- I used v7.1-rc6 as base, but the driver has no changes since
6.18 even in linux-next and there are no pending patches for
it on the mailinglist either, so it applies to *any* recent
kernel branch.
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 (15):
dt-bindings: phy: rockchip-usbdp: add improved ports scheme
phy: rockchip: usbdp: Do not lose 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
phy: rockchip: usbdp: Support going from DP-only mode to USB mode
phy: rockchip: usbdp: Add some extra debug messages
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 | 357 +++++++++------------
3 files changed, 181 insertions(+), 201 deletions(-)
---
base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
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 v5 03/18] phy: rockchip: usbdp: Keep clocks running on PHY re-init
From: Sebastian Reichel @ 2026-06-12 16:21 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: <20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@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().
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
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
* Re: [PATCH v4 07/16] phy: rockchip: usbdp: Support single-lane DP
From: Sebastian Reichel @ 2026-06-12 15:57 UTC (permalink / raw)
To: Neil Armstrong
Cc: Vinod Koul, Heiko Stuebner, Frank Wang, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andy Yan, Dmitry Baryshkov,
Yubing Zhang, Alexey Charkov, linux-phy, linux-arm-kernel,
linux-rockchip, linux-kernel, kernel, devicetree
In-Reply-To: <f29df43b-111d-471b-8579-0196596fc32b@linaro.org>
[-- Attachment #1.1: Type: text/plain, Size: 2156 bytes --]
Hi,
On Wed, May 06, 2026 at 04:53:07PM +0200, Neil Armstrong wrote:
> > @@ -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;
>
> What's the point of keeping this no-op calculation ?
This function is cleaned up in a later patch to no longer have the
switch/case at all ("Cleanup DP lane selection function"). I kept
the no-op calculation here, since it IMHO makes it easier to understand
the cleanup patch and will be optimized away by the compiler anyways.
(I will send out a new patch series in a jiffy)
Greetings,
-- Sebastian
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v1 phy-next 7/8] soc: fsl: guts: implement the RCW override procedure
From: Conor Dooley @ 2026-06-12 15:44 UTC (permalink / raw)
To: Vladimir Oltean
Cc: linux-phy, devicetree, linuxppc-dev, linux-arm-kernel,
Ioana Ciornei, Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel, Krzysztof Kozlowski, Rob Herring
In-Reply-To: <20260611193940.44416-8-vladimir.oltean@nxp.com>
[-- Attachment #1.1: Type: text/plain, Size: 15588 bytes --]
On Thu, Jun 11, 2026 at 10:39:39PM +0300, Vladimir Oltean wrote:
> From: Ioana Ciornei <ioana.ciornei@nxp.com>
>
> Add support for the RCW override procedure which enables runtime
> reconfiguration of the protocol running on a SerDes lane. The procedure
> is done through the DCFG DCSR space which now can be defined as the
> second memory region of the guts DT node.
> Support is added on the following SoCs: LS1046A, LS1088A, LS2088A.
>
> The procedure is exported to the "client" driver - the Lynx10G SerDes
> PHY driver - through the following functions:
> - fsl_guts_lane_init() used to notify the initial / boot time lane mode
> running on a SerDes lane.
> - fsl_guts_lane_validate() used to validate that changing the protocol
> on a specific lane is supported.
> - fsl_guts_lane_set_mode() which can be used to request the RCW
> procedure be executed for a specific lane.
>
> Since the RCW override procedure is different depending on the SoC, the
> private fsl_soc_data structure is updated with two new per SoC callbacks
> (.serdes_get_rcw_override() and .serdes_init_rcwcr()) which get used
> from the generic fsl_guts_lane_set_mode() function. These two callbacks
> hide all the SoC specific register offsets, masks and values so that the
> _set_mode() procedure is straightforward.
>
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
> Cc: Conor Dooley <conor@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Rob Herring <robh@kernel.org>
> Cc: devicetree@vger.kernel.org
Wrong CC list for this specific patch?
ta,
Conor.
> ---
> drivers/soc/fsl/guts.c | 286 ++++++++++++++++++++++++++++++++++++++-
> include/linux/fsl/guts.h | 20 ++-
> 2 files changed, 299 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
> index 9f2aff07a274..23ec5750080c 100644
> --- a/drivers/soc/fsl/guts.c
> +++ b/drivers/soc/fsl/guts.c
> @@ -15,6 +15,30 @@
> #include <linux/fsl/guts.h>
>
> #define DCFG_CCSR 0
> +#define DCFG_DCSR 1
> +
> +#define MAX_NUM_LANES 8
> +#define MAX_NUM_SERDES 2
> +
> +#define LS1088A_RCWSR29_SRDS_PRTCL_S1_LNn(lane) \
> + GENMASK(19 + 4 * (3 - lane), 16 + 4 * (3 - lane))
> +#define LS1088A_RCWSR30_SRDS_PRTCL_S2_LNn(lane) \
> + GENMASK(3 + 4 * (3 - lane), 4 * (3 - lane))
> +
> +#define LS1046A_RCWSR5_SRDS_PRTCL_S1(lane) \
> + GENMASK(19 + 4 * (lane), 16 + 4 * (lane))
> +#define SRDS_PRTCL_NONE 0
> +#define SRDS_PRTCL_XFI 1
> +#define SRDS_PRTCL_2500BASEX 2
> +#define SRDS_PRTCL_100BASEX_SGMII 3
> +#define SRDS_PRTCL_QSGMII 4
> +#define SRDS_PRTCL_PCIE 5
> +
> +#define LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1 BIT(14)
> +#define LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(lane) BIT(6 + (7 - (lane)))
> +#define LS2088A_RCWSR30_SRDS_CLK_SEL_MSK GENMASK(13, 6)
> +#define SRDS_CLK_SEL_XGMII 1
> +#define SRDS_CLK_SEL_GMII 0
>
> struct fsl_soc_die_attr {
> char *die;
> @@ -22,9 +46,19 @@ struct fsl_soc_die_attr {
> u32 mask;
> };
>
> +struct fsl_soc_serdes_rcw_override {
> + int offset;
> + int mask;
> + int val;
> +};
> +
> struct fsl_soc_data {
> const char *sfp_compat;
> u32 uid_offset;
> + int (*serdes_get_rcw_override)(int index, int lane,
> + enum lynx_lane_mode lane_mode,
> + struct fsl_soc_serdes_rcw_override *override);
> + void (*serdes_init_rcwcr)(int index);
> };
>
> enum qoriq_die {
> @@ -138,9 +172,13 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
>
> static struct fsl_soc_guts {
> struct ccsr_guts __iomem *dcfg_ccsr;
> + struct ccsr_guts __iomem *dcfg_dcsr;
> const struct fsl_soc_data *data;
> bool little_endian;
> u32 svr;
> + enum lynx_lane_mode lane_mode[MAX_NUM_SERDES][MAX_NUM_LANES];
> + bool rcwcr_init_done;
> + spinlock_t rcwcr_lock; /* serializes concurrent writes to the RCWCR */
> } soc;
>
> static unsigned int fsl_guts_read(const void __iomem *reg)
> @@ -151,6 +189,28 @@ static unsigned int fsl_guts_read(const void __iomem *reg)
> return ioread32be(reg);
> }
>
> +static void fsl_guts_write(void __iomem *reg, u32 val)
> +{
> + if (soc.little_endian)
> + iowrite32(val, reg);
> + else
> + iowrite32be(val, reg);
> +}
> +
> +/* Some fields of the Reset Configuration Word (RCW) can be overridden at
> + * runtime by writing to the RCWCRn registers contained within the DCSR space
> + * of the Device Configuration (DCFG) block. The layout of the RCWCRn registers
> + * is identical with the read-only RCWSRn from the CCSR space.
> + */
> +static void fsl_guts_rmw(int offset, u32 val, u32 mask)
> +{
> + u32 tmp = fsl_guts_read(&soc.dcfg_ccsr->rcwsr[offset]);
> +
> + tmp &= ~mask;
> + tmp |= val;
> + fsl_guts_write(&soc.dcfg_dcsr->rcwcr[offset], tmp);
> +}
> +
> static bool fsl_soc_die_match_one(u32 svr, const struct fsl_soc_die_attr *match)
> {
> return match->svr == (svr & match->mask);
> @@ -167,6 +227,97 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
> return NULL;
> }
>
> +static int
> +fsl_guts_serdes_get_rcw_override(int serdes_idx, int lane,
> + enum lynx_lane_mode lane_mode,
> + struct fsl_soc_serdes_rcw_override *override)
> +{
> + if ((!fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS1088A]) &&
> + !fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS2088A]) &&
> + !fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS1046A])) ||
> + !soc.data || !soc.data->serdes_get_rcw_override) {
> + pr_debug("RCW override not implemented for SoC\n");
> + return -EINVAL;
> + }
> +
> + if (!soc.dcfg_dcsr) {
> + pr_debug("Device tree does not define DCFG_DCSR region necessary for RCW override\n");
> + return -EINVAL;
> + }
> +
> + return soc.data->serdes_get_rcw_override(serdes_idx, lane, lane_mode,
> + override);
> +}
> +
> +/**
> + * fsl_guts_lane_init() - Notify guts module of SerDes lane configuration
> + * @serdes_idx: zero-based SerDes block index
> + * @lane: zero-based lane index within SerDes
> + * @lane_mode: initial / boot time SerDes protocol for lane
> + *
> + * On the LS208xA SoC, the RCW override procedure needs to be aware of all link
> + * modes which are configured on a SerDes block.
> + */
> +void fsl_guts_lane_init(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
> +{
> + soc.lane_mode[serdes_idx - 1][lane] = lane_mode;
> +}
> +EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_init, "FSL_GUTS");
> +
> +/**
> + * fsl_guts_lane_validate() - Validate that SerDes protocol is implemented and
> + * supported on current SoC
> + * @serdes_idx: zero-based SerDes block index
> + * @lane: zero-based lane index within SerDes
> + * @lane_mode: requested SerDes protocol
> + *
> + * Should be called before actually requesting the RCW override procedure to be
> + * applied using %fsl_guts_lane_set_mode()
> + *
> + * Return: 0 if RCW override to protocol is possible, negative error otherwise
> + */
> +int fsl_guts_lane_validate(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
> +{
> + struct fsl_soc_serdes_rcw_override override;
> +
> + return fsl_guts_serdes_get_rcw_override(serdes_idx, lane, lane_mode,
> + &override);
> +}
> +EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_validate, "FSL_GUTS");
> +
> +/**
> + * fsl_guts_lane_set_mode() - apply RCW override procedure for SerDes lane
> + * @serdes_idx: zero-based SerDes block index
> + * @lane: zero-based lane index within SerDes
> + * @lane_mode: requested SerDes protocol
> + *
> + * Return: 0 on success, negative error otherwise
> + */
> +int fsl_guts_lane_set_mode(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
> +{
> + struct fsl_soc_serdes_rcw_override override;
> + int err;
> +
> + err = fsl_guts_serdes_get_rcw_override(serdes_idx, lane, lane_mode,
> + &override);
> + if (err)
> + return err;
> +
> + spin_lock(&soc.rcwcr_lock);
> +
> + if (soc.data->serdes_init_rcwcr)
> + soc.data->serdes_init_rcwcr(serdes_idx);
> +
> + fsl_guts_rmw(override.offset, override.val << __bf_shf(override.mask),
> + override.mask);
> + soc.lane_mode[serdes_idx - 1][lane] = lane_mode;
> +
> + spin_unlock(&soc.rcwcr_lock);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_set_mode, "FSL_GUTS");
> +
> static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset)
> {
> struct device_node *np;
> @@ -193,6 +344,128 @@ static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset)
> return uid;
> }
>
> +static int ls1088a_serdes_get_rcw_override(int index, int lane,
> + enum lynx_lane_mode lane_mode,
> + struct fsl_soc_serdes_rcw_override *override)
> +{
> + /* The RCW override procedure has to write to different registers
> + * depending on the SerDes block index.
> + */
> + switch (index) {
> + case 1:
> + override->offset = 28;
> + override->mask = LS1088A_RCWSR29_SRDS_PRTCL_S1_LNn(lane);
> + break;
> + case 2:
> + override->offset = 29;
> + override->mask = LS1088A_RCWSR30_SRDS_PRTCL_S2_LNn(lane);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
> + override->val = SRDS_PRTCL_XFI;
> + else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
> + override->val = SRDS_PRTCL_100BASEX_SGMII;
> + else
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int ls1046a_serdes_get_rcw_override(int index, int lane,
> + enum lynx_lane_mode lane_mode,
> + struct fsl_soc_serdes_rcw_override *override)
> +{
> + /* The RCW override procedure has to write to different registers
> + * depending on the SerDes block index.
> + */
> + switch (index) {
> + case 1:
> + override->offset = 4;
> + override->mask = LS1046A_RCWSR5_SRDS_PRTCL_S1(lane);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
> + override->val = SRDS_PRTCL_XFI;
> + else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
> + override->val = SRDS_PRTCL_100BASEX_SGMII;
> + else
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int ls2088a_serdes_get_rcw_override(int index, int lane,
> + enum lynx_lane_mode lane_mode,
> + struct fsl_soc_serdes_rcw_override *override)
> +{
> + switch (index) {
> + case 1:
> + override->offset = 29;
> + override->mask = LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(lane);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
> + override->val = SRDS_CLK_SEL_XGMII;
> + else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
> + override->val = SRDS_CLK_SEL_GMII;
> + else
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static void ls2088a_serdes_init_rcwcr(int serdes_idx)
> +{
> + u32 reg;
> + int i;
> +
> + if (serdes_idx != 1)
> + return;
> + if (soc.rcwcr_init_done)
> + return;
> +
> + /* SRDS_CLK_EN_SEL_XGMII_S1: SerDes Clock Enable Select XGMII Serdes 1:
> + * Enables to select GMII/XGMII clock according to
> + * SRDS_CLK_SEL_XGMII_Ln_S1
> + */
> + reg = LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1;
> +
> + /* We need to configure the initial state of all lanes for
> + * the SerDes block #1
> + */
> + for (i = 0; i < MAX_NUM_LANES; i++)
> + if (lynx_lane_mode_uses_xgmii_mac(soc.lane_mode[serdes_idx - 1][i]))
> + reg |= LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(i);
> +
> + fsl_guts_rmw(29, reg,
> + LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1 |
> + LS2088A_RCWSR30_SRDS_CLK_SEL_MSK);
> +
> + soc.rcwcr_init_done = true;
> +}
> +
> +static const struct fsl_soc_data ls1088a_data = {
> + .serdes_get_rcw_override = ls1088a_serdes_get_rcw_override,
> +};
> +
> +static const struct fsl_soc_data ls1046a_data = {
> + .serdes_get_rcw_override = ls1046a_serdes_get_rcw_override,
> +};
> +
> +static const struct fsl_soc_data ls2088a_data = {
> + .serdes_get_rcw_override = ls2088a_serdes_get_rcw_override,
> + .serdes_init_rcwcr = ls2088a_serdes_init_rcwcr,
> +};
> +
> static const struct fsl_soc_data ls1028a_data = {
> .sfp_compat = "fsl,ls1028a-sfp",
> .uid_offset = 0x21c,
> @@ -221,10 +494,10 @@ static const struct of_device_id fsl_guts_of_match[] = {
> { .compatible = "fsl,mpc8572-guts", },
> { .compatible = "fsl,ls1021a-dcfg", },
> { .compatible = "fsl,ls1043a-dcfg", },
> - { .compatible = "fsl,ls2080a-dcfg", },
> - { .compatible = "fsl,ls1088a-dcfg", },
> + { .compatible = "fsl,ls2080a-dcfg", .data = &ls2088a_data},
> + { .compatible = "fsl,ls1088a-dcfg", .data = &ls1088a_data},
> { .compatible = "fsl,ls1012a-dcfg", },
> - { .compatible = "fsl,ls1046a-dcfg", },
> + { .compatible = "fsl,ls1046a-dcfg", .data = &ls1046a_data},
> { .compatible = "fsl,lx2160a-dcfg", },
> { .compatible = "fsl,ls1028a-dcfg", .data = &ls1028a_data},
> {}
> @@ -250,6 +523,8 @@ static int __init fsl_guts_init(void)
> of_node_put(np);
> return -ENOMEM;
> }
> + /* DCFG_DCSR is optional */
> + soc.dcfg_dcsr = of_iomap(np, DCFG_DCSR);
>
> soc.little_endian = of_property_read_bool(np, "little-endian");
> soc.svr = fsl_guts_read(&soc.dcfg_ccsr->svr);
> @@ -296,6 +571,8 @@ static int __init fsl_guts_init(void)
> goto err;
> }
>
> + spin_lock_init(&soc.rcwcr_lock);
> +
> pr_info("Machine: %s\n", soc_dev_attr->machine);
> pr_info("SoC family: %s\n", soc_dev_attr->family);
> pr_info("SoC ID: %s, Revision: %s\n",
> @@ -305,7 +582,8 @@ static int __init fsl_guts_init(void)
>
> err_nomem:
> ret = -ENOMEM;
> -
> + if (soc.dcfg_dcsr)
> + iounmap(soc.dcfg_dcsr);
> iounmap(soc.dcfg_ccsr);
> err:
> kfree(soc_dev_attr->family);
> diff --git a/include/linux/fsl/guts.h b/include/linux/fsl/guts.h
> index fdb55ca47a4f..176842531241 100644
> --- a/include/linux/fsl/guts.h
> +++ b/include/linux/fsl/guts.h
> @@ -13,6 +13,7 @@
>
> #include <linux/types.h>
> #include <linux/io.h>
> +#include <soc/fsl/phy-fsl-lynx.h>
>
> /*
> * Global Utility Registers.
> @@ -91,9 +92,15 @@ struct ccsr_guts {
> u32 iovselsr; /* 0x.00c0 - I/O voltage select status register
> Called 'elbcvselcr' on 86xx SOCs */
> u8 res0c4[0x100 - 0xc4];
> - u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
> - There are 16 registers */
> - u8 res140[0x224 - 0x140];
> + /* 0x.0100 - read-only Reset Configuration Word Status registers in
> + * CCSR, or write-only Reset Configuration Word Control registers in
> + * DCSR. In both cases there are 32 registers.
> + */
> + union {
> + u32 rcwsr[32];
> + u32 rcwcr[32];
> + };
> + u8 res180[0x224 - 0x180];
> u32 iodelay1; /* 0x.0224 - IO delay control register 1 */
> u32 iodelay2; /* 0x.0228 - IO delay control register 2 */
> u8 res22c[0x604 - 0x22c];
> @@ -131,6 +138,13 @@ struct ccsr_guts {
> u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
> } __attribute__ ((packed));
>
> +void fsl_guts_lane_init(int serdes_idx, int lane,
> + enum lynx_lane_mode lane_mode);
> +int fsl_guts_lane_validate(int serdes_idx, int lane,
> + enum lynx_lane_mode lane_mode);
> +int fsl_guts_lane_set_mode(int serdes_idx, int lane,
> + enum lynx_lane_mode lane_mode);
> +
> /* Alternate function signal multiplex control */
> #define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
>
> --
> 2.34.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v1 phy-next 6/8] dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region
From: Conor Dooley @ 2026-06-12 15:44 UTC (permalink / raw)
To: Vladimir Oltean
Cc: linux-phy, devicetree, linuxppc-dev, linux-arm-kernel,
Ioana Ciornei, Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel, Krzysztof Kozlowski, Rob Herring
In-Reply-To: <20260611193940.44416-7-vladimir.oltean@nxp.com>
[-- Attachment #1.1: Type: text/plain, Size: 3952 bytes --]
On Thu, Jun 11, 2026 at 10:39:38PM +0300, Vladimir Oltean wrote:
> In Layerscape (Arm) and QorIQ (PowerPC) devices, hardware peripherals
> are accessed by the CPU through a portion of the SoC address space
> called CCSR ("Configuration, Control, and Status Registers"). All
> hardware IP blocks have their registers mapped here, and the Device
> Configuration block makes no exception.
>
> However, there exists a secondary range of the address space named DCSR
> ("Debug Control and Status Registers") which, like CCSR, also holds
> registers of hardware IP blocks, except the DCSR contents is hidden in
> all public reference manuals.
>
> The intention of the CCSR/DCSR split, to the best of my knowledge, was
> to place the functionality that is too low level for normal use, and
> which is necessary only for debug, in a completely separate address
> space which can be hidden.
>
> A use case has appeared where networking SerDes lanes need to be
> reconfigured at runtime for a different protocol (example: 10GBase-R to
> SGMII), and the architecture of the SoCs does not normally permit that.
> The Reset Configuration Word (RCW) is a data structure read by the SoC
> preboot loader (PBL) which contains stuff like pinmuxing and SerDes
> protocol mapping for each lane.
>
> The RCW that the PBL has loaded is visible in the DCFG block's normal
> status registers (from CCSR), as read only. Turns out, the RCW is also
> mapped in the DCFG's shadow register map (in DCSR), in a write-only
> form. Writing to the RCW registers from the DCFG's DCSR space to change
> what the PBL has loaded is called "RCW override".
>
> It has been validated that the RCW override procedure is necessary to
> reconfigure the networking data path when a SerDes lane performs a major
> protocol change. It changes some internal muxes which connect the PCS to
> either the 10G MAC or to the 1G MAC.
>
> Defining the DCSR area of the DCFG as a secondary 'reg' array element
> allows operating systems to perform RCW overrides. Since it is
> introduced late in the binding's lifetime, it is optional. It can be
> identified by name, but also by index (first 'reg' is CCSR).
>
> Note that while all SoCs should have a DCFG register block in DCSR, we
> only need to expose it for the SoCs where the RCW override procedure is
> known to be needed and has been validated.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
> Cc: Conor Dooley <conor@kernel.org>
Where did this email come from btw? get_maintainer.pl result should have
+dt in it.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
Cheers,
Conor.
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Rob Herring <robh@kernel.org>
> Cc: devicetree@vger.kernel.org
> ---
> .../bindings/soc/fsl/fsl,layerscape-dcfg.yaml | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml b/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
> index 3fb0534ea597..fc14fd0bf84b 100644
> --- a/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
> +++ b/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
> @@ -36,7 +36,20 @@ properties:
> - const: simple-mfd
>
> reg:
> - maxItems: 1
> + minItems: 1
> + items:
> + - description:
> + Customer-visible DCFG register map from CCSR address space
> + (Configuration, Control and Status Registers)
> + - description:
> + Customer-hidden DCFG register map from DCSR address space
> + (Debug Control and Status Registers)
> +
> + reg-names:
> + minItems: 1
> + items:
> + - const: dcfg_ccsr
> + - const: dcfg_dcsr
>
> little-endian: true
> big-endian: true
> --
> 2.34.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Yoshihiro Shimoda, Vinod Koul, Geert Uytterhoeven, Magnus Damm
Cc: Biju Das, Neil Armstrong, Philipp Zabel, linux-renesas-soc,
linux-phy, linux-kernel, Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260612143048.317907-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
devm_regulator_get_exclusive() initialises the regulator with
enable_count = 1, requiring the consumer to disable it before release.
Previously, the devm disable action was only registered when the
regulator was explicitly enabled, causing the cleanup path to skip
decrementing enable_count on device removal when the regulator was
left disabled.
Fix this by always registering the devm disable action when the regulator
is enabled (checked via regulator_is_enabled()), covering both the
explicitly-enabled case and the initial state set by
devm_regulator_get_exclusive().
This fixes WARN_ON enable count during regulator release.
Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS for RZ/G2L SoCs")
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index d06fb52ed5f1..ef38c3b365d4 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -905,15 +905,17 @@ static int rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(struct rcar_ge
if (IS_ERR(channel->vbus))
return PTR_ERR(channel->vbus);
- if (!enable)
- return 0;
+ if (enable) {
+ ret = regulator_enable(channel->vbus);
+ if (ret)
+ return ret;
+ }
- ret = regulator_enable(channel->vbus);
- if (ret)
- return ret;
+ if (regulator_is_enabled(channel->vbus))
+ return devm_add_action_or_reset(dev, rcar_gen3_phy_usb2_vbus_disable_action,
+ channel->vbus);
- return devm_add_action_or_reset(dev, rcar_gen3_phy_usb2_vbus_disable_action,
- channel->vbus);
+ return 0;
}
static int rcar_gen3_phy_usb2_vbus_regulator_register(struct rcar_gen3_chan *channel)
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 08/11] phy: renesas: phy-rcar-gen3-usb2: Add RZ/G3L support
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Yoshihiro Shimoda, Vinod Koul, Geert Uytterhoeven, Magnus Damm
Cc: Biju Das, Neil Armstrong, linux-renesas-soc, linux-phy,
linux-kernel, Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260612143048.317907-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
Add renesas,usb2-phy-r9a08g046 to the OF match table, reusing
rz_g3s_phy_usb2_data since the PHY configuration is shared with RZ/G3S.
Unlike RZ/G3S, RZ/G3L has two OTG controllers, OTG interrupts on port 2,
and a controllable OTG_PERI bit in COMMCTRL for host/device switching on
the port 2 USB controller (fixed to host-only on RZ/G3S).
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 9a45d840efeb..d06fb52ed5f1 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -721,6 +721,10 @@ static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
.compatible = "renesas,usb2-phy-r9a08g045",
.data = &rz_g3s_phy_usb2_data,
},
+ {
+ .compatible = "renesas,usb2-phy-r9a08g046",
+ .data = &rz_g3s_phy_usb2_data,
+ },
{
.compatible = "renesas,usb2-phy-r9a09g057",
.data = &rz_v2h_phy_usb2_data,
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 02/11] dt-bindings: phy: renesas,usb2-phy: Document RZ/G3L PHY bindings
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Biju Das, Neil Armstrong, Yoshihiro Shimoda, linux-phy,
devicetree, linux-kernel, linux-renesas-soc,
Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260612143048.317907-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
Add device tree binding support for the RZ/G3L (r9a08g046) USB2 PHY.
The RZ/G3L USB PHY is almost identical to the RZ/G3S USB PHY, the
difference being 2 OTG blocks on RZ/G3L compared to 1 on RZ/G3S.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
index 9740e5b335f9..d6b9d08ceec6 100644
--- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
@@ -16,6 +16,7 @@ properties:
- enum:
- renesas,usb2-phy-r8a77470 # RZ/G1C
- renesas,usb2-phy-r9a08g045 # RZ/G3S
+ - renesas,usb2-phy-r9a08g046 # RZ/G3L
- renesas,usb2-phy-r9a09g057 # RZ/V2H(P)
- items:
@@ -132,6 +133,7 @@ allOf:
enum:
- renesas,usb2-phy-r9a09g057
- renesas,usb2-phy-r9a08g045
+ - renesas,usb2-phy-r9a08g046
- renesas,rzg2l-usb2-phy
then:
properties:
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 00/11] Add RZ/G3L USB2.0 host support
From: Biju @ 2026-06-12 14:30 UTC (permalink / raw)
To: Philipp Zabel, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Geert Uytterhoeven, Michael Turquette, Stephen Boyd,
Liam Girdwood, Mark Brown, Magnus Damm
Cc: Biju Das, Neil Armstrong, Yoshihiro Shimoda, linux-phy,
devicetree, linux-kernel, linux-clk, linux-renesas-soc,
Prabhakar Mahadev Lad, Biju Das
From: Biju Das <biju.das.jz@bp.renesas.com>
Add device tree binding support for the RZ/G3L (r9a08g046) USB PHY
controller. The RZ/G3L USB PHY block is similar to RZ/G3S, but each port
has an OTG controller, unlike RZ/G3S, which has an OTG controller only on
port 1.
Biju Das (11):
dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3L support
dt-bindings: phy: renesas,usb2-phy: Document RZ/G3L PHY bindings
clk: renesas: r9a08g046: Add USB2.0 clock and reset entries
reset: rzg2l-usbphy-ctrl: Introduce info struct for match data
reset: rzg2l-usbphy-ctrl: Add RZ/G3L support
regulator: renesas-usb-vbus-regulator: Introduce helper for regulator
registration
regulator: renesas-usb-vbus-regulator: Add RZ/G3L VBUS regulator
support
phy: renesas: phy-rcar-gen3-usb2: Add RZ/G3L support
phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for
disabled VBUS regulator
arm64: dts: renesas: r9a08g046: Add USB2.0 device nodes
arm64: dts: renesas: r9a08g046l48-smarc: Add USB2.0 support
.../bindings/phy/renesas,usb2-phy.yaml | 2 +
.../reset/renesas,rzg2l-usbphy-ctrl.yaml | 20 +++-
arch/arm64/boot/dts/renesas/r9a08g046.dtsi | 103 ++++++++++++++++++
.../boot/dts/renesas/r9a08g046l48-smarc.dts | 49 +++++++++
drivers/clk/renesas/r9a08g046-cpg.c | 15 +++
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++--
.../regulator/renesas-usb-vbus-regulator.c | 72 ++++++++++--
drivers/reset/reset-rzg2l-usbphy-ctrl.c | 44 +++++---
8 files changed, 291 insertions(+), 34 deletions(-)
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH phy-next] phy: lynx-10g: fix lynx_10g_pccr_val_enabled()
From: Vladimir Oltean @ 2026-06-12 12:57 UTC (permalink / raw)
To: linux-phy; +Cc: Ioana Ciornei, Vinod Koul, Neil Armstrong, linux-kernel
The intention of the code is to extract the PCCR8_SGMIIa_CFG field out
of the "pccr" value, not to create a new value with the PCCR8_SGMIIa_CFG
field set to the "pccr" value.
Since FIELD_GET() is implemented as ((reg) & (mask)) >> __bf_shf(mask)
and FIELD_PREP() as (val) << __bf_shf(mask)) & (mask) and since "mask"
is GENMASK(2, 0), in practice there is no functional difference between
FIELD_GET() and FIELD_PREP(). But FIELD_GET() is logically the correct
helper.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/phy/freescale/phy-fsl-lynx-10g.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-10g.c b/drivers/phy/freescale/phy-fsl-lynx-10g.c
index 0dbe6fc9b7ba..32caabc406a3 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-10g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-10g.c
@@ -544,7 +544,7 @@ static void lynx_10g_backup_pccr_val(struct lynx_lane *lane)
*/
static bool lynx_10g_pccr_val_enabled(u32 pccr)
{
- return FIELD_PREP(PCCR8_SGMIIa_CFG, pccr) != 0;
+ return FIELD_GET(PCCR8_SGMIIa_CFG, pccr) != 0;
}
static bool lynx_10g_lane_is_3_125g(struct lynx_lane *lane)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH 0/2] Add support for the QMP PCIe PHYs in Qualcomm IPQ9650
From: Kathiravan Thirumoorthy @ 2026-06-12 8:08 UTC (permalink / raw)
To: Vinod Koul
Cc: Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <8a0e9314-0c97-48c8-be95-986c7e6fe641@oss.qualcomm.com>
On 6/11/2026 9:52 PM, Kathiravan Thirumoorthy wrote:
>
> On 6/11/2026 4:45 PM, Vinod Koul wrote:
>> On 02-06-26, 14:40, Kathiravan Thirumoorthy wrote:
>>> Qualcomm's IPQ9650 SoC has 3 Gen3 dual lane and 2 Gen3 single lane
>>> controllers with the QMP PHYs. Unlike the PHYs in the other IPQ SoC,
>>> refgen supply is needed to bringup the PHYs. Both single and dual lane
>>> shares the same HW init sequence. So reuse the tables.
>>>
>>> Document the compatible along with refgen supply and add the phy driver
>>> support for it.
>> Please rebase this on phy-next tomorrow. It does not apply for me due to
>> changes applied ealier today
>
> There is a discussion open about the supplies[1]. Once that is
> clarified, let me re spin. So we can take up this series for v7.3 once
> that discussion is closed.
>
> [1]
> https://lore.kernel.org/linux-arm-msm/aiqYtowP2DQt7Jw0@vaman/T/#m37a571fac0c77fd00f6379ad9a2414b60431820b
>
Discussion is concluded and I have sent the V2[1] on top of phy-next
(2ace2e949979 ("phy: rockchip: inno-usb2: Add missing clkout_ctl_phy
kerneldoc")). Please take a look at it.
[1]
https://lore.kernel.org/linux-arm-msm/20260612-ipq9650_pcie_phy-v2-0-b938cc2fc267@qti.qualcomm.com/#t
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 2/4] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: Add support for Shikra
From: Dmitry Baryshkov @ 2026-06-12 8:00 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Krishna Kurapati, Krzysztof Kozlowski, Neil Armstrong, Vinod Koul,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Xiangxu Yin, Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <0947e485-4619-43a3-a127-5b887780190b@oss.qualcomm.com>
On Wed, Jun 10, 2026 at 03:36:20PM +0200, Konrad Dybcio wrote:
> On 5/17/26 9:16 PM, Dmitry Baryshkov wrote:
> > On Fri, May 15, 2026 at 09:06:21PM +0530, Krishna Kurapati wrote:
> >>
> >>
> >> On 5/14/2026 8:07 PM, Krzysztof Kozlowski wrote:
> >>> On 14/05/2026 08:22, Krishna Kurapati wrote:
> >>>>
> >>>>
> >>>> On 5/14/2026 12:26 AM, Krzysztof Kozlowski wrote:
> >>>>> On 07/05/2026 13:37, Krishna Kurapati wrote:
> >>>>>>
> >>>>>>
> >>>>>> On 5/5/2026 7:30 PM, Krzysztof Kozlowski wrote:
> >>>>>>> On 05/05/2026 15:57, Krishna Kurapati wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 5/5/2026 6:59 PM, Krzysztof Kozlowski wrote:
> >>>>>>>>> On 05/05/2026 15:27, Krishna Kurapati wrote:
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> On 5/5/2026 4:22 PM, Krzysztof Kozlowski wrote:
> >>>>>>>>>>> On 05/05/2026 12:49, Krzysztof Kozlowski wrote:
> >>>>>>>>>>>> On Mon, May 04, 2026 at 10:36:57PM +0530, Krishna Kurapati wrote:
> >>>>>>>>>>>>> Declare the USB-C QMP PHY present on the Qualcomm Shikra platform.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> >>>>>>>>>>>>> ---
> >>>>>>>>>>>>> .../devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml | 2 ++
> >>>>>>>>>>>>> 1 file changed, 2 insertions(+)
> >>>>>>>>>>>>
> >>>>>>>>>>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> >>>>>>>>>>>
> >>>>>>>>>>> ... and then I looked at the driver. So un-reviewed. Devices are clearly
> >>>>>>>>>>> compatible. If not, explain what is not compatible.
> >>>>>>>>>>>
> >>>>>>>>>> Talos uses GCC_USB3_PRIM_PHY_AUX_CLK.
> >>>>>>>>>>
> >>>>>>>>>> In Shikra, we are using GCC_USB3_PRIM_PHY_COM_AUX_CLK. We don't have
> >>>>>>>>>> GCC_USB3_PRIM_PHY_AUX_CLK.
> >>>>>>>>>>
> >>>>>>>>>> Hence, I didn't use a fallback compatible.
> >>>>>>>>>
> >>>>>>>>> This still explains nothing. How different clock makes interface for SW
> >>>>>>>>> incompatible exactly?
> >>>>>>>>>
> >>>>>>>> So I went by the naming. AUX vs COM_AUX.
> >>>>>>>
> >>>>>>> The naming does not matter. If the clock is called
> >>>>>>> "no_one_expects_spanish_inquisition", does that make software
> >>>>>>> incompatible? Why would the name itself matter?
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Can I use a fallback compatible and in DT vote for "COM_AUX" clock with
> >>>>>>>> clock-names mentioning "aux" ?
> >>>>>>>
> >>>>>>> I don't know, I asked what is different in software interface.
> >>>>>>>
> >>>>>>
> >>>>>> Hi Krzysztof,
> >>>>>>
> >>>>>> I checked with the hw team here and found out two things.
> >>>>>>
> >>>>>> 1. Shikra is a spinoff of Agatti and its sw interface (clocks used and
> >>>>>> regulators used) is the same as agatti.
> >>>>>>
> >>>>>> 2. I thought we could use qcm2290 as a fallback since the phy register
> >>>>>> init sequence is the same for Talos/Shikra/Agatti. The difference
> >>>>>> between Talos and agatti when checked in the driver was the init load
> >>>>>> settings. I checked with the hw team and they suggested using the init
> >>>>>> load settings which talos was using.
> >>>>>>
> >>>>>> Hence both these compatibles (qcm2290 and qcs615) cannot be used as
> >>>>>> fallback for Shikra.
> >>>>>
> >>>>> Then I do not understand why you are using qcs615_usb3phy_cfg for
> >>>>> Shikra. You say that the initialization is different, but you use
> >>>>> exactly the same initialization. So in a meaning of compatibility
> >>>>> between hardware for Devicetree they are compatible.
> >>>>>
> >>>> Hi Krzysztof,
> >>>>
> >>>> There are 3 things:
> >>>>
> >>>> 1. Clocks used:
> >>>> -> Talos supports AUX Clock since it supports DP over USB.
> >>>> -> Agatti and Shikra use COM_AUX clock since they dont support DP over USB.
> >>>>
> >>>> 2. Phy register Init sequence - same for all 3 targets
> >>>>
> >>>> 3. Regulator init load:
> >>>> -> Different for both Talos and Agatti
> >>>> -> Recommendation is to use Talos regulator load values.
> >>>>
> >>>> SW interface wise, shikra is comaptible with agatti. If we use agatti as
> >>>> fallback, we would end up using the platform data of Agatti where the
> >>>> regulator init load is not suitable for Shikra. Hence not using Agatti
> >>>> as fallback.
> >>>>
> >>>> Coming to driver changes, I used qcs615_cfg because it has required phy
> >>>> register sequence and regulator init load as needed by shikra.
> >>>
> >>> So is it compatible with QCS615? If not, then something is incomplete or
> >>> confusing. The driver uses the same software interface.
> >>>
> >> Sorry for the confusion. The Talos compatible represents the USB/DP PHY with
> >> aux clock input, while Shikra is a USB-only PHY with com_aux input clock, so
> >> the two PHYs are not compatible with each other.
> >
> > According to the memory map, there is an (unused) DP registers part
> > right after the QMP USB3 PHY. So, sofware-wise it is compatible to
> > Talos. Having the different clock input means different integration of
> > the block rather than the differences in the hardware block.
> >
> > So, the block should be compatible to qcom,qcs615-qmp-usb3-dp-phy
>
> It should still carry its own compatible though, to let the driver
> disallow powering up the DP part
Why? The DP part is there, in the PHY, pretty much like it's present on
most of USBC platforms. I assume it can be powered on. There is no
point in it though as there is no DP controller (nor DP pins).
--
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 v2 2/2] phy: qcom: qmp-pcie: Add IPQ9650 PCIe PHY support
From: Dmitry Baryshkov @ 2026-06-12 7:56 UTC (permalink / raw)
To: Kathiravan Thirumoorthy
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260612-ipq9650_pcie_phy-v2-2-b938cc2fc267@qti.qualcomm.com>
On Fri, Jun 12, 2026 at 01:21:02PM +0530, Kathiravan Thirumoorthy wrote:
> From: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
>
> Add support for the IPQ9650 platform, which includes three Gen3 x2 PCIe
> controllers and two Gen3 x1 PCIe controllers. The PHY instances require
> the on-chip refgen supply.
>
> Add the IPQ9650 Gen3 x1 and x2 QMP PCIe PHY configurations along with
> the refgen regulator supply. Note that an on-chip LDO, driven by the SoC
> CX, supplies the PHY voltages without requiring software control. Note
> that IPQ9650 does not support CX power collapse or rail scaling.
>
> Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 220 +++++++++++++++++++++++++++++++
> 1 file changed, 220 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
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 2/2] phy: qcom: qmp-pcie: Add IPQ9650 PCIe PHY support
From: Kathiravan Thirumoorthy @ 2026-06-12 7:52 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <epxrpj52vst4zjigsn6ghaiajyzkwdtji2dvgrf7euag4indvf@wzhhy7wtuhhi>
On 6/12/2026 12:54 PM, Dmitry Baryshkov wrote:
> On Fri, Jun 12, 2026 at 12:13:04PM +0530, Kathiravan Thirumoorthy wrote:
>> On 6/12/2026 11:44 AM, Dmitry Baryshkov wrote:
>>> On Fri, Jun 12, 2026 at 08:22:02AM +0530, Kathiravan Thirumoorthy wrote:
>>>> On 6/12/2026 1:52 AM, Dmitry Baryshkov wrote:
>>>>> On Tue, Jun 09, 2026 at 03:46:56PM +0530, Kathiravan Thirumoorthy wrote:
>>>>>> On 6/8/2026 12:26 PM, Dmitry Baryshkov wrote:
>>>>>>> On Tue, Jun 02, 2026 at 02:40:18PM +0530, Kathiravan Thirumoorthy wrote:
>>>>>>>> The IPQ9650 platform has three Gen3 2-lane PCIe controllers and two Gen3
>>>>>>>> 1-lane PCIe controllers. The PHY instances also require the on-chip refgen
>>>>>>>> supply.
>>>>>>>>
>>>>>>>> Add the IPQ9650 Gen3 x1 and x2 QMP PCIe PHY configurations, including the
>>>>>>>> refgen regulator supply.
>>>>>>>>
>>>>>>>> Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
>>>>>>>> ---
>>>>>>>> drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 220 +++++++++++++++++++++++++++++++
>>>>>>>> 1 file changed, 220 insertions(+)
>>>>>>>>
>>>>>>>> @@ -3378,6 +3524,10 @@ static const char * const qmp_phy_vreg_l[] = {
>>>>>>>> "vdda-phy", "vdda-pll",
>>>>>>>> };
>>>>>>>> +static const char * const ipq9650_qmp_phy_vreg_l[] = {
>>>>>>>> + "refgen",
>>>>>>>> +};
>>>>>>> Now vdda-phy / vdda-pll supplies?
>>>>>> Cross checked with HW team again. Along with refgen, there is a on-chip LDO
>>>>>> which supplies fixed voltage to the PHYs. It is enabled upon system power on
>>>>>> and no SW intervention is required.
>>>>> What is it being powered by? MX? CX?
>>>> It is driven by CX.
>>> I assume that there is no CX collapse on IPQ9650? Is CX not scaling on
>>> this chip. Please provide some details on the commit message.
>> That's right. No CX collapse on IPQ9650. Let me rewrite the commit message
>> as below. Hope its okay.
>>
>> --
>>
>> Add support for the IPQ9650 platform, which includes three Gen3 x2 PCIe
>> controllers and two Gen3 x1 PCIe controllers. The PHY instances require the
>> on-chip refgen supply.
>>
>> Add the IPQ9650 Gen3 x1 and x2 QMP PCIe PHY configurations along with the
>> refgen regulator supply. Note that an on-chip LDO, driven by the SoC CX,
>> supplies the PHY voltages without requiring software control. Note that CX
>> power collapse is not supported on IPQ9650.
> ...neither CX power collapse nor rail scaling...
>
> LGTM.
Thanks much. Have sent V2. Please have a look.
>
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v2 2/2] phy: qcom: qmp-pcie: Add IPQ9650 PCIe PHY support
From: Kathiravan Thirumoorthy @ 2026-06-12 7:51 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Kathiravan Thirumoorthy
In-Reply-To: <20260612-ipq9650_pcie_phy-v2-0-b938cc2fc267@qti.qualcomm.com>
From: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
Add support for the IPQ9650 platform, which includes three Gen3 x2 PCIe
controllers and two Gen3 x1 PCIe controllers. The PHY instances require
the on-chip refgen supply.
Add the IPQ9650 Gen3 x1 and x2 QMP PCIe PHY configurations along with
the refgen regulator supply. Note that an on-chip LDO, driven by the SoC
CX, supplies the PHY voltages without requiring software control. Note
that IPQ9650 does not support CX power collapse or rail scaling.
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 220 +++++++++++++++++++++++++++++++
1 file changed, 220 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index d3effad7a074..1b94c411321a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -857,6 +857,152 @@ static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
};
+static const struct qmp_phy_init_tbl ipq9650_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_TIMER1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xd4),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x53),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x29),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x7d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xa2),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x13),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xb5),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_HIGHZ_DRVR_EN, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xb5),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x00),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_VGA_GAIN2_LSB, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_VGA_GAIN2_MSB, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_PRE_THRESH1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_PRE_THRESH2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_POST_THRESH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_MAIN_THRESH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x67),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x35),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x25),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB, 0x10),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_DCC_CAL_CONFIG, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_pcie_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x1c),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0b),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P2_P3_POST, 0x34),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_POST, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
+};
+
static const struct qmp_phy_init_tbl qcs615_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V2_COM_CLK_ENABLE1, 0x10),
@@ -3484,6 +3630,10 @@ static const char * const qmp_phy_vreg_l[] = {
"vdda-phy", "vdda-pll",
};
+static const char * const ipq9650_qmp_phy_vreg_l[] = {
+ "refgen",
+};
+
static const char * const sm8550_qmp_phy_vreg_l[] = {
"vdda-phy", "vdda-pll", "vdda-qref",
};
@@ -3527,6 +3677,14 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v4x1 = {
.rx = 0x0400,
};
+static const struct qmp_pcie_offsets qmp_pcie_offsets_9650_v4x1 = {
+ .serdes = 0,
+ .pcs = 0x0600,
+ .pcs_misc = 0x0a00,
+ .tx = 0x0200,
+ .rx = 0x0400,
+};
+
static const struct qmp_pcie_offsets qmp_pcie_offsets_v4x2 = {
.serdes = 0,
.pcs = 0x0a00,
@@ -3802,6 +3960,62 @@ static const struct qmp_phy_cfg ipq9574_gen3x2_pciephy_cfg = {
.pipe_clock_rate = 250000000,
};
+static const struct qmp_phy_cfg ipq9650_gen3x1_pciephy_cfg = {
+ .lanes = 1,
+
+ .offsets = &qmp_pcie_offsets_9650_v4x1,
+
+ .tbls = {
+ .serdes = ipq9650_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(ipq9650_pcie_serdes_tbl),
+ .tx = ipq9650_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(ipq9650_pcie_tx_tbl),
+ .rx = ipq9650_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(ipq9650_pcie_rx_tbl),
+ .pcs = ipq9650_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(ipq9650_pcie_pcs_tbl),
+ .pcs_misc = ipq9650_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(ipq9650_pcie_pcs_misc_tbl),
+ },
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = ipq9650_qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(ipq9650_qmp_phy_vreg_l),
+ .regs = pciephy_v4_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+ .pipe_clock_rate = 250000000,
+};
+
+static const struct qmp_phy_cfg ipq9650_gen3x2_pciephy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_pcie_offsets_v4x2,
+
+ .tbls = {
+ .serdes = ipq9650_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(ipq9650_pcie_serdes_tbl),
+ .tx = ipq9650_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(ipq9650_pcie_tx_tbl),
+ .rx = ipq9650_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(ipq9650_pcie_rx_tbl),
+ .pcs = ipq9650_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(ipq9650_pcie_pcs_tbl),
+ .pcs_misc = ipq9650_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(ipq9650_pcie_pcs_misc_tbl),
+ },
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = ipq9650_qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(ipq9650_qmp_phy_vreg_l),
+ .regs = pciephy_v4_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+ .pipe_clock_rate = 250000000,
+};
+
static const struct qmp_phy_cfg qcs615_pciephy_cfg = {
.lanes = 1,
@@ -5558,6 +5772,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy",
.data = &ipq9574_gen3x2_pciephy_cfg,
+ }, {
+ .compatible = "qcom,ipq9650-qmp-gen3x1-pcie-phy",
+ .data = &ipq9650_gen3x1_pciephy_cfg,
+ }, {
+ .compatible = "qcom,ipq9650-qmp-gen3x2-pcie-phy",
+ .data = &ipq9650_gen3x2_pciephy_cfg,
}, {
.compatible = "qcom,kaanapali-qmp-gen3x2-pcie-phy",
.data = &qmp_v8_gen3x2_pciephy_cfg,
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 1/2] dt-bindings: phy: qcom,ipq8074-qmp-pcie: document IPQ9650 QMP PCIe PHYs
From: Kathiravan Thirumoorthy @ 2026-06-12 7:51 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Kathiravan Thirumoorthy, Krzysztof Kozlowski
In-Reply-To: <20260612-ipq9650_pcie_phy-v2-0-b938cc2fc267@qti.qualcomm.com>
From: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
Document the single-lane and dual-lane QMP PCIe PHYs found on the
IPQ9650 SoC.
Unlike the PHYs in the other supported IPQ SoCs, the IPQ9650 PHYs require
the on-chip refgen supply to power up. Add the refgen-supply property
and require it only for the IPQ9650 compatibles.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
---
.../bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
index f60804687412..048b2e3ff0ef 100644
--- a/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
@@ -22,6 +22,8 @@ properties:
- qcom,ipq8074-qmp-pcie-phy
- qcom,ipq9574-qmp-gen3x1-pcie-phy
- qcom,ipq9574-qmp-gen3x2-pcie-phy
+ - qcom,ipq9650-qmp-gen3x1-pcie-phy
+ - qcom,ipq9650-qmp-gen3x2-pcie-phy
- items:
- enum:
- qcom,ipq5424-qmp-gen3x1-pcie-phy
@@ -61,6 +63,8 @@ properties:
"#phy-cells":
const: 0
+ refgen-supply: true
+
required:
- compatible
- reg
@@ -72,6 +76,21 @@ required:
- clock-output-names
- "#phy-cells"
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq9650-qmp-gen3x1-pcie-phy
+ - qcom,ipq9650-qmp-gen3x2-pcie-phy
+ then:
+ required:
+ - refgen-supply
+ else:
+ properties:
+ refgen-supply: false
+
additionalProperties: false
examples:
--
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