From nobody Sat Feb 7 14:34:22 2026 Received: from smtpbgbr1.qq.com (smtpbgbr1.qq.com [54.207.19.206]) (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 34D9913D2B2 for ; Thu, 23 Oct 2025 03:31:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.207.19.206 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190324; cv=none; b=Zy12Vq+9aLwbpCJUQJZha6Zr066ae6znBfErO7F1czBdKGlaJeu/XdX1xaGtKoeGrtRFzQLzXQvhW4jptxR6Wqaf6kdjcKW9oQ5ArnHRXo2k1sb7MzqVxdD9Esn7CQTwoBZ+fjsV4Th4MmLxxEzKntHfUgCxVbUd6uRKwZW7BMA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190324; c=relaxed/simple; bh=Km0tnPpSvB7hKaQPVLRA5Qgjl88/xHP2CenuDJI6+u8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=FGDXRsMTHMh1uKG9HFFcUU2TthKeegOywfzctj0AMW9s2mGCo4uOrcrqahwd+d2spREvzI5vytb+ErGcvtWXEtf4399P3IdrLZ1PRcnaSFvLR2TJAwkRXVgeeA+MQHhyiLg/+JdMYKR2iHfNYkebQL8fIZKe/VQvaUmruYfHdSQ= 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=fvQh5Rx/; arc=none smtp.client-ip=54.207.19.206 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="fvQh5Rx/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190228; bh=z3Z+FuiRydfa9KXtfzUasAoRXAzbkbbUPpgJYhzIq0U=; h=From:To:Subject:Date:Message-Id; b=fvQh5Rx/qOdUPwL/NmSRGR/O9HBASU/O5L60P0fi0XssvgAV+Y9TPUnGudA584Uxd BbAhG5kwanEqIjneHVpoxEr5qcJ5Ih3idZVeqmdgGPD+b+gbmkv4/md71spaIdtdw2 ZCfpaeTMTENtbrIEacWHQlviev0pB0iumuS44X7s= X-QQ-mid: esmtpsz16t1761190226t700443f6 X-QQ-Originating-IP: CR3cgQmOsWIwA9RJdPHoa1hKzkyO00I9vsk6MHfqamI= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:21 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 8850868920315239972 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 1/9] usb: typec: Add notifier functions Date: Thu, 23 Oct 2025 11:30:01 +0800 Message-Id: <20251023033009.90-2-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: N9DIJtFs/avns4hvy0i9PlTO1llTc6+s5DYNrWvUUGtIy9BgBfmcWslQ 1UTPV5mBaQDktx8W5kLRsCl6ibq5kbjHck7obp8QhRFSjAoZt6JUi7p5HQ7spXZN1mHCrJH QyNNHkC4cXqKg/ECqvNQ1sqgVJFCz92Eh+6mCtmcw261pLPHY1ZtRvE23Z/I0AKQ+bsSS7U o6ocUzGUDM65QCwpfGB4X7goi+A91idEFwsl2wp4Wan6sKZVtHqIaUr0K3MxqFgsi2jZIzs i9Q8RINJrcf86xyZxKDRl8rV2SBQAq61jPlPXwikXqyEZS1+cqHvkhB2+h/FSmC+YmefBMa 2Z8Oy7+F3FvnRQhHa02kww/d6e6RoCQ4T4JF76FNkmGFqfvFHddrygNtIuysC4PUHSuIa4X 9C14/2XdN86zzv9Qc9/BaqHGC1ubCpogMByZTZ/eGtr9T1r3DdKZFsdO0fpY4Tbm0urdmYc XIqjU11npO2M9c5O+yT1L2IN1SE6farad0FJHjhQirZOfY3wKlmaUfuPNQ9B9+KC5BeR3xt qVWzH6fQBFRl7cCHrWftcbUaxh8P37Gtrf7JHHa1bUuS9cbwiPG78Dxc1dBbirhvtouJhsy DfeC+uG9DauwTI0fcChRtD5NFEGFhs8YuPPIwrTVYfKA9o6gt8oOMLJH3uTzgO+iPhe7mvz N5w14N/RzoUcatyc0h4/R16/jl8ZaABi/OTyx7nUR4mKAtsaDrVqC9uHCDVadV+N+Kc/4+/ YPkpvUER8desoALEvxl3iM/q27iHPd7/nFmXpjMlKUNJoDIjyIjkAC4Cej6omKYVpKgQJqs gbLKbX+VdJgTLbYNng2fGaeWFPuoDWESdlw13TW4sUWiqbXkH2el45gEeyh2r42yO5NRxzT yyibbI+hs6naBC7N7mXogZ29J0nAoHGJPaRZRI79XUaUlTSFgsMaw4RzlP3cGqAkhEieGGx Ofo0AhMtwH7dj5g+OrqhRspGpLlwc6T7KwICTwgiWatNvLnn5iWjDsHVtOXDc7Nl0zVE= X-QQ-XMRINFO: NS+P29fieYNw95Bth2bWPxk= 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 Some other part of kernel may want to know the event of typec bus. This patch add common notifier function to notify these event. Signed-off-by: Chaoyi Chen --- drivers/usb/typec/Makefile | 2 +- drivers/usb/typec/class.c | 3 +++ drivers/usb/typec/notify.c | 22 ++++++++++++++++++++++ include/linux/usb/typec_notify.h | 17 +++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/typec/notify.c create mode 100644 include/linux/usb/typec_notify.h diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 7a368fea61bc..20d09c5314d7 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TYPEC) +=3D typec.o -typec-y :=3D class.o mux.o bus.o pd.o retimer.o +typec-y :=3D class.o mux.o notify.o bus.o pd.o retimer.o typec-$(CONFIG_ACPI) +=3D port-mapper.o obj-$(CONFIG_TYPEC) +=3D altmodes/ obj-$(CONFIG_TYPEC_TCPM) +=3D tcpm/ diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 67a533e35150..11c80bc59cda 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include =20 @@ -600,6 +601,8 @@ typec_register_altmode(struct device *parent, return ERR_PTR(ret); } =20 + typec_notify_event(TYPEC_ALTMODE_REGISTERED, &alt->adev); + return &alt->adev; } =20 diff --git a/drivers/usb/typec/notify.c b/drivers/usb/typec/notify.c new file mode 100644 index 000000000000..4ae14dd1f461 --- /dev/null +++ b/drivers/usb/typec/notify.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +static BLOCKING_NOTIFIER_HEAD(typec_notifier_list); + +int typec_register_notify(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&typec_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(typec_register_notify); + +int typec_unregister_notify(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&typec_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(typec_unregister_notify); + +void typec_notify_event(unsigned long event, void *data) +{ + blocking_notifier_call_chain(&typec_notifier_list, event, data); +} diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_not= ify.h new file mode 100644 index 000000000000..a3f1f3b3ae47 --- /dev/null +++ b/include/linux/usb/typec_notify.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __USB_TYPEC_NOTIFY +#define __USB_TYPEC_NOTIFY + +#include + +enum usb_typec_event { + TYPEC_ALTMODE_REGISTERED +}; + +int typec_register_notify(struct notifier_block *nb); +int typec_unregister_notify(struct notifier_block *nb); + +void typec_notify_event(unsigned long event, void *data); + +#endif /* __USB_TYPEC_NOTIFY */ --=20 2.49.0 From nobody Sat Feb 7 14:34:22 2026 Received: from smtpbgsg1.qq.com (smtpbgsg1.qq.com [54.254.200.92]) (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 BD8DF2DC777 for ; Thu, 23 Oct 2025 03:32:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.92 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190362; cv=none; b=ogi5VUDix+jpWOKdaNLBNuKUaQ89KFJZ/JGawjW0hprmCc8MiTgEUWBa9ytofp/dDlFL9uzihaJGkLTBjRlmbQmyFTvWaDZ5BKMzQzQfzI9vnPQQGL4utpwQcofgjWzER+S1hQH8A5VQlZbKBaLGNUnuEg0MRoidjIKYSur4Rps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190362; c=relaxed/simple; bh=VHSKA2HFsM9+jjFn1th+KI+Eh4o3xbpE+Vm5UfGT46M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=jP7UqqbKQCH1UcAkmcWNevbzTc3U3wjybINpR087cvLv4ZSePMOl1SRfaNgZO3/I8L6f4IrPwIVj7M4cgcqlVymn9a69n6TB/mTC7O5EwZfvIp1SyOJEuG7iHN3/cfbaphv+YIXsychUfCnrs38WQnNecIJbl9JIxL1uoFKI84s= 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=OXkT7nnh; arc=none smtp.client-ip=54.254.200.92 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="OXkT7nnh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190234; bh=umNcsJfQXn20u9b8R1M4KUZg1ShG0gK3GbHIbkBThtI=; h=From:To:Subject:Date:Message-Id; b=OXkT7nnhBVPpNBUhTmED0A8BDwM39R6EvAktks43nN8Htg5clFG0Nac3yuGHSjq4h msBCY1Fnag+1s1uCKTQ5XkTruWcoIJMWHBGT/xsrKMkNkloTBF+DUFZS7RtREC4STP vm7oD1UdQ5c7a1EU49AaAfVNF/MbW0rR/Pynrzfw= X-QQ-mid: esmtpsz16t1761190231tebd0ea05 X-QQ-Originating-IP: lmB1WZeKvtf5VM4hJL0jYLeppT9A2VeZOLIbFh5pRJk= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:27 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 18264625426006429648 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 2/9] drm/bridge: Implement generic USB Type-C DP HPD bridge Date: Thu, 23 Oct 2025 11:30:02 +0800 Message-Id: <20251023033009.90-3-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: MI8xiyr9SLuAXVPvvA1fD2USjttncnOPXxABKJaZLl1ydENCdNmpS63R /3diLaEzy1tctr5bPdOlG6ijcyH7URCdTO7f0CgLK30QUnJsul2FUH/Yl61mmhWQrGH2R/C 3XZQx9IX+QypkmlztuZxvqGhKXgT+S6dl6vGyakfhW7zNdqwAjXdfy6IUv7DvfavhETi/aH 1E2ov4ryHoZ7pfbG2/Ql64KTxF5sAOoRublXLVqHL7lG/MvsfuW2wupYlgkTfE0xo3c2uWo gwD3OTUpQQmil5oXLn8cl4ZvwBsaxjPZmKgcPO9ki17/xN3uve6pU70f7vzTayO+JulfWJJ MvnH24f+F9xYo379DYa/xiwJyHY1V9f53hXWpZbphFlEty12+5dfNzEYvnE8gVbupjgF+ZN iS9qya1raE0GMR8Uw56f22XYaUatjLH9Ccfk+ZXwnqK1/+wBUKJ4a1dfGJKAyFnawOVJqQn 4lUQb+jcdCPalhB/Uf34w0duWqIlVhWfBbIAN5uK5uv4UunTvGaeP6U0uxxFPLF2eLbXmcz 7B0BAPTjdwV9HeQLjeqDXizRGeYmBHZNwLSUcGLR5w0LoqII2CeKD0khkWqyM4TL+9Ue0tF 6toF7YGbwOlhXRQDTXqmRRk9VKE89ZgmLW6mdGDAwNCFw1bXJ2FtbO8t8WYd7qIsIFU0/T4 HU5lbyMlMHgQWEmYa3uyZTGjwFx23HM8YQ/iua5i0iGIDs7/Fd+8cR/aqtkkXQ7ffOYv/6g vXj0As+FBqvRfoIoNHsdlIZ6VA/4wGidqlN1RB/6X/Tv5cFDi20KAzzvSMpl5s0I6MIFE0U rOU7pYiTVWWmIQbza04Z+E+lVPmti/F8uS3j38tyAvnveXB1APrAOhPqZ/FGaP0rQKV3rM9 9GjC2D9Qy77rCCA3wpP6Pq6FaIWdtQMiwxxD7gYjqBkCq/doN46EvwlSyjUoqngRdAgNi3C oGHX/GG55I6wCgreezRdIYkWaheljyOGFgbZ8aR3TLOdsAjAMPCLdmIqNhc+VlXHziButfr QWGByxWagGAOyN8dO9zjfqBw5c9z4= X-QQ-XMRINFO: OWPUhxQsoeAVDbp3OJHYyFg= 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 Several USB-C controller drivers have already implemented the DP HPD bridge function provided by aux-hpd-bridge.c, but there are still some USB-C controller driver that have not yet implemented it. This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c, so that other USB-C controller drivers don't need to implement it again. Signed-off-by: Chaoyi Chen --- drivers/gpu/drm/bridge/Kconfig | 11 ++++ drivers/gpu/drm/bridge/Makefile | 1 + .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 51 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index b9e0ca85226a..9f31540d3ad8 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -33,6 +33,17 @@ config DRM_AUX_HPD_BRIDGE menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE =20 +config DRM_AUX_TYPEC_DP_HPD_BRIDGE + tristate "TypeC DP HPD bridge" + depends on DRM_BRIDGE && OF && TYPEC + select DRM_AUX_HPD_BRIDGE + help + Simple USB Type-C DP bridge that terminates the bridge chain and + provides HPD support. + + If the USB-C controller driver has not implemented this and you need + the DP HPD support, say "Y" or "m" here. + config DRM_CHIPONE_ICN6211 tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makef= ile index 245e8a27e3fc..e91736829167 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_AUX_BRIDGE) +=3D aux-bridge.o obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) +=3D aux-hpd-bridge.o +obj-$(CONFIG_DRM_AUX_TYPEC_DP_HPD_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..2235b7438fe9 --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include +#include + +#include + +static int drm_typec_bus_event(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct typec_altmode *alt =3D (struct typec_altmode *)data; + + if (action !=3D TYPEC_ALTMODE_REGISTERED) + goto done; + + if (alt->svid !=3D USB_TYPEC_DP_SID) + goto done; + + /* + * alt->dev.parent->parent : USB-C controller device + * alt->dev.parent : USB-C connector device + */ + drm_dp_hpd_bridge_register(alt->dev.parent->parent, + to_of_node(alt->dev.parent->fwnode)); + +done: + return NOTIFY_OK; +} + +static struct notifier_block drm_typec_event_nb =3D { + .notifier_call =3D drm_typec_bus_event, +}; + +static void drm_aux_hpd_typec_dp_bridge_module_exit(void) +{ + typec_unregister_notify(&drm_typec_event_nb); +} + +static int __init drm_aux_hpd_typec_dp_bridge_module_init(void) +{ + typec_register_notify(&drm_typec_event_nb); + + return 0; +} + +module_init(drm_aux_hpd_typec_dp_bridge_module_init); +module_exit(drm_aux_hpd_typec_dp_bridge_module_exit); + +MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE"); +MODULE_LICENSE("GPL"); --=20 2.49.0 From nobody Sat Feb 7 14:34:22 2026 Received: from smtpbgjp3.qq.com (smtpbgjp3.qq.com [54.92.39.34]) (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 904E829B789 for ; Thu, 23 Oct 2025 03:32:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.92.39.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190327; cv=none; b=Kss6a6QxPFlNtlFQl2TNxzXxplZ3GQ5KVv0lfSnEZewYg9sS5DMSKdN+F4gGohC213qSBtK7YVRN4qqGfLP5joPKR1e1ReXS+tXuSyPMEp0dTNxdCQW91+iDLH19xhHzvcTK4iMeaAm4bvjkxO7MJnySaBhtzhFoh4XsOfrj2kc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190327; c=relaxed/simple; bh=JkC2n3cUcgwqX4mM3+Lhi39ig/OE1/fWWocxtgBRO8k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=MUvbSnHsHE4miPEnpkHkZyNxDre03yO4jpogFcTA9lWMtNHDGhcslS0r++u7s5AeMF+rP3VupwP7oqQHPkjVeK3hjk3zVymgrhfBkKuarqgSGYi1/P+OK92JRg/hOZ5vjNaRmZGloeCEYt5zkwDSoZvbjFMUbjDKofY9nTEbusU= 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=lyMJKUIv; arc=none smtp.client-ip=54.92.39.34 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="lyMJKUIv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190238; bh=YHT4Mxhe+zSodIVHd2qzlGnysBWHBxMufel41tGudBs=; h=From:To:Subject:Date:Message-Id; b=lyMJKUIv/Qx2CC50WnCYCHr/AsHK7/RoGhlq+rIz1XJpmNWGc847ct1N9ztq4AvP9 fKsCuD9JzTTPtaIStHF2gVRg72tXypDUwICeDzQBTeNsSyH+7KVBjFnzvFhqEerIrH Vx8S1LvgxwQFwdJbhi27zaCnV3Nlk27UQGAX6lcE= X-QQ-mid: esmtpsz16t1761190237tbfdb6da7 X-QQ-Originating-IP: mQbiV5TvA+6VNgwYEj2mZ26rSyqpwRzXYdmUfICKqpw= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:32 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 8877655953729844497 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 3/9] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Date: Thu, 23 Oct 2025 11:30:03 +0800 Message-Id: <20251023033009.90-4-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NqGwt1Nz+QGBHHknu3Bh5bp6wIzU/OjXR9N5F/MnNNnjsUIkF6TtAJX1 O2tGJ2q2KAoyGtmped++H7DLmpxE9YQvFO5VyojS+zBi0suc8sV0vhhLSpmPoiJ//C7aiQm 2tOL0jtqGVIHHFNIfsxT7IWBJcZgNMpibQAV/9LvOJh30NP3SEOJE5LXyStaqcl8hxmP8Iw 3NmT3ATS8kIpJTwHy8/0RgiaU18tI1b7cj1rj+hONauPjyUdDdlP8myGxsESWK5PHw0PbDC N3lTX5CslOWWLKK1gJ6ULTdC7+I6hCaUUBGdRvaDjDjpvdLStcFgBYy0uaiWM1/x3248vzq hlvLs0FxIVVzbn2ia5g1M1LZtogXfSDuNNLjVKqQfGu/ZYQVjNF37zd6op3bUedDWic86C3 alIrPkEyiF687Bg3h8ackVjX0gTOSXUcO4Zah3WjfEruvK07yLqkA4QHLe0g64dndDMdSbl +uL/kNYT9xokGQ2id9nW7uMLwgBXnfRouVOVWMKtny2n8HULJBAPInKrszKdNbXlY103cCH lQ70Zy80tJo+bnQ6rbQy2p/k020OADBnFPULt4CXhwivbZgMBLsP/uuA2e94PnPRTzS+Gr7 UftM0/4sAyyPN8EUIt+rSpjFBl08E/Ui+7LyK1DO4Fjaw5PcpsvYi9CWKYJ2V/3/dvTZZJp a0LE864BhsF7CqU3oax4hpoEylRGdUGy4U9CxR4dFNEGBsqXTZGwFSrt+Y5EwwretHslTmm mBJAz17wv6slXWdRnmCj43e9vQRlsxBdlaBA5JJwV4c70vM/rN5O4pMPdwj3INBg2WQDpmL bunMngm9C2R5eqJ4goJSBXFxbBj12DheezqTaM8nmx/TfxHzFaO/2crweZe10NTk96sjERY +ZRchjT4oYlFf7lhFgejDWXMT9FyibYDG8N8fVfhSEnE8fzQ5cFgtay0A+0wNepweEmQaIE CIhxk2U01MZkDs+vPU++xCmh6wYuZGLWN2iltO2MIpwHWnKWxdgZmGhQwRA+p1kythJ8wiq nMR1EKrA== X-QQ-XMRINFO: M/715EihBoGSf6IYSX1iLFg= 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 --- (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.49.0 From nobody Sat Feb 7 14:34:22 2026 Received: from smtpbgbr2.qq.com (smtpbgbr2.qq.com [54.207.22.56]) (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 488332BE649 for ; Thu, 23 Oct 2025 03:32:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.207.22.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190335; cv=none; b=YxCx6sLTXFN/kcpYU32sTx6UsUW/swt3aG5WL0R7ps5TInDNKWWhI8CIS+fOI3KHtA2GoCo0aXh+wHqhFCg1zokZnhSVaCtXIb/HROrbOCD44k3LQPc7VRrIxN9K9uDxnCYod9TrpJpjndtw3i5RNfKvRKhORuYYKJTEBPcD8SY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190335; c=relaxed/simple; bh=zCsRQvdeDvLSLnzuI7LiKYZp7U2SJUl0e0AEo+KRhvM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=ncxVRgKEfNYF75AV8FYX8Ty+3CEdJVCqQsrIGeBW6hV/sNUh9fxRhwD5Q2+rP3v6J2mpHSvSYE4MCHjtlrcAMqKznyVsGoByRWfRD7WSrhnr2R02q5N2hWm0fHRNSrlVmWOp4IteH6Yma4hJKxk8tvk2q4zN11yYLKVpGTQK/l4= 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=ZgNlDM37; arc=none smtp.client-ip=54.207.22.56 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="ZgNlDM37" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190244; bh=5KS6qDGs3DgFeS16auSi0pL5JfRWGjMinEXlOe5PpTI=; h=From:To:Subject:Date:Message-Id; b=ZgNlDM379MP0yearjBAtNepW773vadOlZ5EKqE7uL7JrS2JYI+dbc5LR6sWOVlOi4 bRWY6o3EyXgp/AbvscsF1KKOPuRpacUZxD7lM/xEBXsSj8H3dztYzvT7hnEwyBVyis yyYGZnZT8iDNJaXT/urbNNZeYn0YvLZIQcQPIIrY= X-QQ-mid: esmtpsz16t1761190243tf9bd6dad X-QQ-Originating-IP: ohwKbMb8KIZCwDp3iVhH4bLAQ9TinDSAejJpyBmWD6g= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:38 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 11047843021497731627 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 4/9] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Date: Thu, 23 Oct 2025 11:30:04 +0800 Message-Id: <20251023033009.90-5-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NqGwt1Nz+QGBHHknu3Bh5br+qm10ObjcQZdjab67RkK4w2Tfx7NS7c7I xEpZfxuwHengV8RExijvU/2iedpp63CX0nkO9vkYWYF0q3JsIhFPXgXdaQ8FmuMA25bkaGS iY1+om4m70d1pq4yQgrSUxckkKQNSWKDzxvlk0sBSOg4pemPLzZonHfkS1+JeHI1lWGzYa5 z5dDreAd6iNl5VnTstcy+j+Z5A/8NsFRX03PhPD6pLGBzYLI2TKbSUM3CaIA8cW3T12NOh1 hPBPhiqBKHky+7kb68cvaBT4k7DRNVb4hwZHXgl5oDPvhJWeZZLegmt1pYfYf4yMkqHwJ+a 68dV8pU7FkSl5lgd8n6h6yqgKOyxK5PAS1gORCegjM4FXyjw87HZGTnKnhOUPYWLC4GoCYR ZiNXC0TrQB8bdR6Er620ASQXmTKXReTCEVdoBbZDoE+DTDZxeiLMK18NRuGjdRQVtbXLNT7 bgrpyj2NNoUT9IYxPWfKkxr06LPjQ3tImWsonwNet2zPObHHR81aoQ+v5RDGEvJo2xDoURU Ascyy6NWhSKBvlfOzcAr5p1gbZd7ENBiLvuwFYSmU9qRHg/YYNqPSRuw/XqB+WIF0t35f19 XsuyfqrhpiPa1Puq5nzDiI3AqxpwX/nM6/Q+ljkvRrCxeakRTMGO8OticRyeVq1q7wWYfMc 5/91b2d7u6Z5nHBVqAO43oERoD22a/oLZOc5D7Ohh4CePRWzCzaMxHJsLPAGVYraPhArKII OEv50OdTwEztBJuG5RURr+0gKRYBtA9ibp3otvq3zBnlouKVOJ+VwT//PUDcizzHdh1Szuy D4lr4RApHrhnpoN8WfWEYD2N+LCajFYqIi/yzEG0NEotiItKQdhDWgnw/REx8TqGQynluo1 2NJdj9dF035CD/FssHTteJwTIkTTcGjHScPZISNFH6M75ic7hnJ2Ntx5ISX2areVI89Mg6Z J3CFytDJb+eY4ogezD7adfcMabEBhqQqCH4FiDcHPOMr2Qyw9AFclAfC89gu2RzkvezM/jo y0On8jfzXpU+3uoJEgwfKpdZSEuwk= X-QQ-XMRINFO: Mp0Kj//9VHAxr69bL5MkOOs= 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 --- (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.49.0 From nobody Sat Feb 7 14:34:22 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 B97262BF012 for ; Thu, 23 Oct 2025 03:32:13 +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=1761190336; cv=none; b=knoKxVqDH37/M1X64uG80fmEHIqzBT/ywTireiScMUO92SH9gGL1xHdm7+hhJsLnig2PGRPcemg8f8YYkhRHNmX8cd4CvHhCpJyBSezGlnYaTHIRqor6J5VrGSZ6kBx++4K2ECmGblRqodGMw0wVlE1JdLXXt3zzBsbuL1V8Exc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190336; c=relaxed/simple; bh=HysgThJSB58INGyifNQGXbmX0lFauL5Bf5bQD741kwA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=o2Soaw5P1sOisQYnndctuKqFhh1vmm4oQjuheqcgGhu8bVCz29+iMoKABgl0/j/nkJkqWrDuMRlvjkpE5QVVTX/RnyYgUlfVZOewzvU0hB2FpzO2DjKjvLLjYTcH6QpCWWYA/sBAO9nlXuNzCE3U8QS1DSnFomThKRaFuBphw+Q= 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=Rwkoae0F; 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="Rwkoae0F" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190250; bh=AFQcoHE/dlPx/r75ImuKZ7C8fGQ0d+TgBuYEF1fP98Q=; h=From:To:Subject:Date:Message-Id; b=Rwkoae0F7jLs4NMnDIsKk4B5emn7Hjk9ujRhKjsp/NpDiOwnhsUPkcZnAy2GKij3f iTDDuBSDOg9t4GeXHDu7ecqaYJm/tgFju2qMcMT2ur4yM80WcpLko7VP+0rBMsRJM+ XcYbTCiasx60tdd3GBq8sAWgDfrbgGPDbtm3GtKc= X-QQ-mid: esmtpsz16t1761190248tddc1db9c X-QQ-Originating-IP: 79hG5RSiNIqAGUfWumvqMnoN1zJNDnasQCzDIp5dXnM= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:44 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 1756416242830638748 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 5/9] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Date: Thu, 23 Oct 2025 11:30:05 +0800 Message-Id: <20251023033009.90-6-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: MVbvI5amSZ2YjBsber5S6w8cbLdG5azchJryTpxne12o2m8/bPxGcFiK ItQxomtF3h1xnIRVgjBRIEdz5ogr7qt2MDbeuWTp8utviuS037yUitZ4jJnTycR/TxNrere 5+IW8H1en1MMcrsmKAGjXpGsKFYj4FHfotCqpjdhfxfCWEk8GYLnhOYE7QzMDdSR4OT0OZN lCpO2K8rzRmf5KaJFsg4/X5OFLdeYxA57LQMOZhoF08lLluR4e9RcpOUEYYOOhv8eEqK7L5 kCiWkuUixmT4wizV8Dz9CQcBLPuk3P2dtwaxN/7XuKUUBESOraa5OtoJ/+TsCYrNNnqVBtY JK9fqotWe/cVHSv+EWRVXZ2wEAxa17st4H4H6G/VWBswNK++7N5Nh5NQsYbGbItoYRrw06x ps8iYctDjW9pO+PoAd2BSa7Nh6viPsWvzb8bi59+k2CrhguHeTMJe1mphVr+BZOUh8aOQX6 MJwCXCpNrPaxdVvDN5CR+mFyo4ELbbR1uzfe6ypA7i30fIWCw6cMHH6bzV6QQpNPxVj1bLk hH/cpbuEDWfgcCz4yPhsPeojoxcI/MipPPG2jHWabWK2AQQeJkoYI2Gwip/Du3udBQ0l0VY byomHswWk/vUQhF8wPBfzsK2FOFncfuWDij+TbYOGmjigvoy0YHccJ2nY6lLf0S2dKg7cgw csnONUymONqX7rotQ0uGg6Sf6AuRkxRW9cjq0K9qCAj+Vc4IFfwIr7Gei4M5vw/XI3RlFiz qHjZD273uFjD2BZGLh+62zQ2neXgj0zuUSAxA4Do7mVVCaiNF0ijuR/vfFx+5U1rMkc1ayE 98YAK34NqbdJlDZ4Rix1PwDtzF4N5G/hgolPREVTmRy5VqEiupWTK19NFztFYgE6ykOv2nw b2tq/TyZ5IwT0bRZV6nkAhyfvzh9zITsvcUc7c7Qc275nyAeq6QW6dVgjR4B+bGaG6xKdad lBHDuL1QqdqsDEflN4ATAkfTjCI2WAZEHn/pml0jRXZdks8aPU5OABt2FbosLSLK9eaFgeK N+oufLORfiR+IsdDA1WEW3xTcR0ERNkme/T7Teag== X-QQ-XMRINFO: Nq+8W0+stu50PRdwbJxPCL0= 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 --- (no changes since v7) Changes in v6: - Fix depend in Kconfig.=20 drivers/phy/rockchip/Kconfig | 2 + drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index db4adc7c53da..bcb5476222fc 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC tristate "Rockchip TYPEC PHY Driver" depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) depends on TYPEC || TYPEC=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..748a6eb8ad95 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -36,6 +36,7 @@ * orientation, false is normal orientation. */ =20 +#include #include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -415,6 +417,7 @@ struct rockchip_usb3phy_port_cfg { =20 struct rockchip_typec_phy { struct device *dev; + struct auxiliary_device dp_port_dev; void __iomem *base; struct extcon_dev *extcon; struct typec_mux_dev *mux; @@ -1299,6 +1302,51 @@ static void tcphy_typec_mux_unregister(void *data) typec_mux_unregister(tcphy->mux); } =20 +static void tcphy_dp_port_dev_release(struct device *dev) +{ + struct auxiliary_device *adev =3D to_auxiliary_dev(dev); + + of_node_put(adev->dev.of_node); +} + +static void tcphy_dp_port_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev =3D _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static int tcphy_aux_bridge_register(struct rockchip_typec_phy *tcphy, str= uct device_node *np) +{ + struct auxiliary_device *adev =3D &tcphy->dp_port_dev; + int ret; + + adev->name =3D "dp_port"; + adev->dev.parent =3D tcphy->dev; + adev->dev.of_node =3D of_node_get(np); + adev->dev.release =3D tcphy_dp_port_dev_release; + + ret =3D auxiliary_device_init(adev); + + if (ret) { + of_node_put(adev->dev.of_node); + return ret; + } + + ret =3D auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + devm_add_action_or_reset(tcphy->dev, tcphy_dp_port_unregister_adev, adev); + + ret =3D drm_aux_bridge_register(&adev->dev); + + return 0; +} + static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) { struct typec_mux_desc mux_desc =3D {}; @@ -1312,6 +1360,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 tcphy_aux_bridge_register(tcphy, 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.49.0 From nobody Sat Feb 7 14:34:22 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 1FDC82DA76D for ; Thu, 23 Oct 2025 03:32:30 +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=1761190353; cv=none; b=RgTsmV5+3xdJFfHmNYNGOp8LISsmlRdjdGqYK4cI+q+6TO72mQ8Cb9XmZ+2iqBsvtrfT8bq/t9rEfz6QJdBYpwlyDNlQ230fhxHqyDM0K+bC7KbbSFcE2wCbdIln/Mgs36/lASRNGiM42fwJy4L3iZocNRiT0q0rpznW5zNqP0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190353; c=relaxed/simple; bh=M4nUEX7h4FeSk6XVEQszUpUpBE3mjUtZPXnyDXgdiFI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Pw2s9avewS0KJcB0xsNHyIFjxm/cuamFvhGH9TIomfLj9uA7JkFr4DywX+mhLRsiAHLEUEqjt8U125stU36iJdVQUnC5xK1/wOtvMDRHABFSsfMmEe5IdGtwOLRJeKKNwnIosDGjOFQFHAM6cV3HFXai0Rj7ijaz6oUkDvuZ90s= 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=Bl6Jik6J; 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="Bl6Jik6J" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190256; bh=nQG0w7dhU7Aew5bKV30plkPn0nBnVdgTnfwSbxYLntU=; h=From:To:Subject:Date:Message-Id; b=Bl6Jik6Jxip/hTqiPay47yYQOKK0urbSQ+11av+8o1jdXKbPTwFeWy2ByYb9MANdS q3IhxOhu5V1re2mD+0huqAId/Z7+805LGqrxh3HRvCvbq/7vy0IiTM24aCmGqyjRRQ oain0HVh0EXyaC9aokU+vXoMQ5D2CV3C4CVOUUJU= X-QQ-mid: esmtpsz16t1761190254t76ee6809 X-QQ-Originating-IP: ry/u4/8KR4C2zosHm3ALD9iejKzqUxaT+ZTDF/OGwF0= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:49 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 13604929082984056362 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 6/9] drm/rockchip: cdn-dp: Support handle lane info without extcon Date: Thu, 23 Oct 2025 11:30:06 +0800 Message-Id: <20251023033009.90-7-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: N+aOzryTDkdC5TOsXVCC0WKSzV5F98nb9pI8IwZiHMt3xvfr+pGitVZ4 3l06+XIvSFBbVjWWdoqBF23sQYxAQBo/q8gkxB3OvdRna9WfofjaBfSYJSQa+uNkXT1UAiE 0tfIhEa9XHDqR2CZRDM8GCVouPV5RNrPTuA1CvhWmA/FDIVOFDB/KfzhVkunwY01Nhz5WKh uDArCOSG1pUdR8B5MJijKDyzQ1qrPOMADTpAKAAsG3ocHphE4nDahZELBlfE9CY7oL/ikoS rNxSClIqQiKFp3jTEbxOFMhJ5aUeUs5GAsz9jasGqraYRCi1USNYGUCM/d6BHzPLmNaLWKw 2SuJTq49Rbq/g5o7brJfXMn9wGudqA6jLBk8iwqujqdbXmf4mAFyvwHBC2TR0mvILHw1cGB FgvwGbeTE3l1epCVZcjLVby0TDKAVXCIw23RLtvuaoW0DPYreYmW4kGMWOHHPSKTNgSLGzF /NVs+B74nde/Jq6l+mA/SzdYJ79MuTauzOqkGxZqd3qzqhSCFqbnAT8A4I5Coc1KUZ2BQEB F8I3tKL1HhR+KkZg3I9YaII9WTKpZVsodsXYHhMmWGjWFBfI9jlv9QbdcJZa14XvIWQqAvt EObHv+6lGrMo7oPoFDug/K13KtZnYQ01OziWVx769wI8RjqRfiJLC/RUjWe4dxUynfS8Ig5 8mMCZWopgwK6CpYGHrT+nkKysuJ2IBpJckTl/HHnCQpxpRn7uxHXkUnaUdBLtTbcK+N0jyh Va2ZUhxlhF6TH5eA4NG0hLhw+bbwgRag0pXQfzhymvg0EBYwLhXM35SukPIDtzgSCrTISlJ iUGptvRAz3Qh/Pr+A0cQ+8Osr1HSlkK9e8bhyKBfku7wKo8nbKq98GSRhAChXiBSirh9lwk ngMUlHt+fG0V1ZrjhGc94d7aETWXAf7lL2fMIGi0amDyMGdwHJP6aMmCzQknQ1NRQ9sODUT JpbeQIKErwpzCD6n4Yly9f23vN+pGJ7yiKOaekCkW1bkiYWevbe0PEqCdZAY/Mq+VmzCRmH jaOTLw/71n6+4XhZahiPb1uMFTWGVyid8AaIroRA== X-QQ-XMRINFO: Nq+8W0+stu50PRdwbJxPCL0= 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 --- (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.49.0 From nobody Sat Feb 7 14:34:22 2026 Received: from smtpbgbr2.qq.com (smtpbgbr2.qq.com [54.207.22.56]) (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 3AB0E2DCF55 for ; Thu, 23 Oct 2025 03:32:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.207.22.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190361; cv=none; b=amYvGHFJbvm2HHYAEuIERVYQi11YW/xZYVMV2tcpejPes7bNJ13CV7p5lTxiVFyITUDSxxQkByJcZdHIzWogTwvfVG4zCWfgLHN5du6liqe5QYNpqCs1kdvXbIOEMUFAozl716sE+JyIXdlfvPWCzOsOVg/3pLR5qLrh4GwJgs0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190361; c=relaxed/simple; bh=OXgqGd240jl1dl8s89weeb6lNI01aFEZdjrmoZw3yQc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=D16eE/FqTl9qelFwneiLR5Q2KXO1KlXU6oRkshIVSSjkYZL6zSKYesIuur4VLJpcgCQSFc5kykaGXAmo4OVyOiL4XW9/n3aeAHt4n+hDySyvPaAWaJCwlEzqWUslS4P0XktNrYs6u1QApJ53yZLHxP81FNxz9iiErhZCflkpbIM= 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=I6qGZLoa; arc=none smtp.client-ip=54.207.22.56 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="I6qGZLoa" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190260; bh=x/h3kc5q4YrTjG/Gxzoz2V8jDCSypc2d8gFKkYTUbXE=; h=From:To:Subject:Date:Message-Id; b=I6qGZLoa1fnfcNElxeLxxG91sr5I2G721+wn4KrU3DFLlJSclz7A2vvwvyIRgC6jF Xf3Wsoctrc5DECJ/K2eOOZMm9UrUZqYGkQB7LWrbMTA0gTmpo/n1ddPwt5/ucVYWGS dT2XIx8gPIQn7uTUUG55jl8jPjuPw9ua2a1zSAuA= X-QQ-mid: esmtpsz16t1761190258taa5a4dc4 X-QQ-Originating-IP: YA/CNmMAZ/ys50cRb6LoCkV6IzqJekPURW70jy4zD44= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:55 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 2796748068971189876 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 7/9] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Date: Thu, 23 Oct 2025 11:30:07 +0800 Message-Id: <20251023033009.90-8-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NYz8c2bcbB9MQnNn3zMpWCw84OuTnnaBtUmsxeIpydzFKFTJvu7C/HvW yblgziVlCBzib2W7Tw7HWMpn1kKG/WUWzXyfHMcQdPXtsO75gfn2MJLKID7B9zrlKjfdn3E ZXyDByPhdMpUMC5JB0QQKz0JTk42OD5d1JHh+TwCZexgGMSQz+qw5rgZTaEYmfNqs1pJJE2 0j1e6tqm8WcbNIsJtqsfpC1R8EqV35Pk3RP8VFwL0rhiu5cRtSIEpr1/3cIJJQ6MCs1NHtW 5CPAT4FQjoKJFmlP9PEOb+cFrznmKPwXfP3l9Pwed9dzGrGyY2a4RaUu9Z3qyAGfKgo9YX3 B1/eRkQMKavmuA3hUzv1DTEhmselndY076UG7jAMLDJnRNwlJmu73gCxWpeCQFyZWopVgqB KCDtfSjf33rTI01SG9AvLXebr27QfLE3O0cdbPWF/ioF9uODMYzrjBLbPlG4pmAw+Z3SBCC hMCoHeUwDpXkt3boDoSDxVVKsDaA6hL7P3RT0dy8iKbaIxk1fjmSSWEq4OktzdU00AOUjsk ekfYDXxbigiRzTtaJEJIlABo0vb4tFjcQfDp7B92t2W9zkQTgRCCPgkf6S5Jy66NnGea8LW 9lSoj00LeleNeZoVg07QH5Z+DMGKF6R/fKBuAueH/KH5014iOTYZ3uT3sN5t5cxwyNZapZH eES3WiltiFKKZyWzZ/dsysC1b88orWhm/2Xe4ZQewrFcPRBgYuEN/BgtgTD0l+C7lLzbxbR eBwrgwIognuujzW1TVMs8jd9MPHA0LGPTKjWtzS8aPw5M5gYaRp0H4RibNNXRa/6mK+WC8e k38I6ncHH0aUaN0JGaK8JnCIu9vL/sjbiI8shu8QWa1psfs0TOTFoJaK1SBMpTut2iJjVja pTPRxEKNftsWr5Bke2D8dtO41tw4dKdDFWLPVFPGwZ7i/0pTfzBOHY9kac8MIf92HRChc3y QIsfhQgQMOCNBQEXJN24aKoRtlD01GZTNaMapTULsdelWh9RsaIKC/HA4aDD+BOeGDkfOC6 aZfIKurxEy2pfIbUsGDhoAnCu/R3EVNzI6pWiZ1w== X-QQ-XMRINFO: MPJ6Tf5t3I/ycC2BItcBVIA= 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 --- (no changes since v7) Changes in v6: - Rename some variable names. - Attach the DP bridge to the next bridge. Changes in v5: - By parsing the HPD bridge chain, set the connector's of_node to the of_node corresponding to the USB-C connector. - Return EDID cache when other port is already enabled. drivers/gpu/drm/rockchip/cdn-dp-core.c | 329 ++++++++++++++++++++----- drivers/gpu/drm/rockchip/cdn-dp-core.h | 24 +- 2 files changed, 296 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index 1e27301584a4..5c0e5209d3b8 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -27,16 +27,17 @@ #include "cdn-dp-core.h" #include "cdn-dp-reg.h" =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 =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,38 @@ 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 next_bridge; + while (drm_bridge_get_next_bridge(last_bridge)) + last_bridge =3D drm_bridge_get_next_bridge(last_bridge); + } + connector =3D drm_bridge_connector_init(drm_dev, encoder); if (IS_ERR(connector)) { ret =3D PTR_ERR(connector); @@ -1029,8 +1147,102 @@ 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; + } + + dp->next_bridge_valid =3D true; + dp->next_bridge_list[count].bridge =3D bridge; + dp->next_bridge_list[count].parent =3D dp; + dp->next_bridge_list[count].id =3D count; + 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].bridge; + 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 +1270,17 @@ 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); + } + + 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 +1331,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..ce1707a5c746 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h @@ -38,6 +38,8 @@ enum vic_pxl_encoding_format { Y_ONLY =3D 0x10, }; =20 +struct cdn_dp_device; + struct video_info { bool h_sync_polarity; bool v_sync_polarity; @@ -63,16 +65,34 @@ struct cdn_dp_port { u8 id; }; =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_next_bridge { + struct cdn_dp_device *parent; + struct drm_bridge *bridge; + int id; +}; + struct cdn_dp_device { struct device *dev; struct drm_device *drm_dev; - struct drm_bridge bridge; - struct rockchip_encoder encoder; + int bridge_count; + struct cdn_dp_bridge *bridge_list[MAX_PHY]; + struct cdn_dp_next_bridge next_bridge_list[MAX_PHY]; + const struct drm_edid *edid_cache[MAX_PHY]; struct drm_display_mode mode; struct platform_device *audio_pdev; struct work_struct event_work; =20 struct mutex lock; + bool next_bridge_valid; bool connected; bool active; bool suspended; --=20 2.49.0 From nobody Sat Feb 7 14:34:22 2026 Received: from smtpbgsg1.qq.com (smtpbgsg1.qq.com [54.254.200.92]) (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 330812BD033 for ; Thu, 23 Oct 2025 03:32:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.92 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190346; cv=none; b=IRlLu+zoaPI92K+T6VYDdgj7cpr433NQPcLfQ/xHVQxJJQl8Sv7Er68sEj6WnLVfh/AoHUtcQy/aNM/XKtWRis5mhKdGCZC0bVflRwGtapFwmreyo8DaosB/t3MCNpZ4RWm5oG8b2mKhb/c6hMUy2uwnepOH4zm8UPXzcjIVZbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190346; c=relaxed/simple; bh=3OiqcRrs7DLfC1hTPje6cpCre8EW3o9TnIIexoI2iuY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=kU2PBqaVuoAfvPlkXguGFcYF2gq7aCIvvFIOuFvO9EoCZeNFOjmWH0ttqiuZclT+U0iLgmdWRWCBX8O9ZYwcLBq4B3BW+yuN1uKlfcEve3S9++gTlelTM8Wg1HKDP8Hz9xd8PqaNwSWKG0f4PNU26Im/CaQhRNZgUytqdK0w9wY= 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=AQBoAVdh; arc=none smtp.client-ip=54.254.200.92 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="AQBoAVdh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190264; bh=cDiOxEFqYuonRjIga1t9o2u02p12TN3hXALWFcjKD9c=; h=From:To:Subject:Date:Message-Id; b=AQBoAVdhJGnqIyD6FLVazTtIT29+H8cQ+LxIxOIJF2U/R6iSk5i+dzxKH/olJWmlo fMdv/egZ477gbv9izsezOr3thNCxcwM3k/vlcCHvfvliePaUICZ2p197MfS6iiHNY4 aeS6hsknrB51ZfI7R+PsTzVjHhf8Wimf3FDys00Q= X-QQ-mid: esmtpsz16t1761190262t8232f799 X-QQ-Originating-IP: oQ3NBPzRHx0Ix2kkEvnLPPXZcoZY0uBDIA9nYNoZhes= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:30:59 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 10751282431167518610 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 8/9] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Date: Thu, 23 Oct 2025 11:30:08 +0800 Message-Id: <20251023033009.90-9-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: M+9A/6HISCYbMp11zyepCiZ3gzZ5kFvwmvxZ9DdzHsXfItPdMU81ChiI fLvHGEoUqZHzIi6u+y2/JrFiW6VBx+kW7R3DXQEJTfEk8TLCUdp9I1pfxivi/FSHhQFuZ7C XFygVRzEvs1RkqU6eVRj463YnyTMEBAFsPaNew90IkM3G3kE1PfuaO7ym+1CxGcFgjlkS7M 0oIUMPxlUhV6OoT63MB5tHCS6tUROqmH6sTj+IC2Vec1JQ2zXLzWWqf67tesp9tLykqkKw8 FoVQHjAMVK/0pLXHweG3lA/xHyfrgcXiI8Ez6EWq6i+InlvLi0kLS+t7IBQTgKeRDh5xcwq MA6DKoPYiY4E+B9WsizESwADu2JXKs5hXGFcT3A7Jotb1vrZYO/3+Dl989AxOLA//hakzMW rAH0zntH9t5kmCT+Ocipn+CuyH+gXWLsHBfbbLlH7Ga8mYd1z5IUS/bWs44nnAcDL+oshu7 nquZNmQVUA013M4Wukt1MwhUYrPD1q/486Vd1CcijdThVurBhh0xGagm//tSWLvrV+P+gqx /0CVHHZEr94QGX0la38FwG62zlkE9CJ5JeZe/gQ4HekisY1SyMkdrdRz9oIYyirFAKLQYob ZaKsuu6lJASMsEszFeoq1VQ5syLPXfxYtFEPwBwJRukFBmD0cy5ptr5tXyLkiEnINqxpqIy 6BESc1c3P1ixPY4gnhUnFLmzYo3UPVqcQHHoGECzAj19iBJWO/50TdkUTFHthEX+CMbinWw sFbu8ZNHhkgy01dS3TPoIGgl3cAE3y/fa0r+Fv2MXuBzyEaEXKagldpAt44g2rqttE4y5kv 3B7k8ps7mzY7n5HEFR+iSYWIOZa3ZHPY8Ueo6sA9QYlaL+FfRoKBowPwRpGdjZj4Id7GvDG zbuUlNncNiQVlW4RIm4jsCO8s6doF3jotJMctgBnJgvt3bHKhJOTLTCprnbjil1Z6cfvAw4 IupDQ2TV05uU+ssQa9QRTpFip2D0wYymWPx03bD8rw7FR2iSy16frY6br8SKGaetchwuTMI i1j9rrrA== X-QQ-XMRINFO: NyFYKkN4Ny6FSmKK/uo/jdU= 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 --- (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.49.0 From nobody Sat Feb 7 14:34:22 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 54D86296BCD for ; Thu, 23 Oct 2025 03:32:36 +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=1761190358; cv=none; b=fKyIot3EdMIqAvpGRPcyetvkM12b/mCpqEvv1aEQ2LKfglb+x4QTPzc9vYEbHF83jFMmwBugy0sSEhTUiDyyUkNKcF8TrlHHxPZhj6okyLnE9cEL0vkRBm7VjOea/MBcTlIlbquy0awq99dPbxySvolBd8/NEIj+3qdGXLH3WXg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761190358; c=relaxed/simple; bh=Ksu1m13XDgyOSNrC/yix/S/ref0aCyYvyb9gG5K8i98=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=UFsLEPfWT6REXRjOKOVGtACPKID0rBNAK9bNEnzy6cseVh2Gdyh2Liuejjpii64VgREEDeNy5Q9Woesdkq+9AvqVtDGU+LlyvDdgL5ORjZyfiFtlbsSxMrii1FKHYqEcwtDSS0ynCnQpct93OLxR3YACbPvRwpZVjHqs77e5OLc= 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=QGcMjIbA; 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="QGcMjIbA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761190268; bh=1RfAR5qe3fDpGYWfe4IMPee9wlWopj1wjBrVtJQSHJQ=; h=From:To:Subject:Date:Message-Id; b=QGcMjIbAOrhi7siyAK0cs+JmzOc7o/pDAVv5Ys8MMHuuHSD9jG5bOdMioiH6YhLUN lEw3UDV/Q825nB5fHeoGiLJ5qUEw9nIyB4Bu8Zmbt/my4TpNg20+Ror4K0zKeGaeRV svRKLXjGbCIJ8HFnzPgT4CGvaYuFKQmSrMm9yYS8= X-QQ-mid: esmtpsz16t1761190266t43abe1df X-QQ-Originating-IP: 0d5iSVWuoMY/pzXTcvdmH8vOvSaqskohuXcY4gRyoIQ= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 23 Oct 2025 11:31:03 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 14524474531760413252 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@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 v7 9/9] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Date: Thu, 23 Oct 2025 11:30:09 +0800 Message-Id: <20251023033009.90-10-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251023033009.90-1-kernel@airkyi.com> References: <20251023033009.90-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: OE3tIrIEWSq4dvSAti+YxEXfy0MmWUDFapUQ60ZDGd9sngP6WSFoYF5n VZHjz92kd/WEOhR8O8/gE7v/OStY7NtIWCgQnT3FgcHGWMKoIe+IJr30LbONPgwz9YMTWMq sDbBm++/oB9MnaQ/73nsFTM/RE1WtMT1SSziLehG467cB2kXN8NiOgxGEe40+Bf1ejOxxxZ UaCRGAxzNSdQGEcIy6T8JGoeQ5WVZ8ieOD88tSjCbb3ncJ/jt8HmFdXwKvd7vY1vPp9C800 cIvME+sx0HFb6Hr7HfjMy4W6ILJSb6Asfi2F3CeYSNtsVWoDGG15m/5ycLdH/sB9fwG/L/s HY3ZN+aLkeX4EDyKUpRI2o4vxKMmP/XfVn6AW5ozful80y99ipmxCc2xFXWQ9plpAmOPt9R 6QtlGflQxH7kPC32A5Oje/rqtQBGs5Aaj6c0Wv5TR0arLDcrJkbtX1ADz41TQ/rWu2VVfRU BfmUzyTcURen0EscCGaUvvE8KZvvGvbkX+ps3X4dhiEDzTPKggMIDziBSVvuIhe14qbaYr1 WvISUknJzN5LXSrqJNRndAL2iD4GIcpl+zUafhSPCg3twg/meGNfLh7dpmaG67qNW6/xi0Q AEV9q21pe2kcVJ2GqLi+1JeGN45DqwBK5EXQDJmuaKUWriEwYBy9UtZzTMi0gvROSrA7Nli M0kBRBq1tVhJ2yQ4DPwn3IrlEVcA7UVxxEivUL6yIWWe4PVOhzomiJhVPQemX4AiLlDeVcw Vu6z0WcrcmNsEJZExNxaklUHa8GQNSM6TMawP7PmDEEy9QZTzHR2zPIAa9I8p62BF/ESJ6n fBT6NL4Yu3xMXglKzcvyRXPLJSCmroxSbhQeuuPc6yjOXih8907XvdH4mf/r9a1QZalj5ym pVYbbYPcKK0B1aj/DneF6kTMWiQNA0wf5wFusIGhTMOCHgXq96LUfiL3/Zqi0ZgttHElrUo XhWGrrTZqlegREj6WjnE4ubwnTv5TN563Gep/FB9vam+jNRQH9S0f7YqFZKFGrNbET443KL JQt+29MQ== X-QQ-XMRINFO: NS+P29fieYNw95Bth2bWPxk= 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 --- (no changes since v4) Changes in v3: - Fix wrong vdo value. - Fix port node in usb-c-connector. Changes in v2: - Add endpoint to link DP PHY and DP controller. - Fix devicetree coding style. .../boot/dts/rockchip/rk3399-evb-ind.dts | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/b= oot/dts/rockchip/rk3399-evb-ind.dts index 70aee1ab904c..aeeee6bd2973 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts @@ -4,6 +4,7 @@ */ =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>; + + usbc_hs: endpoint { + remote-endpoint =3D <&u2phy0_typec_hs>; + }; + }; + + port@1 { + reg =3D <1>; + + usbc_ss: endpoint { + remote-endpoint =3D <&tcphy0_typec_ss>; + }; + }; + + port@2 { + reg =3D <2>; + + usbc_dp: 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 <&usbc_dp>; + }; + + dp_phy_in: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&dp_controller_output>; + }; + }; +}; + +&tcphy0_usb3 { + orientation-switch; + + port { + tcphy0_typec_ss: endpoint { + remote-endpoint =3D <&usbc_ss>; + }; + }; +}; + &tcphy1 { status =3D "okay"; }; @@ -418,6 +558,12 @@ &tsadc { =20 &u2phy0 { status =3D "okay"; + + port { + u2phy0_typec_hs: endpoint { + remote-endpoint =3D <&usbc_hs>; + }; + }; }; =20 &u2phy0_host { --=20 2.49.0