From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbguseast1.qq.com (smtpbguseast1.qq.com [54.204.34.129]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C1C3FD531; Mon, 19 Jan 2026 07:31:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.204.34.129 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807905; cv=none; b=ANilEigZgwncsn6Bq8uJxSZNqbju4AoTUwZAKNvYQUthiKhPBuceOe1Fs0QmZGcGW9lDJVZpQkh0MnA0X0qVlNKYQyRGQ86U7oDKEseVLHzKycdrm2xSwmktXhulm2BzOlWGev7ucG2RZgSveqTaQGH7X3sxhU2l4Y7xsjB8grw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807905; c=relaxed/simple; bh=xUSsOkydNp3uq6fFe9PAhbwC4yfTInu6czge2AyPPYU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=aUEIjTJ5v7/Wvq1cG1OOTJfq+yvHcTCN8fDEgYZlbm6qdMNwCOFCu96NLOSTTQNXFMmZ7ZMKB4IG4Sx6riHLACwsHBvUHnUonyFYf1yqxsfwPXyIr3Urc59IOtf6IdtXmoIT7v1t+w4Er4vOt/uYKpahJfB4dYONm7sgQyqKFOg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=Uod0nkml; arc=none smtp.client-ip=54.204.34.129 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="Uod0nkml" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807881; bh=OToeNz4t2oXNHYHV6Pu5IF6zpl5lN3hD9z93ek1ZgZE=; h=From:To:Subject:Date:Message-Id; b=Uod0nkmlqrXZXPZM1MWByTE0PC8pIyG5YgyEI/z17ut/xvkX9m/SV/mq9el3oCB4S Azv0JWd7g5IzWtE+MksM3y4939LHss4DBhOt8iAzb+16g5D2NH1Jv3H5Ej3oO4C5K+ LWhOvLGWcVtBhXdrXBFayjLPIwMfj1TekSEbqVoQ= X-QQ-mid: esmtpsz17t1768807880t0b5bc7d4 X-QQ-Originating-IP: rUc8iNV8fJzPqcaO9ExsW47sRe4cqZbnD2CD0yEkQV4= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:31:11 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 8138520730138124000 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 1/9] drm/bridge: Implement generic USB Type-C DP HPD bridge Date: Mon, 19 Jan 2026 15:30:52 +0800 Message-Id: <20260119073100.143-2-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MX+1SEN3H+wAprBSZyZpYvfjKkAEBXBia0if9pIIpzZeNUhkW9+SP97a mpTDPni3mqcTf8sBrRpWuHTIku36nfifeJkZQT4B/cLvHz/RPIZUHa4N6FZY2SRnfLKITXi aNsT9Z+duZYNV95ckbW6ZXZglg8ErHQJOaAw1jAANIRi/oWxCmiQHD6snPCiwdaYuzeBLka ge0CuTpYa9Lyg1GrN05qnOB3xX1Nd6tOL2Ojum42OqdnO+s6d+rfny8kyiJpitjGCxNVNJs Yog5Jt2TIeQPFcsJLw1exxo/HSigjjXGgpMVimGGJaiQmcMA7X+Z8rQa7elud+Pcl62chC2 ZxYaTzvmua9Y/0hLTvNcHKbffbGrKm1v3/woG9NmBV5aXXL6gJu8Qr/Y+7O1cUmtzYemUi3 KzCWzjtaaWYbcbVEkRd3MOgIs+A9N8aRfiqKtWfCYy02YLps3c4woqwTuh/9ftaGvTfHzPU WB6W/L7Kx4WrYkrDUUvPpI9JHCUQHJ090F2gWprqRIGSjH16JopWVv7wYovm4Sq9YTzTZTc JyAgFB8HhIuOc8eNyHB0F0pWLLqlr8rtMKrimJe0dl8y+KSjxYhmd0aepHi70nLnwdGMgIi JdMD/hKl6hehuS/aCBPr2v6M5by4oPtw1mCdNaBVvHJVwOi1HKdiLajbK8FF0v4UBX8DtDm eJiLHP5f2bKJxzgeabf92W0qE8MpRG8jMqETY4Uh744UacHdinRyM0Riuq3vw7DeTZzzFEs TsJVkNBv14pQTK9O+qCIQQMh2SwrbA8C5oqty+WDXlSFPe5GsOf05gfP89R/LBAV3UZGqHD FveOvQP79CqDHsPWL45A0g7PbNIeitHCLHSAmfSN/Eaq/IzTBfFpbkE+I7Ls15ceIdoVwwg bHqu24N9N/EY29LBQ5xNYaWls9fD07xTIIeGm2fdlXzvz8+uPxm+84hohCWN7Otj6jgsqvq tyGij7eswwtv+Rmrg/3L6fNNCNoMdfjEN7g53+oxHBzGrETMooM6L9x3kZByyFRL4ulR4+q gQ3NFHxA== X-QQ-XMRINFO: OWPUhxQsoeAVwkVaQIEGSKwwgKCxK/fD5g== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The HPD function of Type-C DP is implemented through drm_connector_oob_hotplug_event(). For embedded DP, it is required that the DRM connector fwnode corresponds to the Type-C port fwnode. To describe the relationship between the DP controller and the Type-C port device, we usually using drm_bridge to build a bridge chain. Now several USB-C controller drivers have already implemented the DP HPD bridge function provided by aux-hpd-bridge.c, it will build a DP HPD bridge on USB-C connector port device. But this requires the USB-C controller driver to manually register the HPD bridge. If the driver does not implement this feature, the bridge will not be create. So this patch implements a generic DP HPD bridge based on aux-hpd-bridge.c. It will monitor Type-C bus events, and when a Type-C port device containing the DP svid is registered, it will create an HPD bridge for it without the need for the USB-C controller driver to implement it. Signed-off-by: Chaoyi Chen Reviewed-by: Heikki Krogerus Tested-by: Hugh Cole-Baker --- (no changes since v14) Changes in v13: - Only register drm dp hpd bridge for typec port altmode device. (no changes since v12) Changes in v11: - Switch to using typec bus notifiers. (no changes since v10) Changes in v9: - Remove the exposed DRM_AUX_HPD_BRIDGE option, and select DRM_AUX_HPD_TYPEC_BRIDGE when it is available. - Add more commit comment about problem background. Changes in v8: - Merge generic DP HPD bridge into one module. --- drivers/gpu/drm/bridge/Kconfig | 10 ++++ drivers/gpu/drm/bridge/Makefile | 1 + .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 49 +++++++++++++++++++ 3 files changed, 60 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 a250afd8d662..559487aa09a9 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE Simple bridge that terminates the bridge chain and provides HPD support. =20 +if DRM_AUX_HPD_BRIDGE +config DRM_AUX_HPD_TYPEC_BRIDGE + tristate + depends on TYPEC || !TYPEC + default TYPEC + help + Simple bridge that terminates the bridge chain and provides HPD + support. It build bridge on each USB-C connector device node. +endif + menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE =20 diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makef= ile index c7dc03182e59..a3a0393d2e72 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) +=3D aux-bridge.o obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) +=3D aux-hpd-bridge.o +obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) +=3D aux-hpd-typec-dp-bridge.o obj-$(CONFIG_DRM_CHIPONE_ICN6211) +=3D chipone-icn6211.o obj-$(CONFIG_DRM_CHRONTEL_CH7033) +=3D chrontel-ch7033.o obj-$(CONFIG_DRM_CROS_EC_ANX7688) +=3D 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..d915e0fb0668 --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include + +#include + +static int drm_typec_bus_event(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev =3D (struct device *)data; + struct typec_altmode *alt =3D to_typec_altmode(dev); + + if (action !=3D BUS_NOTIFY_ADD_DEVICE) + goto done; + + /* + * alt->dev.parent->parent : USB-C controller device + * alt->dev.parent : USB-C connector device + */ + if (is_typec_port_altmode(&alt->dev) && alt->svid =3D=3D USB_TYPEC_DP_SID) + 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 =3D { + .notifier_call =3D drm_typec_bus_event, +}; + +static void drm_aux_hpd_typec_dp_bridge_module_exit(void) +{ + bus_unregister_notifier(&typec_bus, &drm_typec_event_nb); +} + +static int __init drm_aux_hpd_typec_dp_bridge_module_init(void) +{ + bus_register_notifier(&typec_bus, &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"); --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbgau2.qq.com (smtpbgau2.qq.com [54.206.34.216]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 818C52F6590; Mon, 19 Jan 2026 07:31:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.206.34.216 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807904; cv=none; b=YbVyBbbY6kIBmax9JZkcVU+XNkI16Dk4lLiMbaEho3oULaoOs5rdI3aAirOWmAukJwUTerOIcTn5s9a+MHwnhA6u7+7Rd+5eltsVOc3OB4/jUJeGDkYcTG6TWRue75xGWjJHjbVwOvSCYEpEr+4R20E1C3grvN5hZ+kuKbdTGFQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807904; c=relaxed/simple; bh=vPsyzj6/MSOc6sqNmDWLDGrmzZ/tzKyolgK8GVFnH9Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=CunjBZV5sw4Vk9rD1yEh9KdufR2lQpGxUcH3iVrIt6vG3dqbj37K7NUdVCZ+llBMqBBB1QjZZw1Hi9+KVQ1yZ+SRDGMnQZnpra55ZkvQ8veTCh0lJtILxaO9aeDBGVSB/AB76itWilbEiQ9rBLK1KhiDZmBkIatR9KnNshDrIwI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=D+elyjcK; arc=none smtp.client-ip=54.206.34.216 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="D+elyjcK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807889; bh=5ZqODQ5igOoBvPuYVh0rP+EhPppD6n2yhjb+6z4KnfU=; h=From:To:Subject:Date:Message-Id; b=D+elyjcKTTFVbtpb3ndAthNniClbtm0vXyqxJHMTp4WT3S99mLAJr9cBQc2BMPVnL rCYmYSTR/9bfuYVk9CP0lA/vfoPbHWjEVdojQjxr+/VTvhPyBbi8YzMiUi2R0LrOMv ZPeNiLixk7h8/QLayo/CaHSLpLc2Vr0mxOS/ZYhw= X-QQ-mid: esmtpsz17t1768807887tc6c1cd7e X-QQ-Originating-IP: Y9Cfzzlo6OYydIEHXqhCNUVPKhYgnaX7YPgZi2JRbME= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:31:21 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 14245727192888249367 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 2/9] drm/bridge: aux: Add drm_aux_bridge_register_from_node() Date: Mon, 19 Jan 2026 15:30:53 +0800 Message-Id: <20260119073100.143-3-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MgOcfNUnrri+sqbCh2B7bRF7YnOvRybRTkLsFlF0iVOUCyAXF4ZU9JNC Npq/5bKYRsboTYSvj5t28zBYZKy5ZYc3t3qupUeg52J0apd6CbhYlLHhgbT4R77VxP0D0di AJ73iJ2oixavKTjRsvyxLWiaH6B3+KI5hKzw8lz9/YfI8ONSCUl2DXUFYsAotuAXjc/j1Wk Nq14q8h8LpOKau42zH1ryczN2TkFAAUdEKow+9Wet89dqzb6h7dpaSzFZlEBO9FlpL804/f Nb9h/Wywn3/FOgRt2FP/vOfkxus6eBUah2irq9bYNXbfrIQUYfdQ9BtWWDHob0rMo0Szh/S pxGmzvezZhmPHFucBepr2jIAc9WM4Mhjk+UaQLz5RQk9GAF0D3Ba54ibUacf+H0EfQiF8qr t9NYgOhap01tMR7n2bFSPwwbyGrGSUcMHdpYZtnTDosZXbglMpL61zOfERvw3/5OADvoGLb nx2/I1eQgu1QxXWUxxM0oy8I2pcxgaDR9FGeVVmhhN+sIq1I/yj5ZEZ9D25pissIxSBtUL6 kMBPkHgYvI8lt687U3LzEipvmU0YY4h4kcsps08a2M4XiFZ0GT34gQ9PrMQ+bORBuXx/VRS +eap6hmXCFsy5d+uQRFybF9QxLdoY/REWKZyWjEYRmc/dC8K/MW24eRdVt0xYEagX7J1rDJ J4Y0Hah0CwMePL8i3MEZMa8nO5fTnAXhMXVwGhJDEf9H8K/d1PQcNFGibPRf+RbADQudVZw 6cV/RqL+StNxQN0sx1KFJwvjetzpX9bgKIy0lnw8T+9Y9y5XIKtwr4Fj95poXKD0raHUkVS N9FoQI9SBQZKXcjn28qpVjtclkgbGBhX8NNd0NHzoBOfk6UjtDqIjmKRvB2kLegDCRzSx6/ d9YszO6nVjZMn+eoM6zgT3XrvJyS8GupHQ7kpJp4xUF4Qp9DRCwV9PCviJzrD2m6mhVGfJy O+a4y5U5TTDSdxionRsc8HIOFYqL9+/6/bFmvVSfizDLEJt0xvEsKEnpZ2Z55sMEmupbTco FY8JL5/hdh4eYYL3h8kQZQGUc52Gqg4qaJD+1VvQ== X-QQ-XMRINFO: OWPUhxQsoeAVwkVaQIEGSKwwgKCxK/fD5g== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The drm_aux_bridge_register() uses the device->of_node as the bridge->of_node. This patch adds drm_aux_bridge_register_from_node() to allow specifying the of_node corresponding to the bridge. Signed-off-by: Chaoyi Chen Reviewed-by: Neil Armstrong Tested-by: Hugh Cole-Baker --- (no changes since v11) --- drivers/gpu/drm/bridge/aux-bridge.c | 24 ++++++++++++++++++++++-- include/drm/bridge/aux-bridge.h | 6 ++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/a= ux-bridge.c index b3e4cdff61d6..52dff4601c2d 100644 --- a/drivers/gpu/drm/bridge/aux-bridge.c +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -35,6 +35,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev) /** * drm_aux_bridge_register - Create a simple bridge device to link the cha= in * @parent: device instance providing this bridge + * @np: device node pointer corresponding to this bridge instance * * Creates a simple DRM bridge that doesn't implement any drm_bridge * operations. Such bridges merely fill a place in the bridge chain linking @@ -42,7 +43,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev) * * Return: zero on success, negative error code on failure */ -int drm_aux_bridge_register(struct device *parent) +int drm_aux_bridge_register_from_node(struct device *parent, struct device= _node *np) { struct auxiliary_device *adev; int ret; @@ -62,7 +63,10 @@ int drm_aux_bridge_register(struct device *parent) adev->dev.parent =3D parent; adev->dev.release =3D drm_aux_bridge_release; =20 - device_set_of_node_from_dev(&adev->dev, parent); + if (np) + device_set_node(&adev->dev, of_fwnode_handle(np)); + else + device_set_of_node_from_dev(&adev->dev, parent); =20 ret =3D auxiliary_device_init(adev); if (ret) { @@ -80,6 +84,22 @@ int drm_aux_bridge_register(struct device *parent) =20 return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, a= dev); } +EXPORT_SYMBOL_GPL(drm_aux_bridge_register_from_node); + +/** + * drm_aux_bridge_register - Create a simple bridge device to link the cha= in + * @parent: device instance providing this bridge + * + * Creates a simple DRM bridge that doesn't implement any drm_bridge + * operations. Such bridges merely fill a place in the bridge chain linking + * surrounding DRM bridges. + * + * Return: zero on success, negative error code on failure + */ +int drm_aux_bridge_register(struct device *parent) +{ + return drm_aux_bridge_register_from_node(parent, NULL); +} EXPORT_SYMBOL_GPL(drm_aux_bridge_register); =20 struct drm_aux_bridge_data { diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridg= e.h index c2f5a855512f..7dd1f17a1354 100644 --- a/include/drm/bridge/aux-bridge.h +++ b/include/drm/bridge/aux-bridge.h @@ -13,11 +13,17 @@ struct auxiliary_device; =20 #if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE) int drm_aux_bridge_register(struct device *parent); +int drm_aux_bridge_register_from_node(struct device *parent, struct device= _node *np); #else static inline int drm_aux_bridge_register(struct device *parent) { return 0; } + +static inline int drm_aux_bridge_register_from_node(struct device *parent,= struct device_node *np) +{ + return 0; +} #endif =20 #if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE) --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbguseast2.qq.com (smtpbguseast2.qq.com [54.204.34.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEE4E3358D6; Mon, 19 Jan 2026 07:31:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.204.34.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807920; cv=none; b=WkRrkdfsmaWogrmV7O4UfHQhkHUEbd+IIbuBqIXsIxYsvHJ+hCRhgqoQGFXIFK1ZVILW/BwLMdbQrqY+9wDm5mPWIAh9cVKOMf2ussyUca93OheG0BKni8X9w6xSC1yH+WZ2zLiANClPlKBL7wUREoVeVMHYRdzi9PDgtDDdlcI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807920; c=relaxed/simple; bh=yNNivodlTIieW/Vd3vihN5C8kuvtirtl4pr8GWh/M90=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=aA4IaKoog7tAXvPnmRa7MZSCP+GO7W4XFoduRRp+JkCL7j6nDjPck0qwn8dJvqoO7qAqQWr5RwKRL6117A0nOPLXbfIbLiPNZBSuTHxiKmPXbCJa5FY4A9165lKTskBhNdb5zOOw+7QPczl2NHxlXCMWEZH58MkDiaGfgcp0IBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=flSsfzdH; arc=none smtp.client-ip=54.204.34.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="flSsfzdH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807895; bh=Js8LohQ5FKnKhCP/1X+pjHvtWvmL3//jFEdtasdSj/c=; h=From:To:Subject:Date:Message-Id; b=flSsfzdHeKHEQi+hdnykBXqvGQvWZCYiA+N9dwoL5ql+3qL7KU8tcMTjuSSeOxSNq lpa7Gjd20MQcVRgXamrimyJtz/uDxWrGmdzB/jNzNHQBfI44QAd4PleStl4fawGve5 n4+t3YjIZ0+vaUjRwbeG/H6fKXlWX7YM/kDinJBc= X-QQ-mid: esmtpsz17t1768807894t2b9d6dd4 X-QQ-Originating-IP: AqKRKbAHcm84t5Ai8LOV/Z1hHzoNbpXZnvn4/yP/VCg= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:31:29 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 14299818678048633841 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 3/9] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Date: Mon, 19 Jan 2026 15:30:54 +0800 Message-Id: <20260119073100.143-4-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: OE2SNMSfMbmOirWZKivO9hs+BxhHJG6Jpwluo23f2loh3fKcTmX567pE CJk4kAWJlw2yKegl+zAUHAiMsVlKfb2flQnVYkbAWnTkL6/STzBa+OXsiEBGIxH4f6rMLk8 5BgLfOUzy1mqECD7lVMUS0rf0TkBlz7EY/scXiMD740YwZdjriOFMvGrxPlX+wvsJHa16WC K0ZTwSdseJmiwTCFcaHAiirPY70J9Kry6j3K3zeZWZPuLebjbTeqUe1GpjuWo+OYh5AKtcu LDtoIOrmVolGOwUrpWCH6FLnx+Uun7e+BYDHNOjkHqlotLZURJdOEeRbXu/jOQ/jufPCdTF +/3LpX8VA9opmTcIZO0pIyMJTvGmb21uzT39IecRCtK3PEpWKDbg0CsghXJbz/NGkByCB4O E0Rl1g3W56j2BvlXoRN+YOTN1JEDTLmV+2Lwp8OUu0JyHaefaCDWKrAH0DI6t61dP+MdCi9 efkboxy5WQqnTaddc5VK+Qm6UNfu5DkveknN6VFxOsRjOJ/1+GakYYHKuDDHqTWuLEv2OqR 6aoAxO2Bzd1imEVlvYaEOJzOiYI7Wv2txF1q1gdC04f5unK+yv5NrEeTDFIwjdetNkR+eKa zazFJuv7gKRY3frSeMYTrR6P57gXzXAWcMqmEy18MokSQk9Ho2Qsi0ap0wxAHoZ+3rPpVFY egRDLTdYwSyrsODJIS1URgVfWQZtyThNVtB/BLENBXZsjHa4R89/lYhx6ZNQgG8tOmLoqtB +auVsrgNBWtSRV1dQet9qxko+wgQM+o51kfOOMooJWfSaq1rkFNAClNuGbKf9xz4/OWa2hS VZfWsv/Y2tIj4rCdhmUMeCUzjYpEHkvZ2CaHyl/oG9D92L3XxkooIG3qQ57Ux3og8MOq54l W9oCAaWNVE9V1xft9SNKKwDVZ1aK1pRytdjNmXYbba24TRri3xq1UsjNLHR5+JKGHK6A7Oc ByOKLy+Rzs0ocMz/Dk0OvX2og6Eytt1kLlbZVrKVShZnh+GhlvF64PhB6twfh6iveBzB6U0 XnzY3H5AsaJnz3rNKEJQxaiXcWdjMp1b/4M5sTCg== X-QQ-XMRINFO: NyFYKkN4Ny6FuXrnB5Ye7Aabb3ujjtK+gg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The RK3399 SoC integrates two USB/DP combo PHYs, each of which supports software-configurable pin mapping and DisplayPort lane assignment. These capabilities enable the PHY itself to handle both mode switching and orientation switching, based on the Type-C plug orientation and USB PD negotiation results. While an external Type-C controller is still required to detect cable attachment and report USB PD events, the actual mode and orientation switching is performed internally by the PHY through software configuration. This allows the PHY to act as a Type-C multiplexer for both data role and DP altmode configuration. To reflect this hardware design, this patch introduces a new "mode-switch" property for the dp-port node in the device tree bindings. This property indicates that the connected PHY is capable of handling Type-C mode switching itself. Signed-off-by: Chaoyi Chen Acked-by: Krzysztof Kozlowski Tested-by: Hugh Cole-Baker --- (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-ph= y.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.ya= ml 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 =20 + mode-switch: + description: + Indicates the PHY can handle altmode switching. In this case, + requires an external USB Type-C controller to report USB PD mess= age. + type: boolean + port: $ref: /schemas/graph.yaml#/properties/port description: Connection to USB Type-C connector --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 06CD033033B; Mon, 19 Jan 2026 07:31:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.206.16.166 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807926; cv=none; b=Z2un588W46nAKKnhotC5UymQB7OIRdaRNkWSr8zxH922wElotHbH+jc+EobQYd+plRcHYm8pTGkEhulWVLWCGVKPkbgmCgs1z7ehV9/pWEEp7SYQC765lCFtq+ICd7CBvTL4ZAD2xHcZU5vRVWPOx3DNQozyJSkmIqgj0dTfd10= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807926; c=relaxed/simple; bh=Wo0vIZKpJX2kZrZGzEADk8DkzhMOTPZ6Nj6Gq1fGGtA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=hAFO+hAuJ9hwOVsYeqBZQvVCQ0eC9+L170QWY5dmK07CsjlM9Ne5L2YKUZzN7onZnGxLqAkuyPpku+dsED2K09D/mdE0bFxApxQKExtysH9Jgw2Z75nl1NH8FqBicMwCjS8N1sEj5boSmO5I21or+lmGrZ9RJpPXXRPG068jdik= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=ie/97vst; arc=none smtp.client-ip=54.206.16.166 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="ie/97vst" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807902; bh=Q/C/81n2ESiHICwb5qDeywuFY/hqwhxLLbWeZ9weSUI=; h=From:To:Subject:Date:Message-Id; b=ie/97vst3cfLvqEuOzTKRiILu4srGczkv5JnPZ9m3Hy/kVf1/v6N8T3Q+6r8c5zaT 128ypXN1RC2VK9nR16unIJZFEZWUzur3RESBPnFl41dBU/Ycxzsloakrcnbn6yJ8ky sHR2VciJ/Pd7edz5PuW/z+GyLTIqJulqTrw7LPjw= X-QQ-mid: esmtpsz17t1768807900t1d03033a X-QQ-Originating-IP: Wr+YlhhDHYSj6kCJ2OjE+Wd6LWoSfGOmGCoesV8ZiOk= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:31:35 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 14437086725457086973 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 4/9] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Date: Mon, 19 Jan 2026 15:30:55 +0800 Message-Id: <20260119073100.143-5-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: OAGxezCvFUVrxmf9dgDG5rq0LG9ds37iudH1T4c55iY+tV5CC70R3WQa OgSPWI6nAU4wOUwTzDbd2I22QbVMQA4Ps4JhXZYKaC7I29ZB2CQa5FKCQ8CM2UpRTDpHL+t zRw1qFw5eQRwGUBf6orHAjHfArDQsVv7dNZwtMvTXh+GIggZFE4kh+6U8o5Oy0Ika0zTx7S didDHdmZRUw6u4uUQRwugFNfAVTOA/3epJfHr77VyULGyuY73qpzcTUgArN9/WeMZvZFgC9 W1TgPaKKNsWtgBqUk48o6M7kDA5KC68+aU6YJdoXvCwRYROx+Je7tHSyOReMOsePIIWp5Ja ZUfOHYL5KXSQt7Oyk884qvJbzi2c6K50amsj/unm9Nkc1DI1iQCAelZTXRtrIxDXAFStB4i 4BygGdMBxWT3R9W1HL+2bw4npcCh4Fl0w08z2YqhdRu9ZXE6z+eY78pYE7/szIxVSvVAlOG fNppJeNsYt2hY77MYfZDoG0GyGQFhOdl/MTFY6nzgb/RC3U0wLq4IC9m+CuWGVNmwghTCWJ ZlQVOaW5fsLNnjw5Id7bWG3v3m4S+hnGcAbInbE8F9Na6kKEkJ0TL702IyTmb/J8tKboT9f KsJh68PZLg2QxObpIJQ3UVPOrXCUgdTi8bTyUj3gPCnrr+NltEGJl9vrMMhGhkhEq3T5uGu raou2Rbp5RX1wePJEKxUMgVz7jqWhYCoKqQy8B2lzxQDzbIp7k2ZpJcAHiPhSOn2LpHMhtK G1pW0B0HVgP40QKFmKhxP/V8VKEdITneQy01m3IyzD7wTcqNTHk+52mNRLwUd5ifDEQqcsu wnHS7RYEMahrwmT3z0juZ3e6SnrufP9zRi0w3J8s2dEiaoot7VIZ+/Ei1jhi6yPzI51VQiv B/8QH5KewmBLz97w+JBV83UdYDMxrDx9R7vOn9Mu1vWvutQBvwct2VofxzfBGouiRpGl1pv Lt1o8FToMopKIpTR5ZiDxtOx0zBbx6mqToN+h+KQo3uDZm1M2CEq2muE5Z+XHg3kJtrD0ld z3ccd3a873s8W9RItj X-QQ-XMRINFO: Mp0Kj//9VHAxzExpfF+O8yhSrljjwrznVg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen This patch add support for Type-C Port Controller Manager. Each PHY will register typec_mux and typec_switch when external Type-C controller is present. Type-C events are handled by TCPM without extcon. The extcon device should still be supported. Signed-off-by: Chaoyi Chen Tested-by: Hugh Cole-Baker --- (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=3Dn select EXTCON select GENERIC_PHY select RESET_CONTROLLER diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockch= ip/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 @@ =20 #include #include +#include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -286,12 +288,23 @@ #define RX_DIAG_SC2C_DELAY (0x81e1 << 2) =20 #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 @@ =20 #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) =20 #define PHY_MODE_SET_TIMEOUT 100000 =20 @@ -340,6 +360,31 @@ #define MODE_DFP_USB BIT(1) #define MODE_DFP_DP BIT(2) =20 +enum phy_dp_lane_num { + PHY_DP_LANE_0 =3D 0, + PHY_DP_LANE_1, + PHY_DP_LANE_2, + PHY_DP_LANE_3, +}; + +enum phy_pma_if { + PMA_IF_PIPE_PCS =3D 0, + PMA_IF_PHY_DP, +}; + +enum phy_typec_role { + TYPEC_PHY_USB =3D 0, + TYPEC_PHY_DP, + TYPEC_PHY_MAX, +}; + +enum phy_dp_power_state { + PHY_DP_POWER_STATE_A0 =3D 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; =20 bool flip; u8 mode; + u8 new_mode; }; =20 struct phy_reg { @@ -454,6 +503,99 @@ static const struct rockchip_usb3phy_port_cfg rk3399_u= sb3phy_port_cfgs[] =3D { { /* sentinel */ } }; =20 +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 =3D BIT(state); + int ret; + + /* + * Power state changes must not be requested until after the cmn_ready + * signal has gone active. + */ + reg =3D readl(tcphy->base + PMA_CMN_CTRL1); + if (!(reg & CMN_READY)) { + dev_err(tcphy->dev, "cmn_ready in the inactive state\n"); + return -EINVAL; + } + + reg =3D readl(tcphy->base + DP_MODE_CTL); + reg &=3D ~PHY_DP_POWER_STATE_MASK; + reg |=3D sts; + writel(reg, tcphy->base + DP_MODE_CTL); + + ret =3D readl_poll_timeout(tcphy->base + DP_MODE_CTL, + ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >> + PHY_DP_POWER_STATE_ACK_SHIFT) =3D=3D 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 mo= de) +{ + /* + * 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 =3D=3D 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 *t= cphy, u8 mode) tcphy_dp_aux_set_flip(tcphy); =20 tcphy_cfg_24m(tcphy); + tcphy_set_lane_mapping(tcphy, mode); =20 if (mode =3D=3D MODE_DFP_DP) { + tcphy_cfg_usb3_to_usb2_only(tcphy, true); tcphy_cfg_dp_pll(tcphy); for (i =3D 0; i < 4; i++) tcphy_dp_cfg_lane(tcphy, i); @@ -768,7 +912,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *t= cphy, u8 mode) writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG); } =20 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); + val =3D readl(tcphy->base + DP_MODE_CTL); + val &=3D ~DP_MODE_MASK; + val |=3D DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED; + writel(val, tcphy->base + DP_MODE_CTL); =20 reset_control_deassert(tcphy->uphy_rst); =20 @@ -811,8 +958,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tc= phy) u8 mode; int ret, ufp, dp; =20 + /* If extcon not exist, try to use tcpm mode */ if (!edev) - return MODE_DFP_USB; + return tcphy->new_mode; =20 ufp =3D extcon_get_state(edev, EXTCON_USB); dp =3D extcon_get_state(edev, EXTCON_DISP_DP); @@ -850,6 +998,71 @@ static int tcphy_get_mode(struct rockchip_typec_phy *t= cphy) return mode; } =20 +#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 =3D typec_switch_get_drvdata(sw); + + mutex_lock(&tcphy->lock); + + if (orien =3D=3D TYPEC_ORIENTATION_NONE) { + tcphy->new_mode =3D MODE_DISCONNECT; + goto unlock_ret; + } + + tcphy->flip =3D (orien =3D=3D 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 =3D data; + + typec_switch_unregister(tcphy->sw); +} + +static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy) +{ + struct typec_switch_desc sw_desc =3D { }; + struct device_node *np; + int ret =3D 0; + + np =3D 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 =3D tcphy; + sw_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "usb3-port"); + sw_desc.set =3D tcphy_orien_sw_set; + + tcphy->sw =3D 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 =3D PTR_ERR(tcphy->sw); + goto put_np; + } + + ret =3D devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregiste= r, 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) =20 tcphy_dp_aux_calibration(tcphy); =20 - writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL); - - ret =3D 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 =3D 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; } =20 @@ -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 =3D phy_get_drvdata(phy); + int ret; =20 mutex_lock(&tcphy->lock); =20 @@ -1021,7 +1230,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy) =20 tcphy->mode &=3D ~MODE_DFP_DP; =20 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); + ret =3D 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; + } =20 if (tcphy->mode =3D=3D MODE_DISCONNECT) tcphy_phy_deinit(tcphy); @@ -1037,6 +1250,93 @@ static const struct phy_ops rockchip_dp_phy_ops =3D { .owner =3D THIS_MODULE, }; =20 +#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 =3D typec_mux_get_drvdata(mux); + struct typec_displayport_data *data; + int hpd =3D 0; + + mutex_lock(&tcphy->lock); + + switch (state->mode) { + case TYPEC_STATE_SAFE: + fallthrough; + case TYPEC_STATE_USB: + tcphy->new_mode =3D 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 !=3D USB_TYPEC_DP_SID) + break; + tcphy->new_mode =3D MODE_DFP_DP; + data =3D state->data; + hpd =3D !!(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 !=3D USB_TYPEC_DP_SID) + break; + tcphy->new_mode =3D MODE_DFP_DP | MODE_DFP_USB; + data =3D state->data; + hpd =3D !!(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 =3D data; + + typec_mux_unregister(tcphy->mux); +} + +static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) +{ + struct typec_mux_desc mux_desc =3D {}; + struct device_node *np; + int ret =3D 0; + + np =3D 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 =3D tcphy; + mux_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "dp-port"); + mux_desc.set =3D tcphy_typec_mux_set; + + tcphy->mux =3D 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 =3D PTR_ERR(tcphy->mux); + goto put_np; + } + + ret =3D 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 =3D MODE_DISCONNECT; } =20 +static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy) +{ + int dp_lanes; + + switch (tcphy->new_mode) { + case MODE_DFP_DP: + dp_lanes =3D 4; + break; + case MODE_DFP_DP | MODE_DFP_USB: + dp_lanes =3D 2; + break; + default: + dp_lanes =3D 0; + break; + } + + return dp_lanes; +} + static int rockchip_typec_phy_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; @@ -1142,6 +1461,7 @@ static int rockchip_typec_phy_probe(struct platform_d= evice *pdev) return ret; =20 tcphy->dev =3D dev; + tcphy->new_mode =3D MODE_DFP_USB; platform_set_drvdata(pdev, tcphy); mutex_init(&tcphy->lock); =20 @@ -1151,6 +1471,7 @@ static int rockchip_typec_phy_probe(struct platform_d= evice *pdev) if (IS_ERR(tcphy->extcon)) { if (PTR_ERR(tcphy->extcon) =3D=3D -ENODEV) { tcphy->extcon =3D NULL; + dev_info(dev, "extcon not exist, try to use typec mux\n"); } else { if (PTR_ERR(tcphy->extcon) !=3D -EPROBE_DEFER) dev_err(dev, "Invalid or missing extcon\n"); @@ -1158,19 +1479,34 @@ static int rockchip_typec_phy_probe(struct platform= _device *pdev) } } =20 + ret =3D tcphy_setup_orien_switch(tcphy); + if (ret) + return ret; + + ret =3D tcphy_setup_typec_mux(tcphy); + if (ret) + return ret; + pm_runtime_enable(dev); =20 for_each_available_child_of_node(np, child_np) { struct phy *phy; =20 - if (of_node_name_eq(child_np, "dp-port")) + if (of_node_name_eq(child_np, "dp-port")) { phy =3D 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] =3D phy; + phy_set_bus_width(phy, typec_dp_lane_get(tcphy)); + } + } else if (of_node_name_eq(child_np, "usb3-port")) { phy =3D devm_phy_create(dev, child_np, &rockchip_usb3_phy_ops); - else + if (!IS_ERR(phy)) + tcphy->phys[TYPEC_PHY_USB] =3D phy; + } else { continue; + } =20 if (IS_ERR(phy)) { dev_err(dev, "failed to create phy: %pOFn\n", --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbgeu2.qq.com (smtpbgeu2.qq.com [18.194.254.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A85E26FA77; Mon, 19 Jan 2026 07:32:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=18.194.254.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807947; cv=none; b=bUw4OzZ9+7XB5MFah97tzDAaNHghnM6XFO7rLmvZVKxTfesHqv3T4+F/gzAMj4DgT785rlJjUAYOq5BSoAFpPsXAKv5rnG12sd7h5LdsIcVsMYlc+BRqd4hLY04A8PzFfmiUnCcThGo56bj7gVp2PzZIFFHUCwb+GD7eA76tJH4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807947; c=relaxed/simple; bh=PFaJSo44CFzbK0ZXM4EX8zDefFrJAyK83Tu4AAPXASU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=sCJv2uvy0Da10v9shlZ5ESDcnSERA+gw07ClfxANw2DTKUyGDNgdVmwmbpoYpsyNuWbANqRJkzGLGItxK56Kuh6mdHsKEBdFtQhZVLH1524QZzmAAAte/2RxrrtTUdIrH1z6KoIEMzbhKfqe/4dcxeCHJG6yApFJMWCI/xS4zM8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=hxw4nfDa; arc=none smtp.client-ip=18.194.254.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="hxw4nfDa" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807910; bh=mTE8GiUrUtEaTT4O+e4/NPc8OEJgo20N+GCnBt48BNo=; h=From:To:Subject:Date:Message-Id; b=hxw4nfDaEYrB85e3OtJB1IYMjZgEU+nbkGafIRuiHf0aOvBlyE1wdxwXipNLAmvj/ iIC0exSX+TOm6yLHCPvfGwiBLbOYLZ0K7kwrf1WiOM1hrRokDT+KVJeiL7pVW2DqB3 4jw6/XJvtq/cJHRUoqQanwr4Ze4wD9BK8hAa9a6Q= X-QQ-mid: esmtpsz17t1768807909t6177b3cf X-QQ-Originating-IP: 7rQc2nr+44BlSU0iP8JPeW5epauJLxNX/QDEkb7wpC8= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:31:42 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 12188449118939079178 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 5/9] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Date: Mon, 19 Jan 2026 15:30:56 +0800 Message-Id: <20260119073100.143-6-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MJWNsjxQgzaEIlLTbUYZXFYq8VoSA5MQ6BuOIF7d2ppZCjebNBlVT0AC SJWA4ZnKBl3kqfir5pP1tly7unDb8qMTUqf4eCbPyeHKB1PdV4nKR3Fk4mVrZdlRyebs19Y JjL5CF21Pjd19yRAAFHjc8qpqfaI6BcXdA5dktV/jQt/E2crjekVtacAHvpfHktcL3IjQhc FEQ8AYJcY7DID0Vnh3zxgOLfl/853dsW2fILKskOXk6Rb297AZQD/qITNv9iIznBMm7Or2O 3vWhyDSbjH2NQheG5pNoPD8A1Co6zl7dv0tyGeCnmhkqNAdH1gF5ZM9OmNqtIThi3ycOY2F 1PGIkStl6lI2GSpikGiZ15cZiqS2zPRrxClqsQbJjL4C6FZyowkkZJ2uVKzm7Kg4ccECpaV N1t9cYOAFW/9WdD1FXfRYKKM/O6hxTpH6V5Bur400n4Jd2uvbDEi+48CgjQjaF7gB5G2X2w EyJO/JOT75xhRwzFGUUbYjls3EbvXAhsJgJ6aga+1QYAGZC1sjm1H4xi+rX/6/v9avrJyqP LDDdIGHRibgWWObUlySG44dwWeowAKLXVb/0c8cOmDkpaMGf9zuXWFWaiYC7ZONiysI8aRZ tYxGw5q08X0ZaKBhY/KJipQ6t4geh7WwzPw1z7SGkHMrEu7JTF+CRu7ogYaJgBl1/t7YnC7 awWt01M2VfgBJSxpyyXv+dKXJE3HofF3hxkCxle9IeXanhafF+H7S4rur9dZJQvF2YLiJRi MboYHLA/NCIDT5CTpWsu1ErtCH2x8VXjqRmcx+qDJhyzUd1+REaGc2RXyIXIBz+H0MEwTV/ CJumdcWhTu0hUpExvybxbkN6RoTAJUt5XnjJgOUKPgonyO9BajyPaT9zvne/zavEUPZG09S Z+umtNmao12z8TzrlNyvjvYs4Qjg7X2dUEeT3vuXtJ/U1VR6rP6qidKJMMchjbG3XR6wO6F R/coSq/2wlg7dKxf5q0/y5mcPQabhOyq7ez4NTlQLv5m2SdLM7U+O59r07mbxvWFAV0A9Nn dCVVjS2M2dUFaERvLSPb8ZvYOHFYE= X-QQ-XMRINFO: OD9hHCdaPRBwH5bRRRw8tsiH4UAatJqXfg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge device. Signed-off-by: Chaoyi Chen Reviewed-by: Neil Armstrong Tested-by: Hugh Cole-Baker --- (no changes since v11) Changes in v10: - Use drm_aux_bridge_register_from_node() instead. (no changes since v7) Changes in v6: - Fix depend in Kconfig. --- drivers/phy/rockchip/Kconfig | 2 ++ drivers/phy/rockchip/phy-rockchip-typec.c | 5 +++++ 2 files changed, 7 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=3Dn + depends on DRM || DRM=3Dn + 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/rockch= ip/phy-rockchip-typec.c index 1f5b4142cbe4..e31b778c3537 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -56,6 +56,7 @@ #include #include #include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -1312,6 +1313,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typ= ec_phy *tcphy) if (!of_property_read_bool(np, "mode-switch")) goto put_np; =20 + ret =3D drm_aux_bridge_register_from_node(tcphy->dev, np); + if (ret) + goto put_np; + mux_desc.drvdata =3D tcphy; mux_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "dp-port"); mux_desc.set =3D tcphy_typec_mux_set; --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbgsg2.qq.com (smtpbgsg2.qq.com [54.254.200.128]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B219726FA5B; Mon, 19 Jan 2026 07:32:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.128 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807931; cv=none; b=jLwxZr5LmIKeb2WkLxg4U+P73yTNEDy/ewGQf+Yb+wgeWDNT2oLP4pAGjYhrUCUjma32HGLn5+hEqhO50PzLtgM+J9QqpA36n/ezQ4dBOVjzKclzFCucFUkfh38mlYozz0SjiKpkcGXzIyYRLvX7Jx3Jx1MdYFgTYgB4IBIqfOg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807931; c=relaxed/simple; bh=Zo5rb2kFGKM1wpR7HFPird+yVAzTtbv7BriEoQsoSYA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=q4QZiVnyqTnqC4j0GodwS5YZrZxL5HoY/HRmr0xGD4YBKY6P4HARLkMzRuADmIwimWPMyhZAgV9T00vmlV5R/VdDo7TSrImV0Au8f/pzGWph0ZpQA2CnX1Pj1W+D9rVWWrfYIxwvFQGY8dX+MPrbXPAdi0D30ngGbU7Mnzok17U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=bsXn66gg; arc=none smtp.client-ip=54.254.200.128 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="bsXn66gg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807918; bh=R2+PAKy3j90tO2/aruykNQqG1CqbsF2c64m7OhVP2Wo=; h=From:To:Subject:Date:Message-Id; b=bsXn66ggPNFk7Oan4yn7Ql4bowvViOY28p44wQIUmT0id6vYEtKxgeEY0wg5+8PEl CqpbGVpzAeNsqwZh6Ao74PrL+xcIdFpTrCK9hr5nIYIpJFITGWXflL7X/oUitFtYzv dEB8kpsvPABNB8E5CKrLhmASFwKKTj6PruEkyeps= X-QQ-mid: esmtpsz17t1768807916td2cc47e5 X-QQ-Originating-IP: 3ssUqBNd2o2Knol46BpVfLFCjgBvfw+ahn46Z46w9Z8= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:31:50 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 924543254067491200 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 6/9] drm/rockchip: cdn-dp: Support handle lane info without extcon Date: Mon, 19 Jan 2026 15:30:57 +0800 Message-Id: <20260119073100.143-7-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MVbvI5amSZ2YcLIzxUIrBzKbeXwSVSMKxiEzsA6dGvNwUwuJDMNr1eU+ DWQuZfTvsix0NTXcGPJArZvsHaL7KBUuZ07hGQTsHNjHrSWRJpac+SX7DHRsrAt8RjIkC59 QVtfqPBBf1F264Wpiq0s0PNj3by2s4jRaib7uCCLOLykI1Gz8iwUiauZJP7PwxFZOBvhZGr PfkObAI7rID0WtVu2YNlKdch95+6eHT6tZjLbbfb3N+AQ/ISrtDGzLQpdKygzKYszeXUsLa Y0aIh8TLo/JouIE+5UNHkZVeQbDpb8JIvulSmf9TVkgKMRc5Yq0wJCLDg2iA1wjXC+mUKaX zvYkQPmRA6fqiSe2WJBAS3U31BDd6WaqPX2B8xbZPri+Vma1czTRFgeV5aDMxY8foG6hMZA oMnxJoCVginxyYQoQSnCpyQJoVga4K9rI24vTsObwBKOZT+ZtzGw9+4XJn2yqEoPMSjKTKQ G2fftZw+lekbbpWTSCwPAC+4t+P1lgYQC82j4SzcMjPnkIUYZgeRdC2bDDUIWxIycr4EAIe GNRF3tlhEmOPL7hebv6s7YV9f/6zytFUyGslAcDJAX1r5jyGh0uEnrw6CPpBt1kO/7Zeula 62cdogRS+bTukEHtw9DHw1QfpvRkJOYVDtqnjXL6pc3Qmn0sb6honr22gySTqE42aN59eYJ hkJX8i9pxTrTM2FvPZqWDUcFy1AAwJ8++UjPRTCK0MsodZpJX/QMQ9fU1YEDudya+QnXsHn EV5E+vlULzl6abLOcR2979fB5mM2j7UiG1TJoKsZMLtiOl5jIH71Biwys8V5geJ0rfvlLuJ DLxqds7nC9c66IdmyKiE5W2BVAZbkTwIWmYC/Clkgel6PZWf8/1ut/2yGkK0/Cyasko0oCy kShze33ojXIGZZRlD/SFmy2qQGhcPtbWTlMFIC/4k1gpElainQjs/cW/w+txsi/qEVjbbEv 81Ap9hg97/1mc7Xib+294EmNie8gP0CzrckuFmqGOgSWRcLtXvN2fwtd+MINw8qKb+Ohu3d 5bGOKGKynNAzQ+1LU0z6Jk/sU/nlhbAy8HpfzlPR3ECpawJt6MJBr9Eg1RoZA= X-QQ-XMRINFO: NyFYKkN4Ny6FuXrnB5Ye7Aabb3ujjtK+gg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen This patch add support for get PHY lane info without help of extcon. There is no extcon needed if the Type-C controller is present. In this case, the lane info can be get from PHY instead of extcon. The extcon device should still be supported if Type-C controller is not present. Signed-off-by: Chaoyi Chen Tested-by: Hugh Cole-Baker --- (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/rockc= hip/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 *po= rt) int dptx; u8 lanes; =20 + if (!edev) + return phy_get_bus_width(port->phy); + dptx =3D 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; =20 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; } =20 - ret =3D 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 =3D 0; + if (port->extcon) { + ret =3D 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; + } } =20 port->lanes =3D cdn_dp_get_port_lanes(port); @@ -1028,6 +1034,9 @@ static int cdn_dp_bind(struct device *dev, struct dev= ice *master, void *data) for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; =20 + if (!port->extcon) + continue; + port->event_nb.notifier_call =3D cdn_dp_pd_event; ret =3D devm_extcon_register_notifier(dp->dev, port->extcon, EXTCON_DISP_DP, @@ -1120,14 +1129,14 @@ static int cdn_dp_probe(struct platform_device *pde= v) PTR_ERR(phy) =3D=3D -EPROBE_DEFER) return -EPROBE_DEFER; =20 - if (IS_ERR(extcon) || IS_ERR(phy)) + if (IS_ERR(phy) || PTR_ERR(extcon) !=3D -ENODEV) continue; =20 port =3D devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); if (!port) return -ENOMEM; =20 - port->extcon =3D extcon; + port->extcon =3D IS_ERR(extcon) ? NULL : extcon; port->phy =3D phy; port->dp =3D dp; port->id =3D i; --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbgeu1.qq.com (smtpbgeu1.qq.com [52.59.177.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7BE126FA5B; Mon, 19 Jan 2026 07:32:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.59.177.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807956; cv=none; b=howMlGgkoY6CpRVc03T/tIsl9w/R1UqaO1lvJU+Rs/gWg4H5MO2A2lOUKVtHAUJwfyaDhOs0Pb4UQ5E91KrovY/wPnbK7o/3KTx9RwNvXebbHjleGar4Id1GRwDMBXZxMRZMGa52CMEWpO2VU2timxYxC/jIm4yC7AlSZ5obfpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807956; c=relaxed/simple; bh=3BwA/ttU9IEUvdXqhATE2iPwsKyUXs/WBH64h3udsGE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=GhXs7qD8KUI4xl7MCdI+1zT/2ywjHzw0jrYlWU6XHCdUkOS2Reap987ahFtDbZgE1UdOVXKzpWLNJAkpLA39ga5Odmvo3bMdroEg9gmK52ldRqVL4grbWkK9Bv1mYOK9fvGFJov7QTOzKCYTPTIqvuyEyGkjbwZwR/AdY5RnejA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=IDRZPJkW; arc=none smtp.client-ip=52.59.177.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="IDRZPJkW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807933; bh=2lPU+fzbVxFUN3Mj0wJ2o8bGFSY4BfTyvQaFLnEG0vA=; h=From:To:Subject:Date:Message-Id; b=IDRZPJkWZc35kwnW54CbTcKHEkNSeQa+vEtoaUM4nNDPxl4zaM99SihOgTAsAmKBL 9O/oEllCPnF5kAzNc9NXI/cNL0kYhpUu3GS4tkCktzxGhkVqRbnacvAezhowxa9H2W h/GJBPtZB0seUGEpYwUgYtyMC37J3qBsAoZdZM2k= X-QQ-mid: esmtpsz17t1768807932taaf982bb X-QQ-Originating-IP: zTpAmIjiNfTwcqfKAgm2a1PCfPOo6ca5AGq+sWFW/pA= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:31:58 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 8885856857600727136 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Date: Mon, 19 Jan 2026 15:30:58 +0800 Message-Id: <20260119073100.143-8-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NqGwt1Nz+QGBrgUw+c9+vRkALG7jJEGcxLy4dfCrkR2W/aFvykKWPFjA YnqLF1/BKiLkJ81O34gxLEbn1LtE3HBmvCLBPcZX6FOTZOKwdq6NOXI2rVXapgwx9G/smAh T1CfRnPPjgbunO0Zz9AHbowO24/BzUQ5iMXIq9ih3K1KHFTp3vvZQZTJFhIz490GtDXvmU8 tAO5BAZM3u6iG7r1l2D70VSsEvJ/K0kFkSCo5TiMc6gVcBXToXKfBSzxTY6lMhRDsXW/iKo DN5tAcjJzJ2vV4zjlYvAnfqHHF09JJ47qfjOf++cr5X4a9c0OycdcB9tQsbDe1FDRNWDv5t XanwQEK59z612h6gQ2HTdJl8ZSNzOpoVklRAJv9iXhUPRr8xm3hxymBN1x0edHZtBorMvX3 NYzD8fhA85HZ5hrDqd64eQvMPqJQQyLEataQlbTr2Ipr7IdAjoBrEW9XeDYCx3snc0/6+lT taW5GFW0vTsPMrUA+BwI4aBPyqhbqNmHXbhAjVmBw7A3mehSpb0zbuGBFbOR0hZIv6HJ0fF Ns+CmhDzxpcpD5JPclWs8yHcEYsgQPRiKJhone5v5sR+5444MpJAZEzcP6rU8Fl29a9RoRg zL1VJq7qUeYw5dItDiG58L8HYuQEZbMNC2Sr+ok+fgcwm2uO67mKN6xCifOBxgaq9wp5ZD8 +26vNHvG97szujYb7HZuGRZVqvycxr7sYESzIH9IhCg+8i70jWXIdowTA/nMWT9/StbC852 Pb/IRk4xoSAC7yiFdScIUT8q9unLPP6CFSgWGGyUHfYCcUDAbmCMjq27d1uwRXkavKVwStO 36VSIwnYNYOdD3o3O7Tzz95LoaCnJRWWQWlC2ngfuJbjEhafIdSNrYn8rEXxSW1hsh/+DFg cN+5TcSEJyRHOaqXWegm3f3dL3ZxQuecIDAEbV+KedMUy5DfpDAYwHafh4OVWQxPxuDgORi g8NuDA0r066lyN1cNbpVKsqsq7hd5Odm4jAht0bqfq+qRlisG73d8I6oZUIVbP81JTomRpQ QgeIZ21Zglj2mGRzsHIxPSQGEzEqBD5ghUTG9QAhHjBAuNJDwx X-QQ-XMRINFO: MSVp+SPm3vtSI1QTLgDHQqIV1w2oNKDqfg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And the CDN-DP can be switched to output to one of the PHYs. If both ports are plugged into DP, DP will select the first port for output. This patch adds support for multiple bridges, enabling users to flexibly select the output port. For each PHY port, a separate encoder and bridge are registered. The change is based on the DRM AUX HPD bridge, rather than the extcon approach. This requires the DT to correctly describe the connections between the 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 Tested-by: Hugh Cole-Baker --- (no changes since v11) Changes in v10: - Fix refcount usage of drm_bridge. - Remove unused cdn_dp_next_bridge type. Changes in v9: - Select DRM_AUX_HPD_BRIDGE when using DP driver. (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/Kconfig | 1 + drivers/gpu/drm/rockchip/cdn-dp-core.c | 325 ++++++++++++++++++++----- drivers/gpu/drm/rockchip/cdn-dp-core.h | 18 +- 3 files changed, 287 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kc= onfig index b7b025814e72..10d9f29a3d44 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -56,6 +56,7 @@ config ROCKCHIP_CDN_DP select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR select DRM_DISPLAY_DP_HELPER + select DRM_AUX_HPD_BRIDGE help This selects support for Rockchip SoC specific extensions for the cdn DP driver. If you want to enable Dp on diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index 1e27301584a4..0bc3d248c266 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" =20 -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); } =20 -static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *enco= der) +static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge) { - struct rockchip_encoder *rkencoder =3D to_rockchip_encoder(encoder); - - return container_of(rkencoder, struct cdn_dp_device, encoder); + return bridge_to_dp_bridge(bridge)->parent; } =20 #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]; =20 for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; - lanes =3D cdn_dp_get_port_lanes(port); - if (lanes) + lanes[i] =3D 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 o= rder */ + for (i =3D 0; i < dp->bridge_count; i++) { + if (lanes[i]) + return dp->port[i]; + } + } + return NULL; } =20 @@ -253,12 +267,45 @@ static const struct drm_edid * cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *c= onnector) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); - const struct drm_edid *drm_edid; + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); + struct cdn_dp_port *port =3D dp->port[dp_bridge->id]; + struct cdn_dp_port *prev_port; + const struct drm_edid *drm_edid =3D NULL; + int i, ret; =20 mutex_lock(&dp->lock); + + /* More than one port is available */ + if (dp->bridge_count > 1 && !port->phy_enabled) { + for (i =3D 0; i < dp->bridge_count; i++) { + /* Another port already enable */ + if (dp->bridge_list[i] !=3D dp_bridge && dp->bridge_list[i]->enabled) + goto get_cache; + /* Find already enabled port */ + if (dp->port[i]->phy_enabled) + prev_port =3D dp->port[i]; + } + + /* Switch to current port */ + if (prev_port) { + ret =3D cdn_dp_switch_port(dp, prev_port, port); + if (ret) + goto get_cache; + } + } + drm_edid =3D 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] =3D drm_edid_dup(drm_edid); + mutex_unlock(&dp->lock); + return drm_edid; =20 +get_cache: + drm_edid =3D drm_edid_dup(dp->edid_cache[dp_bridge->id]); + mutex_unlock(&dp->lock); return drm_edid; } =20 @@ -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 =3D bridge_to_dp_bridge(bridge); struct cdn_dp_device *dp =3D bridge_to_dp(bridge); u32 requested, actual, rate, sink_max, source_max =3D 0; u8 lanes, bpc; =20 /* If DP is disconnected, every mode is invalid */ - if (!dp->connected) + if (!dp_bridge->connected || !dp->connected) return MODE_BAD; =20 switch (display_info->bpc) { @@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_dev= ice *dp) return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes)); } =20 +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 =3D cdn_dp_disable_phy(dp, prev_port); + if (ret) + goto out; + ret =3D cdn_dp_enable_phy(dp, port); + if (ret) + goto out; + + ret =3D cdn_dp_get_sink_capability(dp); + if (ret) { + cdn_dp_disable_phy(dp, port); + goto out; + } + + dp->active =3D true; + dp->lanes =3D port->lanes; + + if (!cdn_dp_check_link_status(dp)) { + dev_info(dp->dev, "Connected with sink; re-train link\n"); + + ret =3D cdn_dp_train_link(dp); + if (ret) { + dev_err(dp->dev, "Training link failed: %d\n", ret); + goto out; + } + + ret =3D 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 =3D 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_de= vice *dp, static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct = drm_atomic_state *state) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); struct drm_connector *connector; int ret, val; =20 @@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_brid= ge *bridge, struct drm_at =20 cdn_dp_display_info_update(dp, &connector->display_info); =20 - ret =3D drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.= encoder); + ret =3D drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->e= ncoder.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_brid= ge *bridge, struct drm_at =20 mutex_lock(&dp->lock); =20 + if (dp->next_bridge_valid) + dp->active_port =3D dp_bridge->id; + ret =3D 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_brid= ge *bridge, struct drm_at goto out; } =20 + dp_bridge->enabled =3D true; out: mutex_unlock(&dp->lock); } @@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bri= dge *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 =3D bridge_to_dp(bridge); + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); int ret; =20 mutex_lock(&dp->lock); + dp_bridge->enabled =3D false; =20 if (dp->active) { ret =3D cdn_dp_disable(dp); @@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge = *bridge, return ret; } =20 +static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge, + enum drm_connector_status status) +{ + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); + struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + + dp->bridge_list[dp_bridge->id]->connected =3D status =3D=3D connector_sta= tus_connected; + schedule_work(&dp->event_work); +} + static const struct drm_bridge_funcs cdn_dp_bridge_funcs =3D { .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, @@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_func= s =3D { .atomic_disable =3D cdn_dp_bridge_atomic_disable, .mode_valid =3D cdn_dp_bridge_mode_valid, .mode_set =3D cdn_dp_bridge_mode_set, + .hpd_notify =3D cdn_dp_bridge_hpd_notify, =20 .dp_audio_prepare =3D cdn_dp_audio_prepare, .dp_audio_mute_stream =3D cdn_dp_audio_mute_stream, @@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *wo= rk) { struct cdn_dp_device *dp =3D container_of(work, struct cdn_dp_device, event_work); - int ret; + bool connected; + int i, ret; =20 mutex_lock(&dp->lock); =20 @@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *= work) =20 out: mutex_unlock(&dp->lock); - drm_bridge_hpd_notify(&dp->bridge, - dp->connected ? connector_status_connected - : connector_status_disconnected); + for (i =3D 0; i < dp->bridge_count; i++) { + connected =3D dp->connected && dp->bridge_list[i]->connected; + drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge, + connected ? connector_status_connected + : connector_status_disconnected); + } } =20 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; } =20 -static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +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 =3D dev_get_drvdata(dev); - struct drm_encoder *encoder; + struct drm_device *drm_dev =3D dp->drm_dev; + struct drm_bridge *last_bridge __free(drm_bridge_put) =3D NULL; struct drm_connector *connector; - struct cdn_dp_port *port; - struct drm_device *drm_dev =3D data; - int ret, i; - - ret =3D cdn_dp_parse_dt(dp); - if (ret < 0) - return ret; - - dp->drm_dev =3D drm_dev; - dp->connected =3D false; - dp->active =3D false; - dp->active_port =3D -1; - dp->fw_loaded =3D false; - - INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); - - encoder =3D &dp->encoder.encoder; + int ret; =20 encoder->possible_crtcs =3D drm_of_find_possible_crtcs(drm_dev, dev->of_node); @@ -1002,26 +1108,35 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) =20 drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs); =20 - dp->bridge.ops =3D - DRM_BRIDGE_OP_DETECT | - DRM_BRIDGE_OP_EDID | - DRM_BRIDGE_OP_HPD | - DRM_BRIDGE_OP_DP_AUDIO; - dp->bridge.of_node =3D dp->dev->of_node; - dp->bridge.type =3D DRM_MODE_CONNECTOR_DisplayPort; - dp->bridge.hdmi_audio_dev =3D dp->dev; - dp->bridge.hdmi_audio_max_i2s_playback_channels =3D 8; - dp->bridge.hdmi_audio_spdif_playback =3D 1; - dp->bridge.hdmi_audio_dai_port =3D -1; - - ret =3D devm_drm_bridge_add(dev, &dp->bridge); + bridge->ops =3D + DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | + DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_DP_AUDIO; + bridge->of_node =3D dp->dev->of_node; + bridge->type =3D DRM_MODE_CONNECTOR_DisplayPort; + bridge->hdmi_audio_dev =3D dp->dev; + bridge->hdmi_audio_max_i2s_playback_channels =3D 8; + bridge->hdmi_audio_spdif_playback =3D 1; + bridge->hdmi_audio_dai_port =3D -1; + + ret =3D devm_drm_bridge_add(dev, bridge); if (ret) return ret; =20 - ret =3D drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_N= O_CONNECTOR); + ret =3D drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CON= NECTOR); if (ret) return ret; =20 + if (next_bridge) { + ret =3D drm_bridge_attach(encoder, next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ret; + + last_bridge =3D drm_bridge_chain_get_last_bridge(bridge->encoder); + } + connector =3D drm_bridge_connector_init(drm_dev, encoder); if (IS_ERR(connector)) { ret =3D PTR_ERR(connector); @@ -1029,8 +1144,100 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) return ret; } =20 + if (last_bridge) + connector->fwnode =3D fwnode_handle_get(of_fwnode_handle(last_bridge->of= _node)); + drm_connector_attach_encoder(connector, encoder); =20 + return 0; +} + +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp) +{ + struct device_node *np =3D dp->dev->of_node; + struct device_node *port __free(device_node) =3D of_graph_get_port_by_id(= np, 1); + struct drm_bridge *bridge; + int count =3D 0; + int ret =3D 0; + int i; + + /* If device use extcon, do not use hpd bridge */ + for (i =3D 0; i < dp->ports; i++) { + if (dp->port[i]->extcon) { + dp->bridge_count =3D 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) =3D + of_graph_get_remote_port_parent(dp_ep); + + bridge =3D of_drm_find_bridge(next_bridge_node); + if (!bridge) { + ret =3D -EPROBE_DEFER; + goto out; + } + + drm_bridge_get(bridge); + dp->next_bridge_valid =3D true; + dp->next_bridge_list[count] =3D bridge; + count++; + } + +out: + dp->bridge_count =3D count ? count : 1; + return ret; +} + +static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +{ + struct cdn_dp_device *dp =3D dev_get_drvdata(dev); + struct drm_bridge *bridge, *next_bridge; + struct drm_encoder *encoder; + struct cdn_dp_port *port; + struct drm_device *drm_dev =3D data; + struct cdn_dp_bridge *dp_bridge; + int ret, i; + + ret =3D cdn_dp_parse_dt(dp); + if (ret < 0) + return ret; + + ret =3D cdn_dp_parse_next_bridge_dt(dp); + if (ret) + return ret; + + dp->drm_dev =3D drm_dev; + dp->connected =3D false; + dp->active =3D false; + dp->active_port =3D -1; + dp->fw_loaded =3D false; + + for (i =3D 0; i < dp->bridge_count; i++) { + dp_bridge =3D 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 =3D i; + dp_bridge->parent =3D dp; + if (!dp->next_bridge_valid) + dp_bridge->connected =3D true; + dp->bridge_list[i] =3D dp_bridge; + } + + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + bridge =3D &dp->bridge_list[i]->bridge; + next_bridge =3D dp->next_bridge_list[i]; + ret =3D cdn_bridge_add(dev, bridge, next_bridge, encoder); + if (ret) + return ret; + } + + INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); + for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; =20 @@ -1058,10 +1265,18 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) static void cdn_dp_unbind(struct device *dev, struct device *master, void = *data) { struct cdn_dp_device *dp =3D dev_get_drvdata(dev); - struct drm_encoder *encoder =3D &dp->encoder.encoder; + struct drm_encoder *encoder; + int i; =20 cancel_work_sync(&dp->event_work); - encoder->funcs->destroy(encoder); + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + encoder->funcs->destroy(encoder); + drm_bridge_put(dp->next_bridge_list[i]); + } + + for (i =3D 0; i < MAX_PHY; i++) + drm_edid_free(dp->edid_cache[i]); =20 pm_runtime_disable(dev); if (dp->fw_loaded) @@ -1112,10 +1327,10 @@ static int cdn_dp_probe(struct platform_device *pde= v) int ret; int i; =20 - dp =3D devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge, - &cdn_dp_bridge_funcs); - if (IS_ERR(dp)) - return PTR_ERR(dp); + dp =3D devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + dp->dev =3D dev; =20 match =3D 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/rockc= hip/cdn-dp-core.h index e9c30b9fd543..c10e423bbf06 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 =3D 0x10, }; =20 +struct cdn_dp_device; + struct video_info { bool h_sync_polarity; bool v_sync_polarity; @@ -63,16 +65,28 @@ struct cdn_dp_port { u8 id; }; =20 +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_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 drm_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; =20 struct mutex lock; + bool next_bridge_valid; bool connected; bool active; bool suspended; --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbg150.qq.com (smtpbg150.qq.com [18.132.163.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 06FA133033B; Mon, 19 Jan 2026 07:32:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=18.132.163.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807961; cv=none; b=OLneiP6h41+ZFYTbGsW41yd4I+PPPht1R94YJPPeLTDFZ8vwkcPUwN4WmMy9Kb2UU2b4eBjGCNQK+sASBSKdwKEymOdKBvuBdtuFo5Eky1Tp4ArusLhEYi0ftMANgALYcOCkLY9hIdw2N6dRxFHyTJvfMBB1pVHz1WA0hSMPjxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807961; c=relaxed/simple; bh=4YalIBUlKCSuqLKMYj8QW21cucOEQ0PxecICR8IYRKQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=b1WPs5QVU0RSB9Nlu/ST+f0bquQRI+qR5VJPW9RY70JskzPA4xQky2BOlqWhFb94AsdYUoVoIh/3sGf1uxBIWsrZYJnPELtty97yESPa1ldM8+UGzcy9EBrTvo2ZVWkHob4137naFDqhnjqpPButjwT5NZ2ebcnQwkNntTsqkbw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=m0+VERdE; arc=none smtp.client-ip=18.132.163.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="m0+VERdE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807941; bh=6RKYrl9uKKYeoPLwxT7m43ODsBqPn7Ulx0XyJQsA0lM=; h=From:To:Subject:Date:Message-Id; b=m0+VERdEZM6EZ4VXwKxHdkutXvYXh0i86jixhGzmeNofFppwD87p1h23h+92MhTu7 wmANYB4hSWh5PqdIBlvfl2kQ/jbcCKOObLU2dqHQzgW2eDnE1vO2accU0zQlb1O9+f tLggGOtOLAtVPmk3/5BvnrL2TUhzaRhZpTJs9+lQ= X-QQ-mid: esmtpsz17t1768807939t4e3bec3b X-QQ-Originating-IP: A7VIZcKkSbUgehWQYkOQDZdSzfyBv0nlR5sBVFW6EVM= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:32:13 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 6769309788427873216 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 8/9] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Date: Mon, 19 Jan 2026 15:30:59 +0800 Message-Id: <20260119073100.143-9-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NYz8c2bcbB9MwYPtkRmeV685CCQEbaHYbdVAlNW1i8mIqEI9wr5ymJFH i2U8PqeMY3EYrAvElS/FSB+OttyIva5bAt7/oIx8ueqifTFJWVOUFHZx2u3OAtEqpO7hXvV 8FlmEbSFBcfKb3q7bX3+YEx3NQ537AickZKpqNtupsh+wqqKcLzZJLbEifq3PYRsYGGfTQg KDa6KG0JM1KSHTRKMgeeSH/Y3477gqk4k5EdijIJAbJ6UVq5PdaV3btHCFmVPJ9Hb3BnwI0 iRD5cIgQ1UpwX4f7ZV04ahml3LNtc9vPv0EU9oI7S+zGYezsz25p34tOIf+0z9hZc2zggcT MHMSB3bFjqb5uwkCfGRY4enPNe2+iLynz53/Ap9TPBWfTZ/eI9V0jf/pPKHsAmRc/++5PYH gWMUQeHoLp/IswS5Mq39f3X4afvNUU4bUz88qd5oJHEKczDDJ1Kd4FRRo5GLiHN28RK46bA GZJrfUOdbkwwxJCBTPZm1gR30Ejiqh9kEk1hP+CWqro2YETCNGa/2nu4jstI+kCLrGSNkuf gunWRMMA+jN06+QmcONlJDYhuzlAG4yro/3tfTUR5XfFBMF08kJXtFJEfKJuv7PVHE20KPM aGpf4vvrYQnqulKLJrYLxxC4uy3dae0fXz+DY2ItOA2bICK4jDB5PBV69FORjyj5xkjPoKZ IkfNE8WYeak1CQ1ohfztehnoPdQtePTlGEVBV+y5ivBopzb0LuFfLI1h6OuZ8sE9JJ8Szht 5K8uEaHPJuFMVK0sMPs+zSNRsdsRDaGlCY2Ha8imFFPPpKsAkTaj2/KbrAewMnVEuZJR2ug Ke+u3vY5v/L8gUQp6ySxzZLUezgePjqzKmJG46M3p61dKq1qHnxdx/xxxM0Lt9j+itA1H36 3xgT9KHr+czixhXJ2N+TIoW0gxB3dBQDopUV4GaxGT0P6U4eOtycwmwvGEzMUkugr5L1DAv F06N6/uf91E/xy2wku5s1e7ylUERLWqsXooEc7LdV6FpSG6JOcoLB8CwON0v2sTCJ6BDnPy luj6GXIoX18vYJHyHsPFcchD8rZd5FCi8rXS6zxA== X-QQ-XMRINFO: M/715EihBoGS47X28/vv4NpnfpeBLnr4Qg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen Let's make the ports nodes of cdn_dp in the same style as the other display interface, and match the style of ports's yaml. Signed-off-by: Chaoyi Chen Tested-by: Hugh Cole-Baker --- (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/boo= t/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 =3D "disabled"; =20 ports { - dp_in: port { + #address-cells =3D <1>; + #size-cells =3D <0>; + + dp_in: port@0 { + reg =3D <0>; #address-cells =3D <1>; #size-cells =3D <0>; =20 @@ -632,6 +636,10 @@ dp_in_vopl: endpoint@1 { remote-endpoint =3D <&vopl_out_dp>; }; }; + + dp_out: port@1 { + reg =3D <1>; + }; }; }; =20 --=20 2.51.1 From nobody Sat Feb 7 05:01:44 2026 Received: from smtpbgau2.qq.com (smtpbgau2.qq.com [54.206.34.216]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C274127991E; Mon, 19 Jan 2026 07:32:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.206.34.216 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807983; cv=none; b=uOTdeELWlDcyOuQAoL9Zzr/x7B4kW3ZWFxnVGv368NuGLzonXN94vcy8d93iNpgVXRptWFT8kjEVBrfH7Q6koRfEJTtw+YP3c/XdgKaX9KKD96CjFg7pJ76r7p/yRs4bB1PJVQlEiicSLnuaQpP0Q3vGtJESTqleZUcAlGGZmfk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768807983; c=relaxed/simple; bh=wFnaLVPpDQm//bP6iFP69Ahx9vGyahry2cq4Wey0uVw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=HOes3FjbEB/3VbU+0gy3boDkp0sf6m9C9d5gEQweUAjsL2hbx6ImzsgniR5Qyt84PTvbd3wREIFEtd/CSn441Eyo9rluwDqCaJ3qkvTmJw4u7svEpkE0xZsq5JyOHHf3o95Plkea0uy60YVefA+08/4+DXz9vcgqhtzVMsq+XKY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com; spf=pass smtp.mailfrom=airkyi.com; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b=JR3kSHVA; arc=none smtp.client-ip=54.206.34.216 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="JR3kSHVA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1768807949; bh=U0ahzAOwsK3I30DVXt7Ne0dyRxyxzPxU5WVcboIAjPU=; h=From:To:Subject:Date:Message-Id; b=JR3kSHVA6czN1Hfs6EmBfPpqLufzbFUFrVXa0w6FgA9ALhKWpoHCEoeiJmDea3Ii8 zPN72i39Tp7txSZdlTw+s4MPf/YUKuC4HMxXBPJ57JIM64Y5CUU03Lu7/p0pV+b4YU yvRjoh3YJ/k/gHLQFGVg+DoaHBnCYSBb9Pgc7Tcg= X-QQ-mid: esmtpsz17t1768807947t6c620025 X-QQ-Originating-IP: 4/DQe9zBJPz+u7arfEakRzgFkkH4PMCGXrVkOz+gmz8= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 19 Jan 2026 15:32:21 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 9088237500228411525 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , Luca Ceresoli , 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@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v14 9/9] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Date: Mon, 19 Jan 2026 15:31:00 +0800 Message-Id: <20260119073100.143-10-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260119073100.143-1-kernel@airkyi.com> References: <20260119073100.143-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NFNrK8KlcSCRWT5gKTpomERfTBWZBEWLNm7vkYvxJ0BFkXG6eKFhOBbs pryx8J9fojFRJePxoLUQmiYekFPx/kkKIz+DTEO/IsoY57n9N6iVidK1XczeG4nP5Tf8VYC CPvqyVsXFIARR2yi0JIwiBbY1LjCx7nykUYASF2wwxQFQIaAchOsbKsb/iAL+duZuMzPvcu ejYx3PJEpi21o3qbNoTR8ZGpmsT+F/VpVoyucBgizC59QK0ywL38ypBoYM3HuNdlWpcNwya R43BYjKC9HIEwbYDtTDhXL+1PvBLrDSvPgSmiClnzeiRLuFVaDp5D4MQUePqH1ocFk1Ec23 OzuBNNwsauYRCRZg5Mo+6w75TT5PKs5oUzhNctrAiCxOXm/cdU5xjdicpDw9FgdnHi/yrmw cpgDyr2iwqsXrHX6+r5w+fR6WBwbPR4KcBCrt2u4xm3xkLJldTJLvTC6xgH6PhVBU+iR970 PBe8ejw9jLUESHS2/rsKihWCvSIyrgX9iPeaW5zlx0zVSCpFk0PpECARyeVCk/01cwYU1w6 2sK4CXSKnyX4Z5E7FZwAFR+6SB64lkVfVuRFw+a8qNgXvCW0OwHPdtXzU5+1ieAKJZizbEQ a0w0En0Tc1Tp4QPI4zp42xvdaJ9K2aBvYG2lF4CDpFT3/HXMQi9FdONl0tvEY+9VUR8MoaN X3Z5fAOc2Xp125wxoxqlacrDW8J83u1vxpWnF1jeGttHy4g4gRU4yq72p0sSjmaQaEHwxKD dugBh6t5RwicINv0KoUOjU9f57gwAhrf/KYW2ImiB3sR+bDyigd63/KdLh/xSsyWHkOwWUt bJdTVuBzoTN00XrV59MUSD1Mf0fx7Nq1qwnpUA0uVjW0ef6jVPcLMlJitPv2pqRdt3Qozir JVNwnRaNsoGEDmfCsLRk3QshwDQsRSx9e4xlMCn/bRWOgpqEgRJja7m50RppXjEOQW2GEqr uvwnCSb+Fo9XRak+ODlySqDJDzX/3dbMrZor4eRp/RAz6FFcYJNnP8ORDOQEVXSoeImi8lI Tq0/GwJ70GuvijEyFk X-QQ-XMRINFO: Nq+8W0+stu50tPAe92KXseR0ZZmBTk3gLg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The RK3399 EVB IND board has a Type-C interface DisplayPort. It use fusb302 chip as Type-C controller. fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller Signed-off-by: Chaoyi Chen Tested-by: Hugh Cole-Baker --- (no changes since v10) Changes in v9: - Add usb role switch for Type-C. - Remove USB2 PHY in Type-C connection. (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 | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/b= oot/dts/rockchip/rk3399-evb-ind.dts index 70aee1ab904c..be1e90f7a453 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 @@ */ =20 /dts-v1/; +#include #include "rk3399.dtsi" =20 / { @@ -19,6 +20,21 @@ chosen { stdout-path =3D "serial2:1500000n8"; }; =20 + sound: sound { + compatible =3D "rockchip,rk3399-gru-sound"; + rockchip,cpu =3D <&i2s0 &spdif>; + }; + + vbus_typec: regulator-vbus-typec { + compatible =3D "regulator-fixed"; + enable-active-high; + gpio =3D <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&vcc5v0_typec0_en>; + regulator-name =3D "vbus_typec"; + vin-supply =3D <&vcc5v0_sys>; + }; + vcc5v0_sys: regulator-vcc5v0-sys { compatible =3D "regulator-fixed"; enable-active-high; @@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys { }; }; =20 +&cdn_dp { + phys =3D <&tcphy0_dp>; + status =3D "okay"; +}; + &cpu_b0 { cpu-supply =3D <&vdd_cpu_b>; }; @@ -55,6 +76,12 @@ &cpu_l3 { cpu-supply =3D <&vdd_cpu_l>; }; =20 +&dp_out { + dp_controller_output: endpoint { + remote-endpoint =3D <&dp_phy_in>; + }; +}; + &emmc_phy { status =3D "okay"; }; @@ -341,6 +368,71 @@ regulator-state-mem { }; }; =20 +&i2c4 { + i2c-scl-rising-time-ns =3D <475>; + i2c-scl-falling-time-ns =3D <26>; + status =3D "okay"; + + usbc0: typec-portc@22 { + compatible =3D "fcs,fusb302"; + reg =3D <0x22>; + interrupt-parent =3D <&gpio1>; + interrupts =3D ; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&usbc0_int>; + vbus-supply =3D <&vbus_typec>; + + usb_con: connector { + compatible =3D "usb-c-connector"; + label =3D "USB-C"; + data-role =3D "dual"; + power-role =3D "dual"; + try-power-role =3D "sink"; + op-sink-microwatt =3D <1000000>; + sink-pdos =3D + ; + source-pdos =3D + ; + + altmodes { + displayport { + svid =3D /bits/ 16 <0xff01>; + vdo =3D <0x00001c46>; + }; + }; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + + usbc0_orien_sw: endpoint { + remote-endpoint =3D <&tcphy0_orientation_switch>; + }; + }; + + port@1 { + reg =3D <1>; + + usbc0_role_sw: endpoint { + remote-endpoint =3D <&dwc3_0_role_switch>; + }; + }; + + port@2 { + reg =3D <2>; + + dp_altmode_mux: endpoint { + remote-endpoint =3D <&tcphy0_typec_dp>; + }; + }; + }; + }; + }; +}; + &i2s2 { status =3D "okay"; }; @@ -354,6 +446,16 @@ &io_domains { }; =20 &pinctrl { + usb-typec { + usbc0_int: usbc0-int { + rockchip,pins =3D <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vcc5v0_typec0_en: vcc5v0-typec0-en { + rockchip,pins =3D <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int_l: pmic-int-l { rockchip,pins =3D <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; @@ -400,10 +502,48 @@ &sdmmc { status =3D "okay"; }; =20 +&sound { + rockchip,codec =3D <&cdn_dp>; + status =3D "okay"; +}; + +&spdif { + status =3D "okay"; +}; + &tcphy0 { status =3D "okay"; }; =20 +&tcphy0_dp { + mode-switch; + + port { + #address-cells =3D <1>; + #size-cells =3D <0>; + + tcphy0_typec_dp: endpoint@0 { + reg =3D <0>; + remote-endpoint =3D <&dp_altmode_mux>; + }; + + dp_phy_in: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&dp_controller_output>; + }; + }; +}; + +&tcphy0_usb3 { + orientation-switch; + + port { + tcphy0_orientation_switch: endpoint { + remote-endpoint =3D <&usbc0_orien_sw>; + }; + }; +}; + &tcphy1 { status =3D "okay"; }; @@ -461,7 +601,14 @@ &usb_host1_ohci { }; =20 &usbdrd_dwc3_0 { + usb-role-switch; status =3D "okay"; + + port { + dwc3_0_role_switch: endpoint { + remote-endpoint =3D <&usbc0_role_sw>; + }; + }; }; =20 &usbdrd3_0 { --=20 2.51.1