From nobody Mon Dec 15 19:10:34 2025 Received: from smtpbg151.qq.com (smtpbg151.qq.com [18.169.211.239]) (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 22DA93101CE for ; Wed, 29 Oct 2025 07:16:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=18.169.211.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722191; cv=none; b=YBPWekRqgdZfq40c5n4spYDgu89JeK3d+sTUzVA4Cfu49LkrUkvMP5igCGmkYVkLS0gcum5OYCfEDLKeFF6ymnFjZjQ6fk4uPiTr0jQFx1VikbJ4besL3RPpCpNxI9Lj51XWav3Ok1Im1ganOJWUsdaWkVkhwduu0unsPysKY0c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722191; c=relaxed/simple; bh=0cv2DaVOvSCRKuK43q4uxtIsFfdtbekWcTaoQMKAUa8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=kM/b76S9fouu8AEqjg7R/pNN3ppRWszL3a6Wgfdgamw/wMw6Uic67pHRqcJwj+ZXu0E1RsUiN0Wtkir/lNYOCiUBDzblcYtE7JdgZ8Iu/T9Mj1DeWk2s+6a/2nartzR9u8bXyMksRCx603DsF86T8l39W0FPZ8RnE4PRFZ1sEDE= 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=axDSjnoM; arc=none smtp.client-ip=18.169.211.239 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="axDSjnoM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722091; bh=j2j9WA1trqT3vAVw/jd1rQawmJe4KSEvtc97hT+jsmc=; h=From:To:Subject:Date:Message-Id; b=axDSjnoMzuC5X6IKwC9o8L+YT8jloY/jdQraAGDAwFUMaGnjlNLYOJirtVl6qZZMj KneCijyldkDE7fIj9+2B5ZIO+YkhaGeOAIMhQqG3eo8f3ddXdiIzVbfcZnKqBQRTEj 9dpvZ6nagLyzIzSQCBE/WfKsv90ZVTNJhy0lwi0g= X-QQ-mid: zesmtpsz6t1761722089t7ff69d0c X-QQ-Originating-IP: 7bQdVQ9oUX34jRxfdd7Wtzl35M8B8aqczAbGIlIcToY= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:14:45 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 376849328953314141 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 01/10] usb: typec: Add notifier functions Date: Wed, 29 Oct 2025 15:14:26 +0800 Message-Id: <20251029071435.88-2-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: MjqaYNLY8QZGIpmhSyWql8me1d5OxWxLDL4l4EY/xytzQsP2bDcsJWMt 49n8ST3h+nN0tPnp1cxviRfuOfbgBmdWy+/hy5YZ3jSgKY3dsUAR3393FgGroGshRWi+nSD +OcO90YAQWoOhyV3VuW6G9femXmqzYHnKNQytoLtnQwlvl2TiUy/xPwH44PcrgFWMnT3rXz bVWEqUmBcKXUDbo7nMaYbjWqgXDXeM01N6xqbxHaQ3v3p28kWEDyHEDLVjkGcf8/DnlxhqI PH68mbUb1+mhy0mgVYxTwcqA7Qtwx9Tni5dTDIf2LrZ50lCjcas7THoR2tJfiZ5UwpjICJ+ tnZduuYp7U1yaSzw3ZDY5ZRKgcwGj4/jnblrjELDykEdh+mOtQO5DkWzFc05+lnTRh+Bbp6 J2LAKv98Seg6CSCuMvZv6yWkZXlJ++csPj1YivMvL2tVu1jhfOwjtyqecPGx7LJ1lH6z4i1 YOKjECb8140Ugw/c8eqCu1onEupANpLfjiZa0ULJ8aRAuz+kA+kkLgYn8l92bYnWe9J93EN tLD6RC8+t1Y6mT0z9LeJ4V5qg34LDHODStS28IEefDVda4tX+NWbOkaCykv9LaNkCTj54Hr GZi671WHSuRneXDpZuqUh6I3cTOwsYSj2L5MiixFYuTm1HbFbm1UVTrvMOpqywjFp389geM n1VaiuGgqmeO/k7fHx4F0Sc6OAC407IhzI/389SOsaNuJ+02KllOEWwJAW/fA2Mr7AYTE07 Oog5lplwnUlfrBqCGIsfV/45LFLKxBYckhWcmnmbkqEod6oVNgyQD279QKxJ6Ga9blkWEl9 GAYeeZc5+etZAY9KwWsGaX3Oyf0C/YDoV6gcgHsQdWHZMURiRO+cJJw5Y6zeJSpA0puJxZA /+S7w0Bd8hE6g2kfBoyjWUODYCZHGmjmZXqMF21N9q67X3r/zTAs7n5d56MNYTtIIfHtud/ U86yulE2M359yC5hhMBPrUJrRru3RbeXeROxvtwJjfYbgcSjLZfrsJIdtdHQXkHCV4d4= X-QQ-XMRINFO: M/715EihBoGSf6IYSX1iLFg= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen 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 v8: - Fix coding style. drivers/usb/typec/Makefile | 2 +- drivers/usb/typec/bus.h | 2 ++ drivers/usb/typec/class.c | 3 +++ drivers/usb/typec/notify.c | 24 ++++++++++++++++++++++++ include/linux/usb/typec_notify.h | 16 ++++++++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/typec/notify.c create mode 100644 include/linux/usb/typec_notify.h diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 7a368fea61bc..20d09c5314d7 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TYPEC) +=3D typec.o -typec-y :=3D class.o mux.o bus.o pd.o retimer.o +typec-y :=3D class.o mux.o notify.o bus.o pd.o retimer.o typec-$(CONFIG_ACPI) +=3D port-mapper.o obj-$(CONFIG_TYPEC) +=3D altmodes/ obj-$(CONFIG_TYPEC_TCPM) +=3D tcpm/ diff --git a/drivers/usb/typec/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..51e971bc68d1 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include =20 @@ -600,6 +601,8 @@ typec_register_altmode(struct device *parent, return ERR_PTR(ret); } =20 + typec_notify_event(TYPEC_ALTMODE_REGISTERED, &alt->adev); + return &alt->adev; } =20 diff --git a/drivers/usb/typec/notify.c b/drivers/usb/typec/notify.c new file mode 100644 index 000000000000..0a14d3ae224e --- /dev/null +++ b/drivers/usb/typec/notify.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#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_notify.h b/include/linux/usb/typec_not= ify.h new file mode 100644 index 000000000000..f3a7b5f5b05b --- /dev/null +++ b/include/linux/usb/typec_notify.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __USB_TYPEC_NOTIFY +#define __USB_TYPEC_NOTIFY + +#include + +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); + +#endif /* __USB_TYPEC_NOTIFY */ --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 Received: from smtpbgjp3.qq.com (smtpbgjp3.qq.com [54.92.39.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 408893101B4 for ; Wed, 29 Oct 2025 07:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.92.39.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722186; cv=none; b=vC8NsBvgUnwsfyHRv5OLNz0WOK+/3Zhbv/knuTXOvUbgjwJX+5vmknsoqbNKN05l+FF8dT9Fj09prxtz1QzMg0kQxbA4C/sZfvwFVMRQeGRLy59Uk9kIx1DmIZNWjbCrY8lzC+wcMEMJwyx7bRaEpm5IKM92H2Jajoz4ksKzkl4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722186; c=relaxed/simple; bh=B2zgCFdycTJPuhk+bmDbmYgStcK4CB41tVtMHlEqCBw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Kxubp0e2qpJ/V9e+r5G0L7sWDLz/ddVRWVrlSDGslWG0iE5xizQeL+zJtoAMFAqrpI8v/MVbipmuyrL9UuPzR8DSeRUV8tLCfTN9IlEFbY2b6eSMNJoUaSwoqiYYxeXKnWVQF1PLLQh7QLby/Aw4031188+jLWF4o9gsnmLPL6A= 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=GjU2IXd6; arc=none smtp.client-ip=54.92.39.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="GjU2IXd6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722095; bh=brizxRBu3LFpj2XHv7UBCSeP95PLEUGrh/8On/FsYA4=; h=From:To:Subject:Date:Message-Id; b=GjU2IXd6PkwymaUvkTE9jFp822SjnwxBtY2tuju2gt0wMsra9EK6aLL47yxgxE+Wl zZfZASSTthemMhNWbB38ddjliV6/wu/3zfc2Xe2LunsI8baWe6N93UQYQay7/sklGe YfNTU2+Nviq41BV+/ewpSJrbmdqPL+yoyaHKM4lU= X-QQ-mid: zesmtpsz6t1761722094tafaac705 X-QQ-Originating-IP: 6uKBeLRKt9TvmdEuUvqbMA/JOlRqI8QIJ5dkrGmyzOE= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:14:51 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 10059686084255947240 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 02/10] usb: typec: Export all typec device types Date: Wed, 29 Oct 2025 15:14:27 +0800 Message-Id: <20251029071435.88-3-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NE5Pnkvry7UFYCMhecDQbQs4M31xG+wRVtJNT1y+KXxm1VlUFVE3FuN9 p3T896cvThq7faeZTXBOdcsfiH92OHkq6mJ8iTXFAWdI5hMRsBSTR/RD5iYv4omkGFShyYU ynA7hHE8rH+ovLMbrOJQKs6werzfep3djzmTlWzHdG2+nT7S2c3DRfD4JxgqRfSyYnZoxIe yl7cCSlFSkspHUtaxD3VmxuOyJovm9POqagQ0jGDiEpPA3lQZ5voVOsUnarbIIJPjqle2AC my92ivocc9J8kQu8PZ+jTjHxEPGAGiDWxQMoE5YVep53YsAyeXen3HnuuZNG6eQbHD6zuPd JeNRmxja62pxh0qWwpnjVJRAm+d3Z5MM+qR4WmkoNpUY61CmsE9T0IKzCgjYBIAQC9OLkw/ gvIxTpLmTslExIWX3rl1JQ2lvCj/vz9rWADWonY7B0ugeuraM+dNWurixY+GdpVRWANX32i BS/YiL8x0dSazCmmtmNqZfJ9zM3hJliakoI7BSoozglalvQWlAfA6Ge7MwI52AU1yn9qiov /ynrVqvr2Scx2JO+jPvbOSXgTPMOI5VKk+37Tt39hklkWWTXe6WPeNJ3B1kUt8JEyERU4b1 mMcLoZX8SZZopOF4VfQ25unw5Vsm3kQxK+eecrnaZ5inj6/LtE264vIusFGHFfiDuqGC0JE +DNETzK2yCTUAAw0q5fUrz146e2EbqN9ru/7roMsrhlHkdDF3PQlP+Xy0itrB5NN5mgOIIC 6F2GDJb0d7EbY9+XxcjHyLTEAYR2Ht786USXsg/3UIaIGYZlr1h4W/UamxYlUgDH4luPVAN IgjXAKsPzXD0I4UX6/NpbxzzlY5+qEjf0GLBmMY/YOWbPaWaNj37hjwtA8zy3b7ZN4rti1e 224z5gbpWH8JT8VKKxOeDgKFZjY8rbcXd2cWQG+1y0mMDwtkqZt2fDa0VXDxMdOZbTIZRYU HgAyockj4tphOllgltTCXX122guoyFldG4wTmECnFeaqtTgwG63/AUyYk80ZDm3v6kg8RHd fR5OWn1v2tKEccti8D 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 Export all typec device types for identification. Signed-off-by: Chaoyi Chen Reviewed-by: Heikki Krogerus --- 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 51e971bc68d1..04b55f066b06 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -793,6 +793,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) { @@ -1147,6 +1148,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 @@ -1295,6 +1297,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 @@ -2034,6 +2037,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.49.0 From nobody Mon Dec 15 19:10:34 2025 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 16B2630E83E for ; Wed, 29 Oct 2025 07:16:44 +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=1761722207; cv=none; b=XhrvcIK8CNes76bLn0gG/hL3PvMcNkzBGsgQlp+TPegpYvnqvbkymegTj4KjAN67/PCf0KqVSUvVlcnxssVBSTTZ8/9PZjRj2UuzlfJAXTUuKgn2coXIszrE7vtUpcnfvpFWCMdpnm33GB219w9QHsMWAkgXChm9JrsbZsk94jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722207; c=relaxed/simple; bh=4CCYR8EmTCLjnjMKWXRVpb3kDaoWjn7pZFM/jfqBMF0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=ilsdWaf+QJxGTxurYKBZQAhUP1rWe4NCmZMF3/0IEb3S9RwxETAL3R1K85grCIcbXC1FZU2C0YM1APyR8GqiI7/pq4r8yqKbF/9mA4PKzONPQOdapWzr+inDxfjBHl82kjKLTZp8jwMNSFctNp9ecefDUa9qBMphva1lgMQ9ij4= 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=WfsLwyq4; 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="WfsLwyq4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722101; bh=FJMoyZ1t1YeDBw7c8GChVfEptGd+0NATOX776m3g0j4=; h=From:To:Subject:Date:Message-Id; b=WfsLwyq4FS8wSfAryEYVifdG9ybxMh9BxPhlWhlLPJ9Ws9+Zg1Tp1HgRBHfWE7Iyb BtJZIxFXnP94bPr2p4bz8Lnxfwdsx0GUv3AK4dyJMdjyJXlRzAGMfRr1vFYXr0VCi2 hW0MQQjpYofYNPWUvI7h1oEG4iUxxMbaKJaMbJ68= X-QQ-mid: zesmtpsz6t1761722098t70ec4185 X-QQ-Originating-IP: nrXTS2MjCDfq0/Rdag/r96GHT70yO64qGAp8vt7JiO8= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:14:55 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 238686505024682894 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 03/10] drm/bridge: Implement generic USB Type-C DP HPD bridge Date: Wed, 29 Oct 2025 15:14:28 +0800 Message-Id: <20251029071435.88-4-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: Non7B45eNO9BaBSoFlGwoRXV2OmWn8KRiK6uYLn7ywxwE29wtMwDJyZm 2tT/HRL+JM2WLApvGJbwkfcsC9zCQon0VkgP10jWshukESwmPnN9S4NQvG64PWBwIluI4lp XQsedcX688J25pN1JvD0wH35e+57B4h6Kmi6Zn/mhBWoy1tzclPEoL0PwTD7F8weUbo/xwq 0HKmEWEv5xLwAH1UFvc1GfmSUqpoZNVJf5sl/FrvV2HOp3vvSoW1A7yNBcx4napbicgjYK6 n5OM3PagBifX4lCB+xxrc7SL1KWK50p81vObqQZwjibKjkhA3J0/aeRRJKe04c483grXjpB y2DyDZ/SlyBxZK+zwiCB5b63HLthB/UH/T9GyNLWJyyGZinFMTPcMZGqhZOMTZIDXd0ZtUA nDrlE4qm0xH6x/YkAcAIiDAkgI4rRZx8IQ9Ljjx4UHIvujRiOcuXuBnd7ufOx+jKKR0r7T9 cGO/EycjO/hQGXdNRwCBMuRaBr3a/PbNHrfMgK5/i//EnS0Oh1MXz2rZ8KAh+Kg1Ton4LVN Dv4Uj9F+J5GOG3WbmwJPrXf+Iy68Nn2fR149pm5vFNXwEiN6XXpx0LHaR6XwqFCrXEBfJi6 wf4ORP9DXPj9vQewD8RfRx0L25cnvD3WYSy2m6Ux50SQ6h5aN1iVv6kOsGnivF/YGYVYOSR oQtp+XnnwvE503ypzAFcE62tkNq2sQLW7uD29KD74Qn+Fji3jo09gQEe1mK+en/7Mid2+mh FE7v8TaPZXbsGjWOe0x12aMpbrlo0IHUQNQX4VtmJyT4qvOyalujhwbdfernR81j5JK/vSt K+BkK9tqKxJuZnoXcfmTtgB4mClTWPWf3i9iAZOmH8BQFQWO4Nzrt67kU5aaFRsFBspT4i0 wkkP5Aqg7orzWKNlgBvFTidtL6LyHw9bF0IDFOoOJX1ipD/KIpHRlog+CxXQ9jCbIIutAqZ 3CY1Ca0caTNJLibEDS0qitMhp+0pwRy/5LKaps1g1iWsQKU/x0RA/HCUI3EIICgSpIFpRXI mk0Wpg65QMsjHJK2g0CFIYaILTi1WoPzz22laIjg== 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 Several USB-C controller drivers have already implemented the DP HPD bridge function provided by aux-hpd-bridge.c, but there are still some USB-C controller driver that have not yet implemented it. This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c, so that other USB-C controller drivers don't need to implement it again. Signed-off-by: Chaoyi Chen --- Changes in v8: - Merge generic DP HPD bridge into one module. drivers/gpu/drm/bridge/Kconfig | 5 +- drivers/gpu/drm/bridge/Makefile | 8 +++- drivers/gpu/drm/bridge/aux-hpd-bridge.c | 23 ++++++++- drivers/gpu/drm/bridge/aux-hpd-bridge.h | 13 +++++ .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 47 +++++++++++++++++++ 5 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/bridge/aux-hpd-bridge.h 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..17257b223a28 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -23,13 +23,16 @@ config DRM_AUX_BRIDGE build bridges chain. =20 config DRM_AUX_HPD_BRIDGE - tristate + tristate "AUX HPD bridge support" depends on DRM_BRIDGE && OF select AUXILIARY_BUS help Simple bridge that terminates the bridge chain and provides HPD support. =20 + Specifically, if you want a default Type-C DisplayPort HPD bridge for + each port of the Type-C controller, say Y here. + 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..2998937444bc 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,6 +1,12 @@ # 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 + +hpd-bridge-y :=3D aux-hpd-bridge.o +ifneq ($(CONFIG_TYPEC),) +hpd-bridge-y +=3D aux-hpd-typec-dp-bridge.o +endif +obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) +=3D hpd-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-bridge.c b/drivers/gpu/drm/brid= ge/aux-hpd-bridge.c index 2e9c702c7087..11ad6dc776c7 100644 --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c @@ -12,6 +12,8 @@ #include #include =20 +#include "aux-hpd-bridge.h" + static DEFINE_IDA(drm_aux_hpd_bridge_ida); =20 struct drm_aux_hpd_bridge_data { @@ -204,7 +206,26 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = =3D { .id_table =3D drm_aux_hpd_bridge_table, .probe =3D drm_aux_hpd_bridge_probe, }; -module_auxiliary_driver(drm_aux_hpd_bridge_drv); + +static int drm_aux_hpd_bridge_mod_init(void) +{ + int ret; + + ret =3D auxiliary_driver_register(&drm_aux_hpd_bridge_drv); + if (ret) + return ret; + + return drm_aux_hpd_typec_dp_bridge_init(); +} + +static void drm_aux_hpd_bridge_mod_exit(void) +{ + drm_aux_hpd_typec_dp_bridge_exit(); + auxiliary_driver_unregister(&drm_aux_hpd_bridge_drv); +} + +module_init(drm_aux_hpd_bridge_mod_init); +module_exit(drm_aux_hpd_bridge_mod_exit); =20 MODULE_AUTHOR("Dmitry Baryshkov "); MODULE_DESCRIPTION("DRM HPD bridge"); diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.h b/drivers/gpu/drm/brid= ge/aux-hpd-bridge.h new file mode 100644 index 000000000000..69364731c2f1 --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef AUX_HPD_BRIDGE_H +#define AUX_HPD_BRIDGE_H + +#if IS_REACHABLE(CONFIG_TYPEC) +int drm_aux_hpd_typec_dp_bridge_init(void); +void drm_aux_hpd_typec_dp_bridge_exit(void); +#else +static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; } +static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { } +#endif /* IS_REACHABLE(CONFIG_TYPEC) */ + +#endif /* AUX_HPD_BRIDGE_H */ 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..6f2a1fca0fc5 --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include +#include + +#include + +#include "aux-hpd-bridge.h" + +#if IS_REACHABLE(CONFIG_TYPEC) +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, +}; + +int drm_aux_hpd_typec_dp_bridge_init(void) +{ + return typec_altmode_register_notify(&drm_typec_event_nb); +} + +void drm_aux_hpd_typec_dp_bridge_exit(void) +{ + typec_altmode_unregister_notify(&drm_typec_event_nb); +} +#endif --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 777E630F542 for ; Wed, 29 Oct 2025 07:16:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.206.16.166 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722181; cv=none; b=i0CX7tu7RmIaJm+tg3a9B1ZGSKF1KB5pqsE6EaXg3ffbmGHR3oaa1SmbSD+c7MNzZx9bvJjXegSEC0nS+VlL5uFAXvaETMoGVsPQrvhV0eiNcSmkdgpfbLrPp/T3+gqMTBRGIab96BMlwdStCna0+CKR1EgpqB+HTq4I1xEt89g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722181; c=relaxed/simple; bh=JkC2n3cUcgwqX4mM3+Lhi39ig/OE1/fWWocxtgBRO8k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=V2ZZ6qUa3cz4eixwn+Mrldv/SxoaSwWoXov6gOL/8DFdc+LVHaBqmnYygxwOUMKJiYfPfl2QxF3Nxb+N7G6jf7rP0nzdqE1ZaBTPjOmr+GOiGu+4QJ1Bg0n0SbRKOrmrx+xfiwqAMRWAh2E8F7WB/sceSIMyIV/YBXfdlO7zXkU= 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=ZP0potWU; arc=none smtp.client-ip=54.206.16.166 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="ZP0potWU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722105; bh=YHT4Mxhe+zSodIVHd2qzlGnysBWHBxMufel41tGudBs=; h=From:To:Subject:Date:Message-Id; b=ZP0potWUGEJJnJlGR0dpTvyFnp+9HW5m8eBLSzghIm1BMioCwhr99HXC/coVmaCMa HtxkBOqqvDRRNkXj5VRArWuZhbBD+Jo1Ueb0oNmyEFWCq952svOf6Aj4RSiDA+p4up R3Lk3O7boUzjw4hYgDYBWUnWT7qvtPl0A06J1Adg= X-QQ-mid: zesmtpsz6t1761722103tee7fa66f X-QQ-Originating-IP: Ik7AVVI+4BnZaf1rl0zVbH4aG4jaNbSh2N+2iERqELk= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:15:00 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 6689497526499472264 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 04/10] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Date: Wed, 29 Oct 2025 15:14:29 +0800 Message-Id: <20251029071435.88-5-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NNgTDNpHPdfoSadMONWltYKZnnLo9D5gXeruG5XLO8PXo4YdZ3JDGtAE 2N9VIyPNwwHpVdBAJI2cqrO5UHF+TtEZKj95bVVA8lvWkiI+FCUogw4wtzhlbKu/rtcm2rD P+IDwVvQH1haTBPusFg0Yh1Wb0x/zuq+uUT+xKS3bzzjZ19Dxn9MIdfAGw0KHb+3NDJTeLE kAhfhVCaRp6Ffu9NChKK6nKWB2tPgG/HuO/aCcwMQiYtWl/0LOSpZcdTX/knzMAH1lVyXuh fO5T+2tgCji/7cMjaPQwKsc6ICgf96396B5YCJmEp7ox2eskYZ7ccqYqB1WKQ9cPcOeXpTa oRArcN8mIZc3mvPepo1KHJ/N3kJhZqe5HJLI6w78LJor6B83Mnjw14Yu6IiGUVpO//3bU3s DIg/zkPCz5SzFSIGFm+5OTAMyDIWUryvcJ/7sxLDVpOEEN/Mf0Fk4h4o7+3mJ7vW0pkSQFa vwLnIAlgOs1H9TY64pv8bLFdD0bZgwtnlnsFaNfjPp+RxBXT3kGB2JBqOSE89CWpQpgEJzj kz7yaVr65mQ6bySG6qDGF1mf+ffYGUne5zZq08Jki5PLpyWCOMPf+sH6uisY0XLfULhZpYt O0MfvDKBh/FjeOrc4SANyS28m0+sVyTmZCzkI8uoZlOQ3iqaHxfAlpPH65XkZYfeF+7wy62 0sNWEgRGWG436TyAoaCoajme//38vIG4zjJ1vu4o9RPxMdD/hC07anjw+8Vbb7dklVyR3dO 4aO6W5k4S1bkWZZFfU1/JkxzIEjtUrDcZxhsdf7Ce0VDZsjnXGN1fYC4jYHbrLgfU5cbVUH ODbGGCh3Hl91WoFd4j6f50AfhKLKt7A6OXn2p5RYsDC5Fz+k5hr/KBAqb2u/YY43GsGJ4v7 Q+wwjNhR/xc/YQPUf/IT47d6DhROonJLs8Gdvpkli0CGsxUX4JmmBj+VlfWofu6wBBgaRX7 8VjUzMvdvKpRjN97+CzlL704WOXcGSJjjEecs61XN68YxdoDQzEF4N52wYOnHY55+OZGM0Z 5OSEbw4A== 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 The RK3399 SoC integrates two USB/DP combo PHYs, each of which supports software-configurable pin mapping and DisplayPort lane assignment. These capabilities enable the PHY itself to handle both mode switching and orientation switching, based on the Type-C plug orientation and USB PD negotiation results. While an external Type-C controller is still required to detect cable attachment and report USB PD events, the actual mode and orientation switching is performed internally by the PHY through software configuration. This allows the PHY to act as a Type-C multiplexer for both data role and DP altmode configuration. To reflect this hardware design, this patch introduces a new "mode-switch" property for the dp-port node in the device tree bindings. This property indicates that the connected PHY is capable of handling Type-C mode switching itself. Signed-off-by: Chaoyi Chen Acked-by: Krzysztof Kozlowski --- (no changes since v5) Changes in v4: - Remove "|" in description. Changes in v3: - Add more descriptions to clarify the role of the PHY in switching. Changes in v2: - Reuse dp-port/usb3-port in rk3399-typec-phy binding. .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-ph= y.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.ya= ml index 91c011f68cd0..83ebcde096ea 100644 --- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml +++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml @@ -51,6 +51,12 @@ properties: '#phy-cells': const: 0 =20 + mode-switch: + description: + Indicates the PHY can handle altmode switching. In this case, + requires an external USB Type-C controller to report USB PD mess= age. + type: boolean + port: $ref: /schemas/graph.yaml#/properties/port description: Connection to USB Type-C connector --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 Received: from smtpbgsg2.qq.com (smtpbgsg2.qq.com [54.254.200.128]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 450FB313E3F for ; Wed, 29 Oct 2025 07:16:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.128 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722189; cv=none; b=jq6/F67dRkHy1exkdM+m4wJRt/yQT/pwVsxoQyoj02od+O3DVsCV9C8PdWgGBS1UhWj8XcHWsCILzNHFzOYGx7Lkue5ik8z6qexyrwoQmJ3KLwgm2XFFrpxRqOFEgfUbanyx1ivOZh1l1vM5qNzEMt8roDlKPdls++dnZNxhq54= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722189; c=relaxed/simple; bh=zCsRQvdeDvLSLnzuI7LiKYZp7U2SJUl0e0AEo+KRhvM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=ZZouvhS5DsQ6d04fj/b7dnrqd4/YYuPeeJUhQedG/HbrUku2D62z6ON4+L4xJz3VplP/XNw7z7Mb+fFAWkOVWvQO4DPTOM1//hc9oWLujqFt39EWcQRbMZbAA5AcBLgUMQ//DzzQohl9V+M2L5Jtpw6e4xd/ImxJQcgSTJtfNxU= 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=ndPthHny; arc=none smtp.client-ip=54.254.200.128 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="ndPthHny" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722109; bh=5KS6qDGs3DgFeS16auSi0pL5JfRWGjMinEXlOe5PpTI=; h=From:To:Subject:Date:Message-Id; b=ndPthHnyOa4hsOs1cD53zuucJwks+C227WWFnG8armne6GpsebHxdIfYyzftvPLUp Uru/Q0oxyMgnhGk/m2gwbYJBwUKVMKI4+DzwyXV8tIeDlg2fCjz65eZ3rWoiCRdLEO Pt+1oNk/OChxHJZXJ66WIguf43TL8P4o4Ow0jIK8= X-QQ-mid: zesmtpsz6t1761722107t906d9810 X-QQ-Originating-IP: 7Iqys5e5mtuaeL8hJ/Qw7mtU+uxrjoQBEiCzFJ3YJqw= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:15:05 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 15925501631327247557 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 05/10] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Date: Wed, 29 Oct 2025 15:14:30 +0800 Message-Id: <20251029071435.88-6-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NOIkHYnr7Vzd/tMyFT2j8ch1LAjAQnnQDx5VbT+TIFa0fjSe1tTbiG94 ubiO1oJ4+Bum3yzx1rZmuyovA7PYS1EMWhzEnRs85H/Hgwr/sMEG8dvAI1UIbdSDLVdlexR Mqw+rjNRDCGoRYMzuaPVuDwkteINzMppYdDHkgGrWJAj2Y8jCtMjN6g4L0ze4QksB4q83PC MtQLnkq6D5Zi8Psd6NFuUjLOg/8JqFhUkx40SA3NLSb0wErEN1ANaDYG8hS1o+/GQ4rQq0d CM9n/87nxRAnnTDvZBhr5DIT2j4CTM8PkUhgZKDsOnsyWCXxFvqJbvhfpgvAJxNK4DYPFoj QKPGAuKjuXSwnZwbP3eUoDHtSJGb9j2lre0pWjtWl/99JvkGwVs95Zc9LjELFs8NKHjyp/m Asp8LBf8FLuWg+Lkf1aB1YDTB/UUu81VZSSxIrvjUO2+Pd5a9DgS49Tki43fbSgf6nDUpOk RMudmqbWXpWTCwIWPy2JrnzJWkMrJyN7YGwtdi3OVqm7OdUMe9zDVWd+M7YtnvLNHaxpwxS 7lZcZGAPx/DLHyOAboqJ1fJIC1szG+v/VAZhF3I5N2duRRjaYujY1oTI3m3fqQuXIaa5PxV Zqhjz//ZerDcmMNPv+hbJPhi9JqoqkkdB+7eeILEAbFAabfOC0wK6vKEOjT9d6TBNj9RtI5 ES93Fk2sxS40RO+z5dCbuPRK22VIzmkIiNR/TIORUksSKNVMdMPOEYvYeHrELg5MEj0XrsX yf4hO2ohYWBPm7hrhv4tK9T021Ws3R8aw/HVDAMmbQKfnkzU1EtY5yrQ4qrfB410IYkxeHB 7ju+nphxDIjsC4/lnWAXA+wRRuH3ZPP42XYEWLSO6T8PG8pt/wW54Vxrc0TtY7p196mxH+Y dUv5doa3miP0yrsOLtrWXMLI22brMLOiRj/wkupr/J7ruhIpE3Ax3Ck983BKah1zIjiXL7F A3VA8qNx4snjFHGtmFMj+V6KrisqgnVMUTOzCxnUSKm1ezVworHcopbW9Do6v8G61mJc= X-QQ-XMRINFO: OD9hHCdaPRBwq3WW+NvGbIU= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen This patch add support for Type-C Port Controller Manager. Each PHY will register typec_mux and typec_switch when external Type-C controller is present. Type-C events are handled by TCPM without extcon. The extcon device should still be supported. Signed-off-by: Chaoyi Chen --- (no changes since v7) Changes in v6: - Fix depend in Kconfig. - Check DP svid in tcphy_typec_mux_set(). - Remove mode setting in tcphy_orien_sw_set(). (no changes since v5) Changes in v4: - Remove notify DP HPD state by USB/DP PHY. (no changes since v3) Changes in v2: - Fix compile error when CONFIG_TYPEC is not enabled. - Notify DP HPD state by USB/DP PHY. drivers/phy/rockchip/Kconfig | 1 + drivers/phy/rockchip/phy-rockchip-typec.c | 368 +++++++++++++++++++++- 2 files changed, 353 insertions(+), 16 deletions(-) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index 14698571b607..db4adc7c53da 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -119,6 +119,7 @@ config PHY_ROCKCHIP_SNPS_PCIE3 config PHY_ROCKCHIP_TYPEC tristate "Rockchip TYPEC PHY Driver" depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) + depends on TYPEC || TYPEC=3Dn select EXTCON select GENERIC_PHY select RESET_CONTROLLER diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockch= ip/phy-rockchip-typec.c index d9701b6106d5..1f5b4142cbe4 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -54,6 +54,8 @@ =20 #include #include +#include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -286,12 +288,23 @@ #define RX_DIAG_SC2C_DELAY (0x81e1 << 2) =20 #define PMA_LANE_CFG (0xc000 << 2) +#define PMA_LANE3_DP_LANE_SEL(x) (((x) & 0x3) << 14) +#define PMA_LANE3_INTERFACE_SEL(x) (((x) & 0x1) << 12) +#define PMA_LANE2_DP_LANE_SEL(x) (((x) & 0x3) << 10) +#define PMA_LANE2_INTERFACE_SEL(x) (((x) & 0x1) << 8) +#define PMA_LANE1_DP_LANE_SEL(x) (((x) & 0x3) << 6) +#define PMA_LANE1_INTERFACE_SEL(x) (((x) & 0x1) << 4) +#define PMA_LANE0_DP_LANE_SEL(x) (((x) & 0x3) << 2) +#define PMA_LANE0_INTERFACE_SEL(x) (((x) & 0x1) << 0) #define PIPE_CMN_CTRL1 (0xc001 << 2) #define PIPE_CMN_CTRL2 (0xc002 << 2) #define PIPE_COM_LOCK_CFG1 (0xc003 << 2) #define PIPE_COM_LOCK_CFG2 (0xc004 << 2) #define PIPE_RCV_DET_INH (0xc005 << 2) #define DP_MODE_CTL (0xc008 << 2) +#define PHY_DP_POWER_STATE_ACK_MASK GENMASK(7, 4) +#define PHY_DP_POWER_STATE_ACK_SHIFT 4 +#define PHY_DP_POWER_STATE_MASK GENMASK(3, 0) #define DP_CLK_CTL (0xc009 << 2) #define STS (0xc00F << 2) #define PHY_ISO_CMN_CTRL (0xc010 << 2) @@ -327,8 +340,15 @@ =20 #define DP_MODE_A0 BIT(4) #define DP_MODE_A2 BIT(6) -#define DP_MODE_ENTER_A0 0xc101 -#define DP_MODE_ENTER_A2 0xc104 + +#define DP_MODE_MASK 0xf +#define DP_MODE_ENTER_A0 BIT(0) +#define DP_MODE_ENTER_A2 BIT(2) +#define DP_MODE_ENTER_A3 BIT(3) +#define DP_MODE_A0_ACK BIT(4) +#define DP_MODE_A2_ACK BIT(6) +#define DP_MODE_A3_ACK BIT(7) +#define DP_LINK_RESET_DEASSERTED BIT(8) =20 #define PHY_MODE_SET_TIMEOUT 100000 =20 @@ -340,6 +360,31 @@ #define MODE_DFP_USB BIT(1) #define MODE_DFP_DP BIT(2) =20 +enum phy_dp_lane_num { + PHY_DP_LANE_0 =3D 0, + PHY_DP_LANE_1, + PHY_DP_LANE_2, + PHY_DP_LANE_3, +}; + +enum phy_pma_if { + PMA_IF_PIPE_PCS =3D 0, + PMA_IF_PHY_DP, +}; + +enum phy_typec_role { + TYPEC_PHY_USB =3D 0, + TYPEC_PHY_DP, + TYPEC_PHY_MAX, +}; + +enum phy_dp_power_state { + PHY_DP_POWER_STATE_A0 =3D 0, + PHY_DP_POWER_STATE_A1, + PHY_DP_POWER_STATE_A2, + PHY_DP_POWER_STATE_A3, +}; + struct usb3phy_reg { u32 offset; u32 enable_bit; @@ -372,18 +417,22 @@ struct rockchip_typec_phy { struct device *dev; void __iomem *base; struct extcon_dev *extcon; + struct typec_mux_dev *mux; + struct typec_switch_dev *sw; struct regmap *grf_regs; struct clk *clk_core; struct clk *clk_ref; struct reset_control *uphy_rst; struct reset_control *pipe_rst; struct reset_control *tcphy_rst; + struct phy *phys[TYPEC_PHY_MAX]; const struct rockchip_usb3phy_port_cfg *port_cfgs; /* mutex to protect access to individual PHYs */ struct mutex lock; =20 bool flip; u8 mode; + u8 new_mode; }; =20 struct phy_reg { @@ -454,6 +503,99 @@ static const struct rockchip_usb3phy_port_cfg rk3399_u= sb3phy_port_cfgs[] =3D { { /* sentinel */ } }; =20 +static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy, + bool value); + +static int tcphy_dp_set_power_state(struct rockchip_typec_phy *tcphy, + enum phy_dp_power_state state) +{ + u32 ack, reg, sts =3D BIT(state); + int ret; + + /* + * Power state changes must not be requested until after the cmn_ready + * signal has gone active. + */ + reg =3D readl(tcphy->base + PMA_CMN_CTRL1); + if (!(reg & CMN_READY)) { + dev_err(tcphy->dev, "cmn_ready in the inactive state\n"); + return -EINVAL; + } + + reg =3D readl(tcphy->base + DP_MODE_CTL); + reg &=3D ~PHY_DP_POWER_STATE_MASK; + reg |=3D sts; + writel(reg, tcphy->base + DP_MODE_CTL); + + ret =3D readl_poll_timeout(tcphy->base + DP_MODE_CTL, + ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >> + PHY_DP_POWER_STATE_ACK_SHIFT) =3D=3D sts), 10, + PHY_MODE_SET_TIMEOUT); + if (ret < 0) { + dev_err(tcphy->dev, "failed to enter power state %d\n", state); + return ret; + } + + return 0; +} + +/* + * For the TypeC PHY, the 4 lanes are mapping to the USB TypeC receptacle = pins + * as follows: + * ------------------------------------------------------------------- + * PHY Lanes/Module Pins TypeC Receptacle Pins + * ------------------------------------------------------------------- + * Lane0 (tx_p/m_ln_0) TX1+/TX1- (pins A2/A3) + * Lane1 (tx_rx_p/m_ln_1) RX1+/RX1- (pins B11/B10) + * Lane2 (tx_rx_p/m_ln_2) RX2+/RX2- (pins A11/A10) + * Lane3 (tx_p/m_ln_3) TX2+/TX2- (pins B2/B3) + * ------------------------------------------------------------------- + * + * USB and DP lanes mapping to TypeC PHY lanes for each of pin assignment + * options (normal connector orientation) described in the VESA DisplayPort + * Alt Mode on USB TypeC Standard as follows: + * + * ---------------------------------------------------------------------- + * PHY Lanes A B C D E F + * ---------------------------------------------------------------------- + * 0 ML1 SSTX ML2 SSTX ML2 SSTX + * 1 ML3 SSRX ML3 SSRX ML3 SSRX + * 2 ML2 ML1 ML0 ML0 ML0 ML0 + * 3 ML0 ML0 ML1 ML1 ML1 ML1 + * ---------------------------------------------------------------------- + */ +static void tcphy_set_lane_mapping(struct rockchip_typec_phy *tcphy, u8 mo= de) +{ + /* + * The PMA_LANE_CFG register is used to select whether a PMA lane + * is mapped for USB or PHY DP. The PMA_LANE_CFG register is + * configured based on a normal connector orientation. Logic in the + * PHY automatically handles the flipped connector case based on the + * setting of orientation of TypeC PHY. + */ + if (mode =3D=3D MODE_DFP_DP) { + /* This maps to VESA DP Alt Mode pin assignments C and E. */ + writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) | + PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) | + PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE1_DP_LANE_SEL(PHY_DP_LANE_3) | + PMA_LANE1_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE0_DP_LANE_SEL(PHY_DP_LANE_2) | + PMA_LANE0_INTERFACE_SEL(PMA_IF_PHY_DP), + tcphy->base + PMA_LANE_CFG); + } else { + /* This maps to VESA DP Alt Mode pin assignments D and F. */ + writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) | + PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) | + PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE1_INTERFACE_SEL(PMA_IF_PIPE_PCS) | + PMA_LANE0_INTERFACE_SEL(PMA_IF_PIPE_PCS), + tcphy->base + PMA_LANE_CFG); + } +} + static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy) { u32 i, rdata; @@ -743,8 +885,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *t= cphy, u8 mode) tcphy_dp_aux_set_flip(tcphy); =20 tcphy_cfg_24m(tcphy); + tcphy_set_lane_mapping(tcphy, mode); =20 if (mode =3D=3D MODE_DFP_DP) { + tcphy_cfg_usb3_to_usb2_only(tcphy, true); tcphy_cfg_dp_pll(tcphy); for (i =3D 0; i < 4; i++) tcphy_dp_cfg_lane(tcphy, i); @@ -768,7 +912,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *t= cphy, u8 mode) writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG); } =20 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); + val =3D readl(tcphy->base + DP_MODE_CTL); + val &=3D ~DP_MODE_MASK; + val |=3D DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED; + writel(val, tcphy->base + DP_MODE_CTL); =20 reset_control_deassert(tcphy->uphy_rst); =20 @@ -811,8 +958,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tc= phy) u8 mode; int ret, ufp, dp; =20 + /* If extcon not exist, try to use tcpm mode */ if (!edev) - return MODE_DFP_USB; + return tcphy->new_mode; =20 ufp =3D extcon_get_state(edev, EXTCON_USB); dp =3D extcon_get_state(edev, EXTCON_DISP_DP); @@ -850,6 +998,71 @@ static int tcphy_get_mode(struct rockchip_typec_phy *t= cphy) return mode; } =20 +#if IS_ENABLED(CONFIG_TYPEC) +static int tcphy_orien_sw_set(struct typec_switch_dev *sw, + enum typec_orientation orien) +{ + struct rockchip_typec_phy *tcphy =3D typec_switch_get_drvdata(sw); + + mutex_lock(&tcphy->lock); + + if (orien =3D=3D TYPEC_ORIENTATION_NONE) { + tcphy->new_mode =3D MODE_DISCONNECT; + goto unlock_ret; + } + + tcphy->flip =3D (orien =3D=3D TYPEC_ORIENTATION_REVERSE) ? true : false; + +unlock_ret: + mutex_unlock(&tcphy->lock); + return 0; +} + +static void udphy_orien_switch_unregister(void *data) +{ + struct rockchip_typec_phy *tcphy =3D data; + + typec_switch_unregister(tcphy->sw); +} + +static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy) +{ + struct typec_switch_desc sw_desc =3D { }; + struct device_node *np; + int ret =3D 0; + + np =3D of_get_child_by_name(tcphy->dev->of_node, "usb3-port"); + if (!np) + return 0; + + if (!of_property_read_bool(np, "orientation-switch")) + goto put_np; + + sw_desc.drvdata =3D tcphy; + sw_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "usb3-port"); + sw_desc.set =3D tcphy_orien_sw_set; + + tcphy->sw =3D typec_switch_register(tcphy->dev, &sw_desc); + if (IS_ERR(tcphy->sw)) { + dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n", + PTR_ERR(tcphy->sw)); + ret =3D PTR_ERR(tcphy->sw); + goto put_np; + } + + ret =3D devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregiste= r, tcphy); + +put_np: + of_node_put(np); + return ret; +} +#else +static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy) +{ + return 0; +} +#endif + static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy, bool value) { @@ -989,14 +1202,9 @@ static int rockchip_dp_phy_power_on(struct phy *phy) =20 tcphy_dp_aux_calibration(tcphy); =20 - writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL); - - ret =3D readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, - val, val & DP_MODE_A0, 1000, - PHY_MODE_SET_TIMEOUT); - if (ret < 0) { - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); - dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n"); + ret =3D tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A0); + if (ret) { + dev_err(tcphy->dev, "failed to enter A0 power state\n"); goto power_on_finish; } =20 @@ -1013,6 +1221,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy) static int rockchip_dp_phy_power_off(struct phy *phy) { struct rockchip_typec_phy *tcphy =3D phy_get_drvdata(phy); + int ret; =20 mutex_lock(&tcphy->lock); =20 @@ -1021,7 +1230,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy) =20 tcphy->mode &=3D ~MODE_DFP_DP; =20 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); + ret =3D tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A2); + if (ret) { + dev_err(tcphy->dev, "failed to enter A2 power state\n"); + goto unlock; + } =20 if (tcphy->mode =3D=3D MODE_DISCONNECT) tcphy_phy_deinit(tcphy); @@ -1037,6 +1250,93 @@ static const struct phy_ops rockchip_dp_phy_ops =3D { .owner =3D THIS_MODULE, }; =20 +#if IS_ENABLED(CONFIG_TYPEC) +static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux= _state *state) +{ + struct rockchip_typec_phy *tcphy =3D typec_mux_get_drvdata(mux); + struct typec_displayport_data *data; + int hpd =3D 0; + + mutex_lock(&tcphy->lock); + + switch (state->mode) { + case TYPEC_STATE_SAFE: + fallthrough; + case TYPEC_STATE_USB: + tcphy->new_mode =3D MODE_DFP_USB; + phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0); + break; + case TYPEC_DP_STATE_C: + case TYPEC_DP_STATE_E: + if (state->alt->svid !=3D USB_TYPEC_DP_SID) + break; + tcphy->new_mode =3D MODE_DFP_DP; + data =3D state->data; + hpd =3D !!(data->status & DP_STATUS_HPD_STATE); + phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0); + break; + case TYPEC_DP_STATE_D: + if (state->alt->svid !=3D USB_TYPEC_DP_SID) + break; + tcphy->new_mode =3D MODE_DFP_DP | MODE_DFP_USB; + data =3D state->data; + hpd =3D !!(data->status & DP_STATUS_HPD_STATE); + phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0); + break; + default: + break; + } + + mutex_unlock(&tcphy->lock); + + return 0; +} + +static void tcphy_typec_mux_unregister(void *data) +{ + struct rockchip_typec_phy *tcphy =3D data; + + typec_mux_unregister(tcphy->mux); +} + +static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) +{ + struct typec_mux_desc mux_desc =3D {}; + struct device_node *np; + int ret =3D 0; + + np =3D of_get_child_by_name(tcphy->dev->of_node, "dp-port"); + if (!np) + return 0; + + if (!of_property_read_bool(np, "mode-switch")) + goto put_np; + + mux_desc.drvdata =3D tcphy; + mux_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "dp-port"); + mux_desc.set =3D tcphy_typec_mux_set; + + tcphy->mux =3D typec_mux_register(tcphy->dev, &mux_desc); + if (IS_ERR(tcphy->mux)) { + dev_err(tcphy->dev, "Error register typec mux: %ld\n", + PTR_ERR(tcphy->mux)); + ret =3D PTR_ERR(tcphy->mux); + goto put_np; + } + + ret =3D devm_add_action_or_reset(tcphy->dev, tcphy_typec_mux_unregister, = tcphy); + +put_np: + of_node_put(np); + return ret; +} +#else +static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) +{ + return 0; +} +#endif + static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy, struct device *dev) { @@ -1095,6 +1395,25 @@ static void typec_phy_pre_init(struct rockchip_typec= _phy *tcphy) tcphy->mode =3D MODE_DISCONNECT; } =20 +static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy) +{ + int dp_lanes; + + switch (tcphy->new_mode) { + case MODE_DFP_DP: + dp_lanes =3D 4; + break; + case MODE_DFP_DP | MODE_DFP_USB: + dp_lanes =3D 2; + break; + default: + dp_lanes =3D 0; + break; + } + + return dp_lanes; +} + static int rockchip_typec_phy_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; @@ -1142,6 +1461,7 @@ static int rockchip_typec_phy_probe(struct platform_d= evice *pdev) return ret; =20 tcphy->dev =3D dev; + tcphy->new_mode =3D MODE_DFP_USB; platform_set_drvdata(pdev, tcphy); mutex_init(&tcphy->lock); =20 @@ -1151,6 +1471,7 @@ static int rockchip_typec_phy_probe(struct platform_d= evice *pdev) if (IS_ERR(tcphy->extcon)) { if (PTR_ERR(tcphy->extcon) =3D=3D -ENODEV) { tcphy->extcon =3D NULL; + dev_info(dev, "extcon not exist, try to use typec mux\n"); } else { if (PTR_ERR(tcphy->extcon) !=3D -EPROBE_DEFER) dev_err(dev, "Invalid or missing extcon\n"); @@ -1158,19 +1479,34 @@ static int rockchip_typec_phy_probe(struct platform= _device *pdev) } } =20 + ret =3D tcphy_setup_orien_switch(tcphy); + if (ret) + return ret; + + ret =3D tcphy_setup_typec_mux(tcphy); + if (ret) + return ret; + pm_runtime_enable(dev); =20 for_each_available_child_of_node(np, child_np) { struct phy *phy; =20 - if (of_node_name_eq(child_np, "dp-port")) + if (of_node_name_eq(child_np, "dp-port")) { phy =3D devm_phy_create(dev, child_np, &rockchip_dp_phy_ops); - else if (of_node_name_eq(child_np, "usb3-port")) + if (!IS_ERR(phy)) { + tcphy->phys[TYPEC_PHY_DP] =3D phy; + phy_set_bus_width(phy, typec_dp_lane_get(tcphy)); + } + } else if (of_node_name_eq(child_np, "usb3-port")) { phy =3D devm_phy_create(dev, child_np, &rockchip_usb3_phy_ops); - else + if (!IS_ERR(phy)) + tcphy->phys[TYPEC_PHY_USB] =3D phy; + } else { continue; + } =20 if (IS_ERR(phy)) { dev_err(dev, "failed to create phy: %pOFn\n", --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 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 163AB30E856 for ; Wed, 29 Oct 2025 07:16:15 +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=1761722178; cv=none; b=iX2jVmVWr66QdEjpHq6plw8QxaPt0rTWbNeRxd9CmxEmCzeCpokkWw+buy0nbZ8g/K4Nk0O58rNFxTEaTtNFQ8IRARVeW82vyAwCYbn7O2EmopNnOHsiecJ/y+SM+3svfcql70CVsrFIjece3/MV67Rsvfs2jB0P8NEbl2M+LQ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722178; c=relaxed/simple; bh=HysgThJSB58INGyifNQGXbmX0lFauL5Bf5bQD741kwA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=cmMxMmNderSpzVMfDiVz9+z2pHKS6mFXN00UA4ZJS0IAO8c4vg8UFkZVzOBFpD1Y+RZFmMit8AE6faaEdvzrn5OSZoN0a8sMD1NioLZ0BHomthTmwUCLUCz2mWMHhrRXBn3an0Bmv/D5muHV4e1MkXRRib2DrBA4ugFEN5F0Zis= 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=ZA36WjG8; 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="ZA36WjG8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722116; bh=AFQcoHE/dlPx/r75ImuKZ7C8fGQ0d+TgBuYEF1fP98Q=; h=From:To:Subject:Date:Message-Id; b=ZA36WjG8lUhyCNfN8X+g6+oiDFK43UsQ+3/VGANeCeklTPe+WntJapcggALLRBnum IgNak6kvYBnXr0xZeJx3q1ZYI3Aj+95IIEFDRH+nhwO+df1mKF8WtE0tV8fCN1PWb+ hJzB0GTHs8yd6i3UFkUnh4QYGMRYpeNrr4Av9KXs= X-QQ-mid: zesmtpsz6t1761722113t4c4a24c5 X-QQ-Originating-IP: WMfK1js/UW7s6StnIpjDkyDreu4Jf2mWtPcMyatS3g4= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:15:09 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 14311052351362136618 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 06/10] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Date: Wed, 29 Oct 2025 15:14:31 +0800 Message-Id: <20251029071435.88-7-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NnBlO8MsmACrRff/5IWYDaIcxcnVMxjOCZjMKnz7TA01DAkSJzQId/Gm lGe0VHLlyDOkxjAK6l1URU32pwzsHr3NB1Dh8AIFMd9nGrY2ktN/+j7jFCmYdruOGMOVw8x BLUmY3dJ0lFuKLCyRSrCbpfVkhzxASwsy5kL5Ob0l8KQDVrM1LWm32VzNzB39Fxi0JxxNul /XlP+9TRgWB0JMlnF0AXYHRdHvuU7X484Ua1TjMlzwg7xNkTaAX4sXZQph3Enh1K1o6gXfV R1bdh8GF7m4oFZ/pvKE9yLhJlHveepAgYsYt0Jl6WbG8LVitO/L2RdXyL91PPMPMp4IU5cZ QZscCQ0mEQINC2s3Xdi3kdnj4z1+Bp4s+BxLT2jE+rd33R/IjdSHCy2p/X2KU1Z1KhWDErM rCKlk8WEfi/vtyORRwT3jmQvsnkPvbxiO+J0TRDAK7t6EbKkPa6LjkwN+Y9IV+eFqbxNfl3 2BaTzahrrWE5rkdYS3ri8jnjMhkTowDNIU+3l7+7EKZY/8Lem5IK5eaoGESpjkutZY86nrE wt+yLCLMF9/C8kPAJ/0u7vQJk70vl3bmiyZVkIiKrUBjQ0kqyiRyRKXUaWvFY/tfRj40Tbv 1vF3Qi05rORYB6QQQ0oem6bUqRfPtml0iW1COO37eOlyMW6m6ev73+f6Zv5Ro+73+WKy/o/ CnndJlvu9jCC9HP2RlKjik4pw4yMOYOD2j7VHUsdQbNj5lEEFM3nVLQ/zKttuseYAJ77Ibv isysfa4ZvcUmNnlQRx+5NDYmgd8QtCEWPooOdyYcaP3PMEBqPQsW9zv3vi4ygRRaTTU1yMv U6jXxmC8CmuQeKIFv4OExzv71+g5C9H2ZYHOqqM0E6/PVNvL1dBhUS6M5uP2a2fo0xkB88l fU5tU/BSdojyDj7SqZZNbBGCcSriuSSIyd3Ru3s3H2Xq5OIYwS8OPVH8zvRzj0xNMO2b/ql oDhuzDOQSndjhTNzTl70Z6opBGTzrORRNJ1O/PhrUm+tav1M8DYaAASvQ2lb5p6332Nir+y ba6bF8UagMkIAKQaFGDmL0ktTQ4lYGUrzBmBDRNA== 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 Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge device. Signed-off-by: Chaoyi Chen --- (no changes since v7) Changes in v6: - Fix depend in Kconfig.=20 drivers/phy/rockchip/Kconfig | 2 + drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index db4adc7c53da..bcb5476222fc 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC tristate "Rockchip TYPEC PHY Driver" depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) depends on TYPEC || TYPEC=3Dn + depends on DRM || DRM=3Dn + select DRM_AUX_BRIDGE if DRM_BRIDGE select EXTCON select GENERIC_PHY select RESET_CONTROLLER diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockch= ip/phy-rockchip-typec.c index 1f5b4142cbe4..748a6eb8ad95 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -36,6 +36,7 @@ * orientation, false is normal orientation. */ =20 +#include #include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -415,6 +417,7 @@ struct rockchip_usb3phy_port_cfg { =20 struct rockchip_typec_phy { struct device *dev; + struct auxiliary_device dp_port_dev; void __iomem *base; struct extcon_dev *extcon; struct typec_mux_dev *mux; @@ -1299,6 +1302,51 @@ static void tcphy_typec_mux_unregister(void *data) typec_mux_unregister(tcphy->mux); } =20 +static void tcphy_dp_port_dev_release(struct device *dev) +{ + struct auxiliary_device *adev =3D to_auxiliary_dev(dev); + + of_node_put(adev->dev.of_node); +} + +static void tcphy_dp_port_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev =3D _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static int tcphy_aux_bridge_register(struct rockchip_typec_phy *tcphy, str= uct device_node *np) +{ + struct auxiliary_device *adev =3D &tcphy->dp_port_dev; + int ret; + + adev->name =3D "dp_port"; + adev->dev.parent =3D tcphy->dev; + adev->dev.of_node =3D of_node_get(np); + adev->dev.release =3D tcphy_dp_port_dev_release; + + ret =3D auxiliary_device_init(adev); + + if (ret) { + of_node_put(adev->dev.of_node); + return ret; + } + + ret =3D auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + devm_add_action_or_reset(tcphy->dev, tcphy_dp_port_unregister_adev, adev); + + ret =3D drm_aux_bridge_register(&adev->dev); + + return 0; +} + static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) { struct typec_mux_desc mux_desc =3D {}; @@ -1312,6 +1360,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typ= ec_phy *tcphy) if (!of_property_read_bool(np, "mode-switch")) goto put_np; =20 + ret =3D tcphy_aux_bridge_register(tcphy, np); + if (ret) + goto put_np; + mux_desc.drvdata =3D tcphy; mux_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "dp-port"); mux_desc.set =3D tcphy_typec_mux_set; --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 Received: from smtpbgsg2.qq.com (smtpbgsg2.qq.com [54.254.200.128]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0985E314A8F for ; Wed, 29 Oct 2025 07:16:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.128 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722193; cv=none; b=LQLqHoiDEx7C28HCYXFs8n58BgWAemIzyaOIcd5mkeIpd5LTyzaJsh2LVJ1ffSN6A7rUFtHf2FAO3lAoELO0deBwIwx1G8nsOvkTFzC1qM1Lgh2oE2Agf6E311BsBIN9jsVkwD4vuNIjGE9lRgbn5dkFQHnxqB9OYENSEabYj9g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722193; c=relaxed/simple; bh=M4nUEX7h4FeSk6XVEQszUpUpBE3mjUtZPXnyDXgdiFI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=B+r7wyxhngotZCSZmMAnxGPnKtNOcNXHLIn4rq1l/xHLH+mXEY0K3RGe/+lLIUBpk6ZCFeIfXllTO1NsDC5059jHsLCBrrme30U3GRu0mDiz+6Ts8+k0i8Wlk/rFXstgviKH0VTTJBoz5Acz67oV1BElMbpTD7pPklCtXhj0368= 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=HN//Psng; arc=none smtp.client-ip=54.254.200.128 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="HN//Psng" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722122; bh=nQG0w7dhU7Aew5bKV30plkPn0nBnVdgTnfwSbxYLntU=; h=From:To:Subject:Date:Message-Id; b=HN//Psng4UWIAXQuItcyhOMHu7Dq+gDdQCi4pOBr2/h0pxW0oUD3mqLm5oJxAQb2/ 3Dr9I8rgxmXpVyH9f7SrNuUD4YKBWTja56UYiYU0YEELUU/+yMNXPvV/hdmRiDTIo9 6agCnidfxv0z5BNWLqVBBX9QzUwWVKopfAySwPcY= X-QQ-mid: zesmtpsz6t1761722120tb092f96d X-QQ-Originating-IP: IvyddLy9KbD2cvJM24xB9IzAVzZki3T5MpHuel05bj4= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:15:14 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 2981954368563909056 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 07/10] drm/rockchip: cdn-dp: Support handle lane info without extcon Date: Wed, 29 Oct 2025 15:14:32 +0800 Message-Id: <20251029071435.88-8-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: OW8nL0XA5GqlUhPJoOErPUPlgT5YGY1oJwz4RFWOF1nWFluuzq+FKJOv 2m5x3pEHURyNACWM0xwmzEsvq1mgA3PG7OK1CtVSl5ocgS7Ma8ji0KqksXb1rx8b2DhMdLf PNNGnfw63KjILlIF/Ef2A1YP2gjgjwPAi6oyYGMXKygALVIvyHqcgVqszyliI/8IPilgwC1 w9ugLphYuNlgDcRW2nVHoxcxROg0zJU0rzfMbb4o1OD0kgweWHExvSDp0A7KeGSJOwGYE9y mnGekSxw2AUJATY7pEav3PYCeiry2Pmcy1Iikmx4iLorVs2vbul6KeU9puBXcn1gQpd68xa fg/XL3pEvPz1CaeUOMGBs/fGD/r97Dt7rQ0QA/DdM0wD3q4Wa81X7/Y1imBwH0BIg+jxJ9h GkxaS95+55Dkw1gc7fyOJPaE3JK/4FNV5DYoEWhlV4WeCtHzXgT4+9eo7wDBIwFuWocnF84 vjht4oKAp6NSdOpXM8DWBCsCBlND1+nlUuwcoo+gPvpOYXolcc88PuzpK5rcIeVPtCp5e+H 1+4GfkZ7kIcdGg8G1umhrrw5BeW08N2sXDqgY0CPIJFLgjyezxiFKISvQTU6ly+O/666+ye WGZ2CDmFh54zE42xnVEe29+cVI0llNgYqrlMV+NiVjkYc/tWzd4sBpHUjrAEK1k8v825Tya XOx7zzBYMRL0UYtcr987w4DchMqdWk/BdDRwXh64gmAB3701gTYT7oLnCX/RS2lRK9Vi+SC +mmzDBXPbxBW0vdvaWqoJAPhobZw5FASZF2D5U6CeJR3h/h3dlhXWXvLXIccXm7NI0A9znj 5kHa6074x8MbR8lhFMsVL/8EVFUSi7Tl50DJ/P+P0nuJV+EBVmjPrqzJ1Tgd5J6Y4BhCEq8 TH1heHdJ9+mDiX0H7n11DSwLeBxE7P3CxsQVeZzgDZDb/D9Z7Yj6wv2XGhivAEsfeibxnhE BD2vFtSQIkc4+QtID4XnDKHSjVvBSwQjRXwkIXwTrLpl467yOms1+kxYLHTVfiRluezK6is DoZJl5I+FqB51Dn9rD6nQSXK9GXit6YgMkfMVWYw== X-QQ-XMRINFO: OWPUhxQsoeAVDbp3OJHYyFg= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen This patch add support for get PHY lane info without help of extcon. There is no extcon needed if the Type-C controller is present. In this case, the lane info can be get from PHY instead of extcon. The extcon device should still be supported if Type-C controller is not present. Signed-off-by: Chaoyi Chen --- (no changes since v5) Changes in v4: - Remove cdn_dp_hpd_notify(). (no changes since v3) Changes in v2: - Ignore duplicate HPD events. drivers/gpu/drm/rockchip/cdn-dp-core.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index b7e3f5dcf8d5..1e27301584a4 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *po= rt) int dptx; u8 lanes; =20 + if (!edev) + return phy_get_bus_width(port->phy); + dptx =3D extcon_get_state(edev, EXTCON_DISP_DP); if (dptx > 0) { extcon_get_property(edev, EXTCON_DISP_DP, @@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_= device *dp) * some docks need more time to power up. */ while (time_before(jiffies, timeout)) { - if (!extcon_get_state(port->extcon, EXTCON_DISP_DP)) + if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP)) return false; =20 if (!cdn_dp_get_sink_count(dp, &sink_count)) @@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp= , struct cdn_dp_port *port) goto err_power_on; } =20 - ret =3D extcon_get_property(port->extcon, EXTCON_DISP_DP, - EXTCON_PROP_USB_TYPEC_POLARITY, &property); - if (ret) { - DRM_DEV_ERROR(dp->dev, "get property failed\n"); - goto err_power_on; + property.intval =3D 0; + if (port->extcon) { + ret =3D extcon_get_property(port->extcon, EXTCON_DISP_DP, + EXTCON_PROP_USB_TYPEC_POLARITY, &property); + if (ret) { + DRM_DEV_ERROR(dp->dev, "get property failed\n"); + goto err_power_on; + } } =20 port->lanes =3D cdn_dp_get_port_lanes(port); @@ -1028,6 +1034,9 @@ static int cdn_dp_bind(struct device *dev, struct dev= ice *master, void *data) for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; =20 + if (!port->extcon) + continue; + port->event_nb.notifier_call =3D cdn_dp_pd_event; ret =3D devm_extcon_register_notifier(dp->dev, port->extcon, EXTCON_DISP_DP, @@ -1120,14 +1129,14 @@ static int cdn_dp_probe(struct platform_device *pde= v) PTR_ERR(phy) =3D=3D -EPROBE_DEFER) return -EPROBE_DEFER; =20 - if (IS_ERR(extcon) || IS_ERR(phy)) + if (IS_ERR(phy) || PTR_ERR(extcon) !=3D -ENODEV) continue; =20 port =3D devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); if (!port) return -ENOMEM; =20 - port->extcon =3D extcon; + port->extcon =3D IS_ERR(extcon) ? NULL : extcon; port->phy =3D phy; port->dp =3D dp; port->id =3D i; --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 Received: from smtpbg154.qq.com (smtpbg154.qq.com [15.184.224.54]) (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 6442F30E82B for ; Wed, 29 Oct 2025 07:16:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=15.184.224.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722215; cv=none; b=QsbSs2Y5ryOr2RA02SZ4ZM/hz1REYaY3b+PZSrCap/BBnIX/ZZSxzvj4tb7NjRjUVQUf/1Wz99w5Tb328xz/9uHedvSQIFOk6sphiVGN21H7prGoCy3GUj9AqZNpEtnfOhFCsMXUxl78ZWFzqG0KX/dte5gGjFTHAiS3Fyh1HcA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722215; c=relaxed/simple; bh=OXgqGd240jl1dl8s89weeb6lNI01aFEZdjrmoZw3yQc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=sAmGhO42RoW9/blyScITp0jdRLo/UEP0vzJ34RFljV6zhDnElMyHOzMZZqE0ODdynrf16TokUyUeTb83pz9MqZFMuuV+JQpU91JcX2FkhcfLehIRm3qCZWhzy0UAkiHoNAFj0hBBOQesrjaTqxWtKM1OSZ2fv1K0VA/HZ1Re5II= 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=DIIdeN9T; arc=none smtp.client-ip=15.184.224.54 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="DIIdeN9T" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722128; bh=x/h3kc5q4YrTjG/Gxzoz2V8jDCSypc2d8gFKkYTUbXE=; h=From:To:Subject:Date:Message-Id; b=DIIdeN9TZ2xiAdZd5kvgmzL6vbGwbhmdK9vHFhYmIb0aWp70PoiaSJmfbh+qw3p5c RglOncrhMXoaVB8nFnpsIlKo7EKyHIg0PpnsD2MhDE2F/uE1JtDAtRx8ek+x8zCE9i wB/SuVDZtuMd/zbvQlPGyeXOptuEkXyvdG1XO8Z0= X-QQ-mid: zesmtpsz6t1761722126t69bcd525 X-QQ-Originating-IP: h6guRnzLmFjRSviakqq+JAB3+E+OUSmahoB1TMJgMcI= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:15:21 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 110532954524999058 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 08/10] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Date: Wed, 29 Oct 2025 15:14:33 +0800 Message-Id: <20251029071435.88-9-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: MMjDQqT0mb2nyw4BqdlH3Kp9XTUqKv4Ox2d8d8tajiqTkW7TjqRiNBwj ZTNJPfFFkPJyOQC8WOr3vMsOOHz9X0FU263DgPJtQ4RqBBVL8eazRibAf8yTV05r7N8dM0V 5Jg5QRaRcZ1wE+0he3piKkEHfOs6v0RM29nsj5XuZTAOcxEuIY2UR33TnrW4XnZ2rwipnOB ZRrjUQuEQWHid9jZUnxnTHdrn1Ph6UQzukwkFqJux6mdcSiXAM6IEJzYhvN3LBLV6y68tcw oLaA/d0eQpvrxYSAnT6Q6BWwREHqnVpU5y4M6kB8PyjV6jhcn6uitcs/qQjW2UuXuSVvW2N P9/XSvknLjiV4tKBLhMJEsshcnZT82Vg4sb1p4BuU5J/ldbFk9ynhcLvzZ44RrnaMyiLRAZ Gb+cS7I/JE8kFRWITlXellP0n2HLUVKwtW+KB8gfco2bWaOyvNqcU0Y9OuztSVk089d+5/2 g1uoHb1Dm+hQOd2zO4TbQazV9wCub/b0yWSTThuNRuvx0AvsusCTG7OuEt+m7Tvh/6O42GF DOhnAOLtZtYBFLrHhGX+bWoRTE3RNr+cJ1GUJdrVoZHsr2GG1Ru/PkpLkqEtrxu6dRb1zHZ 91XoXr1rzS9qXGWaBY7hneC7qR+j7pyFBjJf+DNrw4OEvIhK3pTNhAmNswi/jv6q/83C0VA v97EBxJu+BHf2CpYzLqHu1ldQZ4GU5Ah9m/btDaWYQLscy2R7boiQit+pHCK6dbEhoT/IS2 05FWPwBcrgkDcgoIvhp0YCai0BhYbZPG39S6VQjuACctzIeEQY/hR2cB34eBn7IWD55LaIF OKmtLm4d6aQjswOMv0Y008A9CHnBeqkIV8bM6sTJIeZbgDteAKbbWiPuPGaAsx6Z97p1E0d HE0n5eEb0NNVakLylfk0AKUX4W6cxP0FbHcHtSW2Lh3cZa85+rejzHsztjIugDaGf1EROzl LAVYlMjeJq1lLVm9cOWq0g67zZTfcexrmjd6FKnXF8q87cLzwgyd5WctsJQH4+RvCeDUD6G OYceIVwjawSQcb7qwA6SnheMYPeHQAAue3QS3fHg== X-QQ-XMRINFO: OWPUhxQsoeAVDbp3OJHYyFg= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And the CDN-DP can be switched to output to one of the PHYs. If both ports are plugged into DP, DP will select the first port for output. This patch adds support for multiple bridges, enabling users to flexibly select the output port. For each PHY port, a separate encoder and bridge are registered. The change is based on the DRM AUX HPD bridge, rather than the extcon approach. This requires the DT to correctly describe the connections between the first bridge in bridge chain and DP controller. For example, the bridge chain may be like this: PHY aux birdge -> fsa4480 analog audio switch bridge -> onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge In this case, the connection relationships among the PHY aux bridge and the DP contorller need to be described in DT. In addition, the cdn_dp_parse_next_bridge_dt() will parses it and determines whether to register one or two bridges. Since there is only one DP controller, only one of the PHY ports can output at a time. The key is how to switch between different PHYs, which is handled by cdn_dp_switch_port() and cdn_dp_enable(). There are two cases: 1. Neither bridge is enabled. In this case, both bridges can independently read the EDID, and the PHY port may switch before reading the EDID. 2. One bridge is already enabled. In this case, other bridges are not allowed to read the EDID. So we will try to return the cached EDID. Since the scenario of two ports plug in at the same time is rare, I don't have a board which support two TypeC connector to test this. Therefore, I tested forced switching on a single PHY port, as well as output using a fake PHY port alongside a real PHY port. Signed-off-by: Chaoyi Chen --- (no changes since v7) Changes in v6: - Rename some variable names. - Attach the DP bridge to the next bridge. Changes in v5: - By parsing the HPD bridge chain, set the connector's of_node to the of_node corresponding to the USB-C connector. - Return EDID cache when other port is already enabled. drivers/gpu/drm/rockchip/cdn-dp-core.c | 329 ++++++++++++++++++++----- drivers/gpu/drm/rockchip/cdn-dp-core.h | 24 +- 2 files changed, 296 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index 1e27301584a4..5c0e5209d3b8 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -27,16 +27,17 @@ #include "cdn-dp-core.h" #include "cdn-dp-reg.h" =20 -static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge) +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port= *prev_port, + struct cdn_dp_port *port); + +static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge = *bridge) { - return container_of(bridge, struct cdn_dp_device, bridge); + return container_of(bridge, struct cdn_dp_bridge, bridge); } =20 -static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *enco= der) +static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge) { - struct rockchip_encoder *rkencoder =3D to_rockchip_encoder(encoder); - - return container_of(rkencoder, struct cdn_dp_device, encoder); + return bridge_to_dp_bridge(bridge)->parent; } =20 #define GRF_SOC_CON9 0x6224 @@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device= *dp, u8 *sink_count) static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp) { struct cdn_dp_port *port; - int i, lanes; + int i, lanes[MAX_PHY]; =20 for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; - lanes =3D cdn_dp_get_port_lanes(port); - if (lanes) + lanes[i] =3D cdn_dp_get_port_lanes(port); + if (!dp->next_bridge_valid) return port; } + + if (dp->next_bridge_valid) { + /* If more than one port is available, pick the last active port */ + if (dp->active_port > 0 && lanes[dp->active_port]) + return dp->port[dp->active_port]; + + /* If the last active port is not available, pick an available port in o= rder */ + for (i =3D 0; i < dp->bridge_count; i++) { + if (lanes[i]) + return dp->port[i]; + } + } + return NULL; } =20 @@ -253,12 +267,45 @@ static const struct drm_edid * cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *c= onnector) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); - const struct drm_edid *drm_edid; + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); + struct cdn_dp_port *port =3D dp->port[dp_bridge->id]; + struct cdn_dp_port *prev_port; + const struct drm_edid *drm_edid =3D NULL; + int i, ret; =20 mutex_lock(&dp->lock); + + /* More than one port is available */ + if (dp->bridge_count > 1 && !port->phy_enabled) { + for (i =3D 0; i < dp->bridge_count; i++) { + /* Another port already enable */ + if (dp->bridge_list[i] !=3D dp_bridge && dp->bridge_list[i]->enabled) + goto get_cache; + /* Find already enabled port */ + if (dp->port[i]->phy_enabled) + prev_port =3D dp->port[i]; + } + + /* Switch to current port */ + if (prev_port) { + ret =3D cdn_dp_switch_port(dp, prev_port, port); + if (ret) + goto get_cache; + } + } + drm_edid =3D drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp); + /* replace edid cache */ + if (dp->edid_cache[dp_bridge->id]) + drm_edid_free(dp->edid_cache[dp_bridge->id]); + dp->edid_cache[dp_bridge->id] =3D drm_edid_dup(drm_edid); + mutex_unlock(&dp->lock); + return drm_edid; =20 +get_cache: + drm_edid =3D drm_edid_dup(dp->edid_cache[dp_bridge->id]); + mutex_unlock(&dp->lock); return drm_edid; } =20 @@ -267,12 +314,13 @@ cdn_dp_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *display_info, const struct drm_display_mode *mode) { + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); struct cdn_dp_device *dp =3D bridge_to_dp(bridge); u32 requested, actual, rate, sink_max, source_max =3D 0; u8 lanes, bpc; =20 /* If DP is disconnected, every mode is invalid */ - if (!dp->connected) + if (!dp_bridge->connected || !dp->connected) return MODE_BAD; =20 switch (display_info->bpc) { @@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_dev= ice *dp) return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes)); } =20 +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port= *prev_port, + struct cdn_dp_port *port) +{ + int ret; + + if (dp->active) + return 0; + + ret =3D cdn_dp_disable_phy(dp, prev_port); + if (ret) + goto out; + ret =3D cdn_dp_enable_phy(dp, port); + if (ret) + goto out; + + ret =3D cdn_dp_get_sink_capability(dp); + if (ret) { + cdn_dp_disable_phy(dp, port); + goto out; + } + + dp->active =3D true; + dp->lanes =3D port->lanes; + + if (!cdn_dp_check_link_status(dp)) { + dev_info(dp->dev, "Connected with sink; re-train link\n"); + + ret =3D cdn_dp_train_link(dp); + if (ret) { + dev_err(dp->dev, "Training link failed: %d\n", ret); + goto out; + } + + ret =3D cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE); + if (ret) { + dev_err(dp->dev, "Failed to idle video %d\n", ret); + goto out; + } + + ret =3D cdn_dp_config_video(dp); + if (ret) + dev_err(dp->dev, "Failed to configure video: %d\n", ret); + } + +out: + return ret; +} + static void cdn_dp_display_info_update(struct cdn_dp_device *dp, struct drm_display_info *display_info) { @@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_de= vice *dp, static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct = drm_atomic_state *state) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); struct drm_connector *connector; int ret, val; =20 @@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_brid= ge *bridge, struct drm_at =20 cdn_dp_display_info_update(dp, &connector->display_info); =20 - ret =3D drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.= encoder); + ret =3D drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->e= ncoder.encoder); if (ret < 0) { DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret); return; @@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_brid= ge *bridge, struct drm_at =20 mutex_lock(&dp->lock); =20 + if (dp->next_bridge_valid) + dp->active_port =3D dp_bridge->id; + ret =3D cdn_dp_enable(dp); if (ret) { DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n", @@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_brid= ge *bridge, struct drm_at goto out; } =20 + dp_bridge->enabled =3D true; out: mutex_unlock(&dp->lock); } @@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bri= dge *bridge, struct drm_at static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct= drm_atomic_state *state) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); int ret; =20 mutex_lock(&dp->lock); + dp_bridge->enabled =3D false; =20 if (dp->active) { ret =3D cdn_dp_disable(dp); @@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge = *bridge, return ret; } =20 +static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge, + enum drm_connector_status status) +{ + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); + struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + + dp->bridge_list[dp_bridge->id]->connected =3D status =3D=3D connector_sta= tus_connected; + schedule_work(&dp->event_work); +} + static const struct drm_bridge_funcs cdn_dp_bridge_funcs =3D { .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, @@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_func= s =3D { .atomic_disable =3D cdn_dp_bridge_atomic_disable, .mode_valid =3D cdn_dp_bridge_mode_valid, .mode_set =3D cdn_dp_bridge_mode_set, + .hpd_notify =3D cdn_dp_bridge_hpd_notify, =20 .dp_audio_prepare =3D cdn_dp_audio_prepare, .dp_audio_mute_stream =3D cdn_dp_audio_mute_stream, @@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *wo= rk) { struct cdn_dp_device *dp =3D container_of(work, struct cdn_dp_device, event_work); - int ret; + bool connected; + int i, ret; =20 mutex_lock(&dp->lock); =20 @@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *= work) =20 out: mutex_unlock(&dp->lock); - drm_bridge_hpd_notify(&dp->bridge, - dp->connected ? connector_status_connected - : connector_status_disconnected); + for (i =3D 0; i < dp->bridge_count; i++) { + connected =3D dp->connected && dp->bridge_list[i]->connected; + drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge, + connected ? connector_status_connected + : connector_status_disconnected); + } } =20 static int cdn_dp_pd_event(struct notifier_block *nb, @@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb, return NOTIFY_DONE; } =20 -static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +static int cdn_bridge_add(struct device *dev, + struct drm_bridge *bridge, + struct drm_bridge *next_bridge, + struct drm_encoder *encoder) { struct cdn_dp_device *dp =3D dev_get_drvdata(dev); - struct drm_encoder *encoder; + struct drm_device *drm_dev =3D dp->drm_dev; + struct drm_bridge *last_bridge =3D NULL; struct drm_connector *connector; - struct cdn_dp_port *port; - struct drm_device *drm_dev =3D data; - int ret, i; - - ret =3D cdn_dp_parse_dt(dp); - if (ret < 0) - return ret; - - dp->drm_dev =3D drm_dev; - dp->connected =3D false; - dp->active =3D false; - dp->active_port =3D -1; - dp->fw_loaded =3D false; - - INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); - - encoder =3D &dp->encoder.encoder; + int ret; =20 encoder->possible_crtcs =3D drm_of_find_possible_crtcs(drm_dev, dev->of_node); @@ -1002,26 +1108,38 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) =20 drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs); =20 - dp->bridge.ops =3D - DRM_BRIDGE_OP_DETECT | - DRM_BRIDGE_OP_EDID | - DRM_BRIDGE_OP_HPD | - DRM_BRIDGE_OP_DP_AUDIO; - dp->bridge.of_node =3D dp->dev->of_node; - dp->bridge.type =3D DRM_MODE_CONNECTOR_DisplayPort; - dp->bridge.hdmi_audio_dev =3D dp->dev; - dp->bridge.hdmi_audio_max_i2s_playback_channels =3D 8; - dp->bridge.hdmi_audio_spdif_playback =3D 1; - dp->bridge.hdmi_audio_dai_port =3D -1; - - ret =3D devm_drm_bridge_add(dev, &dp->bridge); + + bridge->ops =3D + DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | + DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_DP_AUDIO; + bridge->of_node =3D dp->dev->of_node; + bridge->type =3D DRM_MODE_CONNECTOR_DisplayPort; + bridge->hdmi_audio_dev =3D dp->dev; + bridge->hdmi_audio_max_i2s_playback_channels =3D 8; + bridge->hdmi_audio_spdif_playback =3D 1; + bridge->hdmi_audio_dai_port =3D -1; + + ret =3D devm_drm_bridge_add(dev, bridge); if (ret) return ret; =20 - ret =3D drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_N= O_CONNECTOR); + ret =3D drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CON= NECTOR); if (ret) return ret; =20 + if (next_bridge) { + ret =3D drm_bridge_attach(encoder, next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ret; + + last_bridge =3D next_bridge; + while (drm_bridge_get_next_bridge(last_bridge)) + last_bridge =3D drm_bridge_get_next_bridge(last_bridge); + } + connector =3D drm_bridge_connector_init(drm_dev, encoder); if (IS_ERR(connector)) { ret =3D PTR_ERR(connector); @@ -1029,8 +1147,102 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) return ret; } =20 + if (last_bridge) + connector->fwnode =3D fwnode_handle_get(of_fwnode_handle(last_bridge->of= _node)); + drm_connector_attach_encoder(connector, encoder); =20 + return 0; +} + +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp) +{ + struct device_node *np =3D dp->dev->of_node; + struct device_node *port __free(device_node) =3D of_graph_get_port_by_id(= np, 1); + struct drm_bridge *bridge; + int count =3D 0; + int ret =3D 0; + int i; + + /* If device use extcon, do not use hpd bridge */ + for (i =3D 0; i < dp->ports; i++) { + if (dp->port[i]->extcon) { + dp->bridge_count =3D 1; + return 0; + } + } + + + /* One endpoint may correspond to one next bridge. */ + for_each_of_graph_port_endpoint(port, dp_ep) { + struct device_node *next_bridge_node __free(device_node) =3D + of_graph_get_remote_port_parent(dp_ep); + + bridge =3D of_drm_find_bridge(next_bridge_node); + if (!bridge) { + ret =3D -EPROBE_DEFER; + goto out; + } + + dp->next_bridge_valid =3D true; + dp->next_bridge_list[count].bridge =3D bridge; + dp->next_bridge_list[count].parent =3D dp; + dp->next_bridge_list[count].id =3D count; + count++; + } + +out: + dp->bridge_count =3D count ? count : 1; + return ret; +} + +static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +{ + struct cdn_dp_device *dp =3D dev_get_drvdata(dev); + struct drm_bridge *bridge, *next_bridge; + struct drm_encoder *encoder; + struct cdn_dp_port *port; + struct drm_device *drm_dev =3D data; + struct cdn_dp_bridge *dp_bridge; + int ret, i; + + ret =3D cdn_dp_parse_dt(dp); + if (ret < 0) + return ret; + + ret =3D cdn_dp_parse_next_bridge_dt(dp); + if (ret) + return ret; + + dp->drm_dev =3D drm_dev; + dp->connected =3D false; + dp->active =3D false; + dp->active_port =3D -1; + dp->fw_loaded =3D false; + + for (i =3D 0; i < dp->bridge_count; i++) { + dp_bridge =3D devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge, + &cdn_dp_bridge_funcs); + if (IS_ERR(dp_bridge)) + return PTR_ERR(dp_bridge); + dp_bridge->id =3D i; + dp_bridge->parent =3D dp; + if (!dp->next_bridge_valid) + dp_bridge->connected =3D true; + dp->bridge_list[i] =3D dp_bridge; + } + + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + bridge =3D &dp->bridge_list[i]->bridge; + next_bridge =3D dp->next_bridge_list[i].bridge; + ret =3D cdn_bridge_add(dev, bridge, next_bridge, encoder); + if (ret) + return ret; + } + + INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); + for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; =20 @@ -1058,10 +1270,17 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) static void cdn_dp_unbind(struct device *dev, struct device *master, void = *data) { struct cdn_dp_device *dp =3D dev_get_drvdata(dev); - struct drm_encoder *encoder =3D &dp->encoder.encoder; + struct drm_encoder *encoder; + int i; =20 cancel_work_sync(&dp->event_work); - encoder->funcs->destroy(encoder); + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + encoder->funcs->destroy(encoder); + } + + for (i =3D 0; i < MAX_PHY; i++) + drm_edid_free(dp->edid_cache[i]); =20 pm_runtime_disable(dev); if (dp->fw_loaded) @@ -1112,10 +1331,10 @@ static int cdn_dp_probe(struct platform_device *pde= v) int ret; int i; =20 - dp =3D devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge, - &cdn_dp_bridge_funcs); - if (IS_ERR(dp)) - return PTR_ERR(dp); + dp =3D devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + dp->dev =3D dev; =20 match =3D of_match_node(cdn_dp_dt_ids, pdev->dev.of_node); diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockc= hip/cdn-dp-core.h index e9c30b9fd543..ce1707a5c746 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h @@ -38,6 +38,8 @@ enum vic_pxl_encoding_format { Y_ONLY =3D 0x10, }; =20 +struct cdn_dp_device; + struct video_info { bool h_sync_polarity; bool v_sync_polarity; @@ -63,16 +65,34 @@ struct cdn_dp_port { u8 id; }; =20 +struct cdn_dp_bridge { + struct cdn_dp_device *parent; + struct drm_bridge bridge; + struct rockchip_encoder encoder; + bool connected; + bool enabled; + int id; +}; + +struct cdn_dp_next_bridge { + struct cdn_dp_device *parent; + struct drm_bridge *bridge; + int id; +}; + struct cdn_dp_device { struct device *dev; struct drm_device *drm_dev; - struct drm_bridge bridge; - struct rockchip_encoder encoder; + int bridge_count; + struct cdn_dp_bridge *bridge_list[MAX_PHY]; + struct cdn_dp_next_bridge next_bridge_list[MAX_PHY]; + const struct drm_edid *edid_cache[MAX_PHY]; struct drm_display_mode mode; struct platform_device *audio_pdev; struct work_struct event_work; =20 struct mutex lock; + bool next_bridge_valid; bool connected; bool active; bool suspended; --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 Received: from smtpbgsg2.qq.com (smtpbgsg2.qq.com [54.254.200.128]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA0E8313283 for ; Wed, 29 Oct 2025 07:18:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.128 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722334; cv=none; b=rUFt9yaAr//5qWCobhB6QwPcwyrSnoggXXGqa3h8D7VBRH+uc7OWy4cd7U92fjLSbXj4dfQb5XyrAoZNS6u+HFT+KeQ1ta0j4qNiPun/YMBs7OkjOphGGJCfnLyus3ZO9dXaxvXJT0MdR7CeUeK3KoT0Hqmhb3j+Cl9/aGTLf1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722334; c=relaxed/simple; bh=3OiqcRrs7DLfC1hTPje6cpCre8EW3o9TnIIexoI2iuY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=UjwawkIDdKpIluOcLj8WccoPHJUmKv+VqHZkSE7sxja3Y5Hc3y4ZNAP4zkdQ5DwY+ygPhd8QaMUjvt4AFelNnOBGCNCbmLVtFODJ2aqMJnrYhhgTGTewG3xN5UrHpmKl2j+EExyDtAyD6bfjmNj4KnXZlijhMe9YIMpdO62kcTo= 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=Sy8c4HFW; arc=none smtp.client-ip=54.254.200.128 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="Sy8c4HFW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722134; bh=cDiOxEFqYuonRjIga1t9o2u02p12TN3hXALWFcjKD9c=; h=From:To:Subject:Date:Message-Id; b=Sy8c4HFWY5o434CVWL0VrQJSlxNoGws2p1QMXxoUelIpGbivpBwhf5/a5Jr8im875 kH2jpeoYpUwuE1sAOL/MyOPUobEewdcbkErQWAOYH0hZB3tXE0E87CIhIPATZ1BdC7 5GE/s47fIDAD22YVOi0FzSFonZM8v87ugQ0r0Vxs= X-QQ-mid: zesmtpsz6t1761722132t2011f568 X-QQ-Originating-IP: 7NBRw7TbdpqiA0XMn9RW6Owy6xUxWMzzgSSAg2TdaX4= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:15:27 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 1472557446544160381 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 09/10] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Date: Wed, 29 Oct 2025 15:14:34 +0800 Message-Id: <20251029071435.88-10-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: OAowhIcaKHQtd6oVjnadb7aZlVx2kEzBnMWiCBA0evMlFcXz1CuEM/5+ mBculbqO7TOTvHfDikQuz+YelxP/70MaAmd1w7j/K42WpBc+2GuRMb8MUebMgVboDYh43Pc DvfnoXyoXLbS38GStzFVdRbmTs3bHn1MheC8dID6gpYWEySAbKhFinWsozXjY2Dc/72SGod kWsPQqSEACaHlLp4j+I722Imt8i62kN30qX1V5emLsvkcasSL1Hdns/wf/g6xjatU2t3qEh AA3/vTNslFvc6WnRSUfLkHpM6TQadPxs69ZYhSyoGIb2Q1N+Gr3puSjJLaIVLbmEpErtZmL QMyyj7bU0ZMxY23RqvNdr6ZWytM+54jM6MI41Cpr3lIev9N6xgQQbLS6SQdKTDIpPhmZSXz HS27CDBxjpi7cWc5FGw3hpWyyXFRm7ocxRUYUPz23uQJeQ/yTJXLnLB+7WEypSni+2wZABK ov+mIXmBGSjSYYJtn011aU5T4P1B/bOgNuionFatXdvurjmNOJCKSmSFYsp7BpJmZ1BL4CL ML4jSTMxk8iOXTNRD7zJx9y64CxwvUdyzJ4ccl5VnWiBMOFxshBCbLkrwI7jkVlitzh7IEi BbOqbmAVQkn7LUBiquWElXnxjgETY4416cDUIFPlMV9N+3MdUStGIQMFwFUH1VgBBXrELl7 v49VNsFkAHsbAp1WlfwDelrGwPTvc3Po8x2WeVmqes64ThNXpAHKC/Ib1hODj0ZTgpxpG71 4OsAGVcRPGguoLNBZ5U7Q4E0oXKb9p30B4bZQOuiR7wBXqf+MZjqe3bcab2llDGWi9p9iaH UaRnW1GlvxKWZqynQc6jAp+pesBGbynCjjCoVsknZuHXweBXYgTwBQmauVt4wEBIhnJobcr oJHbPP05E0gn77cDmQujJn1suO+5gfQVPymtwPe8gtngTvrKwm8UUXZ60D5HxofOe02mqz3 Pgq+WR9qMY1gFAZf2i8PnQDq6vILGQeCRnaKNsvGZTWDbZVkxxRkBxGhx+1xELkmpyQIPQP KmuBGL37hVXY7erEVSe3dcOBNn5zuWYRMXu9PHXg== X-QQ-XMRINFO: NS+P29fieYNw95Bth2bWPxk= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen Let's make the ports nodes of cdn_dp in the same style as the other display interface, and match the style of ports's yaml. Signed-off-by: Chaoyi Chen --- (no changes since v5) Changes in v4: - Remove unnecessary #address/#size-cells (no changes since v1) arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boo= t/dts/rockchip/rk3399-base.dtsi index 4dcceb9136b7..93b42820998f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi @@ -618,7 +618,11 @@ cdn_dp: dp@fec00000 { status =3D "disabled"; =20 ports { - dp_in: port { + #address-cells =3D <1>; + #size-cells =3D <0>; + + dp_in: port@0 { + reg =3D <0>; #address-cells =3D <1>; #size-cells =3D <0>; =20 @@ -632,6 +636,10 @@ dp_in_vopl: endpoint@1 { remote-endpoint =3D <&vopl_out_dp>; }; }; + + dp_out: port@1 { + reg =3D <1>; + }; }; }; =20 --=20 2.49.0 From nobody Mon Dec 15 19:10:34 2025 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 A2044311957 for ; Wed, 29 Oct 2025 07:17:21 +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=1761722245; cv=none; b=tkP2OWwQnzlHdsWGnhDVBQSZ4xIgzhGshEih0awq5E4Ibl8AsdWKMtqzc9ijtk1qK+kl/cBrLn0s5ROPxCniPXCJaepDyuwPHVZpHQdENFtTZ41Q6JH8q1vGLk2ebAeul4qzelgIBk3aKK/GGWDZLkq5kGbWoTY/n/4f6DW9Wss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761722245; c=relaxed/simple; bh=Ksu1m13XDgyOSNrC/yix/S/ref0aCyYvyb9gG5K8i98=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=tFJiXnWYXbL2+PseD3QP6Wo1NNSKb5DGgQcEfSfu0yzk2mkjFgJStKb5EHZgPcYlW5kGXHLDYSUYz0MbYwA3oQYSUs4enqeqOeJFz84DrUrdZEn8W1oot6H9vaxLCdA8SgKoHCxb+mlm+ZYBjjJOfLeeEPw33BtGy6PHPQMiXSQ= 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=ZnfEzsEx; 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="ZnfEzsEx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1761722181; bh=1RfAR5qe3fDpGYWfe4IMPee9wlWopj1wjBrVtJQSHJQ=; h=From:To:Subject:Date:Message-Id; b=ZnfEzsEx2zZXXKu2HSsIfRuAbYwOfsTqdKjYLDYNL8OUWSYDu9P2Zo14u3MBvYBCn 8dSv4ISLEHrqtVHZr8mv7EotmvEOAy7OrEyjL2n4KIojL50yDklhLmcRwC6RGtIpGK bBsKwnxdLwdXvBT8lH1RAUAnKxrQ+fKEHI9kV2aQ= X-QQ-mid: zesmtpsz6t1761722139t9151357f X-QQ-Originating-IP: /bUuDFF9LoIstyTpUXcLBmZNXpV9iclT5Q9ER/D5JLM= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Oct 2025 15:15:34 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 10265484516757037659 From: Chaoyi Chen To: Heikki Krogerus , Greg Kroah-Hartman , Dmitry Baryshkov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Peter Robinson Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH v8 10/10] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Date: Wed, 29 Oct 2025 15:14:35 +0800 Message-Id: <20251029071435.88-11-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251029071435.88-1-kernel@airkyi.com> References: <20251029071435.88-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: MI8xiyr9SLuAXVPvvA1fD2UVI9ooUgKnNR27iWQk//0QAlIHO6Y7Szus RaPuxLvhpYC2wLL6+a3ddUrPxP98CIPOktd6at0zI643XPzmZ0HmBhT43eMPzo7AkT0LRax tmsXnrXYqgTHVFlI7oBOqWNaEt9TBIRgZ5SCDKzPabaVF4J8vqI7O3T8FrHzpH8kWRURTHG 8QVqv/kxtEGpRM2ma6xLmdciGFG+/YyCZpjaGedeYTCATy5OW6c4Bk1+Ah49Eyx7sR8Kluh v7/uTkms3dh+K9LKs7MV+GtlGFrLBuBg5kWQ5aJUNEQCM1B/pg/RsWx187lrTR7axsgzBqP DdF1WlKqs4diOjYPjyVfQ1FcGkIyjVtPM8iXuV5rncmyP+CN+RHAa4iYf+i6gRfAPau6Em4 +ALHEGWJZWF97Hr88mPjc3dHqWR+uR9e7r5lL02Vwbu/sbviKav8vCLeWZ6fPr2WfEXgexO C7oujV37/i1X4nyIKJWiCapONB8eIME3/Kw9Qds38Nu+An4v9DGeOGdaOSx1VWLVHc8FGgl VLea1M9YhUhK1oj0gHUZsI2RLv9hdJOJFtUJF5dGvAfBFjrwbbCclRZxBC8qFbH9/BX/FdA uJUpeQNy2WcIORiMSaYxlnNXMWxLX/hOlul8bfG0zmcATiCB7++xB1x/c7rxkIv2+BMjeHs YAdBGGXYn8HBAJXYIbz9Xes98oWsNSFGWD/vZC10gv6W38FyHM7kbnynzO1FGX2Zvv9r/Iz oIZMFz7Kd/rSHHzQgoWIGIzJz+Sa33c2hH3meucwrPMYaf9L0qAw31k8bezoyTiF8K/r0Zo Paocz6CmXZtbWvcOOO6fpqDrxRsK9S8AZvWldE+EAv4Q2ZQQ2PEK3gIiaujZKBf0eiJGvzp +YQKp6MZj8tqQyGPhsTqzG8gwxr1aD41N/7CSHq4IX1fv6lBA5IqyXtjU8yG3/Z05dwGmBm guJTVlANG1tZp9lGy8SfmhTtlZHWIaTKLkRgmQZ9AZ1Soypicr0noKoPo1Y1UPyDzuYaqrT poIxRLy8wiRCYDC6jC2buwLaP+PIsr/ShXpleqCH8jeMiIj2CI X-QQ-XMRINFO: MPJ6Tf5t3I/ycC2BItcBVIA= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The RK3399 EVB IND board has a Type-C interface DisplayPort. It use fusb302 chip as Type-C controller. fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller Signed-off-by: Chaoyi Chen --- (no changes since v4) Changes in v3: - Fix wrong vdo value. - Fix port node in usb-c-connector. Changes in v2: - Add endpoint to link DP PHY and DP controller. - Fix devicetree coding style. .../boot/dts/rockchip/rk3399-evb-ind.dts | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/b= oot/dts/rockchip/rk3399-evb-ind.dts index 70aee1ab904c..aeeee6bd2973 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts @@ -4,6 +4,7 @@ */ =20 /dts-v1/; +#include #include "rk3399.dtsi" =20 / { @@ -19,6 +20,21 @@ chosen { stdout-path =3D "serial2:1500000n8"; }; =20 + sound: sound { + compatible =3D "rockchip,rk3399-gru-sound"; + rockchip,cpu =3D <&i2s0 &spdif>; + }; + + vbus_typec: regulator-vbus-typec { + compatible =3D "regulator-fixed"; + enable-active-high; + gpio =3D <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&vcc5v0_typec0_en>; + regulator-name =3D "vbus_typec"; + vin-supply =3D <&vcc5v0_sys>; + }; + vcc5v0_sys: regulator-vcc5v0-sys { compatible =3D "regulator-fixed"; enable-active-high; @@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys { }; }; =20 +&cdn_dp { + phys =3D <&tcphy0_dp>; + status =3D "okay"; +}; + &cpu_b0 { cpu-supply =3D <&vdd_cpu_b>; }; @@ -55,6 +76,12 @@ &cpu_l3 { cpu-supply =3D <&vdd_cpu_l>; }; =20 +&dp_out { + dp_controller_output: endpoint { + remote-endpoint =3D <&dp_phy_in>; + }; +}; + &emmc_phy { status =3D "okay"; }; @@ -341,6 +368,71 @@ regulator-state-mem { }; }; =20 +&i2c4 { + i2c-scl-rising-time-ns =3D <475>; + i2c-scl-falling-time-ns =3D <26>; + status =3D "okay"; + + usbc0: typec-portc@22 { + compatible =3D "fcs,fusb302"; + reg =3D <0x22>; + interrupt-parent =3D <&gpio1>; + interrupts =3D ; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&usbc0_int>; + vbus-supply =3D <&vbus_typec>; + + usb_con: connector { + compatible =3D "usb-c-connector"; + label =3D "USB-C"; + data-role =3D "dual"; + power-role =3D "dual"; + try-power-role =3D "sink"; + op-sink-microwatt =3D <1000000>; + sink-pdos =3D + ; + source-pdos =3D + ; + + altmodes { + displayport { + svid =3D /bits/ 16 <0xff01>; + vdo =3D <0x00001c46>; + }; + }; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + + usbc_hs: endpoint { + remote-endpoint =3D <&u2phy0_typec_hs>; + }; + }; + + port@1 { + reg =3D <1>; + + usbc_ss: endpoint { + remote-endpoint =3D <&tcphy0_typec_ss>; + }; + }; + + port@2 { + reg =3D <2>; + + usbc_dp: endpoint { + remote-endpoint =3D <&tcphy0_typec_dp>; + }; + }; + }; + }; + }; +}; + &i2s2 { status =3D "okay"; }; @@ -354,6 +446,16 @@ &io_domains { }; =20 &pinctrl { + usb-typec { + usbc0_int: usbc0-int { + rockchip,pins =3D <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vcc5v0_typec0_en: vcc5v0-typec0-en { + rockchip,pins =3D <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int_l: pmic-int-l { rockchip,pins =3D <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; @@ -400,10 +502,48 @@ &sdmmc { status =3D "okay"; }; =20 +&sound { + rockchip,codec =3D <&cdn_dp>; + status =3D "okay"; +}; + +&spdif { + status =3D "okay"; +}; + &tcphy0 { status =3D "okay"; }; =20 +&tcphy0_dp { + mode-switch; + + port { + #address-cells =3D <1>; + #size-cells =3D <0>; + + tcphy0_typec_dp: endpoint@0 { + reg =3D <0>; + remote-endpoint =3D <&usbc_dp>; + }; + + dp_phy_in: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&dp_controller_output>; + }; + }; +}; + +&tcphy0_usb3 { + orientation-switch; + + port { + tcphy0_typec_ss: endpoint { + remote-endpoint =3D <&usbc_ss>; + }; + }; +}; + &tcphy1 { status =3D "okay"; }; @@ -418,6 +558,12 @@ &tsadc { =20 &u2phy0 { status =3D "okay"; + + port { + u2phy0_typec_hs: endpoint { + remote-endpoint =3D <&usbc_hs>; + }; + }; }; =20 &u2phy0_host { --=20 2.49.0