From nobody Sat Feb 7 18:16:07 2026 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 46CBC946C; Thu, 16 Oct 2025 02:28:22 +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=1760581708; cv=none; b=oD7jnGcMUHvfoRPW6cJPMK/lrhU+0DZB4SK4ojnqSXQF8VMcPhTvl3UZYZB2yTuaTVARpH5gKcljb53NFlT5j1STTunRtarGXSkp9KHnY64VY9XX2WcLZq3Rl6IDuaZKcVQf0PkVNUr7L6hXPeUaIo/xhoTq+wuvh0mXZ+XIC5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581708; c=relaxed/simple; bh=UElW6+tvG8/iKEmkoRcs7rVIPtVKGX/BFPBAupTKCEk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=m3Coe+TXTli2VAG4PBNhYOD7dLxEw2lXHnEPrZ0OIgwTRreYpGYKxLa3JCQNSz8hsILStFqk7Z3+5ArCLM3VtFvOsE9YC6qVR62N47lp9gmc3+aExZ4Ro7DT30B5wgDylomwMBVs5MQugkFnT6fet1/dHyG6GtwFPVKP5AfwsuY= 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=T73qDtJH; 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="T73qDtJH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581684; bh=AlMiAnu04or0UGQaGW/qka23taZ4VUW7EHDn8WHbWS4=; h=From:To:Subject:Date:Message-Id; b=T73qDtJHdvfokrryu399G/b1QyU4IUWOoEfIlyCt1PiFhmANDZUv4tXuhqZPLSbDi 3BrIU4YMNDkJpplWc+mEe1KPjO8JVIUrW1aeiPt9grdHfjyhFIzyZZLVuMAP23wuW/ 5f1iPtTTRiKbSGP6yaW7kJW/WwlohoGCi9gt24wc= X-QQ-mid: zesmtpgz1t1760581683t6699f087 X-QQ-Originating-IP: dRL8Fgzddpf7C4ifv6ilM/yZbCupdu3op2UO1npiUEE= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:00 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 4592435285348485794 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 1/8] usb: typec: Add default HPD device when register DisplayPort altmode Date: Thu, 16 Oct 2025 10:27:34 +0800 Message-Id: <20251016022741.91-2-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NENrrmtYLi890+bHytffGpEWHX0V0f8DHxBLmeek2iRAzA6N7CwxZuJE Xm+mYNomYPGRw0299yrm0+uOm8OOo7MToqEo2XlWweAwpIKFwawwLVxpu8q4W5QMSYeL6sU WiqSNJxHA+FDJqBkEmfdR8i9+61ULclvTX+qpR+j14KaP0ssEFY63aohfnlu85MloxxOta+ ZFG7BJ0L0Y7jhQKSCdObIws8YiAeEzQWeZLGXo+/o/uICUod8lU0mEIfzdP82nxPD0tuWSc 7Y5v6PDjIzqS1zv+kGLn+Qzd10N+Qvmk0AymVr1W3nKFNkIC9KcDB9qcp9f/qZ5uB6VV2vf amugJ6lG5KqQPdpdC4p+A9gLnM2OCR2Owsv5/xprtTNmdJ41ufio5dDiZ6mBJQUUX0KtW3O d7xQy3gAI9dQXfvDh1vcvdaWVX9ir+MDMI4XY9D7fIIjq/llhf/9mNAf3Rcg8vLSiXPW/X1 PuCJFFm+q9Z8d2CSeMXW+Z8j+re1EUt0zqvlDp91aH8JoZ+FbKz0WQmKmof3IkueybC8BO1 hVjzbcxyxMJhzoekEWPT0ZdakJwpJZHijv3CX8Zr9OIyKj2095HCfih+hmyZ4qM5z5IwHki oGIdJ3lNqgfBjUpjObpNZHW/2j2giP7uaEsiazX0bKBkDpPIyzdamR/TLQlkZPaDapXJxBc Vlht+kDqGz9erALgV5QePZqbixn+KuRHNS+xCL/ulDxR9tGykYyi+qKsFLxhgQhZKtM2IiQ xQTVIHfIvTnfUmryV7+762kftwD3DGZ9aJa3QkkMyUM+U4D27PRadIUaqwU476kgytEPuoh y7JRB0GqyCQofdXg8jP+6g1oE5/kxC8ahj4gfJI5QhEfLB2jIQZygRct1D/E5XaXs/w9fAA 9xrwP0oHiB8u9BRope21qAPsgAAVjsN/s2gqAnYfJh794JYS1tUGz5U71HNIP2O6AlaWDAm C4c9JYDlFfjZ4wmVN7Z21xZnGEJgXKehpA3adcWXIfQBoyjylRBztcXt0OiMX+Gmco0CgaD I/9I1RapKyvH+Mf7gr X-QQ-XMRINFO: Nq+8W0+stu50PRdwbJxPCL0= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen Add default DRM AUX HPD bridge device when register DisplayPort altmode. That makes it redundant for each Type-C driver to implement a similar registration process in embedded scenarios. Signed-off-by: Chaoyi Chen --- Changes in v6: - Fix depend in Kconfig. Changes in v5: - Remove the calls related to `drm_aux_hpd_bridge_notify()`. - Place the helper functions in the same compilation unit. - Add more comments about parent device. drivers/usb/typec/Kconfig | 2 ++ drivers/usb/typec/class.c | 26 ++++++++++++++++++++++++++ include/linux/usb/typec_altmode.h | 2 ++ 3 files changed, 30 insertions(+) diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index 2f80c2792dbd..a6730fbb576b 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -2,6 +2,8 @@ =20 menuconfig TYPEC tristate "USB Type-C Support" + depends on DRM || DRM=3Dn + select DRM_AUX_HPD_BRIDGE if DRM_BRIDGE && OF help USB Type-C Specification defines a cable and connector for USB where only one type of plug is supported on both ends, i.e. there will not diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 67a533e35150..e9d7772d1a8f 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -8,14 +8,18 @@ =20 #include #include +#include #include #include #include #include +#include #include #include #include =20 +#include + #include "bus.h" #include "class.h" #include "pd.h" @@ -538,6 +542,21 @@ const struct device_type typec_altmode_dev_type =3D { .release =3D typec_altmode_release, }; =20 +static void dp_altmode_hpd_device_register(struct typec_altmode *alt) +{ + if (alt->svid !=3D USB_TYPEC_DP_SID) + return; + + /* + * alt->dev.parent->parent : USB-C controller device + * alt->dev.parent : USB-C connector device + */ + alt->hpd_dev =3D drm_dp_hpd_bridge_register(alt->dev.parent->parent, + to_of_node(alt->dev.parent->fwnode)); + if (IS_ERR(alt->hpd_dev)) + alt->hpd_dev =3D NULL; +} + static struct typec_altmode * typec_register_altmode(struct device *parent, const struct typec_altmode_desc *desc) @@ -600,6 +619,13 @@ typec_register_altmode(struct device *parent, return ERR_PTR(ret); } =20 + /* + * It is too late to register the HPD device when the DisplayPort + * altmode device becomes ready. If the current altmode is DP, + * register a static HPD device. + */ + dp_altmode_hpd_device_register(&alt->adev); + return &alt->adev; } =20 diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_al= tmode.h index b3c0866ea70f..acb0af1b9d5d 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -21,6 +21,7 @@ struct typec_altmode_ops; * @desc: Optional human readable description of the mode * @ops: Operations vector from the driver * @cable_ops: Cable operations vector from the driver. + * @hpd_dev: HPD device for DisplayPort */ struct typec_altmode { struct device dev; @@ -32,6 +33,7 @@ struct typec_altmode { char *desc; const struct typec_altmode_ops *ops; const struct typec_cable_ops *cable_ops; + struct device *hpd_dev; }; =20 #define to_typec_altmode(d) container_of(d, struct typec_altmode, dev) --=20 2.49.0 From nobody Sat Feb 7 18:16:07 2026 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 B35EA15D5B6; Thu, 16 Oct 2025 02:28:43 +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=1760581729; cv=none; b=VPpQ4UQQOOqUKTlrPcGJ3IsLAo/VQ1443cWnT6MxADf7x43eVVluHTP1M/Q6mJakz2+ayQ11Z4p/m/lkh3YN+9WfN2Wl+oxOp28hD805cdfyHWy2QSpF0P0oq6PtL95VR0OBKcbsk6vqM4KTmICwLmesupjgMimDLnfgt2wduXA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581729; c=relaxed/simple; bh=JkC2n3cUcgwqX4mM3+Lhi39ig/OE1/fWWocxtgBRO8k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=GnbDtDac++rOf4tJd52WXXJXsjHW9GFmz45m9886wQ/LkE2bPMTwzWFAUpY+Xly0muj6fXXLVFyhG9NeEOVUm4j+eJTMDBvQFIRmru1xCuK1GQ61e/sf5x0WVKcL+yOsYi8SN8MvSOZXw8NVXO39fY8Y7dpnx0bYUfBC+lgNCEE= 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=t1uSJlCh; 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="t1uSJlCh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581688; bh=YHT4Mxhe+zSodIVHd2qzlGnysBWHBxMufel41tGudBs=; h=From:To:Subject:Date:Message-Id; b=t1uSJlCh6BKui0tSWCB4a5j/1fjlPSegptuGjd0kHLT4U15hlYxGxPZFuIKlp+phR AK0ukJLrBUvej52ujlnMIjCyQwjQyezqBVCBELYgRgdzCYn8VSEbRe7bqUa1xXc1vX iP5p1RZCoHof+7iUyYKTtjzmW4BpF3iEQ88QrHT4= X-QQ-mid: zesmtpgz1t1760581686t5a2ab742 X-QQ-Originating-IP: Br9MCe7LW7Ki5BF9qcSTZOmwdKejc+6aFdxKCmwAYcg= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:04 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 18423012065782556951 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 2/8] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch Date: Thu, 16 Oct 2025 10:27:35 +0800 Message-Id: <20251016022741.91-3-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NFzQ23lyTybaJuTmj8KGjQOpMbVaG8xJuoB4qgry0OKY8aYRsbgI0RyM r2whhdbJBMP8IWWrtuHKqk2hX5IMgA8kYGcvO8F2ZmTUWDOBiZ+iOPtJJHGUX30h4UOuX7M 2WhrB/H8/OA68OggCVjy/CdLTTeAgYEva+ZknsPIsgIV3ELNs6h06e++X5Xk0H2XLBLJ9e0 0WYxS4u3H48UiSXlm2MIXpk2hA9kSzMeWPk4TojWh7KfSPaTeFljyJc7UYqBBNd1Q8xKLm3 FyaGgB2fqpZ3LAIBbJUzhBXJzmW595I6XrQHSInogXQulnb7xOVni4kiBdFhYr5QVGrQDYj QzJroEnhg+sZ0OgcSjjZMyZJS76zZL2hI3pJBFNAlALw6pqIkeInFR3b9fPFd2jF+6QGixg utZQvEAXKnBRS+Zln0p2wTm8UL/NqXAhoV++ImP7YiNANNkpxg+ft6EYVcDsPO7MXBF0Jvy uC1JM7T7brTdOK6Qkb+9OObwdSqOmUMyM204RLX6evvHfJoHmptGpZt2tGiHEwIgry/gUiw MJK/DVv1rJDqCb/jAWejf07h9hRhOlnm6OmnkfDdIQ0tnWuKlc5HiBN0zrAVXoGYMXhIiCp roL81eLxZQmFeQPQAs9uyuYoaYoNlV+7L2VmKHTqg11pWaKE8fwuom3ArBX9+a0+/JlQ8Ui 6utWmIxAHJxs78nE+nqZuzOjK4G5WewYmKX2Xjv28oA895oOlmROTmt71t0ZGqBFVRIcHqf faI2Rh2jUJ9ly88CYL9VGVSLvcbFZzph5bLKTmhgVQDh+21Sx7uZGBty3Yx9AhliAznRPoq 0HOhDjfCkYcBRXkBjyyqnAFHBQfG2fn6c0DJgSp0YNHoS2lzkwFKTE6y9Qab25yes28imXz vwHetVmwEHUxAKaTe/Ir30+//0E/nC+PmgHynTaq432j3fOj+Ajfbam49MWLNi0r8QsDX9u FKCYBWj4IfaH3z2A4vPTXny8/HfW1DDgHjgRSQaVEUZvq5GP7oTALLi2/SibaLtgbXwX42J JUt06X8g== X-QQ-XMRINFO: Nq+8W0+stu50PRdwbJxPCL0= X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The RK3399 SoC integrates two USB/DP combo PHYs, each of which supports software-configurable pin mapping and DisplayPort lane assignment. These capabilities enable the PHY itself to handle both mode switching and orientation switching, based on the Type-C plug orientation and USB PD negotiation results. While an external Type-C controller is still required to detect cable attachment and report USB PD events, the actual mode and orientation switching is performed internally by the PHY through software configuration. This allows the PHY to act as a Type-C multiplexer for both data role and DP altmode configuration. To reflect this hardware design, this patch introduces a new "mode-switch" property for the dp-port node in the device tree bindings. This property indicates that the connected PHY is capable of handling Type-C mode switching itself. Signed-off-by: Chaoyi Chen Acked-by: Krzysztof Kozlowski --- (no changes since v5) Changes in v4: - Remove "|" in description. Changes in v3: - Add more descriptions to clarify the role of the PHY in switching. Changes in v2: - Reuse dp-port/usb3-port in rk3399-typec-phy binding. .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-ph= y.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.ya= ml index 91c011f68cd0..83ebcde096ea 100644 --- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml +++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml @@ -51,6 +51,12 @@ properties: '#phy-cells': const: 0 =20 + mode-switch: + description: + Indicates the PHY can handle altmode switching. In this case, + requires an external USB Type-C controller to report USB PD mess= age. + type: boolean + port: $ref: /schemas/graph.yaml#/properties/port description: Connection to USB Type-C connector --=20 2.49.0 From nobody Sat Feb 7 18:16:07 2026 Received: from smtpbgsg2.qq.com (smtpbgsg2.qq.com [54.254.200.128]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2AB311CAA85; Thu, 16 Oct 2025 02:28:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.128 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581721; cv=none; b=b5r//X+c8omhUf2Kk7bp68W9s8lqd1+bDs2CfkFlb4GSHQwkqnGdVT5G9oigR9W+iCCO2KVb7AjH7hDGoL8ZHvbSdwozB5/IUH0KPf3YYpxsmjljNZSA9IUOzlBM4/7zdilhHyxpg/C740jvca4AMLRzVDIu8FPwk6z3RMQRE5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581721; c=relaxed/simple; bh=h387lzJv8jEzmStX72YjwGwvaID6bnySvOp/6nv8d30=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=FhnhXLXo16tx6q3vdvN4+xqDvcRJjsoKSzDOqwXFWFlA/z9G0Yi07+l/fbISftw25ubsQuTKhTVALCmdei6v3/MkzVSLNa29hMEj5aijoJJlRnKo2n/P64XsNco2gyoRzgW8FPiE9HIPfssESM+Wp3g3HBS9apeIQo898tisT3g= 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=kCl1ML5Q; 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="kCl1ML5Q" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581691; bh=ZMpkEKwIkta5UTKgQWNbZANjjgU4AyBVB7o11g46BnI=; h=From:To:Subject:Date:Message-Id; b=kCl1ML5QvssmQHXqtBQxx6mqUxjjvBgh99ElVWhEgVSqZwtkDMmJVGf4f4N/214WK RW1S/SDHVJ/6bU3LhassquoBmbbgiR3+CLD8V+F9At3aap9tpJr6VZPsEkcXsLLVtT UT0DAnjRPpBZLCh7q4DBdVbjxOEWxdoD0791rLec= X-QQ-mid: zesmtpgz1t1760581690t2bbc748f X-QQ-Originating-IP: pm6/5+z49EdP548aDh4xykufWiU3ohvxcJCYIZGBs10= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:07 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 17288607060969659030 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 3/8] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support Date: Thu, 16 Oct 2025 10:27:36 +0800 Message-Id: <20251016022741.91-4-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: MOfwHzgDpc8Idlr4mzNVkNASKvT1qblzdplQPXJhRHRJ8/zh/JbJVWBJ ib8+ncJ8XNAa+pLRQivHhS3xmctp21Jd4Gw1nJI721Syhc0YwI4W5psS53JALNxWGeEla2Z IgMp6EWBvhI9qnlA/4tZnk45lXepp5N43nifehC8cbUmeK7St9Xo7iT04wC5toivDUgQY29 Bnse1j4jz9N2NxDmm/dEELap+nOJ961RBeuEa9ZnHdqCoxAmubTEjnsFB47ERCKALM6COag HkkgAIktsTG5J6dj0PqwA16nyx2NmHYhBU6bwVI9HFU8kMEUoCdlUq6/lNClZ9cyDOZOxc6 mEJA27qmiqUmr7us/hf4ZztU9mf8Tz3ccz040XrD2Xgfii5heCi/2HH2NFhNKlKl7J1Q+QQ +s9lNHT7/HFdFPw4j70HHlcJVaZj994xyyHvBzc77o1zI5ihBeGPfmeVn3pdCPd4P7/bCZU fSoqhCg70vFUaUDkBGaRYfmK8BYsbReYDDIZDVvN17eR6Tp18Te3Bn+SoRQFh/FgLgH2AYx 2APM1d/pP9RlmbOUrj9pLz8/2jZZ5MFMNbbPgW/epQRG2TrD+1naj1vgy7KvbbIun4wJ70a iZhRL5x6IE0yuLTLH9bVln8h5JPjEZwZQ9vsYOt4U2+pAUHHkoi5S8O+r/3FUqSM2cpP+84 AKkzmb3zhzneBonuGxK7ha+8OvTApwBuvp3yHj7GTmWlUhxIsma9nJ9waehZGTpJEx+r0kX yDpCK49IWXTySJs3ChDVnWqOA1FiM4IYaO0tNqBKz7ExrmGXN5lEYqQM47i7IgJwd3NQ6LZ PDEOx2i87pTb3rr7VBceif/gU4oGt2fNppvZRj4MSv2gxtlP5GCzXAsdjc2Cw54Bp8gV7BA 2kzrYtXzS2KriYID9b+Hx8z78zwTTwaPvPqaenCF2+iXLnu9oqtpH3LG7/ywMhQ1BtekGSG nPq7I39oNiKlyPUzMls80delql0EJZyaXxbl037Rr0tju+CeaVge2BnPTAKi+YqcsMzRrSD 7NrMtHsA== 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 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 --- Changes in v6: - Fix depend in Kconfig. - Check DP svid in tcphy_typec_mux_set(). - Remove mode setting in tcphy_orien_sw_set(). (no changes since v5) Changes in v4: - Remove notify DP HPD state by USB/DP PHY. (no changes since v3) Changes in v2: - Fix compile error when CONFIG_TYPEC is not enabled. - Notify DP HPD state by USB/DP PHY. drivers/phy/rockchip/Kconfig | 1 + drivers/phy/rockchip/phy-rockchip-typec.c | 368 +++++++++++++++++++++- 2 files changed, 353 insertions(+), 16 deletions(-) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index 14698571b607..db4adc7c53da 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -119,6 +119,7 @@ config PHY_ROCKCHIP_SNPS_PCIE3 config PHY_ROCKCHIP_TYPEC tristate "Rockchip TYPEC PHY Driver" depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) + depends on TYPEC || TYPEC=3Dn select EXTCON select GENERIC_PHY select RESET_CONTROLLER diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockch= ip/phy-rockchip-typec.c index d9701b6106d5..1f5b4142cbe4 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -54,6 +54,8 @@ =20 #include #include +#include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -286,12 +288,23 @@ #define RX_DIAG_SC2C_DELAY (0x81e1 << 2) =20 #define PMA_LANE_CFG (0xc000 << 2) +#define PMA_LANE3_DP_LANE_SEL(x) (((x) & 0x3) << 14) +#define PMA_LANE3_INTERFACE_SEL(x) (((x) & 0x1) << 12) +#define PMA_LANE2_DP_LANE_SEL(x) (((x) & 0x3) << 10) +#define PMA_LANE2_INTERFACE_SEL(x) (((x) & 0x1) << 8) +#define PMA_LANE1_DP_LANE_SEL(x) (((x) & 0x3) << 6) +#define PMA_LANE1_INTERFACE_SEL(x) (((x) & 0x1) << 4) +#define PMA_LANE0_DP_LANE_SEL(x) (((x) & 0x3) << 2) +#define PMA_LANE0_INTERFACE_SEL(x) (((x) & 0x1) << 0) #define PIPE_CMN_CTRL1 (0xc001 << 2) #define PIPE_CMN_CTRL2 (0xc002 << 2) #define PIPE_COM_LOCK_CFG1 (0xc003 << 2) #define PIPE_COM_LOCK_CFG2 (0xc004 << 2) #define PIPE_RCV_DET_INH (0xc005 << 2) #define DP_MODE_CTL (0xc008 << 2) +#define PHY_DP_POWER_STATE_ACK_MASK GENMASK(7, 4) +#define PHY_DP_POWER_STATE_ACK_SHIFT 4 +#define PHY_DP_POWER_STATE_MASK GENMASK(3, 0) #define DP_CLK_CTL (0xc009 << 2) #define STS (0xc00F << 2) #define PHY_ISO_CMN_CTRL (0xc010 << 2) @@ -327,8 +340,15 @@ =20 #define DP_MODE_A0 BIT(4) #define DP_MODE_A2 BIT(6) -#define DP_MODE_ENTER_A0 0xc101 -#define DP_MODE_ENTER_A2 0xc104 + +#define DP_MODE_MASK 0xf +#define DP_MODE_ENTER_A0 BIT(0) +#define DP_MODE_ENTER_A2 BIT(2) +#define DP_MODE_ENTER_A3 BIT(3) +#define DP_MODE_A0_ACK BIT(4) +#define DP_MODE_A2_ACK BIT(6) +#define DP_MODE_A3_ACK BIT(7) +#define DP_LINK_RESET_DEASSERTED BIT(8) =20 #define PHY_MODE_SET_TIMEOUT 100000 =20 @@ -340,6 +360,31 @@ #define MODE_DFP_USB BIT(1) #define MODE_DFP_DP BIT(2) =20 +enum phy_dp_lane_num { + PHY_DP_LANE_0 =3D 0, + PHY_DP_LANE_1, + PHY_DP_LANE_2, + PHY_DP_LANE_3, +}; + +enum phy_pma_if { + PMA_IF_PIPE_PCS =3D 0, + PMA_IF_PHY_DP, +}; + +enum phy_typec_role { + TYPEC_PHY_USB =3D 0, + TYPEC_PHY_DP, + TYPEC_PHY_MAX, +}; + +enum phy_dp_power_state { + PHY_DP_POWER_STATE_A0 =3D 0, + PHY_DP_POWER_STATE_A1, + PHY_DP_POWER_STATE_A2, + PHY_DP_POWER_STATE_A3, +}; + struct usb3phy_reg { u32 offset; u32 enable_bit; @@ -372,18 +417,22 @@ struct rockchip_typec_phy { struct device *dev; void __iomem *base; struct extcon_dev *extcon; + struct typec_mux_dev *mux; + struct typec_switch_dev *sw; struct regmap *grf_regs; struct clk *clk_core; struct clk *clk_ref; struct reset_control *uphy_rst; struct reset_control *pipe_rst; struct reset_control *tcphy_rst; + struct phy *phys[TYPEC_PHY_MAX]; const struct rockchip_usb3phy_port_cfg *port_cfgs; /* mutex to protect access to individual PHYs */ struct mutex lock; =20 bool flip; u8 mode; + u8 new_mode; }; =20 struct phy_reg { @@ -454,6 +503,99 @@ static const struct rockchip_usb3phy_port_cfg rk3399_u= sb3phy_port_cfgs[] =3D { { /* sentinel */ } }; =20 +static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy, + bool value); + +static int tcphy_dp_set_power_state(struct rockchip_typec_phy *tcphy, + enum phy_dp_power_state state) +{ + u32 ack, reg, sts =3D BIT(state); + int ret; + + /* + * Power state changes must not be requested until after the cmn_ready + * signal has gone active. + */ + reg =3D readl(tcphy->base + PMA_CMN_CTRL1); + if (!(reg & CMN_READY)) { + dev_err(tcphy->dev, "cmn_ready in the inactive state\n"); + return -EINVAL; + } + + reg =3D readl(tcphy->base + DP_MODE_CTL); + reg &=3D ~PHY_DP_POWER_STATE_MASK; + reg |=3D sts; + writel(reg, tcphy->base + DP_MODE_CTL); + + ret =3D readl_poll_timeout(tcphy->base + DP_MODE_CTL, + ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >> + PHY_DP_POWER_STATE_ACK_SHIFT) =3D=3D sts), 10, + PHY_MODE_SET_TIMEOUT); + if (ret < 0) { + dev_err(tcphy->dev, "failed to enter power state %d\n", state); + return ret; + } + + return 0; +} + +/* + * For the TypeC PHY, the 4 lanes are mapping to the USB TypeC receptacle = pins + * as follows: + * ------------------------------------------------------------------- + * PHY Lanes/Module Pins TypeC Receptacle Pins + * ------------------------------------------------------------------- + * Lane0 (tx_p/m_ln_0) TX1+/TX1- (pins A2/A3) + * Lane1 (tx_rx_p/m_ln_1) RX1+/RX1- (pins B11/B10) + * Lane2 (tx_rx_p/m_ln_2) RX2+/RX2- (pins A11/A10) + * Lane3 (tx_p/m_ln_3) TX2+/TX2- (pins B2/B3) + * ------------------------------------------------------------------- + * + * USB and DP lanes mapping to TypeC PHY lanes for each of pin assignment + * options (normal connector orientation) described in the VESA DisplayPort + * Alt Mode on USB TypeC Standard as follows: + * + * ---------------------------------------------------------------------- + * PHY Lanes A B C D E F + * ---------------------------------------------------------------------- + * 0 ML1 SSTX ML2 SSTX ML2 SSTX + * 1 ML3 SSRX ML3 SSRX ML3 SSRX + * 2 ML2 ML1 ML0 ML0 ML0 ML0 + * 3 ML0 ML0 ML1 ML1 ML1 ML1 + * ---------------------------------------------------------------------- + */ +static void tcphy_set_lane_mapping(struct rockchip_typec_phy *tcphy, u8 mo= de) +{ + /* + * The PMA_LANE_CFG register is used to select whether a PMA lane + * is mapped for USB or PHY DP. The PMA_LANE_CFG register is + * configured based on a normal connector orientation. Logic in the + * PHY automatically handles the flipped connector case based on the + * setting of orientation of TypeC PHY. + */ + if (mode =3D=3D MODE_DFP_DP) { + /* This maps to VESA DP Alt Mode pin assignments C and E. */ + writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) | + PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) | + PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE1_DP_LANE_SEL(PHY_DP_LANE_3) | + PMA_LANE1_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE0_DP_LANE_SEL(PHY_DP_LANE_2) | + PMA_LANE0_INTERFACE_SEL(PMA_IF_PHY_DP), + tcphy->base + PMA_LANE_CFG); + } else { + /* This maps to VESA DP Alt Mode pin assignments D and F. */ + writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) | + PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) | + PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) | + PMA_LANE1_INTERFACE_SEL(PMA_IF_PIPE_PCS) | + PMA_LANE0_INTERFACE_SEL(PMA_IF_PIPE_PCS), + tcphy->base + PMA_LANE_CFG); + } +} + static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy) { u32 i, rdata; @@ -743,8 +885,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *t= cphy, u8 mode) tcphy_dp_aux_set_flip(tcphy); =20 tcphy_cfg_24m(tcphy); + tcphy_set_lane_mapping(tcphy, mode); =20 if (mode =3D=3D MODE_DFP_DP) { + tcphy_cfg_usb3_to_usb2_only(tcphy, true); tcphy_cfg_dp_pll(tcphy); for (i =3D 0; i < 4; i++) tcphy_dp_cfg_lane(tcphy, i); @@ -768,7 +912,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *t= cphy, u8 mode) writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG); } =20 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); + val =3D readl(tcphy->base + DP_MODE_CTL); + val &=3D ~DP_MODE_MASK; + val |=3D DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED; + writel(val, tcphy->base + DP_MODE_CTL); =20 reset_control_deassert(tcphy->uphy_rst); =20 @@ -811,8 +958,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tc= phy) u8 mode; int ret, ufp, dp; =20 + /* If extcon not exist, try to use tcpm mode */ if (!edev) - return MODE_DFP_USB; + return tcphy->new_mode; =20 ufp =3D extcon_get_state(edev, EXTCON_USB); dp =3D extcon_get_state(edev, EXTCON_DISP_DP); @@ -850,6 +998,71 @@ static int tcphy_get_mode(struct rockchip_typec_phy *t= cphy) return mode; } =20 +#if IS_ENABLED(CONFIG_TYPEC) +static int tcphy_orien_sw_set(struct typec_switch_dev *sw, + enum typec_orientation orien) +{ + struct rockchip_typec_phy *tcphy =3D typec_switch_get_drvdata(sw); + + mutex_lock(&tcphy->lock); + + if (orien =3D=3D TYPEC_ORIENTATION_NONE) { + tcphy->new_mode =3D MODE_DISCONNECT; + goto unlock_ret; + } + + tcphy->flip =3D (orien =3D=3D TYPEC_ORIENTATION_REVERSE) ? true : false; + +unlock_ret: + mutex_unlock(&tcphy->lock); + return 0; +} + +static void udphy_orien_switch_unregister(void *data) +{ + struct rockchip_typec_phy *tcphy =3D data; + + typec_switch_unregister(tcphy->sw); +} + +static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy) +{ + struct typec_switch_desc sw_desc =3D { }; + struct device_node *np; + int ret =3D 0; + + np =3D of_get_child_by_name(tcphy->dev->of_node, "usb3-port"); + if (!np) + return 0; + + if (!of_property_read_bool(np, "orientation-switch")) + goto put_np; + + sw_desc.drvdata =3D tcphy; + sw_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "usb3-port"); + sw_desc.set =3D tcphy_orien_sw_set; + + tcphy->sw =3D typec_switch_register(tcphy->dev, &sw_desc); + if (IS_ERR(tcphy->sw)) { + dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n", + PTR_ERR(tcphy->sw)); + ret =3D PTR_ERR(tcphy->sw); + goto put_np; + } + + ret =3D devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregiste= r, tcphy); + +put_np: + of_node_put(np); + return ret; +} +#else +static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy) +{ + return 0; +} +#endif + static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy, bool value) { @@ -989,14 +1202,9 @@ static int rockchip_dp_phy_power_on(struct phy *phy) =20 tcphy_dp_aux_calibration(tcphy); =20 - writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL); - - ret =3D readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, - val, val & DP_MODE_A0, 1000, - PHY_MODE_SET_TIMEOUT); - if (ret < 0) { - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); - dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n"); + ret =3D tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A0); + if (ret) { + dev_err(tcphy->dev, "failed to enter A0 power state\n"); goto power_on_finish; } =20 @@ -1013,6 +1221,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy) static int rockchip_dp_phy_power_off(struct phy *phy) { struct rockchip_typec_phy *tcphy =3D phy_get_drvdata(phy); + int ret; =20 mutex_lock(&tcphy->lock); =20 @@ -1021,7 +1230,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy) =20 tcphy->mode &=3D ~MODE_DFP_DP; =20 - writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); + ret =3D tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A2); + if (ret) { + dev_err(tcphy->dev, "failed to enter A2 power state\n"); + goto unlock; + } =20 if (tcphy->mode =3D=3D MODE_DISCONNECT) tcphy_phy_deinit(tcphy); @@ -1037,6 +1250,93 @@ static const struct phy_ops rockchip_dp_phy_ops =3D { .owner =3D THIS_MODULE, }; =20 +#if IS_ENABLED(CONFIG_TYPEC) +static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux= _state *state) +{ + struct rockchip_typec_phy *tcphy =3D typec_mux_get_drvdata(mux); + struct typec_displayport_data *data; + int hpd =3D 0; + + mutex_lock(&tcphy->lock); + + switch (state->mode) { + case TYPEC_STATE_SAFE: + fallthrough; + case TYPEC_STATE_USB: + tcphy->new_mode =3D MODE_DFP_USB; + phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0); + break; + case TYPEC_DP_STATE_C: + case TYPEC_DP_STATE_E: + if (state->alt->svid !=3D USB_TYPEC_DP_SID) + break; + tcphy->new_mode =3D MODE_DFP_DP; + data =3D state->data; + hpd =3D !!(data->status & DP_STATUS_HPD_STATE); + phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0); + break; + case TYPEC_DP_STATE_D: + if (state->alt->svid !=3D USB_TYPEC_DP_SID) + break; + tcphy->new_mode =3D MODE_DFP_DP | MODE_DFP_USB; + data =3D state->data; + hpd =3D !!(data->status & DP_STATUS_HPD_STATE); + phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0); + break; + default: + break; + } + + mutex_unlock(&tcphy->lock); + + return 0; +} + +static void tcphy_typec_mux_unregister(void *data) +{ + struct rockchip_typec_phy *tcphy =3D data; + + typec_mux_unregister(tcphy->mux); +} + +static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) +{ + struct typec_mux_desc mux_desc =3D {}; + struct device_node *np; + int ret =3D 0; + + np =3D of_get_child_by_name(tcphy->dev->of_node, "dp-port"); + if (!np) + return 0; + + if (!of_property_read_bool(np, "mode-switch")) + goto put_np; + + mux_desc.drvdata =3D tcphy; + mux_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "dp-port"); + mux_desc.set =3D tcphy_typec_mux_set; + + tcphy->mux =3D typec_mux_register(tcphy->dev, &mux_desc); + if (IS_ERR(tcphy->mux)) { + dev_err(tcphy->dev, "Error register typec mux: %ld\n", + PTR_ERR(tcphy->mux)); + ret =3D PTR_ERR(tcphy->mux); + goto put_np; + } + + ret =3D devm_add_action_or_reset(tcphy->dev, tcphy_typec_mux_unregister, = tcphy); + +put_np: + of_node_put(np); + return ret; +} +#else +static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) +{ + return 0; +} +#endif + static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy, struct device *dev) { @@ -1095,6 +1395,25 @@ static void typec_phy_pre_init(struct rockchip_typec= _phy *tcphy) tcphy->mode =3D MODE_DISCONNECT; } =20 +static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy) +{ + int dp_lanes; + + switch (tcphy->new_mode) { + case MODE_DFP_DP: + dp_lanes =3D 4; + break; + case MODE_DFP_DP | MODE_DFP_USB: + dp_lanes =3D 2; + break; + default: + dp_lanes =3D 0; + break; + } + + return dp_lanes; +} + static int rockchip_typec_phy_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; @@ -1142,6 +1461,7 @@ static int rockchip_typec_phy_probe(struct platform_d= evice *pdev) return ret; =20 tcphy->dev =3D dev; + tcphy->new_mode =3D MODE_DFP_USB; platform_set_drvdata(pdev, tcphy); mutex_init(&tcphy->lock); =20 @@ -1151,6 +1471,7 @@ static int rockchip_typec_phy_probe(struct platform_d= evice *pdev) if (IS_ERR(tcphy->extcon)) { if (PTR_ERR(tcphy->extcon) =3D=3D -ENODEV) { tcphy->extcon =3D NULL; + dev_info(dev, "extcon not exist, try to use typec mux\n"); } else { if (PTR_ERR(tcphy->extcon) !=3D -EPROBE_DEFER) dev_err(dev, "Invalid or missing extcon\n"); @@ -1158,19 +1479,34 @@ static int rockchip_typec_phy_probe(struct platform= _device *pdev) } } =20 + ret =3D tcphy_setup_orien_switch(tcphy); + if (ret) + return ret; + + ret =3D tcphy_setup_typec_mux(tcphy); + if (ret) + return ret; + pm_runtime_enable(dev); =20 for_each_available_child_of_node(np, child_np) { struct phy *phy; =20 - if (of_node_name_eq(child_np, "dp-port")) + if (of_node_name_eq(child_np, "dp-port")) { phy =3D devm_phy_create(dev, child_np, &rockchip_dp_phy_ops); - else if (of_node_name_eq(child_np, "usb3-port")) + if (!IS_ERR(phy)) { + tcphy->phys[TYPEC_PHY_DP] =3D phy; + phy_set_bus_width(phy, typec_dp_lane_get(tcphy)); + } + } else if (of_node_name_eq(child_np, "usb3-port")) { phy =3D devm_phy_create(dev, child_np, &rockchip_usb3_phy_ops); - else + if (!IS_ERR(phy)) + tcphy->phys[TYPEC_PHY_USB] =3D phy; + } else { continue; + } =20 if (IS_ERR(phy)) { dev_err(dev, "failed to create phy: %pOFn\n", --=20 2.49.0 From nobody Sat Feb 7 18:16:07 2026 Received: from smtpbgsg1.qq.com (smtpbgsg1.qq.com [54.254.200.92]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9DDC8214812; Thu, 16 Oct 2025 02:28:43 +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=1760581726; cv=none; b=qgVSMoJ4h4KhH/V9D50ZTYQEgLqRIQr0mMI3j9IECMt1zylr22XUdccVyT6GJRGVTxKnoqKesFXrZnD6e1v5A6vXFsisuT5SXaKLeixAVqR5SMcN2Vbb/r6o1YyHfbV9b9xZDW9tseMB+/0jHhYJwA7/A5rWRFouifZ/KOch68g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581726; c=relaxed/simple; bh=3IrJq2eY7H58BhtqUIT1x/6vJnGaTeTxDX146pHI90M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=V5hRl3Hx2MjaqP3m0EeEw9KrY+iy5mG9P3dXuxspb1eYmv2MbGz6xsZstvgkm20w0bfbdfh3k0KWEq/Xiwdqo85rHR5o9DxKE83GbevjVVhDA+shL/7YingrfOTvYLe7zNgZUvDiI4JwNqobLxYXhb4KE3fcVnr8KpFo2x3enTc= 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=GPUk5rh7; 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="GPUk5rh7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581695; bh=i25gNlDAtw8b5HK1jAZXBoV/IQCgdqvoMWGREg/E/KM=; h=From:To:Subject:Date:Message-Id; b=GPUk5rh7mMqjgsxEC1/munKSS+h9QPAfQvRACESSoENYcTw5clr8Kpqwis4Zs84un BqpQjvxAM7BY9mzpV92DqVhakILGXv/0EVPWa6Vd9LwYCDsZeCsPhKDNWqPrFwK/RJ YNcJycuncnHwcCF2fW9mG1KTTh/EqwbBiV9nTRkQ= X-QQ-mid: zesmtpgz1t1760581693tcd70b443 X-QQ-Originating-IP: VcuS+Dxp0BYExURU8Vsw6C9TnS/E0vZwDdscGFf6LgY= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:11 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 12339062551155621707 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 4/8] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Date: Thu, 16 Oct 2025 10:27:37 +0800 Message-Id: <20251016022741.91-5-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: N2bAIxLK0elnxzwM3GPcOMqS01K4312xqBbjR7dK+BPWVl+VPlGReoLj vmqTEScDKZK+c5TBsvDAitd/kYLsI22wObvHJVvy3tj06Y+CJKyR6p5Z5qrjCbmB+MssEb6 aHtodOzYBiJDTeyEIC0O0vPK16rtyOD7Q9Bqs1SQGxNKvHMutOEe8ynVz3vpj2+FatLK0aH D/rztYL3jwF/NSKXQBCccgp5lDSS3Dn6oshsODQAsuXLNAem3//0dek5d1YsCApoUwGyxTJ E6hQJZGQVwA/PIlO937X/OisBCx3OjruiFZN81s1cosbh1OkuMLnh4GPWKj/q2H3HVJwbeK xu82FMZxJI6lfTJTpaRSNeERbfk8npm61zguFRu7gnziYW8gUubJONZGEByqvFHH0iFuQS3 ni/E00gU2N3qeTAoUm0H4P0DPBc3U5qt1mvJ9X8kJ1fGak8g5Xw1PYWW34mnpLCk3ojwxHI XUiUHa5+6crSiOmQz7Ae5EiOq3qRQCHmQXAdQNCnLk3RYcYk2evcCQkL2Q3ljIPNeqFFk9R gUzCMog/evEY+kEVVaZFNoRSoesWtUnVv9Fne259q/Dhkgujq+HH6J0V55XAZU2fbPBeuAB 6Lgtnyfk4yVt60hBSXkfcciiuspqtVQKCtHkN5YB3e1fAND372L9S2Omfi4wykikXc7XPjH N7ESDA8Hp+jp8jF0htTBL7MMy9UI/3IZuP0o/33ipUhMOyoZefPcTuLDne5s/mrdn0A8Wvr MXI+qV16re9DfWaq6VRGPuWd1O0pd2hSicIrGVPYTiGdo7w2BsBEdPRJY0ONPRNkx4rk2wK PwfVcVQJzHwrnGQlA0S4JTbOzVn4D2IV+DPM0AEm00oT0pEz94osWn8o7r5n9SjswkyiwcY wXrl1dq9ss1FrImzXqwtLkboJIWsrlKkbmmtrdLSfWsU+VUVkmYB6nKPa6rUgdGRsCv7p9U k9wjdvxBbS12bXlxO14XkL5gzpkpTPaxHD0D9lewry8ZumSo+kW5UNlwkGzQn13W71rJZl6 qHteDqqA== 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 --- Changes in v6: - Fix depend in Kconfig.=20 drivers/phy/rockchip/Kconfig | 2 + drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index db4adc7c53da..bcb5476222fc 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC tristate "Rockchip TYPEC PHY Driver" depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) depends on TYPEC || TYPEC=3Dn + depends on DRM || DRM=3Dn + select DRM_AUX_BRIDGE if DRM_BRIDGE select EXTCON select GENERIC_PHY select RESET_CONTROLLER diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockch= ip/phy-rockchip-typec.c index 1f5b4142cbe4..748a6eb8ad95 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -36,6 +36,7 @@ * orientation, false is normal orientation. */ =20 +#include #include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -415,6 +417,7 @@ struct rockchip_usb3phy_port_cfg { =20 struct rockchip_typec_phy { struct device *dev; + struct auxiliary_device dp_port_dev; void __iomem *base; struct extcon_dev *extcon; struct typec_mux_dev *mux; @@ -1299,6 +1302,51 @@ static void tcphy_typec_mux_unregister(void *data) typec_mux_unregister(tcphy->mux); } =20 +static void tcphy_dp_port_dev_release(struct device *dev) +{ + struct auxiliary_device *adev =3D to_auxiliary_dev(dev); + + of_node_put(adev->dev.of_node); +} + +static void tcphy_dp_port_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev =3D _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static int tcphy_aux_bridge_register(struct rockchip_typec_phy *tcphy, str= uct device_node *np) +{ + struct auxiliary_device *adev =3D &tcphy->dp_port_dev; + int ret; + + adev->name =3D "dp_port"; + adev->dev.parent =3D tcphy->dev; + adev->dev.of_node =3D of_node_get(np); + adev->dev.release =3D tcphy_dp_port_dev_release; + + ret =3D auxiliary_device_init(adev); + + if (ret) { + of_node_put(adev->dev.of_node); + return ret; + } + + ret =3D auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + devm_add_action_or_reset(tcphy->dev, tcphy_dp_port_unregister_adev, adev); + + ret =3D drm_aux_bridge_register(&adev->dev); + + return 0; +} + static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy) { struct typec_mux_desc mux_desc =3D {}; @@ -1312,6 +1360,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typ= ec_phy *tcphy) if (!of_property_read_bool(np, "mode-switch")) goto put_np; =20 + ret =3D tcphy_aux_bridge_register(tcphy, np); + if (ret) + goto put_np; + mux_desc.drvdata =3D tcphy; mux_desc.fwnode =3D device_get_named_child_node(tcphy->dev, "dp-port"); mux_desc.set =3D tcphy_typec_mux_set; --=20 2.49.0 From nobody Sat Feb 7 18:16:07 2026 Received: from smtpbgjp3.qq.com (smtpbgjp3.qq.com [54.92.39.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFEC721CC56; Thu, 16 Oct 2025 02:28:41 +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=1760581726; cv=none; b=RyV6G2CCCcHL173DXcDCXXKt8qxzzDbBOP0RwNZz/PzTlLkpOoVuRg7n03XsVOY7CJyD0mSvLOcWdElMaoOA5iKcQomi+kpyOUBh+kKt8nYSwJTAuaaYyBx14kg3nzScSj8TeB3wwzux3FNiC+osqvBemI6Igr6s2SdoI4RybsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581726; c=relaxed/simple; bh=M4nUEX7h4FeSk6XVEQszUpUpBE3mjUtZPXnyDXgdiFI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=MNj5cN6d2pkQUipxUo96cCnI0cWyq67IpcN8x8hQPX1rHnTiYrjNOBViXajZqy4MMV1fKyBu6wpPcwgCGNQNCRdLirS0Iwz+oGm0z4m2G11X3gHJLIspl8GvD7tY4JvVMAg/rRuMA+rGm1e49eTMjCKBNxHg9HuXjCRUZET81/8= 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=Bw472g63; 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="Bw472g63" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581698; bh=nQG0w7dhU7Aew5bKV30plkPn0nBnVdgTnfwSbxYLntU=; h=From:To:Subject:Date:Message-Id; b=Bw472g63hnshVM/rG0XxziDyhCywS2vTxA0imz+PNliiwRr94KJxcr8vMButxCHLP ukEQSurTxAJzm3SWO9eVDWmeSQOEqjofz4CRrKRYPtpGC4y0pv5d7yrNrM573r3R9b d1vqueU7q4JUOynJTlWH4Hvv5c+Z7G+/8+ZPQw/0= X-QQ-mid: zesmtpgz1t1760581697tf65e1f89 X-QQ-Originating-IP: 6NbQJeS/+dGFQkjM52rtrshJx1shko+6S27zLhjeTRw= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:14 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 6632506262232562505 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 5/8] drm/rockchip: cdn-dp: Support handle lane info without extcon Date: Thu, 16 Oct 2025 10:27:38 +0800 Message-Id: <20251016022741.91-6-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: Mo29KZ8DTxVyj0Tul/DDy2zwezEXvJzU01bxOq6uj59q38k9jpNfZxPs 4jyhuIWNwIFHZrP89abCSjTjUUBSmBu+qjUO+q6UXkTyBDQpEmpKe/pfQr7HZ6BHiUwokC4 0e4VDzy2Ux9taohThMbZhsxOKqpwaz3/mtDJnD0ZKr2lLWwcQAdFmC9mhHKH7xdeSooG6+f 0Ch2rLRfIt0mT//VNM8rINAH57SDoP7rtBbrm6s9tWRy1GNifYgWYOF7NoMzgj04l7ozvfT 0sspI/0oyOoDe2/HAo6bPmqxMcMfFYMccT3/GDp9SpElM0C2j5WN7HMBAMfE+3nB34vHp7o 6+dtQ32inRugwoCFnV70Bk/Txx7SB4Tlg5tr3axETMx1RXyqrbGg5MmxhV0lFLsQrBmZxfH An9DUTyLhy5NcIgwbUrmCO0s4YQLVmJG0ue0ZKbZ9TQUsT3tvcZA4vSurQC0S5czNviZU5+ YDjn3GKEl5/jn9SP2yDiHi4Gl+NcpN3+S/EszUpstBbIiGjr9Gv2I/VZA093IefWFUJeViR ClJUjJIgsNnxq94IwAv0/iHkbhQvt6+LK84NMBlS5Xysd1UpB9US04koLIMnukU11ZgL+o3 kBt35xyLf7DumDMHn8xvnb/RXJ1A4tIQbe8/sAdy3oBnot1rt/vG4iSb5JHg2Q5PoMWhEEl MZj+6LV+N4aT8Ovg8WTpMAQcIYPSCsoOkutv6/O+RwzWcVr3BjM4byph5q5NWrHa4wEFTJ8 3mFFJj+pwqv4b9mUHPRHhDOZ4gm8sq4S94bsVbjiFgDe8Dh29ZF6BPGUV3Ul5niwKEEHkuA 3KzMXUszP8jCuc7RxmafB9w7xrPkYB3UaMl15RCr7caJiiDM4Ok4UYPZH9XXFg4OfkHPa2z 37ytoXNPZCwv8sZNJftEzQcyOc7YYWKIFzg/CsH16uyMIEzE1CCcM70EdguJcNl0S8ECHHw 0zg65iZmDLLzIaTy7vdI2YQLZt6KkVCdgO+0MSdDvQRkvxHxLAbaHmbVxCZ3iBrozEqjHUb JmC3tJfIZUljAuRUdb/gCEpAooQYsIma/ikQfXsw== 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 This patch add support for get PHY lane info without help of extcon. There is no extcon needed if the Type-C controller is present. In this case, the lane info can be get from PHY instead of extcon. The extcon device should still be supported if Type-C controller is not present. Signed-off-by: Chaoyi Chen --- (no changes since v5) Changes in v4: - Remove cdn_dp_hpd_notify(). (no changes since v3) Changes in v2: - Ignore duplicate HPD events. drivers/gpu/drm/rockchip/cdn-dp-core.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index b7e3f5dcf8d5..1e27301584a4 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *po= rt) int dptx; u8 lanes; =20 + if (!edev) + return phy_get_bus_width(port->phy); + dptx =3D extcon_get_state(edev, EXTCON_DISP_DP); if (dptx > 0) { extcon_get_property(edev, EXTCON_DISP_DP, @@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_= device *dp) * some docks need more time to power up. */ while (time_before(jiffies, timeout)) { - if (!extcon_get_state(port->extcon, EXTCON_DISP_DP)) + if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP)) return false; =20 if (!cdn_dp_get_sink_count(dp, &sink_count)) @@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp= , struct cdn_dp_port *port) goto err_power_on; } =20 - ret =3D extcon_get_property(port->extcon, EXTCON_DISP_DP, - EXTCON_PROP_USB_TYPEC_POLARITY, &property); - if (ret) { - DRM_DEV_ERROR(dp->dev, "get property failed\n"); - goto err_power_on; + property.intval =3D 0; + if (port->extcon) { + ret =3D extcon_get_property(port->extcon, EXTCON_DISP_DP, + EXTCON_PROP_USB_TYPEC_POLARITY, &property); + if (ret) { + DRM_DEV_ERROR(dp->dev, "get property failed\n"); + goto err_power_on; + } } =20 port->lanes =3D cdn_dp_get_port_lanes(port); @@ -1028,6 +1034,9 @@ static int cdn_dp_bind(struct device *dev, struct dev= ice *master, void *data) for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; =20 + if (!port->extcon) + continue; + port->event_nb.notifier_call =3D cdn_dp_pd_event; ret =3D devm_extcon_register_notifier(dp->dev, port->extcon, EXTCON_DISP_DP, @@ -1120,14 +1129,14 @@ static int cdn_dp_probe(struct platform_device *pde= v) PTR_ERR(phy) =3D=3D -EPROBE_DEFER) return -EPROBE_DEFER; =20 - if (IS_ERR(extcon) || IS_ERR(phy)) + if (IS_ERR(phy) || PTR_ERR(extcon) !=3D -ENODEV) continue; =20 port =3D devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); if (!port) return -ENOMEM; =20 - port->extcon =3D extcon; + port->extcon =3D IS_ERR(extcon) ? NULL : extcon; port->phy =3D phy; port->dp =3D dp; port->id =3D i; --=20 2.49.0 From nobody Sat Feb 7 18:16:07 2026 Received: from smtpbgeu2.qq.com (smtpbgeu2.qq.com [18.194.254.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9A4A946C; Thu, 16 Oct 2025 02:28:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=18.194.254.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581737; cv=none; b=FmHglNZ/EQbLlm5wXeAoDebT8x/QF4UQOEt1HSI1TUg6994niR+OAlBhMZn3SC96hNGMUTfogTgQQiRkOEORMCwQY+m0RllriJ/tyWF+wL2aOvrM+Pgx3MOw1MF6vc4o7NbruTXQvNkLKd0MX3TpsyqizCxYzjTSvYBW0O3PEIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581737; c=relaxed/simple; bh=RJoM0jg7WAYXvbJDn23mboIGzdCcxI+U8/15ldWASvM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=ppgL94WHshYHe6WIcg9AmutGHWp3Mn2fSyIkS6De+5gSuyaBjQO/PQ2eGTDflhNI5zet3lXr4EgfZKfeiNQFwUHIUemXqkp7Hs64CUOk+DfPf/vQv6r0J5bFrHVclJR7F5fv+MHKephzRN4HznniRZGcMI9hOB+6+ToLvdar23w= 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=G6MI9ONZ; arc=none smtp.client-ip=18.194.254.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="G6MI9ONZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581702; bh=BuQ4mBEiN+7/ObTTcK+p0KiLMvuXBc9ZgL86oY+Ib4A=; h=From:To:Subject:Date:Message-Id; b=G6MI9ONZnta1d4VViTHAH1aDMehrO8wPguCENgicAVypVrxWd7jNo0W9zwx3dz8qm aofOARI5lgxuCobY4Ats8JMIjXW9vqdnS/m98VT4jCoQaR/Rh1lZItciTRyWKB40IJ hOgK4VMp+tcsox20cJ+nhg+sTC6EBWELeHcmYwHI= X-QQ-mid: zesmtpgz1t1760581700t137f5e57 X-QQ-Originating-IP: +UfW3lMvNEHII+EXqp/+l4Sn1gYY13VXaXZz79ARNNo= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:18 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 17802569404537797185 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 6/8] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Date: Thu, 16 Oct 2025 10:27:39 +0800 Message-Id: <20251016022741.91-7-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: OSjQccS6YHkHkBmfentXafWiBmGgvQIj5rLxq6fOoFPqm9uJAkRPd4P4 rtf92fFwyDLKcm+44wKNggjjDZpLY1PAjtOe23gnLlvZuBLCaF26soQ7LGBDaN2tTpC2W4A oE70jtoaV1VN+gohDvg7TrlC6rYyr74IlTsuKED6+WCinfo74fZmqFahtD7LWfNF2gM+UTK wLmAJ8gyIq6O0r6HtxYste7xREUgi6RPoTFnDnDKz+8z1gffMe9aZcO109CnnbEZyg07WjD MiAzh91T8JwdrMO9e3RuZ7hozAKCNz0hnaJBupKVE9zJ12ICDuPgI45VXsKm7MNRPxdIWAI 1zWvOihG5vVIyNT3Nx/uPDLYLmlzD5IRYvYmFve5xq7r2yXOd6n9mJZBFvcS5XdXETng8Zj 9imGXVWlCa7qB9rgd4p9EWcLDbqstMOhv3o5irjCjktXLLdobecCzFIjhyUAMW7jG/NrGMZ vDOLcdcvxP2Lz0tDC1d16x/tF0f4bQ047VGRWBtNSxvFySg+YFonzPjqeuyQS/v7A/g2yao 6Cn98EC6GvPxjl+qfrUkiDB4vydwA3CDPd4/jKed8u+rrfAqh3ryiQElW9hz7KvUchehg3b C2amOinjV2bdk6R/gzfOY8JSOh29rWqsmNluV7h5wCt8V24ITQGoVsGaFj4Cd2H5ol1TU03 YVr631CWJeDx9lVfEf5fVES5uL/V/CxdfP79rgNu3SRuSAZwxSqtjun9xYBIO66Q1rKiYL6 Y5uOQL5oGnsRWwzITkP2mhc3qI0mUlrs325EiarNmUkR0G9muJJF9sEieDxqTNunT6n8Npk iRTLc5o+Sf23sOjbAXCD0a4A8EvNCQKJLaW7AUMsTmc+tX1PFysa532/JwrkF4hT8pfx4RM nII7S/6YJPfyyYN+EbBUQWaOy1ecmCPSw0HPiEBL9/3v8IW7vqbmx9OlraZCFWAbawioCzM R8FEX8sWz02hpd0Ym+vHDK6VGPL0wSgB6TMZqPPS+VgPIez4VAZeGmbuVW26oWPsY4HYRzW k9+FQUZ/8noX+bsy++1IfLph+jBcFvXQvoNbw63NTiu+3R6kS3 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 has two USB/DP combo PHY and one CDN-DP controller. And the CDN-DP can be switched to output to one of the PHYs. If both ports are plugged into DP, DP will select the first port for output. This patch adds support for multiple bridges, enabling users to flexibly select the output port. For each PHY port, a separate encoder and bridge are registered. The change is based on the DRM AUX HPD bridge, rather than the extcon approach. This requires the DT to correctly describe the connections between the first bridge in bridge chain and DP controller. For example, the bridge chain may be like this: PHY aux birdge -> fsa4480 analog audio switch bridge -> onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge In this case, the connection relationships among the PHY aux bridge and the DP contorller need to be described in DT. In addition, the cdn_dp_parse_next_bridge_dt() will parses it and determines whether to register one or two bridges. Since there is only one DP controller, only one of the PHY ports can output at a time. The key is how to switch between different PHYs, which is handled by cdn_dp_switch_port() and cdn_dp_enable(). There are two cases: 1. Neither bridge is enabled. In this case, both bridges can independently read the EDID, and the PHY port may switch before reading the EDID. 2. One bridge is already enabled. In this case, other bridges are not allowed to read the EDID. So we will try to return the cached EDID. Since the scenario of two ports plug in at the same time is rare, I don't have a board which support two TypeC connector to test this. Therefore, I tested forced switching on a single PHY port, as well as output using a fake PHY port alongside a real PHY port. Signed-off-by: Chaoyi Chen --- Changes in v6: - Rename some variable names. - Attach the DP bridge to the next bridge. Changes in v5: - By parsing the HPD bridge chain, set the connector's of_node to the of_node corresponding to the USB-C connector. - Return EDID cache when other port is already enabled. drivers/gpu/drm/rockchip/cdn-dp-core.c | 329 ++++++++++++++++++++----- drivers/gpu/drm/rockchip/cdn-dp-core.h | 24 +- 2 files changed, 296 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index 1e27301584a4..5c0e5209d3b8 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -27,16 +27,17 @@ #include "cdn-dp-core.h" #include "cdn-dp-reg.h" =20 -static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge) +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port= *prev_port, + struct cdn_dp_port *port); + +static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge = *bridge) { - return container_of(bridge, struct cdn_dp_device, bridge); + return container_of(bridge, struct cdn_dp_bridge, bridge); } =20 -static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *enco= der) +static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge) { - struct rockchip_encoder *rkencoder =3D to_rockchip_encoder(encoder); - - return container_of(rkencoder, struct cdn_dp_device, encoder); + return bridge_to_dp_bridge(bridge)->parent; } =20 #define GRF_SOC_CON9 0x6224 @@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device= *dp, u8 *sink_count) static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp) { struct cdn_dp_port *port; - int i, lanes; + int i, lanes[MAX_PHY]; =20 for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; - lanes =3D cdn_dp_get_port_lanes(port); - if (lanes) + lanes[i] =3D cdn_dp_get_port_lanes(port); + if (!dp->next_bridge_valid) return port; } + + if (dp->next_bridge_valid) { + /* If more than one port is available, pick the last active port */ + if (dp->active_port > 0 && lanes[dp->active_port]) + return dp->port[dp->active_port]; + + /* If the last active port is not available, pick an available port in o= rder */ + for (i =3D 0; i < dp->bridge_count; i++) { + if (lanes[i]) + return dp->port[i]; + } + } + return NULL; } =20 @@ -253,12 +267,45 @@ static const struct drm_edid * cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *c= onnector) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); - const struct drm_edid *drm_edid; + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); + struct cdn_dp_port *port =3D dp->port[dp_bridge->id]; + struct cdn_dp_port *prev_port; + const struct drm_edid *drm_edid =3D NULL; + int i, ret; =20 mutex_lock(&dp->lock); + + /* More than one port is available */ + if (dp->bridge_count > 1 && !port->phy_enabled) { + for (i =3D 0; i < dp->bridge_count; i++) { + /* Another port already enable */ + if (dp->bridge_list[i] !=3D dp_bridge && dp->bridge_list[i]->enabled) + goto get_cache; + /* Find already enabled port */ + if (dp->port[i]->phy_enabled) + prev_port =3D dp->port[i]; + } + + /* Switch to current port */ + if (prev_port) { + ret =3D cdn_dp_switch_port(dp, prev_port, port); + if (ret) + goto get_cache; + } + } + drm_edid =3D drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp); + /* replace edid cache */ + if (dp->edid_cache[dp_bridge->id]) + drm_edid_free(dp->edid_cache[dp_bridge->id]); + dp->edid_cache[dp_bridge->id] =3D drm_edid_dup(drm_edid); + mutex_unlock(&dp->lock); + return drm_edid; =20 +get_cache: + drm_edid =3D drm_edid_dup(dp->edid_cache[dp_bridge->id]); + mutex_unlock(&dp->lock); return drm_edid; } =20 @@ -267,12 +314,13 @@ cdn_dp_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *display_info, const struct drm_display_mode *mode) { + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); struct cdn_dp_device *dp =3D bridge_to_dp(bridge); u32 requested, actual, rate, sink_max, source_max =3D 0; u8 lanes, bpc; =20 /* If DP is disconnected, every mode is invalid */ - if (!dp->connected) + if (!dp_bridge->connected || !dp->connected) return MODE_BAD; =20 switch (display_info->bpc) { @@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_dev= ice *dp) return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes)); } =20 +static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port= *prev_port, + struct cdn_dp_port *port) +{ + int ret; + + if (dp->active) + return 0; + + ret =3D cdn_dp_disable_phy(dp, prev_port); + if (ret) + goto out; + ret =3D cdn_dp_enable_phy(dp, port); + if (ret) + goto out; + + ret =3D cdn_dp_get_sink_capability(dp); + if (ret) { + cdn_dp_disable_phy(dp, port); + goto out; + } + + dp->active =3D true; + dp->lanes =3D port->lanes; + + if (!cdn_dp_check_link_status(dp)) { + dev_info(dp->dev, "Connected with sink; re-train link\n"); + + ret =3D cdn_dp_train_link(dp); + if (ret) { + dev_err(dp->dev, "Training link failed: %d\n", ret); + goto out; + } + + ret =3D cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE); + if (ret) { + dev_err(dp->dev, "Failed to idle video %d\n", ret); + goto out; + } + + ret =3D cdn_dp_config_video(dp); + if (ret) + dev_err(dp->dev, "Failed to configure video: %d\n", ret); + } + +out: + return ret; +} + static void cdn_dp_display_info_update(struct cdn_dp_device *dp, struct drm_display_info *display_info) { @@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_de= vice *dp, static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct = drm_atomic_state *state) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); struct drm_connector *connector; int ret, val; =20 @@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_brid= ge *bridge, struct drm_at =20 cdn_dp_display_info_update(dp, &connector->display_info); =20 - ret =3D drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.= encoder); + ret =3D drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->e= ncoder.encoder); if (ret < 0) { DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret); return; @@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_brid= ge *bridge, struct drm_at =20 mutex_lock(&dp->lock); =20 + if (dp->next_bridge_valid) + dp->active_port =3D dp_bridge->id; + ret =3D cdn_dp_enable(dp); if (ret) { DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n", @@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_brid= ge *bridge, struct drm_at goto out; } =20 + dp_bridge->enabled =3D true; out: mutex_unlock(&dp->lock); } @@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bri= dge *bridge, struct drm_at static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct= drm_atomic_state *state) { struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); int ret; =20 mutex_lock(&dp->lock); + dp_bridge->enabled =3D false; =20 if (dp->active) { ret =3D cdn_dp_disable(dp); @@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge = *bridge, return ret; } =20 +static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge, + enum drm_connector_status status) +{ + struct cdn_dp_bridge *dp_bridge =3D bridge_to_dp_bridge(bridge); + struct cdn_dp_device *dp =3D bridge_to_dp(bridge); + + dp->bridge_list[dp_bridge->id]->connected =3D status =3D=3D connector_sta= tus_connected; + schedule_work(&dp->event_work); +} + static const struct drm_bridge_funcs cdn_dp_bridge_funcs =3D { .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, @@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_func= s =3D { .atomic_disable =3D cdn_dp_bridge_atomic_disable, .mode_valid =3D cdn_dp_bridge_mode_valid, .mode_set =3D cdn_dp_bridge_mode_set, + .hpd_notify =3D cdn_dp_bridge_hpd_notify, =20 .dp_audio_prepare =3D cdn_dp_audio_prepare, .dp_audio_mute_stream =3D cdn_dp_audio_mute_stream, @@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *wo= rk) { struct cdn_dp_device *dp =3D container_of(work, struct cdn_dp_device, event_work); - int ret; + bool connected; + int i, ret; =20 mutex_lock(&dp->lock); =20 @@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *= work) =20 out: mutex_unlock(&dp->lock); - drm_bridge_hpd_notify(&dp->bridge, - dp->connected ? connector_status_connected - : connector_status_disconnected); + for (i =3D 0; i < dp->bridge_count; i++) { + connected =3D dp->connected && dp->bridge_list[i]->connected; + drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge, + connected ? connector_status_connected + : connector_status_disconnected); + } } =20 static int cdn_dp_pd_event(struct notifier_block *nb, @@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb, return NOTIFY_DONE; } =20 -static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +static int cdn_bridge_add(struct device *dev, + struct drm_bridge *bridge, + struct drm_bridge *next_bridge, + struct drm_encoder *encoder) { struct cdn_dp_device *dp =3D dev_get_drvdata(dev); - struct drm_encoder *encoder; + struct drm_device *drm_dev =3D dp->drm_dev; + struct drm_bridge *last_bridge =3D NULL; struct drm_connector *connector; - struct cdn_dp_port *port; - struct drm_device *drm_dev =3D data; - int ret, i; - - ret =3D cdn_dp_parse_dt(dp); - if (ret < 0) - return ret; - - dp->drm_dev =3D drm_dev; - dp->connected =3D false; - dp->active =3D false; - dp->active_port =3D -1; - dp->fw_loaded =3D false; - - INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); - - encoder =3D &dp->encoder.encoder; + int ret; =20 encoder->possible_crtcs =3D drm_of_find_possible_crtcs(drm_dev, dev->of_node); @@ -1002,26 +1108,38 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) =20 drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs); =20 - dp->bridge.ops =3D - DRM_BRIDGE_OP_DETECT | - DRM_BRIDGE_OP_EDID | - DRM_BRIDGE_OP_HPD | - DRM_BRIDGE_OP_DP_AUDIO; - dp->bridge.of_node =3D dp->dev->of_node; - dp->bridge.type =3D DRM_MODE_CONNECTOR_DisplayPort; - dp->bridge.hdmi_audio_dev =3D dp->dev; - dp->bridge.hdmi_audio_max_i2s_playback_channels =3D 8; - dp->bridge.hdmi_audio_spdif_playback =3D 1; - dp->bridge.hdmi_audio_dai_port =3D -1; - - ret =3D devm_drm_bridge_add(dev, &dp->bridge); + + bridge->ops =3D + DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | + DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_DP_AUDIO; + bridge->of_node =3D dp->dev->of_node; + bridge->type =3D DRM_MODE_CONNECTOR_DisplayPort; + bridge->hdmi_audio_dev =3D dp->dev; + bridge->hdmi_audio_max_i2s_playback_channels =3D 8; + bridge->hdmi_audio_spdif_playback =3D 1; + bridge->hdmi_audio_dai_port =3D -1; + + ret =3D devm_drm_bridge_add(dev, bridge); if (ret) return ret; =20 - ret =3D drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_N= O_CONNECTOR); + ret =3D drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CON= NECTOR); if (ret) return ret; =20 + if (next_bridge) { + ret =3D drm_bridge_attach(encoder, next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ret; + + last_bridge =3D next_bridge; + while (drm_bridge_get_next_bridge(last_bridge)) + last_bridge =3D drm_bridge_get_next_bridge(last_bridge); + } + connector =3D drm_bridge_connector_init(drm_dev, encoder); if (IS_ERR(connector)) { ret =3D PTR_ERR(connector); @@ -1029,8 +1147,102 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) return ret; } =20 + if (last_bridge) + connector->fwnode =3D fwnode_handle_get(of_fwnode_handle(last_bridge->of= _node)); + drm_connector_attach_encoder(connector, encoder); =20 + return 0; +} + +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp) +{ + struct device_node *np =3D dp->dev->of_node; + struct device_node *port __free(device_node) =3D of_graph_get_port_by_id(= np, 1); + struct drm_bridge *bridge; + int count =3D 0; + int ret =3D 0; + int i; + + /* If device use extcon, do not use hpd bridge */ + for (i =3D 0; i < dp->ports; i++) { + if (dp->port[i]->extcon) { + dp->bridge_count =3D 1; + return 0; + } + } + + + /* One endpoint may correspond to one next bridge. */ + for_each_of_graph_port_endpoint(port, dp_ep) { + struct device_node *next_bridge_node __free(device_node) =3D + of_graph_get_remote_port_parent(dp_ep); + + bridge =3D of_drm_find_bridge(next_bridge_node); + if (!bridge) { + ret =3D -EPROBE_DEFER; + goto out; + } + + dp->next_bridge_valid =3D true; + dp->next_bridge_list[count].bridge =3D bridge; + dp->next_bridge_list[count].parent =3D dp; + dp->next_bridge_list[count].id =3D count; + count++; + } + +out: + dp->bridge_count =3D count ? count : 1; + return ret; +} + +static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +{ + struct cdn_dp_device *dp =3D dev_get_drvdata(dev); + struct drm_bridge *bridge, *next_bridge; + struct drm_encoder *encoder; + struct cdn_dp_port *port; + struct drm_device *drm_dev =3D data; + struct cdn_dp_bridge *dp_bridge; + int ret, i; + + ret =3D cdn_dp_parse_dt(dp); + if (ret < 0) + return ret; + + ret =3D cdn_dp_parse_next_bridge_dt(dp); + if (ret) + return ret; + + dp->drm_dev =3D drm_dev; + dp->connected =3D false; + dp->active =3D false; + dp->active_port =3D -1; + dp->fw_loaded =3D false; + + for (i =3D 0; i < dp->bridge_count; i++) { + dp_bridge =3D devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge, + &cdn_dp_bridge_funcs); + if (IS_ERR(dp_bridge)) + return PTR_ERR(dp_bridge); + dp_bridge->id =3D i; + dp_bridge->parent =3D dp; + if (!dp->next_bridge_valid) + dp_bridge->connected =3D true; + dp->bridge_list[i] =3D dp_bridge; + } + + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + bridge =3D &dp->bridge_list[i]->bridge; + next_bridge =3D dp->next_bridge_list[i].bridge; + ret =3D cdn_bridge_add(dev, bridge, next_bridge, encoder); + if (ret) + return ret; + } + + INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); + for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; =20 @@ -1058,10 +1270,17 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) static void cdn_dp_unbind(struct device *dev, struct device *master, void = *data) { struct cdn_dp_device *dp =3D dev_get_drvdata(dev); - struct drm_encoder *encoder =3D &dp->encoder.encoder; + struct drm_encoder *encoder; + int i; =20 cancel_work_sync(&dp->event_work); - encoder->funcs->destroy(encoder); + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + encoder->funcs->destroy(encoder); + } + + for (i =3D 0; i < MAX_PHY; i++) + drm_edid_free(dp->edid_cache[i]); =20 pm_runtime_disable(dev); if (dp->fw_loaded) @@ -1112,10 +1331,10 @@ static int cdn_dp_probe(struct platform_device *pde= v) int ret; int i; =20 - dp =3D devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge, - &cdn_dp_bridge_funcs); - if (IS_ERR(dp)) - return PTR_ERR(dp); + dp =3D devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + dp->dev =3D dev; =20 match =3D of_match_node(cdn_dp_dt_ids, pdev->dev.of_node); diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockc= hip/cdn-dp-core.h index e9c30b9fd543..ce1707a5c746 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h @@ -38,6 +38,8 @@ enum vic_pxl_encoding_format { Y_ONLY =3D 0x10, }; =20 +struct cdn_dp_device; + struct video_info { bool h_sync_polarity; bool v_sync_polarity; @@ -63,16 +65,34 @@ struct cdn_dp_port { u8 id; }; =20 +struct cdn_dp_bridge { + struct cdn_dp_device *parent; + struct drm_bridge bridge; + struct rockchip_encoder encoder; + bool connected; + bool enabled; + int id; +}; + +struct cdn_dp_next_bridge { + struct cdn_dp_device *parent; + struct drm_bridge *bridge; + int id; +}; + struct cdn_dp_device { struct device *dev; struct drm_device *drm_dev; - struct drm_bridge bridge; - struct rockchip_encoder encoder; + int bridge_count; + struct cdn_dp_bridge *bridge_list[MAX_PHY]; + struct cdn_dp_next_bridge next_bridge_list[MAX_PHY]; + const struct drm_edid *edid_cache[MAX_PHY]; struct drm_display_mode mode; struct platform_device *audio_pdev; struct work_struct event_work; =20 struct mutex lock; + bool next_bridge_valid; bool connected; bool active; bool suspended; --=20 2.49.0 From nobody Sat Feb 7 18:16:07 2026 Received: from smtpbgsg1.qq.com (smtpbgsg1.qq.com [54.254.200.92]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 136F1227563; Thu, 16 Oct 2025 02:28:54 +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=1760581738; cv=none; b=NMzaNP4FqCqEcCi1r3KxOuXGmZ+xrCw445nC7tQ46Ql45J5s4x/XtcpfflGdXEJPDP29/C8SERoWfasz27c2HJq8XEIBGeDdiyYjnZ2lgy78OBV5ShkGBZicwpFn1N/5V2qtfQgwOCFn2sPSNUp0Ps4OASMBKRGFYV5G2VOLpwU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581738; c=relaxed/simple; bh=3OiqcRrs7DLfC1hTPje6cpCre8EW3o9TnIIexoI2iuY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Trl11AV5ws/SdGjuHVNtQXukyTVGNjOD02z8H+wmxZBkBCxX0L2RjikSJG+icAkG4Jx5Q60/afHmjg2Oj6LjDTHDsqnRdi0Z8pkgAJYmsoEUDqLtCCZ68ZSmDxYeHt+G+Rg365UnKj7Q/+jf3BeDrQobZTQrNiTkNAEDADW8iDE= 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=oKKTeL2s; 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="oKKTeL2s" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581705; bh=cDiOxEFqYuonRjIga1t9o2u02p12TN3hXALWFcjKD9c=; h=From:To:Subject:Date:Message-Id; b=oKKTeL2sZnJ/Ra/KO+JjtpEeovUL9rnSUI9xNdOU7MXVLO+02xrqkYfqglXFiuye9 plGCwzspO5dTpRr/XFyPeBfxLTMrRavjxJiEXgwbR5F9J6osU18irF3J8+odbwQnlX p/ZaIGb1UlhwQdARY4WYIAhfvNYGPY8YJ/jAghH0= X-QQ-mid: zesmtpgz1t1760581704t48b93ab9 X-QQ-Originating-IP: jspWVOP8OQq1eMaljl9zTAS2LWtC6NlYZsKyhlsXums= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:21 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 14690965305072094161 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 7/8] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP Date: Thu, 16 Oct 2025 10:27:40 +0800 Message-Id: <20251016022741.91-8-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NvH2zBBgt3uT9PzPxFcjF3BkEwQclaeJHAX6xV1xiqe0SjTx4fFeWK1M M7zsCeSt6x+bbc0envVq3xGYBCBbWKHxqLxtorjJHb1C9UPgZaPjTYOdcA/yiulDv3PiXVB q80ytDfdtcHqbS0ghStldGmkwbpGS5ui1cQWMcjo00lYLtMoFqD6S4Go7Y+Fkb2JjVnJzPL UWDvB+vUP33cPYwpfuqa7xYzC81U2p+sMZPGayzQPHfMlRUpCIuhBWrgOQfMTiFueBsGuBV 7MjerWqSEEohbfa/swTwgVnqGoiyezcUYpf2sz0qad1wr8IpFufHBpcUCMdMca4iCHjDc+I WKcYqGsJ/+PipZDWBv2sBaZANPvcuB286muAzacWF2JTVoLOptY2C9jTi4EQni1RL//Smaq /VKDcjAVpL/F31LGKYwbb0J0n5tMs1tKHGBui3yhLL1o52aZZLQBMz1LAnskXakidQa01ci FaP/StCaqr6kFP3fkysMo/P1ZhUbcsZg7UwM64eQbxaCXPB5N5OrWXiTaeNGgvTd6nEfAVy gl6kFo4Z7QcRgUPfXW5FIwLxOldvZ3GcnmX8LenlCJHNH5IluYdZJazf0u1cpC4mEFOLv+w Kf0jYUMKrHYdzPIg6wvxVF4bPJ1gOr+j5+m9EXp/3kIE1o3emBCX2d6llWKiMFRvSPZazIO gqZyYLmNz7DfLqSc9dUHlonqWJhDdafsikhYeOPh+DYS7FV/XWM5ePTu4JtPVu5eNIsQ1ir xShy87+HRWgSqmIB/sav7WBDhPMktrU2VHvELEYTpi+ZOcwW4Lk0sYcDG9Yv2tRt1uMCJXM RmtMp8myYvMgoMOFi8MztMu55a2x6VO573D86obdc7XO+oYLsbDo9tuVQa5nlj3Bh5BpwCi fP7ovVfvm3POfBGWDI96XQXSL2IYJGKTWXfLJo5vIPKoalsUHswO0u15iI9WTJTSDqMZ6di 4s6R1c7BAfSQn+SnxvSBBtL+UeFN/i7fDI8xPPh5DBLE/9/0lz0AsPorDq6Fd1JRZ6v78VK G+osvW6HHqjnco+R+cOofoOHSBqrbJbqsYOUjCEw== 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 Let's make the ports nodes of cdn_dp in the same style as the other display interface, and match the style of ports's yaml. Signed-off-by: Chaoyi Chen --- (no changes since v5) Changes in v4: - Remove unnecessary #address/#size-cells (no changes since v1) arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boo= t/dts/rockchip/rk3399-base.dtsi index 4dcceb9136b7..93b42820998f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi @@ -618,7 +618,11 @@ cdn_dp: dp@fec00000 { status =3D "disabled"; =20 ports { - dp_in: port { + #address-cells =3D <1>; + #size-cells =3D <0>; + + dp_in: port@0 { + reg =3D <0>; #address-cells =3D <1>; #size-cells =3D <0>; =20 @@ -632,6 +636,10 @@ dp_in_vopl: endpoint@1 { remote-endpoint =3D <&vopl_out_dp>; }; }; + + dp_out: port@1 { + reg =3D <1>; + }; }; }; =20 --=20 2.49.0 From nobody Sat Feb 7 18:16:07 2026 Received: from smtpbgeu1.qq.com (smtpbgeu1.qq.com [52.59.177.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD60D223DE7; Thu, 16 Oct 2025 02:28:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.59.177.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581735; cv=none; b=J1zrPa9fkZilSg2zTNoM6VtEnuC9zYp9WlotamzHHmGEqcCz4uKCOL/4ip24rBKqk6DAVkUwX+zG9bT++cWgKH5h1C6ULiBhrQ6gKW1tSV+ZBRpl8qcCgfOZXWvLemoaFLh2nOYGSXDklhifhVVGLNbi2FpK+hOGTzC4wMv4Wec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760581735; c=relaxed/simple; bh=Ksu1m13XDgyOSNrC/yix/S/ref0aCyYvyb9gG5K8i98=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=EejwR4vXUqU/8hDyAbm7SX9BQn1XRLpuy5XLvRdGegi76f3zwswwQm0XRuJO7N3JZNTwXID8HfDiM502dwoIrv50Uq6vwNwAPEskwMAD1714vOXlW37EOkaoMVDHGzg1DU1meo8jZhi6vFnkkkfeSZ+9mUwggR4Vvtq+B7UREZo= 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=ePMMocVh; arc=none smtp.client-ip=52.59.177.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="ePMMocVh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1760581708; bh=1RfAR5qe3fDpGYWfe4IMPee9wlWopj1wjBrVtJQSHJQ=; h=From:To:Subject:Date:Message-Id; b=ePMMocVhYpf+bx3EtPyKWKKIVsXxiiUO8q88h8aMWMd16ANKKXzCy0KDnWXQfU+EZ UPnXNEZ2Pe5GGjqVpd3dANfKLy2NEMKIeWCGx107PFH9q3WJqaP6qXnAUVjVrO1DCr wjuy7gCEyAhpkpnwEeAeLhzqF8V/CE7YwvB0uZdc= X-QQ-mid: zesmtpgz1t1760581707te7834fa0 X-QQ-Originating-IP: fu4+9mqDE3XZAMSCh/z+SENLWrlcpaz7T3n6vsQJy5o= Received: from DESKTOP-8BT1A2O.localdomain ( [58.22.7.114]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 16 Oct 2025 10:28:25 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 18195829153663395563 From: Chaoyi Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Vinod Koul , Kishon Vijay Abraham I , Heiko Stuebner , Sandy Huang , Andy Yan , Yubing Zhang , Frank Wang , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Amit Sunil Dhamne , Heikki Krogerus , Greg Kroah-Hartman , Chaoyi Chen , Dragan Simic , Johan Jonker , Diederik de Haas , Dmitry Baryshkov , 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 v6 8/8] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort Date: Thu, 16 Oct 2025 10:27:41 +0800 Message-Id: <20251016022741.91-9-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20251016022741.91-1-kernel@airkyi.com> References: <20251016022741.91-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpgz:airkyi.com:qybglogicsvrsz:qybglogicsvrsz4a-0 X-QQ-XMAILINFO: NyTsQ4JOu2J27F0cQTRa45Ef9+r4ktGvtzz8BSBcGwlKmK4bUQ9BqOKr 7lnp5y6VNi9cvAsawFfhIjGqtlpWOw4TKTT/T53Xe8aGFka1FxZpFl6XiKzEarnSUCLaQPD Wwe25p4lploE0MGXVBg6ilyEJwse/GLHWNA3lYjXg37lPbP9WjkzvKua/TO08t5c8yb1Elu WzIWnEk/ii2oR0uzll54wldD/1iDQ5rQyOwLoULrS1AKcEeKpCTmePCcSfw38amlPDRxMVX 7N9KxDFQzG1P545BiN1p40hZNFuKaSslQycZVPXm7UfxNRTtnTFczVQmxRuG2JpbAVCOMCg uBZpS1n93kQ/5S90YxD/oAE4C0uUW+/Y0mt5fWsG+KyGdh1JrUrt+TyYwbbVSnfuAJC6LpO KzG0U0Y2gaa7Zqsqlaoe4QBUvkQLs65kyHVGmHr/kYHphMSjfkFyWKGmk1/OKChOeP4j25D Gjcfn/3FI/QvC82lQfvp9x62k1yRxo+JW5ob8CbratMkkUtHgWIC1Y7ImHi8EzYk91LKi+q v+TqUBXYICoPERWdG7DpVhqs6cbktXkgnqEbh1iDLLx3mif/jG8lSz8RGgZrW//goj0RooQ hxjakLofksce+yOUZilYPOBB92zTu0UeLr09eWpb7Lfi7X3IKyQH0gt5ukcxaH8T332l3Tr Pz2cl9e46C0xAf8wZqXAB0NIXsSbbHxtllkNtRUBVPopuKkhGs6zh7H1HjHGi33kkmjpNc8 NuI5Yzqe1AeylddJV7e79SKZN9aInTl1ucpbkTbsW6edQsb5guKWLWbtXGn5QYqnNIFX7jE 9heikYT0QHnWf0svJ7CyW3oNqFtkVeMTIy92OAxTw17dKJ3zVJ3TNbrbzmHrgBZdjT5smOa 50vivkbEGVoo6af53yl4XQLT1cO2ANhxM8mMciCRbkYCiYwCofzlY0bRxiWRwJqMZKqbJZP ivV7C79a85fWPFftKkijCTtpD++imtzRLO55hXZMBM25dU5xIVC6RQI4/UewQfIQtx1NgnD ldAPF7G1t93eAxttixuR5JSMhTVo/if0wFnptew8hiBPPGrr58 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 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