linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: "Kory Maincent (TI.com)" <kory.maincent@bootlin.com>
To: Jyri Sarha <jyri.sarha@iki.fi>,
	 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>,
	 Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	 Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	 David Airlie <airlied@gmail.com>,
	Simona Vetter <simona@ffwll.ch>,  Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	 Conor Dooley <conor+dt@kernel.org>,
	Russell King <linux@armlinux.org.uk>,
	 Bartosz Golaszewski <brgl@bgdev.pl>,
	Tony Lindgren <tony@atomide.com>,
	 Andrzej Hajda <andrzej.hajda@intel.com>,
	 Neil Armstrong <neil.armstrong@linaro.org>,
	Robert Foss <rfoss@kernel.org>,
	 Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	 Jonas Karlman <jonas@kwiboo.se>,
	Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Markus Schneider-Pargmann <msp@baylibre.com>,
	 Luca Ceresoli <luca.ceresoli@bootlin.com>,
	 Louis Chauvet <louis.chauvet@bootlin.com>,
	 Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	 Miguel Gazquez <miguel.gazquez@bootlin.com>,
	 dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	 linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	 linux-omap@vger.kernel.org,
	 "Kory Maincent (TI.com)" <kory.maincent@bootlin.com>
Subject: [PATCH 20/21] drm/bridge: tda998x: Add support for DRM_BRIDGE_ATTACH_NO_CONNECTOR
Date: Wed, 26 Nov 2025 18:36:02 +0100	[thread overview]
Message-ID: <20251126-feature_tilcdc-v1-20-49b9ef2e3aa0@bootlin.com> (raw)
In-Reply-To: <20251126-feature_tilcdc-v1-0-49b9ef2e3aa0@bootlin.com>

Add support for the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag to allow display
controller drivers to create their own connectors. This modernizes the
driver to work with the current DRM bridge framework.

The implementation includes:
- Refactoring detection and EDID reading into bridge-usable helpers
- Adding bridge operations: edid_read, detect, hpd_enable, hpd_disable
- Setting appropriate bridge ops (DRM_BRIDGE_OP_EDID, DRM_BRIDGE_OP_DETECT,
  DRM_BRIDGE_OP_HPD) and connector type (HDMIA)
- Skipping connector creation when DRM_BRIDGE_ATTACH_NO_CONNECTOR is set
- Handling conditional connector cleanup in bridge_detach

The driver maintains backward compatibility by continuing to create its
own connector when the flag is not set.

Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
---
 drivers/gpu/drm/bridge/tda998x_drv.c | 96 +++++++++++++++++++++++++++++++-----
 1 file changed, 85 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c
index 43ace6ee2ca35..4d78615634691 100644
--- a/drivers/gpu/drm/bridge/tda998x_drv.c
+++ b/drivers/gpu/drm/bridge/tda998x_drv.c
@@ -1193,16 +1193,22 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
 
 /* DRM connector functions */
 
-static enum drm_connector_status
-tda998x_connector_detect(struct drm_connector *connector, bool force)
+static enum drm_connector_status tda998x_conn_detect(struct tda998x_priv *priv)
 {
-	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
 	u8 val = cec_read(priv, REG_CEC_RXSHPDLEV);
 
 	return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected :
 			connector_status_disconnected;
 }
 
+static enum drm_connector_status
+tda998x_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
+
+	return tda998x_conn_detect(priv);
+}
+
 static const struct drm_connector_funcs tda998x_connector_funcs = {
 	.reset = drm_atomic_helper_connector_reset,
 	.fill_modes = drm_helper_probe_single_connector_modes,
@@ -1276,11 +1282,10 @@ static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
 	return ret;
 }
 
-static int tda998x_connector_get_modes(struct drm_connector *connector)
+static const struct drm_edid *tda998x_edid_read(struct tda998x_priv *priv,
+						struct drm_connector *connector)
 {
-	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
 	const struct drm_edid *drm_edid;
-	int n;
 
 	/*
 	 * If we get killed while waiting for the HPD timeout, return
@@ -1298,6 +1303,16 @@ static int tda998x_connector_get_modes(struct drm_connector *connector)
 	if (priv->rev == TDA19988)
 		reg_set(priv, REG_TX4, TX4_PD_RAM);
 
+	return drm_edid;
+}
+
+static int tda998x_connector_get_modes(struct drm_connector *connector)
+{
+	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
+	const struct drm_edid *drm_edid;
+	int n;
+
+	drm_edid = tda998x_edid_read(priv, connector);
 	drm_edid_connector_update(connector, drm_edid);
 	cec_notifier_set_phys_addr(priv->cec_notify,
 				   connector->display_info.source_physical_address);
@@ -1365,10 +1380,8 @@ static int tda998x_bridge_attach(struct drm_bridge *bridge,
 {
 	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
 
-	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
-		DRM_ERROR("Fix bridge driver to make connector optional!");
-		return -EINVAL;
-	}
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+		return 0;
 
 	return tda998x_connector_init(priv, bridge->dev);
 }
@@ -1377,7 +1390,8 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
 {
 	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
 
-	drm_connector_cleanup(&priv->connector);
+	if (priv->connector.dev)
+		drm_connector_cleanup(&priv->connector);
 }
 
 static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
@@ -1677,6 +1691,59 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
 	mutex_unlock(&priv->audio_mutex);
 }
 
+static const struct drm_edid *
+tda998x_bridge_edid_read(struct drm_bridge *bridge,
+			 struct drm_connector *connector)
+{
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+	const struct drm_edid *drm_edid;
+	const struct edid *edid;
+
+	drm_edid = tda998x_edid_read(priv, connector);
+	if (!drm_edid) {
+		dev_dbg(&priv->hdmi->dev, "failed to get edid\n");
+		return NULL;
+	}
+
+	/*
+	 * FIXME: This should use connector->display_info.has_audio from
+	 * a path that has read the EDID and called
+	 * drm_edid_connector_update().
+	 */
+	edid = drm_edid_raw(drm_edid);
+
+	dev_dbg(&priv->hdmi->dev, "got edid: width[%d] x height[%d]\n",
+		edid->width_cm, edid->height_cm);
+
+	priv->sink_has_audio = drm_detect_monitor_audio(edid);
+	cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid);
+
+	return drm_edid;
+}
+
+static enum drm_connector_status
+tda998x_bridge_detect(struct drm_bridge *bridge,
+		      struct drm_connector *connector)
+{
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+	return tda998x_conn_detect(priv);
+}
+
+static void tda998x_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+	cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
+}
+
+static void tda998x_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+	cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
+}
+
 static const struct drm_bridge_funcs tda998x_bridge_funcs = {
 	.attach = tda998x_bridge_attach,
 	.detach = tda998x_bridge_detach,
@@ -1684,6 +1751,10 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = {
 	.disable = tda998x_bridge_disable,
 	.mode_set = tda998x_bridge_mode_set,
 	.enable = tda998x_bridge_enable,
+	.edid_read = tda998x_bridge_edid_read,
+	.detect = tda998x_bridge_detect,
+	.hpd_enable = tda998x_bridge_hpd_enable,
+	.hpd_disable = tda998x_bridge_hpd_disable,
 };
 
 /* I2C driver functions */
@@ -1872,6 +1943,7 @@ tda998x_probe(struct i2c_client *client)
 
 		/* enable HPD irq */
 		cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
+		priv->bridge.ops = DRM_BRIDGE_OP_HPD;
 	}
 
 	priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
@@ -1932,6 +2004,8 @@ tda998x_probe(struct i2c_client *client)
 	priv->bridge.of_node = dev->of_node;
 #endif
 
+	priv->bridge.ops |= DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
+	priv->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	drm_bridge_add(&priv->bridge);
 
 	return 0;

-- 
2.43.0



  parent reply	other threads:[~2025-11-26 17:38 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-26 17:35 [PATCH 00/21] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 01/21] dt-bindings: display: tilcdc: Convert to DT schema Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 02/21] dt-bindings: display: tilcdc: Add fifo-threshold property Kory Maincent (TI.com)
2025-11-27  8:22   ` Krzysztof Kozlowski
2025-11-27  9:37     ` Kory Maincent
2025-11-26 17:35 ` [PATCH 03/21] drm/tilcdc: Remove simulate_vesa_sync flag Kory Maincent (TI.com)
2025-12-10 18:10   ` Luca Ceresoli
2025-12-11  9:40     ` Kory Maincent
2025-12-11  9:47       ` Luca Ceresoli
2025-11-26 17:35 ` [PATCH 04/21] drm/tilcdc: Add support for DRM bus flags and simplify panel config Kory Maincent (TI.com)
2025-12-10 18:13   ` Luca Ceresoli
2025-11-26 17:35 ` [PATCH 05/21] ARM: dts: omap: Bind panel to panel-dpi instead of ti,tilcdc,panel driver Kory Maincent (TI.com)
2025-12-01 14:13   ` Tomi Valkeinen
2025-12-01 21:46     ` Krzysztof Kozlowski
2025-12-02  9:42       ` Kory Maincent
2025-12-02 10:28         ` Krzysztof Kozlowski
2025-12-02 10:44           ` Kory Maincent
2025-12-02 10:47             ` Krzysztof Kozlowski
2025-12-02 11:18               ` Kory Maincent
2025-12-02 11:51                 ` Tomi Valkeinen
2025-12-02 12:20                   ` Krzysztof Kozlowski
2025-12-02 12:56                   ` Kory Maincent
2025-12-03  8:30                     ` Krzysztof Kozlowski
2025-12-02 12:19                 ` Krzysztof Kozlowski
2025-11-26 17:35 ` [PATCH 06/21] dt-bindings: display: tilcdc: Remove panel binding Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 07/21] drm/tilcdc: Remove tilcdc panel driver Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 08/21] drm/tilcdc: Remove component framework support Kory Maincent (TI.com)
2025-12-11  9:42   ` Luca Ceresoli
2025-11-26 17:35 ` [PATCH 09/21] drm/tilcdc: Remove tilcdc_panel_info structure Kory Maincent (TI.com)
2025-12-11  9:44   ` Luca Ceresoli
2025-11-26 17:35 ` [PATCH 10/21] drm/tilcdc: Remove redundant #endif/#ifdef in debugfs code Kory Maincent (TI.com)
2025-12-10 18:22   ` Luca Ceresoli
2025-11-26 17:35 ` [PATCH 11/21] drm/tilcdc: Remove unused encoder and connector tracking arrays Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 12/21] drm/tilcdc: Rename external_encoder and external_connector to encoder and connector Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 13/21] drm/tilcdc: Rename tilcdc_external to tilcdc_encoder Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 14/21] drm/tilcdc: Remove the useless module list support Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 15/21] drm/tilcdc: Modernize driver initialization and cleanup paths Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 16/21] drm/tilcdc: Remove the use of drm_device private_data Kory Maincent (TI.com)
2025-11-26 17:35 ` [PATCH 17/21] drm/bridge: tda998x: Remove component support Kory Maincent (TI.com)
2025-11-26 17:36 ` [PATCH 18/21] drm/bridge: tda998x: Move tda998x_create/destroy into probe and remove Kory Maincent (TI.com)
2025-11-26 17:36 ` [PATCH 19/21] drm/bridge: tda998x: Remove useless tda998x_connector_destroy wrapper Kory Maincent (TI.com)
2025-11-26 17:36 ` Kory Maincent (TI.com) [this message]
2025-11-26 17:36 ` [PATCH 21/21] drm/tilcdc: Add support for DRM_BRIDGE_ATTACH_NO_CONNECTOR Kory Maincent (TI.com)
2025-12-02 12:25 ` [PATCH 00/21] Clean and update tilcdc driver to support DRM_BRIDGE_ATTACH_NO_CONNECTOR Swamil Jain
2025-12-03 10:49   ` Kory Maincent
2025-12-03 12:13     ` Swamil Jain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251126-feature_tilcdc-v1-20-49b9ef2e3aa0@bootlin.com \
    --to=kory.maincent@bootlin.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=airlied@gmail.com \
    --cc=andrzej.hajda@intel.com \
    --cc=brgl@bgdev.pl \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jernej.skrabec@gmail.com \
    --cc=jonas@kwiboo.se \
    --cc=jyri.sarha@iki.fi \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=louis.chauvet@bootlin.com \
    --cc=luca.ceresoli@bootlin.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=miguel.gazquez@bootlin.com \
    --cc=mripard@kernel.org \
    --cc=msp@baylibre.com \
    --cc=neil.armstrong@linaro.org \
    --cc=rfoss@kernel.org \
    --cc=robh@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=tomi.valkeinen@ideasonboard.com \
    --cc=tony@atomide.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).