* [PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board
@ 2025-07-18 6:26 Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
` (4 more replies)
0 siblings, 5 replies; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 6:26 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs. For USB
Type-C interfaces, an external chip assists the PHY in handling
altmode switching and orientation switching.
Their connection diagram is shown below:
external Type-C Chip0 ---> USB/DP PHY0 ---+
| <----> CDN-DP controller
external Type-C Chip1 ---> USB/DP PHY1 ---+
The RK3399 EVB IND board has a Type-C interface DisplayPort. It use
fusb302 chip as Type-C controller. The connection diagram is shown below:
fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller
This series focuses on adding TCPM support for USBDP PHY and DP driver.
Before this, the USBDP PHY and DP controller of RK3399 sensed state
changes through extcon, and devices such as the RK3399 Gru-Chromebook
rely on them. This series should not break them.
BTW, one of the important things to do is to implement extcon-like
notifications. I found include/drm/bridge/aux-bridge.h , but if the
aux-bridge is used, the bridge chain would look like this:
PHY0 aux-bridge ---+
| ----> CDN-DP bridge
PHY1 aux-bridge ---+
Oh, CDN-DP bridge has two previous aux-bridge!
Now, I try to use drm_connector_oob_hotplug_event() to notify HPD
state between PHY and CDN-DP controller.
Patch1 add new Type-C mode switch for RK3399 USBDP phy binding.
Patch2 add typec_mux and typec_switch for RK3399 USBDP PHY.
Patch3 drops CDN-DP's extcon dependency when Type-C is present.
Patch4 add missing dp_out port for RK3399 CDN-DP.
Patch5 add Type-C DP support for RK3399 EVB IND board.
Changes in v2:
- Link to V1: https://lore.kernel.org/all/20250715112456.101-1-kernel@airkyi.com/
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.
- Ignore duplicate HPD events.
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.
Chaoyi Chen (5):
dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon
arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
.../phy/rockchip,rk3399-typec-phy.yaml | 4 +
arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 12 +-
.../boot/dts/rockchip/rk3399-evb-ind.dts | 133 ++++++
drivers/gpu/drm/rockchip/cdn-dp-core.c | 37 +-
drivers/phy/rockchip/phy-rockchip-typec.c | 403 +++++++++++++++++-
5 files changed, 564 insertions(+), 25 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
2025-07-18 6:26 [PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
@ 2025-07-18 6:26 ` Chaoyi Chen
2025-07-18 8:10 ` Krzysztof Kozlowski
2025-07-18 6:26 ` [PATCH v2 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Chaoyi Chen
` (3 subsequent siblings)
4 siblings, 1 reply; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 6:26 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
The RK3399 has two USB/DP combo PHY. With the help of external Type-C
controller, the PHY can switch altmode between USB and DP.
Their connection diagram is shown below:
external Type-C Chip0 ---> USB/DP PHY0 ---+
| <----> CDN-DP controller
external Type-C Chip1 ---> USB/DP PHY1 ---+
This patch add new "mode-switch" property for dp-port to indicate
whether the PHY can handle altmode switching.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.
.../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
index 91c011f68cd0..d503de7c7569 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,10 @@ properties:
'#phy-cells':
const: 0
+ mode-switch:
+ description: Flag the port as possible handler of altmode switching
+ type: boolean
+
port:
$ref: /schemas/graph.yaml#/properties/port
description: Connection to USB Type-C connector
--
2.49.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
2025-07-18 6:26 [PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
@ 2025-07-18 6:26 ` Chaoyi Chen
2025-07-19 7:42 ` kernel test robot
2025-07-18 6:26 ` [PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon Chaoyi Chen
` (2 subsequent siblings)
4 siblings, 1 reply; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 6:26 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
This patch add support for Type-C Port Controller Manager. Each PHY
will register typec_mux and typec_switch when external Type-C
controller is present. Type-C events are handled by TCPM without
extcon.
The extcon device should still be supported.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
Changes in v2:
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.
drivers/phy/rockchip/phy-rockchip-typec.c | 403 +++++++++++++++++++++-
1 file changed, 387 insertions(+), 16 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index d9701b6106d5..6334953a225e 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -47,6 +47,7 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -54,6 +55,9 @@
#include <linux/mfd/syscon.h>
#include <linux/phy/phy.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
+#include <drm/drm_connector.h>
#define CMN_SSM_BANDGAP (0x21 << 2)
#define CMN_SSM_BIAS (0x22 << 2)
@@ -286,12 +290,23 @@
#define RX_DIAG_SC2C_DELAY (0x81e1 << 2)
#define PMA_LANE_CFG (0xc000 << 2)
+#define PMA_LANE3_DP_LANE_SEL(x) (((x) & 0x3) << 14)
+#define PMA_LANE3_INTERFACE_SEL(x) (((x) & 0x1) << 12)
+#define PMA_LANE2_DP_LANE_SEL(x) (((x) & 0x3) << 10)
+#define PMA_LANE2_INTERFACE_SEL(x) (((x) & 0x1) << 8)
+#define PMA_LANE1_DP_LANE_SEL(x) (((x) & 0x3) << 6)
+#define PMA_LANE1_INTERFACE_SEL(x) (((x) & 0x1) << 4)
+#define PMA_LANE0_DP_LANE_SEL(x) (((x) & 0x3) << 2)
+#define PMA_LANE0_INTERFACE_SEL(x) (((x) & 0x1) << 0)
#define PIPE_CMN_CTRL1 (0xc001 << 2)
#define PIPE_CMN_CTRL2 (0xc002 << 2)
#define PIPE_COM_LOCK_CFG1 (0xc003 << 2)
#define PIPE_COM_LOCK_CFG2 (0xc004 << 2)
#define PIPE_RCV_DET_INH (0xc005 << 2)
#define DP_MODE_CTL (0xc008 << 2)
+#define PHY_DP_POWER_STATE_ACK_MASK GENMASK(7, 4)
+#define PHY_DP_POWER_STATE_ACK_SHIFT 4
+#define PHY_DP_POWER_STATE_MASK GENMASK(3, 0)
#define DP_CLK_CTL (0xc009 << 2)
#define STS (0xc00F << 2)
#define PHY_ISO_CMN_CTRL (0xc010 << 2)
@@ -327,8 +342,15 @@
#define DP_MODE_A0 BIT(4)
#define DP_MODE_A2 BIT(6)
-#define DP_MODE_ENTER_A0 0xc101
-#define DP_MODE_ENTER_A2 0xc104
+
+#define DP_MODE_MASK 0xf
+#define DP_MODE_ENTER_A0 BIT(0)
+#define DP_MODE_ENTER_A2 BIT(2)
+#define DP_MODE_ENTER_A3 BIT(3)
+#define DP_MODE_A0_ACK BIT(4)
+#define DP_MODE_A2_ACK BIT(6)
+#define DP_MODE_A3_ACK BIT(7)
+#define DP_LINK_RESET_DEASSERTED BIT(8)
#define PHY_MODE_SET_TIMEOUT 100000
@@ -340,6 +362,31 @@
#define MODE_DFP_USB BIT(1)
#define MODE_DFP_DP BIT(2)
+enum phy_dp_lane_num {
+ PHY_DP_LANE_0 = 0,
+ PHY_DP_LANE_1,
+ PHY_DP_LANE_2,
+ PHY_DP_LANE_3,
+};
+
+enum phy_pma_if {
+ PMA_IF_PIPE_PCS = 0,
+ PMA_IF_PHY_DP,
+};
+
+enum phy_typec_role {
+ TYPEC_PHY_USB = 0,
+ TYPEC_PHY_DP,
+ TYPEC_PHY_MAX,
+};
+
+enum phy_dp_power_state {
+ PHY_DP_POWER_STATE_A0 = 0,
+ PHY_DP_POWER_STATE_A1,
+ PHY_DP_POWER_STATE_A2,
+ PHY_DP_POWER_STATE_A3,
+};
+
struct usb3phy_reg {
u32 offset;
u32 enable_bit;
@@ -372,18 +419,23 @@ struct rockchip_typec_phy {
struct device *dev;
void __iomem *base;
struct extcon_dev *extcon;
+ struct fwnode_handle *connector_fwnode;
+ struct typec_mux_dev *mux;
+ struct typec_switch_dev *sw;
struct regmap *grf_regs;
struct clk *clk_core;
struct clk *clk_ref;
struct reset_control *uphy_rst;
struct reset_control *pipe_rst;
struct reset_control *tcphy_rst;
+ struct phy *phys[TYPEC_PHY_MAX];
const struct rockchip_usb3phy_port_cfg *port_cfgs;
/* mutex to protect access to individual PHYs */
struct mutex lock;
bool flip;
u8 mode;
+ u8 new_mode;
};
struct phy_reg {
@@ -454,6 +506,99 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
{ /* sentinel */ }
};
+static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
+ bool value);
+
+static int tcphy_dp_set_power_state(struct rockchip_typec_phy *tcphy,
+ enum phy_dp_power_state state)
+{
+ u32 ack, reg, sts = BIT(state);
+ int ret;
+
+ /*
+ * Power state changes must not be requested until after the cmn_ready
+ * signal has gone active.
+ */
+ reg = readl(tcphy->base + PMA_CMN_CTRL1);
+ if (!(reg & CMN_READY)) {
+ dev_err(tcphy->dev, "cmn_ready in the inactive state\n");
+ return -EINVAL;
+ }
+
+ reg = readl(tcphy->base + DP_MODE_CTL);
+ reg &= ~PHY_DP_POWER_STATE_MASK;
+ reg |= sts;
+ writel(reg, tcphy->base + DP_MODE_CTL);
+
+ ret = readl_poll_timeout(tcphy->base + DP_MODE_CTL,
+ ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >>
+ PHY_DP_POWER_STATE_ACK_SHIFT) == sts), 10,
+ PHY_MODE_SET_TIMEOUT);
+ if (ret < 0) {
+ dev_err(tcphy->dev, "failed to enter power state %d\n", state);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * For the TypeC PHY, the 4 lanes are mapping to the USB TypeC receptacle pins
+ * as follows:
+ * -------------------------------------------------------------------
+ * PHY Lanes/Module Pins TypeC Receptacle Pins
+ * -------------------------------------------------------------------
+ * Lane0 (tx_p/m_ln_0) TX1+/TX1- (pins A2/A3)
+ * Lane1 (tx_rx_p/m_ln_1) RX1+/RX1- (pins B11/B10)
+ * Lane2 (tx_rx_p/m_ln_2) RX2+/RX2- (pins A11/A10)
+ * Lane3 (tx_p/m_ln_3) TX2+/TX2- (pins B2/B3)
+ * -------------------------------------------------------------------
+ *
+ * USB and DP lanes mapping to TypeC PHY lanes for each of pin assignment
+ * options (normal connector orientation) described in the VESA DisplayPort
+ * Alt Mode on USB TypeC Standard as follows:
+ *
+ * ----------------------------------------------------------------------
+ * PHY Lanes A B C D E F
+ * ----------------------------------------------------------------------
+ * 0 ML1 SSTX ML2 SSTX ML2 SSTX
+ * 1 ML3 SSRX ML3 SSRX ML3 SSRX
+ * 2 ML2 ML1 ML0 ML0 ML0 ML0
+ * 3 ML0 ML0 ML1 ML1 ML1 ML1
+ * ----------------------------------------------------------------------
+ */
+static void tcphy_set_lane_mapping(struct rockchip_typec_phy *tcphy, u8 mode)
+{
+ /*
+ * The PMA_LANE_CFG register is used to select whether a PMA lane
+ * is mapped for USB or PHY DP. The PMA_LANE_CFG register is
+ * configured based on a normal connector orientation. Logic in the
+ * PHY automatically handles the flipped connector case based on the
+ * setting of orientation of TypeC PHY.
+ */
+ if (mode == MODE_DFP_DP) {
+ /* This maps to VESA DP Alt Mode pin assignments C and E. */
+ writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+ PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+ PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE1_DP_LANE_SEL(PHY_DP_LANE_3) |
+ PMA_LANE1_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE0_DP_LANE_SEL(PHY_DP_LANE_2) |
+ PMA_LANE0_INTERFACE_SEL(PMA_IF_PHY_DP),
+ tcphy->base + PMA_LANE_CFG);
+ } else {
+ /* This maps to VESA DP Alt Mode pin assignments D and F. */
+ writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+ PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+ PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE1_INTERFACE_SEL(PMA_IF_PIPE_PCS) |
+ PMA_LANE0_INTERFACE_SEL(PMA_IF_PIPE_PCS),
+ tcphy->base + PMA_LANE_CFG);
+ }
+}
+
static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
{
u32 i, rdata;
@@ -743,8 +888,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
tcphy_dp_aux_set_flip(tcphy);
tcphy_cfg_24m(tcphy);
+ tcphy_set_lane_mapping(tcphy, mode);
if (mode == MODE_DFP_DP) {
+ tcphy_cfg_usb3_to_usb2_only(tcphy, true);
tcphy_cfg_dp_pll(tcphy);
for (i = 0; i < 4; i++)
tcphy_dp_cfg_lane(tcphy, i);
@@ -768,7 +915,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
}
- writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+ val = readl(tcphy->base + DP_MODE_CTL);
+ val &= ~DP_MODE_MASK;
+ val |= DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED;
+ writel(val, tcphy->base + DP_MODE_CTL);
reset_control_deassert(tcphy->uphy_rst);
@@ -811,8 +961,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
u8 mode;
int ret, ufp, dp;
+ /* If extcon not exist, try to use tcpm mode */
if (!edev)
- return MODE_DFP_USB;
+ return tcphy->new_mode;
ufp = extcon_get_state(edev, EXTCON_USB);
dp = extcon_get_state(edev, EXTCON_DISP_DP);
@@ -850,6 +1001,72 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
return mode;
}
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_orien_sw_set(struct typec_switch_dev *sw,
+ enum typec_orientation orien)
+{
+ struct rockchip_typec_phy *tcphy = typec_switch_get_drvdata(sw);
+
+ mutex_lock(&tcphy->lock);
+
+ if (orien == TYPEC_ORIENTATION_NONE) {
+ tcphy->new_mode = MODE_DISCONNECT;
+ goto unlock_ret;
+ }
+
+ tcphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
+ tcphy->new_mode = MODE_DFP_USB;
+
+unlock_ret:
+ mutex_unlock(&tcphy->lock);
+ return 0;
+}
+
+static void udphy_orien_switch_unregister(void *data)
+{
+ struct rockchip_typec_phy *tcphy = data;
+
+ typec_switch_unregister(tcphy->sw);
+}
+
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+ struct typec_switch_desc sw_desc = { };
+ struct device_node *np;
+ int ret = 0;
+
+ np = of_get_child_by_name(tcphy->dev->of_node, "usb3-port");
+ if (!np)
+ return 0;
+
+ if (!of_property_read_bool(np, "orientation-switch"))
+ goto put_np;
+
+ sw_desc.drvdata = tcphy;
+ sw_desc.fwnode = device_get_named_child_node(tcphy->dev, "usb3-port");
+ sw_desc.set = tcphy_orien_sw_set;
+
+ tcphy->sw = typec_switch_register(tcphy->dev, &sw_desc);
+ if (IS_ERR(tcphy->sw)) {
+ dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n",
+ PTR_ERR(tcphy->sw));
+ ret = PTR_ERR(tcphy->sw);
+ goto put_np;
+ }
+
+ ret = devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregister, tcphy);
+
+put_np:
+ of_node_put(np);
+ return ret;
+}
+#else
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+ return 0;
+}
+#endif
+
static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
bool value)
{
@@ -989,14 +1206,9 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
tcphy_dp_aux_calibration(tcphy);
- writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
-
- ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
- val, val & DP_MODE_A0, 1000,
- PHY_MODE_SET_TIMEOUT);
- if (ret < 0) {
- writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
- dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
+ ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A0);
+ if (ret) {
+ dev_err(tcphy->dev, "failed to enter A0 power state\n");
goto power_on_finish;
}
@@ -1013,6 +1225,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
static int rockchip_dp_phy_power_off(struct phy *phy)
{
struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
+ int ret;
mutex_lock(&tcphy->lock);
@@ -1021,7 +1234,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
tcphy->mode &= ~MODE_DFP_DP;
- writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+ ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A2);
+ if (ret) {
+ dev_err(tcphy->dev, "failed to enter A2 power state\n");
+ goto unlock;
+ }
if (tcphy->mode == MODE_DISCONNECT)
tcphy_phy_deinit(tcphy);
@@ -1037,6 +1254,94 @@ static const struct phy_ops rockchip_dp_phy_ops = {
.owner = THIS_MODULE,
};
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+{
+ struct rockchip_typec_phy *tcphy = typec_mux_get_drvdata(mux);
+ struct typec_displayport_data *data;
+ int hpd = 0;
+
+ mutex_lock(&tcphy->lock);
+
+ switch (state->mode) {
+ case TYPEC_STATE_SAFE:
+ fallthrough;
+ case TYPEC_STATE_USB:
+ tcphy->new_mode = MODE_DFP_USB;
+ phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0);
+ break;
+ case TYPEC_DP_STATE_C:
+ case TYPEC_DP_STATE_E:
+ tcphy->new_mode = MODE_DFP_DP;
+ data = state->data;
+ hpd = !!(data->status & DP_STATUS_HPD_STATE);
+ phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0);
+ break;
+ case TYPEC_DP_STATE_D:
+ tcphy->new_mode = MODE_DFP_DP | MODE_DFP_USB;
+ data = state->data;
+ hpd = !!(data->status & DP_STATUS_HPD_STATE);
+ phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0);
+ break;
+ default:
+ break;
+ }
+
+ mutex_unlock(&tcphy->lock);
+
+ if (state->alt && state->alt->svid == USB_TYPEC_DP_SID)
+ drm_connector_oob_hotplug_event(tcphy->connector_fwnode,
+ hpd ? connector_status_connected :
+ connector_status_disconnected);
+
+ return 0;
+}
+
+static void tcphy_typec_mux_unregister(void *data)
+{
+ struct rockchip_typec_phy *tcphy = data;
+
+ typec_mux_unregister(tcphy->mux);
+}
+
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+ struct typec_mux_desc mux_desc = {};
+ struct device_node *np;
+ int ret = 0;
+
+ np = of_get_child_by_name(tcphy->dev->of_node, "dp-port");
+ if (!np)
+ return 0;
+
+ if (!of_property_read_bool(np, "mode-switch"))
+ goto put_np;
+
+ mux_desc.drvdata = tcphy;
+ mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
+ mux_desc.set = tcphy_typec_mux_set;
+
+ tcphy->mux = typec_mux_register(tcphy->dev, &mux_desc);
+ if (IS_ERR(tcphy->mux)) {
+ dev_err(tcphy->dev, "Error register typec mux: %ld\n",
+ PTR_ERR(tcphy->mux));
+ ret = PTR_ERR(tcphy->mux);
+ goto put_np;
+ }
+
+ ret = devm_add_action_or_reset(tcphy->dev, tcphy_typec_mux_unregister, tcphy);
+
+put_np:
+ of_node_put(np);
+ return ret;
+}
+#else
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+ return 0;
+}
+#endif
+
static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
struct device *dev)
{
@@ -1095,6 +1400,53 @@ static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy)
tcphy->mode = MODE_DISCONNECT;
}
+static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy)
+{
+ int dp_lanes;
+
+ switch (tcphy->new_mode) {
+ case MODE_DFP_DP:
+ dp_lanes = 4;
+ break;
+ case MODE_DFP_DP | MODE_DFP_USB:
+ dp_lanes = 2;
+ break;
+ default:
+ dp_lanes = 0;
+ break;
+ }
+
+ return dp_lanes;
+}
+
+static void rockchip_dp_connector_fwnode_get(struct rockchip_typec_phy *tcphy)
+{
+ struct device *dev = tcphy->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *dp_port;
+ struct device_node *ep;
+ struct device_node *remote;
+
+ dp_port = of_get_child_by_name(np, "dp-port");
+ if (!dp_port)
+ return;
+
+ ep = of_graph_get_endpoint_by_regs(dp_port, -1, 1); /* endpoint@1 */
+ if (!ep)
+ goto put_dp_port;
+
+ remote = of_graph_get_remote_port_parent(ep);
+ if (!remote)
+ goto put_ep;
+
+ tcphy->connector_fwnode = fwnode_handle_get(of_fwnode_handle(remote));
+
+put_ep:
+ of_node_put(ep);
+put_dp_port:
+ of_node_put(dp_port);
+}
+
static int rockchip_typec_phy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1142,6 +1494,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
return ret;
tcphy->dev = dev;
+ tcphy->new_mode = MODE_DFP_USB;
platform_set_drvdata(pdev, tcphy);
mutex_init(&tcphy->lock);
@@ -1151,6 +1504,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
if (IS_ERR(tcphy->extcon)) {
if (PTR_ERR(tcphy->extcon) == -ENODEV) {
tcphy->extcon = NULL;
+ dev_info(dev, "extcon not exist, try to use typec mux\n");
} else {
if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER)
dev_err(dev, "Invalid or missing extcon\n");
@@ -1158,19 +1512,36 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
}
}
+ ret = tcphy_setup_orien_switch(tcphy);
+ if (ret)
+ return ret;
+
+ ret = tcphy_setup_typec_mux(tcphy);
+ if (ret)
+ return ret;
+
+ rockchip_dp_connector_fwnode_get(tcphy);
+
pm_runtime_enable(dev);
for_each_available_child_of_node(np, child_np) {
struct phy *phy;
- if (of_node_name_eq(child_np, "dp-port"))
+ if (of_node_name_eq(child_np, "dp-port")) {
phy = devm_phy_create(dev, child_np,
&rockchip_dp_phy_ops);
- else if (of_node_name_eq(child_np, "usb3-port"))
+ if (!IS_ERR(phy)) {
+ tcphy->phys[TYPEC_PHY_DP] = phy;
+ phy_set_bus_width(phy, typec_dp_lane_get(tcphy));
+ }
+ } else if (of_node_name_eq(child_np, "usb3-port")) {
phy = devm_phy_create(dev, child_np,
&rockchip_usb3_phy_ops);
- else
+ if (!IS_ERR(phy))
+ tcphy->phys[TYPEC_PHY_USB] = phy;
+ } else {
continue;
+ }
if (IS_ERR(phy)) {
dev_err(dev, "failed to create phy: %pOFn\n",
--
2.49.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon
2025-07-18 6:26 [PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Chaoyi Chen
@ 2025-07-18 6:26 ` Chaoyi Chen
2025-07-19 10:53 ` Dmitry Baryshkov
2025-07-18 6:26 ` [PATCH v2 4/5] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
4 siblings, 1 reply; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 6:26 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
This patch add support for get PHY lane info and handle HPD state
without help of extcon.
There is no extcon needed if the Type-C controller is present. In this
case, cdn_dp_hpd_notify() will handle HPD event from USB/DP combo PHY,
and the lane info can be get from PHY instead of extcon.
The extcon device should still be supported if Type-C controller is
not present.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
Changes in v2:
- Ignore duplicate HPD events.
drivers/gpu/drm/rockchip/cdn-dp-core.c | 37 ++++++++++++++++++++------
1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 24f6b3879f4b..b574b059b58d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *port)
int dptx;
u8 lanes;
+ if (!edev)
+ return phy_get_bus_width(port->phy);
+
dptx = extcon_get_state(edev, EXTCON_DISP_DP);
if (dptx > 0) {
extcon_get_property(edev, EXTCON_DISP_DP,
@@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
* some docks need more time to power up.
*/
while (time_before(jiffies, timeout)) {
- if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
+ if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP))
return false;
if (!cdn_dp_get_sink_count(dp, &sink_count))
@@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
goto err_power_on;
}
- ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
- EXTCON_PROP_USB_TYPEC_POLARITY, &property);
- if (ret) {
- DRM_DEV_ERROR(dp->dev, "get property failed\n");
- goto err_power_on;
+ property.intval = 0;
+ if (port->extcon) {
+ ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
+ EXTCON_PROP_USB_TYPEC_POLARITY, &property);
+ if (ret) {
+ DRM_DEV_ERROR(dp->dev, "get property failed\n");
+ goto err_power_on;
+ }
}
port->lanes = cdn_dp_get_port_lanes(port);
@@ -821,6 +827,17 @@ static int cdn_dp_audio_mute_stream(struct drm_connector *connector,
return ret;
}
+static void cdn_dp_hpd_notify(struct drm_bridge *bridge,
+ enum drm_connector_status status)
+{
+ struct cdn_dp_device *dp = bridge_to_dp(bridge);
+ enum drm_connector_status last_status =
+ dp->connected ? connector_status_connected : connector_status_disconnected;
+
+ if (last_status != status)
+ schedule_work(&dp->event_work);
+}
+
static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -831,6 +848,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
.atomic_disable = cdn_dp_bridge_atomic_disable,
.mode_valid = cdn_dp_bridge_mode_valid,
.mode_set = cdn_dp_bridge_mode_set,
+ .hpd_notify = cdn_dp_hpd_notify,
.dp_audio_prepare = cdn_dp_audio_prepare,
.dp_audio_mute_stream = cdn_dp_audio_mute_stream,
@@ -1028,6 +1046,9 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
+ if (!port->extcon)
+ continue;
+
port->event_nb.notifier_call = cdn_dp_pd_event;
ret = devm_extcon_register_notifier(dp->dev, port->extcon,
EXTCON_DISP_DP,
@@ -1120,14 +1141,14 @@ static int cdn_dp_probe(struct platform_device *pdev)
PTR_ERR(phy) == -EPROBE_DEFER)
return -EPROBE_DEFER;
- if (IS_ERR(extcon) || IS_ERR(phy))
+ if (IS_ERR(phy) || PTR_ERR(extcon) != -ENODEV)
continue;
port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
- port->extcon = extcon;
+ port->extcon = IS_ERR(extcon) ? NULL : extcon;
port->phy = phy;
port->dp = dp;
port->id = i;
--
2.49.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 4/5] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
2025-07-18 6:26 [PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (2 preceding siblings ...)
2025-07-18 6:26 ` [PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon Chaoyi Chen
@ 2025-07-18 6:26 ` Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
4 siblings, 0 replies; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 6:26 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Let's make the ports nodes of cdn_dp in the same style as the other
display interface, and match the style of ports's yaml.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
index 9d5f5b083e3c..edeb177bc433 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
@@ -618,7 +618,11 @@ cdn_dp: dp@fec00000 {
status = "disabled";
ports {
- dp_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dp_in: port@0 {
+ reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
@@ -632,6 +636,12 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+ dp_out: port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
};
--
2.49.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
2025-07-18 6:26 [PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (3 preceding siblings ...)
2025-07-18 6:26 ` [PATCH v2 4/5] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Chaoyi Chen
@ 2025-07-18 6:26 ` Chaoyi Chen
2025-07-18 8:12 ` Krzysztof Kozlowski
` (2 more replies)
4 siblings, 3 replies; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 6:26 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
The RK3399 EVB IND board has a Type-C interface DisplayPort.
It use fusb302 chip as Type-C controller.
fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
Changes in v2:
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.
.../boot/dts/rockchip/rk3399-evb-ind.dts | 133 ++++++++++++++++++
1 file changed, 133 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
index 70aee1ab904c..997b822a57ff 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
@@ -4,6 +4,7 @@
*/
/dts-v1/;
+#include <dt-bindings/usb/pd.h>
#include "rk3399.dtsi"
/ {
@@ -19,6 +20,21 @@ chosen {
stdout-path = "serial2:1500000n8";
};
+ sound: sound {
+ compatible = "rockchip,rk3399-gru-sound";
+ rockchip,cpu = <&i2s0 &spdif>;
+ };
+
+ vbus_typec: regulator-vbus-typec {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_typec0_en>;
+ regulator-name = "vbus_typec";
+ vin-supply = <&vcc5v0_sys>;
+ };
+
vcc5v0_sys: regulator-vcc5v0-sys {
compatible = "regulator-fixed";
enable-active-high;
@@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys {
};
};
+&cdn_dp {
+ phys = <&tcphy0_dp>;
+ status = "okay";
+};
+
&cpu_b0 {
cpu-supply = <&vdd_cpu_b>;
};
@@ -55,6 +76,12 @@ &cpu_l3 {
cpu-supply = <&vdd_cpu_l>;
};
+&dp_out {
+ dp_controller_output: endpoint {
+ remote-endpoint = <&dp_phy_in>;
+ };
+};
+
&emmc_phy {
status = "okay";
};
@@ -341,6 +368,63 @@ regulator-state-mem {
};
};
+&i2c4 {
+ i2c-scl-rising-time-ns = <475>;
+ i2c-scl-falling-time-ns = <26>;
+ status = "okay";
+
+ usbc0: typec-portc@22 {
+ compatible = "fcs,fusb302";
+ reg = <0x22>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbc0_int>;
+ vbus-supply = <&vbus_typec>;
+
+ usb_con: connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "dual";
+ power-role = "dual";
+ try-power-role = "sink";
+ op-sink-microwatt = <1000000>;
+ sink-pdos =
+ <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
+ source-pdos =
+ <PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
+
+ altmodes {
+ displayport {
+ svid = /bits/ 16 <0xff01>;
+ vdo = <0xffffffff>;
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usbc0_orien_sw: endpoint {
+ remote-endpoint = <&tcphy0_orientation_switch>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ dp_mode_sw: endpoint {
+ remote-endpoint = <&tcphy_dp_altmode_switch>;
+ };
+ };
+ };
+ };
+ };
+};
+
&i2s2 {
status = "okay";
};
@@ -354,6 +438,16 @@ &io_domains {
};
&pinctrl {
+ usb-typec {
+ usbc0_int: usbc0-int {
+ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ vcc5v0_typec0_en: vcc5v0-typec0-en {
+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -400,10 +494,48 @@ &sdmmc {
status = "okay";
};
+&sound {
+ rockchip,codec = <&cdn_dp>;
+ status = "okay";
+};
+
+&spdif {
+ status = "okay";
+};
+
&tcphy0 {
status = "okay";
};
+&tcphy0_dp {
+ mode-switch;
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tcphy_dp_altmode_switch: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&dp_mode_sw>;
+ };
+
+ dp_phy_in: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dp_controller_output>;
+ };
+ };
+};
+
+&tcphy0_usb3 {
+ orientation-switch;
+
+ port {
+ tcphy0_orientation_switch: endpoint {
+ remote-endpoint = <&usbc0_orien_sw>;
+ };
+ };
+};
+
&tcphy1 {
status = "okay";
};
@@ -461,6 +593,7 @@ &usb_host1_ohci {
};
&usbdrd_dwc3_0 {
+ usb-role-switch;
status = "okay";
};
--
2.49.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
2025-07-18 6:26 ` [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
@ 2025-07-18 8:10 ` Krzysztof Kozlowski
2025-07-18 10:39 ` Chaoyi Chen
0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-18 8:10 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov, devicetree, linux-kernel,
linux-phy, linux-arm-kernel, linux-rockchip, dri-devel
On Fri, Jul 18, 2025 at 02:26:15PM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>
> The RK3399 has two USB/DP combo PHY. With the help of external Type-C
> controller, the PHY can switch altmode between USB and DP.
>
> Their connection diagram is shown below:
>
> external Type-C Chip0 ---> USB/DP PHY0 ---+
> | <----> CDN-DP controller
> external Type-C Chip1 ---> USB/DP PHY1 ---+
It looks like your "external" controller is not described. Look at your
port property - "Connection to USB Type-C connector". Lack of proper
hardware description leads you to claim that the PHY is the mode switch.
I have doubts on that.
You already received the comments that you need to come with rationale
why making PHY a USB switch is correct. I don't see the arguments for
that.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
2025-07-18 6:26 ` [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
@ 2025-07-18 8:12 ` Krzysztof Kozlowski
2025-07-18 8:14 ` Krzysztof Kozlowski
2025-07-19 10:50 ` Dmitry Baryshkov
2 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-18 8:12 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, Dmitry Baryshkov, devicetree, linux-kernel,
linux-phy, linux-arm-kernel, linux-rockchip, dri-devel
On Fri, Jul 18, 2025 at 02:26:19PM +0800, Chaoyi Chen wrote:
> +&i2c4 {
> + i2c-scl-rising-time-ns = <475>;
> + i2c-scl-falling-time-ns = <26>;
> + status = "okay";
> +
> + usbc0: typec-portc@22 {
> + compatible = "fcs,fusb302";
Look at your binding - it said you don't have fcs,fusb302 - but directly
port plugged to the PHY...
Plus this looks like the switch. I don't think you really addressed
previous comments. Please give it a time.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
2025-07-18 6:26 ` [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
2025-07-18 8:12 ` Krzysztof Kozlowski
@ 2025-07-18 8:14 ` Krzysztof Kozlowski
2025-07-18 8:29 ` Chaoyi Chen
2025-07-19 10:50 ` Dmitry Baryshkov
2 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-18 8:14 UTC (permalink / raw)
To: Chaoyi Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Vinod Koul, Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang,
Andy Yan, Yubing Zhang, Frank Wang, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Amit Sunil Dhamne, Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
On 18/07/2025 08:26, Chaoyi Chen wrote:
> + altmodes {
> + displayport {
> + svid = /bits/ 16 <0xff01>;
> + vdo = <0xffffffff>;
> + };
> + };
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + usbc0_orien_sw: endpoint {
> + remote-endpoint = <&tcphy0_orientation_switch>;
How did you address feedback given here? I don't see any replies.
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> +
> + dp_mode_sw: endpoint {
> + remote-endpoint = <&tcphy_dp_altmode_switch>;
> + };
> + };
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
2025-07-18 8:14 ` Krzysztof Kozlowski
@ 2025-07-18 8:29 ` Chaoyi Chen
0 siblings, 0 replies; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 8:29 UTC (permalink / raw)
To: Krzysztof Kozlowski, Chaoyi Chen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Dragan Simic, Johan Jonker, Diederik de Haas,
Dmitry Baryshkov
Cc: devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
Hi Krzysztof,
On 2025/7/18 16:14, Krzysztof Kozlowski wrote:
> On 18/07/2025 08:26, Chaoyi Chen wrote:
>> + altmodes {
>> + displayport {
>> + svid = /bits/ 16 <0xff01>;
>> + vdo = <0xffffffff>;
>> + };
>> + };
>> +
>> + ports {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + port@0 {
>> + reg = <0>;
>> +
>> + usbc0_orien_sw: endpoint {
>> + remote-endpoint = <&tcphy0_orientation_switch>;
> How did you address feedback given here? I don't see any replies.
Sorry, I miss it. The port@0 should be used for USB HS. Will fix in v3.
>
>> + };
>> + };
>> +
>> + port@1 {
>> + reg = <1>;
>> +
>> + dp_mode_sw: endpoint {
>> + remote-endpoint = <&tcphy_dp_altmode_switch>;
>> + };
>> + };
>
>
> Best regards,
> Krzysztof
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
2025-07-18 8:10 ` Krzysztof Kozlowski
@ 2025-07-18 10:39 ` Chaoyi Chen
0 siblings, 0 replies; 16+ messages in thread
From: Chaoyi Chen @ 2025-07-18 10:39 UTC (permalink / raw)
To: Krzysztof Kozlowski, Chaoyi Chen
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Dragan Simic, Johan Jonker, Diederik de Haas,
Dmitry Baryshkov, devicetree, linux-kernel, linux-phy,
linux-arm-kernel, linux-rockchip, dri-devel
Hi Krzysztof,
On 2025/7/18 16:10, Krzysztof Kozlowski wrote:
> On Fri, Jul 18, 2025 at 02:26:15PM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>>
>> The RK3399 has two USB/DP combo PHY. With the help of external Type-C
>> controller, the PHY can switch altmode between USB and DP.
>>
>> Their connection diagram is shown below:
>>
>> external Type-C Chip0 ---> USB/DP PHY0 ---+
>> | <----> CDN-DP controller
>> external Type-C Chip1 ---> USB/DP PHY1 ---+
> It looks like your "external" controller is not described. Look at your
> port property - "Connection to USB Type-C connector". Lack of proper
> hardware description leads you to claim that the PHY is the mode switch.
> I have doubts on that.
>
> You already received the comments that you need to come with rationale
> why making PHY a USB switch is correct. I don't see the arguments for
> that.
Sorry, I didn't get your point before. Now let me clear it up.
The RK3399 USB/DP commbo PHY support change it's pin mapping, this
means that we can implement the function of typec switch by changing the
pin mapping through software configuration. In addition, DP lane can be
configured for PHYs via software. Therefore, both mode-switch and
orientation-switch are actually performed by the PHY itself, rather than
by an external Type-C controller chip. The external chip is only used to
report PD events.
Besides RK3399, RK3576/RK3588 also integrate these capabilities in their
USB/DP PHY, with both mode-switch and orientation-switch handled by the
PHY[0] .
Thanks for pointing this out. I'll add more detail in v3.
[0]:
https://elixir.bootlin.com/linux/v6.15.6/source/drivers/phy/rockchip/phy-rockchip-usbdp.c#L693
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
2025-07-18 6:26 ` [PATCH v2 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Chaoyi Chen
@ 2025-07-19 7:42 ` kernel test robot
0 siblings, 0 replies; 16+ messages in thread
From: kernel test robot @ 2025-07-19 7:42 UTC (permalink / raw)
To: Chaoyi Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Vinod Koul, Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang,
Andy Yan, Yubing Zhang, Frank Wang, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Amit Sunil Dhamne, Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Dmitry Baryshkov
Cc: llvm, oe-kbuild-all, devicetree, linux-kernel, linux-phy,
linux-arm-kernel, linux-rockchip, dri-devel
Hi Chaoyi,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20250717]
[also build test ERROR on linus/master v6.16-rc6]
[cannot apply to robh/for-next rockchip/for-next krzk/for-next krzk-dt/for-next v6.16-rc6 v6.16-rc5 v6.16-rc4]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Chaoyi-Chen/dt-bindings-phy-rockchip-rk3399-typec-phy-Support-mode-switch/20250718-142814
base: next-20250717
patch link: https://lore.kernel.org/r/20250718062619.99-3-kernel%40airkyi.com
patch subject: [PATCH v2 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
config: arm64-randconfig-004-20250719 (https://download.01.org/0day-ci/archive/20250719/202507191526.Ts6qTQJj-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250719/202507191526.Ts6qTQJj-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202507191526.Ts6qTQJj-lkp@intel.com/
All errors (new ones prefixed by >>):
>> ld.lld: error: undefined symbol: typec_mux_register
>>> referenced by phy-rockchip-typec.c
>>> drivers/phy/rockchip/phy-rockchip-typec.o:(rockchip_typec_phy_probe) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: typec_mux_unregister
>>> referenced by phy-rockchip-typec.c
>>> drivers/phy/rockchip/phy-rockchip-typec.o:(rockchip_typec_phy_probe) in archive vmlinux.a
>>> referenced by phy-rockchip-typec.c
>>> drivers/phy/rockchip/phy-rockchip-typec.o:(tcphy_typec_mux_unregister) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: typec_mux_get_drvdata
>>> referenced by phy-rockchip-typec.c
>>> drivers/phy/rockchip/phy-rockchip-typec.o:(tcphy_typec_mux_set) in archive vmlinux.a
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
2025-07-18 6:26 ` [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
2025-07-18 8:12 ` Krzysztof Kozlowski
2025-07-18 8:14 ` Krzysztof Kozlowski
@ 2025-07-19 10:50 ` Dmitry Baryshkov
2025-07-20 10:00 ` air windows
2 siblings, 1 reply; 16+ messages in thread
From: Dmitry Baryshkov @ 2025-07-19 10:50 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, devicetree, linux-kernel, linux-phy,
linux-arm-kernel, linux-rockchip, dri-devel
On Fri, Jul 18, 2025 at 02:26:19PM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>
> The RK3399 EVB IND board has a Type-C interface DisplayPort.
> It use fusb302 chip as Type-C controller.
>
> fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
> ---
>
> Changes in v2:
> - Add endpoint to link DP PHY and DP controller.
> - Fix devicetree coding style.
>
> .../boot/dts/rockchip/rk3399-evb-ind.dts | 133 ++++++++++++++++++
> 1 file changed, 133 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
> index 70aee1ab904c..997b822a57ff 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
> @@ -4,6 +4,7 @@
> */
>
> /dts-v1/;
> +#include <dt-bindings/usb/pd.h>
> #include "rk3399.dtsi"
>
> / {
> @@ -19,6 +20,21 @@ chosen {
> stdout-path = "serial2:1500000n8";
> };
>
> + sound: sound {
> + compatible = "rockchip,rk3399-gru-sound";
> + rockchip,cpu = <&i2s0 &spdif>;
> + };
> +
> + vbus_typec: regulator-vbus-typec {
> + compatible = "regulator-fixed";
> + enable-active-high;
> + gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&vcc5v0_typec0_en>;
> + regulator-name = "vbus_typec";
> + vin-supply = <&vcc5v0_sys>;
> + };
> +
> vcc5v0_sys: regulator-vcc5v0-sys {
> compatible = "regulator-fixed";
> enable-active-high;
> @@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys {
> };
> };
>
> +&cdn_dp {
> + phys = <&tcphy0_dp>;
> + status = "okay";
> +};
> +
> &cpu_b0 {
> cpu-supply = <&vdd_cpu_b>;
> };
> @@ -55,6 +76,12 @@ &cpu_l3 {
> cpu-supply = <&vdd_cpu_l>;
> };
>
> +&dp_out {
> + dp_controller_output: endpoint {
> + remote-endpoint = <&dp_phy_in>;
> + };
> +};
> +
> &emmc_phy {
> status = "okay";
> };
> @@ -341,6 +368,63 @@ regulator-state-mem {
> };
> };
>
> +&i2c4 {
> + i2c-scl-rising-time-ns = <475>;
> + i2c-scl-falling-time-ns = <26>;
> + status = "okay";
> +
> + usbc0: typec-portc@22 {
> + compatible = "fcs,fusb302";
> + reg = <0x22>;
> + interrupt-parent = <&gpio1>;
> + interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&usbc0_int>;
> + vbus-supply = <&vbus_typec>;
> +
> + usb_con: connector {
> + compatible = "usb-c-connector";
> + label = "USB-C";
> + data-role = "dual";
> + power-role = "dual";
> + try-power-role = "sink";
> + op-sink-microwatt = <1000000>;
> + sink-pdos =
> + <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
> + source-pdos =
> + <PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
> +
> + altmodes {
> + displayport {
> + svid = /bits/ 16 <0xff01>;
> + vdo = <0xffffffff>;
I don't think that this VDO is correct. Please adjust it according to
the spec.
> + };
> + };
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + usbc0_orien_sw: endpoint {
> + remote-endpoint = <&tcphy0_orientation_switch>;
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> +
> + dp_mode_sw: endpoint {
> + remote-endpoint = <&tcphy_dp_altmode_switch>;
> + };
> + };
> + };
> + };
> + };
> +};
> +
> &i2s2 {
> status = "okay";
> };
> @@ -354,6 +438,16 @@ &io_domains {
> };
>
> &pinctrl {
> + usb-typec {
> + usbc0_int: usbc0-int {
> + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
> + };
> +
> + vcc5v0_typec0_en: vcc5v0-typec0-en {
> + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
> + };
> + };
> +
> pmic {
> pmic_int_l: pmic-int-l {
> rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
> @@ -400,10 +494,48 @@ &sdmmc {
> status = "okay";
> };
>
> +&sound {
> + rockchip,codec = <&cdn_dp>;
> + status = "okay";
> +};
> +
> +&spdif {
> + status = "okay";
> +};
> +
> &tcphy0 {
> status = "okay";
> };
>
> +&tcphy0_dp {
> + mode-switch;
But not an orientation-switch? Shouldn't it also note the SBU pins
orientation? Or DP lanes orientation?
> +
> + port {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + tcphy_dp_altmode_switch: endpoint@0 {
> + reg = <0>;
> + remote-endpoint = <&dp_mode_sw>;
> + };
> +
> + dp_phy_in: endpoint@1 {
> + reg = <1>;
> + remote-endpoint = <&dp_controller_output>;
> + };
> + };
> +};
> +
> +&tcphy0_usb3 {
> + orientation-switch;
Hmmm.
> +
> + port {
> + tcphy0_orientation_switch: endpoint {
> + remote-endpoint = <&usbc0_orien_sw>;
> + };
> + };
> +};
> +
> &tcphy1 {
> status = "okay";
> };
> @@ -461,6 +593,7 @@ &usb_host1_ohci {
> };
>
> &usbdrd_dwc3_0 {
> + usb-role-switch;
This is an SoC-level property.
> status = "okay";
> };
>
> --
> 2.49.0
>
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon
2025-07-18 6:26 ` [PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon Chaoyi Chen
@ 2025-07-19 10:53 ` Dmitry Baryshkov
2025-07-20 10:06 ` air windows
0 siblings, 1 reply; 16+ messages in thread
From: Dmitry Baryshkov @ 2025-07-19 10:53 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, devicetree, linux-kernel, linux-phy,
linux-arm-kernel, linux-rockchip, dri-devel
On Fri, Jul 18, 2025 at 02:26:17PM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>
> This patch add support for get PHY lane info and handle HPD state
> without help of extcon.
>
> There is no extcon needed if the Type-C controller is present. In this
> case, cdn_dp_hpd_notify() will handle HPD event from USB/DP combo PHY,
> and the lane info can be get from PHY instead of extcon.
The DP AltMode driver will send drm_connector_oob_hotplug_event() to the
DRM connector associated with the USB-C connector fwnode. However your
DP connector will have fwnode set to the DP controller, if I'm not
mistaken. So I doubt that HPD events are going to be delivered
correctly.
>
> The extcon device should still be supported if Type-C controller is
> not present.
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
> ---
>
> Changes in v2:
> - Ignore duplicate HPD events.
>
> drivers/gpu/drm/rockchip/cdn-dp-core.c | 37 ++++++++++++++++++++------
> 1 file changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> index 24f6b3879f4b..b574b059b58d 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> @@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *port)
> int dptx;
> u8 lanes;
>
> + if (!edev)
> + return phy_get_bus_width(port->phy);
> +
> dptx = extcon_get_state(edev, EXTCON_DISP_DP);
> if (dptx > 0) {
> extcon_get_property(edev, EXTCON_DISP_DP,
> @@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
> * some docks need more time to power up.
> */
> while (time_before(jiffies, timeout)) {
> - if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
> + if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP))
> return false;
>
> if (!cdn_dp_get_sink_count(dp, &sink_count))
> @@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
> goto err_power_on;
> }
>
> - ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
> - EXTCON_PROP_USB_TYPEC_POLARITY, &property);
> - if (ret) {
> - DRM_DEV_ERROR(dp->dev, "get property failed\n");
> - goto err_power_on;
> + property.intval = 0;
> + if (port->extcon) {
> + ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
> + EXTCON_PROP_USB_TYPEC_POLARITY, &property);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev, "get property failed\n");
> + goto err_power_on;
> + }
> }
>
> port->lanes = cdn_dp_get_port_lanes(port);
> @@ -821,6 +827,17 @@ static int cdn_dp_audio_mute_stream(struct drm_connector *connector,
> return ret;
> }
>
> +static void cdn_dp_hpd_notify(struct drm_bridge *bridge,
> + enum drm_connector_status status)
> +{
> + struct cdn_dp_device *dp = bridge_to_dp(bridge);
> + enum drm_connector_status last_status =
> + dp->connected ? connector_status_connected : connector_status_disconnected;
> +
> + if (last_status != status)
> + schedule_work(&dp->event_work);
> +}
> +
> static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
> .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> @@ -831,6 +848,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
> .atomic_disable = cdn_dp_bridge_atomic_disable,
> .mode_valid = cdn_dp_bridge_mode_valid,
> .mode_set = cdn_dp_bridge_mode_set,
> + .hpd_notify = cdn_dp_hpd_notify,
>
> .dp_audio_prepare = cdn_dp_audio_prepare,
> .dp_audio_mute_stream = cdn_dp_audio_mute_stream,
> @@ -1028,6 +1046,9 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
> for (i = 0; i < dp->ports; i++) {
> port = dp->port[i];
>
> + if (!port->extcon)
> + continue;
> +
> port->event_nb.notifier_call = cdn_dp_pd_event;
> ret = devm_extcon_register_notifier(dp->dev, port->extcon,
> EXTCON_DISP_DP,
> @@ -1120,14 +1141,14 @@ static int cdn_dp_probe(struct platform_device *pdev)
> PTR_ERR(phy) == -EPROBE_DEFER)
> return -EPROBE_DEFER;
>
> - if (IS_ERR(extcon) || IS_ERR(phy))
> + if (IS_ERR(phy) || PTR_ERR(extcon) != -ENODEV)
> continue;
>
> port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> if (!port)
> return -ENOMEM;
>
> - port->extcon = extcon;
> + port->extcon = IS_ERR(extcon) ? NULL : extcon;
> port->phy = phy;
> port->dp = dp;
> port->id = i;
> --
> 2.49.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
2025-07-19 10:50 ` Dmitry Baryshkov
@ 2025-07-20 10:00 ` air windows
0 siblings, 0 replies; 16+ messages in thread
From: air windows @ 2025-07-20 10:00 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, devicetree, linux-kernel, linux-phy,
linux-arm-kernel, linux-rockchip, dri-devel
在 2025/7/19 18:50, Dmitry Baryshkov 写道:
> On Fri, Jul 18, 2025 at 02:26:19PM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>>
>> The RK3399 EVB IND board has a Type-C interface DisplayPort.
>> It use fusb302 chip as Type-C controller.
>>
>> fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>> ---
>>
>> Changes in v2:
>> - Add endpoint to link DP PHY and DP controller.
>> - Fix devicetree coding style.
>>
>> .../boot/dts/rockchip/rk3399-evb-ind.dts | 133 ++++++++++++++++++
>> 1 file changed, 133 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
>> index 70aee1ab904c..997b822a57ff 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
>> @@ -4,6 +4,7 @@
>> */
>>
>> /dts-v1/;
>> +#include <dt-bindings/usb/pd.h>
>> #include "rk3399.dtsi"
>>
>> / {
>> @@ -19,6 +20,21 @@ chosen {
>> stdout-path = "serial2:1500000n8";
>> };
>>
>> + sound: sound {
>> + compatible = "rockchip,rk3399-gru-sound";
>> + rockchip,cpu = <&i2s0 &spdif>;
>> + };
>> +
>> + vbus_typec: regulator-vbus-typec {
>> + compatible = "regulator-fixed";
>> + enable-active-high;
>> + gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&vcc5v0_typec0_en>;
>> + regulator-name = "vbus_typec";
>> + vin-supply = <&vcc5v0_sys>;
>> + };
>> +
>> vcc5v0_sys: regulator-vcc5v0-sys {
>> compatible = "regulator-fixed";
>> enable-active-high;
>> @@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys {
>> };
>> };
>>
>> +&cdn_dp {
>> + phys = <&tcphy0_dp>;
>> + status = "okay";
>> +};
>> +
>> &cpu_b0 {
>> cpu-supply = <&vdd_cpu_b>;
>> };
>> @@ -55,6 +76,12 @@ &cpu_l3 {
>> cpu-supply = <&vdd_cpu_l>;
>> };
>>
>> +&dp_out {
>> + dp_controller_output: endpoint {
>> + remote-endpoint = <&dp_phy_in>;
>> + };
>> +};
>> +
>> &emmc_phy {
>> status = "okay";
>> };
>> @@ -341,6 +368,63 @@ regulator-state-mem {
>> };
>> };
>>
>> +&i2c4 {
>> + i2c-scl-rising-time-ns = <475>;
>> + i2c-scl-falling-time-ns = <26>;
>> + status = "okay";
>> +
>> + usbc0: typec-portc@22 {
>> + compatible = "fcs,fusb302";
>> + reg = <0x22>;
>> + interrupt-parent = <&gpio1>;
>> + interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&usbc0_int>;
>> + vbus-supply = <&vbus_typec>;
>> +
>> + usb_con: connector {
>> + compatible = "usb-c-connector";
>> + label = "USB-C";
>> + data-role = "dual";
>> + power-role = "dual";
>> + try-power-role = "sink";
>> + op-sink-microwatt = <1000000>;
>> + sink-pdos =
>> + <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
>> + source-pdos =
>> + <PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
>> +
>> + altmodes {
>> + displayport {
>> + svid = /bits/ 16 <0xff01>;
>> + vdo = <0xffffffff>;
> I don't think that this VDO is correct. Please adjust it according to
> the spec.
Will fix in v3.
>
>> + };
>> + };
>> +
>> + ports {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + port@0 {
>> + reg = <0>;
>> +
>> + usbc0_orien_sw: endpoint {
>> + remote-endpoint = <&tcphy0_orientation_switch>;
>> + };
>> + };
>> +
>> + port@1 {
>> + reg = <1>;
>> +
>> + dp_mode_sw: endpoint {
>> + remote-endpoint = <&tcphy_dp_altmode_switch>;
>> + };
>> + };
>> + };
>> + };
>> + };
>> +};
>> +
>> &i2s2 {
>> status = "okay";
>> };
>> @@ -354,6 +438,16 @@ &io_domains {
>> };
>>
>> &pinctrl {
>> + usb-typec {
>> + usbc0_int: usbc0-int {
>> + rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
>> + };
>> +
>> + vcc5v0_typec0_en: vcc5v0-typec0-en {
>> + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
>> + };
>> + };
>> +
>> pmic {
>> pmic_int_l: pmic-int-l {
>> rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
>> @@ -400,10 +494,48 @@ &sdmmc {
>> status = "okay";
>> };
>>
>> +&sound {
>> + rockchip,codec = <&cdn_dp>;
>> + status = "okay";
>> +};
>> +
>> +&spdif {
>> + status = "okay";
>> +};
>> +
>> &tcphy0 {
>> status = "okay";
>> };
>>
>> +&tcphy0_dp {
>> + mode-switch;
> But not an orientation-switch? Shouldn't it also note the SBU pins
> orientation? Or DP lanes orientation?
Ah, you will find it in tcphy0_usb3. Yes this should also apply to DP, it's combo PHY.
>
>> +
>> + port {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + tcphy_dp_altmode_switch: endpoint@0 {
>> + reg = <0>;
>> + remote-endpoint = <&dp_mode_sw>;
>> + };
>> +
>> + dp_phy_in: endpoint@1 {
>> + reg = <1>;
>> + remote-endpoint = <&dp_controller_output>;
>> + };
>> + };
>> +};
>> +
>> +&tcphy0_usb3 {
>> + orientation-switch;
>
> Hmmm.
Well, I put it under &tcp_phy0 at first, but it looks like someone has already added this in other dtsi. So I put the two prop under each "child" phy...
>
>> +
>> + port {
>> + tcphy0_orientation_switch: endpoint {
>> + remote-endpoint = <&usbc0_orien_sw>;
>> + };
>> + };
>> +};
>> +
>> &tcphy1 {
>> status = "okay";
>> };
>> @@ -461,6 +593,7 @@ &usb_host1_ohci {
>> };
>>
>> &usbdrd_dwc3_0 {
>> + usb-role-switch;
> This is an SoC-level property.
Will fix in v3.
>
>> status = "okay";
>> };
>>
>> --
>> 2.49.0
>>
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon
2025-07-19 10:53 ` Dmitry Baryshkov
@ 2025-07-20 10:06 ` air windows
0 siblings, 0 replies; 16+ messages in thread
From: air windows @ 2025-07-20 10:06 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Amit Sunil Dhamne,
Greg Kroah-Hartman, Chaoyi Chen, Dragan Simic, Johan Jonker,
Diederik de Haas, devicetree, linux-kernel, linux-phy,
linux-arm-kernel, linux-rockchip, dri-devel
在 2025/7/19 18:53, Dmitry Baryshkov 写道:
> On Fri, Jul 18, 2025 at 02:26:17PM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>>
>> This patch add support for get PHY lane info and handle HPD state
>> without help of extcon.
>>
>> There is no extcon needed if the Type-C controller is present. In this
>> case, cdn_dp_hpd_notify() will handle HPD event from USB/DP combo PHY,
>> and the lane info can be get from PHY instead of extcon.
> The DP AltMode driver will send drm_connector_oob_hotplug_event() to the
> DRM connector associated with the USB-C connector fwnode. However your
> DP connector will have fwnode set to the DP controller, if I'm not
> mistaken. So I doubt that HPD events are going to be delivered
> correctly.
Yes, that's exactly the case for the DP Altmode driver! I've thought of a few approaches, but none of them are elegant. Now it relying on the PHY driver to call the drm_connector_oob_hotplug_event(). You'll find the relevant code in the PHY driver.
>
>> The extcon device should still be supported if Type-C controller is
>> not present.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>> ---
>>
>> Changes in v2:
>> - Ignore duplicate HPD events.
>>
>> drivers/gpu/drm/rockchip/cdn-dp-core.c | 37 ++++++++++++++++++++------
>> 1 file changed, 29 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> index 24f6b3879f4b..b574b059b58d 100644
>> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> @@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *port)
>> int dptx;
>> u8 lanes;
>>
>> + if (!edev)
>> + return phy_get_bus_width(port->phy);
>> +
>> dptx = extcon_get_state(edev, EXTCON_DISP_DP);
>> if (dptx > 0) {
>> extcon_get_property(edev, EXTCON_DISP_DP,
>> @@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
>> * some docks need more time to power up.
>> */
>> while (time_before(jiffies, timeout)) {
>> - if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
>> + if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP))
>> return false;
>>
>> if (!cdn_dp_get_sink_count(dp, &sink_count))
>> @@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
>> goto err_power_on;
>> }
>>
>> - ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
>> - EXTCON_PROP_USB_TYPEC_POLARITY, &property);
>> - if (ret) {
>> - DRM_DEV_ERROR(dp->dev, "get property failed\n");
>> - goto err_power_on;
>> + property.intval = 0;
>> + if (port->extcon) {
>> + ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
>> + EXTCON_PROP_USB_TYPEC_POLARITY, &property);
>> + if (ret) {
>> + DRM_DEV_ERROR(dp->dev, "get property failed\n");
>> + goto err_power_on;
>> + }
>> }
>>
>> port->lanes = cdn_dp_get_port_lanes(port);
>> @@ -821,6 +827,17 @@ static int cdn_dp_audio_mute_stream(struct drm_connector *connector,
>> return ret;
>> }
>>
>> +static void cdn_dp_hpd_notify(struct drm_bridge *bridge,
>> + enum drm_connector_status status)
>> +{
>> + struct cdn_dp_device *dp = bridge_to_dp(bridge);
>> + enum drm_connector_status last_status =
>> + dp->connected ? connector_status_connected : connector_status_disconnected;
>> +
>> + if (last_status != status)
>> + schedule_work(&dp->event_work);
>> +}
>> +
>> static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
>> .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
>> .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
>> @@ -831,6 +848,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
>> .atomic_disable = cdn_dp_bridge_atomic_disable,
>> .mode_valid = cdn_dp_bridge_mode_valid,
>> .mode_set = cdn_dp_bridge_mode_set,
>> + .hpd_notify = cdn_dp_hpd_notify,
>>
>> .dp_audio_prepare = cdn_dp_audio_prepare,
>> .dp_audio_mute_stream = cdn_dp_audio_mute_stream,
>> @@ -1028,6 +1046,9 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>> for (i = 0; i < dp->ports; i++) {
>> port = dp->port[i];
>>
>> + if (!port->extcon)
>> + continue;
>> +
>> port->event_nb.notifier_call = cdn_dp_pd_event;
>> ret = devm_extcon_register_notifier(dp->dev, port->extcon,
>> EXTCON_DISP_DP,
>> @@ -1120,14 +1141,14 @@ static int cdn_dp_probe(struct platform_device *pdev)
>> PTR_ERR(phy) == -EPROBE_DEFER)
>> return -EPROBE_DEFER;
>>
>> - if (IS_ERR(extcon) || IS_ERR(phy))
>> + if (IS_ERR(phy) || PTR_ERR(extcon) != -ENODEV)
>> continue;
>>
>> port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
>> if (!port)
>> return -ENOMEM;
>>
>> - port->extcon = extcon;
>> + port->extcon = IS_ERR(extcon) ? NULL : extcon;
>> port->phy = phy;
>> port->dp = dp;
>> port->id = i;
>> --
>> 2.49.0
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-07-20 10:07 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-18 6:26 [PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
2025-07-18 8:10 ` Krzysztof Kozlowski
2025-07-18 10:39 ` Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Chaoyi Chen
2025-07-19 7:42 ` kernel test robot
2025-07-18 6:26 ` [PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon Chaoyi Chen
2025-07-19 10:53 ` Dmitry Baryshkov
2025-07-20 10:06 ` air windows
2025-07-18 6:26 ` [PATCH v2 4/5] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Chaoyi Chen
2025-07-18 6:26 ` [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
2025-07-18 8:12 ` Krzysztof Kozlowski
2025-07-18 8:14 ` Krzysztof Kozlowski
2025-07-18 8:29 ` Chaoyi Chen
2025-07-19 10:50 ` Dmitry Baryshkov
2025-07-20 10:00 ` air windows
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).