Re: [PATCH v2 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-10 Thread Chaoyi Chen

Hi Krzysztof,

On 2025/5/9 17:21, Krzysztof Kozlowski wrote:

On 09/05/2025 09:34, Chaoyi Chen wrote:

Hi Krzysztof,

On 2025/5/9 15:11, Krzysztof Kozlowski wrote:

On 09/05/2025 09:02, Chaoyi Chen wrote:

+
+  clock-names:
+items:
+  - const: core-clk
+  - const: pclk
+  - const: spdif
+  - const: grf
+
+  extcon:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+description:
+  Phandle to the extcon device providing the cable state for the DP PHY.
+
+  interrupts:
+maxItems: 1
+
+  phys:
+$ref: /schemas/types.yaml#/definitions/phandle-array

Just phandle. If this is an array (but why?), you need maxItems for
outer and inner dimensions.

Uh, sorry, that was supposed to be under extcon.


Oh, this also applies to extcon. Each extcon is used to indicate the 
status of the PHY.






I think it could be phandle or phandle-array. Since the RK3399 DP has

Here it is obviously not needed, that's a dtschema type.


Do you mean that there is no need to explicitly specify something like 
"$ref: /schemas/types.yaml#/definitions/phandle" ?







two PHYs, if we put in two PHYs here, the driver will pick one PHY port
that is already plugged into the DP for output. If we fill in only one
PHY here, then output is only allowed on the corresponding PHY.

Will add restrictions and add more descriptions in v3.



+description:
+  Phandle to the PHY device for DP output.

You need to list the items with description iinstead.


Okay, will fix in v3.






Best regards,
Krzysztof




Re: [PATCH v2 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-10 Thread Chaoyi Chen

Hi Krzysztof,

On 2025/5/9 15:11, Krzysztof Kozlowski wrote:

On 09/05/2025 09:02, Chaoyi Chen wrote:

+
+  clock-names:
+items:
+  - const: core-clk
+  - const: pclk
+  - const: spdif
+  - const: grf
+
+  extcon:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+description:
+  Phandle to the extcon device providing the cable state for the DP PHY.
+
+  interrupts:
+maxItems: 1
+
+  phys:
+$ref: /schemas/types.yaml#/definitions/phandle-array

Just phandle. If this is an array (but why?), you need maxItems for
outer and inner dimensions.


I think it could be phandle or phandle-array. Since the RK3399 DP has 
two PHYs, if we put in two PHYs here, the driver will pick one PHY port 
that is already plugged into the DP for output. If we fill in only one 
PHY here, then output is only allowed on the corresponding PHY.


Will add restrictions and add more descriptions in v3.





+description:
+  Phandle to the PHY device for DP output.
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input of the CDN DP
+properties:
+  endpoint@0:
+description: Connection to the VOPB
+  endpoint@1:
+description: Connection to the VOPL
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output of the CDN DP
+
+required:
+  - port@0
+  - port@1
+
+  power-domains:
+maxItems: 1
+
+  resets:
+maxItems: 4
+
+  reset-names:
+items:
+  - const: spdif
+  - const: dptx
+  - const: apb
+  - const: core
+
+  rockchip,grf:
+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  Phandle to GRF register to control HPD.
+
+  "#sound-dai-cells":
+const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - phys
+  - ports
+  - resets
+  - reset-names
+  - rockchip,grf
+
+additionalProperties: false

Well, if you added dai-common $ref then this could have stayed as
unevaluatedProperties, so you will allow names for the DAI as well.


Thanks for your clarification. Will fix in v3.





Best regards,
Krzysztof




[PATCH 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-07 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert cdn-dp-rockchip.txt to yaml.

Tested with:

1. make ARCH=arm64 dt_binding_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

2. make ARCH=arm64 dtbs_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

Signed-off-by: Chaoyi Chen 
---
 .../display/rockchip/cdn-dp-rockchip.txt  |  74 -
 .../display/rockchip/rockchip,cdn-dp.yaml | 148 ++
 2 files changed, 148 insertions(+), 74 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
deleted file mode 100644
index 8df7d2e393d6..
--- a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-Rockchip RK3399 specific extensions to the cdn Display Port
-
-
-Required properties:
-- compatible: must be "rockchip,rk3399-cdn-dp"
-
-- reg: physical base address of the controller and length
-
-- clocks: from common clock binding: handle to dp clock.
-
-- clock-names: from common clock binding:
-  Required elements: "core-clk" "pclk" "spdif" "grf"
-
-- resets : a list of phandle + reset specifier pairs
-- reset-names : string of reset names
-   Required elements: "apb", "core", "dptx", "spdif"
-- power-domains : power-domain property defined with a phandle
- to respective power domain.
-- assigned-clocks: main clock, should be <&cru SCLK_DP_CORE>
-- assigned-clock-rates : the DP core clk frequency, shall be: 1
-
-- rockchip,grf: this soc should set GRF regs, so need get grf here.
-
-- ports: contain a port nodes with endpoint definitions as defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-contained 2 endpoints, connecting to the output of vop.
-
-- phys: from general PHY binding: the phandle for the PHY device.
-
-- extcon: extcon specifier for the Power Delivery
-
-- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
-

-
-Example:
-   cdn_dp: dp@fec0 {
-   compatible = "rockchip,rk3399-cdn-dp";
-   reg = <0x0 0xfec0 0x0 0x10>;
-   interrupts = ;
-   clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>,
-<&cru SCLK_SPDIF_REC_DPTX>, <&cru PCLK_VIO_GRF>;
-   clock-names = "core-clk", "pclk", "spdif", "grf";
-   assigned-clocks = <&cru SCLK_DP_CORE>;
-   assigned-clock-rates = <1>;
-   power-domains = <&power RK3399_PD_HDCP>;
-   phys = <&tcphy0_dp>, <&tcphy1_dp>;
-   resets = <&cru SRST_DPTX_SPDIF_REC>;
-   reset-names = "spdif";
-   extcon = <&fusb0>, <&fusb1>;
-   rockchip,grf = <&grf>;
-   #address-cells = <1>;
-   #size-cells = <0>;
-   #sound-dai-cells = <1>;
-
-   ports {
-   #address-cells = <1>;
-   #size-cells = <0>;
-
-   dp_in: port {
-   #address-cells = <1>;
-   #size-cells = <0>;
-   dp_in_vopb: endpoint@0 {
-   reg = <0>;
-   remote-endpoint = <&vopb_out_dp>;
-   };
-
-   dp_in_vopl: endpoint@1 {
-   reg = <1>;
-   remote-endpoint = <&vopl_out_dp>;
-   };
-   };
-   };
-   };
diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml
new file mode 100644
index ..ed68b48a6743
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml
@@ -0,0 +1,148 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/rockchip/rockchip,cdn-dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3399 

[PATCH 1/2] arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp

2025-05-07 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +-
 1 file changed, 9 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..e340b6df7445 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@fec0 {
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,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+   dp_out: port@1 {
+   reg = <1>;
+   };
};
};
 
-- 
2.49.0



[PATCH 0/2] Convert Rockchip CDN DP binding to yaml

2025-05-07 Thread Chaoyi Chen
From: Chaoyi Chen 

This series convert cdn-dp-rockchip.txt to yaml.

PATCH 1 try to improve coding style on the existing rk3399 cdn-dp
node.
PATCH 2 try to convert cdn-dp-rockchip.txt to yaml.

Tested with:

1. make ARCH=arm64 dt_binding_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

2. make ARCH=arm64 dtbs_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml


Chaoyi Chen (2):
  arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp
  dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

 .../display/rockchip/cdn-dp-rockchip.txt  |  74 -
 .../display/rockchip/rockchip,cdn-dp.yaml | 148 ++
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 3 files changed, 157 insertions(+), 75 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

--
2.49.0



Re: [PATCH 3/5] phy: rockchip: phy-rockchip-typec: Add support for Type-C TCPM

2025-07-15 Thread Chaoyi Chen

Hi Dmitry,

On 2025/7/15 20:05, Dmitry Baryshkov wrote:

On Tue, Jul 15, 2025 at 07:24:54PM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

This patch add support for Type-C Port Controller Manager.
The extcon device should still be supported.

Signed-off-by: Chaoyi Chen 
---
  drivers/phy/rockchip/phy-rockchip-typec.c | 335 --
  1 file changed, 319 insertions(+), 16 deletions(-)

Please keep TCPM implementation under drivers/usb/typec/tcpm/ . Create
an aux device and write an aux driver for the TCPM part.


Sorry, the commit messages may not be described accurately enough.


This patch adds mux/switch operations to the PHY driver to improve 
communication with the TCPM framework. Since this PHY is a combo USB/DP 
PHY, it requires configuration changes to the PHY lanes based on the 
USB-C  plug orientation (CC logic), similar to the existing extcon 
mechanism implementation. Of course, the original extcon functionality 
will remain fully compatible.





[PATCH 2/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode/orientation switch

2025-07-15 Thread Chaoyi Chen
From: Chaoyi Chen 

Add support for Type-C orientation and altmode switch.
The Type-C controller can be specified to handling switching.

Signed-off-by: Chaoyi Chen 
---
 .../bindings/phy/rockchip,rk3399-typec-phy.yaml| 14 ++
 1 file changed, 14 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..a885c6893a90 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -43,6 +43,20 @@ properties:
 description:
   Phandle to the syscon managing the "general register files" (GRF).
 
+  orientation-switch:
+description: Flag the port as possible handler of orientation switching
+type: boolean
+
+  mode-switch:
+description: Flag the port as possible handler of altmode switching
+type: boolean
+
+  port:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  A port node to link the PHY to a TypeC controller for the purpose of
+  handling orientation switching.
+
   dp-port:
 type: object
 additionalProperties: false
-- 
2.49.0




[PATCH 3/5] phy: rockchip: phy-rockchip-typec: Add support for Type-C TCPM

2025-07-15 Thread Chaoyi Chen
From: Chaoyi Chen 

This patch add support for Type-C Port Controller Manager.
The extcon device should still be supported.

Signed-off-by: Chaoyi Chen 
---
 drivers/phy/rockchip/phy-rockchip-typec.c | 335 --
 1 file changed, 319 insertions(+), 16 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c 
b/drivers/phy/rockchip/phy-rockchip-typec.c
index d9701b6106d5..ce2e710c1738 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -54,6 +54,8 @@
 
 #include 
 #include 
+#include 
+#include 
 
 #define CMN_SSM_BANDGAP(0x21 << 2)
 #define CMN_SSM_BIAS   (0x22 << 2)
@@ -286,12 +288,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_MASKGENMASK(7, 4)
+#define PHY_DP_POWER_STATE_ACK_SHIFT   4
+#define PHY_DP_POWER_STATE_MASKGENMASK(3, 0)
 #define DP_CLK_CTL (0xc009 << 2)
 #define STS(0xc00F << 2)
 #define PHY_ISO_CMN_CTRL   (0xc010 << 2)
@@ -327,8 +340,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   10
 
@@ -340,6 +360,31 @@
 #define MODE_DFP_USB   BIT(1)
 #define MODE_DFP_DPBIT(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 +417,22 @@ struct rockchip_typec_phy {
struct device *dev;
void __iomem *base;
struct extcon_dev *extcon;
+   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 +503,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_S

[PATCH 1/5] dt-bindings: connector: Add displayport connector for hotplug notify

2025-07-15 Thread Chaoyi Chen
From: Chaoyi Chen 

The USB Type-C DisplayPort alternate mode driver will find
"displayport" property for DRM hotplug event notify[0].

[0]: https://lore.kernel.org/all/20210817215201.795062-9-hdego...@redhat.com/

Signed-off-by: Chaoyi Chen 
---
 .../devicetree/bindings/connector/usb-connector.yaml  | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml 
b/Documentation/devicetree/bindings/connector/usb-connector.yaml
index 11e40d225b9f..ccb258972cd6 100644
--- a/Documentation/devicetree/bindings/connector/usb-connector.yaml
+++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml
@@ -300,6 +300,10 @@ properties:
 $ref: /schemas/types.yaml#/definitions/uint8-array
 maxItems: 4
 
+  displayport:
+description: A phandle to displayport connector for DRM hotplug event 
notify.
+$ref: /schemas/types.yaml#/definitions/phandle
+
 dependencies:
   sink-vdos-v1: [ sink-vdos ]
   sink-vdos: [ sink-vdos-v1 ]
-- 
2.49.0




[PATCH 4/5] drm/rockchip: cdn-dp: Add support for Type-C TCPM

2025-07-15 Thread Chaoyi Chen
From: Chaoyi Chen 

This patch add support for Type-C Port Manager. If the Type-C
controller is present, the DP hot plug events can be notified with
the help of TCPM and without the need for extcon.

The extcon device should still be supported.

Signed-off-by: Chaoyi Chen 
---
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 37 ++
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 24f6b3879f4b..3354d0e4ae4f 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,14 @@ 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);
+
+   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 +845,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,
@@ -938,9 +953,6 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 
 out:
mutex_unlock(&dp->lock);
-   drm_bridge_hpd_notify(&dp->bridge,
- dp->connected ? connector_status_connected
-   : connector_status_disconnected);
 }
 
 static int cdn_dp_pd_event(struct notifier_block *nb,
@@ -1028,6 +1040,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 +1135,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




[PATCH 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

2025-07-15 Thread Chaoyi Chen
From: Chaoyi Chen 

The RK3399 EVB IND board has a Type-C interface DisplayPort.
It use fusb302 chip as Type-C controller.

Signed-off-by: Chaoyi Chen 
---
 .../boot/dts/rockchip/rk3399-evb-ind.dts  | 119 ++
 1 file changed, 119 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..9ceda32456a0 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 
 #include "rk3399.dtsi"
 
 / {
@@ -19,6 +20,16 @@ chosen {
stdout-path = "serial2:150n8";
};
 
+   vbus_typec: vbus-typec-regulator {
+   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;
@@ -29,6 +40,16 @@ vcc5v0_sys: regulator-vcc5v0-sys {
regulator-max-microvolt = <500>;
regulator-min-microvolt = <500>;
};
+
+   sound: sound {
+   compatible = "rockchip,rk3399-gru-sound";
+   rockchip,cpu = <&i2s0 &spdif>;
+   };
+};
+
+&cdn_dp {
+   status = "okay";
+   phys = <&tcphy0_dp>;
 };
 
 &cpu_b0 {
@@ -341,6 +362,66 @@ regulator-state-mem {
};
 };
 
+&i2c4 {
+   i2c-scl-rising-time-ns = <475>;
+   i2c-scl-falling-time-ns = <26>;
+   status = "okay";
+
+   usbc0: fusb302@22 {
+   compatible = "fcs,fusb302";
+   reg = <0x22>;
+   interrupt-parent = <&gpio1>;
+   interrupts = ;
+   pinctrl-names = "default";
+   pinctrl-0 = <&usbc0_int>;
+   vbus-supply = <&vbus_typec>;
+   status = "okay";
+
+   usb_con: connector {
+   compatible = "usb-c-connector";
+   label = "USB-C";
+   data-role = "dual";
+   power-role = "dual";
+   try-power-role = "sink";
+   op-sink-microwatt = <100>;
+   sink-pdos =
+   ;
+   source-pdos =
+   ;
+
+   displayport = <&cdn_dp>;
+
+   altmodes {
+   displayport {
+   svid = /bits/ 16 <0xff01>;
+   vdo = <0x>;
+   };
+   };
+
+   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 +435,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,8 +491,35 @@ &sdmmc {
status = "okay";
 };
 
+&sound {
+   rockchip,codec = <&cdn_dp>;
+   status = "okay";
+};
+
+&spdif {
+   status = "okay";
+};
+
 &

Re: [PATCH 1/5] dt-bindings: connector: Add displayport connector for hotplug notify

2025-07-15 Thread Chaoyi Chen

On 2025/7/15 20:04, Dmitry Baryshkov wrote:


On Tue, Jul 15, 2025 at 07:24:52PM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

The USB Type-C DisplayPort alternate mode driver will find
"displayport" property for DRM hotplug event notify[0].

[0]: https://lore.kernel.org/all/20210817215201.795062-9-hdego...@redhat.com/

Signed-off-by: Chaoyi Chen 
---
  .../devicetree/bindings/connector/usb-connector.yaml  | 4 
  1 file changed, 4 insertions(+)


Please see how it was done on other platforms. For example, qualcomm
(both tcpm and pmic-glink) use port / endpoint to link to the DP PHY /
DP controller.

Thank you! I'll check these out.



Re: [PATCH 2/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode/orientation switch

2025-07-15 Thread Chaoyi Chen

Hi Krzysztof,

On 2025/7/15 19:34, Krzysztof Kozlowski wrote:

On 15/07/2025 13:24, Chaoyi Chen wrote:

From: Chaoyi Chen 

Add support for Type-C orientation and altmode switch.
The Type-C controller can be specified to handling switching.

Please describe the hardware in details. Above sentences don't help me
to understand this.


I will add more description in v2.






Signed-off-by: Chaoyi Chen 
---
  .../bindings/phy/rockchip,rk3399-typec-phy.yaml| 14 ++
  1 file changed, 14 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..a885c6893a90 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -43,6 +43,20 @@ properties:
  description:
Phandle to the syscon managing the "general register files" (GRF).
  
+  orientation-switch:

+description: Flag the port as possible handler of orientation switching
+type: boolean
+
+  mode-switch:
+description: Flag the port as possible handler of altmode switching
+type: boolean
+
+  port:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  A port node to link the PHY to a TypeC controller for the purpose of
+  handling orientation switching.


You are using usb-switch.yaml properties in phy node, which raises
questions whether this is actually complete. It might be, but commit msg
is so vague that I have doubts.

Also, why only one port?

Or wait... you already have ports! two of them. This needs to stop, why
are you adding more?


Oh, I will try to reuse them. Will fix in v2.




Best regards,
Krzysztof




Re: [PATCH 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

2025-07-15 Thread Chaoyi Chen

Hi Krzysztof,

On 2025/7/15 19:37, Krzysztof Kozlowski wrote:

On 15/07/2025 13:24, Chaoyi Chen wrote:

  /dts-v1/;
+#include 
  #include "rk3399.dtsi"
  
  / {

@@ -19,6 +20,16 @@ chosen {
stdout-path = "serial2:150n8";
};
  
+	vbus_typec: vbus-typec-regulator {

use consistent naming. How other regulators are called? foo-regulator?


Will fix in v2.





+   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;
@@ -29,6 +40,16 @@ vcc5v0_sys: regulator-vcc5v0-sys {
regulator-max-microvolt = <500>;
regulator-min-microvolt = <500>;
};
+
+   sound: sound {
+   compatible = "rockchip,rk3399-gru-sound";
+   rockchip,cpu = <&i2s0 &spdif>;
+   };
+};
+
+&cdn_dp {
+   status = "okay";
+   phys = <&tcphy0_dp>;
  };
  
  &cpu_b0 {

@@ -341,6 +362,66 @@ regulator-state-mem {
};
  };
  
+&i2c4 {

+   i2c-scl-rising-time-ns = <475>;
+   i2c-scl-falling-time-ns = <26>;
+   status = "okay";
+
+   usbc0: fusb302@22 {

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation


Thank you for the explanation. Will fix in v2.






+   compatible = "fcs,fusb302";
+   reg = <0x22>;
+   interrupt-parent = <&gpio1>;
+   interrupts = ;
+   pinctrl-names = "default";
+   pinctrl-0 = <&usbc0_int>;
+   vbus-supply = <&vbus_typec>;
+   status = "okay";

Why? What disabled it?


Oh, that is redundant. Will drop it in v2.





+
+   usb_con: connector {
+   compatible = "usb-c-connector";
+   label = "USB-C";

Best regards,
Krzysztof




Re: [PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

2025-07-18 Thread Chaoyi Chen

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 = <0x>;
+   };
+   };
+
+   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




[PATCH v2 0/5] Add Type-C DP support for RK3399 EVB IND board

2025-07-17 Thread Chaoyi Chen
From: Chaoyi Chen 

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-ker...@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




[PATCH v2 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon

2025-07-17 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

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



[PATCH v2 4/5] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP

2025-07-17 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---
 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@fec0 {
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



[PATCH v2 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

2025-07-17 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

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 
 #include "rk3399.dtsi"
 
 / {
@@ -19,6 +20,21 @@ chosen {
stdout-path = "serial2:150n8";
};
 
+   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 = ;
+   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 = <100>;
+   sink-pdos =
+   ;
+   source-pdos =
+   ;
+
+   altmodes {
+   displayport {
+   svid = /bits/ 16 <0xff01>;
+   vdo = <0x>;
+   };
+   };
+
+   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 &

Re: [PATCH v2 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch

2025-07-18 Thread Chaoyi Chen

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 

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




Re: [PATCH] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-21 Thread Chaoyi Chen

Hi Andy,

On 2025/5/21 20:09, Andy Yan wrote:

Hi Chaoyi,

At 2025-05-07 11:51:48, "Chaoyi Chen"  wrote:

From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.

Tested with RK3399 EVB IND board.

Signed-off-by: Chaoyi Chen 
---
drivers/gpu/drm/rockchip/cdn-dp-core.c | 163 +
drivers/gpu/drm/rockchip/cdn-dp-core.h |   5 +-
2 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 292c31de18f1..bc70dae8ff72 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -25,9 +25,9 @@
#include "cdn-dp-core.h"
#include "cdn-dp-reg.h"

-static inline struct cdn_dp_device *connector_to_dp(struct drm_connector 
*connector)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
{
-   return container_of(connector, struct cdn_dp_device, connector);
+   return container_of(bridge, struct cdn_dp_device, bridge);
}

static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
@@ -231,9 +231,9 @@ static bool cdn_dp_check_sink_connection(struct 
cdn_dp_device *dp)
}

static enum drm_connector_status
-cdn_dp_connector_detect(struct drm_connector *connector, bool force)
+cdn_dp_bridge_detect(struct drm_bridge *bridge)
{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
enum drm_connector_status status = connector_status_disconnected;

mutex_lock(&dp->lock);
@@ -244,41 +244,26 @@ cdn_dp_connector_detect(struct drm_connector *connector, 
bool force)
return status;
}

-static void cdn_dp_connector_destroy(struct drm_connector *connector)
+static const struct drm_edid *
+cdn_dp_connector_edid_read(struct drm_bridge *bridge, struct drm_connector 
*connector)

This should be cdn_dp_bridge_edid_read


Will fix in v2.





{
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
-   .detect = cdn_dp_connector_detect,
-   .destroy = cdn_dp_connector_destroy,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int cdn_dp_connector_get_modes(struct drm_connector *connector)
-{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   int ret = 0;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   const struct drm_edid *drm_edid;

mutex_lock(&dp->lock);
-
-   ret = drm_edid_connector_add_modes(connector);
-
+   drm_edid = drm_edid_read_custom(dp->connector,
+   cdn_dp_get_edid_block, dp);

Use drm_edid_read_ddc


drm_edid_read_ddc() need a i2c_adapter, but cdn-dp doesn't have it.





mutex_unlock(&dp->lock);

-   return ret;
+   return drm_edid;
}

static enum drm_mode_status
-cdn_dp_connector_mode_valid(struct drm_connector *connector,
-   const struct drm_display_mode *mode)
+cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
+const struct drm_display_info *display_info,
+const struct drm_display_mode *mode)
{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   struct drm_display_info *display_info = &dp->connector.display_info;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;

@@ -323,11 +308,6 @@ cdn_dp_connector_mode_valid(struct drm_connector 
*connector,
return MODE_OK;
}

-static struct drm_connector_helper_funcs cdn_dp_connector_helper_funcs = {
-   .get_modes = cdn_dp_connector_get_modes,
-   .mode_valid = cdn_dp_connector_mode_valid,
-};
-
static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
{
int ret;
@@ -360,7 +340,7 @@ static int cdn_dp_firmware_init(struct cdn_dp_device *dp)

static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
{
-   const struct drm_display_info *info = &dp->connector.display_info;
+   const struct drm_display_info *info = &dp->connector->display_info;
int ret;

if (!cdn_dp_check_sink_connection(dp))
@@ -374,9 +354,9 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device 
*dp)
}

drm_edid_free(dp->drm_edid);
-   dp->drm_edid = drm_edid_read_custom(&dp->connector,
+   dp->drm_edid = drm_edid_read_custom(dp->connector,
cdn_dp_get_edid_block, dp);
-   drm_ed

[PATCH v2] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-22 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.

Considering that some code depend on the connector, the following
changes have been made:
- Do not get edid in cdn_dp_get_sink_capability() when connector is
not present.
- Update bpc info in cdn_dp_bridge_atomic_enable() instead of
cdn_dp_encoder_mode_set(). Actually, the bpc data will be used in
cdn_dp_bridge_atomic_enable().

This patch also convert to use devm_drm_bridge_alloc() API.

Tested with RK3399 EVB IND board.

Signed-off-by: Chaoyi Chen 
---

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250507035148.415-1-ker...@airkyi.com/
- Use drm_atomic_get_new_connector_for_encoder() to get connector
- Convert to use devm_drm_bridge_alloc() API
- Fix typo: cdn_dp_connector_edid_read -> cdn_dp_bridge_edid_read

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 204 +
 drivers/gpu/drm/rockchip/cdn-dp-core.h |   5 +-
 2 files changed, 112 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 292c31de18f1..848f47d4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -25,9 +25,9 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *connector_to_dp(struct drm_connector 
*connector)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-   return container_of(connector, struct cdn_dp_device, connector);
+   return container_of(bridge, struct cdn_dp_device, bridge);
 }
 
 static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
@@ -231,9 +231,9 @@ static bool cdn_dp_check_sink_connection(struct 
cdn_dp_device *dp)
 }
 
 static enum drm_connector_status
-cdn_dp_connector_detect(struct drm_connector *connector, bool force)
+cdn_dp_bridge_detect(struct drm_bridge *bridge)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
enum drm_connector_status status = connector_status_disconnected;
 
mutex_lock(&dp->lock);
@@ -244,41 +244,25 @@ cdn_dp_connector_detect(struct drm_connector *connector, 
bool force)
return status;
 }
 
-static void cdn_dp_connector_destroy(struct drm_connector *connector)
+static const struct drm_edid *
+cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector 
*connector)
 {
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
-   .detect = cdn_dp_connector_detect,
-   .destroy = cdn_dp_connector_destroy,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int cdn_dp_connector_get_modes(struct drm_connector *connector)
-{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   int ret = 0;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   const struct drm_edid *drm_edid;
 
mutex_lock(&dp->lock);
-
-   ret = drm_edid_connector_add_modes(connector);
-
+   drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
mutex_unlock(&dp->lock);
 
-   return ret;
+   return drm_edid;
 }
 
 static enum drm_mode_status
-cdn_dp_connector_mode_valid(struct drm_connector *connector,
-   const struct drm_display_mode *mode)
+cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
+const struct drm_display_info *display_info,
+const struct drm_display_mode *mode)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   struct drm_display_info *display_info = &dp->connector.display_info;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;
 
@@ -323,11 +307,6 @@ cdn_dp_connector_mode_valid(struct drm_connector 
*connector,
return MODE_OK;
 }
 
-static struct drm_connector_helper_funcs cdn_dp_connector_helper_funcs = {
-   .get_modes = cdn_dp_connector_get_modes,
-   .mode_valid = cdn_dp_connector_mode_valid,
-};
-
 static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
 {
int ret;
@@ -360,7 +339,8 @@ static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
 
 static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
 {
-   const struct drm_display_info *info = &dp->connector.display_info;
+   struct drm_connector *connector = dp->connector;
+   const struct drm_display_info *info;
int ret;
 
if (!cdn_d

Re: [PATCH v3] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-28 Thread Chaoyi Chen

Hi Dmitry,

On 2025/5/29 0:09, Dmitry Baryshkov wrote:

@@ -595,16 +546,41 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
*dp)
   static void cdn_dp_audio_handle_plugged_change(struct cdn_dp_device *dp,
 bool plugged)
   {
-if (dp->codec_dev)
-dp->plugged_cb(dp->codec_dev, plugged);
+if (dp->sink_has_audio)
+drm_connector_hdmi_audio_plugged_notify(dp->connector, plugged);

I'd say, notify always and let userspace figure it out via the ELD. Then
you shouldn't need sink_has_audio. This would match the behaviour of
HDMI drivers.

Oh, I find that there are similar usages in qcom msm driver. Is there
any more progress?

For msm driver it is required as DSP requires HDMI to be plugged for
the audio path to work.


I see, will fix in v4.


@@ -705,8 +681,6 @@ static int cdn_dp_encoder_atomic_check(struct drm_encoder 
*encoder,

   static const struct drm_encoder_helper_funcs cdn_dp_encoder_helper_funcs = {
  .mode_set = cdn_dp_encoder_mode_set,
-.enable = cdn_dp_encoder_enable,
-.disable = cdn_dp_encoder_disable,
  .atomic_check = cdn_dp_encoder_atomic_check,

Nit: for the future cleanup, it should probably be possible to get rid
of these encoder ops too by moving them to the bridge ops.

Interesting, have these patches been submitted upstream yet?

Everything is already there, see drm_bridge_funcs::mode_set() and
drm_bridge_funcs::atomic_check().


Thanks for the clarification. I will move mode_set() to bridge ops.

And for the drm_encoder_helper_funcs::atomic_check(), most Rockchip 
drivers will set some Rockchip-specific properties here so that the VOP 
driver can process them. In the future, we may integrate a new encoder 
driver to process these private properties. So, I prefer to keep this as 
it is.





[PATCH v4] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-29 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.
Considering that some code depend on the connector, the following
changes have been made:
- Only process edid in &drm_bridge_funcs.edid_read(), so no need to
store additional edid info.
- Now cdn_dp_get_sink_capability() only focused on reading DPCD_REV.
- Update bpc info in cdn_dp_bridge_atomic_enable() instead of
cdn_dp_encoder_mode_set(). Actually, the bpc data will be used in
cdn_dp_bridge_atomic_enable().
- Switch to use DRM_BRIDGE_OP_DP_AUDIO helpers.

This patch also convert to use devm_drm_bridge_alloc() API.

Tested with RK3399 EVB IND board.

Signed-off-by: Chaoyi Chen 
---

Changes in v4:
- Link to V3: 
https://lore.kernel.org/all/20250527081447.304-1-ker...@airkyi.com/
- Code cleanup for connector/audio

Changes in v3:
- Link to V2: 
https://lore.kernel.org/all/20250523011310.120-1-ker...@airkyi.com/
- Switch to use DRM_BRIDGE_OP_DP_AUDIO helpers
- Remove the dependency for connector
- Remove the extra stored edid
- Code cleanup

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250507035148.415-1-ker...@airkyi.com/
- Use drm_atomic_get_new_connector_for_encoder() to get connector
- Convert to use devm_drm_bridge_alloc() API
- Fix typo: cdn_dp_connector_edid_read -> cdn_dp_bridge_edid_read

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 292 +
 drivers/gpu/drm/rockchip/cdn-dp-core.h |   8 +-
 2 files changed, 110 insertions(+), 190 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 292c31de18f1..bf9b78c4c034 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -16,7 +16,9 @@
 #include 
 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,9 +27,9 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *connector_to_dp(struct drm_connector 
*connector)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-   return container_of(connector, struct cdn_dp_device, connector);
+   return container_of(bridge, struct cdn_dp_device, bridge);
 }
 
 static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
@@ -231,9 +233,9 @@ static bool cdn_dp_check_sink_connection(struct 
cdn_dp_device *dp)
 }
 
 static enum drm_connector_status
-cdn_dp_connector_detect(struct drm_connector *connector, bool force)
+cdn_dp_bridge_detect(struct drm_bridge *bridge)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
enum drm_connector_status status = connector_status_disconnected;
 
mutex_lock(&dp->lock);
@@ -244,41 +246,25 @@ cdn_dp_connector_detect(struct drm_connector *connector, 
bool force)
return status;
 }
 
-static void cdn_dp_connector_destroy(struct drm_connector *connector)
+static const struct drm_edid *
+cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector 
*connector)
 {
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
-   .detect = cdn_dp_connector_detect,
-   .destroy = cdn_dp_connector_destroy,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int cdn_dp_connector_get_modes(struct drm_connector *connector)
-{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   int ret = 0;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   const struct drm_edid *drm_edid;
 
mutex_lock(&dp->lock);
-
-   ret = drm_edid_connector_add_modes(connector);
-
+   drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
mutex_unlock(&dp->lock);
 
-   return ret;
+   return drm_edid;
 }
 
 static enum drm_mode_status
-cdn_dp_connector_mode_valid(struct drm_connector *connector,
-   const struct drm_display_mode *mode)
+cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
+const struct drm_display_info *display_info,
+const struct drm_display_mode *mode)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   struct drm_display_info *display_info = &dp->connector.display_info;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;
 
@@ -323,11 +309,6 @@ cdn_dp_connector_mode_valid(struct drm_connector 
*connector,
return MODE_OK;
 }
 
-static struct d

[PATCH RESEND] drm/bridge-connector: Fix bridge in drm_connector_hdmi_audio_init()

2025-06-19 Thread Chaoyi Chen
From: Chaoyi Chen 

The bridge used in drm_connector_hdmi_audio_init() does not correctly
point to the required audio bridge, which lead to incorrect audio
configuration input.

Fixes: 231adeda9f67 ("drm/bridge-connector: hook DisplayPort audio support")
Signed-off-by: Chaoyi Chen 
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c 
b/drivers/gpu/drm/display/drm_bridge_connector.c
index 7d2e499ea5de..262e93e07a28 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -708,11 +708,14 @@ struct drm_connector *drm_bridge_connector_init(struct 
drm_device *drm,
if (bridge_connector->bridge_hdmi_audio ||
bridge_connector->bridge_dp_audio) {
struct device *dev;
+   struct drm_bridge *bridge;
 
if (bridge_connector->bridge_hdmi_audio)
-   dev = 
bridge_connector->bridge_hdmi_audio->hdmi_audio_dev;
+   bridge = bridge_connector->bridge_hdmi_audio;
else
-   dev = bridge_connector->bridge_dp_audio->hdmi_audio_dev;
+   bridge = bridge_connector->bridge_dp_audio;
+
+   dev = bridge->hdmi_audio_dev;
 
ret = drm_connector_hdmi_audio_init(connector, dev,

&drm_bridge_connector_hdmi_audio_funcs,
-- 
2.49.0




[PATCH v3 1/5] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch

2025-07-29 Thread Chaoyi Chen
From: Chaoyi Chen 

The RK3399 SoC integrates two USB/DP combo PHYs, each of which
supports software-configurable pin mapping and DisplayPort lane
assignment. These capabilities enable the PHY itself to handle both
mode switching and orientation switching, based on the Type-C plug
orientation and USB PD negotiation results.

While an external Type-C controller is still required to detect cable
attachment and report USB PD events, the actual mode and orientation
switching is performed internally by the PHY through software
configuration. This allows the PHY to act as a Type-C multiplexer for
both data role and DP altmode configuration.

To reflect this hardware design, this patch introduces a new
"mode-switch" property for the dp-port node in the device tree bindings.
This property indicates that the connected PHY is capable of handling
Type-C mode switching itself.

Signed-off-by: Chaoyi Chen 
---

Changes in v3:
- Add more descriptions to clarify the role of the PHY in switching.

Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.

 .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++
 1 file changed, 6 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..ccbe1c9cb0bf 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,12 @@ properties:
   '#phy-cells':
 const: 0
 
+  mode-switch:
+description: |
+  Indicates the PHY can handle altmode switching. In this case,
+  requires an external USB Type-C controller to report USB PD message.
+type: boolean
+
   port:
 $ref: /schemas/graph.yaml#/properties/port
 description: Connection to USB Type-C connector
-- 
2.49.0



[PATCH v3 3/5] drm/rockchip: cdn-dp: Support handle lane info and HPD without extcon

2025-07-29 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

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



[PATCH v3 4/5] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP

2025-07-29 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---
 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@fec0 {
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



[PATCH v3 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support

2025-07-29 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

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 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -54,6 +55,9 @@
 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #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_MASKGENMASK(7, 4)
+#define PHY_DP_POWER_STATE_ACK_SHIFT   4
+#define PHY_DP_POWER_STATE_MASKGENMASK(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   10
 
@@ -340,6 +362,31 @@
 #define MODE_DFP_USB   BIT(1)
 #define MODE_DFP_DPBIT(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

[PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board

2025-07-29 Thread Chaoyi Chen
From: Chaoyi Chen 

This series focuses on adding Type-C DP support for USBDP PHY and DP
driver. The USBDP PHY and DP will perceive the changes in cable status
based on the USB PD and Type-C state machines provided by TCPM. Before
this, the USBDP PHY and DP controller of RK3399 sensed cable state
changes through extcon, and devices such as the RK3399 Gru-Chromebook
rely on them. This series should not break them.


1. Altmode switching and orientation switching for USBDP PHY

For USB Type-C interfaces, an external Type-C controller chip assists
by detecting cable attachment, determining plug orientation, and
reporting USB PD message. The USB/DP combo PHY supports software
configurable pin mapping and DisplayPort lane assignment. Based on
these message, the combo PHY can perform both altmode switching and
orientation switching via software.

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 +---> USB2.0 PHY > DWC3 USB controller
 |
 +---> USB/DP PHY0 +--> CDN-DP controller
   |
   +--> DWC3 USB controller

2. DP HPD event notify

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.

USB/DP PHY0 ---+
   | <> CDN-DP controller
USB/DP PHY1 ---+

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 v3:
- Link to V2: https://lore.kernel.org/all/20250718062619.99-1-ker...@airkyi.com/
- Add more descriptions to clarify the role of the PHY in switching.
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250715112456.101-1-ker...@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|   6 +
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  12 +-
 .../boot/dts/rockchip/rk3399-evb-ind.dts  | 146 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.c|  37 +-
 drivers/phy/rockchip/phy-rockchip-typec.c | 403 +-
 5 files changed, 579 insertions(+), 25 deletions(-)

-- 
2.49.0



[PATCH v3 5/5] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

2025-07-29 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

Changes in v3:
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.

 .../boot/dts/rockchip/rk3399-evb-ind.dts  | 146 ++
 1 file changed, 146 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..a6bd2973 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 
 #include "rk3399.dtsi"
 
 / {
@@ -19,6 +20,21 @@ chosen {
stdout-path = "serial2:150n8";
};
 
+   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,71 @@ 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 = ;
+   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 = <100>;
+   sink-pdos =
+   ;
+   source-pdos =
+   ;
+
+   altmodes {
+   displayport {
+   svid = /bits/ 16 <0xff01>;
+   vdo = <0x1c46>;
+   };
+   };
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   usbc_hs: endpoint {
+   remote-endpoint = 
<&u2phy0_typec_hs>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   usbc_ss: endpoint {
+   remote-endpoint = 
<&tcphy0_typec_ss>;
+   };
+   };
+
+   port@2 {
+   reg = <2>;
+
+   usbc_dp: endpoint {
+   remote-endpoint = 
<&tcphy0_typec_dp>;
+   };
+   };
+   };
+   };
+   };
+};
+
 &i2s2 {
status = "okay";
 };
@@ -354,6 +446,16 @@ &io_domains {
 };
 
 &pinctrl {
+   usb-typec {
+   usbc0_int: usbc0-int {
+  

Re: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board

2025-08-04 Thread Chaoyi Chen

Hi Dmitry,

On 8/5/2025 12:26 PM, Dmitry Baryshkov wrote:

On 05/08/2025 09:13, Chaoyi Chen wrote:

Hi Dmitry,

On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:

[...]


Currently, the software simply selects the first available port. So 
if user
plugs in DP dongles in both USB-C ports, the DP driver will select 
the first

port. This process is implemented in cdn_dp_connected_port() .

I think Stephen Boyd has been looking on similar issues for 
Chromebooks,

which were sharing DP controller between several USB-C ports. I don't
remember what was his last status. I think there it was easier since 
the

bifurcation point was the EC.


I think the latest progress should be here: [0]. It seems that it 
hasn't been updated for a while.


Might be :-(



[0]: https://lore.kernel.org/all/20240901040658.157425-1- 
swb...@chromium.org/





I think, CDN-DP needs to register up to two encoders and up to two
connectors, having a separate drm_bridge chain for each of the DP
signals paths (in the end, you can not guarantee that both branches 
will

have the same simple CDN-DP -> PHY -> USB-C configuration: there can be
different retimers, etc).

Both encoders should list the same CRTC in possible_crtcs, etc. Of
course, it should not be possible to enable both of them.

This way if the user plugs in two DP dongles, it would be possible to
select, which output actually gets a signal.


That makes sense, but this might make the DP driver quite complex. I 
will see if I can make it happen.


I think it's trading one burden for another, because CDN-DP currently 
has a complication of calling cdn_dp_get_port_lanes() / 
cdn_dp_enable_phy() in a loop rather than just enabling one instance.


Yep, I will give it a try.












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.
Does it actually work? The OOB HPD event will be repoted for the 
usb-c
connector's fwnode, but the DP controller isn't connected to that 
node
anyhow. If I'm not mistaken, the HPD signal will not reach DP 
driver in

this case.

Yes.  What you mentioned is the case in
drivers/usb/typec/altmodes/displayport.c . I have also added a new 
OOB event
notify in the PHY driver in Patch 3, where the expected fwnode is 
used in
the PHY. So now we have two OOB HPD events, one from altmodes/ 
displayport.c
and the other from PHY. Only the HPD from PHY is eventually passed 
to the DP

driver.

This way you will loose IRQ_HPD pulse events from the DP. They are used
by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
change on the DPRX side and the DPTX should reread link params and 
maybe

retrain the link.


Sorry, I still don't quite understand your point. I think the entire 
notification path is as follows:


Type-C mux callback -> RK3399 USBDP PHY -> PHY calls 
drm_connector_oob_hotplug_event() -> DP driver


Are you concerned that the IRQ_HPD event is not being handled 
somewhere along the path? Is it that the Type-C mux callback didn't 
notify the PHY, or that after the PHY passed the event to the DP 
driver via the OOB event, the DP driver didn't handle it?


The IRQ_HPD is an event coming from DPRX, it is delivered as a part of 
the attention VDM, see DP_STATUS_IRQ_HPD. It's being handled by the 
altmode displayport.c driver and is then delivered as an OOB hotplug 
call. However, it's not a mux event, so it is not (and it should not) 
being broadcasted over the typec_mux devices.


The way we were handling that is by having a chain of drm_aux_bridges 
for all interim devices, ending up with a drm_dp_hpd_bridge registered 
by the TCPM. This way when the DPRX triggers the IRQ_HPD event, it is 
being handled by the displayport.c and then delivered through that 
bridge to the DP driver.


I think the issue goes back to the beginning. The key is to reuse the 
logic in displayport.c, and the previous approach of directly setting 
the fwnode has already been rejected. Is it a good idea to register the 
aux hpd bridge in displayport.c? In this way, we don't need to register 
it with a bunch of PD drivers (such as fusb302), which seems like a more 
generic solution.





Re: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board

2025-08-05 Thread Chaoyi Chen

On 8/5/2025 6:44 PM, Dmitry Baryshkov wrote:


On Tue, Aug 05, 2025 at 02:32:17PM +0800, Chaoyi Chen wrote:

Hi Dmitry,

On 8/5/2025 12:26 PM, Dmitry Baryshkov wrote:

On 05/08/2025 09:13, Chaoyi Chen wrote:

Hi Dmitry,

On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:

[...]



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.

Does it actually work? The OOB HPD event will be repoted
for the usb-c
connector's fwnode, but the DP controller isn't
connected to that node
anyhow. If I'm not mistaken, the HPD signal will not
reach DP driver in
this case.

Yes.  What you mentioned is the case in
drivers/usb/typec/altmodes/displayport.c . I have also added
a new OOB event
notify in the PHY driver in Patch 3, where the expected
fwnode is used in
the PHY. So now we have two OOB HPD events, one from
altmodes/ displayport.c
and the other from PHY. Only the HPD from PHY is eventually
passed to the DP
driver.

This way you will loose IRQ_HPD pulse events from the DP. They are used
by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
change on the DPRX side and the DPTX should reread link params
and maybe
retrain the link.

Sorry, I still don't quite understand your point. I think the entire
notification path is as follows:

Type-C mux callback -> RK3399 USBDP PHY -> PHY calls
drm_connector_oob_hotplug_event() -> DP driver

Are you concerned that the IRQ_HPD event is not being handled
somewhere along the path? Is it that the Type-C mux callback didn't
notify the PHY, or that after the PHY passed the event to the DP
driver via the OOB event, the DP driver didn't handle it?

The IRQ_HPD is an event coming from DPRX, it is delivered as a part of
the attention VDM, see DP_STATUS_IRQ_HPD. It's being handled by the
altmode displayport.c driver and is then delivered as an OOB hotplug
call. However, it's not a mux event, so it is not (and it should not)
being broadcasted over the typec_mux devices.

The way we were handling that is by having a chain of drm_aux_bridges
for all interim devices, ending up with a drm_dp_hpd_bridge registered
by the TCPM. This way when the DPRX triggers the IRQ_HPD event, it is
being handled by the displayport.c and then delivered through that
bridge to the DP driver.

I think the issue goes back to the beginning. The key is to reuse the logic
in displayport.c, and the previous approach of directly setting the fwnode
has already been rejected. Is it a good idea to register the aux hpd bridge
in displayport.c? In this way, we don't need to register it with a bunch of
PD drivers (such as fusb302), which seems like a more generic solution.

displayport.c comes into play only when you actually attach a DP dongle,
which is too late for bringing up the display pipeline. But your point
is valid, it might be worth moving drm_dp_hpd registration to
typec_port_register_altmode().


Very insightful, thank you! I will try to do this in v4 :)




Re: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board

2025-07-30 Thread Chaoyi Chen

Hi Dmitry,

On 7/31/2025 3:13 AM, Dmitry Baryshkov wrote:

On Tue, Jul 29, 2025 at 05:00:27PM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

This series focuses on adding Type-C DP support for USBDP PHY and DP
driver. The USBDP PHY and DP will perceive the changes in cable status
based on the USB PD and Type-C state machines provided by TCPM. Before
this, the USBDP PHY and DP controller of RK3399 sensed cable state
changes through extcon, and devices such as the RK3399 Gru-Chromebook
rely on them. This series should not break them.


[]



2. DP HPD event notify

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.

USB/DP PHY0 ---+
| <> CDN-DP controller
USB/DP PHY1 ---+

Could you please clarify this, can you switch DP stream between two
USB-C outputs? What happens if user plugs in DP dongles in both USB-C
ports?


Currently, the software simply selects the first available port. So if 
user plugs in DP dongles in both USB-C ports, the DP driver will select 
the first port. This process is implemented in cdn_dp_connected_port() .







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.

Does it actually work? The OOB HPD event will be repoted for the usb-c
connector's fwnode, but the DP controller isn't connected to that node
anyhow. If I'm not mistaken, the HPD signal will not reach DP driver in
this case.


Yes.  What you mentioned is the case in 
drivers/usb/typec/altmodes/displayport.c . I have also added a new OOB 
event notify in the PHY driver in Patch 3, where the expected fwnode is 
used in the PHY. So now we have two OOB HPD events, one from 
altmodes/displayport.c and the other from PHY. Only the HPD from PHY is 
eventually passed to the DP driver.







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.



Re: [PATCH v3 4/5] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP

2025-07-29 Thread Chaoyi Chen

On 7/30/2025 3:59 AM, Diederik de Haas wrote:


On Tue Jul 29, 2025 at 11:00 AM CEST, Chaoyi Chen wrote:

From: Chaoyi Chen 

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 
---
  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@fec0 {
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>;
+   };

Patch 5 adds a single endpoint to dp_out (without a reg property), so it
seems that #address/#size-cells is not needed?
If you run ``make CHECK_DTBS=y W=1 rockchip/rk3399-evb-ind.dtb`` it
should spit out a warning about that.

Exactly! Will remove this in v4.


Cheers,
   Diederik


};
};
  


Re: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board

2025-08-04 Thread Chaoyi Chen

Hi Dmitry,

On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:

[...]



Currently, the software simply selects the first available port. So if user
plugs in DP dongles in both USB-C ports, the DP driver will select the first
port. This process is implemented in cdn_dp_connected_port() .


I think Stephen Boyd has been looking on similar issues for Chromebooks,
which were sharing DP controller between several USB-C ports. I don't
remember what was his last status. I think there it was easier since the
bifurcation point was the EC.


I think the latest progress should be here: [0]. It seems that it hasn't 
been updated for a while.


[0]: 
https://lore.kernel.org/all/20240901040658.157425-1-swb...@chromium.org/





I think, CDN-DP needs to register up to two encoders and up to two
connectors, having a separate drm_bridge chain for each of the DP
signals paths (in the end, you can not guarantee that both branches will
have the same simple CDN-DP -> PHY -> USB-C configuration: there can be
different retimers, etc).

Both encoders should list the same CRTC in possible_crtcs, etc. Of
course, it should not be possible to enable both of them.

This way if the user plugs in two DP dongles, it would be possible to
select, which output actually gets a signal.


That makes sense, but this might make the DP driver quite complex. I 
will see if I can make it happen.








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.

Does it actually work? The OOB HPD event will be repoted for the usb-c
connector's fwnode, but the DP controller isn't connected to that node
anyhow. If I'm not mistaken, the HPD signal will not reach DP driver in
this case.

Yes.  What you mentioned is the case in
drivers/usb/typec/altmodes/displayport.c . I have also added a new OOB event
notify in the PHY driver in Patch 3, where the expected fwnode is used in
the PHY. So now we have two OOB HPD events, one from altmodes/displayport.c
and the other from PHY. Only the HPD from PHY is eventually passed to the DP
driver.

This way you will loose IRQ_HPD pulse events from the DP. They are used
by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
change on the DPRX side and the DPTX should reread link params and maybe
retrain the link.


Sorry, I still don't quite understand your point. I think the entire 
notification path is as follows:


Type-C mux callback -> RK3399 USBDP PHY -> PHY calls 
drm_connector_oob_hotplug_event() -> DP driver


Are you concerned that the IRQ_HPD event is not being handled somewhere 
along the path? Is it that the Type-C mux callback didn't notify the 
PHY, or that after the PHY passed the event to the DP driver via the OOB 
event, the DP driver didn't handle it?




[PATCH v3 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-12 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert cdn-dp-rockchip.txt to yaml.

Signed-off-by: Chaoyi Chen 
---

Changes in v3:
- Add more description about phy/extcon
- Fix some coding style

Changes in v2:
- Rename binding file name to match compatible
- Add more description about grf/phy/extcon
- Fix coding style


 .../display/rockchip/cdn-dp-rockchip.txt  |  74 
 .../rockchip/rockchip,rk3399-cdn-dp.yaml  | 165 ++
 2 files changed, 165 insertions(+), 74 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
deleted file mode 100644
index 8df7d2e393d6..
--- a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-Rockchip RK3399 specific extensions to the cdn Display Port
-
-
-Required properties:
-- compatible: must be "rockchip,rk3399-cdn-dp"
-
-- reg: physical base address of the controller and length
-
-- clocks: from common clock binding: handle to dp clock.
-
-- clock-names: from common clock binding:
-  Required elements: "core-clk" "pclk" "spdif" "grf"
-
-- resets : a list of phandle + reset specifier pairs
-- reset-names : string of reset names
-   Required elements: "apb", "core", "dptx", "spdif"
-- power-domains : power-domain property defined with a phandle
- to respective power domain.
-- assigned-clocks: main clock, should be <&cru SCLK_DP_CORE>
-- assigned-clock-rates : the DP core clk frequency, shall be: 1
-
-- rockchip,grf: this soc should set GRF regs, so need get grf here.
-
-- ports: contain a port nodes with endpoint definitions as defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-contained 2 endpoints, connecting to the output of vop.
-
-- phys: from general PHY binding: the phandle for the PHY device.
-
-- extcon: extcon specifier for the Power Delivery
-
-- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
-

-
-Example:
-   cdn_dp: dp@fec0 {
-   compatible = "rockchip,rk3399-cdn-dp";
-   reg = <0x0 0xfec0 0x0 0x10>;
-   interrupts = ;
-   clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>,
-<&cru SCLK_SPDIF_REC_DPTX>, <&cru PCLK_VIO_GRF>;
-   clock-names = "core-clk", "pclk", "spdif", "grf";
-   assigned-clocks = <&cru SCLK_DP_CORE>;
-   assigned-clock-rates = <1>;
-   power-domains = <&power RK3399_PD_HDCP>;
-   phys = <&tcphy0_dp>, <&tcphy1_dp>;
-   resets = <&cru SRST_DPTX_SPDIF_REC>;
-   reset-names = "spdif";
-   extcon = <&fusb0>, <&fusb1>;
-   rockchip,grf = <&grf>;
-   #address-cells = <1>;
-   #size-cells = <0>;
-   #sound-dai-cells = <1>;
-
-   ports {
-   #address-cells = <1>;
-   #size-cells = <0>;
-
-   dp_in: port {
-   #address-cells = <1>;
-   #size-cells = <0>;
-   dp_in_vopb: endpoint@0 {
-   reg = <0>;
-   remote-endpoint = <&vopb_out_dp>;
-   };
-
-   dp_in_vopl: endpoint@1 {
-   reg = <1>;
-   remote-endpoint = <&vopl_out_dp>;
-   };
-   };
-   };
-   };
diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
new file mode 100644
index ..7c2225204de2
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
@@ -0,0 +1,165 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/display/rockchip/rockchip,rk3399-cdn-dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3399 specific extensions to the 

[PATCH v3 1/2] arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp

2025-05-12 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +-
 1 file changed, 9 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..e340b6df7445 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@fec0 {
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,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+   dp_out: port@1 {
+   reg = <1>;
+   };
};
};

--
2.49.0



[PATCH v3 0/2] Convert Rockchip CDN DP binding to yaml

2025-05-12 Thread Chaoyi Chen
From: Chaoyi Chen 

This series convert cdn-dp-rockchip.txt to yaml.

PATCH 1 try to improve coding style on the existing rk3399 cdn-dp
node.
PATCH 2 try to convert cdn-dp-rockchip.txt to yaml.

Changes in v3:
- Link to V2: 
https://lore.kernel.org/all/20250509070247.868-1-ker...@airkyi.com/
- Add more description about phy/extcon
- Fix some coding style

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250508064304.670-1-ker...@airkyi.com/
- Rename binding file name to match compatible
- Add more description about grf/phy/extcon
- Fix coding style

Chaoyi Chen (2):
  arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp
  dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

 .../display/rockchip/cdn-dp-rockchip.txt  |  74 
 .../rockchip/rockchip,rk3399-cdn-dp.yaml  | 165 ++
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 3 files changed, 174 insertions(+), 75 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml

--
2.49.0



[PATCH v2 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-09 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert cdn-dp-rockchip.txt to yaml.

Signed-off-by: Chaoyi Chen 
---

Changes in v2:
- Rename binding file name to match compatible
- Add more description about grf/phy/extcon
- Fix coding style


 .../display/rockchip/cdn-dp-rockchip.txt  |  74 
 .../rockchip/rockchip,rk3399-cdn-dp.yaml  | 158 ++
 2 files changed, 158 insertions(+), 74 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
deleted file mode 100644
index 8df7d2e393d6..
--- a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-Rockchip RK3399 specific extensions to the cdn Display Port
-
-
-Required properties:
-- compatible: must be "rockchip,rk3399-cdn-dp"
-
-- reg: physical base address of the controller and length
-
-- clocks: from common clock binding: handle to dp clock.
-
-- clock-names: from common clock binding:
-  Required elements: "core-clk" "pclk" "spdif" "grf"
-
-- resets : a list of phandle + reset specifier pairs
-- reset-names : string of reset names
-   Required elements: "apb", "core", "dptx", "spdif"
-- power-domains : power-domain property defined with a phandle
- to respective power domain.
-- assigned-clocks: main clock, should be <&cru SCLK_DP_CORE>
-- assigned-clock-rates : the DP core clk frequency, shall be: 1
-
-- rockchip,grf: this soc should set GRF regs, so need get grf here.
-
-- ports: contain a port nodes with endpoint definitions as defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-contained 2 endpoints, connecting to the output of vop.
-
-- phys: from general PHY binding: the phandle for the PHY device.
-
-- extcon: extcon specifier for the Power Delivery
-
-- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
-

-
-Example:
-   cdn_dp: dp@fec0 {
-   compatible = "rockchip,rk3399-cdn-dp";
-   reg = <0x0 0xfec0 0x0 0x10>;
-   interrupts = ;
-   clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>,
-<&cru SCLK_SPDIF_REC_DPTX>, <&cru PCLK_VIO_GRF>;
-   clock-names = "core-clk", "pclk", "spdif", "grf";
-   assigned-clocks = <&cru SCLK_DP_CORE>;
-   assigned-clock-rates = <1>;
-   power-domains = <&power RK3399_PD_HDCP>;
-   phys = <&tcphy0_dp>, <&tcphy1_dp>;
-   resets = <&cru SRST_DPTX_SPDIF_REC>;
-   reset-names = "spdif";
-   extcon = <&fusb0>, <&fusb1>;
-   rockchip,grf = <&grf>;
-   #address-cells = <1>;
-   #size-cells = <0>;
-   #sound-dai-cells = <1>;
-
-   ports {
-   #address-cells = <1>;
-   #size-cells = <0>;
-
-   dp_in: port {
-   #address-cells = <1>;
-   #size-cells = <0>;
-   dp_in_vopb: endpoint@0 {
-   reg = <0>;
-   remote-endpoint = <&vopb_out_dp>;
-   };
-
-   dp_in_vopl: endpoint@1 {
-   reg = <1>;
-   remote-endpoint = <&vopl_out_dp>;
-   };
-   };
-   };
-   };
diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
new file mode 100644
index ..99d1f0ad9cda
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/rockchip/rockchip,cdn-dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3399 specific extensions to the CDN Display Port
+
+maintainers:
+  - Andy Yan 
+  - Heiko Stuebner 
+  - Sandy Huan

[PATCH v2 0/2] Convert Rockchip CDN DP binding to yaml

2025-05-09 Thread Chaoyi Chen
From: Chaoyi Chen 

This series convert cdn-dp-rockchip.txt to yaml.

PATCH 1 try to improve coding style on the existing rk3399 cdn-dp
node.
PATCH 2 try to convert cdn-dp-rockchip.txt to yaml.

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250508064304.670-1-ker...@airkyi.com/
- Rename binding file name to match compatible
- Add more description about grf/phy/extcon
- Fix coding style

Chaoyi Chen (2):
  arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp
  dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

 .../display/rockchip/cdn-dp-rockchip.txt  |  74 
 .../rockchip/rockchip,rk3399-cdn-dp.yaml  | 158 ++
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 3 files changed, 167 insertions(+), 75 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml

--
2.49.0



[PATCH v2 1/2] arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp

2025-05-09 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +-
 1 file changed, 9 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..e340b6df7445 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@fec0 {
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,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+   dp_out: port@1 {
+   reg = <1>;
+   };
};
};

--
2.49.0



Re: [PATCH 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-09 Thread Chaoyi Chen

Hi Krzysztof,

On 2025/5/8 15:16, Krzysztof Kozlowski wrote:

On 08/05/2025 08:43, Chaoyi Chen wrote:

From: Chaoyi Chen 

Convert cdn-dp-rockchip.txt to yaml.

Tested with:

1. make ARCH=arm64 dt_binding_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

2. make ARCH=arm64 dtbs_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

Drop. You do not have to embed in commit msg standard makefile targets.
We all know how to use it. You do not do it for C files, do you?


Will drop it on v2.





Signed-off-by: Chaoyi Chen 
---

...


-   };
diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml
new file mode 100644
index ..ed68b48a6743
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,cdn-dp.yaml

Filename matching compatible.


Will change it in v2.





@@ -0,0 +1,148 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/rockchip/rockchip,cdn-dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3399 specific extensions to the CDN Display Port
+
+maintainers:
+  - Andy Yan 
+  - Heiko Stuebner 
+  - Sandy Huang 
+
+properties:
+  compatible:
+items:
+  - const: rockchip,rk3399-cdn-dp
+
+  reg:
+description:
+  CDN DP core register

Missing constraints. Drop description.

Just look at other bindings.


Will fix in v2.





+
+  assigned-clock-rates: true
+  assigned-clocks: true

Drop these two


+
+  clocks:
+minItems: 4

No, look at other bindings.


Will fix in v2.





+
+  clock-names:
+items:
+  - const: core-clk
+  - const: pclk
+  - const: spdif
+  - const: grf
+
+  extcon:
+description:
+  Phandle to the extcon device providing the cable state for the DP phy.

Missing type, unless you could not add a type because of conflicts? This
should be really fixed...


Will add refs in v2.






+
+  interrupts:
+maxItems: 1

and here is maxItems. Why in other places you put minItems?


Sorry for that,  I misunderstood the meaning of those filed. Will fix in v2.





+
+  phys:
+minItems: 1
+maxItems: 2

Why is this flexible? It wasn't in original binding and you must
document all the changes done to the binding in commit msg.


I think the original binding had this. I will fix this in v2 and add 
more description.






+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input of the CDN DP
+properties:
+  endpoint@0:
+description: Connection to the VOPB
+  endpoint@1:
+description: Connection to the VOPL
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output of the CDN DP
+
+required:
+  - port@0
+  - port@1
+
+  power-domains:
+maxItems: 1
+
+  resets:
+minItems: 4

No, look at other bindings.


Will fix in v2.





+
+  reset-names:
+items:
+  - const: spdif
+  - const: dptx
+  - const: apb
+  - const: core
+
+  rockchip,grf:
+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  This SoC makes use of GRF regs.

For what? You did not say anything useful above, so instead explain the
purpose.


Will add more description in v2.





+
+  "#sound-dai-cells":
+const: 1

Missing dai-common ref, unless this is not a DAI?


Will add dai-common.yaml ref in v2.





+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - phys
+  - ports
+  - resets
+  - reset-names
+  - rockchip,grf
+
+unevaluatedProperties: false

Where is any $ref? additionalProperties instead or add proper ref


Will fix in v2.






+
+examples:
+  - |
+#include 
+#include 
+#include 
+cdn_dp: dp@fec0 {

Drop unused label


Will drop it in v2.


Thanks for you fast reply!



[PATCH] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-06 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.

Tested with RK3399 EVB IND board.

Signed-off-by: Chaoyi Chen 
---
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 163 +
 drivers/gpu/drm/rockchip/cdn-dp-core.h |   5 +-
 2 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 292c31de18f1..bc70dae8ff72 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -25,9 +25,9 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *connector_to_dp(struct drm_connector 
*connector)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-   return container_of(connector, struct cdn_dp_device, connector);
+   return container_of(bridge, struct cdn_dp_device, bridge);
 }
 
 static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
@@ -231,9 +231,9 @@ static bool cdn_dp_check_sink_connection(struct 
cdn_dp_device *dp)
 }
 
 static enum drm_connector_status
-cdn_dp_connector_detect(struct drm_connector *connector, bool force)
+cdn_dp_bridge_detect(struct drm_bridge *bridge)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
enum drm_connector_status status = connector_status_disconnected;
 
mutex_lock(&dp->lock);
@@ -244,41 +244,26 @@ cdn_dp_connector_detect(struct drm_connector *connector, 
bool force)
return status;
 }
 
-static void cdn_dp_connector_destroy(struct drm_connector *connector)
+static const struct drm_edid *
+cdn_dp_connector_edid_read(struct drm_bridge *bridge, struct drm_connector 
*connector)
 {
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
-   .detect = cdn_dp_connector_detect,
-   .destroy = cdn_dp_connector_destroy,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int cdn_dp_connector_get_modes(struct drm_connector *connector)
-{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   int ret = 0;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   const struct drm_edid *drm_edid;
 
mutex_lock(&dp->lock);
-
-   ret = drm_edid_connector_add_modes(connector);
-
+   drm_edid = drm_edid_read_custom(dp->connector,
+   cdn_dp_get_edid_block, dp);
mutex_unlock(&dp->lock);
 
-   return ret;
+   return drm_edid;
 }
 
 static enum drm_mode_status
-cdn_dp_connector_mode_valid(struct drm_connector *connector,
-   const struct drm_display_mode *mode)
+cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
+const struct drm_display_info *display_info,
+const struct drm_display_mode *mode)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   struct drm_display_info *display_info = &dp->connector.display_info;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;
 
@@ -323,11 +308,6 @@ cdn_dp_connector_mode_valid(struct drm_connector 
*connector,
return MODE_OK;
 }
 
-static struct drm_connector_helper_funcs cdn_dp_connector_helper_funcs = {
-   .get_modes = cdn_dp_connector_get_modes,
-   .mode_valid = cdn_dp_connector_mode_valid,
-};
-
 static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
 {
int ret;
@@ -360,7 +340,7 @@ static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
 
 static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
 {
-   const struct drm_display_info *info = &dp->connector.display_info;
+   const struct drm_display_info *info = &dp->connector->display_info;
int ret;
 
if (!cdn_dp_check_sink_connection(dp))
@@ -374,9 +354,9 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device 
*dp)
}
 
drm_edid_free(dp->drm_edid);
-   dp->drm_edid = drm_edid_read_custom(&dp->connector,
+   dp->drm_edid = drm_edid_read_custom(dp->connector,
cdn_dp_get_edid_block, dp);
-   drm_edid_connector_update(&dp->connector, dp->drm_edid);
+   drm_edid_connector_update(dp->connector, dp->drm_edid);
 
dp->sink_has_audio = info->has_audio;
 
@@ -416,11 +396,11 @@ static int cdn_dp_enable_phy(st

Re: [PATCH v3 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-16 Thread Chaoyi Chen

Hi Heiko,

On 2025/5/15 21:00, Heiko Stübner wrote:

Hi,

Am Dienstag, 13. Mai 2025, 03:19:04 Mitteleuropäische Sommerzeit schrieb Chaoyi 
Chen:

From: Chaoyi Chen 
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input of the CDN DP
+properties:
+  endpoint@0:
+description: Connection to the VOPB
+  endpoint@1:
+description: Connection to the VOPL
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output of the CDN DP
+
+required:
+  - port@0
+  - port@1

you're adding the 2nd port (port@1) as output port, which has not been
part of the old binding. I think this warrants an explanation in the
commit message on what it is meant to contain.


This is mainly to keep consistent with the binding style of other 
display interfaces, which all have an Input (port@0) and Output (port@1).


This change has no effect on the driver.  I will explain this in v4.




[PATCH v4 1/2] arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp

2025-05-18 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +-
 1 file changed, 9 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..e340b6df7445 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@fec0 {
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,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+   dp_out: port@1 {
+   reg = <1>;
+   };
};
};

--
2.49.0



[PATCH v4 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-18 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert cdn-dp-rockchip.txt to yaml.

Add port@1 which represents the CDN DP output to keep the same style
as the other display interfaces.

Signed-off-by: Chaoyi Chen 
---

Changes in v4:
- Add commit about port@1 node

Changes in v3:
- Add more description about phy/extcon
- Fix some coding style

Changes in v2:
- Rename binding file name to match compatible
- Add more description about grf/phy/extcon
- Fix coding style

 .../display/rockchip/cdn-dp-rockchip.txt  |  74 
 .../rockchip/rockchip,rk3399-cdn-dp.yaml  | 165 ++
 2 files changed, 165 insertions(+), 74 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
deleted file mode 100644
index 8df7d2e393d6..
--- a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-Rockchip RK3399 specific extensions to the cdn Display Port
-
-
-Required properties:
-- compatible: must be "rockchip,rk3399-cdn-dp"
-
-- reg: physical base address of the controller and length
-
-- clocks: from common clock binding: handle to dp clock.
-
-- clock-names: from common clock binding:
-  Required elements: "core-clk" "pclk" "spdif" "grf"
-
-- resets : a list of phandle + reset specifier pairs
-- reset-names : string of reset names
-   Required elements: "apb", "core", "dptx", "spdif"
-- power-domains : power-domain property defined with a phandle
- to respective power domain.
-- assigned-clocks: main clock, should be <&cru SCLK_DP_CORE>
-- assigned-clock-rates : the DP core clk frequency, shall be: 1
-
-- rockchip,grf: this soc should set GRF regs, so need get grf here.
-
-- ports: contain a port nodes with endpoint definitions as defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-contained 2 endpoints, connecting to the output of vop.
-
-- phys: from general PHY binding: the phandle for the PHY device.
-
-- extcon: extcon specifier for the Power Delivery
-
-- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
-

-
-Example:
-   cdn_dp: dp@fec0 {
-   compatible = "rockchip,rk3399-cdn-dp";
-   reg = <0x0 0xfec0 0x0 0x10>;
-   interrupts = ;
-   clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>,
-<&cru SCLK_SPDIF_REC_DPTX>, <&cru PCLK_VIO_GRF>;
-   clock-names = "core-clk", "pclk", "spdif", "grf";
-   assigned-clocks = <&cru SCLK_DP_CORE>;
-   assigned-clock-rates = <1>;
-   power-domains = <&power RK3399_PD_HDCP>;
-   phys = <&tcphy0_dp>, <&tcphy1_dp>;
-   resets = <&cru SRST_DPTX_SPDIF_REC>;
-   reset-names = "spdif";
-   extcon = <&fusb0>, <&fusb1>;
-   rockchip,grf = <&grf>;
-   #address-cells = <1>;
-   #size-cells = <0>;
-   #sound-dai-cells = <1>;
-
-   ports {
-   #address-cells = <1>;
-   #size-cells = <0>;
-
-   dp_in: port {
-   #address-cells = <1>;
-   #size-cells = <0>;
-   dp_in_vopb: endpoint@0 {
-   reg = <0>;
-   remote-endpoint = <&vopb_out_dp>;
-   };
-
-   dp_in_vopl: endpoint@1 {
-   reg = <1>;
-   remote-endpoint = <&vopl_out_dp>;
-   };
-   };
-   };
-   };
diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
new file mode 100644
index ..7c2225204de2
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml
@@ -0,0 +1,165 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/displa

Re: [PATCH v4 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-19 Thread Chaoyi Chen

Hi Krzysztof,

On 2025/5/19 14:16, Krzysztof Kozlowski wrote:

On 19/05/2025 03:26, Chaoyi Chen wrote:

+maintainers:
+  - Andy Yan 
+  - Heiko Stuebner 
+  - Sandy Huang 
+
+allOf:
+  - $ref: /schemas/sound/dai-common.yaml#
+
+properties:
+  compatible:
+items:
+  - const: rockchip,rk3399-cdn-dp
+
+  reg:
+maxItems: 1
+
+  clocks:
+items:
+  - description: DP core work clock
+  - description: APB clock
+  - description: SPDIF interface clock
+  - description: GRF clock
+
+  clock-names:
+items:
+  - const: core-clk
+  - const: pclk
+  - const: spdif
+  - const: grf
+
+  extcon:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+items:
+  maxItems: 1
+maxItems: 2

Instead of this, list the items. Old binding said only "specifier", so
this is technically a change, which should be explained in commit msg.


Will fix in v5.





+description:
+  List of phandle to the extcon device providing the cable state for the 
DP PHY.
+
+  interrupts:
+maxItems: 1
+
+  phys:
+items:
+  maxItems: 1
+maxItems: 2
+description: |
+  List of phandle to the PHY device for DP output.
+  RK3399 have two DP-TPYEC PHY, specifying one PHY which want to use,
+  or specify two PHYs here to let the driver determine which PHY to use.


You do not allow one phy, so your description is not accurate. OTOH,
original binding did not allow two phandles, so that's another change in
the binding. You need to document all changes done to the binding in the
commit msg.


Oh, the original binding example use two phandles. I think only one PHY 
can also pass the dtb check here, or maybe I'm missing something else?






+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input of the CDN DP
+properties:
+  endpoint@0:
+description: Connection to the VOPB
+  endpoint@1:
+description: Connection to the VOPL
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output of the CDN DP
+
+required:
+  - port@0
+  - port@1
+
+  power-domains:
+maxItems: 1
+
+  resets:
+maxItems: 4
+
+  reset-names:
+items:
+  - const: spdif
+  - const: dptx
+  - const: apb
+  - const: core
+
+  rockchip,grf:
+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  Phandle to GRF register to control HPD.
+
+  "#sound-dai-cells":
+const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - phys
+  - ports
+  - resets
+  - reset-names
+  - rockchip,grf


sound-dai-cells was a required property.


Okay, will add in v5.



Re: [PATCH v4 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-19 Thread Chaoyi Chen

Hi Krzysztof,

On 2025/5/19 16:23, Krzysztof Kozlowski wrote:

On Mon, May 19, 2025 at 02:56:03PM GMT, Chaoyi Chen wrote:

Hi Krzysztof,

On 2025/5/19 14:16, Krzysztof Kozlowski wrote:

On 19/05/2025 03:26, Chaoyi Chen wrote:

+maintainers:
+  - Andy Yan 
+  - Heiko Stuebner 
+  - Sandy Huang 
+
+allOf:
+  - $ref: /schemas/sound/dai-common.yaml#
+
+properties:
+  compatible:
+items:
+  - const: rockchip,rk3399-cdn-dp
+
+  reg:
+maxItems: 1
+
+  clocks:
+items:
+  - description: DP core work clock
+  - description: APB clock
+  - description: SPDIF interface clock
+  - description: GRF clock
+
+  clock-names:
+items:
+  - const: core-clk
+  - const: pclk
+  - const: spdif
+  - const: grf
+
+  extcon:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+items:
+  maxItems: 1
+maxItems: 2

Instead of this, list the items. Old binding said only "specifier", so
this is technically a change, which should be explained in commit msg.

Will fix in v5.



+description:
+  List of phandle to the extcon device providing the cable state for the 
DP PHY.
+
+  interrupts:
+maxItems: 1
+
+  phys:
+items:
+  maxItems: 1
+maxItems: 2
+description: |
+  List of phandle to the PHY device for DP output.
+  RK3399 have two DP-TPYEC PHY, specifying one PHY which want to use,
+  or specify two PHYs here to let the driver determine which PHY to use.

You do not allow one phy, so your description is not accurate. OTOH,
original binding did not allow two phandles, so that's another change in
the binding. You need to document all changes done to the binding in the
commit msg.

Oh, the original binding example use two phandles. I think only one PHY can

Example is not the binding, just an example.


also pass the dtb check here, or maybe I'm missing something else?

You think or you tested it? What is the minItems value? 2, so even if
this works it's rather a bug in dtschema.


Yes I tested it. Both of "phys = <&tcphy0_dp>", "phys = <&tcphy0_dp>, 
<&tcphy1_dp>" pass the dtb check.





Also, inner maxItems:1 is not really correct. Why can't this work with
different phy providers?


I'll see what other bindings do. Thanks for the clarification!



[PATCH v5 1/2] arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp

2025-05-19 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +-
 1 file changed, 9 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..e340b6df7445 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@fec0 {
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,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+   dp_out: port@1 {
+   reg = <1>;
+   };
};
};

--
2.49.0



[PATCH v5 0/2] Convert Rockchip CDN DP binding to yaml

2025-05-19 Thread Chaoyi Chen
From: Chaoyi Chen 

This series convert cdn-dp-rockchip.txt to yaml.

PATCH 1 try to improve coding style on the existing rk3399 cdn-dp
node.
PATCH 2 try to convert cdn-dp-rockchip.txt to yaml. It changed the
constraints for the phys and extcon properties.

Both of them add new port@1 node that represents the CDN DP output to
keep the same style as the other display interfaces.

Changes in v5:
- Link to V4: https://lore.kernel.org/all/20250519012632.94-1-ker...@airkyi.com/
- Fix constraints on extcon and phys
- Add commit about changes to extcon and phys
- Add "#sound-dai-cells" to required properties

Changes in v4:
- Link to V3: 
https://lore.kernel.org/all/20250513011904.102-1-ker...@airkyi.com/
- Add commit about port@1 node

Changes in v3:
- Link to V2: 
https://lore.kernel.org/all/20250509070247.868-1-ker...@airkyi.com/
- Add more description about phy/extcon
- Fix some coding style

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250508064304.670-1-ker...@airkyi.com/
- Rename binding file name to match compatible
- Add more description about grf/phy/extcon
- Fix coding style

Chaoyi Chen (2):
  arm64: dts: rockchip: Improve coding style for rk3399 cdn_dp
  dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

 .../display/rockchip/cdn-dp-rockchip.txt  |  74 
 .../rockchip/rockchip,rk3399-cdn-dp.yaml  | 168 ++
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 3 files changed, 177 insertions(+), 75 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml

--
2.49.0




[PATCH v5 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml

2025-05-19 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert cdn-dp-rockchip.txt to yaml.

Add new "port@1" property which represents the CDN DP output to keep
the same style as the other display interfaces.

This patch also changes the constraints for "phys" and "extcon". For
the original binding, only one phy and the corresponding extcon can
be specified. In the new binding, one or two phys can be specified.
Since the RK3399 has two DP-USB PHYs, specifying one allows output
via the corresponding PHY, while specifying two lets the driver
choose one PHY for output. This rule also applies to extcon, which
provides the cable state for the corresponding PHY.

Signed-off-by: Chaoyi Chen 
---

Changes in v5:
- Fix constraints on extcon and phys
- Add commit about changes to extcon and phys
- Add "#sound-dai-cells" to required properties

Changes in v4:
- Add commit about port@1 node

Changes in v3:
- Add more description about phy/extcon
- Fix some coding style

Changes in v2:
- Rename binding file name to match compatible
- Add more description about grf/phy/extcon
- Fix coding style

 .../display/rockchip/cdn-dp-rockchip.txt  |  74 
 .../rockchip/rockchip,rk3399-cdn-dp.yaml  | 168 ++
 2 files changed, 168 insertions(+), 74 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip,rk3399-cdn-dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
deleted file mode 100644
index 8df7d2e393d6..
--- a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-Rockchip RK3399 specific extensions to the cdn Display Port
-
-
-Required properties:
-- compatible: must be "rockchip,rk3399-cdn-dp"
-
-- reg: physical base address of the controller and length
-
-- clocks: from common clock binding: handle to dp clock.
-
-- clock-names: from common clock binding:
-  Required elements: "core-clk" "pclk" "spdif" "grf"
-
-- resets : a list of phandle + reset specifier pairs
-- reset-names : string of reset names
-   Required elements: "apb", "core", "dptx", "spdif"
-- power-domains : power-domain property defined with a phandle
- to respective power domain.
-- assigned-clocks: main clock, should be <&cru SCLK_DP_CORE>
-- assigned-clock-rates : the DP core clk frequency, shall be: 1
-
-- rockchip,grf: this soc should set GRF regs, so need get grf here.
-
-- ports: contain a port nodes with endpoint definitions as defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-contained 2 endpoints, connecting to the output of vop.
-
-- phys: from general PHY binding: the phandle for the PHY device.
-
-- extcon: extcon specifier for the Power Delivery
-
-- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
-

-
-Example:
-   cdn_dp: dp@fec0 {
-   compatible = "rockchip,rk3399-cdn-dp";
-   reg = <0x0 0xfec0 0x0 0x10>;
-   interrupts = ;
-   clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>,
-<&cru SCLK_SPDIF_REC_DPTX>, <&cru PCLK_VIO_GRF>;
-   clock-names = "core-clk", "pclk", "spdif", "grf";
-   assigned-clocks = <&cru SCLK_DP_CORE>;
-   assigned-clock-rates = <1>;
-   power-domains = <&power RK3399_PD_HDCP>;
-   phys = <&tcphy0_dp>, <&tcphy1_dp>;
-   resets = <&cru SRST_DPTX_SPDIF_REC>;
-   reset-names = "spdif";
-   extcon = <&fusb0>, <&fusb1>;
-   rockchip,grf = <&grf>;
-   #address-cells = <1>;
-   #size-cells = <0>;
-   #sound-dai-cells = <1>;
-
-   ports {
-   #address-cells = <1>;
-   #size-cells = <0>;
-
-   dp_in: port {
-   #address-cells = <1>;
-   #size-cells = <0>;
-   dp_in_vopb: endpoint@0 {
-   reg = <0>;
-   remote-endpoint = <&vopb_out_dp>;
-   };
-
-   dp_in_vopl: endpoint@1 {
-

[PATCH] drm/bridge-connector: Fix bridge in drm_connector_hdmi_audio_init()

2025-05-26 Thread Chaoyi Chen
From: Chaoyi Chen 

The bridge used in drm_connector_hdmi_audio_init() does not correctly
point to the required audio bridge, which lead to incorrect audio
configuration input.

Fixes: 231adeda9f67 ("drm/bridge-connector: hook DisplayPort audio support")
Signed-off-by: Chaoyi Chen 
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c 
b/drivers/gpu/drm/display/drm_bridge_connector.c
index 7d2e499ea5de..262e93e07a28 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -708,11 +708,14 @@ struct drm_connector *drm_bridge_connector_init(struct 
drm_device *drm,
if (bridge_connector->bridge_hdmi_audio ||
bridge_connector->bridge_dp_audio) {
struct device *dev;
+   struct drm_bridge *bridge;
 
if (bridge_connector->bridge_hdmi_audio)
-   dev = 
bridge_connector->bridge_hdmi_audio->hdmi_audio_dev;
+   bridge = bridge_connector->bridge_hdmi_audio;
else
-   dev = bridge_connector->bridge_dp_audio->hdmi_audio_dev;
+   bridge = bridge_connector->bridge_dp_audio;
+
+   dev = bridge->hdmi_audio_dev;
 
ret = drm_connector_hdmi_audio_init(connector, dev,

&drm_bridge_connector_hdmi_audio_funcs,
-- 
2.49.0



[PATCH] drm/rockchip: lvds: Convert to drm bridge

2025-05-25 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.

Signed-off-by: Chaoyi Chen 
---
 drivers/gpu/drm/rockchip/rockchip_lvds.c | 68 ++--
 1 file changed, 29 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c 
b/drivers/gpu/drm/rockchip/rockchip_lvds.c
index a673779de3d2..2411260db51d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -56,14 +56,13 @@ struct rockchip_lvds {
struct drm_device *drm_dev;
struct drm_panel *panel;
struct drm_bridge *bridge;
-   struct drm_connector connector;
struct rockchip_encoder encoder;
struct dev_pin_info *pins;
 };
 
-static inline struct rockchip_lvds *connector_to_lvds(struct drm_connector 
*connector)
+static inline struct rockchip_lvds *brige_to_lvds(struct drm_bridge *bridge)
 {
-   return container_of(connector, struct rockchip_lvds, connector);
+   return (struct rockchip_lvds *)bridge->driver_private;
 }
 
 static inline struct rockchip_lvds *encoder_to_lvds(struct drm_encoder 
*encoder)
@@ -106,25 +105,21 @@ static inline int rockchip_lvds_name_to_output(const char 
*s)
return -EINVAL;
 }
 
-static const struct drm_connector_funcs rockchip_lvds_connector_funcs = {
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .destroy = drm_connector_cleanup,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int rockchip_lvds_connector_get_modes(struct drm_connector *connector)
+static int
+rockchip_lvds_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector 
*connector)
 {
-   struct rockchip_lvds *lvds = connector_to_lvds(connector);
+   struct rockchip_lvds *lvds = brige_to_lvds(bridge);
struct drm_panel *panel = lvds->panel;
 
return drm_panel_get_modes(panel, connector);
 }
 
 static const
-struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = {
-   .get_modes = rockchip_lvds_connector_get_modes,
+struct drm_bridge_funcs rockchip_lvds_bridge_funcs = {
+   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+   .atomic_reset = drm_atomic_helper_bridge_reset,
+   .get_modes = rockchip_lvds_bridge_get_modes,
 };
 
 static int
@@ -606,26 +601,23 @@ static int rockchip_lvds_bind(struct device *dev, struct 
device *master,
}
 
drm_encoder_helper_add(encoder, lvds->soc_data->helper_funcs);
-   connector = &lvds->connector;
 
if (lvds->panel) {
-   connector->dpms = DRM_MODE_DPMS_OFF;
-   ret = drm_connector_init(drm_dev, connector,
-&rockchip_lvds_connector_funcs,
-DRM_MODE_CONNECTOR_LVDS);
-   if (ret < 0) {
-   drm_err(drm_dev,
-   "failed to initialize connector: %d\n", ret);
+   lvds->bridge = drm_panel_bridge_add_typed(lvds->panel, 
DRM_MODE_CONNECTOR_LVDS);
+   if (IS_ERR(lvds->bridge)) {
+   ret = PTR_ERR(lvds->bridge);
goto err_free_encoder;
}
+   }
 
-   drm_connector_helper_add(connector,
-&rockchip_lvds_connector_helper_funcs);
-   } else {
-   ret = drm_bridge_attach(encoder, lvds->bridge, NULL,
-   DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+   if (lvds->bridge) {
+   lvds->bridge->driver_private = lvds;
+   lvds->bridge->ops = DRM_BRIDGE_OP_MODES;
+   lvds->bridge->funcs = &rockchip_lvds_bridge_funcs;
+
+   ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret)
-   goto err_free_encoder;
+   goto err_free_bridge;
 
connector = drm_bridge_connector_init(lvds->drm_dev, encoder);
if (IS_ERR(connector)) {
@@ -633,14 +625,14 @@ static int rockchip_lvds_bind(struct device *dev, struct 
device *master,
"failed to initialize bridge connector: %pe\n",
connector);
ret = PTR_ERR(connector);
-   goto err_free_encoder;
+   goto err_free_bridge;
}
-   }
 
-   ret = drm_connector_attach_encoder(connector, encoder);
-   if (ret < 0) {
-   drm_err(drm_

Re: [PATCH v2] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-25 Thread Chaoyi Chen

Hi Dmitry,

On 2025/5/24 6:17, Dmitry Baryshkov wrote:

On Fri, May 23, 2025 at 09:13:10AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.

Considering that some code depend on the connector, the following
changes have been made:
- Do not get edid in cdn_dp_get_sink_capability() when connector is
not present.
- Update bpc info in cdn_dp_bridge_atomic_enable() instead of
cdn_dp_encoder_mode_set(). Actually, the bpc data will be used in
cdn_dp_bridge_atomic_enable().

This patch also convert to use devm_drm_bridge_alloc() API.

Tested with RK3399 EVB IND board.

Signed-off-by: Chaoyi Chen 
---

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250507035148.415-1-ker...@airkyi.com/
- Use drm_atomic_get_new_connector_for_encoder() to get connector
- Convert to use devm_drm_bridge_alloc() API
- Fix typo: cdn_dp_connector_edid_read -> cdn_dp_bridge_edid_read

  drivers/gpu/drm/rockchip/cdn-dp-core.c | 204 +
  drivers/gpu/drm/rockchip/cdn-dp-core.h |   5 +-
  2 files changed, 112 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 292c31de18f1..848f47d4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -25,9 +25,9 @@
  #include "cdn-dp-core.h"
  #include "cdn-dp-reg.h"
  
-static inline struct cdn_dp_device *connector_to_dp(struct drm_connector *connector)

+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
  {
-   return container_of(connector, struct cdn_dp_device, connector);
+   return container_of(bridge, struct cdn_dp_device, bridge);
  }
  
  static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)

@@ -231,9 +231,9 @@ static bool cdn_dp_check_sink_connection(struct 
cdn_dp_device *dp)
  }
  
  static enum drm_connector_status

-cdn_dp_connector_detect(struct drm_connector *connector, bool force)
+cdn_dp_bridge_detect(struct drm_bridge *bridge)
  {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
enum drm_connector_status status = connector_status_disconnected;
  
  	mutex_lock(&dp->lock);

@@ -244,41 +244,25 @@ cdn_dp_connector_detect(struct drm_connector *connector, 
bool force)
return status;
  }
  
-static void cdn_dp_connector_destroy(struct drm_connector *connector)

+static const struct drm_edid *
+cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector 
*connector)
  {
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
-   .detect = cdn_dp_connector_detect,
-   .destroy = cdn_dp_connector_destroy,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int cdn_dp_connector_get_modes(struct drm_connector *connector)
-{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   int ret = 0;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   const struct drm_edid *drm_edid;
  
  	mutex_lock(&dp->lock);

-
-   ret = drm_edid_connector_add_modes(connector);
-
+   drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
mutex_unlock(&dp->lock);

I know that the lock has been here. What does it protect here?


The cdn worker may read the edid at the same time.




  
-	return ret;

+   return drm_edid;
  }
  
  static enum drm_mode_status

-cdn_dp_connector_mode_valid(struct drm_connector *connector,
-   const struct drm_display_mode *mode)
+cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
+const struct drm_display_info *display_info,
+const struct drm_display_mode *mode)
  {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   struct drm_display_info *display_info = &dp->connector.display_info;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;
  
@@ -323,11 +307,6 @@ cdn_dp_connector_mode_valid(struct drm_connector *connector,

return MODE_OK;
  }
  
-static struct drm_connector_helper_funcs cdn_dp_connector_helper_funcs = {

-   .get_modes = cdn_dp_connector_get_modes,
-   .mode_valid = cdn_dp_connector_mode_valid,
-};
-
  static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
  {
int ret;
@@ -360,7 +339,8 @@ static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
  
  static int 

[PATCH v3] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-27 Thread Chaoyi Chen
From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.
Considering that some code depend on the connector, the following
changes have been made:
- Only process edid in &drm_bridge_funcs.edid_read(), so no need to
store additional edid info.
- Now cdn_dp_get_sink_capability() only focused on reading DPCD_REV.
- Update bpc info in cdn_dp_bridge_atomic_enable() instead of
cdn_dp_encoder_mode_set(). Actually, the bpc data will be used in
cdn_dp_bridge_atomic_enable().
- Switch to use DRM_BRIDGE_OP_DP_AUDIO helpers.

This patch also convert to use devm_drm_bridge_alloc() API.

Tested with RK3399 EVB IND board.

Signed-off-by: Chaoyi Chen 
---

Changes in v3:
- Link to V2: 
https://lore.kernel.org/all/20250523011310.120-1-ker...@airkyi.com/
- Switch to use DRM_BRIDGE_OP_DP_AUDIO helpers
- Remove the dependency for connector
- Remove the extra stored edid
- Code cleanup

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250507035148.415-1-ker...@airkyi.com/
- Use drm_atomic_get_new_connector_for_encoder() to get connector
- Convert to use devm_drm_bridge_alloc() API
- Fix typo: cdn_dp_connector_edid_read -> cdn_dp_bridge_edid_read

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 279 ++---
 drivers/gpu/drm/rockchip/cdn-dp-core.h |   9 +-
 2 files changed, 110 insertions(+), 178 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 292c31de18f1..5e116d3e516b 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -16,6 +16,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,9 +26,9 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *connector_to_dp(struct drm_connector 
*connector)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-   return container_of(connector, struct cdn_dp_device, connector);
+   return container_of(bridge, struct cdn_dp_device, bridge);
 }
 
 static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
@@ -231,9 +232,9 @@ static bool cdn_dp_check_sink_connection(struct 
cdn_dp_device *dp)
 }
 
 static enum drm_connector_status
-cdn_dp_connector_detect(struct drm_connector *connector, bool force)
+cdn_dp_bridge_detect(struct drm_bridge *bridge)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
enum drm_connector_status status = connector_status_disconnected;
 
mutex_lock(&dp->lock);
@@ -244,41 +245,25 @@ cdn_dp_connector_detect(struct drm_connector *connector, 
bool force)
return status;
 }
 
-static void cdn_dp_connector_destroy(struct drm_connector *connector)
+static const struct drm_edid *
+cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector 
*connector)
 {
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
-   .detect = cdn_dp_connector_detect,
-   .destroy = cdn_dp_connector_destroy,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int cdn_dp_connector_get_modes(struct drm_connector *connector)
-{
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   int ret = 0;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   const struct drm_edid *drm_edid;
 
mutex_lock(&dp->lock);
-
-   ret = drm_edid_connector_add_modes(connector);
-
+   drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
mutex_unlock(&dp->lock);
 
-   return ret;
+   return drm_edid;
 }
 
 static enum drm_mode_status
-cdn_dp_connector_mode_valid(struct drm_connector *connector,
-   const struct drm_display_mode *mode)
+cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
+const struct drm_display_info *display_info,
+const struct drm_display_mode *mode)
 {
-   struct cdn_dp_device *dp = connector_to_dp(connector);
-   struct drm_display_info *display_info = &dp->connector.display_info;
+   struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;
 
@@ -323,11 +308,6 @@ cdn_dp_connector_mode_valid(struct drm_connector 
*connector,
return MODE_OK;
 }
 
-static struct drm_connector_helper_funcs cdn_dp_connector_helper_funcs = {
-   .get_modes = cdn_dp_connector_get_modes,
-   .mode_valid = cdn_dp_connector_mode_valid,
-};

Re: [PATCH v3] drm/rockchip: cdn-dp: Convert to drm bridge

2025-05-27 Thread Chaoyi Chen

Hi Dmitry,

On 2025/5/28 4:25, Dmitry Baryshkov wrote:

On Tue, May 27, 2025 at 04:14:47PM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.
Considering that some code depend on the connector, the following
changes have been made:
- Only process edid in &drm_bridge_funcs.edid_read(), so no need to
store additional edid info.
- Now cdn_dp_get_sink_capability() only focused on reading DPCD_REV.
- Update bpc info in cdn_dp_bridge_atomic_enable() instead of
cdn_dp_encoder_mode_set(). Actually, the bpc data will be used in
cdn_dp_bridge_atomic_enable().
- Switch to use DRM_BRIDGE_OP_DP_AUDIO helpers.

This patch also convert to use devm_drm_bridge_alloc() API.

Tested with RK3399 EVB IND board.

Signed-off-by: Chaoyi Chen 
---

Changes in v3:
- Link to V2: 
https://lore.kernel.org/all/20250523011310.120-1-ker...@airkyi.com/
- Switch to use DRM_BRIDGE_OP_DP_AUDIO helpers
- Remove the dependency for connector
- Remove the extra stored edid
- Code cleanup

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250507035148.415-1-ker...@airkyi.com/
- Use drm_atomic_get_new_connector_for_encoder() to get connector
- Convert to use devm_drm_bridge_alloc() API
- Fix typo: cdn_dp_connector_edid_read -> cdn_dp_bridge_edid_read

  drivers/gpu/drm/rockchip/cdn-dp-core.c | 279 ++---
  drivers/gpu/drm/rockchip/cdn-dp-core.h |   9 +-
  2 files changed, 110 insertions(+), 178 deletions(-)




@@ -595,16 +546,41 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
*dp)
  static void cdn_dp_audio_handle_plugged_change(struct cdn_dp_device *dp,
   bool plugged)
  {
-   if (dp->codec_dev)
-   dp->plugged_cb(dp->codec_dev, plugged);
+   if (dp->sink_has_audio)
+   drm_connector_hdmi_audio_plugged_notify(dp->connector, plugged);

I'd say, notify always and let userspace figure it out via the ELD. Then
you shouldn't need sink_has_audio. This would match the behaviour of
HDMI drivers.


Oh, I find that there are similar usages in qcom msm driver. Is there 
any more progress?






  }
  

[...]


@@ -705,8 +681,6 @@ static int cdn_dp_encoder_atomic_check(struct drm_encoder 
*encoder,
  
  static const struct drm_encoder_helper_funcs cdn_dp_encoder_helper_funcs = {

.mode_set = cdn_dp_encoder_mode_set,
-   .enable = cdn_dp_encoder_enable,
-   .disable = cdn_dp_encoder_disable,
.atomic_check = cdn_dp_encoder_atomic_check,

Nit: for the future cleanup, it should probably be possible to get rid
of these encoder ops too by moving them to the bridge ops.


Interesting, have these patches been submitted upstream yet?





  };
  

[...]


@@ -1006,7 +947,8 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
  
  out:

mutex_unlock(&dp->lock);
-   drm_connector_helper_hpd_irq_event(&dp->connector);
+   if (dp->connector)
+   drm_connector_helper_hpd_irq_event(dp->connector);

drm_bridge_hpd_notify(). I think then you don't need dp->connector.


That make sense! Will fix in v4.





  }
  
  static int cdn_dp_pd_event(struct notifier_block *nb,

@@ -1062,26 +1004,35 @@ static int cdn_dp_bind(struct device *dev, struct 
device *master, void *data)
  
  	drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
  
-	connector = &dp->connector;

-   connector->polled = DRM_CONNECTOR_POLL_HPD;
-   connector->dpms = DRM_MODE_DPMS_OFF;
-
-   ret = drm_connector_init(drm_dev, connector,
-&cdn_dp_atomic_connector_funcs,
-DRM_MODE_CONNECTOR_DisplayPort);
-   if (ret) {
-   DRM_ERROR("failed to initialize connector with drm\n");
-   goto err_free_encoder;
-   }
+   dp->bridge.ops =
+   DRM_BRIDGE_OP_DETECT |
+   DRM_BRIDGE_OP_EDID |
+   DRM_BRIDGE_OP_HPD |
+   DRM_BRIDGE_OP_DP_AUDIO;
+   dp->bridge.of_node = dp->dev->of_node;
+   dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
+   dp->bridge.hdmi_audio_dev = dp->dev;
+   dp->bridge.hdmi_audio_max_i2s_playback_channels = 8;
+   dp->bridge.hdmi_audio_spdif_playback = 1;
+   dp->bridge.hdmi_audio_dai_port = -1;
+
+   ret = devm_drm_bridge_add(dev, &dp->bridge);
+   if (ret)
+   return ret;
  
-	drm_connector_helper_add(connector, &cdn_dp_connector_helper_funcs);

+   ret = drm_bridge_attach(encoder, &dp->bridge, NULL, 
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+   if (ret)
+   return ret;
  
-	ret = drm_connector_attach_encoder(connector, encoder);

-   if (ret) {
-   DRM_ERROR("failed to attach connector and enc

[PATCH v4 7/7] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

2025-09-21 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

(no changes since v4)

Changes in v3:
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.

 .../boot/dts/rockchip/rk3399-evb-ind.dts  | 146 ++
 1 file changed, 146 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..a6bd2973 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 
 #include "rk3399.dtsi"
 
 / {
@@ -19,6 +20,21 @@ chosen {
stdout-path = "serial2:150n8";
};
 
+   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,71 @@ 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 = ;
+   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 = <100>;
+   sink-pdos =
+   ;
+   source-pdos =
+   ;
+
+   altmodes {
+   displayport {
+   svid = /bits/ 16 <0xff01>;
+   vdo = <0x1c46>;
+   };
+   };
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   usbc_hs: endpoint {
+   remote-endpoint = 
<&u2phy0_typec_hs>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   usbc_ss: endpoint {
+   remote-endpoint = 
<&tcphy0_typec_ss>;
+   };
+   };
+
+   port@2 {
+   reg = <2>;
+
+   usbc_dp: endpoint {
+   remote-endpoint = 
<&tcphy0_typec_dp>;
+   };
+   };
+   };
+   };
+   };
+};
+
 &i2s2 {
status = "okay";
 };
@@ -354,6 +446,16 @@ &io_domains {
 };
 
 &pinctrl {
+   usb-typec {
+   usbc0_int: usbc0-

[PATCH v4 5/7] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection

2025-09-21 Thread Chaoyi Chen
From: Chaoyi Chen 

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. If both ports
are plugged into DP, DP will select the first port for output.

This patch adds support for multiple bridges, enabling users to flexibly
select the output port. For each PHY port, a separate encoder and bridge
are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the PHY, USB connector, and DP controller.
And cdn_dp_parse_hpd_bridge_dt() will parses it and determines
whether to register one or two bridges.

Since there is only one DP controller, only one of the PHY ports can
output at a time. The key is how to switch between different PHYs,
which is handled by cdn_dp_switch_port() and cdn_dp_enable().

There are two cases:

1. Neither bridge is enabled. In this case, both bridges can
independently read the EDID, and the PHY port may switch before
reading the EDID.

2. One bridge is already enabled. In this case, other bridges are not
allowed to read the EDID.

Since the scenario of two ports plug in at the same time is rare,
I don't have a board which support two TypeC connector to test this.
Therefore, I tested forced switching on a single PHY port, as well as
output using a fake PHY port alongside a real PHY port.

Signed-off-by: Chaoyi Chen 
---
 drivers/gpu/drm/rockchip/Kconfig   |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 398 +
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  23 +-
 3 files changed, 366 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index faf50d872be3..3a6266279323 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -55,6 +55,7 @@ config ROCKCHIP_CDN_DP
select DRM_DISPLAY_HELPER
select DRM_BRIDGE_CONNECTOR
select DRM_DISPLAY_DP_HELPER
+   select DRM_AUX_HPD_BRIDGE
help
  This selects support for Rockchip SoC specific extensions
  for the cdn DP driver. If you want to enable Dp on
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 1e27301584a4..784f5656fcc4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -27,16 +27,17 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port 
*prev_port,
+ struct cdn_dp_port *port);
+
+static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge 
*bridge)
 {
-   return container_of(bridge, struct cdn_dp_device, bridge);
+   return container_of(bridge, struct cdn_dp_bridge, bridge);
 }
 
-static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-   struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
-
-   return container_of(rkencoder, struct cdn_dp_device, encoder);
+   return bridge_to_dp_bridge(bridge)->parent;
 }
 
 #define GRF_SOC_CON9   0x6224
@@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device 
*dp, u8 *sink_count)
 static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
 {
struct cdn_dp_port *port;
-   int i, lanes;
+   int i, lanes[MAX_PHY];
 
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
-   lanes = cdn_dp_get_port_lanes(port);
-   if (lanes)
+   lanes[i] = cdn_dp_get_port_lanes(port);
+   if (!dp->hpd_bridge_valid)
return port;
}
+
+   if (dp->hpd_bridge_valid) {
+   /* If more than one port is available, pick the last active 
port */
+   if (dp->active_port > 0 && lanes[dp->active_port])
+   return dp->port[dp->active_port];
+
+   /* If the last active port is not available, pick an available 
port in order */
+   for (i = 0; i < dp->bridge_count; i++) {
+   if (lanes[i])
+   return dp->port[i];
+   }
+   }
+
return NULL;
 }
 
@@ -239,10 +253,11 @@ static enum drm_connector_status
 cdn_dp_bridge_detect(struct drm_bridge *bridge, struct drm_connector 
*connector)
 {
struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
enum drm_connector_status status = connector_status_disconnected;
 
mutex_lock(&dp->lock);
-   if (dp->connected)
+   if (dp_bridge->connected && dp

[PATCH v4 1/7] usb: typec: Add default HPD device when register DisplayPort altmode

2025-09-21 Thread Chaoyi Chen
From: Chaoyi Chen 

Add default DRM AUX HPD bridge device when register DisplayPort
altmode. That makes it redundant for each Type-C driver to implement
a similar registration process in embedded scenarios.

Signed-off-by: Chaoyi Chen 
---
 drivers/usb/typec/altmodes/displayport.c | 27 
 drivers/usb/typec/altmodes/displayport.h |  2 ++
 drivers/usb/typec/class.c|  8 +++
 include/linux/usb/typec_altmode.h|  2 ++
 4 files changed, 39 insertions(+)

diff --git a/drivers/usb/typec/altmodes/displayport.c 
b/drivers/usb/typec/altmodes/displayport.c
index 1dcb77faf85d..e026dc6e5430 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "displayport.h"
 
@@ -182,6 +183,10 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
dp->pending_irq_hpd = true;
}
} else {
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ hpd ? 
connector_status_connected :
+   
connector_status_disconnected);
drm_connector_oob_hotplug_event(dp->connector_fwnode,
hpd ? 
connector_status_connected :
  
connector_status_disconnected);
@@ -206,6 +211,9 @@ static int dp_altmode_configured(struct dp_altmode *dp)
 * configuration is complete to signal HPD.
 */
if (dp->pending_hpd) {
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ connector_status_connected);
drm_connector_oob_hotplug_event(dp->connector_fwnode,
connector_status_connected);
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
@@ -391,6 +399,9 @@ static int dp_altmode_vdm(struct typec_altmode *alt,
dp->data.status = 0;
dp->data.conf = 0;
if (dp->hpd) {
+   if (dp->port->hpd_dev)
+   
drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ 
connector_status_disconnected);

drm_connector_oob_hotplug_event(dp->connector_fwnode,

connector_status_disconnected);
dp->hpd = false;
@@ -751,6 +762,18 @@ static const struct attribute_group *displayport_groups[] 
= {
NULL,
 };
 
+void dp_altmode_hpd_device_register(struct typec_altmode *alt)
+{
+   if (alt->svid != USB_TYPEC_DP_SID)
+   return;
+
+   alt->hpd_dev = drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+ 
dev_of_node(alt->dev.parent->parent));
+   if (IS_ERR(alt->hpd_dev))
+   alt->hpd_dev = NULL;
+}
+EXPORT_SYMBOL_GPL(dp_altmode_hpd_device_register);
+
 int dp_altmode_probe(struct typec_altmode *alt)
 {
const struct typec_altmode *port = typec_altmode_get_partner(alt);
@@ -812,6 +835,10 @@ void dp_altmode_remove(struct typec_altmode *alt)
cancel_work_sync(&dp->work);
typec_altmode_put_plug(dp->plug_prime);
 
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ connector_status_disconnected);
+
if (dp->connector_fwnode) {
drm_connector_oob_hotplug_event(dp->connector_fwnode,
connector_status_disconnected);
diff --git a/drivers/usb/typec/altmodes/displayport.h 
b/drivers/usb/typec/altmodes/displayport.h
index e120364da9fd..9f3483ec10fb 100644
--- a/drivers/usb/typec/altmodes/displayport.h
+++ b/drivers/usb/typec/altmodes/displayport.h
@@ -2,7 +2,9 @@
 #if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE)
 int dp_altmode_probe(struct typec_altmode *alt);
 void dp_altmode_remove(struct typec_altmode *alt);
+void dp_altmode_hpd_device_register(struct typec_altmode *alt);
 #else
 int dp_altmode_probe(struct typec_altmode *alt) { return -ENOTSUPP; }
 void dp_altmode_remove(struct typec_altmode *alt) { }
+void dp_altmode_hpd_device_register(struct typec_altmode *alt) { }
 #endif /* CONFIG_TYPEC_DP_ALTMODE */
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 67a533e35150..95732b6d9a95 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -15,6 +15,7

[PATCH v4 4/7] drm/rockchip: cdn-dp: Support handle lane info without extcon

2025-09-21 Thread Chaoyi Chen
From: Chaoyi Chen 

This patch add support for get PHY lane info without help of extcon.

There is no extcon needed if the Type-C controller is present. In this
case, 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 
---

Changes in v4:
- Remove cdn_dp_hpd_notify().

(no changes since v3)

Changes in v2:
- Ignore duplicate HPD events.

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b7e3f5dcf8d5..1e27301584a4 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);
@@ -1028,6 +1034,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 +1129,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



[PATCH v4 2/7] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch

2025-09-21 Thread Chaoyi Chen
From: Chaoyi Chen 

The RK3399 SoC integrates two USB/DP combo PHYs, each of which
supports software-configurable pin mapping and DisplayPort lane
assignment. These capabilities enable the PHY itself to handle both
mode switching and orientation switching, based on the Type-C plug
orientation and USB PD negotiation results.

While an external Type-C controller is still required to detect cable
attachment and report USB PD events, the actual mode and orientation
switching is performed internally by the PHY through software
configuration. This allows the PHY to act as a Type-C multiplexer for
both data role and DP altmode configuration.

To reflect this hardware design, this patch introduces a new
"mode-switch" property for the dp-port node in the device tree bindings.
This property indicates that the connected PHY is capable of handling
Type-C mode switching itself.

Signed-off-by: Chaoyi Chen 

Acked-by: Krzysztof Kozlowski 
---

Changes in v4:
- Remove "|" in description.

Changes in v3:
- Add more descriptions to clarify the role of the PHY in switching.

Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.

 .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++
 1 file changed, 6 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..83ebcde096ea 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,12 @@ properties:
   '#phy-cells':
 const: 0
 
+  mode-switch:
+description:
+  Indicates the PHY can handle altmode switching. In this case,
+  requires an external USB Type-C controller to report USB PD message.
+type: boolean
+
   port:
 $ref: /schemas/graph.yaml#/properties/port
 description: Connection to USB Type-C connector
-- 
2.49.0



[PATCH v4 6/7] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP

2025-09-21 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

Changes in v4:
- Remove unnecessary #address/#size-cells

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
index 4dcceb9136b7..93b42820998f 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@fec0 {
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,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+   dp_out: port@1 {
+   reg = <1>;
+   };
};
};
 
-- 
2.49.0



[PATCH v4 0/7] Add Type-C DP support for RK3399 EVB IND board

2025-09-21 Thread Chaoyi Chen
From: Chaoyi Chen 

This series focuses on adding Type-C DP support for USBDP PHY and DP
driver. The USBDP PHY and DP will perceive the changes in cable status
based on the USB PD and Type-C state machines provided by TCPM. Before
this, the USBDP PHY and DP controller of RK3399 sensed cable state
changes through extcon, and devices such as the RK3399 Gru-Chromebook
rely on them. This series should not break them.


1. DisplayPort HPD status notify

Before v4, I implemented a variety of DP HPD status notify. However,
they all had various problems and it was difficult to become a common
solution.

Under Dmitry's guidance, I try to add default DRM AUX HPD device when
register DisplayPort altmode in patch 1. That makes it redundant for
each Type-C chip driver to implement a similar registration process
in embedded scenarios.

I'm not certain if the current implementation is appropriate.
Please let me know if there's a better way.
 

2. Altmode switching and orientation switching for USBDP PHY

For USB Type-C interfaces, an external Type-C controller chip assists
by detecting cable attachment, determining plug orientation, and
reporting USB PD message. The USB/DP combo PHY supports software
configurable pin mapping and DisplayPort lane assignment. Based on
these message, the combo PHY can perform both altmode switching and
orientation switching via software.

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 +---> USB2.0 PHY > DWC3 USB controller
 |
 +---> USB/DP PHY0 +--> CDN-DP controller
   |
   +--> DWC3 USB controller


3. Multiple bridge model for RK3399 CDN-DP

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.

USB/DP PHY0 ---+
   | <> CDN-DP controller
USB/DP PHY1 ---+

In previous versions, if both PHY ports were connected to DP,
the CDN-DP driver would select the first PHY port for output.

On Dmitry's suggestion, we introduced a multi-bridge model to support
flexible selection of the output PHY port. For each PHY port, a
separate encoder and bridge are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the PHY, USB connector, and DP controller.
And cdn_dp_parse_hpd_bridge_dt() will parses it and determines
whether to register one or two bridges.


Patch1 add default HPD device when register Displayport altmode.
Patch2 add new Type-C mode switch for RK3399 USBDP phy binding.
Patch3 add typec_mux and typec_switch for RK3399 USBDP PHY.
Patch4 drops CDN-DP's extcon dependency when Type-C is present.
Patch5 add multiple bridges to support PHY port selection. 
Patch6 add missing dp_out port for RK3399 CDN-DP.
Patch7 add Type-C DP support for RK3399 EVB IND board.

Changes in v4:
- Link to V3: https://lore.kernel.org/all/20250729090032.97-1-ker...@airkyi.com/
- Add default HPD device for DisplayPort altmode.
- Introduce multiple bridges for CDN-DP.
- ...

Changes in v3:
- Link to V2: https://lore.kernel.org/all/20250718062619.99-1-ker...@airkyi.com/
- Add more descriptions to clarify the role of the PHY in switching.
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Link to V1: 
https://lore.kernel.org/all/20250715112456.101-1-ker...@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 (7):
  usb: typec: Add default HPD device when register DisplayPort altmode
  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 without extcon
  drm/rockchip: cdn-dp: Add multiple bridges to support PHY port
selection
  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|   6 +
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 .../boot/dts/rockchip/rk3399-evb-ind.dts  | 146 ++
 drivers/gpu/drm/rockchip/Kconfig  |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c| 423 +++---
 drivers/gpu/drm/rockchip/cdn-dp-core.h|  23 +-
 drivers/phy/rockchip/phy-rockchip-typec.c | 365 ++-
 drivers/usb/typec/altmodes/displayport.c  |  27 ++
 drivers/usb/typec/altmodes/displayport.h  |   2 +
 drivers/usb/typec/class.c |   8 +
 include/linux/usb/typec_altmode.h |   2 +
 11 

Re: [PATCH v4 2/7] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch

2025-09-22 Thread Chaoyi Chen

On 9/23/2025 11:17 AM, Dmitry Baryshkov wrote:


On Tue, Sep 23, 2025 at 09:53:06AM +0800, Chaoyi Chen wrote:

Hi Dmitry,

On 9/23/2025 9:12 AM, Dmitry Baryshkov wrote:

On Mon, Sep 22, 2025 at 09:20:34AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

The RK3399 SoC integrates two USB/DP combo PHYs, each of which
supports software-configurable pin mapping and DisplayPort lane
assignment. These capabilities enable the PHY itself to handle both
mode switching and orientation switching, based on the Type-C plug
orientation and USB PD negotiation results.

While an external Type-C controller is still required to detect cable
attachment and report USB PD events, the actual mode and orientation
switching is performed internally by the PHY through software
configuration. This allows the PHY to act as a Type-C multiplexer for
both data role and DP altmode configuration.

To reflect this hardware design, this patch introduces a new
"mode-switch" property for the dp-port node in the device tree bindings.
This property indicates that the connected PHY is capable of handling
Type-C mode switching itself.

Signed-off-by: Chaoyi Chen 

Acked-by: Krzysztof Kozlowski 
---

Changes in v4:
- Remove "|" in description.

Changes in v3:
- Add more descriptions to clarify the role of the PHY in switching.

Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.

   .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++
   1 file changed, 6 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..83ebcde096ea 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,12 @@ properties:
 '#phy-cells':
   const: 0
+  mode-switch:

Having the mode-switch here is a bit strange. I think the whole PHY
device should be an orientation-switch and mode-switch. Otherwise it
feels weird to me.

I think this is a difference in practice. In the previous binding, there was 
already an orientation-switch under the usb-port. I trying to add both an 
orientation-switch and a mode-switch to the top-level device in v2. And 
Krzysztof reminded me that adding a mode-switch under the dp-port would be 
better, so I changed it to the current form :)

I couldn't find the comment on lore. Could you please point it out?


Sorry, it is v1. I added an orientation-switch and a mode-switch in the 
top-level PHY [0]. Comment is here: [1]


[0] https://lore.kernel.org/all/20250715112456.101-4-ker...@airkyi.com/

[1] https://lore.kernel.org/all/4dfed94c-665d-4e04-b527-ddd34fd3d...@kernel.org/







+description:
+  Indicates the PHY can handle altmode switching. In this case,
+  requires an external USB Type-C controller to report USB PD message.
+type: boolean
+
 port:
   $ref: /schemas/graph.yaml#/properties/port
   description: Connection to USB Type-C connector
--
2.49.0


--
Best,
Chaoyi


--
Best,
Chaoyi



Re: [PATCH v4 5/7] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection

2025-09-22 Thread Chaoyi Chen

On 9/23/2025 11:22 AM, Dmitry Baryshkov wrote:


On Tue, Sep 23, 2025 at 10:09:38AM +0800, Chaoyi Chen wrote:

On 9/23/2025 9:50 AM, Dmitry Baryshkov wrote:


On Mon, Sep 22, 2025 at 09:20:37AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

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. If both ports
are plugged into DP, DP will select the first port for output.

This patch adds support for multiple bridges, enabling users to flexibly
select the output port. For each PHY port, a separate encoder and bridge
are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the PHY, USB connector, and DP controller.
And cdn_dp_parse_hpd_bridge_dt() will parses it and determines
whether to register one or two bridges.

Since there is only one DP controller, only one of the PHY ports can
output at a time. The key is how to switch between different PHYs,
which is handled by cdn_dp_switch_port() and cdn_dp_enable().

There are two cases:

1. Neither bridge is enabled. In this case, both bridges can
independently read the EDID, and the PHY port may switch before
reading the EDID.

2. One bridge is already enabled. In this case, other bridges are not
allowed to read the EDID.

Since the scenario of two ports plug in at the same time is rare,
I don't have a board which support two TypeC connector to test this.
Therefore, I tested forced switching on a single PHY port, as well as
output using a fake PHY port alongside a real PHY port.

Signed-off-by: Chaoyi Chen 
---
   drivers/gpu/drm/rockchip/Kconfig   |   1 +
   drivers/gpu/drm/rockchip/cdn-dp-core.c | 398 +
   drivers/gpu/drm/rockchip/cdn-dp-core.h |  23 +-
   3 files changed, 366 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index faf50d872be3..3a6266279323 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -55,6 +55,7 @@ config ROCKCHIP_CDN_DP
select DRM_DISPLAY_HELPER
select DRM_BRIDGE_CONNECTOR
select DRM_DISPLAY_DP_HELPER
+   select DRM_AUX_HPD_BRIDGE
help
  This selects support for Rockchip SoC specific extensions
  for the cdn DP driver. If you want to enable Dp on
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 1e27301584a4..784f5656fcc4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -27,16 +27,17 @@
   #include "cdn-dp-core.h"
   #include "cdn-dp-reg.h"
-static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port 
*prev_port,
+ struct cdn_dp_port *port);
+
+static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge 
*bridge)
   {
-   return container_of(bridge, struct cdn_dp_device, bridge);
+   return container_of(bridge, struct cdn_dp_bridge, bridge);
   }
-static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
   {
-   struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
-
-   return container_of(rkencoder, struct cdn_dp_device, encoder);
+   return bridge_to_dp_bridge(bridge)->parent;
   }
   #define GRF_SOC_CON9 0x6224
@@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device 
*dp, u8 *sink_count)
   static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
   {
struct cdn_dp_port *port;
-   int i, lanes;
+   int i, lanes[MAX_PHY];
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
-   lanes = cdn_dp_get_port_lanes(port);
-   if (lanes)
+   lanes[i] = cdn_dp_get_port_lanes(port);
+   if (!dp->hpd_bridge_valid)
return port;
}
+
+   if (dp->hpd_bridge_valid) {
+   /* If more than one port is available, pick the last active 
port */
+   if (dp->active_port > 0 && lanes[dp->active_port])
+   return dp->port[dp->active_port];
+
+   /* If the last active port is not available, pick an available 
port in order */
+   for (i = 0; i < dp->bridge_count; i++) {
+   if (lanes[i])
+   return dp->port[i];
+   }
+   }
+
return NULL;
   }
@@ -239,10 +253,11 @@ static enum drm_connector_status
   cdn_dp_bridge_detect(struct drm_bridge *bridge, struct drm_connector 
*connector)
   {
struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   struct cdn_dp_bridge 

Re: [PATCH v4 1/7] usb: typec: Add default HPD device when register DisplayPort altmode

2025-09-22 Thread Chaoyi Chen

On 9/23/2025 9:10 AM, Dmitry Baryshkov wrote:


On Mon, Sep 22, 2025 at 09:20:33AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

Add default DRM AUX HPD bridge device when register DisplayPort
altmode. That makes it redundant for each Type-C driver to implement
a similar registration process in embedded scenarios.

Signed-off-by: Chaoyi Chen 
---
  drivers/usb/typec/altmodes/displayport.c | 27 
  drivers/usb/typec/altmodes/displayport.h |  2 ++
  drivers/usb/typec/class.c|  8 +++
  include/linux/usb/typec_altmode.h|  2 ++
  4 files changed, 39 insertions(+)

diff --git a/drivers/usb/typec/altmodes/displayport.c 
b/drivers/usb/typec/altmodes/displayport.c
index 1dcb77faf85d..e026dc6e5430 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -14,6 +14,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include "displayport.h"
  
@@ -182,6 +183,10 @@ static int dp_altmode_status_update(struct dp_altmode *dp)

dp->pending_irq_hpd = true;
}
} else {
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ hpd ? 
connector_status_connected :
+   
connector_status_disconnected);

There should be no need for these calls. Once the HPD bridge is added to
a correct fwnode, the drm_connector_oob_hotplug_event() calls should
deliver the signal as expected.


It seems that only drm_bridge_connector can do this. I'm not sure if I remember 
correctly. I'll give it a try.





drm_connector_oob_hotplug_event(dp->connector_fwnode,
hpd ? 
connector_status_connected :
  
connector_status_disconnected);
@@ -206,6 +211,9 @@ static int dp_altmode_configured(struct dp_altmode *dp)
 * configuration is complete to signal HPD.
 */
if (dp->pending_hpd) {
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ connector_status_connected);
drm_connector_oob_hotplug_event(dp->connector_fwnode,
connector_status_connected);
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
@@ -391,6 +399,9 @@ static int dp_altmode_vdm(struct typec_altmode *alt,
dp->data.status = 0;
dp->data.conf = 0;
if (dp->hpd) {
+   if (dp->port->hpd_dev)
+   
drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ 
connector_status_disconnected);

drm_connector_oob_hotplug_event(dp->connector_fwnode,

connector_status_disconnected);
dp->hpd = false;
@@ -751,6 +762,18 @@ static const struct attribute_group *displayport_groups[] 
= {
NULL,
  };
  
+void dp_altmode_hpd_device_register(struct typec_altmode *alt)

+{
+   if (alt->svid != USB_TYPEC_DP_SID)
+   return;
+
+   alt->hpd_dev = drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+ 
dev_of_node(alt->dev.parent->parent));

This needs at least a comment, what is dev.parent->parent. Also, the
of_node is not correct here. It should be a node of the connector,
rather than the device itself. Consider USB-C controllers which handle
several USB-C connectors (e.g. UCSI). The DRM core won't be able to
identify the correct bridge.


I think  alt.dev->parent->parent is the connector device. Am I missing 
something?






+   if (IS_ERR(alt->hpd_dev))
+   alt->hpd_dev = NULL;
+}
+EXPORT_SYMBOL_GPL(dp_altmode_hpd_device_register);

Having the function here will bring a typec -> displayport dependency
between drivers (which you didn't document). It means it won't be
possible to build typec core into the kernel, having the DP AltMode
driver in the module (which also doesn't sound like a good idea).


It make sense. Perhaps moving it into class.c would be a good idea.





+
  int dp_altmode_probe(struct typec_altmode *alt)
  {
const struct typec_altmode *port = typec_altmode_get_partner(alt);


--
Best,
Chaoyi



Re: [PATCH v4 4/7] drm/rockchip: cdn-dp: Support handle lane info without extcon

2025-09-22 Thread Chaoyi Chen

On 9/22/2025 6:01 PM, Dmitry Baryshkov wrote:


On Mon, Sep 22, 2025 at 09:20:36AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

This patch add support for get PHY lane info without help of extcon.

There is no extcon needed if the Type-C controller is present. In this
case, 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 
---

Changes in v4:
- Remove cdn_dp_hpd_notify().

(no changes since v3)

Changes in v2:
- Ignore duplicate HPD events.

  drivers/gpu/drm/rockchip/cdn-dp-core.c | 25 +
  1 file changed, 17 insertions(+), 8 deletions(-)

@@ -1120,14 +1129,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;

This will break the case when the extcon is present. It should be
(IS_ERR(extcon) && PTR_ERR(extcon) != -ENODEV)


Yes, will fix in v5




  
  		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


--
Best,
Chaoyi



Re: [PATCH v4 5/7] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection

2025-09-22 Thread Chaoyi Chen

On 9/23/2025 9:50 AM, Dmitry Baryshkov wrote:


On Mon, Sep 22, 2025 at 09:20:37AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

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. If both ports
are plugged into DP, DP will select the first port for output.

This patch adds support for multiple bridges, enabling users to flexibly
select the output port. For each PHY port, a separate encoder and bridge
are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the PHY, USB connector, and DP controller.
And cdn_dp_parse_hpd_bridge_dt() will parses it and determines
whether to register one or two bridges.

Since there is only one DP controller, only one of the PHY ports can
output at a time. The key is how to switch between different PHYs,
which is handled by cdn_dp_switch_port() and cdn_dp_enable().

There are two cases:

1. Neither bridge is enabled. In this case, both bridges can
independently read the EDID, and the PHY port may switch before
reading the EDID.

2. One bridge is already enabled. In this case, other bridges are not
allowed to read the EDID.

Since the scenario of two ports plug in at the same time is rare,
I don't have a board which support two TypeC connector to test this.
Therefore, I tested forced switching on a single PHY port, as well as
output using a fake PHY port alongside a real PHY port.

Signed-off-by: Chaoyi Chen 
---
  drivers/gpu/drm/rockchip/Kconfig   |   1 +
  drivers/gpu/drm/rockchip/cdn-dp-core.c | 398 +
  drivers/gpu/drm/rockchip/cdn-dp-core.h |  23 +-
  3 files changed, 366 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index faf50d872be3..3a6266279323 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -55,6 +55,7 @@ config ROCKCHIP_CDN_DP
select DRM_DISPLAY_HELPER
select DRM_BRIDGE_CONNECTOR
select DRM_DISPLAY_DP_HELPER
+   select DRM_AUX_HPD_BRIDGE
help
  This selects support for Rockchip SoC specific extensions
  for the cdn DP driver. If you want to enable Dp on
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 1e27301584a4..784f5656fcc4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -27,16 +27,17 @@
  #include "cdn-dp-core.h"
  #include "cdn-dp-reg.h"
  
-static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)

+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port 
*prev_port,
+ struct cdn_dp_port *port);
+
+static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge 
*bridge)
  {
-   return container_of(bridge, struct cdn_dp_device, bridge);
+   return container_of(bridge, struct cdn_dp_bridge, bridge);
  }
  
-static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)

+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
  {
-   struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
-
-   return container_of(rkencoder, struct cdn_dp_device, encoder);
+   return bridge_to_dp_bridge(bridge)->parent;
  }
  
  #define GRF_SOC_CON9		0x6224

@@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device 
*dp, u8 *sink_count)
  static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
  {
struct cdn_dp_port *port;
-   int i, lanes;
+   int i, lanes[MAX_PHY];
  
  	for (i = 0; i < dp->ports; i++) {

port = dp->port[i];
-   lanes = cdn_dp_get_port_lanes(port);
-   if (lanes)
+   lanes[i] = cdn_dp_get_port_lanes(port);
+   if (!dp->hpd_bridge_valid)
return port;
}
+
+   if (dp->hpd_bridge_valid) {
+   /* If more than one port is available, pick the last active 
port */
+   if (dp->active_port > 0 && lanes[dp->active_port])
+   return dp->port[dp->active_port];
+
+   /* If the last active port is not available, pick an available 
port in order */
+   for (i = 0; i < dp->bridge_count; i++) {
+   if (lanes[i])
+   return dp->port[i];
+   }
+   }
+
return NULL;
  }
  
@@ -239,10 +253,11 @@ static enum drm_connector_status

  cdn_dp_bridge_detect(struct drm_bridge *bridge, struct drm_connector 
*connector)
  {
struct cdn_dp_device *dp = bridge_to_dp(bridge);
+   struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
enum drm_connector_status status = connector_status_disconnected;
  

Re: [PATCH v4 1/7] usb: typec: Add default HPD device when register DisplayPort altmode

2025-09-25 Thread Chaoyi Chen

On 9/23/2025 11:11 AM, Dmitry Baryshkov wrote:


On Tue, Sep 23, 2025 at 09:34:39AM +0800, Chaoyi Chen wrote:

On 9/23/2025 9:10 AM, Dmitry Baryshkov wrote:


On Mon, Sep 22, 2025 at 09:20:33AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

Add default DRM AUX HPD bridge device when register DisplayPort
altmode. That makes it redundant for each Type-C driver to implement
a similar registration process in embedded scenarios.

Signed-off-by: Chaoyi Chen 
---
   drivers/usb/typec/altmodes/displayport.c | 27 
   drivers/usb/typec/altmodes/displayport.h |  2 ++
   drivers/usb/typec/class.c|  8 +++
   include/linux/usb/typec_altmode.h|  2 ++
   4 files changed, 39 insertions(+)

diff --git a/drivers/usb/typec/altmodes/displayport.c 
b/drivers/usb/typec/altmodes/displayport.c
index 1dcb77faf85d..e026dc6e5430 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -14,6 +14,7 @@
   #include 
   #include 
   #include 
+#include 
   #include 
   #include "displayport.h"
@@ -182,6 +183,10 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
dp->pending_irq_hpd = true;
}
} else {
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ hpd ? 
connector_status_connected :
+   
connector_status_disconnected);

There should be no need for these calls. Once the HPD bridge is added to
a correct fwnode, the drm_connector_oob_hotplug_event() calls should
deliver the signal as expected.

It seems that only drm_bridge_connector can do this. I'm not sure if I remember 
correctly. I'll give it a try.

Other connectors can implement the .oob_hotplug_event call. Calling
drm_bridge_hpd_notify() also depends on the connector setting the
callbacks via drm_bridge_hpd_enable(), a step which is done by only a
few drivers.


Hmm, let's go over this again. First, drm_connector_oob_hotplug_event() 
requires a connector fwnode.

On the Qualcomm platforms, the fwnode corresponds to the USB-C controller 
device node, so

drm_connector_oob_hotplug_event(dp->connector_fwnode, ..) can handle them 
directly.

But our platform doesn't use the USB-C controller device node as drm connector 
fwnode :(

So I use drm_dp_hpd_bridge_register() and drm_aux_hpd_bridge_notify() here, I 
think it just create a simple hpd bridge to bridge_list.

But drm_connector_oob_hotplug_event() use connector_list instead of bridge_list.








drm_connector_oob_hotplug_event(dp->connector_fwnode,
hpd ? 
connector_status_connected :
  
connector_status_disconnected);
@@ -206,6 +211,9 @@ static int dp_altmode_configured(struct dp_altmode *dp)
 * configuration is complete to signal HPD.
 */
if (dp->pending_hpd) {
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ connector_status_connected);
drm_connector_oob_hotplug_event(dp->connector_fwnode,
connector_status_connected);
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
@@ -391,6 +399,9 @@ static int dp_altmode_vdm(struct typec_altmode *alt,
dp->data.status = 0;
dp->data.conf = 0;
if (dp->hpd) {
+   if (dp->port->hpd_dev)
+   
drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ 
connector_status_disconnected);

drm_connector_oob_hotplug_event(dp->connector_fwnode,

connector_status_disconnected);
dp->hpd = false;
@@ -751,6 +762,18 @@ static const struct attribute_group *displayport_groups[] 
= {
NULL,
   };
+void dp_altmode_hpd_device_register(struct typec_altmode *alt)
+{
+   if (alt->svid != USB_TYPEC_DP_SID)
+   return;
+
+   alt->hpd_dev = drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+ 
dev_of_node(alt->dev.parent->parent));

This needs at least a comment, what is dev.parent->parent. Also, the
of_node is not correct here. It should be a node of the connector,
rather than the device itself. Consider USB-C controllers which handle
several USB-C connectors (e.g. UCSI). The DRM core won't be able to
identify the correct bridge.

Re: [PATCH v4 2/7] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch

2025-09-23 Thread Chaoyi Chen

On 9/23/2025 11:17 AM, Dmitry Baryshkov wrote:


On Tue, Sep 23, 2025 at 09:53:06AM +0800, Chaoyi Chen wrote:

Hi Dmitry,

On 9/23/2025 9:12 AM, Dmitry Baryshkov wrote:

On Mon, Sep 22, 2025 at 09:20:34AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

The RK3399 SoC integrates two USB/DP combo PHYs, each of which
supports software-configurable pin mapping and DisplayPort lane
assignment. These capabilities enable the PHY itself to handle both
mode switching and orientation switching, based on the Type-C plug
orientation and USB PD negotiation results.

While an external Type-C controller is still required to detect cable
attachment and report USB PD events, the actual mode and orientation
switching is performed internally by the PHY through software
configuration. This allows the PHY to act as a Type-C multiplexer for
both data role and DP altmode configuration.

To reflect this hardware design, this patch introduces a new
"mode-switch" property for the dp-port node in the device tree bindings.
This property indicates that the connected PHY is capable of handling
Type-C mode switching itself.

Signed-off-by: Chaoyi Chen 

Acked-by: Krzysztof Kozlowski 
---

Changes in v4:
- Remove "|" in description.

Changes in v3:
- Add more descriptions to clarify the role of the PHY in switching.

Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.

   .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++
   1 file changed, 6 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..83ebcde096ea 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,12 @@ properties:
 '#phy-cells':
   const: 0
+  mode-switch:

Having the mode-switch here is a bit strange. I think the whole PHY
device should be an orientation-switch and mode-switch. Otherwise it
feels weird to me.

I think this is a difference in practice. In the previous binding, there was 
already an orientation-switch under the usb-port. I trying to add both an 
orientation-switch and a mode-switch to the top-level device in v2. And 
Krzysztof reminded me that adding a mode-switch under the dp-port would be 
better, so I changed it to the current form :)

I couldn't find the comment on lore. Could you please point it out?


Sorry, it is v1. I added an orientation-switch and a mode-switch in the 
top-level PHY [0]. Comment is here: [1]


[0] https://lore.kernel.org/all/20250715112456.101-4-ker...@airkyi.com/

[1] https://lore.kernel.org/all/4dfed94c-665d-4e04-b527-ddd34fd3d...@kernel.org/







+description:
+  Indicates the PHY can handle altmode switching. In this case,
+  requires an external USB Type-C controller to report USB PD message.
+type: boolean
+
 port:
   $ref: /schemas/graph.yaml#/properties/port
   description: Connection to USB Type-C connector
--
2.49.0


--
Best,
Chaoyi


--
Best,
Chaoyi



Re: [PATCH v4 1/7] usb: typec: Add default HPD device when register DisplayPort altmode

2025-09-28 Thread Chaoyi Chen

On 9/23/2025 6:40 PM, Dmitry Baryshkov wrote:


On Tue, Sep 23, 2025 at 05:07:25PM +0800, Chaoyi Chen wrote:

On 9/23/2025 11:11 AM, Dmitry Baryshkov wrote:


On Tue, Sep 23, 2025 at 09:34:39AM +0800, Chaoyi Chen wrote:

On 9/23/2025 9:10 AM, Dmitry Baryshkov wrote:


On Mon, Sep 22, 2025 at 09:20:33AM +0800, Chaoyi Chen wrote:

From: Chaoyi Chen 

Add default DRM AUX HPD bridge device when register DisplayPort
altmode. That makes it redundant for each Type-C driver to implement
a similar registration process in embedded scenarios.

Signed-off-by: Chaoyi Chen 
---
drivers/usb/typec/altmodes/displayport.c | 27 
drivers/usb/typec/altmodes/displayport.h |  2 ++
drivers/usb/typec/class.c|  8 +++
include/linux/usb/typec_altmode.h|  2 ++
4 files changed, 39 insertions(+)

diff --git a/drivers/usb/typec/altmodes/displayport.c 
b/drivers/usb/typec/altmodes/displayport.c
index 1dcb77faf85d..e026dc6e5430 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -14,6 +14,7 @@
#include 
#include 
#include 
+#include 
#include 
#include "displayport.h"
@@ -182,6 +183,10 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
dp->pending_irq_hpd = true;
}
} else {
+   if (dp->port->hpd_dev)
+   drm_aux_hpd_bridge_notify(dp->port->hpd_dev,
+ hpd ? 
connector_status_connected :
+   
connector_status_disconnected);

There should be no need for these calls. Once the HPD bridge is added to
a correct fwnode, the drm_connector_oob_hotplug_event() calls should
deliver the signal as expected.

It seems that only drm_bridge_connector can do this. I'm not sure if I remember 
correctly. I'll give it a try.

Other connectors can implement the .oob_hotplug_event call. Calling
drm_bridge_hpd_notify() also depends on the connector setting the
callbacks via drm_bridge_hpd_enable(), a step which is done by only a
few drivers.

Hmm, let's go over this again. First, drm_connector_oob_hotplug_event() 
requires a connector fwnode.

On the Qualcomm platforms, the fwnode corresponds to the USB-C controller 
device node, so

drm_connector_oob_hotplug_event(dp->connector_fwnode, ..) can handle them 
directly.

But our platform doesn't use the USB-C controller device node as drm connector 
fwnode :(

This sounds like an issue to be fixed. Alternative option would be make
the AltMode code find your fwnode and report OOB events against it.
But... I reallly think that using connector's fwnode is the cleanest
solution. In the end, your final 'display' connector is the USB-C
connector present on the board. If your display has a USB-C connector,
that will be the socket that gets the cable from the display, etc.


So I use drm_dp_hpd_bridge_register() and drm_aux_hpd_bridge_notify() here, I 
think it just create a simple hpd bridge to bridge_list.

But drm_connector_oob_hotplug_event() use connector_list instead of bridge_list.

The OOB interface was created by x86 people, but we successfully reused
it. I think that addign drm_bridge_hpd_notify() calls just duplicates
the effort unnecessarily.


Yes, that commit comment said,  "It was proposed to add the displayport OF property 
to the DT bindings, but it was rejected in favor of properly describing the electrical 
signal path using of_graph."

But in the embedded case, we don't seem to have the opportunity to describe 
this kind of of_graph relationship between drm connector and usb connector in 
usb-connector.yaml. On the Qualcomm platform, the DRM connector fwnode to 
correspond to the USB-C controller, which is a clean solution.

However, on our platform we are using external USB-C controllers. In v4 and the 
previous versions, I focused on directly linking the USB-C controller with the 
DP controller. Referring to your suggest in [0], I think maybe this can be 
achieved with the help of the drm bridge chain. Assuming the bridge chain is 
like this:


Other birdges ... ->PHY drm aux hpd bridge -> CDN-DP bridge -> DP to HDMI 
bridge or other bridge or nothing...


We can use drm_bridge_chain_get_first_bridge() to get first bridge. In this 
case, that is drm aux hpd bridge from USB-C controller device. Next, we can 
obtain the fwnode corresponding to this bridge, and once we have it, we can set 
the connector's fwnode to it. In this way, drm_connector_oob_hotplug_event() 
can take effect.


Would this be a good idea? Thanks.


[0] 
https://lore.kernel.org/all/p3kgqn3euumhysckh4yyqavqv5y6any5zcrgkrcg3j5a7z7cyw@lfpkla5p3put/








drm_connector_oob_hotplug_event(dp->connector_fwnode,
hpd ? 
connector_status_c

[PATCH v5 4/8] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge

2025-10-10 Thread Chaoyi Chen
From: Chaoyi Chen 

Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
device.

Signed-off-by: Chaoyi Chen 
---
 drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++
 1 file changed, 52 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c 
b/drivers/phy/rockchip/phy-rockchip-typec.c
index 4a1dfa8d65c7..8003a41de5c6 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -36,6 +36,7 @@
  * orientation, false is normal orientation.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -56,6 +57,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define CMN_SSM_BANDGAP(0x21 << 2)
 #define CMN_SSM_BIAS   (0x22 << 2)
@@ -415,6 +417,7 @@ struct rockchip_usb3phy_port_cfg {
 
 struct rockchip_typec_phy {
struct device *dev;
+   struct auxiliary_device dp_port_dev;
void __iomem *base;
struct extcon_dev *extcon;
struct typec_mux_dev *mux;
@@ -1296,6 +1299,51 @@ static void tcphy_typec_mux_unregister(void *data)
typec_mux_unregister(tcphy->mux);
 }
 
+static void tcphy_dp_port_dev_release(struct device *dev)
+{
+   struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+   of_node_put(adev->dev.of_node);
+}
+
+static void tcphy_dp_port_unregister_adev(void *_adev)
+{
+   struct auxiliary_device *adev = _adev;
+
+   auxiliary_device_delete(adev);
+   auxiliary_device_uninit(adev);
+}
+
+static int tcphy_aux_bridge_register(struct rockchip_typec_phy *tcphy, struct 
device_node *np)
+{
+   struct auxiliary_device *adev = &tcphy->dp_port_dev;
+   int ret;
+
+   adev->name = "dp_port";
+   adev->dev.parent = tcphy->dev;
+   adev->dev.of_node = of_node_get(np);
+   adev->dev.release = tcphy_dp_port_dev_release;
+
+   ret = auxiliary_device_init(adev);
+
+   if (ret) {
+   of_node_put(adev->dev.of_node);
+   return ret;
+   }
+
+   ret = auxiliary_device_add(adev);
+   if (ret) {
+   auxiliary_device_uninit(adev);
+   return ret;
+   }
+
+   devm_add_action_or_reset(tcphy->dev, tcphy_dp_port_unregister_adev, 
adev);
+
+   ret = drm_aux_bridge_register(&adev->dev);
+
+   return 0;
+}
+
 static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
 {
struct typec_mux_desc mux_desc = {};
@@ -1309,6 +1357,10 @@ static int tcphy_setup_typec_mux(struct 
rockchip_typec_phy *tcphy)
if (!of_property_read_bool(np, "mode-switch"))
goto put_np;
 
+   ret = tcphy_aux_bridge_register(tcphy, np);
+   if (ret)
+   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;
-- 
2.49.0



[PATCH v5 7/8] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP

2025-10-10 Thread Chaoyi Chen
From: Chaoyi Chen 

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 
---

(no changes since v5)

Changes in v4:
- Remove unnecessary #address/#size-cells

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
index 4dcceb9136b7..93b42820998f 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@fec0 {
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,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+   dp_out: port@1 {
+   reg = <1>;
+   };
};
};
 
-- 
2.49.0



[PATCH v5 1/8] usb: typec: Add default HPD device when register DisplayPort altmode

2025-10-10 Thread Chaoyi Chen
From: Chaoyi Chen 

Add default DRM AUX HPD bridge device when register DisplayPort
altmode. That makes it redundant for each Type-C driver to implement
a similar registration process in embedded scenarios.

Signed-off-by: Chaoyi Chen 
---

Changes in v5:
- Remove the calls related to `drm_aux_hpd_bridge_notify()`.
- Place the helper functions in the same compilation unit.
- Add more comments about parent device.

 drivers/usb/typec/class.c | 26 ++
 include/linux/usb/typec_altmode.h |  2 ++
 2 files changed, 28 insertions(+)

diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 67a533e35150..e9d7772d1a8f 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -8,14 +8,18 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 
+#include 
+
 #include "bus.h"
 #include "class.h"
 #include "pd.h"
@@ -538,6 +542,21 @@ const struct device_type typec_altmode_dev_type = {
.release = typec_altmode_release,
 };
 
+static void dp_altmode_hpd_device_register(struct typec_altmode *alt)
+{
+   if (alt->svid != USB_TYPEC_DP_SID)
+   return;
+
+   /*
+* alt->dev.parent->parent : USB-C controller device
+* alt->dev.parent : USB-C connector device
+*/
+   alt->hpd_dev = drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+ 
to_of_node(alt->dev.parent->fwnode));
+   if (IS_ERR(alt->hpd_dev))
+   alt->hpd_dev = NULL;
+}
+
 static struct typec_altmode *
 typec_register_altmode(struct device *parent,
   const struct typec_altmode_desc *desc)
@@ -600,6 +619,13 @@ typec_register_altmode(struct device *parent,
return ERR_PTR(ret);
}
 
+   /*
+* It is too late to register the HPD device when the DisplayPort
+* altmode device becomes ready. If the current altmode is DP,
+* register a static HPD device.
+*/
+   dp_altmode_hpd_device_register(&alt->adev);
+
return &alt->adev;
 }
 
diff --git a/include/linux/usb/typec_altmode.h 
b/include/linux/usb/typec_altmode.h
index b3c0866ea70f..acb0af1b9d5d 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -21,6 +21,7 @@ struct typec_altmode_ops;
  * @desc: Optional human readable description of the mode
  * @ops: Operations vector from the driver
  * @cable_ops: Cable operations vector from the driver.
+ * @hpd_dev: HPD device for DisplayPort
  */
 struct typec_altmode {
struct device   dev;
@@ -32,6 +33,7 @@ struct typec_altmode {
char*desc;
const struct typec_altmode_ops  *ops;
const struct typec_cable_ops*cable_ops;
+   struct device   *hpd_dev;
 };
 
 #define to_typec_altmode(d) container_of(d, struct typec_altmode, dev)
-- 
2.49.0