* [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board
@ 2025-10-23 3:30 Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 1/9] usb: typec: Add notifier functions Chaoyi Chen
` (9 more replies)
0 siblings, 10 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
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 v7, I implemented a variety of DP HPD status notify. However,
they all had various problems and it was difficult to become a generic
solution.
Under the guidance of Heikki and Dmitry, a decoupled notification
method between the TypeC and DRM subsystems was introduced in v7.
First, a notification is sent when TypeC registers a new altmode.
Then, a generic DP AUX HPD bridge is implemented on the DRM side.
That makes it redundant for each Type-C controller driver to implement
a similar DP AUX HPD bridge in embedded scenarios.
====
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 first bridge in bridge chain and DP
controller. And Once the first bridge is obtained, we can get the
last bridge corresponding to the USB-C connector, and then set the
DRM connector's fwnode to the corresponding one to enable HPD
notification.
====
Patch1 add notifier functions for Type-C core.
Patch2 add generic USB Type-C DP HPD bridge.
Patch3 add new Type-C mode switch for RK3399 USBDP phy binding.
Patch4 add typec_mux and typec_switch for RK3399 USBDP PHY.
Patch5 add DRM AUX bridge support for RK3399 USBDP PHY.
Patch6 drops CDN-DP's extcon dependency when Type-C is present.
Patch7 add multiple bridges to support PHY port selection.
Patch8 add missing dp_out port for RK3399 CDN-DP.
Patch9 add Type-C DP support for RK3399 EVB IND board.
Changes in v7:
- Link to V6: https://lore.kernel.org/all/20251016022741.91-1-kernel@airkyi.com/
- Add notifier functions for Type-C core.
- Add generic USB Type-C DP HPD bridge.
Changes in v6:
- Link to V5: https://lore.kernel.org/all/20251011033233.97-1-kernel@airkyi.com/
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().
- Rename some variable names.
- Attach the DP bridge to the next bridge.
Changes in v5:
- Link to V4: https://lore.kernel.org/all/20250922012039.323-1-kernel@airkyi.com/
- 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.
- Add DRM AUX bridge support for RK3399 USBDP PHY
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.
Changes in v4:
- Link to V3: https://lore.kernel.org/all/20250729090032.97-1-kernel@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-kernel@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-kernel@airkyi.com/
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.
- Ignore duplicate HPD events.
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.
Chaoyi Chen (9):
usb: typec: Add notifier functions
drm/bridge: Implement generic USB Type-C DP HPD bridge
dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
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/bridge/Kconfig | 11 +
drivers/gpu/drm/bridge/Makefile | 1 +
.../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 51 +++
drivers/gpu/drm/rockchip/cdn-dp-core.c | 354 ++++++++++++---
drivers/gpu/drm/rockchip/cdn-dp-core.h | 24 +-
drivers/phy/rockchip/Kconfig | 3 +
drivers/phy/rockchip/phy-rockchip-typec.c | 420 +++++++++++++++++-
drivers/usb/typec/Makefile | 2 +-
drivers/usb/typec/class.c | 3 +
drivers/usb/typec/notify.c | 22 +
include/linux/usb/typec_notify.h | 17 +
14 files changed, 987 insertions(+), 83 deletions(-)
create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
create mode 100644 drivers/usb/typec/notify.c
create mode 100644 include/linux/usb/typec_notify.h
--
2.49.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 8:10 ` Heikki Krogerus
2025-10-24 8:16 ` Heikki Krogerus
2025-10-23 3:30 ` [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge Chaoyi Chen
` (8 subsequent siblings)
9 siblings, 2 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Some other part of kernel may want to know the event of typec bus.
This patch add common notifier function to notify these event.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
drivers/usb/typec/Makefile | 2 +-
drivers/usb/typec/class.c | 3 +++
drivers/usb/typec/notify.c | 22 ++++++++++++++++++++++
include/linux/usb/typec_notify.h | 17 +++++++++++++++++
4 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 drivers/usb/typec/notify.c
create mode 100644 include/linux/usb/typec_notify.h
diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index 7a368fea61bc..20d09c5314d7 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_TYPEC) += typec.o
-typec-y := class.o mux.o bus.o pd.o retimer.o
+typec-y := class.o mux.o notify.o bus.o pd.o retimer.o
typec-$(CONFIG_ACPI) += port-mapper.o
obj-$(CONFIG_TYPEC) += altmodes/
obj-$(CONFIG_TYPEC_TCPM) += tcpm/
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 67a533e35150..11c80bc59cda 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -13,6 +13,7 @@
#include <linux/string_choices.h>
#include <linux/usb/pd_vdo.h>
#include <linux/usb/typec_mux.h>
+#include <linux/usb/typec_notify.h>
#include <linux/usb/typec_retimer.h>
#include <linux/usb.h>
@@ -600,6 +601,8 @@ typec_register_altmode(struct device *parent,
return ERR_PTR(ret);
}
+ typec_notify_event(TYPEC_ALTMODE_REGISTERED, &alt->adev);
+
return &alt->adev;
}
diff --git a/drivers/usb/typec/notify.c b/drivers/usb/typec/notify.c
new file mode 100644
index 000000000000..4ae14dd1f461
--- /dev/null
+++ b/drivers/usb/typec/notify.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/notifier.h>
+#include <linux/usb/typec_notify.h>
+
+static BLOCKING_NOTIFIER_HEAD(typec_notifier_list);
+
+int typec_register_notify(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&typec_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(typec_register_notify);
+
+int typec_unregister_notify(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&typec_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(typec_unregister_notify);
+
+void typec_notify_event(unsigned long event, void *data)
+{
+ blocking_notifier_call_chain(&typec_notifier_list, event, data);
+}
diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
new file mode 100644
index 000000000000..a3f1f3b3ae47
--- /dev/null
+++ b/include/linux/usb/typec_notify.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __USB_TYPEC_NOTIFY
+#define __USB_TYPEC_NOTIFY
+
+#include <linux/notifier.h>
+
+enum usb_typec_event {
+ TYPEC_ALTMODE_REGISTERED
+};
+
+int typec_register_notify(struct notifier_block *nb);
+int typec_unregister_notify(struct notifier_block *nb);
+
+void typec_notify_event(unsigned long event, void *data);
+
+#endif /* __USB_TYPEC_NOTIFY */
--
2.49.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 1/9] usb: typec: Add notifier functions Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 8:45 ` Heikki Krogerus
2025-10-24 8:01 ` Heikki Krogerus
2025-10-23 3:30 ` [PATCH v7 3/9] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
` (7 subsequent siblings)
9 siblings, 2 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Several USB-C controller drivers have already implemented the DP HPD
bridge function provided by aux-hpd-bridge.c, but there are still
some USB-C controller driver that have not yet implemented it.
This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c,
so that other USB-C controller drivers don't need to implement it again.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
drivers/gpu/drm/bridge/Kconfig | 11 ++++
drivers/gpu/drm/bridge/Makefile | 1 +
.../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 51 +++++++++++++++++++
3 files changed, 63 insertions(+)
create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index b9e0ca85226a..9f31540d3ad8 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -33,6 +33,17 @@ config DRM_AUX_HPD_BRIDGE
menu "Display Interface Bridges"
depends on DRM && DRM_BRIDGE
+config DRM_AUX_TYPEC_DP_HPD_BRIDGE
+ tristate "TypeC DP HPD bridge"
+ depends on DRM_BRIDGE && OF && TYPEC
+ select DRM_AUX_HPD_BRIDGE
+ help
+ Simple USB Type-C DP bridge that terminates the bridge chain and
+ provides HPD support.
+
+ If the USB-C controller driver has not implemented this and you need
+ the DP HPD support, say "Y" or "m" here.
+
config DRM_CHIPONE_ICN6211
tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 245e8a27e3fc..e91736829167 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
+obj-$(CONFIG_DRM_AUX_TYPEC_DP_HPD_BRIDGE) += aux-hpd-typec-dp-bridge.o
obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
new file mode 100644
index 000000000000..2235b7438fe9
--- /dev/null
+++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <linux/of.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_notify.h>
+
+#include <drm/bridge/aux-bridge.h>
+
+static int drm_typec_bus_event(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct typec_altmode *alt = (struct typec_altmode *)data;
+
+ if (action != TYPEC_ALTMODE_REGISTERED)
+ goto done;
+
+ if (alt->svid != USB_TYPEC_DP_SID)
+ goto done;
+
+ /*
+ * alt->dev.parent->parent : USB-C controller device
+ * alt->dev.parent : USB-C connector device
+ */
+ drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+ to_of_node(alt->dev.parent->fwnode));
+
+done:
+ return NOTIFY_OK;
+}
+
+static struct notifier_block drm_typec_event_nb = {
+ .notifier_call = drm_typec_bus_event,
+};
+
+static void drm_aux_hpd_typec_dp_bridge_module_exit(void)
+{
+ typec_unregister_notify(&drm_typec_event_nb);
+}
+
+static int __init drm_aux_hpd_typec_dp_bridge_module_init(void)
+{
+ typec_register_notify(&drm_typec_event_nb);
+
+ return 0;
+}
+
+module_init(drm_aux_hpd_typec_dp_bridge_module_init);
+module_exit(drm_aux_hpd_typec_dp_bridge_module_exit);
+
+MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE");
+MODULE_LICENSE("GPL");
--
2.49.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 3/9] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 1/9] usb: typec: Add notifier functions Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 4/9] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Chaoyi Chen
` (6 subsequent siblings)
9 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
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 <chaoyi.chen@rock-chips.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
(no changes since v5)
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
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 4/9] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (2 preceding siblings ...)
2025-10-23 3:30 ` [PATCH v7 3/9] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 5/9] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Chaoyi Chen
` (5 subsequent siblings)
9 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
This patch add support for Type-C Port Controller Manager. Each PHY
will register typec_mux and typec_switch when external Type-C
controller is present. Type-C events are handled by TCPM without
extcon.
The extcon device should still be supported.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
(no changes since v7)
Changes in v6:
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().
(no changes since v5)
Changes in v4:
- Remove notify DP HPD state by USB/DP PHY.
(no changes since v3)
Changes in v2:
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.
drivers/phy/rockchip/Kconfig | 1 +
drivers/phy/rockchip/phy-rockchip-typec.c | 368 +++++++++++++++++++++-
2 files changed, 353 insertions(+), 16 deletions(-)
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 14698571b607..db4adc7c53da 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -119,6 +119,7 @@ config PHY_ROCKCHIP_SNPS_PCIE3
config PHY_ROCKCHIP_TYPEC
tristate "Rockchip TYPEC PHY Driver"
depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+ depends on TYPEC || TYPEC=n
select EXTCON
select GENERIC_PHY
select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index d9701b6106d5..1f5b4142cbe4 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -54,6 +54,8 @@
#include <linux/mfd/syscon.h>
#include <linux/phy/phy.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
#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_MASK GENMASK(7, 4)
+#define PHY_DP_POWER_STATE_ACK_SHIFT 4
+#define PHY_DP_POWER_STATE_MASK GENMASK(3, 0)
#define DP_CLK_CTL (0xc009 << 2)
#define STS (0xc00F << 2)
#define PHY_ISO_CMN_CTRL (0xc010 << 2)
@@ -327,8 +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 100000
@@ -340,6 +360,31 @@
#define MODE_DFP_USB BIT(1)
#define MODE_DFP_DP BIT(2)
+enum phy_dp_lane_num {
+ PHY_DP_LANE_0 = 0,
+ PHY_DP_LANE_1,
+ PHY_DP_LANE_2,
+ PHY_DP_LANE_3,
+};
+
+enum phy_pma_if {
+ PMA_IF_PIPE_PCS = 0,
+ PMA_IF_PHY_DP,
+};
+
+enum phy_typec_role {
+ TYPEC_PHY_USB = 0,
+ TYPEC_PHY_DP,
+ TYPEC_PHY_MAX,
+};
+
+enum phy_dp_power_state {
+ PHY_DP_POWER_STATE_A0 = 0,
+ PHY_DP_POWER_STATE_A1,
+ PHY_DP_POWER_STATE_A2,
+ PHY_DP_POWER_STATE_A3,
+};
+
struct usb3phy_reg {
u32 offset;
u32 enable_bit;
@@ -372,18 +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_STATE_MASK;
+ reg |= sts;
+ writel(reg, tcphy->base + DP_MODE_CTL);
+
+ ret = readl_poll_timeout(tcphy->base + DP_MODE_CTL,
+ ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >>
+ PHY_DP_POWER_STATE_ACK_SHIFT) == sts), 10,
+ PHY_MODE_SET_TIMEOUT);
+ if (ret < 0) {
+ dev_err(tcphy->dev, "failed to enter power state %d\n", state);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * For the TypeC PHY, the 4 lanes are mapping to the USB TypeC receptacle pins
+ * as follows:
+ * -------------------------------------------------------------------
+ * PHY Lanes/Module Pins TypeC Receptacle Pins
+ * -------------------------------------------------------------------
+ * Lane0 (tx_p/m_ln_0) TX1+/TX1- (pins A2/A3)
+ * Lane1 (tx_rx_p/m_ln_1) RX1+/RX1- (pins B11/B10)
+ * Lane2 (tx_rx_p/m_ln_2) RX2+/RX2- (pins A11/A10)
+ * Lane3 (tx_p/m_ln_3) TX2+/TX2- (pins B2/B3)
+ * -------------------------------------------------------------------
+ *
+ * USB and DP lanes mapping to TypeC PHY lanes for each of pin assignment
+ * options (normal connector orientation) described in the VESA DisplayPort
+ * Alt Mode on USB TypeC Standard as follows:
+ *
+ * ----------------------------------------------------------------------
+ * PHY Lanes A B C D E F
+ * ----------------------------------------------------------------------
+ * 0 ML1 SSTX ML2 SSTX ML2 SSTX
+ * 1 ML3 SSRX ML3 SSRX ML3 SSRX
+ * 2 ML2 ML1 ML0 ML0 ML0 ML0
+ * 3 ML0 ML0 ML1 ML1 ML1 ML1
+ * ----------------------------------------------------------------------
+ */
+static void tcphy_set_lane_mapping(struct rockchip_typec_phy *tcphy, u8 mode)
+{
+ /*
+ * The PMA_LANE_CFG register is used to select whether a PMA lane
+ * is mapped for USB or PHY DP. The PMA_LANE_CFG register is
+ * configured based on a normal connector orientation. Logic in the
+ * PHY automatically handles the flipped connector case based on the
+ * setting of orientation of TypeC PHY.
+ */
+ if (mode == MODE_DFP_DP) {
+ /* This maps to VESA DP Alt Mode pin assignments C and E. */
+ writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+ PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+ PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE1_DP_LANE_SEL(PHY_DP_LANE_3) |
+ PMA_LANE1_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE0_DP_LANE_SEL(PHY_DP_LANE_2) |
+ PMA_LANE0_INTERFACE_SEL(PMA_IF_PHY_DP),
+ tcphy->base + PMA_LANE_CFG);
+ } else {
+ /* This maps to VESA DP Alt Mode pin assignments D and F. */
+ writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+ PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+ PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+ PMA_LANE1_INTERFACE_SEL(PMA_IF_PIPE_PCS) |
+ PMA_LANE0_INTERFACE_SEL(PMA_IF_PIPE_PCS),
+ tcphy->base + PMA_LANE_CFG);
+ }
+}
+
static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
{
u32 i, rdata;
@@ -743,8 +885,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
tcphy_dp_aux_set_flip(tcphy);
tcphy_cfg_24m(tcphy);
+ tcphy_set_lane_mapping(tcphy, mode);
if (mode == MODE_DFP_DP) {
+ tcphy_cfg_usb3_to_usb2_only(tcphy, true);
tcphy_cfg_dp_pll(tcphy);
for (i = 0; i < 4; i++)
tcphy_dp_cfg_lane(tcphy, i);
@@ -768,7 +912,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
}
- writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+ val = readl(tcphy->base + DP_MODE_CTL);
+ val &= ~DP_MODE_MASK;
+ val |= DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED;
+ writel(val, tcphy->base + DP_MODE_CTL);
reset_control_deassert(tcphy->uphy_rst);
@@ -811,8 +958,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
u8 mode;
int ret, ufp, dp;
+ /* If extcon not exist, try to use tcpm mode */
if (!edev)
- return MODE_DFP_USB;
+ return tcphy->new_mode;
ufp = extcon_get_state(edev, EXTCON_USB);
dp = extcon_get_state(edev, EXTCON_DISP_DP);
@@ -850,6 +998,71 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
return mode;
}
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_orien_sw_set(struct typec_switch_dev *sw,
+ enum typec_orientation orien)
+{
+ struct rockchip_typec_phy *tcphy = typec_switch_get_drvdata(sw);
+
+ mutex_lock(&tcphy->lock);
+
+ if (orien == TYPEC_ORIENTATION_NONE) {
+ tcphy->new_mode = MODE_DISCONNECT;
+ goto unlock_ret;
+ }
+
+ tcphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
+
+unlock_ret:
+ mutex_unlock(&tcphy->lock);
+ return 0;
+}
+
+static void udphy_orien_switch_unregister(void *data)
+{
+ struct rockchip_typec_phy *tcphy = data;
+
+ typec_switch_unregister(tcphy->sw);
+}
+
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+ struct typec_switch_desc sw_desc = { };
+ struct device_node *np;
+ int ret = 0;
+
+ np = of_get_child_by_name(tcphy->dev->of_node, "usb3-port");
+ if (!np)
+ return 0;
+
+ if (!of_property_read_bool(np, "orientation-switch"))
+ goto put_np;
+
+ sw_desc.drvdata = tcphy;
+ sw_desc.fwnode = device_get_named_child_node(tcphy->dev, "usb3-port");
+ sw_desc.set = tcphy_orien_sw_set;
+
+ tcphy->sw = typec_switch_register(tcphy->dev, &sw_desc);
+ if (IS_ERR(tcphy->sw)) {
+ dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n",
+ PTR_ERR(tcphy->sw));
+ ret = PTR_ERR(tcphy->sw);
+ goto put_np;
+ }
+
+ ret = devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregister, tcphy);
+
+put_np:
+ of_node_put(np);
+ return ret;
+}
+#else
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+ return 0;
+}
+#endif
+
static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
bool value)
{
@@ -989,14 +1202,9 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
tcphy_dp_aux_calibration(tcphy);
- writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
-
- ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
- val, val & DP_MODE_A0, 1000,
- PHY_MODE_SET_TIMEOUT);
- if (ret < 0) {
- writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
- dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
+ ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A0);
+ if (ret) {
+ dev_err(tcphy->dev, "failed to enter A0 power state\n");
goto power_on_finish;
}
@@ -1013,6 +1221,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
static int rockchip_dp_phy_power_off(struct phy *phy)
{
struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
+ int ret;
mutex_lock(&tcphy->lock);
@@ -1021,7 +1230,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
tcphy->mode &= ~MODE_DFP_DP;
- writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+ ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A2);
+ if (ret) {
+ dev_err(tcphy->dev, "failed to enter A2 power state\n");
+ goto unlock;
+ }
if (tcphy->mode == MODE_DISCONNECT)
tcphy_phy_deinit(tcphy);
@@ -1037,6 +1250,93 @@ static const struct phy_ops rockchip_dp_phy_ops = {
.owner = THIS_MODULE,
};
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+{
+ struct rockchip_typec_phy *tcphy = typec_mux_get_drvdata(mux);
+ struct typec_displayport_data *data;
+ int hpd = 0;
+
+ mutex_lock(&tcphy->lock);
+
+ switch (state->mode) {
+ case TYPEC_STATE_SAFE:
+ fallthrough;
+ case TYPEC_STATE_USB:
+ tcphy->new_mode = MODE_DFP_USB;
+ phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0);
+ break;
+ case TYPEC_DP_STATE_C:
+ case TYPEC_DP_STATE_E:
+ if (state->alt->svid != USB_TYPEC_DP_SID)
+ break;
+ tcphy->new_mode = MODE_DFP_DP;
+ data = state->data;
+ hpd = !!(data->status & DP_STATUS_HPD_STATE);
+ phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0);
+ break;
+ case TYPEC_DP_STATE_D:
+ if (state->alt->svid != USB_TYPEC_DP_SID)
+ break;
+ tcphy->new_mode = MODE_DFP_DP | MODE_DFP_USB;
+ data = state->data;
+ hpd = !!(data->status & DP_STATUS_HPD_STATE);
+ phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0);
+ break;
+ default:
+ break;
+ }
+
+ mutex_unlock(&tcphy->lock);
+
+ return 0;
+}
+
+static void tcphy_typec_mux_unregister(void *data)
+{
+ struct rockchip_typec_phy *tcphy = data;
+
+ typec_mux_unregister(tcphy->mux);
+}
+
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+ struct typec_mux_desc mux_desc = {};
+ struct device_node *np;
+ int ret = 0;
+
+ np = of_get_child_by_name(tcphy->dev->of_node, "dp-port");
+ if (!np)
+ return 0;
+
+ if (!of_property_read_bool(np, "mode-switch"))
+ goto put_np;
+
+ mux_desc.drvdata = tcphy;
+ mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
+ mux_desc.set = tcphy_typec_mux_set;
+
+ tcphy->mux = typec_mux_register(tcphy->dev, &mux_desc);
+ if (IS_ERR(tcphy->mux)) {
+ dev_err(tcphy->dev, "Error register typec mux: %ld\n",
+ PTR_ERR(tcphy->mux));
+ ret = PTR_ERR(tcphy->mux);
+ goto put_np;
+ }
+
+ ret = devm_add_action_or_reset(tcphy->dev, tcphy_typec_mux_unregister, tcphy);
+
+put_np:
+ of_node_put(np);
+ return ret;
+}
+#else
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+ return 0;
+}
+#endif
+
static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
struct device *dev)
{
@@ -1095,6 +1395,25 @@ static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy)
tcphy->mode = MODE_DISCONNECT;
}
+static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy)
+{
+ int dp_lanes;
+
+ switch (tcphy->new_mode) {
+ case MODE_DFP_DP:
+ dp_lanes = 4;
+ break;
+ case MODE_DFP_DP | MODE_DFP_USB:
+ dp_lanes = 2;
+ break;
+ default:
+ dp_lanes = 0;
+ break;
+ }
+
+ return dp_lanes;
+}
+
static int rockchip_typec_phy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1142,6 +1461,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
return ret;
tcphy->dev = dev;
+ tcphy->new_mode = MODE_DFP_USB;
platform_set_drvdata(pdev, tcphy);
mutex_init(&tcphy->lock);
@@ -1151,6 +1471,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
if (IS_ERR(tcphy->extcon)) {
if (PTR_ERR(tcphy->extcon) == -ENODEV) {
tcphy->extcon = NULL;
+ dev_info(dev, "extcon not exist, try to use typec mux\n");
} else {
if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER)
dev_err(dev, "Invalid or missing extcon\n");
@@ -1158,19 +1479,34 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
}
}
+ ret = tcphy_setup_orien_switch(tcphy);
+ if (ret)
+ return ret;
+
+ ret = tcphy_setup_typec_mux(tcphy);
+ if (ret)
+ return ret;
+
pm_runtime_enable(dev);
for_each_available_child_of_node(np, child_np) {
struct phy *phy;
- if (of_node_name_eq(child_np, "dp-port"))
+ if (of_node_name_eq(child_np, "dp-port")) {
phy = devm_phy_create(dev, child_np,
&rockchip_dp_phy_ops);
- else if (of_node_name_eq(child_np, "usb3-port"))
+ if (!IS_ERR(phy)) {
+ tcphy->phys[TYPEC_PHY_DP] = phy;
+ phy_set_bus_width(phy, typec_dp_lane_get(tcphy));
+ }
+ } else if (of_node_name_eq(child_np, "usb3-port")) {
phy = devm_phy_create(dev, child_np,
&rockchip_usb3_phy_ops);
- else
+ if (!IS_ERR(phy))
+ tcphy->phys[TYPEC_PHY_USB] = phy;
+ } else {
continue;
+ }
if (IS_ERR(phy)) {
dev_err(dev, "failed to create phy: %pOFn\n",
--
2.49.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 5/9] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (3 preceding siblings ...)
2025-10-23 3:30 ` [PATCH v7 4/9] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 6/9] drm/rockchip: cdn-dp: Support handle lane info without extcon Chaoyi Chen
` (4 subsequent siblings)
9 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
device.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
(no changes since v7)
Changes in v6:
- Fix depend in Kconfig.
drivers/phy/rockchip/Kconfig | 2 +
drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index db4adc7c53da..bcb5476222fc 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC
tristate "Rockchip TYPEC PHY Driver"
depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
depends on TYPEC || TYPEC=n
+ depends on DRM || DRM=n
+ select DRM_AUX_BRIDGE if DRM_BRIDGE
select EXTCON
select GENERIC_PHY
select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 1f5b4142cbe4..748a6eb8ad95 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 <linux/auxiliary_bus.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
@@ -56,6 +57,7 @@
#include <linux/phy/phy.h>
#include <linux/usb/typec_dp.h>
#include <linux/usb/typec_mux.h>
+#include <drm/bridge/aux-bridge.h>
#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;
@@ -1299,6 +1302,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 = {};
@@ -1312,6 +1360,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
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 6/9] drm/rockchip: cdn-dp: Support handle lane info without extcon
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (4 preceding siblings ...)
2025-10-23 3:30 ` [PATCH v7 5/9] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Chaoyi Chen
` (3 subsequent siblings)
9 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
This patch add support for get PHY lane info 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 <chaoyi.chen@rock-chips.com>
---
(no changes since v5)
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
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (5 preceding siblings ...)
2025-10-23 3:30 ` [PATCH v7 6/9] drm/rockchip: cdn-dp: Support handle lane info without extcon Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 8/9] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Chaoyi Chen
` (2 subsequent siblings)
9 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs. 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 first bridge in bridge chain and DP
controller. For example, the bridge chain may be like this:
PHY aux birdge -> fsa4480 analog audio switch bridge ->
onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge
In this case, the connection relationships among the PHY aux bridge
and the DP contorller need to be described in DT.
In addition, the cdn_dp_parse_next_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. So we will try to return the cached 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 <chaoyi.chen@rock-chips.com>
---
(no changes since v7)
Changes in v6:
- Rename some variable names.
- Attach the DP bridge to the next bridge.
Changes in v5:
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.
drivers/gpu/drm/rockchip/cdn-dp-core.c | 329 ++++++++++++++++++++-----
drivers/gpu/drm/rockchip/cdn-dp-core.h | 24 +-
2 files changed, 296 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 1e27301584a4..5c0e5209d3b8 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->next_bridge_valid)
return port;
}
+
+ if (dp->next_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;
}
@@ -253,12 +267,45 @@ static const struct drm_edid *
cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)
{
struct cdn_dp_device *dp = bridge_to_dp(bridge);
- const struct drm_edid *drm_edid;
+ struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+ struct cdn_dp_port *port = dp->port[dp_bridge->id];
+ struct cdn_dp_port *prev_port;
+ const struct drm_edid *drm_edid = NULL;
+ int i, ret;
mutex_lock(&dp->lock);
+
+ /* More than one port is available */
+ if (dp->bridge_count > 1 && !port->phy_enabled) {
+ for (i = 0; i < dp->bridge_count; i++) {
+ /* Another port already enable */
+ if (dp->bridge_list[i] != dp_bridge && dp->bridge_list[i]->enabled)
+ goto get_cache;
+ /* Find already enabled port */
+ if (dp->port[i]->phy_enabled)
+ prev_port = dp->port[i];
+ }
+
+ /* Switch to current port */
+ if (prev_port) {
+ ret = cdn_dp_switch_port(dp, prev_port, port);
+ if (ret)
+ goto get_cache;
+ }
+ }
+
drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
+ /* replace edid cache */
+ if (dp->edid_cache[dp_bridge->id])
+ drm_edid_free(dp->edid_cache[dp_bridge->id]);
+ dp->edid_cache[dp_bridge->id] = drm_edid_dup(drm_edid);
+
mutex_unlock(&dp->lock);
+ return drm_edid;
+get_cache:
+ drm_edid = drm_edid_dup(dp->edid_cache[dp_bridge->id]);
+ mutex_unlock(&dp->lock);
return drm_edid;
}
@@ -267,12 +314,13 @@ 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_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;
/* If DP is disconnected, every mode is invalid */
- if (!dp->connected)
+ if (!dp_bridge->connected || !dp->connected)
return MODE_BAD;
switch (display_info->bpc) {
@@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
}
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
+ struct cdn_dp_port *port)
+{
+ int ret;
+
+ if (dp->active)
+ return 0;
+
+ ret = cdn_dp_disable_phy(dp, prev_port);
+ if (ret)
+ goto out;
+ ret = cdn_dp_enable_phy(dp, port);
+ if (ret)
+ goto out;
+
+ ret = cdn_dp_get_sink_capability(dp);
+ if (ret) {
+ cdn_dp_disable_phy(dp, port);
+ goto out;
+ }
+
+ dp->active = true;
+ dp->lanes = port->lanes;
+
+ if (!cdn_dp_check_link_status(dp)) {
+ dev_info(dp->dev, "Connected with sink; re-train link\n");
+
+ ret = cdn_dp_train_link(dp);
+ if (ret) {
+ dev_err(dp->dev, "Training link failed: %d\n", ret);
+ goto out;
+ }
+
+ ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+ if (ret) {
+ dev_err(dp->dev, "Failed to idle video %d\n", ret);
+ goto out;
+ }
+
+ ret = cdn_dp_config_video(dp);
+ if (ret)
+ dev_err(dp->dev, "Failed to configure video: %d\n", ret);
+ }
+
+out:
+ return ret;
+}
+
static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
struct drm_display_info *display_info)
{
@@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)
{
struct cdn_dp_device *dp = bridge_to_dp(bridge);
+ struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
struct drm_connector *connector;
int ret, val;
@@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
cdn_dp_display_info_update(dp, &connector->display_info);
- ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.encoder);
+ ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->encoder.encoder);
if (ret < 0) {
DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
return;
@@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
mutex_lock(&dp->lock);
+ if (dp->next_bridge_valid)
+ dp->active_port = dp_bridge->id;
+
ret = cdn_dp_enable(dp);
if (ret) {
DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n",
@@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
goto out;
}
+ dp_bridge->enabled = true;
out:
mutex_unlock(&dp->lock);
}
@@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)
{
struct cdn_dp_device *dp = bridge_to_dp(bridge);
+ struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
int ret;
mutex_lock(&dp->lock);
+ dp_bridge->enabled = false;
if (dp->active) {
ret = cdn_dp_disable(dp);
@@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge *bridge,
return ret;
}
+static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge,
+ enum drm_connector_status status)
+{
+ struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+ struct cdn_dp_device *dp = bridge_to_dp(bridge);
+
+ dp->bridge_list[dp_bridge->id]->connected = status == connector_status_connected;
+ 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,
@@ -837,6 +950,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_bridge_hpd_notify,
.dp_audio_prepare = cdn_dp_audio_prepare,
.dp_audio_mute_stream = cdn_dp_audio_mute_stream,
@@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
{
struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
event_work);
- int ret;
+ bool connected;
+ int i, ret;
mutex_lock(&dp->lock);
@@ -944,9 +1059,12 @@ 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);
+ for (i = 0; i < dp->bridge_count; i++) {
+ connected = dp->connected && dp->bridge_list[i]->connected;
+ drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge,
+ connected ? connector_status_connected
+ : connector_status_disconnected);
+ }
}
static int cdn_dp_pd_event(struct notifier_block *nb,
@@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
return NOTIFY_DONE;
}
-static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+static int cdn_bridge_add(struct device *dev,
+ struct drm_bridge *bridge,
+ struct drm_bridge *next_bridge,
+ struct drm_encoder *encoder)
{
struct cdn_dp_device *dp = dev_get_drvdata(dev);
- struct drm_encoder *encoder;
+ struct drm_device *drm_dev = dp->drm_dev;
+ struct drm_bridge *last_bridge = NULL;
struct drm_connector *connector;
- struct cdn_dp_port *port;
- struct drm_device *drm_dev = data;
- int ret, i;
-
- ret = cdn_dp_parse_dt(dp);
- if (ret < 0)
- return ret;
-
- dp->drm_dev = drm_dev;
- dp->connected = false;
- dp->active = false;
- dp->active_port = -1;
- dp->fw_loaded = false;
-
- INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
-
- encoder = &dp->encoder.encoder;
+ int ret;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
dev->of_node);
@@ -1002,26 +1108,38 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
- 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);
+
+ bridge->ops =
+ DRM_BRIDGE_OP_DETECT |
+ DRM_BRIDGE_OP_EDID |
+ DRM_BRIDGE_OP_HPD |
+ DRM_BRIDGE_OP_DP_AUDIO;
+ bridge->of_node = dp->dev->of_node;
+ bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
+ bridge->hdmi_audio_dev = dp->dev;
+ bridge->hdmi_audio_max_i2s_playback_channels = 8;
+ bridge->hdmi_audio_spdif_playback = 1;
+ bridge->hdmi_audio_dai_port = -1;
+
+ ret = devm_drm_bridge_add(dev, bridge);
if (ret)
return ret;
- ret = drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret)
return ret;
+ if (next_bridge) {
+ ret = drm_bridge_attach(encoder, next_bridge, bridge,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ if (ret)
+ return ret;
+
+ last_bridge = next_bridge;
+ while (drm_bridge_get_next_bridge(last_bridge))
+ last_bridge = drm_bridge_get_next_bridge(last_bridge);
+ }
+
connector = drm_bridge_connector_init(drm_dev, encoder);
if (IS_ERR(connector)) {
ret = PTR_ERR(connector);
@@ -1029,8 +1147,102 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
return ret;
}
+ if (last_bridge)
+ connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
+
drm_connector_attach_encoder(connector, encoder);
+ return 0;
+}
+
+static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
+{
+ struct device_node *np = dp->dev->of_node;
+ struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
+ struct drm_bridge *bridge;
+ int count = 0;
+ int ret = 0;
+ int i;
+
+ /* If device use extcon, do not use hpd bridge */
+ for (i = 0; i < dp->ports; i++) {
+ if (dp->port[i]->extcon) {
+ dp->bridge_count = 1;
+ return 0;
+ }
+ }
+
+
+ /* One endpoint may correspond to one next bridge. */
+ for_each_of_graph_port_endpoint(port, dp_ep) {
+ struct device_node *next_bridge_node __free(device_node) =
+ of_graph_get_remote_port_parent(dp_ep);
+
+ bridge = of_drm_find_bridge(next_bridge_node);
+ if (!bridge) {
+ ret = -EPROBE_DEFER;
+ goto out;
+ }
+
+ dp->next_bridge_valid = true;
+ dp->next_bridge_list[count].bridge = bridge;
+ dp->next_bridge_list[count].parent = dp;
+ dp->next_bridge_list[count].id = count;
+ count++;
+ }
+
+out:
+ dp->bridge_count = count ? count : 1;
+ return ret;
+}
+
+static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+{
+ struct cdn_dp_device *dp = dev_get_drvdata(dev);
+ struct drm_bridge *bridge, *next_bridge;
+ struct drm_encoder *encoder;
+ struct cdn_dp_port *port;
+ struct drm_device *drm_dev = data;
+ struct cdn_dp_bridge *dp_bridge;
+ int ret, i;
+
+ ret = cdn_dp_parse_dt(dp);
+ if (ret < 0)
+ return ret;
+
+ ret = cdn_dp_parse_next_bridge_dt(dp);
+ if (ret)
+ return ret;
+
+ dp->drm_dev = drm_dev;
+ dp->connected = false;
+ dp->active = false;
+ dp->active_port = -1;
+ dp->fw_loaded = false;
+
+ for (i = 0; i < dp->bridge_count; i++) {
+ dp_bridge = devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge,
+ &cdn_dp_bridge_funcs);
+ if (IS_ERR(dp_bridge))
+ return PTR_ERR(dp_bridge);
+ dp_bridge->id = i;
+ dp_bridge->parent = dp;
+ if (!dp->next_bridge_valid)
+ dp_bridge->connected = true;
+ dp->bridge_list[i] = dp_bridge;
+ }
+
+ for (i = 0; i < dp->bridge_count; i++) {
+ encoder = &dp->bridge_list[i]->encoder.encoder;
+ bridge = &dp->bridge_list[i]->bridge;
+ next_bridge = dp->next_bridge_list[i].bridge;
+ ret = cdn_bridge_add(dev, bridge, next_bridge, encoder);
+ if (ret)
+ return ret;
+ }
+
+ INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
+
for (i = 0; i < dp->ports; i++) {
port = dp->port[i];
@@ -1058,10 +1270,17 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
static void cdn_dp_unbind(struct device *dev, struct device *master, void *data)
{
struct cdn_dp_device *dp = dev_get_drvdata(dev);
- struct drm_encoder *encoder = &dp->encoder.encoder;
+ struct drm_encoder *encoder;
+ int i;
cancel_work_sync(&dp->event_work);
- encoder->funcs->destroy(encoder);
+ for (i = 0; i < dp->bridge_count; i++) {
+ encoder = &dp->bridge_list[i]->encoder.encoder;
+ encoder->funcs->destroy(encoder);
+ }
+
+ for (i = 0; i < MAX_PHY; i++)
+ drm_edid_free(dp->edid_cache[i]);
pm_runtime_disable(dev);
if (dp->fw_loaded)
@@ -1112,10 +1331,10 @@ static int cdn_dp_probe(struct platform_device *pdev)
int ret;
int i;
- dp = devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge,
- &cdn_dp_bridge_funcs);
- if (IS_ERR(dp))
- return PTR_ERR(dp);
+ dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+ if (!dp)
+ return -ENOMEM;
+
dp->dev = dev;
match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node);
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index e9c30b9fd543..ce1707a5c746 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -38,6 +38,8 @@ enum vic_pxl_encoding_format {
Y_ONLY = 0x10,
};
+struct cdn_dp_device;
+
struct video_info {
bool h_sync_polarity;
bool v_sync_polarity;
@@ -63,16 +65,34 @@ struct cdn_dp_port {
u8 id;
};
+struct cdn_dp_bridge {
+ struct cdn_dp_device *parent;
+ struct drm_bridge bridge;
+ struct rockchip_encoder encoder;
+ bool connected;
+ bool enabled;
+ int id;
+};
+
+struct cdn_dp_next_bridge {
+ struct cdn_dp_device *parent;
+ struct drm_bridge *bridge;
+ int id;
+};
+
struct cdn_dp_device {
struct device *dev;
struct drm_device *drm_dev;
- struct drm_bridge bridge;
- struct rockchip_encoder encoder;
+ int bridge_count;
+ struct cdn_dp_bridge *bridge_list[MAX_PHY];
+ struct cdn_dp_next_bridge next_bridge_list[MAX_PHY];
+ const struct drm_edid *edid_cache[MAX_PHY];
struct drm_display_mode mode;
struct platform_device *audio_pdev;
struct work_struct event_work;
struct mutex lock;
+ bool next_bridge_valid;
bool connected;
bool active;
bool suspended;
--
2.49.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 8/9] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (6 preceding siblings ...)
2025-10-23 3:30 ` [PATCH v7 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 9/9] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
2025-10-23 13:52 ` [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Rob Herring (Arm)
9 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Let's make the ports nodes of cdn_dp in the same style as the other
display interface, and match the style of ports's yaml.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
(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@fec00000 {
status = "disabled";
ports {
- dp_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dp_in: port@0 {
+ reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
@@ -632,6 +636,10 @@ dp_in_vopl: endpoint@1 {
remote-endpoint = <&vopl_out_dp>;
};
};
+
+ dp_out: port@1 {
+ reg = <1>;
+ };
};
};
--
2.49.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH v7 9/9] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (7 preceding siblings ...)
2025-10-23 3:30 ` [PATCH v7 8/9] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Chaoyi Chen
@ 2025-10-23 3:30 ` Chaoyi Chen
2025-10-23 13:52 ` [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Rob Herring (Arm)
9 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 3:30 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Dmitry Baryshkov,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson
Cc: linux-usb, devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
The RK3399 EVB IND board has a Type-C interface DisplayPort.
It use fusb302 chip as Type-C controller.
fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
(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..aeeee6bd2973 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
@@ -4,6 +4,7 @@
*/
/dts-v1/;
+#include <dt-bindings/usb/pd.h>
#include "rk3399.dtsi"
/ {
@@ -19,6 +20,21 @@ chosen {
stdout-path = "serial2:1500000n8";
};
+ sound: sound {
+ compatible = "rockchip,rk3399-gru-sound";
+ rockchip,cpu = <&i2s0 &spdif>;
+ };
+
+ vbus_typec: regulator-vbus-typec {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_typec0_en>;
+ regulator-name = "vbus_typec";
+ vin-supply = <&vcc5v0_sys>;
+ };
+
vcc5v0_sys: regulator-vcc5v0-sys {
compatible = "regulator-fixed";
enable-active-high;
@@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys {
};
};
+&cdn_dp {
+ phys = <&tcphy0_dp>;
+ status = "okay";
+};
+
&cpu_b0 {
cpu-supply = <&vdd_cpu_b>;
};
@@ -55,6 +76,12 @@ &cpu_l3 {
cpu-supply = <&vdd_cpu_l>;
};
+&dp_out {
+ dp_controller_output: endpoint {
+ remote-endpoint = <&dp_phy_in>;
+ };
+};
+
&emmc_phy {
status = "okay";
};
@@ -341,6 +368,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 = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbc0_int>;
+ vbus-supply = <&vbus_typec>;
+
+ usb_con: connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "dual";
+ power-role = "dual";
+ try-power-role = "sink";
+ op-sink-microwatt = <1000000>;
+ sink-pdos =
+ <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
+ source-pdos =
+ <PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
+
+ altmodes {
+ displayport {
+ svid = /bits/ 16 <0xff01>;
+ vdo = <0x00001c46>;
+ };
+ };
+
+ 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 {
+ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ vcc5v0_typec0_en: vcc5v0-typec0-en {
+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -400,10 +502,48 @@ &sdmmc {
status = "okay";
};
+&sound {
+ rockchip,codec = <&cdn_dp>;
+ status = "okay";
+};
+
+&spdif {
+ status = "okay";
+};
+
&tcphy0 {
status = "okay";
};
+&tcphy0_dp {
+ mode-switch;
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tcphy0_typec_dp: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usbc_dp>;
+ };
+
+ dp_phy_in: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dp_controller_output>;
+ };
+ };
+};
+
+&tcphy0_usb3 {
+ orientation-switch;
+
+ port {
+ tcphy0_typec_ss: endpoint {
+ remote-endpoint = <&usbc_ss>;
+ };
+ };
+};
+
&tcphy1 {
status = "okay";
};
@@ -418,6 +558,12 @@ &tsadc {
&u2phy0 {
status = "okay";
+
+ port {
+ u2phy0_typec_hs: endpoint {
+ remote-endpoint = <&usbc_hs>;
+ };
+ };
};
&u2phy0_host {
--
2.49.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 3:30 ` [PATCH v7 1/9] usb: typec: Add notifier functions Chaoyi Chen
@ 2025-10-23 8:10 ` Heikki Krogerus
2025-10-23 9:04 ` Heikki Krogerus
2025-10-24 8:16 ` Heikki Krogerus
1 sibling, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-23 8:10 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
Hi,
> diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
> new file mode 100644
> index 000000000000..a3f1f3b3ae47
> --- /dev/null
> +++ b/include/linux/usb/typec_notify.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __USB_TYPEC_NOTIFY
> +#define __USB_TYPEC_NOTIFY
> +
> +#include <linux/notifier.h>
> +
> +enum usb_typec_event {
> + TYPEC_ALTMODE_REGISTERED
> +};
Don't you need to know when the altmode is removed?
> +
> +int typec_register_notify(struct notifier_block *nb);
> +int typec_unregister_notify(struct notifier_block *nb);
> +
> +void typec_notify_event(unsigned long event, void *data);
Declare typec_notify_event() in drivers/usb/typec/bus.h
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-23 3:30 ` [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge Chaoyi Chen
@ 2025-10-23 8:45 ` Heikki Krogerus
2025-10-23 11:29 ` Chaoyi Chen
2025-10-24 8:01 ` Heikki Krogerus
1 sibling, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-23 8:45 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
On Thu, Oct 23, 2025 at 11:30:02AM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>
> Several USB-C controller drivers have already implemented the DP HPD
> bridge function provided by aux-hpd-bridge.c, but there are still
> some USB-C controller driver that have not yet implemented it.
>
> This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c,
> so that other USB-C controller drivers don't need to implement it again.
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
> ---
> drivers/gpu/drm/bridge/Kconfig | 11 ++++
> drivers/gpu/drm/bridge/Makefile | 1 +
> .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 51 +++++++++++++++++++
> 3 files changed, 63 insertions(+)
> create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index b9e0ca85226a..9f31540d3ad8 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -33,6 +33,17 @@ config DRM_AUX_HPD_BRIDGE
> menu "Display Interface Bridges"
> depends on DRM && DRM_BRIDGE
>
> +config DRM_AUX_TYPEC_DP_HPD_BRIDGE
> + tristate "TypeC DP HPD bridge"
> + depends on DRM_BRIDGE && OF && TYPEC
> + select DRM_AUX_HPD_BRIDGE
> + help
> + Simple USB Type-C DP bridge that terminates the bridge chain and
> + provides HPD support.
> +
> + If the USB-C controller driver has not implemented this and you need
> + the DP HPD support, say "Y" or "m" here.
You don't need to depend on DRM_BRIDGE separately, but do you really
need a separate module for this in the first place?
> config DRM_CHIPONE_ICN6211
> tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge"
> depends on OF
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 245e8a27e3fc..e91736829167 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -1,6 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
> obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
> +obj-$(CONFIG_DRM_AUX_TYPEC_DP_HPD_BRIDGE) += aux-hpd-typec-dp-bridge.o
Instead, why not just make that a part of aux-hpd-bridge
conditionally:
ifneq ($(CONFIG_TYPEC),)
aux-hpd-bridge-y += aux-hpd-typec-dp-bridge.o
endif
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 8:10 ` Heikki Krogerus
@ 2025-10-23 9:04 ` Heikki Krogerus
2025-10-23 9:44 ` Heikki Krogerus
0 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-23 9:04 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
On Thu, Oct 23, 2025 at 11:10:20AM +0300, Heikki Krogerus wrote:
> Hi,
>
> > diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
> > new file mode 100644
> > index 000000000000..a3f1f3b3ae47
> > --- /dev/null
> > +++ b/include/linux/usb/typec_notify.h
> > @@ -0,0 +1,17 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +#ifndef __USB_TYPEC_NOTIFY
> > +#define __USB_TYPEC_NOTIFY
> > +
> > +#include <linux/notifier.h>
> > +
> > +enum usb_typec_event {
> > + TYPEC_ALTMODE_REGISTERED
> > +};
>
> Don't you need to know when the altmode is removed?
I noticed that you don't because drm_dp_hpd_bridge_register() is
always resource managed. But I think you could still send an event
also when the altmode is removed already now. That way it does not
need to be separately added if and when it is needed.
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 9:04 ` Heikki Krogerus
@ 2025-10-23 9:44 ` Heikki Krogerus
2025-10-23 11:21 ` Chaoyi Chen
2025-10-24 2:54 ` Chaoyi Chen
0 siblings, 2 replies; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-23 9:44 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
On Thu, Oct 23, 2025 at 12:04:44PM +0300, Heikki Krogerus wrote:
> On Thu, Oct 23, 2025 at 11:10:20AM +0300, Heikki Krogerus wrote:
> > Hi,
> >
> > > diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
> > > new file mode 100644
> > > index 000000000000..a3f1f3b3ae47
> > > --- /dev/null
> > > +++ b/include/linux/usb/typec_notify.h
> > > @@ -0,0 +1,17 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +
> > > +#ifndef __USB_TYPEC_NOTIFY
> > > +#define __USB_TYPEC_NOTIFY
> > > +
> > > +#include <linux/notifier.h>
> > > +
> > > +enum usb_typec_event {
> > > + TYPEC_ALTMODE_REGISTERED
> > > +};
> >
> > Don't you need to know when the altmode is removed?
>
> I noticed that you don't because drm_dp_hpd_bridge_register() is
> always resource managed. But I think you could still send an event
> also when the altmode is removed already now. That way it does not
> need to be separately added if and when it is needed.
Hold on! Every bus has already a notifier chain. That's the one that
we should also use. Sorry for not noticing that earlier.
So let's just export the bus type in this patch - you can then use
bus_register_notifier() in your driver:
diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index a884cec9ab7e..65ded9e3cdaa 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -547,3 +547,4 @@ const struct bus_type typec_bus = {
.probe = typec_probe,
.remove = typec_remove,
};
+EXPORT_SYMBOL_GPL(typec_bus);
diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index 643b8c81786d..af9edb3db9d0 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -5,7 +5,6 @@
#include <linux/usb/typec_altmode.h>
-struct bus_type;
struct typec_mux;
struct typec_retimer;
@@ -28,7 +27,6 @@ struct altmode {
#define to_altmode(d) container_of(d, struct altmode, adev)
-extern const struct bus_type typec_bus;
extern const struct device_type typec_altmode_dev_type;
#define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 309251572e2e..c6fd46902fce 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -20,12 +20,15 @@ struct typec_port;
struct typec_altmode_ops;
struct typec_cable_ops;
+struct bus_type;
struct fwnode_handle;
struct device;
struct usb_power_delivery;
struct usb_power_delivery_desc;
+extern const struct bus_type typec_bus;
+
enum typec_port_type {
TYPEC_PORT_SRC,
TYPEC_PORT_SNK,
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 9:44 ` Heikki Krogerus
@ 2025-10-23 11:21 ` Chaoyi Chen
2025-10-23 11:29 ` Greg Kroah-Hartman
2025-10-23 11:36 ` Heikki Krogerus
2025-10-24 2:54 ` Chaoyi Chen
1 sibling, 2 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 11:21 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
Hi Heikki,
On 10/23/2025 5:44 PM, Heikki Krogerus wrote:
> On Thu, Oct 23, 2025 at 12:04:44PM +0300, Heikki Krogerus wrote:
>> On Thu, Oct 23, 2025 at 11:10:20AM +0300, Heikki Krogerus wrote:
>>> Hi,
>>>
>>>> diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
>>>> new file mode 100644
>>>> index 000000000000..a3f1f3b3ae47
>>>> --- /dev/null
>>>> +++ b/include/linux/usb/typec_notify.h
>>>> @@ -0,0 +1,17 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>> +
>>>> +#ifndef __USB_TYPEC_NOTIFY
>>>> +#define __USB_TYPEC_NOTIFY
>>>> +
>>>> +#include <linux/notifier.h>
>>>> +
>>>> +enum usb_typec_event {
>>>> + TYPEC_ALTMODE_REGISTERED
>>>> +};
>>> Don't you need to know when the altmode is removed?
>> I noticed that you don't because drm_dp_hpd_bridge_register() is
>> always resource managed. But I think you could still send an event
>> also when the altmode is removed already now. That way it does not
>> need to be separately added if and when it is needed.
> Hold on! Every bus has already a notifier chain. That's the one that
> we should also use. Sorry for not noticing that earlier.
>
> So let's just export the bus type in this patch - you can then use
> bus_register_notifier() in your driver:
>
> diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
> index a884cec9ab7e..65ded9e3cdaa 100644
> --- a/drivers/usb/typec/bus.c
> +++ b/drivers/usb/typec/bus.c
> @@ -547,3 +547,4 @@ const struct bus_type typec_bus = {
> .probe = typec_probe,
> .remove = typec_remove,
> };
> +EXPORT_SYMBOL_GPL(typec_bus);
> diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
> index 643b8c81786d..af9edb3db9d0 100644
> --- a/drivers/usb/typec/bus.h
> +++ b/drivers/usb/typec/bus.h
> @@ -5,7 +5,6 @@
>
> #include <linux/usb/typec_altmode.h>
>
> -struct bus_type;
> struct typec_mux;
> struct typec_retimer;
>
> @@ -28,7 +27,6 @@ struct altmode {
>
> #define to_altmode(d) container_of(d, struct altmode, adev)
>
> -extern const struct bus_type typec_bus;
> extern const struct device_type typec_altmode_dev_type;
>
> #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
> diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
> index 309251572e2e..c6fd46902fce 100644
> --- a/include/linux/usb/typec.h
> +++ b/include/linux/usb/typec.h
> @@ -20,12 +20,15 @@ struct typec_port;
> struct typec_altmode_ops;
> struct typec_cable_ops;
>
> +struct bus_type;
> struct fwnode_handle;
> struct device;
>
> struct usb_power_delivery;
> struct usb_power_delivery_desc;
>
> +extern const struct bus_type typec_bus;
> +
> enum typec_port_type {
> TYPEC_PORT_SRC,
> TYPEC_PORT_SNK,
Thank you for your detailed explanation. I noticed that there is a device_register() action in typec_register_altmode(), so we can just take advantage of this.
Another thing is that we need to distinguish between different devices in the notifier callback, as typec_register_altmode()/typec_register_partner()/typec_register_plug()/typec_register_cable() may all register devices. Since the data passed in bus_notify() is struct device *dev, I think we can distinguish them through `dev->type.name`? We may already have such names, "typec_alternate_mode", "typec_partner", "typec_plug" in class.c . And then extract these names as macros and put them in the typec header file.
Or do you have any better ideas? Thank you.
> thanks,
>
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-23 8:45 ` Heikki Krogerus
@ 2025-10-23 11:29 ` Chaoyi Chen
2025-10-23 12:03 ` Heikki Krogerus
0 siblings, 1 reply; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 11:29 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
Hi Heikki,
On 10/23/2025 4:45 PM, Heikki Krogerus wrote:
> On Thu, Oct 23, 2025 at 11:30:02AM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>>
>> Several USB-C controller drivers have already implemented the DP HPD
>> bridge function provided by aux-hpd-bridge.c, but there are still
>> some USB-C controller driver that have not yet implemented it.
>>
>> This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c,
>> so that other USB-C controller drivers don't need to implement it again.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>> ---
>> drivers/gpu/drm/bridge/Kconfig | 11 ++++
>> drivers/gpu/drm/bridge/Makefile | 1 +
>> .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 51 +++++++++++++++++++
>> 3 files changed, 63 insertions(+)
>> create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>>
>> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
>> index b9e0ca85226a..9f31540d3ad8 100644
>> --- a/drivers/gpu/drm/bridge/Kconfig
>> +++ b/drivers/gpu/drm/bridge/Kconfig
>> @@ -33,6 +33,17 @@ config DRM_AUX_HPD_BRIDGE
>> menu "Display Interface Bridges"
>> depends on DRM && DRM_BRIDGE
>>
>> +config DRM_AUX_TYPEC_DP_HPD_BRIDGE
>> + tristate "TypeC DP HPD bridge"
>> + depends on DRM_BRIDGE && OF && TYPEC
>> + select DRM_AUX_HPD_BRIDGE
>> + help
>> + Simple USB Type-C DP bridge that terminates the bridge chain and
>> + provides HPD support.
>> +
>> + If the USB-C controller driver has not implemented this and you need
>> + the DP HPD support, say "Y" or "m" here.
> You don't need to depend on DRM_BRIDGE separately, but do you really
> need a separate module for this in the first place?
>
>> config DRM_CHIPONE_ICN6211
>> tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge"
>> depends on OF
>> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
>> index 245e8a27e3fc..e91736829167 100644
>> --- a/drivers/gpu/drm/bridge/Makefile
>> +++ b/drivers/gpu/drm/bridge/Makefile
>> @@ -1,6 +1,7 @@
>> # SPDX-License-Identifier: GPL-2.0
>> obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
>> obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
>> +obj-$(CONFIG_DRM_AUX_TYPEC_DP_HPD_BRIDGE) += aux-hpd-typec-dp-bridge.o
> Instead, why not just make that a part of aux-hpd-bridge
> conditionally:
>
> ifneq ($(CONFIG_TYPEC),)
> aux-hpd-bridge-y += aux-hpd-typec-dp-bridge.o
> endif
Oh, I did consider that! But I noticed that aux-hpd-bridge.c contains the following statement module_auxiliary_driver(drm_aux_hpd_bridge_drv), which already includes a module_init. In the newly added file, in order to call the register function, another module_init was also added. If the two files are each made into a module separately, would there be a problem?
>
>
> thanks,
>
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 11:21 ` Chaoyi Chen
@ 2025-10-23 11:29 ` Greg Kroah-Hartman
2025-10-23 11:36 ` Heikki Krogerus
1 sibling, 0 replies; 32+ messages in thread
From: Greg Kroah-Hartman @ 2025-10-23 11:29 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Heikki Krogerus, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
On Thu, Oct 23, 2025 at 07:21:31PM +0800, Chaoyi Chen wrote:
> Hi Heikki,
>
> On 10/23/2025 5:44 PM, Heikki Krogerus wrote:
> > On Thu, Oct 23, 2025 at 12:04:44PM +0300, Heikki Krogerus wrote:
> > > On Thu, Oct 23, 2025 at 11:10:20AM +0300, Heikki Krogerus wrote:
> > > > Hi,
> > > >
> > > > > diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
> > > > > new file mode 100644
> > > > > index 000000000000..a3f1f3b3ae47
> > > > > --- /dev/null
> > > > > +++ b/include/linux/usb/typec_notify.h
> > > > > @@ -0,0 +1,17 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > +
> > > > > +#ifndef __USB_TYPEC_NOTIFY
> > > > > +#define __USB_TYPEC_NOTIFY
> > > > > +
> > > > > +#include <linux/notifier.h>
> > > > > +
> > > > > +enum usb_typec_event {
> > > > > + TYPEC_ALTMODE_REGISTERED
> > > > > +};
> > > > Don't you need to know when the altmode is removed?
> > > I noticed that you don't because drm_dp_hpd_bridge_register() is
> > > always resource managed. But I think you could still send an event
> > > also when the altmode is removed already now. That way it does not
> > > need to be separately added if and when it is needed.
> > Hold on! Every bus has already a notifier chain. That's the one that
> > we should also use. Sorry for not noticing that earlier.
> >
> > So let's just export the bus type in this patch - you can then use
> > bus_register_notifier() in your driver:
> >
> > diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
> > index a884cec9ab7e..65ded9e3cdaa 100644
> > --- a/drivers/usb/typec/bus.c
> > +++ b/drivers/usb/typec/bus.c
> > @@ -547,3 +547,4 @@ const struct bus_type typec_bus = {
> > .probe = typec_probe,
> > .remove = typec_remove,
> > };
> > +EXPORT_SYMBOL_GPL(typec_bus);
> > diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
> > index 643b8c81786d..af9edb3db9d0 100644
> > --- a/drivers/usb/typec/bus.h
> > +++ b/drivers/usb/typec/bus.h
> > @@ -5,7 +5,6 @@
> > #include <linux/usb/typec_altmode.h>
> > -struct bus_type;
> > struct typec_mux;
> > struct typec_retimer;
> > @@ -28,7 +27,6 @@ struct altmode {
> > #define to_altmode(d) container_of(d, struct altmode, adev)
> > -extern const struct bus_type typec_bus;
> > extern const struct device_type typec_altmode_dev_type;
> > #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
> > diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
> > index 309251572e2e..c6fd46902fce 100644
> > --- a/include/linux/usb/typec.h
> > +++ b/include/linux/usb/typec.h
> > @@ -20,12 +20,15 @@ struct typec_port;
> > struct typec_altmode_ops;
> > struct typec_cable_ops;
> > +struct bus_type;
> > struct fwnode_handle;
> > struct device;
> > struct usb_power_delivery;
> > struct usb_power_delivery_desc;
> > +extern const struct bus_type typec_bus;
> > +
> > enum typec_port_type {
> > TYPEC_PORT_SRC,
> > TYPEC_PORT_SNK,
>
> Thank you for your detailed explanation. I noticed that there is a device_register() action in typec_register_altmode(), so we can just take advantage of this.
>
>
> Another thing is that we need to distinguish between different devices in the notifier callback, as typec_register_altmode()/typec_register_partner()/typec_register_plug()/typec_register_cable() may all register devices. Since the data passed in bus_notify() is struct device *dev, I think we can distinguish them through `dev->type.name`? We may already have such names, "typec_alternate_mode", "typec_partner", "typec_plug" in class.c . And then extract these names as macros and put them in the typec header file.
>
>
> Or do you have any better ideas? Thank you.
Check based on the type itself, NOT on the type name, as all device
types on a bus should be unique. If the structure for that is not
properly exported for you to use, just export it.
thanks,
greg k-h
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 11:21 ` Chaoyi Chen
2025-10-23 11:29 ` Greg Kroah-Hartman
@ 2025-10-23 11:36 ` Heikki Krogerus
2025-10-23 11:41 ` Chaoyi Chen
1 sibling, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-23 11:36 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
> Thank you for your detailed explanation. I noticed that there is a
> device_register() action in typec_register_altmode(), so we can just take
> advantage of this.
>
> Another thing is that we need to distinguish between different devices in the
> notifier callback, as
> typec_register_altmode()/typec_register_partner()/typec_register_plug()/typec_register_cable()
> may all register devices. Since the data passed in bus_notify() is struct
> device *dev, I think we can distinguish them through `dev->type.name`? We may
> already have such names, "typec_alternate_mode", "typec_partner", "typec_plug"
> in class.c . And then extract these names as macros and put them in the typec
> header file.
You don't need to worry about that. Only partner altmodes are bind to
the bus. The device you see in the notifier will always be an altmode.
But in general, if you need to identify the device type, then
you use the device type itself, not the name of the type. It would
require that the device types are exported, but as said, you don't
need to worry about that in this case.
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 11:36 ` Heikki Krogerus
@ 2025-10-23 11:41 ` Chaoyi Chen
0 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 11:41 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
Hi Heikki,
On 10/23/2025 7:36 PM, Heikki Krogerus wrote:
>> Thank you for your detailed explanation. I noticed that there is a
>> device_register() action in typec_register_altmode(), so we can just take
>> advantage of this.
>>
>> Another thing is that we need to distinguish between different devices in the
>> notifier callback, as
>> typec_register_altmode()/typec_register_partner()/typec_register_plug()/typec_register_cable()
>> may all register devices. Since the data passed in bus_notify() is struct
>> device *dev, I think we can distinguish them through `dev->type.name`? We may
>> already have such names, "typec_alternate_mode", "typec_partner", "typec_plug"
>> in class.c . And then extract these names as macros and put them in the typec
>> header file.
> You don't need to worry about that. Only partner altmodes are bind to
> the bus. The device you see in the notifier will always be an altmode.
>
> But in general, if you need to identify the device type, then
> you use the device type itself, not the name of the type. It would
> require that the device types are exported, but as said, you don't
> need to worry about that in this case.
Very insightful! I will try to do this in v8 :)
>
> thanks,
>
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-23 11:29 ` Chaoyi Chen
@ 2025-10-23 12:03 ` Heikki Krogerus
2025-10-23 12:10 ` Chaoyi Chen
0 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-23 12:03 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
> > > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> > > index 245e8a27e3fc..e91736829167 100644
> > > --- a/drivers/gpu/drm/bridge/Makefile
> > > +++ b/drivers/gpu/drm/bridge/Makefile
> > > @@ -1,6 +1,7 @@
> > > # SPDX-License-Identifier: GPL-2.0
> > > obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
> > > obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
> > > +obj-$(CONFIG_DRM_AUX_TYPEC_DP_HPD_BRIDGE) += aux-hpd-typec-dp-bridge.o
> > Instead, why not just make that a part of aux-hpd-bridge
> > conditionally:
> >
> > ifneq ($(CONFIG_TYPEC),)
> > aux-hpd-bridge-y += aux-hpd-typec-dp-bridge.o
> > endif
>
> Oh, I did consider that! But I noticed that aux-hpd-bridge.c contains the
> following statement module_auxiliary_driver(drm_aux_hpd_bridge_drv), which
> already includes a module_init. In the newly added file, in order to call the
> register function, another module_init was also added. If the two files are
> each made into a module separately, would there be a problem?
You would not call module_init() from the new file. Instead you would
call drm_aux_hpd_typec_dp_bridge_init() and what ever directly from
aux-hpd-bridge.c:
diff --git a/drivers/gpu/drm/bridge/aux-bridge.h b/drivers/gpu/drm/bridge/aux-bridge.h
new file mode 100644
index 000000000000..ae689a7778fa
--- /dev/null
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef AUX_HPD_BRIDGE_H
+#define AUX_HPD_BRIDGE_H
+
+#if IS_ENABLED(CONFIG_TYPEC)
+int drm_aux_hpd_typec_dp_bridge_init(void);
+void drm_aux_hpd_typec_dp_bridge_exit(void);
+#else
+static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; }
+static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { }
+#endif /* IS_ENABLED(CONFIG_TYPEC) */
+
+#endif /* AUX_HPD_BRIDGE_H */
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index 2e9c702c7087..3578df1df78a 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -12,6 +12,8 @@
#include <drm/drm_bridge.h>
#include <drm/bridge/aux-bridge.h>
+#include "aux-hpd-bridge.h"
+
static DEFINE_IDA(drm_aux_hpd_bridge_ida);
struct drm_aux_hpd_bridge_data {
@@ -190,9 +192,16 @@ static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
auxiliary_set_drvdata(auxdev, data);
+ drm_aux_hpd_typec_dp_bridge_init();
+
return devm_drm_bridge_add(data->dev, &data->bridge);
}
+static void drm_aux_hpd_bridge_remove(struct auxiliary_device *auxdev)
+{
+ drm_aux_hpd_typec_dp_bridge_exit();
+}
+
static const struct auxiliary_device_id drm_aux_hpd_bridge_table[] = {
{ .name = KBUILD_MODNAME ".dp_hpd_bridge", .driver_data = DRM_MODE_CONNECTOR_DisplayPort, },
{},
@@ -203,6 +212,7 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
.name = "aux_hpd_bridge",
.id_table = drm_aux_hpd_bridge_table,
.probe = drm_aux_hpd_bridge_probe,
+ .remove = drm_aux_hpd_bridge_remove,
};
module_auxiliary_driver(drm_aux_hpd_bridge_drv);
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-23 12:03 ` Heikki Krogerus
@ 2025-10-23 12:10 ` Chaoyi Chen
2025-10-24 7:36 ` Heikki Krogerus
0 siblings, 1 reply; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-23 12:10 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
Hi Heikki,
On 10/23/2025 8:03 PM, Heikki Krogerus wrote:
>>>> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
>>>> index 245e8a27e3fc..e91736829167 100644
>>>> --- a/drivers/gpu/drm/bridge/Makefile
>>>> +++ b/drivers/gpu/drm/bridge/Makefile
>>>> @@ -1,6 +1,7 @@
>>>> # SPDX-License-Identifier: GPL-2.0
>>>> obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
>>>> obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
>>>> +obj-$(CONFIG_DRM_AUX_TYPEC_DP_HPD_BRIDGE) += aux-hpd-typec-dp-bridge.o
>>> Instead, why not just make that a part of aux-hpd-bridge
>>> conditionally:
>>>
>>> ifneq ($(CONFIG_TYPEC),)
>>> aux-hpd-bridge-y += aux-hpd-typec-dp-bridge.o
>>> endif
>> Oh, I did consider that! But I noticed that aux-hpd-bridge.c contains the
>> following statement module_auxiliary_driver(drm_aux_hpd_bridge_drv), which
>> already includes a module_init. In the newly added file, in order to call the
>> register function, another module_init was also added. If the two files are
>> each made into a module separately, would there be a problem?
> You would not call module_init() from the new file. Instead you would
> call drm_aux_hpd_typec_dp_bridge_init() and what ever directly from
> aux-hpd-bridge.c:
>
> diff --git a/drivers/gpu/drm/bridge/aux-bridge.h b/drivers/gpu/drm/bridge/aux-bridge.h
> new file mode 100644
> index 000000000000..ae689a7778fa
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef AUX_HPD_BRIDGE_H
> +#define AUX_HPD_BRIDGE_H
> +
> +#if IS_ENABLED(CONFIG_TYPEC)
> +int drm_aux_hpd_typec_dp_bridge_init(void);
> +void drm_aux_hpd_typec_dp_bridge_exit(void);
> +#else
> +static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; }
> +static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { }
> +#endif /* IS_ENABLED(CONFIG_TYPEC) */
> +
> +#endif /* AUX_HPD_BRIDGE_H */
> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> index 2e9c702c7087..3578df1df78a 100644
> --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> @@ -12,6 +12,8 @@
> #include <drm/drm_bridge.h>
> #include <drm/bridge/aux-bridge.h>
>
> +#include "aux-hpd-bridge.h"
> +
> static DEFINE_IDA(drm_aux_hpd_bridge_ida);
>
> struct drm_aux_hpd_bridge_data {
> @@ -190,9 +192,16 @@ static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
>
> auxiliary_set_drvdata(auxdev, data);
>
> + drm_aux_hpd_typec_dp_bridge_init();
> +
> return devm_drm_bridge_add(data->dev, &data->bridge);
> }
>
> +static void drm_aux_hpd_bridge_remove(struct auxiliary_device *auxdev)
> +{
> + drm_aux_hpd_typec_dp_bridge_exit();
> +}
> +
> static const struct auxiliary_device_id drm_aux_hpd_bridge_table[] = {
> { .name = KBUILD_MODNAME ".dp_hpd_bridge", .driver_data = DRM_MODE_CONNECTOR_DisplayPort, },
> {},
> @@ -203,6 +212,7 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
> .name = "aux_hpd_bridge",
> .id_table = drm_aux_hpd_bridge_table,
> .probe = drm_aux_hpd_bridge_probe,
> + .remove = drm_aux_hpd_bridge_remove,
> };
> module_auxiliary_driver(drm_aux_hpd_bridge_drv);
Yes, if we don't distinguish them through Kconfig, we need to use the IS_ENABLED macro in the code. Thanks again for you code.
Another thing is that CONFIG_DRM_AUX_HPD_BRIDGE originally needed to be selected by other modules. With this change, we also need to expose it in Kconfig.
>
>
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
` (8 preceding siblings ...)
2025-10-23 3:30 ` [PATCH v7 9/9] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
@ 2025-10-23 13:52 ` Rob Herring (Arm)
9 siblings, 0 replies; 32+ messages in thread
From: Rob Herring (Arm) @ 2025-10-23 13:52 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Robert Foss, Maxime Ripard, Peter Robinson, Heikki Krogerus,
Greg Kroah-Hartman, Dmitry Baryshkov, Andy Yan, Jonas Karlman,
Diederik de Haas, David Airlie, Amit Sunil Dhamne, Neil Armstrong,
Chaoyi Chen, Krzysztof Kozlowski, Maarten Lankhorst, Johan Jonker,
Laurent Pinchart, Jernej Skrabec, Thomas Zimmermann,
Simona Vetter, linux-arm-kernel, Sandy Huang, linux-rockchip,
Kishon Vijay Abraham I, devicetree, Frank Wang, linux-phy,
Vinod Koul, Yubing Zhang, linux-usb, Heiko Stuebner,
Andrzej Hajda, Dragan Simic, Conor Dooley, dri-devel,
linux-kernel
On Thu, 23 Oct 2025 11:30:00 +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
>
> 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 v7, I implemented a variety of DP HPD status notify. However,
> they all had various problems and it was difficult to become a generic
> solution.
>
> Under the guidance of Heikki and Dmitry, a decoupled notification
> method between the TypeC and DRM subsystems was introduced in v7.
> First, a notification is sent when TypeC registers a new altmode.
> Then, a generic DP AUX HPD bridge is implemented on the DRM side.
>
> That makes it redundant for each Type-C controller driver to implement
> a similar DP AUX HPD bridge in embedded scenarios.
>
> ====
> 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 first bridge in bridge chain and DP
> controller. And Once the first bridge is obtained, we can get the
> last bridge corresponding to the USB-C connector, and then set the
> DRM connector's fwnode to the corresponding one to enable HPD
> notification.
>
> ====
> Patch1 add notifier functions for Type-C core.
> Patch2 add generic USB Type-C DP HPD bridge.
> Patch3 add new Type-C mode switch for RK3399 USBDP phy binding.
> Patch4 add typec_mux and typec_switch for RK3399 USBDP PHY.
> Patch5 add DRM AUX bridge support for RK3399 USBDP PHY.
> Patch6 drops CDN-DP's extcon dependency when Type-C is present.
> Patch7 add multiple bridges to support PHY port selection.
> Patch8 add missing dp_out port for RK3399 CDN-DP.
> Patch9 add Type-C DP support for RK3399 EVB IND board.
>
> Changes in v7:
> - Link to V6: https://lore.kernel.org/all/20251016022741.91-1-kernel@airkyi.com/
> - Add notifier functions for Type-C core.
> - Add generic USB Type-C DP HPD bridge.
>
> Changes in v6:
> - Link to V5: https://lore.kernel.org/all/20251011033233.97-1-kernel@airkyi.com/
> - Fix depend in Kconfig.
> - Check DP svid in tcphy_typec_mux_set().
> - Remove mode setting in tcphy_orien_sw_set().
> - Rename some variable names.
> - Attach the DP bridge to the next bridge.
>
> Changes in v5:
> - Link to V4: https://lore.kernel.org/all/20250922012039.323-1-kernel@airkyi.com/
> - 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.
> - Add DRM AUX bridge support for RK3399 USBDP PHY
> - By parsing the HPD bridge chain, set the connector's of_node to the
> of_node corresponding to the USB-C connector.
> - Return EDID cache when other port is already enabled.
>
> Changes in v4:
> - Link to V3: https://lore.kernel.org/all/20250729090032.97-1-kernel@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-kernel@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-kernel@airkyi.com/
> - Reuse dp-port/usb3-port in rk3399-typec-phy binding.
> - Fix compile error when CONFIG_TYPEC is not enabled.
> - Notify DP HPD state by USB/DP PHY.
> - Ignore duplicate HPD events.
> - Add endpoint to link DP PHY and DP controller.
> - Fix devicetree coding style.
>
> Chaoyi Chen (9):
> usb: typec: Add notifier functions
> drm/bridge: Implement generic USB Type-C DP HPD bridge
> dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
> phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
> phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
> 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/bridge/Kconfig | 11 +
> drivers/gpu/drm/bridge/Makefile | 1 +
> .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 51 +++
> drivers/gpu/drm/rockchip/cdn-dp-core.c | 354 ++++++++++++---
> drivers/gpu/drm/rockchip/cdn-dp-core.h | 24 +-
> drivers/phy/rockchip/Kconfig | 3 +
> drivers/phy/rockchip/phy-rockchip-typec.c | 420 +++++++++++++++++-
> drivers/usb/typec/Makefile | 2 +-
> drivers/usb/typec/class.c | 3 +
> drivers/usb/typec/notify.c | 22 +
> include/linux/usb/typec_notify.h | 17 +
> 14 files changed, 987 insertions(+), 83 deletions(-)
> create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> create mode 100644 drivers/usb/typec/notify.c
> create mode 100644 include/linux/usb/typec_notify.h
>
> --
> 2.49.0
>
>
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
This patch series was applied (using b4) to base:
Base: attempting to guess base-commit...
Base: tags/v6.18-rc1-18-g924aa1d9e0ae (best guess, 9/11 blobs matched)
Base: tags/v6.18-rc1-18-g924aa1d9e0ae (use --merge-base to override)
If this is not the correct base, please add 'base-commit' tag
(or use b4 which does this automatically)
New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/rockchip/' for 20251023033009.90-1-kernel@airkyi.com:
arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtb: syscon@ff770000 (rockchip,rk3399-grf): usb2phy@e450: 'port' does not match any of the regexes: '^pinctrl-[0-9]+$'
from schema $id: http://devicetree.org/schemas/soc/rockchip/grf.yaml
arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtb: syscon@ff770000 (rockchip,rk3399-grf): usb2phy@e450: Unevaluated properties are not allowed ('port' was unexpected)
from schema $id: http://devicetree.org/schemas/soc/rockchip/grf.yaml
arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtb: usb2phy@e450 (rockchip,rk3399-usb2phy): 'port' does not match any of the regexes: '^pinctrl-[0-9]+$'
from schema $id: http://devicetree.org/schemas/phy/rockchip,inno-usb2phy.yaml
arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtb: /sound: failed to match any schema with compatible: ['rockchip,rk3399-gru-sound']
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 9:44 ` Heikki Krogerus
2025-10-23 11:21 ` Chaoyi Chen
@ 2025-10-24 2:54 ` Chaoyi Chen
2025-10-24 7:43 ` Heikki Krogerus
1 sibling, 1 reply; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-24 2:54 UTC (permalink / raw)
To: Heikki Krogerus, Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
Hi Heikki,
On 10/23/2025 5:44 PM, Heikki Krogerus wrote:
> On Thu, Oct 23, 2025 at 12:04:44PM +0300, Heikki Krogerus wrote:
>> On Thu, Oct 23, 2025 at 11:10:20AM +0300, Heikki Krogerus wrote:
>>> Hi,
>>>
>>>> diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
>>>> new file mode 100644
>>>> index 000000000000..a3f1f3b3ae47
>>>> --- /dev/null
>>>> +++ b/include/linux/usb/typec_notify.h
>>>> @@ -0,0 +1,17 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>> +
>>>> +#ifndef __USB_TYPEC_NOTIFY
>>>> +#define __USB_TYPEC_NOTIFY
>>>> +
>>>> +#include <linux/notifier.h>
>>>> +
>>>> +enum usb_typec_event {
>>>> + TYPEC_ALTMODE_REGISTERED
>>>> +};
>>> Don't you need to know when the altmode is removed?
>> I noticed that you don't because drm_dp_hpd_bridge_register() is
>> always resource managed. But I think you could still send an event
>> also when the altmode is removed already now. That way it does not
>> need to be separately added if and when it is needed.
> Hold on! Every bus has already a notifier chain. That's the one that
> we should also use. Sorry for not noticing that earlier.
>
> So let's just export the bus type in this patch - you can then use
> bus_register_notifier() in your driver:
>
> diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
> index a884cec9ab7e..65ded9e3cdaa 100644
> --- a/drivers/usb/typec/bus.c
> +++ b/drivers/usb/typec/bus.c
> @@ -547,3 +547,4 @@ const struct bus_type typec_bus = {
> .probe = typec_probe,
> .remove = typec_remove,
> };
> +EXPORT_SYMBOL_GPL(typec_bus);
> diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
> index 643b8c81786d..af9edb3db9d0 100644
> --- a/drivers/usb/typec/bus.h
> +++ b/drivers/usb/typec/bus.h
> @@ -5,7 +5,6 @@
>
> #include <linux/usb/typec_altmode.h>
>
> -struct bus_type;
> struct typec_mux;
> struct typec_retimer;
>
> @@ -28,7 +27,6 @@ struct altmode {
>
> #define to_altmode(d) container_of(d, struct altmode, adev)
>
> -extern const struct bus_type typec_bus;
> extern const struct device_type typec_altmode_dev_type;
>
> #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
> diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
> index 309251572e2e..c6fd46902fce 100644
> --- a/include/linux/usb/typec.h
> +++ b/include/linux/usb/typec.h
> @@ -20,12 +20,15 @@ struct typec_port;
> struct typec_altmode_ops;
> struct typec_cable_ops;
>
> +struct bus_type;
> struct fwnode_handle;
> struct device;
>
> struct usb_power_delivery;
> struct usb_power_delivery_desc;
>
> +extern const struct bus_type typec_bus;
> +
> enum typec_port_type {
> TYPEC_PORT_SRC,
> TYPEC_PORT_SNK,
>
> thanks,
I noticed the following statement in typec_register_altmode():
```
/* The partners are bind to drivers */
if (is_typec_partner(parent))
alt->adev.dev.bus = &typec_bus;
```
If the condition is not met, the bus will not be set, which means bus_notify() won't be able to take effect. Did I miss something?
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-23 12:10 ` Chaoyi Chen
@ 2025-10-24 7:36 ` Heikki Krogerus
2025-10-24 8:12 ` Chaoyi Chen
0 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-24 7:36 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
> Another thing is that CONFIG_DRM_AUX_HPD_BRIDGE originally needed to be
> selected by other modules. With this change, we also need to expose it in
> Kconfig.
Sorry, I don't understand the problem here? What do you need to expose
in Kconfig?
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-24 2:54 ` Chaoyi Chen
@ 2025-10-24 7:43 ` Heikki Krogerus
2025-10-24 7:59 ` Chaoyi Chen
0 siblings, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-24 7:43 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Chaoyi Chen, Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
> I noticed the following statement in typec_register_altmode():
>
> ```
>
> /* The partners are bind to drivers */
> if (is_typec_partner(parent))
> alt->adev.dev.bus = &typec_bus;
>
> ```
>
> If the condition is not met, the bus will not be set, which means bus_notify()
> won't be able to take effect. Did I miss something?
Right, that would be the condition that I was talking about. Only
partner altmodes are used in the bus.
Hold on! Do you need the port altmode instead of the partner altmode?
If that's the case, then we can't use the bus notifier. So we'll need
the separate notifier chain after all.
Let me take a closer look at patch 2/9. Sorry about the hassle.
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-24 7:43 ` Heikki Krogerus
@ 2025-10-24 7:59 ` Chaoyi Chen
2025-10-24 8:07 ` Heikki Krogerus
0 siblings, 1 reply; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-24 7:59 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Chaoyi Chen, Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
Hi Heikki,
On 10/24/2025 3:43 PM, Heikki Krogerus wrote:
>> I noticed the following statement in typec_register_altmode():
>>
>> ```
>>
>> /* The partners are bind to drivers */
>> if (is_typec_partner(parent))
>> alt->adev.dev.bus = &typec_bus;
>>
>> ```
>>
>> If the condition is not met, the bus will not be set, which means bus_notify()
>> won't be able to take effect. Did I miss something?
> Right, that would be the condition that I was talking about. Only
> partner altmodes are used in the bus.
>
> Hold on! Do you need the port altmode instead of the partner altmode?
> If that's the case, then we can't use the bus notifier. So we'll need
> the separate notifier chain after all.
Yes, we need port altmode. The partner altmode device appears too late for DRM device, as it only shows up after the corresponding DP device is inserted.
>
> Let me take a closer look at patch 2/9. Sorry about the hassle.
>
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-23 3:30 ` [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge Chaoyi Chen
2025-10-23 8:45 ` Heikki Krogerus
@ 2025-10-24 8:01 ` Heikki Krogerus
2025-10-24 8:16 ` Chaoyi Chen
1 sibling, 1 reply; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-24 8:01 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
[-- Attachment #1: Type: text/plain, Size: 987 bytes --]
On Thu, Oct 23, 2025 at 11:30:02AM +0800, Chaoyi Chen wrote:
> +static int drm_typec_bus_event(struct notifier_block *nb,
> + unsigned long action, void *data)
> +{
> + struct typec_altmode *alt = (struct typec_altmode *)data;
> +
> + if (action != TYPEC_ALTMODE_REGISTERED)
> + goto done;
> +
> + if (alt->svid != USB_TYPEC_DP_SID)
> + goto done;
> +
> + /*
> + * alt->dev.parent->parent : USB-C controller device
> + * alt->dev.parent : USB-C connector device
> + */
> + drm_dp_hpd_bridge_register(alt->dev.parent->parent,
> + to_of_node(alt->dev.parent->fwnode));
Okay, this explains it. So you do need the port altmode.
So you'll need to export the device types and check that the parent of
the altmode is the port instead of partner.
if (!is_typec_port(alt->dev.parent) || alt->svid != USB_TYPEC_DP_SID)
return NOTIFY_DONE;
I think we might as well export all the types while at it. Check the
attachment.
thanks,
--
heikki
[-- Attachment #2: export_typec_dev_types.diff --]
[-- Type: text/plain, Size: 3035 bytes --]
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9b2647cb199b..f0704d605595 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -790,6 +790,7 @@ const struct device_type typec_partner_dev_type = {
.groups = typec_partner_groups,
.release = typec_partner_release,
};
+EXPORT_SYMBOL_GPL(typec_partner_dev_type);
static void typec_partner_link_device(struct typec_partner *partner, struct device *dev)
{
@@ -1144,6 +1145,7 @@ const struct device_type typec_plug_dev_type = {
.groups = typec_plug_groups,
.release = typec_plug_release,
};
+EXPORT_SYMBOL_GPL(typec_plug_dev_type);
/**
* typec_plug_set_num_altmodes - Set the number of available plug altmodes
@@ -1292,6 +1294,7 @@ const struct device_type typec_cable_dev_type = {
.groups = typec_cable_groups,
.release = typec_cable_release,
};
+EXPORT_SYMBOL_GPL(typec_cable_dev_type);
/**
* typec_cable_get - Get a reference to the USB Type-C cable
@@ -2031,6 +2034,7 @@ const struct device_type typec_port_dev_type = {
.uevent = typec_uevent,
.release = typec_release,
};
+EXPORT_SYMBOL_GPL(typec_port_dev_type);
/* --------------------------------------- */
/* Driver callbacks to report role updates */
diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h
index db2fe96c48ff..f04f6987bed8 100644
--- a/drivers/usb/typec/class.h
+++ b/drivers/usb/typec/class.h
@@ -87,16 +87,6 @@ struct typec_port {
#define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev)
#define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, dev)
-extern const struct device_type typec_partner_dev_type;
-extern const struct device_type typec_cable_dev_type;
-extern const struct device_type typec_plug_dev_type;
-extern const struct device_type typec_port_dev_type;
-
-#define is_typec_partner(dev) ((dev)->type == &typec_partner_dev_type)
-#define is_typec_cable(dev) ((dev)->type == &typec_cable_dev_type)
-#define is_typec_plug(dev) ((dev)->type == &typec_plug_dev_type)
-#define is_typec_port(dev) ((dev)->type == &typec_port_dev_type)
-
extern const struct class typec_mux_class;
extern const struct class retimer_class;
extern const struct class typec_class;
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 309251572e2e..02fed8293415 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -56,6 +56,16 @@ enum typec_role {
TYPEC_SOURCE,
};
+extern const struct device_type typec_partner_dev_type;
+extern const struct device_type typec_cable_dev_type;
+extern const struct device_type typec_plug_dev_type;
+extern const struct device_type typec_port_dev_type;
+
+#define is_typec_partner(dev) ((dev)->type == &typec_partner_dev_type)
+#define is_typec_cable(dev) ((dev)->type == &typec_cable_dev_type)
+#define is_typec_plug(dev) ((dev)->type == &typec_plug_dev_type)
+#define is_typec_port(dev) ((dev)->type == &typec_port_dev_type)
+
static inline int is_sink(enum typec_role role)
{
return role == TYPEC_SINK;
[-- Attachment #3: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-24 7:59 ` Chaoyi Chen
@ 2025-10-24 8:07 ` Heikki Krogerus
0 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-24 8:07 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Chaoyi Chen, Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
On Fri, Oct 24, 2025 at 03:59:50PM +0800, Chaoyi Chen wrote:
> Hi Heikki,
>
> On 10/24/2025 3:43 PM, Heikki Krogerus wrote:
> > > I noticed the following statement in typec_register_altmode():
> > >
> > > ```
> > >
> > > /* The partners are bind to drivers */
> > > if (is_typec_partner(parent))
> > > alt->adev.dev.bus = &typec_bus;
> > >
> > > ```
> > >
> > > If the condition is not met, the bus will not be set, which means bus_notify()
> > > won't be able to take effect. Did I miss something?
> > Right, that would be the condition that I was talking about. Only
> > partner altmodes are used in the bus.
> >
> > Hold on! Do you need the port altmode instead of the partner altmode?
> > If that's the case, then we can't use the bus notifier. So we'll need
> > the separate notifier chain after all.
>
> Yes, we need port altmode. The partner altmode device appears too late for
> DRM device, as it only shows up after the corresponding DP device is inserted.
Got it. So just move the declaration of the typec_notify_event() to
drivers/usb/typec/bus.h and this patch is OK by me.
Sorry again about the misunderstanding.
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-24 7:36 ` Heikki Krogerus
@ 2025-10-24 8:12 ` Chaoyi Chen
2025-10-24 8:25 ` Heikki Krogerus
0 siblings, 1 reply; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-24 8:12 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
On 10/24/2025 3:36 PM, Heikki Krogerus wrote:
>> Another thing is that CONFIG_DRM_AUX_HPD_BRIDGE originally needed to be
>> selected by other modules. With this change, we also need to expose it in
>> Kconfig.
> Sorry, I don't understand the problem here? What do you need to expose
> in Kconfig?
config DRM_AUX_HPD_BRIDGE
tristate
depends on DRM_BRIDGE && OF
select AUXILIARY_BUS
help
Simple bridge that terminates the bridge chain and provides HPD
support.
The tristate here is empty, so now it can only be selected by some TypeC controller drivers. I think it's not a big deal, just expose this item.
>
> thanks,
>
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-24 8:01 ` Heikki Krogerus
@ 2025-10-24 8:16 ` Chaoyi Chen
0 siblings, 0 replies; 32+ messages in thread
From: Chaoyi Chen @ 2025-10-24 8:16 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
On 10/24/2025 4:01 PM, Heikki Krogerus wrote:
> On Thu, Oct 23, 2025 at 11:30:02AM +0800, Chaoyi Chen wrote:
>> +static int drm_typec_bus_event(struct notifier_block *nb,
>> + unsigned long action, void *data)
>> +{
>> + struct typec_altmode *alt = (struct typec_altmode *)data;
>> +
>> + if (action != TYPEC_ALTMODE_REGISTERED)
>> + goto done;
>> +
>> + if (alt->svid != USB_TYPEC_DP_SID)
>> + goto done;
>> +
>> + /*
>> + * alt->dev.parent->parent : USB-C controller device
>> + * alt->dev.parent : USB-C connector device
>> + */
>> + drm_dp_hpd_bridge_register(alt->dev.parent->parent,
>> + to_of_node(alt->dev.parent->fwnode));
> Okay, this explains it. So you do need the port altmode.
>
> So you'll need to export the device types and check that the parent of
> the altmode is the port instead of partner.
>
> if (!is_typec_port(alt->dev.parent) || alt->svid != USB_TYPEC_DP_SID)
> return NOTIFY_DONE;
>
> I think we might as well export all the types while at it. Check the
> attachment.
Oh, I did miss the existence of partner. Thank you for your code!
>
> thanks,
>
--
Best,
Chaoyi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 1/9] usb: typec: Add notifier functions
2025-10-23 3:30 ` [PATCH v7 1/9] usb: typec: Add notifier functions Chaoyi Chen
2025-10-23 8:10 ` Heikki Krogerus
@ 2025-10-24 8:16 ` Heikki Krogerus
1 sibling, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-24 8:16 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Chaoyi Chen, Dragan Simic,
Johan Jonker, Diederik de Haas, Peter Robinson, linux-usb,
devicetree, linux-kernel, linux-phy, linux-arm-kernel,
linux-rockchip, dri-devel
> +#include <linux/notifier.h>
> +#include <linux/usb/typec_notify.h>
> +
> +static BLOCKING_NOTIFIER_HEAD(typec_notifier_list);
> +
> +int typec_register_notify(struct notifier_block *nb)
> +{
> + return blocking_notifier_chain_register(&typec_notifier_list, nb);
> +}
> +EXPORT_SYMBOL_GPL(typec_register_notify);
> +
> +int typec_unregister_notify(struct notifier_block *nb)
> +{
> + return blocking_notifier_chain_unregister(&typec_notifier_list, nb);
> +}
> +EXPORT_SYMBOL_GPL(typec_unregister_notify);
Better name these more clearly:
typec_altmode_register_notify()
typec_altmode_unregister_notify()
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge
2025-10-24 8:12 ` Chaoyi Chen
@ 2025-10-24 8:25 ` Heikki Krogerus
0 siblings, 0 replies; 32+ messages in thread
From: Heikki Krogerus @ 2025-10-24 8:25 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Greg Kroah-Hartman, Dmitry Baryshkov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
Kishon Vijay Abraham I, Heiko Stuebner, Sandy Huang, Andy Yan,
Yubing Zhang, Frank Wang, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Amit Sunil Dhamne, Dragan Simic, Johan Jonker,
Diederik de Haas, Peter Robinson, linux-usb, devicetree,
linux-kernel, linux-phy, linux-arm-kernel, linux-rockchip,
dri-devel
On Fri, Oct 24, 2025 at 04:12:47PM +0800, Chaoyi Chen wrote:
> On 10/24/2025 3:36 PM, Heikki Krogerus wrote:
>
> > > Another thing is that CONFIG_DRM_AUX_HPD_BRIDGE originally needed to be
> > > selected by other modules. With this change, we also need to expose it in
> > > Kconfig.
> > Sorry, I don't understand the problem here? What do you need to expose
> > in Kconfig?
>
> config DRM_AUX_HPD_BRIDGE
> tristate
> depends on DRM_BRIDGE && OF
> select AUXILIARY_BUS
> help
> Simple bridge that terminates the bridge chain and provides HPD
> support.
>
> The tristate here is empty, so now it can only be selected by some TypeC
> controller drivers. I think it's not a big deal, just expose this item.
Ah, got it.
thanks,
--
heikki
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2025-10-24 8:25 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-23 3:30 [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 1/9] usb: typec: Add notifier functions Chaoyi Chen
2025-10-23 8:10 ` Heikki Krogerus
2025-10-23 9:04 ` Heikki Krogerus
2025-10-23 9:44 ` Heikki Krogerus
2025-10-23 11:21 ` Chaoyi Chen
2025-10-23 11:29 ` Greg Kroah-Hartman
2025-10-23 11:36 ` Heikki Krogerus
2025-10-23 11:41 ` Chaoyi Chen
2025-10-24 2:54 ` Chaoyi Chen
2025-10-24 7:43 ` Heikki Krogerus
2025-10-24 7:59 ` Chaoyi Chen
2025-10-24 8:07 ` Heikki Krogerus
2025-10-24 8:16 ` Heikki Krogerus
2025-10-23 3:30 ` [PATCH v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge Chaoyi Chen
2025-10-23 8:45 ` Heikki Krogerus
2025-10-23 11:29 ` Chaoyi Chen
2025-10-23 12:03 ` Heikki Krogerus
2025-10-23 12:10 ` Chaoyi Chen
2025-10-24 7:36 ` Heikki Krogerus
2025-10-24 8:12 ` Chaoyi Chen
2025-10-24 8:25 ` Heikki Krogerus
2025-10-24 8:01 ` Heikki Krogerus
2025-10-24 8:16 ` Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 3/9] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 4/9] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 5/9] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 6/9] drm/rockchip: cdn-dp: Support handle lane info without extcon Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 8/9] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Chaoyi Chen
2025-10-23 3:30 ` [PATCH v7 9/9] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Chaoyi Chen
2025-10-23 13:52 ` [PATCH v7 0/9] Add Type-C DP support for RK3399 EVB IND board Rob Herring (Arm)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).