From nobody Sat Feb 7 21:05:40 2026 Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) (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 35669350A3B; Tue, 11 Nov 2025 10:51:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.243.244.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858274; cv=none; b=hOzxs02wC0OKM8Bsq/k2mwCASuOiX0pdd1nGsF5+X7Q0PE+edhn+U+PaW9EDYKARQUGqH/pwnolX/HLRfRoaX1DBEeQbE7xgftDTYSksx/iDKKKXIdBesuadM6AT2zxpDpsSOcPh3Hjf+pdC7xoGW4kfXVOrJTlF/Kfuz0Jczzw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858274; c=relaxed/simple; bh=Hph8zBRgkEl5bsXHuqo9OKoVbkY7ij5bPY5xAR4Aii8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=mm04R3XUzrOftgVi0QHQgoCiEGIbrfmP6cMZvPGwa3qoP2wPxgo3w0czAoul1LxVGmosii986fuCi2Rzy7gu4LcGa0Ww2QiyQzYERmn/1OX9bkVOqDP+vOBRYfGj9Ef24agDlkOLkkiwCUX2ZuyQ3btHFBvUo7Gd+Nh06OpWJUc= 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=Nk+qfpJ9; arc=none smtp.client-ip=54.243.244.52 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="Nk+qfpJ9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858257; bh=3KVgbAMLqk9xskfSyH7zcOVwcHIfJ+/kd/q1XTa1m00=; h=From:To:Subject:Date:Message-Id; b=Nk+qfpJ9ewTcExuBBLpwLuALH30SowqFYwlZAP3IDc65zssyvPZqE8/6CxTOHG3cb 2K2nRKVwhJ6iZUnYAG1PocXYwxOehgxHvFyWgvTQ8VB45MtXdsR7rh/nsNmyEgUrSn yR7g1H7S55xBdUFKVbARuQByF7B8rTr5YbPgJkMM= X-QQ-mid: zesmtpsz9t1762858252t9993007f X-QQ-Originating-IP: QIEzzurO6Fp6z4rwWPRwhcxu3akUrwReXd3stTEf5Lk= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:50:49 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 9719519489223886703 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 01/10] usb: typec: Add notifier functions Date: Tue, 11 Nov 2025 18:50:31 +0800 Message-Id: <20251111105040.94-2-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NSXtYWcyD5KOJ/WAmZMlCfNWBjpTa1WtLqaVQ8wXYopUPgZro2Xon46a XS9sJ99VaNFd72j7fNEVg77lMGY6B4XZKcgA89oNgHqGgJ6SZcKuKCCwjv/NOJFqkq6zxrI udyDOrw62QiytuHHy5kNFc9BzSyKqrPsVKtvIdg5tUs2aNhkVqaL8BNqtd7lTAvXXuOUFUj cpVnX+LeeaVJfXMDo9cuLTrokssIka8xdlzPoiIkQRKtOopmH79CiPYGyfueJxvINp+8EA8 y6o8uXInQfJZDZx+DWzXB2zAhFJBo5trnsk6DAINhaeimno2uAG+a7dm/5ESDLrG8+X7PrV 4QejTTEdG+jcKmce4XJTuK+xGhmxlOe5c0/16QaTK7Zr8IHLr2Mf/E3xPwkLo7g0/35KO6p lpArGBBw8A60RG9dTW60oYP//orUmch6137Teobu2An7Kc/aPXM9+PSiF+FL2Fr28Eved1P XHlPEUyzTC0TnX+XIQeCYjJCgzGYyxiFYPs9Ky2zCmMP8oSTGsEnMLhsX+PF0JcwKkPOnlX 3IaRc4FRMi+JdsX5md1SI7nRuKUDXzU8736R5so2TOGRdmGRbnDV3UdeL4RZ8wagqyRer/P x7p+mLSeR0G6EdF5/Jvjy377MM5E5SiSQZ0TsTojBe8lbUAI5ID0vtk7peKFPuGlh7fXxwo tu1azXCqusTpfhHZAO8ByVDCtNhjqwZZzyPp0FplK8hozV7/gfnsUi72Re8mLOOJLE5hk23 gqlgCEjpEmUH1dxkK6LWctjyblVUb9VwGdMznFeifY3FpsRoUBy5evhgUGBtve4fO/unaZl n9aAkvHfkY8YSvtNMpexAUOeA3tCF+O79H/W7vkWh+KpYJVau/sMB89LRtVUNo29AByCQze +R8mG2OFSQQ9dvwfv8q6MoJ+w3BVjEShmC3gyswUuvj5mPzvceWLgKF925LU0h6rbpeEF+F nJniIo+PaThCj8KDrwAXau+YEjMaf2kR3X3amp2BBaEJ92M+XclXeQjSlBOpJypkcOsM= 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 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 --- Changes in v9: - Remove redundant header files. Changes in v8: - Fix coding style. drivers/usb/typec/Makefile | 2 +- drivers/usb/typec/bus.h | 2 ++ drivers/usb/typec/class.c | 2 ++ drivers/usb/typec/notify.c | 23 +++++++++++++++++++++++ include/linux/usb/typec_altmode.h | 9 +++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/typec/notify.c 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/bus.h b/drivers/usb/typec/bus.h index 643b8c81786d..820b59b6d434 100644 --- a/drivers/usb/typec/bus.h +++ b/drivers/usb/typec/bus.h @@ -26,6 +26,8 @@ struct altmode { struct altmode *plug[2]; }; =20 +void typec_notify_event(unsigned long event, void *data); + #define to_altmode(d) container_of(d, struct altmode, adev) =20 extern const struct bus_type typec_bus; diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 9b2647cb199b..9d2aa3dd3f56 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -600,6 +600,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..9e50b54da359 --- /dev/null +++ b/drivers/usb/typec/notify.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +#include + +#include "bus.h" + +static BLOCKING_NOTIFIER_HEAD(typec_notifier_list); + +int typec_altmode_register_notify(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&typec_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(typec_altmode_register_notify); + +int typec_altmode_unregister_notify(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&typec_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(typec_altmode_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_altmode.h b/include/linux/usb/typec_al= tmode.h index f7db3bd4c90e..59e20702504b 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -10,6 +10,7 @@ #define MODE_DISCOVERY_MAX 6 =20 struct typec_altmode_ops; +struct notifier_block; =20 /** * struct typec_altmode - USB Type-C alternate mode device @@ -77,6 +78,14 @@ int typec_altmode_notify(struct typec_altmode *altmode, = unsigned long conf, const struct typec_altmode * typec_altmode_get_partner(struct typec_altmode *altmode); =20 +enum usb_typec_event { + TYPEC_ALTMODE_REGISTERED, + TYPEC_ALTMODE_UNREGISTERED, +}; + +int typec_altmode_register_notify(struct notifier_block *nb); +int typec_altmode_unregister_notify(struct notifier_block *nb); + /** * struct typec_cable_ops - Cable alternate mode operations vector * @enter: Operations to be executed with Enter Mode Command --=20 2.51.1 From nobody Sat Feb 7 21:05:40 2026 Received: from smtpbg150.qq.com (smtpbg150.qq.com [18.132.163.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D7F8350D6D; Tue, 11 Nov 2025 10:51:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=18.132.163.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858277; cv=none; b=hRNLky3kxMDNa87KTqSwoQCchmjAy3U7qqYAzpJPiWQ9UlkUQIrka/5Zqhzi20fUho8nks46XmTevNT+5nyN9JePg70UFN03iQfUtY9TJtviO9cR1wcTrDIBf9tWg5jYFQ+n99kI0BlXXngOT6N0ugBAfGddbcfH+PsnCbmzOzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858277; c=relaxed/simple; bh=saJYASZoDmHvBZigfXZm9m+GDgk6vGp0Z9kz1QpmUow=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=TXFLFRTJ1Rr0jYUW0mNbmsF9ijNVWNpwvLGTOx6GEzxp7X/XdubT785ZVrZOhH5Nu5rqUySGVdgjmn2QVYpwe+T30UAx2rUS+cQYVA4jTNBEdRVCQzoURBxwPiF5XBzsufz17tU6/EItoMnW+zTnv1hYC5HvjhTsxA5oyebTgBI= 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=Oh88cWI9; arc=none smtp.client-ip=18.132.163.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="Oh88cWI9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858260; bh=iH4TyyzlCs63+PYsRRwCgixuDYK1uZRjwAYMJ2JsaAI=; h=From:To:Subject:Date:Message-Id; b=Oh88cWI9mwcltmI6mzCqokG7anVyG0wGkPHNw9RQkikYJhzW4CK+vpuXosddWOSHr e+raMD5q41iNqHC+rlTnG+MwbJIbV6epzHX4+3j8y6W+lGiy66ah6X/A6VYbJjWnew EoE03dvc5jmkrCQR+kGQrL9DgMBmeH8flH81qzoY= X-QQ-mid: zesmtpsz9t1762858256t97625740 X-QQ-Originating-IP: uB8mCGoHOoLZ1YWe3fAK9YaOMzLs1IbVHP3rribHjTI= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:50:53 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 18215502699769285738 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 02/10] usb: typec: Export all typec device types Date: Tue, 11 Nov 2025 18:50:32 +0800 Message-Id: <20251111105040.94-3-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: M8JnMGwRo1mQ6Zj1L8Z6+mPZz/J9Qctn0KuWzPd7LVH5r/u+chG5HR08 LFckGIcHBoHG/2ARuCuCTN7wWLmMQyBdBIfultcICgtxbz5r2eaLUGmBz4M0k5z8CRSE1nt S3t6u8GZNZTuCK9M+4BjwamDQQkEn6JJ+H81yA8kvlZPO/NZZtdzOea6kLSvN85ttzPgdLj IqWyZgnYLbhveOOxy0oB9iBYF3oAE+nJzFHDVyPxZ7fdvm0UVDVjewAssPmJrmtco+DxQ6t FnHnoLjEfMfV1qHpK5IFNFAvtYAslZXQGMU5CHFbAEr/yvmEGcC+h5MlU0CzXIgwuzBn4ci EQXyjvOc3MMqUmbR+XsS3mTRgDgS8rC7yJrazE8cKxUYfGeDCMyP9x3Ad/Mz00/LdGbQkzb NogE8HnXig6JIlxYQp/dWZpTrWaQfiOtpOLMJLEzuB4KW6LsLtzGNzcMm8e973OBgVBcbh9 IzdYD4OB5TCoKhqyQwUwEAgFfxh+5/MsL7lFOTSgsd35bie8dqnViEjwe/gWG2IEtDiUekQ WEy1zIuKtpHftwL3l7UCmCniHMAkppLh4taL3m0nDh5P4udwpIqDjFQ8TaSnOq4dX8EJngd kDgnV3V4Awwlqwt5IsnRypVpsMoe73K9P7M78+k8x96nHP+C3Hiim4OQxMr8+xVv2NAxm50 aKDWNfuTSTavd6k+lIbSHKrOujPHWmU111s6+V1Z3G5Qj0BvoPqPdbGFXROuEAVEBkdvJRb QXomNHEIHBVJ3ahrPgZIrGOpcmypBE91VssP+xjUlqAE4RUJXGy0FIm5GS+7ig+Ee+wrn+Y exMcwuJrV8U+mG3AqqZ0eKJ3hnNKPI4OL0k09x1PSvHTXSFXQRF7RznkTeDNYbYU4Cxdyxc luCcfa9ER/uqspGt6LxVoQwXWNmBNMgTZky4J+cshlD9F+aGHnT8kUeCiZZ6yIOExnG7XM0 qmIV8SoUs36P3ol9ZqIGSuO5z8lTwdF1f72JtJ9u8PEpHB64P8M8sjBBlog+ZUspTdXU= 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 Export all typec device types for identification. Signed-off-by: Chaoyi Chen Reviewed-by: Heikki Krogerus --- (no changes since v9) drivers/usb/typec/class.c | 4 ++++ drivers/usb/typec/class.h | 10 ---------- include/linux/usb/typec.h | 10 ++++++++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 9d2aa3dd3f56..449f921acd9c 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -792,6 +792,7 @@ const struct device_type typec_partner_dev_type =3D { .groups =3D typec_partner_groups, .release =3D typec_partner_release, }; +EXPORT_SYMBOL_GPL(typec_partner_dev_type); =20 static void typec_partner_link_device(struct typec_partner *partner, struc= t device *dev) { @@ -1146,6 +1147,7 @@ const struct device_type typec_plug_dev_type =3D { .groups =3D typec_plug_groups, .release =3D typec_plug_release, }; +EXPORT_SYMBOL_GPL(typec_plug_dev_type); =20 /** * typec_plug_set_num_altmodes - Set the number of available plug altmodes @@ -1294,6 +1296,7 @@ const struct device_type typec_cable_dev_type =3D { .groups =3D typec_cable_groups, .release =3D typec_cable_release, }; +EXPORT_SYMBOL_GPL(typec_cable_dev_type); =20 /** * typec_cable_get - Get a reference to the USB Type-C cable @@ -2033,6 +2036,7 @@ const struct device_type typec_port_dev_type =3D { .uevent =3D typec_uevent, .release =3D typec_release, }; +EXPORT_SYMBOL_GPL(typec_port_dev_type); =20 /* --------------------------------------- */ /* Driver callbacks to report role updates */ diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index db2fe96c48ff..f04f6987bed8 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -87,16 +87,6 @@ struct typec_port { #define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev) #define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, = dev) =20 -extern const struct device_type typec_partner_dev_type; -extern const struct device_type typec_cable_dev_type; -extern const struct device_type typec_plug_dev_type; -extern const struct device_type typec_port_dev_type; - -#define is_typec_partner(dev) ((dev)->type =3D=3D &typec_partner_dev_type) -#define is_typec_cable(dev) ((dev)->type =3D=3D &typec_cable_dev_type) -#define is_typec_plug(dev) ((dev)->type =3D=3D &typec_plug_dev_type) -#define is_typec_port(dev) ((dev)->type =3D=3D &typec_port_dev_type) - extern const struct class typec_mux_class; extern const struct class retimer_class; extern const struct class typec_class; diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 309251572e2e..02fed8293415 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -56,6 +56,16 @@ enum typec_role { TYPEC_SOURCE, }; =20 +extern const struct device_type typec_partner_dev_type; +extern const struct device_type typec_cable_dev_type; +extern const struct device_type typec_plug_dev_type; +extern const struct device_type typec_port_dev_type; + +#define is_typec_partner(dev) ((dev)->type =3D=3D &typec_partner_dev_type) +#define is_typec_cable(dev) ((dev)->type =3D=3D &typec_cable_dev_type) +#define is_typec_plug(dev) ((dev)->type =3D=3D &typec_plug_dev_type) +#define is_typec_port(dev) ((dev)->type =3D=3D &typec_port_dev_type) + static inline int is_sink(enum typec_role role) { return role =3D=3D TYPEC_SINK; --=20 2.51.1 From nobody Sat Feb 7 21:05:40 2026 Received: from smtpbguseast1.qq.com (smtpbguseast1.qq.com [54.204.34.129]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AED2435471E; Tue, 11 Nov 2025 10:51:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.204.34.129 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858282; cv=none; b=HapO+KY56mVW3+g3m7ecd5K3frtHcZN92PvNlx+z+FPjbXFkMMfcseRdgQDRRcYqn2n77C5IMpyN7DLMHnijBQDXwHbx4M48jyR+IYbLjJNcWaCNK2PwODdRyy1NTDILygGMsYgL7aSsU1oozGqF8ZRmYlqvEHna9D4b4Y/oq4k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858282; c=relaxed/simple; bh=Pet5C3nSfDMCbfvoxji0xnrkRGCFNeRfignYldr3uw0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=uS9c5xwp3B6hSDjJD84VY54E8bgn48Kpn0QvL67TtovTYp2QDJLIuVwnK4nSway5c9Cu1qudjDlZM7nMzf8q6M8nyb0R23OyQryrgJ1aLVFn1TmBsVk0c+kW8cXd5gT3kP8YzE4zm3lyR52MOoZ9AFtWlFrWK3NtJuo9krqu0V4= 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=eUf5o4VI; arc=none smtp.client-ip=54.204.34.129 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="eUf5o4VI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858269; bh=qha7kTMIFWTImkRefy7JrZ1sr78KHWgow87P2iHBbnU=; h=From:To:Subject:Date:Message-Id; b=eUf5o4VIzzXhPAO3kf4zP7CMdasB8PRcXsT9bAC/dKx/koc3ua87CCYmQurMWOjS2 V5TODOxPiwV7RLF/Xrf3M6WPby4xacVrVfmYc+Jv1DGoqeeZcupFfU3QVFjMlJhJ97 FnDHYfAK5lSOwKR68Gd1JKQXf9jkJho9DBqo2lmw= X-QQ-mid: zesmtpsz9t1762858260t14c220c6 X-QQ-Originating-IP: 8yzyQt1WcUQiRY5qQzutWDddM3dqogZr+H0JtzK+Gg8= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:50:57 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 16669197487587565882 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 03/10] drm/bridge: Implement generic USB Type-C DP HPD bridge Date: Tue, 11 Nov 2025 18:50:33 +0800 Message-Id: <20251111105040.94-4-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NPgAY+7cethfznNSp3gZfZmqGADW0pPLxP/H+PmYcc4VPPW25ia2nzZL WTwS78ThlXXHHErIL57O0yfomyCd5s7mN24+r44rdQhI3nBQAfKA+N5pQpcBn58apd4nlD9 cdG5fxQBvysusmFrV7WEbu9h4b8gOIj0cJ6gupR1tL1F2n6J1GHdMGW6O26yWwbJUuziQyn AmJiVegax0V1Z3srRKm2cT9XbnQm9/xmgyVpSDWpyWFpfIn5GiVmm5KnyVb6WCQrzO6i/bY 8v6jRhZuNKb8DTzxh/ELzIMr6bjb6Nx+GLTcc338zY67SM4grsGdTxKgLRP9BtxQdDlDRL3 u0zqN2hHcxclDKg4S+ES2XBIIgF9mcrL5NesOmISNcaurfJJuUAgze6GN/5E6RIo8cP/PxW 7HfACNOOf4E4HIFeBeWIq5OFq5MKQx9B3hHtf0oYJhnUahD6yKw5HE6IDbQIm4PUcPZxciZ 8sRZtj6nq+f3/Rn3hLMJxRDWdpjxOYqmHUmtODmBjSIoWcnQwSBhRhW90LtOSasntuNyyUU a7MMc27VOXcTpTzx11EoZOEyPT6vgL/T+n/lJGBd/C7qEORmprg9MgLe0huiRIlJv3i3SJF hEFjbHpAANcR6tp1tZP3vfataXBIsbunrMlB5W3Vptts5GoYjxYakiqH6Ix6sOk7kl+Ejrw ADm4c5bBnOcA7yAsmkFiilBsMh2Ugi+G4y2sFCDNWAJ8wxsMhdi4/tBk8rsR5q8+pXMJlWm f2AWLaeXz5qu1Q02VIKte1YYQBjSw72l9gxNJMQRRmgz5D+/gQCQ+aFRLkrqkttG5XFZoQe P2D5358Y4BCaqWC+ZW7lzON3hU8O1NaIBLJMqXGgx12OCUOGyvc9ceQ5V7ULqIeKHrjQ7n4 7hTZhJKGgU9453wUSki1tlkNxTZpMVy6RvrfrL8kDyJT5jb6jZBt7os1cVhUSkTO3RUll3U 6Au8zvSCdmdfHdiVu5lkY4JxusGdKR52y7quiq7Ws8LJIx+bQyqSu0bMDbibv3tGAvRSY5b 7cxTpBV+rjBzQCCYv3FbbMQQFzxdDxE59eMuZq4A== X-QQ-XMRINFO: NI4Ajvh11aEj8Xl/2s1/T8w= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The HPD function of Type-C DP is implemented through drm_connector_oob_hotplug_event(). For embedded DP, it is required that the DRM connector fwnode corresponds to the Type-C port fwnode. To describe the relationship between the DP controller and the Type-C port device, we usually using drm_bridge to build a bridge chain. Now several USB-C controller drivers have already implemented the DP HPD bridge function provided by aux-hpd-bridge.c, it will build a DP HPD bridge on USB-C connector port device. But this requires the USB-C controller driver to manually register the HPD bridge. If the driver does not implement this feature, the bridge will not be create. So this patch implements a generic DP HPD bridge based on aux-hpd-bridge.c. It will monitor Type-C bus events, and when a Type-C port device containing the DP svid is registered, it will create an HPD bridge for it without the need for the USB-C controller driver to implement it. Signed-off-by: Chaoyi Chen Reviewed-by: Heikki Krogerus --- Changes in v9: - Remove the exposed DRM_AUX_HPD_BRIDGE option, and select DRM_AUX_HPD_TYPEC_BRIDGE when it is available. - Add more commit comment about problem background. Changes in v8: - Merge generic DP HPD bridge into one module. drivers/gpu/drm/bridge/Kconfig | 10 ++++ drivers/gpu/drm/bridge/Makefile | 1 + .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 50 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index a250afd8d662..559487aa09a9 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE Simple bridge that terminates the bridge chain and provides HPD support. =20 +if DRM_AUX_HPD_BRIDGE +config DRM_AUX_HPD_TYPEC_BRIDGE + tristate + depends on TYPEC || !TYPEC + default TYPEC + help + Simple bridge that terminates the bridge chain and provides HPD + support. It build bridge on each USB-C connector device node. +endif + menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE =20 diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makef= ile index c7dc03182e59..a3a0393d2e72 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_AUX_BRIDGE) +=3D aux-bridge.o obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) +=3D aux-hpd-bridge.o +obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) +=3D aux-hpd-typec-dp-bridge.o obj-$(CONFIG_DRM_CHIPONE_ICN6211) +=3D chipone-icn6211.o obj-$(CONFIG_DRM_CHRONTEL_CH7033) +=3D chrontel-ch7033.o obj-$(CONFIG_DRM_CROS_EC_ANX7688) +=3D cros-ec-anx7688.o diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu= /drm/bridge/aux-hpd-typec-dp-bridge.c new file mode 100644 index 000000000000..9cb6a0cb0f0a --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include + +#include + +static int drm_typec_bus_event(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct typec_altmode *alt =3D (struct typec_altmode *)data; + + if (action !=3D TYPEC_ALTMODE_REGISTERED) + goto done; + + if (is_typec_partner(&alt->dev) || 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_altmode_unregister_notify(&drm_typec_event_nb); +} + +static int __init drm_aux_hpd_typec_dp_bridge_module_init(void) +{ + typec_altmode_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.51.1 From nobody Sat Feb 7 21:05:40 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 EE68E350D6D; Tue, 11 Nov 2025 10:51:20 +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=1762858285; cv=none; b=KkjY4igc1Oc7UzwEJejKKsEq43uX8gOZHFg2WHXyo4y0HPLdLTtQQOLBST+6r3jbXzpCSjkGJwoZypnfZ5HONL7PryDNYrVZ+HPwIMjs0jB7OSCcvThQV9CoYn5Wr+Eps5nfoQVM/RLJVvvpOH+Y1pDBBq1404KSol8xQhj/GQA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858285; c=relaxed/simple; bh=5m35kASviK5Hv89NSiZimFN3XlqevmaILeqOugiZOLI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=mLGd+irYYq/VZc0+LpEY3qc2HyeFJ2fu/DELfH3JzMc0pDBvBSAqs1dtnrEzgRtF4Ljw2noOlzVdETkEbtE3toUqHFWy21fXfPfyo2L+EauPPZVaoXXHvOhqLxNHIkd2svelxNAWwEDzdqEoIkhMN0Twc5T/z8Y8h9Jncr8rppE= 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=HMScYYcS; 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="HMScYYcS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858270; bh=1fj6I5WadX9tXddUihY9i9o+TqzOQO5XPHyy3i2XmCM=; h=From:To:Subject:Date:Message-Id; b=HMScYYcS5YCdsXGaeEm2T9zjUw5qFsdae7Uh3+CmxNRuAAM3SeKlEgjNtwSwhIQvl Md9okgIjNbsqmkcHSooliVZJmfT+gdV0NNURJ/mL6TjJpIN7rub3JgooRCJoYV8y+b 1iTxXtQyVA3vdN7R/oyeN8hF36a0i5+pMz65PeVM= X-QQ-mid: zesmtpsz9t1762858265tfbae2009 X-QQ-Originating-IP: uJyi1b7YJXrK+cM8L16DabO0ulPWhVW0NrJkWY9juG0= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:51:02 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 13153881317845399117 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 04/10] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Date: Tue, 11 Nov 2025 18:50:34 +0800 Message-Id: <20251111105040.94-5-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NOc1LUZ0GKQa3KhKs0ZBpKawp9/yUaHk3thzv8shSomqovd5WCqOIqMW Z5JyytJF3ZKEWGOZ8uHcL84nbz3kbQVSPoS+BRD/+1KNwh97qJ5963LrzVyQCPf5wMpDkjr ZfjQmeYyyHe5iJ/2L+wZW2NH2xQajJ+1+GQX4VVVp6CpnKEeeL5G7tjvRpQdeDtKu6QoYtr Q7NLsbIJgn7boG0kw6Uo1NnBOZ4NHoOqTg4gKs+J28YFM1HXL8ZxMLyoaMF6+BbFgsDhFMC IqlL5uB9GKGav9IqHS9v2UA50CEazH7zmfyiOZ0hliYv4a1cn/RBXPYHtWQjP8evlSkeQP5 7LlRlmjZy11B8LE7zOb1/AXMi8M0peR1IGZ2cAZ9LEfx99IrH+SjPenR7w0OaPEKndtcyYu ueyqlZ3J82Ki1aaPOcShqgP+Wx8loUf1SpVggvDH/Ktwe+Ew1XstiuPU9Ukinb0rmrqrr9q OS3Ixv6wC+P1K38Wmj8/2jI2KovbnG0MrvwYn4I6NtI+9zulUHeYN4W8duBW4kMWelcg+vt M3qJHJvAHLSizkSBQHvxX4L9nlIHV+66PQb19IGyb2vZnr9oTflRyZQ1Q20FrTIV17IBbMP ol9s3RoBsHEkFMy5LJjy5VZphy7BWD00Jrl+xJjew5TkvRG3chekGSxv682yuF3bCIRPmS6 VFTn0iNza/WCY6jXV+HYB8MsG7a2O71yDvWjWVZ6rdcQZSRmocBnWzRa1wvEUcVVcluZblL kG//F3/fs4YZMbDre5u9u9W3KEE/JZ5jlMzKssxHZ3tzinN3Uxm6SGorwMXq2ntyXYrXQ0u 4V+7yylAwU1cuoiiiZrOH+2AOWgcF8G83c4urjfRdooKijAaOh7ZcPHbYRme71DnCT4azFT RuVRrKv2C9pYUfOSJrJIxoMpfo0WpwTMdPUmjwkdQBbk6niywI4kgcFUDlVZG0qiVeqTnTy wc7yAjajKYk+o2IfnH29xwTchmBAnt1wCsNNdn+JktWclVEbetOY+dJJ+jczd3TnjVksrQ/ tXmHvHYoRYRdSz5et/+ar6VFrOctuOZ6XDwLgNzg== X-QQ-XMRINFO: NI4Ajvh11aEj8Xl/2s1/T8w= 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.51.1 From nobody Sat Feb 7 21:05:40 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 76A6B35471D; Tue, 11 Nov 2025 10:51: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=1762858285; cv=none; b=HoL88IdeCFCb0YnKliLgZ8P4VIfY2hLatZ1K2FMHtJa66YozQh38dfzkioRFg+D2ZEwfkrYHnLyRr+H0QP/4pgTVACml+ZAWjQkGCeofdOq5Av2VmZgaDM7fJZFL64C2pn7z1KgaUY1zIhBF4nkBIIQTgexcEGfEOwkE5raZ9V4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858285; c=relaxed/simple; bh=R3heeE9hR3co2ACiydh9o+HhTZMeJ1YRf5V1MBmv3DU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=U8K6YhL6RzLqbfvy0HnDg1iMRlzUyM2LZcYBcl8Ne3qyc+uwxnAdAyWgGz0dnpvgMGzzd87CnjgKm7ezWrXMQq5c0LpfhJ7I8vNNWfCI8iDuZkcWTl05aMFBWuidzu9pLElfh8qusFgyitACKXbZeBNUy7TaRhTnAolFcWH2N4w= 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=lGp13CS6; 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="lGp13CS6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858275; bh=frpOn7dhVQ6Nxp3VUESgJ6aTlZPf3p22en66tauvZ1I=; h=From:To:Subject:Date:Message-Id; b=lGp13CS6F6xu+J9d/FDXmy8WsQNJ3ytyyXN04nhkTLeyaxHazM1hfAjWTpp8KKkTP KY6Wx7vVUmt45dXjjeK2sbXEo8KKq/Gl6INmESM0/+TXWkzoaQ8klQIihY1weoYErY yxUyaZLoL07kzgCqSLS2WxKfSR+2fJLE1Fz5ey34= X-QQ-mid: zesmtpsz9t1762858269tae46e981 X-QQ-Originating-IP: rWOmV6YCbOTOyEE3JVKNe34gp/orc94bJPZ1bMfh/wE= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:51:06 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 10899222183811561793 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 05/10] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Date: Tue, 11 Nov 2025 18:50:35 +0800 Message-Id: <20251111105040.94-6-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: N4ZILu3POr3OrrqQtg4x0NOgBwHXdUwvAOLdOuydX2UKTk1G8G/Wr6+I 2AlrSU+8amWjMoNoQtiOKZZQEMH0GGJAxMi5iV04uJ6EgDFpmmmouwg11CpTDcfNqabW5Ri sq2JtOO+EzAogo7bwDYwtGHPrCkChyUDYe1zKuCCImt0bYSplHw44GopaRwsRRKMeirhyVC nZYg8pg4kUj3vlGyynGQpZzfmZA8EeT8yRSyoLl87XzIhUSnTc4NuDDcrlTgYiK3U6PhaM9 MQ/zpDBXKe43zZmWCn3JTG3yjYpm9xp/+e8/oB5T+OEPoV7WYl7PUrBJTz2flPAAsgREMrb EYeasyGeo+zM7w+YqLe5fuPaKhEYdYfMSWoIa6Z4qF3ag/Y2oTaz+lX4ZmcMrVdMRWNO14I FiXL3B2dxcwzJATP4WZyS0HX0464tKqYSTZ6NIfZCHLTXLLJXgTAWuuxJYL0oBbZ5ryEQzM UF8t74yS+FtiLmaz8UqEuw0b43Ovh0F9qoQ/pikpdBMnCob6AO8VI7+03MLKmhlbUx5aeuC rCCAeSyXE64kChCIjjgRHHKOiG/2ljlR1Ch8Ewz2MvPzcP+6zxHbj05nUDN0LZTFjxp8IkA Tu+dde/HJbqRBN7fXOjEmnZAli7kT/Jpst9wLZxc6Qs7mUZpjLMApbodyJW007B6PQfhtXk P3DJemWC7oMwYbG/e9iDpKruR1QRdE6tM/+ibDuNxDYBOkXLfCU1LBNPOE93BXFDofO7c2R uQAMaMjOQDdXudigRYeGmitFxOoBQswMtHs2hvGkxuw7amy26A9PzQ3DDXtbPDLA0NzzKEf PM1o3aw8Hv13doNirlXz4KoJcc2lWC0pK0QII768nKYmUUpVnCbSliamYNzzYVIuxCbiV6d 13FSB2hI/tCok3XNzCT8dbu3wF6DdDrDhSqXaRcWffsFzZF8OvbGBVmL04d/KIWTNt7J7UL WbABNoTuFclmcHcg1WBV3Q2a1PZqTXzOLwYgstDJJI04CNBxQ3P7Rn7k7cQstVH0haA8= X-QQ-XMRINFO: NI4Ajvh11aEj8Xl/2s1/T8w= 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.51.1 From nobody Sat Feb 7 21:05:40 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 A7CFA3570C5; Tue, 11 Nov 2025 10:51:24 +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=1762858289; cv=none; b=kB/p54PGsdpjU7E9p2bM7A0qrXfavsfvYvtUs6l0cOkcX9cJMZ4/o23iwHssxT9ZmCsNQ3MSm5JndBFj+42WYB725AU4GwfpLxlKVRPQFbAeS26OkgdKLYqzm0t88t94Wql1fQ/VyeZnTmaShzSc4y6S5uTzZrb9bYvrAzadHcg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858289; c=relaxed/simple; bh=uqVYgDBkwXN4jdCDwZamrH9tKaVRuOOIwGDr1iagL6Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=IDhls8OvblrWb+rdh1smWAUj+sC5I/fLrkPLAD0Ei02aJc+E6ggtufhEFLlDezrwQrlLVAASlLNo0CRz8v3VDBQW+8GFDx4O9TPgk5boUo1aMbHW64f2LJ2c/GO4U/k0tDnVhDkeELVyFpnzSI18BQlkTnp7Msw/qEQoCQn5JGE= 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=uC+yPWnK; 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="uC+yPWnK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858279; bh=OWq3Ijzm5puFxMiJhAvdmtx+0UY8U1fFY3/NshKxkPE=; h=From:To:Subject:Date:Message-Id; b=uC+yPWnKZW9+rbYbU3ipHGh/Njq7O/ScwKSkab5yta1/IMzIVq/O8Uw/mVvqyo1dq Pzn2t2/YV93iTYnkGCelJeC4+W74SU1VcM990uiZTV+Qy63mcyFlmp82RmGlu8dshB WT0hXgvMGFwtqVskJV6HhkX/HKl5EhdY6FruLc2Y= X-QQ-mid: zesmtpsz9t1762858274t6e3b4120 X-QQ-Originating-IP: 1slQcncYtee985S5MZrVUhNCU3D2mTKl7D9nmZmqz0Q= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:51:11 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 7739212322103543834 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 06/10] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Date: Tue, 11 Nov 2025 18:50:36 +0800 Message-Id: <20251111105040.94-7-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: N2xbKkhNGEXwG8tJCForXeMJ7E026c7rxK2mw8Lu3H8pBPgrW9SamnnM AkDfWtJkIl0aWDqIj7pNIzrOA4AxJPSqboQ4KY6YihT9fZ9Y3wYTQ6E6Cz+0RBaSkSh3MHw cVa6nhi+Xjr3/1WmCNqh0CAn8pahCZpU+kOluBPvn7gmlrcvXdZtTnwHu7Fy+m9ezqirV/x VpvgmZwzt8iltPvW8Jsg7xNiseye5PgQYLGvEsJbSt4K1XQSUq2LGZDr8ZwoeI/SN/sgJia prBKpGoSqquI+sFkofmMj+1Tcpzg/4zv7noQlpfucqJEi+Bo/dmKtwqgSsDeMAsMDcV2BR0 QxGdLGFphdPzQAu5c39Sv4NbN16f+6/t7EFvL5gMlklldBxeVcMKf2n8Pnm3ZsPlTuCtC3U r1kES/sbqNkVJ5YuXBDiOWNOwgu7Prelnc5Yq3T76UOBtnPvUcjiBS/azp2Gyio8vd+MYk2 KozXZQ8iZ7xQmknizCw04+weWDKJEfsnza88+Q9uK3zDfJG2iuvKhn93Xdo2gBa4EiEQZtg XIumDA0KdVVMBqbVqW4JtTePFlgrbb46eAxWpNJ28UMkXVILUvuj3boYQj7K7NcQLtRAnmS eRpFjsaojbLoFkiH61lUJDiqtnfWNZ9DhuNrkfV4Xazq8HKVXANaL3aQFiN/vHBUXMd3HWD XMCX6lBHE8t0CiZLlZGgTIOEZ0TiG5v9/QLTUVI+ALxoZSt5EQNzv7aG4kS2W4Wv51bPuQk cEJg4UyzJwA1x3q+7fdvABMgFWxHnm3KRC5QttdtcEEMZzgBMj6Z96TidyYOqTwqe0s4plD Ta47WGLmVBOtUc7XMtKU5ZAGp8ZfNrz1jvu89OteGhKGZ6m+MC3LcyYpWRsRjrmTs9twOEb Ydp/jUCH0ZtFQ26pCwiEvv7r1OeiFWrrOi9y9wmMlsovFKawKm9ZmgyPssWcXZjaxJnEgB6 ESiuqD8MjlFkVCEH3SwI5lUiIEtWVhBxbkaUinz572yA/RZhKYozvmw/bhicUD0IL9ipVrM 1YH0u+KOM46+BffQS6Kt5hwDl1puUA1SacAeR7dL+SKUKWk9Rt 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 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.51.1 From nobody Sat Feb 7 21:05:40 2026 Received: from smtpbgau2.qq.com (smtpbgau2.qq.com [54.206.34.216]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 045273570C8; Tue, 11 Nov 2025 10:51:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.206.34.216 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858288; cv=none; b=U8Q/yg8JuFBSkGfrvPJoLVKqrAXdDWTKgsGW6mmzL6nskFfdp/2nAoUzPIGpUS3bSmj5hHCgbbwnsJxmuRfasNB+7myC94fLDsHqf/CVbrFiVR9RVbJy5hAKpI0OLcHBh34Y1iJFj0T5rvvsB+zagEqRBBEgFdbkOWuEiA4kwvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858288; c=relaxed/simple; bh=ktQe0TBZJXNabRClR1zK2GRlgnwznm7iN6OWZIxNePg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=PxU1u9mWrfuWA3xXJioxuXIyehEZKKw/zXGs5/fQPeFuHiJZESRZKUGrlFqkLA/ZOzAwaY76XX2FUYYjDooDiiKzpZc5OSOIlG4lsUPzCRKadAVu6Gtd+E27McOFu3iGgMA5dSjtsGgnxsE4zyPhOXleBFPVWlOUBcuc5b2F3CE= 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=tQOz4Cin; arc=none smtp.client-ip=54.206.34.216 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="tQOz4Cin" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858282; bh=sEWMlrnina66f1mkg7MgIF551DMwzRk8lseSsYVXv/E=; h=From:To:Subject:Date:Message-Id; b=tQOz4Cin+mLCfj9sjw+zFe4WQkA8ZW1g+oLTvoV4MCzkHSqDboN4Maj2hhoi1oVx7 Owi8EgX+0oYQ2EESAz4CJ2v4Lr+s2oSWK1WE5m/7oEVKTI8tRNrQdZf7jHDwjrhkuF ZNnnhRxdqsHggOsyCuxdhgQnZ1rwcEk3JFTTzyqc= X-QQ-mid: zesmtpsz9t1762858278t101ea436 X-QQ-Originating-IP: KIZLeegrDP7BdwpoI03I1Jn77fOqzylhUhpOTTA1aKg= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:51:15 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 9277144909567469895 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 07/10] drm/rockchip: cdn-dp: Support handle lane info without extcon Date: Tue, 11 Nov 2025 18:50:37 +0800 Message-Id: <20251111105040.94-8-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MoXwTY6T4qpUZUqmSovu0Ac1+5W83o5i8kU7W4URJdfU8R8z0FMC8u1F c6GjFVuuMZefjCC8iURyP1sN9JiIMH/UvQykgmrB9YPsBage4AfRbtQuRkNVVsX5q9rUyl6 Gk1bVLWSkofYwoTjOCNR2gVxrj0Uc+udyzCOhL3W5d1oidZ2296maUKkcpYaiU15H6nkj7A 7+TNyQEeSXXKavhFClLRc5LEsSl2MYD2YExUIF2KI6ocDu274DBkW04S/hXOg3IXi0fBDQi dnK8rhhzQd6fypd+qQqo6Gv5qGhJgsRtYcxedbxBjR1bpCDKxTQ+FIiUeo3l+f5a6e3l1Bd d12bByvSeS0dSoypgJn11iKrsnLnDmZPSnHwEJFk3DutQtJDwizzBqqfKQAgvaH2SKTQ1dy jSWA64ktrbaYhgQ3JYufaZM3a/xmPY/jMrJL0hVqfYKePjf6KpIxdq75jvbhjs8h/0zht3c uV4b3QZuRYVVgeyM2pv49EpmjS0mN5Gz750Vn5CI0DpA/U3dOA7OpoLF+PBxTHgTX6g2zR/ H6Dd1adazHL7he41DH16mVm2d23lzynmO2jtOEr/0oHqWhofK/k+/5k2cryj454otzytHW3 HTasWmRbRYXdO4Pbs04zYIs7o1K/dlu9Da7TuGUV17VZC2CiIDGwOK2OnH8mk9STmlNCrlu NjKEZ30ek+JDFoIoNZagJYszvTMhUhSCkcibUHd8lm3aO7vELYFPG6F8T2bhLcDKuGpqUU1 ocPIqNoHOElul6tSOY/5S5Jhdg8qR8lr8bHGC9KOx13BoYEosGlXz2kisrBz7YR6GzcoN93 Yi/sR0R100eKJ93wBkaG/6DyuvEOFjcsP6T3eumvURJt2lNb/r8uAeUFTvj6oq3nnow5cnr lRtwHXYrE6ttfrByxkVVCuXoQP8QSqLuEVsLzxNQURbhGLFpVkAxQ/e/HCtwxOoC/A3JCET SaQuCixTgWti3rxXd3Dg9cXpCpS0sXkAO4ItweB5qvFk/ovB3JA1bGi6lzn/7P0T4XWz9MR QdLaeFGxo7hxr13tmefip5sVOvwCA= X-QQ-XMRINFO: MSVp+SPm3vtS1Vd6Y4Mggwc= 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.51.1 From nobody Sat Feb 7 21:05:40 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 3B2C93587BA; Tue, 11 Nov 2025 10:51:30 +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=1762858296; cv=none; b=FS1Aro88QicREksuDZJHWD7sfucetGsJLqsehJWPeH1zeI8w7b3flUvsPiGZbax2JlDoXLMlCsOj38mUt6MeTm8/6YXdyjrzLh1vkRlqnncmBu+UU//lyhnG0Ld5+JfyQKUBPYc/Z/BwrF4m1/lJP+e6sp1PIWZqrmtWmOzZV+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858296; c=relaxed/simple; bh=uG4ACee89o5yDAx8jl0XQ3Ej30wl3vyq3DFGW2WuGOY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=hLPR76x2/OjMfVAHDutyP4/Bem95QZRCFdX3TM6jT5jL4cyUOY+p+d552g6qCkAuL97d74PwjtwzBRwS2pqg2oZUJNcXnWuXpmz2QF/VuH204WQ3bTHI0uPUeKYSTPgwnlTMaYjgsQf2wkIufN+HYSbGWOjNY7iAtGYD6fHKlAU= 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=oQFGJoTh; 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="oQFGJoTh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858286; bh=vW7i3csX12V3fwAT7AMdFBxlvR1nMoxQ7dR1U2yhBis=; h=From:To:Subject:Date:Message-Id; b=oQFGJoThU2nKhY2kAm6bD7DH2MlXhJ/TkYF89YRiT64ZYB8JYgsZZitMR624l1Lqa Q9szvoKO7WmJPOZMCxe5vS9D0JsJ7mtcYEAouyF1Vmq9pYy4qf9wPtQaqLrFSJXyMh R3odZxren/yiTwxMpUTdR+dy1dIojY6G9EPcOPTM= X-QQ-mid: zesmtpsz9t1762858282tdafe9850 X-QQ-Originating-IP: wyzPTYXjSD/oKTZmDvyOXUmdUWTX2813dJRRjsTLuKg= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:51:19 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 13309204121972102905 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 08/10] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Date: Tue, 11 Nov 2025 18:50:38 +0800 Message-Id: <20251111105040.94-9-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: N9DIJtFs/avns4hvy0i9PlQnzUKMcR9PMBIHO1WJNv0mYLGs2SuQu8Ep 3BpdYmkzaAtmDXHsoVhPoEwkIMZoxbb3Xg/ohwkMMgE22FSeIhVpvtcytMtGnQyLub4q/ot eJPUZrLPm8QRG6536pvRaUrxZlPwMBSFe5Ao4It3IJuueaFAhFC+vDqA3Z2xglk1+QYl4/r qu3rpu+TCJbpN3GtgZqA+BtYK4mOlNy4K6e5PwfOKJGYg/41n/UhyJKCm13Uxvbbluh5R+p 7RTQ4bbVMYMlKxhW6dUtledHHblw5uf/psfMp2znBda83YNVTSSERmhdvPmAV5ea4/7kiAw sap/zb3MYlejUzrCe7Mivwhkso6MoU4AlrZGpE+sVPiCtQ2RWw5WDRGCzhnjcUM8o3FyMh6 trMTnlzDLVLEJRWD/pIP/ZKPby2VSrOKid+VTONgOVGKCsNAV5AYprBbPx/HM/axlc2bCz8 iwrYwLcLDt35VTrmFbKEW0/ByCnmB2T2YE6pzxLujwGOO8hCfeR38ZI5l/JAHvJ7fHHiSOG b+cxgeFml/26JfJcF0ukDcL7JbdarBQD64DSKFaQUj1iuUdkNwL38TwsUUVHQPFZYV4OV+I Ai1Und8JCyIMwRHyMdrOP/bIsAP07iE5Rl+M+GZU7IO+yf8YS7N+c0GxrywwpgXgFRC01X0 gBlzPZH0NLKrdwbl3XZhL0bnIFEXIk6cA1sGSeq2R8VKNEloOC9bhUgrG8bSYD98HeFOwg4 wbOz16Ni4NAE3bZ+YQYTLnOtjcuOgF9LS1btpCK7ms1HfGW318PKsNfENHHMVe/TG7P4hXa ep9xhTvfhFEjJBBr3locRb9hczzGpfsiIaYVT5eOMyfDmyxK1IXcZiARLzExuEcP8BwESwE TyisTHMXlgR1KLGJ364oGOvPCAMxh3j4KgBRtik/V2Ba+WHcSSwDYNWHL8lksGoKsqSl1DU 3rfxTFQVim8Z0I9pQqYHjPA+P0h9KROTf1UfzS5N8jNnqW6tMZ6DyVumjZi5fLcbJV3XaTr qIbuWHIoqG7BK0V/g7q076AOLe4fE= X-QQ-XMRINFO: NI4Ajvh11aEj8Xl/2s1/T8w= 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 --- Changes in v9: - Select DRM_AUX_HPD_BRIDGE when using DP driver. (no changes since v7) Changes in v6: - Rename some variable names. - Attach the DP bridge to the next bridge. Changes in v5: - By parsing the HPD bridge chain, set the connector's of_node to the of_node corresponding to the USB-C connector. - Return EDID cache when other port is already enabled. drivers/gpu/drm/rockchip/Kconfig | 1 + drivers/gpu/drm/rockchip/cdn-dp-core.c | 329 ++++++++++++++++++++----- drivers/gpu/drm/rockchip/cdn-dp-core.h | 24 +- 3 files changed, 297 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kc= onfig index b7b025814e72..10d9f29a3d44 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -56,6 +56,7 @@ config ROCKCHIP_CDN_DP select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR select DRM_DISPLAY_DP_HELPER + select DRM_AUX_HPD_BRIDGE help This selects support for Rockchip SoC specific extensions for the cdn DP driver. If you want to enable Dp on diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index 1e27301584a4..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.51.1 From nobody Sat Feb 7 21:05:40 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 B272A3587D7; Tue, 11 Nov 2025 10:51:32 +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=1762858295; cv=none; b=t/hJRIvsYERHDa7PylWEWJ8odkuNI7u8gRR7s7os1vYcK9k4U/dvl0n1k5HENXXpc1hxTh+27vv8yx3gLQ+2mi+b7Putc6k1p88SUYnMav9Pg0If++RRYPC9uKn87fT5OHm5L1NIj9hSNxSf37BVqecJaF5OthEkg6F41l5AzYc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858295; c=relaxed/simple; bh=UYBXRUGpsPucbSnyCek2T6kQGAmNcIEArFxOg+A85iE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=NE4YCHiU8FN77B/En54Qs2UYhuVuFqFtugaCmPo48bVXORFEc2t5IUyx21M8qk00/JYYlxDnPKhJ1x6rLlUghZ0PsGKvp3LKcy5lBxLEIcyf1LEVHJW0/eS68qEIeoV8SURjhtwTZfhwJesUDQ2yL91OWhZVbPAg2wmiAFbDWYs= 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=oqBD5zV6; 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="oqBD5zV6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858290; bh=pFI7M+6j2JewnD4BwkGRc0QPG+RPFm6rGXiCORxPrVE=; h=From:To:Subject:Date:Message-Id; b=oqBD5zV6YJO40Zi/mJaQijusrScK02HgaGHpiM9DDpi5h964WQ0WaRGZbQ90HbNFt zk1DITH3UujVUhptbnY4M3+JbWYmZd5l+izjdW5bRthGujjzd0EXVhgw8k2Me47ar6 hK2mOXUtpWbelpfvEBdRXl9PzGAT+DACiiJQNDKw= X-QQ-mid: zesmtpsz9t1762858287t5941ed20 X-QQ-Originating-IP: oggRwoMydKBDH0LmcR8KzliYg47YhSd7rMeyclg9ztc= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:51:24 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 15062605320672791780 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 09/10] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Date: Tue, 11 Nov 2025 18:50:39 +0800 Message-Id: <20251111105040.94-10-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: OUksgP1p7wvYcTmCIbAbgPqsFwkz5TEDssB8YMyii1AcuwEqA61bxWOY PLpodXsKH0cvKY/rqj5YXK5Ps3mCuFV2MFOrt+hr5BqnpYqAbiafjfk6gRrhCoY9mIO9Pes IEoLIBHAGOFqo+FosLKsl0qtG6eoGLY1d5EMXZwzddoETlQu8vWNTbCg0j7WyrBlNkmM5k5 lxVzH/xJmR65o2tPK+C+C6Uw+Mwjzv2/mjGCpVM4N0wVqGYl2Grz+gmKPMNVery5BCuC+y9 v/IGZmo9UzjHsNOIr7jtjK3G+Hvbg64KwjO2z7ZZsZE3tizOWrp8oW+itxmZXzO2JNPzR4x ug+cecIrZIa7raPkhQchWLz211ONqkOEdf2cLsy4VKIAv+pa2uHLhFzUgaY64NQGv4x0iO0 2RZ3m1gleLWYP9X7+5XOhXEvWT9RNbd/E127RltXQwQ3f2rGIlzO295tNne25y0eJenKFwd fM1x+zxycqUG7zVFZymzLGYX4E0uMXE67khu9sb6s50wJy0RtillqcxFH508NS91+dk+QJq 1zGM6BVEzfnaVwXMpSsChWbFCXFAvaKJYXeUTIkg0NZK3WzKQUzlMb2MoWMe9qZ+fcHP4Re ScemEVA3ypjiBYmg3KdLOcjAB5r97YKygzo9LEfgRhpM3WEirCe1JGJbN0qVgbgTBrK1V5t /faT/giwM9up2njBBw4mNP0zf2T506kYUPVZ9dlMl5Jc5mioprm25Dmwy2MmumNZGahOkQ3 7bJ4Zoc76ScFiE2nUDkILJyepQ0tO/ypjKAf7EesHPyumSLeCHnb6Ed+kABhM5h3PtQ5h8A mLupmb9xbrP7XYtIc3hIauAoUfAP+KrO6C7+qfwdy1HdgDmEvVcfYzZMpnTw6OItEbID1JH Fom9OYyUmeOiR5idOkOHyqToc1w3wHVlC2pn7gxncdu0SBv0ThzwJo2oIk49yX+33oC4Ri1 Dh4AMyL1GMAITlUDDzL2eJxmcS7ESVLwL3rTLFiKBw+Z/2p1cKdi5LXtdm9o3Lb7HBbtNnv GkE4Ushg== 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 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.51.1 From nobody Sat Feb 7 21:05:40 2026 Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) (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 140111E7C23; Tue, 11 Nov 2025 10:52:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.243.244.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858360; cv=none; b=sbbet1qPreFDmzSda0qm3LreAln82nv184uEqPPY6qwkwAaby/9EGOzAZBM1SqgeZnxGxN3QsySeg2YTX1khh511XmePQd1Tl6ZxGOoaO9bsvEZk1arVlkHxG4svRcifQmrJuGRgR9SPvKynBwQzjLMnMxpaXevmqmnhvCGGKZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762858360; c=relaxed/simple; bh=gU056Y/rFcOj1a11SgXQ0IMaQNIV6nhU5/yij/2i3qk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=QFS8xBF/HSz49Wux7aho2Bp0TzmOVewsyySgTrC4zQk6bvtCSrRTOameSgerCOb1s+xSoz46kB1r98zXrkpRIXMH3ppvtojACmE0GZBTkZKtbiA5FGVJQnEWvg1NFStZnYBYYIjq6Qy0TEElT7LO7M/kmygPMT45Dvz0SPyQxSY= 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=H1wmp5u+; arc=none smtp.client-ip=54.243.244.52 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="H1wmp5u+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1762858353; bh=fg2TKuNBAB7TuYxIVNS/NsLi1w/3kkBrg4QejE4Xpiw=; h=From:To:Subject:Date:Message-Id; b=H1wmp5u+vUxZRDUoAKUtlMByDH46lMU2OwSdcWWntFv64h/BQTQdoGphKzofbpvpb EWGoaaGREiEed4wi7xtzJDf4Ew4jEp6YUAaZK7JNaqGpXubmFSgrAtNIB7ZYi4kmhB H/LLlhYNx+uDD+NBXpjKi9q4n+WyVaV8Q608AO18= X-QQ-mid: zesmtpsz9t1762858291te7294ff4 X-QQ-Originating-IP: exeCqqoIeGySwZLpWAlGG7yGEO1UuQ9aEdXrUWr2v7o= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Nov 2025 18:51:28 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 3148432019982431225 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Peter Chen , 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 v9 10/10] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Date: Tue, 11 Nov 2025 18:50:40 +0800 Message-Id: <20251111105040.94-11-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251111105040.94-1-kernel@airkyi.com> References: <20251111105040.94-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NYz8c2bcbB9MeJGSUhMFJX+QKNtglUuTkBwxriXbkhOkJmswov+ZfY3B oCLlY8sNRsm2hv76MYg7rpgseOTtUQWIAfQ0EU5trx7GQpsBAcl7Fr1ELjvs4JRGAdCExW8 O+Ank2QvOlVAlWk4pvkMbk6jEG+Yfwc10e7QRdHDbENYEvbw5Ve3A6IKjmgbH9Fh1npGSq8 TOWz0VpjA7StX8n1dHLFGrPwAxzxAMmAvzqCTi3aosy/B8ndnKEfXCuBiyPeu5MjN8bWj6U 48bI6RtdfG48s2McjQOQT45cLQCOc5W40k32YZfRQ4gcGr15QRGNyE7jaZy73fNQtwEQul0 NefdWk5BcbdkLFKBtU9uzn4mxC5kxHXWKlnfmkpeLNx8+lbS4Y4zDOODtY3KdAKfeHgiT2o jvKGAPDmRxKO6Hz6RuI4RrRc9snK9zOPByyIpwjE6PP75HUG05Cmw/68Lvss+J9EYVC4FFu j72CzLtle0FzBo6Wq3RmqX77/DFC4MFpTO2cWEOedHam/50cEG2qK57TNDBP8ti694g+6ep p8J6i3kjVRL9w5TE3oOtY4sgnayjeGUc9BM5UQKplI3Hd8zRo0F9HwM7OgtvYr5kn9Jb5yk EFKAvpcVgRpNOWTD0KcnannDLD0H7+0RX1M7zMIVaPFh4IoOQjV/LQPnyn70GbOzPray8mt jx90P9pjgykFTWztUQunZLK2ssbc5fSpw0fGTFO9BNIaJJyi8X+kMwb9trO90Mc/HpMH1cF qHHHGXvrLqLwb9JiFY5HR/yM+wG2SssGkOp1UI0ewgdKXcHiL6+Xsa2nLPomXznR2O541Dh imzsh2eT+OT/erA2kA+6eMIaIQpRyMUKPhyy6dcF1t6sT0fEPNOXqIjSWoq7Os1ZWv+EpPk VKuN8xWFwlvUE2jQ5DHPSQ2gq97FOA/pqkP5DtC+HH5Uotxff+V1TWsPSk6ddL1tqo9z47i N6Nl5GP7AdTwmzFEZsq/7hiWFLoie7sNba/fUuLqENIYaqJ8fkSkns9Y1UbBqKIH8RAPAk5 ex3RKweNxBx4GrpCUUuCrAWnHxaji3wRVGvuW6Jw== X-QQ-XMRINFO: MSVp+SPm3vtS1Vd6Y4Mggwc= 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 --- Changes in v9: - Add usb role switch for Type-C. - Remove USB2 PHY in Type-C connection. (no changes since v4) Changes in v3: - Fix wrong vdo value. - Fix port node in usb-c-connector. Changes in v2: - Add endpoint to link DP PHY and DP controller. - Fix devicetree coding style. .../boot/dts/rockchip/rk3399-evb-ind.dts | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/b= oot/dts/rockchip/rk3399-evb-ind.dts index 70aee1ab904c..be1e90f7a453 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts @@ -4,6 +4,7 @@ */ =20 /dts-v1/; +#include #include "rk3399.dtsi" =20 / { @@ -19,6 +20,21 @@ chosen { stdout-path =3D "serial2:1500000n8"; }; =20 + sound: sound { + compatible =3D "rockchip,rk3399-gru-sound"; + rockchip,cpu =3D <&i2s0 &spdif>; + }; + + vbus_typec: regulator-vbus-typec { + compatible =3D "regulator-fixed"; + enable-active-high; + gpio =3D <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&vcc5v0_typec0_en>; + regulator-name =3D "vbus_typec"; + vin-supply =3D <&vcc5v0_sys>; + }; + vcc5v0_sys: regulator-vcc5v0-sys { compatible =3D "regulator-fixed"; enable-active-high; @@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys { }; }; =20 +&cdn_dp { + phys =3D <&tcphy0_dp>; + status =3D "okay"; +}; + &cpu_b0 { cpu-supply =3D <&vdd_cpu_b>; }; @@ -55,6 +76,12 @@ &cpu_l3 { cpu-supply =3D <&vdd_cpu_l>; }; =20 +&dp_out { + dp_controller_output: endpoint { + remote-endpoint =3D <&dp_phy_in>; + }; +}; + &emmc_phy { status =3D "okay"; }; @@ -341,6 +368,71 @@ regulator-state-mem { }; }; =20 +&i2c4 { + i2c-scl-rising-time-ns =3D <475>; + i2c-scl-falling-time-ns =3D <26>; + status =3D "okay"; + + usbc0: typec-portc@22 { + compatible =3D "fcs,fusb302"; + reg =3D <0x22>; + interrupt-parent =3D <&gpio1>; + interrupts =3D ; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&usbc0_int>; + vbus-supply =3D <&vbus_typec>; + + usb_con: connector { + compatible =3D "usb-c-connector"; + label =3D "USB-C"; + data-role =3D "dual"; + power-role =3D "dual"; + try-power-role =3D "sink"; + op-sink-microwatt =3D <1000000>; + sink-pdos =3D + ; + source-pdos =3D + ; + + altmodes { + displayport { + svid =3D /bits/ 16 <0xff01>; + vdo =3D <0x00001c46>; + }; + }; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + + usbc0_orien_sw: endpoint { + remote-endpoint =3D <&tcphy0_orientation_switch>; + }; + }; + + port@1 { + reg =3D <1>; + + usbc0_role_sw: endpoint { + remote-endpoint =3D <&dwc3_0_role_switch>; + }; + }; + + port@2 { + reg =3D <2>; + + dp_altmode_mux: endpoint { + remote-endpoint =3D <&tcphy0_typec_dp>; + }; + }; + }; + }; + }; +}; + &i2s2 { status =3D "okay"; }; @@ -354,6 +446,16 @@ &io_domains { }; =20 &pinctrl { + usb-typec { + usbc0_int: usbc0-int { + rockchip,pins =3D <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vcc5v0_typec0_en: vcc5v0-typec0-en { + rockchip,pins =3D <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int_l: pmic-int-l { rockchip,pins =3D <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; @@ -400,10 +502,48 @@ &sdmmc { status =3D "okay"; }; =20 +&sound { + rockchip,codec =3D <&cdn_dp>; + status =3D "okay"; +}; + +&spdif { + status =3D "okay"; +}; + &tcphy0 { status =3D "okay"; }; =20 +&tcphy0_dp { + mode-switch; + + port { + #address-cells =3D <1>; + #size-cells =3D <0>; + + tcphy0_typec_dp: endpoint@0 { + reg =3D <0>; + remote-endpoint =3D <&dp_altmode_mux>; + }; + + dp_phy_in: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&dp_controller_output>; + }; + }; +}; + +&tcphy0_usb3 { + orientation-switch; + + port { + tcphy0_orientation_switch: endpoint { + remote-endpoint =3D <&usbc0_orien_sw>; + }; + }; +}; + &tcphy1 { status =3D "okay"; }; @@ -461,7 +601,14 @@ &usb_host1_ohci { }; =20 &usbdrd_dwc3_0 { + usb-role-switch; status =3D "okay"; + + port { + dwc3_0_role_switch: endpoint { + remote-endpoint =3D <&usbc0_role_sw>; + }; + }; }; =20 &usbdrd3_0 { --=20 2.51.1