From nobody Fri Oct 2 06:57:44 2026 Received: from smtpbguseast1.qq.com (smtpbguseast1.qq.com [54.204.34.129]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68F8E3F211A for ; Tue, 4 Aug 2026 07:08:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.204.34.129 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827300; cv=none; b=uxNma764a8qP4GM354NISogGfSn94JddLLGDVlmKW9wF5rQ281SKmshGkgq00/ajCQ6iP4n0mUdUjkaAwlXeGewPUwH5PCf4CjqBJmUf7zz3L8Vo274JdDy62QvT9gU5FFm8xP5+DsdNg6LldSPQZUq+OCc8ZKe+Ejs0XSJmv58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827300; c=relaxed/simple; bh=dt1yYLhIWfjIc/65Ejosz8UrCO86llS84fUjglXJcTY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Lc7brUYIXrdABAxLE1An6Vojx0SoNO3VBrmDtbAoE2y2ri3Chb8zpTotYbheaQczKqhDGo4Oz0mJAt6F3DilLurKyYotFNUXS8U7RaZJKElybjThp+RB4pQV6BZEjIVjF96g5RxOqr4k51bB7LrWOaBN44mQ9a7k6BTiGgK0WHs= 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=cJfvn0qQ; arc=none smtp.client-ip=54.204.34.129 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="cJfvn0qQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1785827278; bh=amLbFrLgaWKdM6iuB7UHZh23ZJ9tGg/UXF/7lGM7lOI=; h=From:To:Subject:Date:Message-Id; b=cJfvn0qQqgJwLba+6SZoAjhEyHrabgBrxCfRCFjnC2X6xNZvCa3ZK9fODfnDkcdEP 3NR7IKdZBa/Q37jda7reVULXaYisQ0JY6GKlFQ0KHNOhoiY6cCXv9HQ9kUx6F350Yb 3GJ6PEdvYa4bhC7MYSW4OmIovpUbS1GTTwwcOXng= X-QQ-mid: esmtpsz19t1785827277tf63c1686 X-QQ-Originating-IP: n7cCnMgNG0f8iJN7ZfLIqZBWbzE4V65U0d+YdsMycP4= Received: from DESKTOP-8BT1A2O.localdomain ( [61.154.14.86]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 04 Aug 2026 15:07:54 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 13234408375334642489 From: Chaoyi Chen To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Vinod Koul , Chaoyi Chen , Sebastian Reichel , Nicolas Frattaroli , Heikki Krogerus Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v6 1/7] drm/bridge: aux-hpd-bridge: Add drm_dev_has_dp_hpd_bridge() Date: Tue, 4 Aug 2026 15:07:24 +0800 Message-Id: <20260804070730.68-2-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260804070730.68-1-kernel@airkyi.com> References: <20260804070730.68-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: OGvgEoGelOUdnQDqmpVkzPPIpZGxg0gBgEjIiDVod56HxjXzSKhuJwtJ Oj7WvJdiQQbxbc1hntvZhz2f801NZ2Xf0NhURig5Xp9vNXUGIKDbysD2J0kL6YZOH59HFyu iut/vtti8fTK7WkKjFDbhsxToQuY6Xu/RV4alQP/QX1WPg5CI93HXdqH/tlXHakkDz3vllN 2avJ3KvAnU09ODQZJ0/1TP6Jz9+Q7ya8AfTxqkQJ7jpq22aztQhRU5yV4Ii79fVWbpMrU9r rX3tadVBPgCHADXvqUaEnbUnH7Xtm3DX4LTYImZQ+AUqblNEQnVpauceoktPeI4TWNK4hoW z7JFaoePCsM3u4s3utHErDX81bWmgMHhpFxEN7IjvHAj8AlXG5uOfBksJdWpwF6L3BxwqrH 46YDtDNsVtPL1QXpGxKNK6aNhOG7VoxavjuN2uJ2bVqf6ZjqJaAvFsO3AsKMiJq8XHgISJ/ 5cnW4IITqq1bPWmBVO/LnnQaUg1mn1kgdQuPShpfUFH0WhVKP/0w29hFqvzV4zWFtFkvP54 56vf8tnB/ciO0YiDKW4/QZ/HWLLNeF95vNayO4tzP+u6U8xb2SOD8DYm0L7aLNX3NGSo2S9 y7HG2NJgcyAshVqaZaoWO0rO55t+KyZWaG3wCy6teVeJ/euWEXLMC+lx+gk9noaFAVjfWZk VjQzcCcUbELQXEUGlqIiMu83AXCpMsamhYXTsdmmsUM9dKi/1d5TkP8+3x+Ny0Nyj56Bjmz i2HZyJMcvasKQwpnEhOn2UkA/5Qjv2jbhQ4LKCOE/Zs0vpxeBD+jiysPPy78iEMct7xVI/U m5ng6W6eWEGsektDRvAqzTmKa7jZvT/bVbgz3qYU64wHAxMh2hl/+DfUF2MOtD3sqKJc7Vm QRcRH8Ml0F6gCFtUeW79NaSqZQC75FHjKh1Nlw/LezDbNZB9UwKWvM31OplMn9G2QYsAmGN niDuGTZ0mjnAqBJyRYkmwp88D9cIA0ciX1jHSjL6rxhIWjSJuIfNbO4MA8cC/lEgdZnVCpr y/zpEDWnuQSvqukwg1XdBdy24LE+I= X-QQ-XMRINFO: NS+P29fieYNwqS3WCnRCOn9D1NpZuCnCRA== 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 a new API to check whether a DisplayPort HPD bridge has already been registered. This helps avoid duplicate registration of the same HPD bridge, although the current framework allows doing so. Suggested-by: Sebastian Reichel Signed-off-by: Chaoyi Chen Reviewed-by: Sebastian Reichel Tested-by: Sebastian Reichel --- drivers/gpu/drm/bridge/aux-hpd-bridge.c | 42 ++++++++++++++++++++++++- include/drm/bridge/aux-bridge.h | 6 ++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/brid= ge/aux-hpd-bridge.c index f02a38a2638a..a56c88eba005 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 +#define DRM_AUX_HPD_BRIDGE_NAME "dp_hpd_bridge" + static DEFINE_IDA(drm_aux_hpd_bridge_ida); =20 struct drm_aux_hpd_bridge_data { @@ -36,6 +38,44 @@ static void drm_aux_hpd_bridge_free_adev(void *_adev) auxiliary_device_uninit(_adev); } =20 +static int hpd_bridge_match(struct device *dev, const void *data) +{ + const struct device_node *np =3D data; + struct auxiliary_device *adev; + + if (!dev_is_auxiliary(dev)) + return 0; + + adev =3D to_auxiliary_dev(dev); + if (strcmp(adev->name, DRM_AUX_HPD_BRIDGE_NAME)) + return 0; + + return adev->dev.platform_data =3D=3D np; +} + +/** + * drm_dev_has_dp_hpd_bridge - check whether a HPD DisplayPort bridge is r= egistered + * @parent: device instance providing this bridge + * @np: device node pointer corresponding to this bridge instance + * + * Walk the children of @parent and check whether a HPD DisplayPort bridge= for + * the given @np has already been registered via devm_drm_dp_hpd_bridge_ad= d(). + * + * Return: true if a HPD bridge for @parent / @np already exists, false ot= herwise + */ +bool drm_dev_has_dp_hpd_bridge(struct device *parent, struct device_node *= np) +{ + struct device *child; + + child =3D device_find_child(parent, np, hpd_bridge_match); + if (child) { + put_device(child); + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(drm_dev_has_dp_hpd_bridge); + /** * devm_drm_dp_hpd_bridge_alloc - allocate a HPD DisplayPort bridge * @parent: device instance providing this bridge @@ -63,7 +103,7 @@ struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(st= ruct device *parent, str } =20 adev->id =3D ret; - adev->name =3D "dp_hpd_bridge"; + adev->name =3D DRM_AUX_HPD_BRIDGE_NAME; adev->dev.parent =3D parent; adev->dev.release =3D drm_aux_hpd_bridge_release; adev->dev.platform_data =3D of_node_get(np); diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridg= e.h index c2f5a855512f..cca07a8e2d45 100644 --- a/include/drm/bridge/aux-bridge.h +++ b/include/drm/bridge/aux-bridge.h @@ -25,6 +25,7 @@ struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(str= uct device *parent, str int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device= *adev); struct device *drm_dp_hpd_bridge_register(struct device *parent, struct device_node *np); +bool drm_dev_has_dp_hpd_bridge(struct device *parent, struct device_node *= np); void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_stat= us status); #else static inline struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct= device *parent, @@ -44,6 +45,11 @@ static inline struct device *drm_dp_hpd_bridge_register(= struct device *parent, return NULL; } =20 +static inline bool drm_dev_has_dp_hpd_bridge(struct device *parent, struct= device_node *np) +{ + return false; +} + static inline void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_= connector_status status) { } --=20 2.53.0 From nobody Fri Oct 2 06:57:44 2026 Received: from smtpbguseast2.qq.com (smtpbguseast2.qq.com [54.204.34.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E15A542049C for ; Tue, 4 Aug 2026 07:08:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.204.34.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827304; cv=none; b=qW2hi9ArgZP789jm3r3MmHUiNgOfmxdnfzQQvMnuQ0/LXJHwKbDBVfdO9ItAMkZQ8S1eKfPYYydHe7jeTN7X02/IiMmZZJNOgZ9uYdmeS2Cf6VRFflTPs5jWkDVeJ3zITUET57DdZmPvfx0Bpf7hRdxIAaThSlroOQj7gc+sOBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827304; c=relaxed/simple; bh=K/757+Xj0f49RBIji9eGvyrhKhuwaqAYgLFSnBCNHpI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=cjFFCFBIW64ib9tOy35FlDXh77yPvOGDgsfdbGfdT+BlieIZMLFw1AkI0cbgY8dgJvHnWa8KyElc+QjGCloD5F+t0WuCmKeadSg1o/dZNWVX/mA5n11wNIcbyzZvbUGs7crigATMBq2/jvRnSq5PMkQugLKfKLxJiNy2g64jWUw= 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=MY4uZyhS; arc=none smtp.client-ip=54.204.34.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="MY4uZyhS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1785827283; bh=fH6u5h4xpDz1C8ZdGsVLKRX5KFIbcVXaaz97fyPxnmA=; h=From:To:Subject:Date:Message-Id; b=MY4uZyhSi0TWs9wHY7ElZgdIRNi+oTTYdxvP4wULKub1RCvUu9Vq3YlGTWUJBHfz0 5VvG7zFNCjT4gOZV4/yCg5CID/81+gl+6PBJ6ULfu1AaMgBEwnwqPKfYd5tnvRg74j jz0cbtw4haW5KiiBs2mAh76AGyTIg0JscpFaGAt8= X-QQ-mid: esmtpsz19t1785827282t0f0d09eb X-QQ-Originating-IP: UacgRZcbWfS4e/DkD9DWOSe5Fguk5twcxO1gmhIpdfM= Received: from DESKTOP-8BT1A2O.localdomain ( [61.154.14.86]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 04 Aug 2026 15:07:58 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 1834984709830205392 From: Chaoyi Chen To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Vinod Koul , Chaoyi Chen , Sebastian Reichel , Nicolas Frattaroli , Heikki Krogerus Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v6 2/7] drm/bridge: Implement generic USB Type-C DP HPD bridge Date: Tue, 4 Aug 2026 15:07:25 +0800 Message-Id: <20260804070730.68-3-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260804070730.68-1-kernel@airkyi.com> References: <20260804070730.68-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NRLj+a+1JRyJfsg4lbGBEPFbqVZcVfOunMNL29MAr9VNNLXA5jHkmjey z5N06wXoDOpIp5jQqhYvDXNHe+kdyx2WRIQXN/ST0fCQozkwxvpxSjf4R4oUFrSzcU7qoEC 3jCEKc/py9ZwkFDggWuGENqJzA8cguCLEvHvE7LA1XeSKU6ZYnE27mWxCCFIqD/oDP3SIPi ED8s/PvibD8SoYRVfDKv0yI4Z+uDTS2BUMQxqIWiU7yuFg5D7f+jZb3jnFDkS4ML+rR6TQ1 KzgeF0x1EQVa8lKp6iCOlEjE3bw+T9IBoUyn0lBh50z5D8I8PgbJkAYAzAeGWrO7HRRhRMf dx/6QB54YvhRJWhMEslIi9fOqksakhGP6m5HEdVPdn8pBmM6wtEWivrSiT8NMvFXoB2T5MK LffAmEhsPalGUOYICE+R+OoJ66MVTRnf6F7L3eD86diB8KMyEzn09SyaRhcMgtVe0YPjHrf spPeTSj0Slzl5aRpSr33ToLjv33f1Y5NOxX6GbsfAq/oNLsBFK5E7QggTMmXkeMAm9tUKpO GEWFp+iPgzgxK+BMMci3TQYwIFqL5YhoUAr3Ope9xcbwjLIGYVXJA6ZAAN5Q7uznXjIAiOv pYa5nrUb0hXSUZU5yFcNQL8c77OKByK+4yKWBMyxHH7zzdWlh17T38lwfSM0HcYdgD/Elif Kj3WhpxVZyNQWUShfvNPocW4jK0ds/wTn9jLATbUi6laI6zJX7Z8Hc7MtGKEXR4tFGEFnWe VxF5HUh7M2LNlwNnoA3O1uR0aHYPTiMqDMyBXN0xexlUIteA7ONZyumJSd3ASAl0UaOhqdi 3IIWliDcMxe12qzqK/78cG7xpJsnlK/BFO/7t5ckISxhJClKome192m+/AbShJLg9OCO6u5 5GSvij76+F1HwRqlMfCdNljZnYRDm6r1vGlUaEtMOf1smk3BSZ/XeYnsbUyrV88IVO/CYQZ dqMfZhv/ycIZjsluSNFmWZGPtgdzol8tbGpNmNN82Td506HBj9WegEd0eMznxW+4ZU2b/NY b05Uhpqj9DcBFZSD0QqviZ60/iYoxQZec7M2kmWc1+UN5MVBNUuHdEcg6467U= X-QQ-XMRINFO: NS+P29fieYNwqS3WCnRCOn9D1NpZuCnCRA== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The HPD function of Type-C DP is implemented through drm_connector_oob_hotplug_event(). For embedded DP, it is required that the DRM connector fwnode corresponds to the Type-C port fwnode. To describe the relationship between the DP controller and the Type-C port device, we usually using drm_bridge to build a bridge chain. Now several USB-C controller drivers have already implemented the DP HPD bridge function provided by aux-hpd-bridge.c, it will build a DP HPD bridge on USB-C connector port device. But this requires the USB-C controller driver to manually register the HPD bridge. If the driver does not implement this feature, the bridge will not be create. So this patch implements a generic DP HPD bridge based on aux-hpd-bridge.c. It will monitor Type-C bus events, and when a Type-C port device containing the DP svid is registered, it will create an HPD bridge for it without the need for the USB-C controller driver to implement it. Signed-off-by: Chaoyi Chen Reviewed-by: Heikki Krogerus Reviewed-by: Nicolas Frattaroli Reviewed-by: Sebastian Reichel Tested-by: Sebastian Reichel --- Changes in v6: - Avoid duplicate registration of the same DisplayPort HPD bridge.=20 (no changes since v5) Changes in v4: - Scan the entire typec_bus and attempt to register the hpd bridge, so as not to miss devices that were already added during initialization. (no changes since v3) Changes in v2: - Add copyright text. - Remove useless goto. --- drivers/gpu/drm/bridge/Kconfig | 10 +++ drivers/gpu/drm/bridge/Makefile | 1 + .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c | 67 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 4a57d49b4c6d..9739b2a19758 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE Simple bridge that terminates the bridge chain and provides HPD support. =20 +if DRM_AUX_HPD_BRIDGE +config DRM_AUX_HPD_TYPEC_BRIDGE + tristate + depends on TYPEC || !TYPEC + default TYPEC + help + Simple bridge that terminates the bridge chain and provides HPD + support. It build bridge on each USB-C connector device node. +endif + menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE =20 diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makef= ile index 15cc821d85b7..d88a9e1ccc9a 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_AUX_BRIDGE) +=3D aux-bridge.o obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) +=3D aux-hpd-bridge.o +obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) +=3D aux-hpd-typec-dp-bridge.o obj-$(CONFIG_DRM_CHIPONE_ICN6211) +=3D chipone-icn6211.o obj-$(CONFIG_DRM_CHRONTEL_CH7033) +=3D chrontel-ch7033.o obj-$(CONFIG_DRM_CROS_EC_ANX7688) +=3D cros-ec-anx7688.o diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu= /drm/bridge/aux-hpd-typec-dp-bridge.c new file mode 100644 index 000000000000..682bc192e093 --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2026 Rockchip Electronics Co., Ltd. + * + * Author: Chaoyi Chen + */ +#include +#include +#include + +#include + +static int drm_typec_bus_event(struct notifier_block *nb, unsigned long ac= tion, + void *data) +{ + struct device *dev =3D (struct device *)data; + struct typec_altmode *alt =3D to_typec_altmode(dev); + struct device_node *np; + + if (action !=3D BUS_NOTIFY_ADD_DEVICE) + return NOTIFY_OK; + + /* + * alt->dev.parent->parent : USB-C controller device + * alt->dev.parent : USB-C connector device + */ + if (is_typec_port_altmode(&alt->dev) && alt->svid =3D=3D USB_TYPEC_DP_SID= ) { + np =3D to_of_node(alt->dev.parent->fwnode); + if (!drm_dev_has_dp_hpd_bridge(alt->dev.parent->parent, np)) + drm_dp_hpd_bridge_register(alt->dev.parent->parent, np); + } + + return NOTIFY_OK; +} + +static struct notifier_block drm_typec_event_nb =3D { + .notifier_call =3D drm_typec_bus_event, +}; + +static int check_device_already_added(struct device *dev, void *data) +{ + drm_typec_bus_event(NULL, BUS_NOTIFY_ADD_DEVICE, dev); + return 0; +} + +static void drm_aux_hpd_typec_dp_bridge_module_exit(void) +{ + bus_unregister_notifier(&typec_bus, &drm_typec_event_nb); +} + +static int __init drm_aux_hpd_typec_dp_bridge_module_init(void) +{ + bus_register_notifier(&typec_bus, &drm_typec_event_nb); + /* + * Before module initialization, some devices may have already been added. + * Register the HPD bridge for these devices. + */ + bus_for_each_dev(&typec_bus, NULL, NULL, check_device_already_added); + return 0; +} + +module_init(drm_aux_hpd_typec_dp_bridge_module_init); +module_exit(drm_aux_hpd_typec_dp_bridge_module_exit); + +MODULE_AUTHOR("Chaoyi Chen "); +MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE"); +MODULE_LICENSE("GPL"); --=20 2.53.0 From nobody Fri Oct 2 06:57:44 2026 Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A28B441F353 for ; Tue, 4 Aug 2026 07:08:30 +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=1785827313; cv=none; b=ks+4dyLrZbngJoB6IIXAtec50AlVa4O3VDZWqq7L3sxp+j8kbYRLaywJZVdhoomzDPc04PUZcZdvVf5feX+gSVFG+QkD9JBFAdIJGPknnPjb7e9a8FbDA1b3sG7aipbWcvhyjSWrxOmflagWLPOu+qOj4PD3imA5SephiKPDpK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827313; c=relaxed/simple; bh=fCVWU7i4rDVgNm+uZ4PBuTAcJDR74k416hV7GI9INCU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=kO9YyBfD8cMt7z75AvBKhXm1o5XMk1gIfZ4BpJhDr3uy6oBGKdbk4N0fJYWSNlZJk22ll+Jg6i0CxT68MTDbhkhACcHKsfzYO7KapYUAfpEO0cNG6KreZoJdf3G2N/PHiDHJddhs/6/tL+xipDvXT2TNQnBLfVprD9HLPnBpeDI= 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=HXYitIg4; 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="HXYitIg4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1785827288; bh=5OdXdwVkKMvJZy3PJIdUzTFPS2ew2EOKKVLqSbTuvnI=; h=From:To:Subject:Date:Message-Id; b=HXYitIg4ObA3mlKbV4rZfOOv1Mf64c1lJucrMK06U+2BnA8DbqZlmPqUGtk5FFsbx E60P4QEuiUgCx76NR0Qx3NW/5F3j2wGpIbmKMCjXU+TZhDfgJ3pNc5wd9dU88kzVAZ bjs8yWb0gNR2YoyqgEXS0KpJhWMhStEQjyxjZYEA= X-QQ-mid: esmtpsz19t1785827286te761e50b X-QQ-Originating-IP: jAGfl1lILVxOAP7hFzihW/Tj4azNJ1oZJNnSI76z3b4= Received: from DESKTOP-8BT1A2O.localdomain ( [61.154.14.86]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 04 Aug 2026 15:08:03 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 16862773005327173646 From: Chaoyi Chen To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Vinod Koul , Chaoyi Chen , Sebastian Reichel , Nicolas Frattaroli , Heikki Krogerus Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v6 3/7] drm/display: Add soft depend for aux-hpd-typec-dp-bridge module Date: Tue, 4 Aug 2026 15:07:26 +0800 Message-Id: <20260804070730.68-4-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260804070730.68-1-kernel@airkyi.com> References: <20260804070730.68-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NTNLxPxYD/4IMIezCCOpbytIezHtDQAnJIHMNdbLMnotsrfl2z/3pcu5 Wlqbkbt6E/ynxh9o1aqw9N9crmYhDAQUp7V7U5ntJyf5GBF9auKzFf24Lj+VqmW1/Q0fAiP k4a38LDbmS9roqci8siRdKwY8t2UvM5zDTZ6LFs9ImAbQ43/fxentDIsPU1cDToUmYhkgt1 q4GPt6B9feGp/S4rQKwIgSPBmVcJBIDprho0agGmUya3U8bvithPtJJ+V+WHbwhQXlm9AAg YRV2xxHpkXfF4LPWLuFw3RtJwfhotG4lpPVpueYLYyeq9D8fjIkv6YIMbQ2qRqhcyuD055Q j43WvQBUTd1MP9MYApxIQ4761zi6C1Pc3D7ViO4BDpFy00VNnaKQz/Iczv9xeUq/m1u3soG rXX+g1wewX3UMjHBT4VlYUfAS6P42o5xSEaW1Du/FNVKdsQ43CksXldKdgcIbhiRO2mB40N biWPSmcpRZslrWubuZVcgV3NyXQxfERYrwfFIjMDIv0LKmOS16VgK4D8NO8if+VlH8zMDNR TkciWxL7B9HPyiwvgtF5JnbZl8ooLuXbFw6tQDuzEi3Nkb/C4xQOwnk/vonMDofWDmyEyPy ID5n++btTPWO0uNEogKU8I9Ue4p8TMf1q4g7/Pp6xdr1j3eS/J70UHBmuPXiK1Vj85jUqN4 INrxkDkaE5XczQmSimlXt/AeHs1+6+UO7k3CY8i5fvCw3LSyEOmCv+QgAggVt+nLG8KF34y HEbRCOcivoU6WbrNMOUVRWYMD+2lxCYD2qRqcFoEJFwjQ9DwQgzUbb1iBvDEi6m+yH7yCSi M7D+4IPllvXFwiBkiw2NY/jc6iUY2ejlMMrknSbktHLqTvWF60DPLOSR3IBoHMG+Tvm9/NY BcIFRhQgzJzJRNge/ZqPA4txEXW+p0uSDTpc+EvP+cAA7PWhaPuvFBf+E+sI6/N4XMuHod7 DRk2YIW7YEK16rZ0KFn8Xw+HO9HQlGgPOkXFj7IL8zCC7s43uiqhPRBi7plKHoYt4nA6Hie N7bumJUQ== X-QQ-XMRINFO: NyFYKkN4Ny6FuXrnB5Ye7Aabb3ujjtK+gg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The aux-hpd-typec-dp-bridge module serves as a generic TypeC DisplayPort HPD bridge and is not required by any other module. Therefore, it will not be auto-loaded. Given that the drm_display_helper module houses DisplayPort-related helper code, add a MODULE_SOFTDEP() within it to suggest loading the aux-hpd-typec-dp-bridge module beforehand. Suggested-by: Sebastian Reichel Signed-off-by: Chaoyi Chen Reviewed-by: Sebastian Reichel Tested-by: Sebastian Reichel --- (no changes since v6) --- drivers/gpu/drm/display/drm_display_helper_mod.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/display/drm_display_helper_mod.c b/drivers/gpu= /drm/display/drm_display_helper_mod.c index d8a6e6228773..f0152d6b0b2d 100644 --- a/drivers/gpu/drm/display/drm_display_helper_mod.c +++ b/drivers/gpu/drm/display/drm_display_helper_mod.c @@ -18,5 +18,6 @@ static void __exit drm_display_helper_module_exit(void) drm_dp_aux_dev_exit(); } =20 +MODULE_SOFTDEP("pre: aux-hpd-typec-dp-bridge"); module_init(drm_display_helper_module_init); module_exit(drm_display_helper_module_exit); --=20 2.53.0 From nobody Fri Oct 2 06:57:44 2026 Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EBD0741E6A7 for ; Tue, 4 Aug 2026 07:08:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.243.244.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827312; cv=none; b=SfRuJ58m2dfdoUdcE8pyThs/OaTXBK3q04Wm61phFsGFUs0Jek3+C1QNw/4NWamubKaynkv3wxe4hS4dctSp7GS5sCFOE6TAPhH4ghqd5RR8Jwg7nCjIaDRBfJJ6SEogkch5iFCdZd3FomKe/wqxWMNYnTf6cebMQZiaxlZZUXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827312; c=relaxed/simple; bh=7KWk+SgqIJbF+ILkzsp3b5+6vrk/Jjm5trU6focfT20=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=F5BRlM+/CtxfxmJNhm1YIXuvTAX/NZYnluxufObxV2dFb6ZmefDooxlhFrkedhvpwXAFwFy/lmV1a2v8qTD6AHhM1OuZ13URDhP4pETjt3hbkeIMc6AmgFRJoaVZLuUtVhPIITMCN2ZJAu4GoIyZd8WW/Yxf1G790Nvzkdn9Ies= 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=KQZJ5Pmh; arc=none smtp.client-ip=54.243.244.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="KQZJ5Pmh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1785827293; bh=cCH7wGS/DSGdpdibtHkqUSVfV1DZbBvdNwFnheuEGLk=; h=From:To:Subject:Date:Message-Id; b=KQZJ5Pmh0eSxyCjA9X/csEPDsMMPZTn6tr8++cHIbUj4gXUS7IkKSdN5dx3rEkChU XRUWUmUtlaMk7QIXJ3xlz30xuU3sadWdIDIWTY/rueNYJ6+Kn92oq13++TL1k0bGWR p2hTn0XdqrqzNV7MUEnivgokqIIYAzwJDXm5czDk= X-QQ-mid: esmtpsz19t1785827291t2f650366 X-QQ-Originating-IP: lD7WTbZHcHLknq1JRmfmpGolqvDJokYAqkLsmcwlCn0= Received: from DESKTOP-8BT1A2O.localdomain ( [61.154.14.86]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 04 Aug 2026 15:08:08 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 11542142582255875228 From: Chaoyi Chen To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Vinod Koul , Chaoyi Chen , Sebastian Reichel , Nicolas Frattaroli , Heikki Krogerus Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v6 4/7] drm/bridge: aux: Add drm_aux_bridge_register_from_node() Date: Tue, 4 Aug 2026 15:07:27 +0800 Message-Id: <20260804070730.68-5-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260804070730.68-1-kernel@airkyi.com> References: <20260804070730.68-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MWdgP8+gtiFR4HAk9GTLLaO9+YbjZgXaKyVmxQY5wQceLFbHKV1Yeve0 lsPVz6boWnJuQUaE+YVWIWi/U8uoglx+Koag37oXXpYFRkUAVdRSG2c8loTIrq/c5101Le/ D1wru/NojkHA8M+rKZmHATSWROG+xxcTsu4HNWk4bvi/qbrwOfqooRtk+/Va9T3E6myzYhb WdVCXL4pQaYrWy5fxI2JmFrllpJhyduewBteYzmr+U2MA1V92U51Kurn9RDsW7V1kHwmIw2 EGzCiEUo6zSXQFa+xlzkzEgWgRuxdYfadc+7fF1PgH2WnAfpKnKVUOp6IrIx3m4/JaNiT6y JRZE3q1Z9O9Za8JE1Ey9+fvC9ZUddyaD7Ajumc563AON5hVcx+cg0cc2TCEYauc8axPbc3C DGbDy9ptj0Efv0Dt5i93By4p23K2HBwSsSWbPsvIVv1eDrIvsa+euEbzKx2dUW4DzZWBJFl bExH8PM/3oFDrWGq0U4ANR6VVEA7I2d8jknJGavBQNhW6KefLmUGJG7XyaHXILX5xfzKXxM Xt9yfgRmXBLZaRW8MXaZYOoyxEiZu0B/ZjDpRtk0oW95G951lJlqEJ5ILqPyA4Lc3juBsLg Kidafc32lE3iuAlIMgsTmtuQxiIyF3+oa4GnUFKLLkT0IhS2jrBi0Icl1bCiwYNBR5BAE16 asIb6/nfHzuPmOgaTFNHxP74PTS8a+99t7K7L+O7Ou72rcZHig08M/UEW3/g4TDrLvRTS1Q 7r6rtAXyavHPyk7b/ROiT8+l2PZqm4EkCtPC6LpkVPrjYu+kty49qbjsA1AowU00mIB9hdo JN28Z4RHAYnt/XKSQhC86BbdAXAdt4hn6CJYcOYPfZru/4vlqVtxwNtr8KllzYBpgH8pXrk 8bripQ/M/TpeWFMgnM1Q+F1UMW9LomQF+JUSCEYFSKayuGHFHeBl2d1HRZT1BnqC6Wgw1Hp iNlAnGgRg/IEZxu4dn4g1hyKCBcS/9MDFv/t3B8AZ1eC4BPfhHHzZlAFoTTkTivyD2kAkcL MhGwLxfTA7aQ/uFItf X-QQ-XMRINFO: Mp0Kj//9VHAxzExpfF+O8yhSrljjwrznVg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen The drm_aux_bridge_register() uses the device->of_node as the bridge->of_node. This patch adds drm_aux_bridge_register_from_node() to allow specifying the of_node corresponding to the bridge. Signed-off-by: Chaoyi Chen Reviewed-by: Neil Armstrong Reviewed-by: Nicolas Frattaroli Reviewed-by: Sebastian Reichel --- (no changes since v3) Changes in v2: - Fix incorrect function names in the documentation comments. --- drivers/gpu/drm/bridge/aux-bridge.c | 26 +++++++++++++++++++++++--- include/drm/bridge/aux-bridge.h | 6 ++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/a= ux-bridge.c index 1ed21a8713bf..06a1466f49bd 100644 --- a/drivers/gpu/drm/bridge/aux-bridge.c +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -33,8 +33,9 @@ static void drm_aux_bridge_unregister_adev(void *_adev) } =20 /** - * drm_aux_bridge_register - Create a simple bridge device to link the cha= in + * drm_aux_bridge_register_from_node - Create a simple bridge device to li= nk the chain * @parent: device instance providing this bridge + * @np: device node pointer corresponding to this bridge instance * * Creates a simple DRM bridge that doesn't implement any drm_bridge * operations. Such bridges merely fill a place in the bridge chain linking @@ -42,7 +43,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev) * * Return: zero on success, negative error code on failure */ -int drm_aux_bridge_register(struct device *parent) +int drm_aux_bridge_register_from_node(struct device *parent, struct device= _node *np) { struct auxiliary_device *adev; int ret; @@ -62,7 +63,10 @@ int drm_aux_bridge_register(struct device *parent) adev->dev.parent =3D parent; adev->dev.release =3D drm_aux_bridge_release; =20 - device_set_of_node_from_dev(&adev->dev, parent); + if (np) + device_set_node(&adev->dev, of_fwnode_handle(np)); + else + device_set_of_node_from_dev(&adev->dev, parent); =20 ret =3D auxiliary_device_init(adev); if (ret) { @@ -80,6 +84,22 @@ int drm_aux_bridge_register(struct device *parent) =20 return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, a= dev); } +EXPORT_SYMBOL_GPL(drm_aux_bridge_register_from_node); + +/** + * drm_aux_bridge_register - Create a simple bridge device to link the cha= in + * @parent: device instance providing this bridge + * + * Creates a simple DRM bridge that doesn't implement any drm_bridge + * operations. Such bridges merely fill a place in the bridge chain linking + * surrounding DRM bridges. + * + * Return: zero on success, negative error code on failure + */ +int drm_aux_bridge_register(struct device *parent) +{ + return drm_aux_bridge_register_from_node(parent, NULL); +} EXPORT_SYMBOL_GPL(drm_aux_bridge_register); =20 struct drm_aux_bridge_data { diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridg= e.h index cca07a8e2d45..67f74ed287d9 100644 --- a/include/drm/bridge/aux-bridge.h +++ b/include/drm/bridge/aux-bridge.h @@ -13,11 +13,17 @@ struct auxiliary_device; =20 #if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE) int drm_aux_bridge_register(struct device *parent); +int drm_aux_bridge_register_from_node(struct device *parent, struct device= _node *np); #else static inline int drm_aux_bridge_register(struct device *parent) { return 0; } + +static inline int drm_aux_bridge_register_from_node(struct device *parent,= struct device_node *np) +{ + return 0; +} #endif =20 #if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE) --=20 2.53.0 From nobody Fri Oct 2 06:57:44 2026 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 033112D780A for ; Tue, 4 Aug 2026 07:08:38 +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=1785827321; cv=none; b=N0VBLf9/zaKn2+KglRi5elxuEfwgFqijQ6m+q6aj/6eZNoWkdg/z4iTAKHEzZhLGvGmD/QYAwPqu16HhVeR5q/6+n+abO2Sf/rAQ+fH8l5d5S/A0S7Q9CoNePg+I7ctVO4og7/0APLtlJy9o+0vvvDRdgeUkF9f8+1JWzTp+Wtc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827321; c=relaxed/simple; bh=pnKrO2JPi7TqlumR6Mrvl6jpLl4SAIGpj9tmPD6rQ7A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=VZ9kkJjmVHszROH1Il3bqwBVzxGMXpjdzsjHKHfkXc5PFaQRUQx5LkVOT01XfFh96KTGLKUvqDwlWFQa4G9V4xzdE/MqluqR2PO/GXFUkI1dWOPUMqjJ7NFjJuW3dwDVb6qtGbNqM++4/fwiYJ+LcGnlVSJcdaoBJYet8Fpwn5w= 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=pgysLPSK; 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="pgysLPSK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1785827298; bh=E2l8SC5Yz3l3RQ8kfLiWXU6wvt0RqrCjSGXwLiFhpCg=; h=From:To:Subject:Date:Message-Id; b=pgysLPSKhco3sMM/jci2VixwgqgdEP3DVtJY8+ymFeeCsM28uQX7zoNoMDJ+3nxrG NMqGb1KVrq0NYFAlgkNPnKcq4GSmfbnz9Nf6lge8n2S84JDI4lBmVndCWGcWnGofdw q77SdDhYGXx1pAndrQoApW9YSAhUC0QjSDEZisRE= X-QQ-mid: esmtpsz19t1785827296t5d5c1fbd X-QQ-Originating-IP: 0cHwMQcP2BBEqYGFtlahXAYAHyCJF7V6tqtxURYr1Mg= Received: from DESKTOP-8BT1A2O.localdomain ( [61.154.14.86]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 04 Aug 2026 15:08:13 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 9911778146744449110 From: Chaoyi Chen To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Vinod Koul , Chaoyi Chen , Sebastian Reichel , Nicolas Frattaroli , Heikki Krogerus Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v6 5/7] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge Date: Tue, 4 Aug 2026 15:07:28 +0800 Message-Id: <20260804070730.68-6-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260804070730.68-1-kernel@airkyi.com> References: <20260804070730.68-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: McfvTdNTSvcBezXVl3WGzI5cWsL41jDsDB7dQuhPeV+EZ81MlJEI0b/r ySgDaV4EOAXQvolt9RdYVD575xkhYeCUPiqdrn8dyQo4eiLz9F0YT7y0SR7nEwugp8xTP4u 9tCBLmV0vyy0RdobIMyXUJolcnBFdMWYFhnUDasWnr1qlqy0x+9ApH736ufcTyxhqUfVwv3 lzH+9GVEJtD60gQ0Fuuhcf/YFPvDSX4yZ7/zCy4vpiG2nphTEwgs0sOT4pQLG7DC6Qg9JKG LMuuNVFD+P7dcexgD5j9sOYv48JpBi1d9q8FhUv6pZ2gVCXPmdHm+wJy4WM1vSMUGQemwJb Qq+n+2HRISmlFWRBcDh7+OzTQLStjcwr5Q2AMAleKqOoB2C4NClL6ZphfnWlIJAAfSRQuD5 i87uX/fvRT+Der04kK1Dq73mTgxTeXj1tph3UTseXcJbiXQWfWU3UOnPc7E4kOqwfBNvwsy kTfE2a59/u5z9Fuq6fs+AGtjrlCIWvkX9X+6m9IES1zBo/NSlkNFNgIa54CYYqkxtCnSUt0 yuOa3cAPRKnQOS7Sk6zUy3VJTQV4Lysm6dwSgveS+NzGDvxz7GsmvgN1I6ycFLVrphGpl0H IO027pvRL701UDMG3Zoz8pUMGj+OlcXTWwrDfqc2rDNBa0XWj5eDOTxA0sftyVOz9T5M66N +GI3J8DUAeMQ1TluyKk5mR769oOOYINOs4WglVDYEZx61V+ZXvIR6xrkWznUbYW4neltI/Y 6SDoGnE2grOV+0MUvw5sheS+BEt4w9pFeV32jHJcBpxSsAZl51aruszacBosUsJgIVtLWnq JLAPS2s3WJvO7lJgHex7IdE6dBdoVHz+yXVCrrUmBQHuXQJZ2hhHArvJhWiTRHsO03ApyPg okMrxgt9qj8iZmNOxtdNmZOVRYM7yCVVbQYdvoIhInQmOc3I4LDN3Tx6oS/nd3uoQcyb+fB /ZIjEVA61JFkr6wEY/6tYxkvmAttMI+XRDkPStKgZ4ydaCnNdtn+9SeRGVxu4fjnFZJUPnK kXPQH3zDshqvbtaMadnMRinSylGTPN8ZkEcOkXbQ== X-QQ-XMRINFO: M/715EihBoGS47X28/vv4NpnfpeBLnr4Qg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge device. Signed-off-by: Chaoyi Chen Reviewed-by: Neil Armstrong Reviewed-by: Sebastian Reichel Acked-by: Vinod Koul --- (no changes since v1) --- drivers/phy/rockchip/Kconfig | 2 ++ drivers/phy/rockchip/phy-rockchip-typec.c | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index 14698571b607..9173d3b4fef4 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -119,6 +119,8 @@ config PHY_ROCKCHIP_SNPS_PCIE3 config PHY_ROCKCHIP_TYPEC tristate "Rockchip TYPEC PHY Driver" depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) + 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 d9701b6106d5..48070b50416e 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -54,6 +54,7 @@ =20 #include #include +#include =20 #define CMN_SSM_BANDGAP (0x21 << 2) #define CMN_SSM_BIAS (0x22 << 2) @@ -1162,16 +1163,24 @@ static int rockchip_typec_phy_probe(struct platform= _device *pdev) =20 for_each_available_child_of_node(np, child_np) { struct phy *phy; + ret =3D 0; =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")) + ret =3D drm_aux_bridge_register_from_node(dev, child_np); + } else if (of_node_name_eq(child_np, "usb3-port")) phy =3D devm_phy_create(dev, child_np, &rockchip_usb3_phy_ops); else continue; =20 + if (ret) { + pm_runtime_disable(dev); + of_node_put(child_np); + return ret; + } + if (IS_ERR(phy)) { dev_err(dev, "failed to create phy: %pOFn\n", child_np); --=20 2.53.0 From nobody Fri Oct 2 06:57:44 2026 Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D5553F44EC for ; Tue, 4 Aug 2026 07:08:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.243.244.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827323; cv=none; b=P7VpsBRw5frv3Gm+j2f8vjF5TkDpSGDMQTVMkcde7SjcVsazSMT70/YJawxjsdjwTsYXD84V25gaNlyEzLDtFrthTr9qPZrjTIbsg3FH1tHPh4txwnfwogmUKbrtaacyWL6tAWCZuA0HNTEaMioaPwN3sUwBcFCTi/7N26QdFtU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827323; c=relaxed/simple; bh=Do2vEEbKffBKIoRwA8XTtrCuUyMId8s9a5j5NUcntlY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Mq3HI4nPms9nrlKyj/85dhJpID5nNSzWhMpziNtctMI8gxZYhWOon1vwZDGiVlNzXRCkyJNEbPH88LlXPC8Yyv+8LHxZ0rMIdTY3543i4nuqKERb54HcIFSxLgq9Iu6GDJZIu9beSbNgpACQ8BlC5lU+oZiWsiMi8vuM1OD30RA= 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=gGBFqoBr; arc=none smtp.client-ip=54.243.244.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=airkyi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=airkyi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=airkyi.com header.i=@airkyi.com header.b="gGBFqoBr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1785827304; bh=hfSDcA/VFf5O36XZ1jIbDeiIvlPOe5N0iYnQa5D5SVg=; h=From:To:Subject:Date:Message-Id; b=gGBFqoBrLYjgIoQf93SB0LsFUNWmWzBa0WAeEL/CHcGgcyXOOUJJdKp6h2PjRTt7U TnNS74zYEUuYk7g+Qv4ewQwYmq60MX6DWWPFz7/6CcN5V0LEZwk85grZkMx60sbYj4 kU1WD4obc4kW82hHefJGXY3+julCFOm2ql+LOYq0= X-QQ-mid: esmtpsz19t1785827303t5bf198e5 X-QQ-Originating-IP: lvl2+FbaNh+rQwA9UiH/mIq1IbGfwWu7ceGOLF34ChE= Received: from DESKTOP-8BT1A2O.localdomain ( [61.154.14.86]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 04 Aug 2026 15:08:17 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 9591211564925430359 From: Chaoyi Chen To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Vinod Koul , Chaoyi Chen , Sebastian Reichel , Nicolas Frattaroli , Heikki Krogerus Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v6 6/7] drm/rockchip: cdn-dp: Support handle lane info without extcon Date: Tue, 4 Aug 2026 15:07:29 +0800 Message-Id: <20260804070730.68-7-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260804070730.68-1-kernel@airkyi.com> References: <20260804070730.68-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: OQhZ3T0tjf0a53H4cXaW5XVJtNDmdpZ5dRqf2kxYUcUjyyAKHgocUyjO DCksxAqaUs0wV6TiJXCYCm/pNU3RnN+l+PVrzwcs/fgsBA4M6208kw6iEamx6x1w32OLtk+ g/mFzWGppVipjjqoXv4cU8D9F285B/GWRxCu9bKmo/p+kbzB588bIgedNwYQOKb7RsY5LzF xKKkWzQ8vecdWRJx4Mxjpw7S2ETiSm3zS/nPAOPyImGDpkZvMSHaufYroYDMPqv2mUJUUq9 ZvpPh5y+sMxAGNAyw1jSAdfRW576fW7RzDE2LKgaRj9KXbCTXiGtReFtEey6kbRqOg2AQ7e oq1QcznUrq9vWmXk8ONSOMgCIoICcfezbslnNKru6iIle9CaieEB7iplrQVBKxrtGAESRNK crLHWtOpweGqWNDsUo2M07Xg6L1Pm+f2ywMaF3K/dMM3gvUXDfQgSzMq9R84MMzSDSpuAtK Yomi2TwWiWSHJ6buC07tws105/NkskXdlf2aaX3TV3iRSZxZwVxoWnZZMwYwdyMiLWQ/Ea8 t6qnbj/0ZQrlmC0/xnfIXnzGWxo6sjEvZJjjPp54RD647liG4tcKVeWr8vhYHyFUe5XAh9F KZVZmZ6KGPbUry6est3NTYdhgXLR00UsXzspQ2rAsp54RPYXkZLPZBHKhBiAvr1KkyJZglC t3Pzvo5jBCeDa7iNLyklWkzYhMtqmKdwAW/21dUm29Qpv1fKqjPV7WT4BNYDcQhOS7hf9DZ n4OYZWGP/UDLfTzM74hfLyzC/5MR0vvTVV77CxcaGCZym+kkRGdWm28W8XxLGQs026D/ngs qlz8UV2ZPafvPauYgh2csgQI4glPUL/kxO6BwZmB00A0DZddW1objjw7y0K9PD/xFQM+s8n HtoB3jn+C/gqO3VQqG3tkASwbjTsGNYD01/1Jl9Ji1spUjKU/WPD1fO/8Aw7HUdXR/JI1M/ i2y+H2hZCArDx8DSeEjaUtPAifVkyEkZl9V5dnDtrGd6DlyvxFDEWmWVFXp+tI3j/k7cD/d 16a3rr6Q== X-QQ-XMRINFO: MSVp+SPm3vtSI1QTLgDHQqIV1w2oNKDqfg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen 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 Reviewed-by: Heiko Stuebner --- (no changes since v1) --- 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 190cce9530c8..74e1f5422a6e 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -157,6 +157,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, @@ -220,7 +223,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)) @@ -386,11 +389,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); @@ -1027,6 +1033,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, @@ -1119,14 +1128,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.53.0 From nobody Fri Oct 2 06:57:44 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 432D2422533 for ; Tue, 4 Aug 2026 07:08:46 +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=1785827330; cv=none; b=DsCeSnq80iNDK16ZQniKD7rMKWvNhfhBDAPsO5VdhGSRU3Ps9ZKQ1FjYiMfT/7gYrMUYIol6jGXSrjlPNq58iA+T0a0sYdyljJJgqyU+ayEUhmuFYhZWg7mezZkyswRkY4xTi7+m73awYtkI5Rb0dYC3Zdt/dtiMAPBz7QnpFkI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785827330; c=relaxed/simple; bh=P1LKPDiPOutvYBd6ww8MKHEvS6DYGGXl0tr1C16p9Dw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=rEZMhtC191qp7XhWGkMN6+gpryl0xEt5+vFusnLQab+9SKIeus+4OS9suhWMi2TpcDogx7Oyp4eht3m19gGlM0xgQKWPdoUc9w/YOhBtc/XMUOTOjn3qaYgackZwGc2/UG3AnJJA8QrfDq5wdRZ6/C8XM4VOorXkYgw9E3HFeRc= 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=Ljk/km1s; 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="Ljk/km1s" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=airkyi.com; s=altu2504; t=1785827309; bh=lKSvP+xMotYW05bEKx8Z16U7leN5oeUpgtpGTiKZ9Ns=; h=From:To:Subject:Date:Message-Id; b=Ljk/km1s51fVgEzQ8w+IrExpRNbNjZX1o0EkkLEM8bIj9JUZbOPSYTdeqpoqsPkaP qLADLRPVkq+kVzsvMdcZgfosr0yTp5to3RUT5Im74ppXXcV8NsMADoSVor1UmhKL/I qq/6fUB8NOrkcA6B/gqipqzf7g7RUp4a4v0txqI4= X-QQ-mid: esmtpsz19t1785827308t1ff26586 X-QQ-Originating-IP: 7jBU/Lp1l1fKb0Myw3eQiALQ0eBCShuuHFDtllJkdY0= Received: from DESKTOP-8BT1A2O.localdomain ( [61.154.14.86]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 04 Aug 2026 15:08:24 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 6744597010020539831 From: Chaoyi Chen To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Vinod Koul , Chaoyi Chen , Sebastian Reichel , Nicolas Frattaroli , Heikki Krogerus Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org Subject: [PATCH v6 7/7] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection Date: Tue, 4 Aug 2026 15:07:30 +0800 Message-Id: <20260804070730.68-8-kernel@airkyi.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260804070730.68-1-kernel@airkyi.com> References: <20260804070730.68-1-kernel@airkyi.com> X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:airkyi.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MmpliBmRb3iCtRt0VXlV8wc82O1ugPelF5X2v5W6y4J0j0gV/CLP/h84 ADXVfgrsXEa5k4MhKmyPcUV4Z9wTkrppUO4bBGcljxNtfpCPovsQKafv0CKqxDv52uMQ5IX XSi57h6QYQkclygZO/dfYReCOwo9bGm9TCz4EcUWbGSazvbYnZ/n0QPhNLZ9K4L5yCR5lee xflzBm7MjKJatU/hNiNdOTggE9+mheYQybo5yzxn3uP+VUQYLP0yfhATX8oeLf0rpr/PDFG 4R/jFGmzpjKjYuFLOhOih/Gc2qCJeqlplzzOXpce2xLNR4mPPD3ZpFLf1WIzJc9f2NnC5OW buHOMVJW3ZPASMEXr5Z1NNZknOSiBROUTgp7M1OjRcgWQ7DxuAuIUzdtC+4YzEr/+jf+5If 93qMoLTFonRi1fV5SdIBqvHreuzGGsT5mO+5KTcvBtdzThRRCHeYs/s7x+iwcKnr5eFPRvR cboo4qwa83vTZlCI9hwlaGt6N3d/tGWl67ixBdU2lQT6yxIMBPQq1DW61qtBA2NtX2wTV57 5lR5/yqOceuWPSeY5hHsB3NTwBst2fpX9/SBpvaTNha0aEBK9nRWfv/vrj3ko678vZL9fJ8 l1Vbg49VOk8F9vlGLsDQLRiK83s1lQb9P21ADBjp3x4EitSxdQJafYb2LQ8Z4+aRa3BfoTW JQjmzdpO2J+7vh65R0na69xcf+fbJi85zJpFQnIYBtw91G+WFHKvOgcsZyRDMl19/LLAp8B A+bBQukcyyXDeagdIvCcyelPOaJmN7lt3oTV9mTl2roYSUoqda15cOkicZuxOqGFA86HB/y 2sWBFmO/DcgphuO1tS6Q539uRA6zjgbQECJUBuZDtXKODzLCMpAB9VNcq9e0rSCOQkGXDSS O6CnSLVQl01MYMDv41eK7aq3fKa05lz6QkAXVSTjbNhiqV8JUdHMu/QTLvn1dbuhXu/uTIP u56+UUXg5yF1uPxSRMtJY5PlGBuRX9kly2JOYTyPZmHqwaLvlE0seepo2eNBMzweBESwiuC SPmmRrbtZHoiMTmH9Dw7uZeeyJBfs= X-QQ-XMRINFO: M/715EihBoGS47X28/vv4NpnfpeBLnr4Qg== X-QQ-RECHKSPAM: 0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chaoyi Chen 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 Reviewed-by: Luca Ceresoli Reviewed-by: Heiko Stuebner --- (no changes since v4) Changes in v3: - Remove now-redundant call to drm_connector_attach_encoder() Changes in v2: - Fix the check logic for dp->active_port (0 is valid). - Fix the uninitialized prev_port. - Remove duplicate logic from cdn_dp_switch_port(). - Fix the prototype of cdn_dp_bridge_hpd_notify(). - Properly release connector->fwnode. - Properly release next_bridge. --- drivers/gpu/drm/rockchip/Kconfig | 1 + drivers/gpu/drm/rockchip/cdn-dp-core.c | 333 ++++++++++++++++++++----- drivers/gpu/drm/rockchip/cdn-dp-core.h | 18 +- 3 files changed, 294 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kc= onfig index e7f49fe845ea..ce70f91c13e6 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -60,6 +60,7 @@ config ROCKCHIP_CDN_DP select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR select DRM_DISPLAY_DP_HELPER + select DRM_AUX_HPD_BRIDGE help This selects support for Rockchip SoC specific extensions for the cdn DP driver. If you want to enable Dp on diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockc= hip/cdn-dp-core.c index 74e1f5422a6e..5e513f6930cb 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -28,16 +28,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 @@ -192,14 +193,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 >=3D 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 @@ -254,12 +268,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 =3D NULL; + 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 @@ -268,12 +315,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) { @@ -551,6 +599,50 @@ 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; + + 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->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) { @@ -572,6 +664,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_commit *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 @@ -581,7 +674,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; @@ -600,6 +693,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", @@ -632,6 +728,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); } @@ -639,9 +736,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_commit *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); @@ -828,6 +927,17 @@ 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, + struct drm_connector *connector, + 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, @@ -838,6 +948,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, @@ -886,7 +997,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 @@ -945,9 +1057,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, @@ -967,28 +1082,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb, return NOTIFY_DONE; } =20 -static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +static int cdn_bridge_add(struct device *dev, + struct drm_bridge *bridge, + struct drm_bridge *next_bridge, + struct drm_encoder *encoder) { struct cdn_dp_device *dp =3D dev_get_drvdata(dev); - struct drm_encoder *encoder; + struct drm_device *drm_dev =3D dp->drm_dev; + struct drm_bridge *last_bridge __free(drm_bridge_put) =3D NULL; struct drm_connector *connector; - struct cdn_dp_port *port; - struct drm_device *drm_dev =3D data; - int ret, i; - - ret =3D cdn_dp_parse_dt(dp); - if (ret < 0) - return ret; - - dp->drm_dev =3D drm_dev; - dp->connected =3D false; - dp->active =3D false; - dp->active_port =3D -1; - dp->fw_loaded =3D false; - - INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); - - encoder =3D &dp->encoder.encoder; + int ret; =20 encoder->possible_crtcs =3D drm_of_find_possible_crtcs(drm_dev, dev->of_node); @@ -1003,26 +1106,35 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) =20 drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs); =20 - dp->bridge.ops =3D - DRM_BRIDGE_OP_DETECT | - DRM_BRIDGE_OP_EDID | - DRM_BRIDGE_OP_HPD | - DRM_BRIDGE_OP_DP_AUDIO; - dp->bridge.of_node =3D dp->dev->of_node; - dp->bridge.type =3D DRM_MODE_CONNECTOR_DisplayPort; - dp->bridge.hdmi_audio_dev =3D dp->dev; - dp->bridge.hdmi_audio_max_i2s_playback_channels =3D 8; - dp->bridge.hdmi_audio_spdif_playback =3D 1; - dp->bridge.hdmi_audio_dai_port =3D -1; - - ret =3D devm_drm_bridge_add(dev, &dp->bridge); + bridge->ops =3D + DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | + DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_DP_AUDIO; + bridge->of_node =3D dp->dev->of_node; + bridge->type =3D DRM_MODE_CONNECTOR_DisplayPort; + bridge->hdmi_audio_dev =3D dp->dev; + bridge->hdmi_audio_max_i2s_playback_channels =3D 8; + bridge->hdmi_audio_spdif_playback =3D 1; + bridge->hdmi_audio_dai_port =3D -1; + + ret =3D devm_drm_bridge_add(dev, bridge); if (ret) return ret; =20 - ret =3D drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_N= O_CONNECTOR); + ret =3D drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CON= NECTOR); if (ret) return ret; =20 + if (next_bridge) { + ret =3D drm_bridge_attach(encoder, next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ret; + + last_bridge =3D drm_bridge_chain_get_last_bridge(bridge->encoder); + } + connector =3D drm_bridge_connector_init(drm_dev, encoder); if (IS_ERR(connector)) { ret =3D PTR_ERR(connector); @@ -1030,6 +1142,101 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) return ret; } =20 + if (last_bridge) { + fwnode_handle_put(connector->fwnode); + connector->fwnode =3D fwnode_handle_get(of_fwnode_handle(last_bridge->of= _node)); + } + + 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] =3D drm_bridge_get(bridge); + count++; + } + +out: + dp->bridge_count =3D count ? count : 1; + return ret; +} + +static int cdn_dp_bind(struct device *dev, struct device *master, void *da= ta) +{ + struct cdn_dp_device *dp =3D dev_get_drvdata(dev); + struct drm_bridge *bridge, *next_bridge; + struct drm_encoder *encoder; + struct cdn_dp_port *port; + struct drm_device *drm_dev =3D data; + struct cdn_dp_bridge *dp_bridge; + int ret, i; + + ret =3D cdn_dp_parse_dt(dp); + if (ret < 0) + return ret; + + ret =3D cdn_dp_parse_next_bridge_dt(dp); + if (ret) + goto out; + + 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)) { + ret =3D PTR_ERR(dp_bridge); + goto out; + } + dp_bridge->id =3D i; + dp_bridge->parent =3D dp; + if (!dp->next_bridge_valid) + dp_bridge->connected =3D true; + dp->bridge_list[i] =3D dp_bridge; + } + + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + bridge =3D &dp->bridge_list[i]->bridge; + next_bridge =3D dp->next_bridge_list[i]; + ret =3D cdn_bridge_add(dev, bridge, next_bridge, encoder); + if (ret) + goto out; + } + + INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); + for (i =3D 0; i < dp->ports; i++) { port =3D dp->port[i]; =20 @@ -1043,7 +1250,7 @@ static int cdn_dp_bind(struct device *dev, struct dev= ice *master, void *data) if (ret) { DRM_DEV_ERROR(dev, "register EXTCON_DISP_DP notifier err\n"); - return ret; + goto out; } } =20 @@ -1052,15 +1259,29 @@ static int cdn_dp_bind(struct device *dev, struct d= evice *master, void *data) schedule_work(&dp->event_work); =20 return 0; + +out: + for (i =3D 0; i < MAX_PHY; i++) + drm_bridge_put(dp->next_bridge_list[i]); + + return ret; } =20 static void cdn_dp_unbind(struct device *dev, struct device *master, void = *data) { struct cdn_dp_device *dp =3D dev_get_drvdata(dev); - struct drm_encoder *encoder =3D &dp->encoder.encoder; + struct drm_encoder *encoder; + int i; =20 cancel_work_sync(&dp->event_work); - encoder->funcs->destroy(encoder); + for (i =3D 0; i < dp->bridge_count; i++) { + encoder =3D &dp->bridge_list[i]->encoder.encoder; + encoder->funcs->destroy(encoder); + drm_bridge_put(dp->next_bridge_list[i]); + } + + for (i =3D 0; i < MAX_PHY; i++) + drm_edid_free(dp->edid_cache[i]); =20 pm_runtime_disable(dev); if (dp->fw_loaded) @@ -1111,10 +1332,10 @@ static int cdn_dp_probe(struct platform_device *pde= v) int ret; int i; =20 - dp =3D devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge, - &cdn_dp_bridge_funcs); - if (IS_ERR(dp)) - return PTR_ERR(dp); + dp =3D devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + dp->dev =3D dev; =20 match =3D of_match_node(cdn_dp_dt_ids, pdev->dev.of_node); diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockc= hip/cdn-dp-core.h index e9c30b9fd543..c10e423bbf06 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h @@ -38,6 +38,8 @@ enum vic_pxl_encoding_format { Y_ONLY =3D 0x10, }; =20 +struct cdn_dp_device; + struct video_info { bool h_sync_polarity; bool v_sync_polarity; @@ -63,16 +65,28 @@ struct cdn_dp_port { u8 id; }; =20 +struct cdn_dp_bridge { + struct cdn_dp_device *parent; + struct drm_bridge bridge; + struct rockchip_encoder encoder; + bool connected; + bool enabled; + int id; +}; + struct cdn_dp_device { struct device *dev; struct drm_device *drm_dev; - struct drm_bridge bridge; - struct rockchip_encoder encoder; + int bridge_count; + struct cdn_dp_bridge *bridge_list[MAX_PHY]; + struct drm_bridge *next_bridge_list[MAX_PHY]; + const struct drm_edid *edid_cache[MAX_PHY]; struct drm_display_mode mode; struct platform_device *audio_pdev; struct work_struct event_work; =20 struct mutex lock; + bool next_bridge_valid; bool connected; bool active; bool suspended; --=20 2.53.0