lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250902-drm-state-readout-v1-17-14ad5315da3f@kernel.org>
Date: Tue, 02 Sep 2025 10:32:45 +0200
From: Maxime Ripard <mripard@...nel.org>
To: Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>, 
 Thomas Zimmermann <tzimmermann@...e.de>, David Airlie <airlied@...il.com>, 
 Simona Vetter <simona@...ll.ch>, Andrzej Hajda <andrzej.hajda@...el.com>, 
 Neil Armstrong <neil.armstrong@...aro.org>, Robert Foss <rfoss@...nel.org>, 
 Laurent Pinchart <Laurent.pinchart@...asonboard.com>, 
 Jonas Karlman <jonas@...boo.se>, Jernej Skrabec <jernej.skrabec@...il.com>, 
 Jyri Sarha <jyri.sarha@....fi>, 
 Tomi Valkeinen <tomi.valkeinen@...asonboard.com>
Cc: Devarsh Thakkar <devarsht@...com>, dri-devel@...ts.freedesktop.org, 
 linux-kernel@...r.kernel.org, Maxime Ripard <mripard@...nel.org>
Subject: [PATCH 17/29] drm/bridge_connector: Implement hw readout for
 connector

drm_bridge_connector allows to create a generic connector from a list of
bridges.

However, it's a somewhat virtual connector, and relies on the bridges to
implement its various capabilities.

What we actually want though is for the last bridge implementing
hardware readout to fill the connector state from its own state.

Thus, let's implement a new op for bridge_connector to allow just that.

Signed-off-by: Maxime Ripard <mripard@...nel.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 36 +++++++++++++++++++++++---
 include/drm/drm_bridge.h                       | 21 +++++++++++++++
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 091c5335355a2b6c70dd823df69ce060fd56c4f9..0cf97cd0e554fd5f1101e4afb28f2a341bd774fb 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -64,10 +64,18 @@ struct drm_bridge_connector {
 	 * @encoder:
 	 *
 	 * The encoder at the start of the bridges chain.
 	 */
 	struct drm_encoder *encoder;
+	/**
+	 * @bridge_connector_hw_readout:
+	 *
+	 * The last bridge in the chain (closest to the connector) that
+	 * provides hardware state readout support, if any (see
+	 * &DRM_BRIDGE_OP_CONNECTOR_HW_READOUT).
+	 */
+	struct drm_bridge *bridge_connector_hw_readout;
 	/**
 	 * @bridge_edid:
 	 *
 	 * The last bridge in the chain (closest to the connector) that provides
 	 * EDID read support, if any (see &DRM_BRIDGE_OP_EDID).
@@ -256,26 +264,46 @@ static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
 		if (bridge->funcs->debugfs_init)
 			bridge->funcs->debugfs_init(bridge, root);
 	}
 }
 
-static void drm_bridge_connector_reset(struct drm_connector *connector)
+static struct drm_connector_state *
+drm_bridge_connector_readout_state(struct drm_connector *connector,
+				   struct drm_atomic_state *state)
 {
 	struct drm_bridge_connector *bridge_connector =
 		to_drm_bridge_connector(connector);
+	struct drm_connector_state *conn_state;
+	struct drm_bridge *readout =
+		bridge_connector->bridge_connector_hw_readout;
+
+	if (connector->state)
+		connector->funcs->atomic_destroy_state(connector,
+						       connector->state);
+
+	conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL);
+	if (!conn_state)
+		return ERR_PTR(-ENOMEM);
+
+	__drm_atomic_helper_connector_state_reset(conn_state, connector);
 
-	drm_atomic_helper_connector_reset(connector);
 	if (bridge_connector->bridge_hdmi)
 		__drm_atomic_helper_connector_hdmi_reset(connector,
 							 connector->state);
+
+	if (readout)
+		readout->funcs->connector_hw_readout(readout, state, conn_state);
+
+	return conn_state;
 }
 
 static const struct drm_connector_funcs drm_bridge_connector_funcs = {
-	.reset = drm_bridge_connector_reset,
 	.detect = drm_bridge_connector_detect,
 	.force = drm_bridge_connector_force,
 	.fill_modes = drm_helper_probe_single_connector_modes,
+	.atomic_readout_state = drm_bridge_connector_readout_state,
+	.atomic_compare_state = drm_atomic_helper_connector_compare_state,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 	.debugfs_init = drm_bridge_connector_debugfs_init,
 	.oob_hotplug_event = drm_bridge_connector_oob_hotplug_event,
 };
@@ -671,10 +699,12 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 		if (!bridge->interlace_allowed)
 			connector->interlace_allowed = false;
 		if (!bridge->ycbcr_420_allowed)
 			connector->ycbcr_420_allowed = false;
 
+		if (bridge->ops & DRM_BRIDGE_OP_CONNECTOR_HW_READOUT)
+			bridge_connector->bridge_connector_hw_readout = bridge;
 		if (bridge->ops & DRM_BRIDGE_OP_EDID)
 			bridge_connector->bridge_edid = bridge;
 		if (bridge->ops & DRM_BRIDGE_OP_HPD)
 			bridge_connector->bridge_hpd = bridge;
 		if (bridge->ops & DRM_BRIDGE_OP_DETECT)
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 5ea63b51a4dd4cb00468afcf7d126c774f63ade0..7c401e905c023923f1f94daec746b56c3e478b83 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -1017,10 +1017,27 @@ struct drm_bridge_funcs {
 	 */
 	int (*dp_audio_mute_stream)(struct drm_bridge *bridge,
 				    struct drm_connector *connector,
 				    bool enable, int direction);
 
+	/**
+	 * @connector_hw_readout:
+	 *
+	 * Initializes the &struct drm_connector_state based on hardware
+	 * state.
+	 *
+	 * This callback is optional, it can be implemented by bridges
+	 * that set the @DRM_BRIDGE_OP_CONNECTOR_HW_READOUT flag in
+	 * their &drm_bridge->ops.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*connector_hw_readout)(struct drm_bridge *bridge,
+				    struct drm_atomic_state *state,
+				    struct drm_connector_state *conn_state);
+
 	/**
 	 * @debugfs_init:
 	 *
 	 * Allows bridges to create bridge-specific debugfs files.
 	 */
@@ -1138,10 +1155,14 @@ enum drm_bridge_ops {
 	/**
 	 * @DRM_BRIDGE_OP_HDMI_CEC_ADAPTER: The bridge requires CEC adapter
 	 * to be present.
 	 */
 	DRM_BRIDGE_OP_HDMI_CEC_ADAPTER = BIT(8),
+	/**
+	 * @DRM_BRIDGE_OP_CONNECTOR_HW_READOUT: TODO
+	 */
+	DRM_BRIDGE_OP_CONNECTOR_HW_READOUT = BIT(9),
 };
 
 /**
  * struct drm_bridge - central DRM bridge control structure
  */

-- 
2.50.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ