From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2ADA53B8BB2 for ; Thu, 23 Apr 2026 10:19:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776939579; cv=none; b=hcrTDtHR27sUbNVmEWgy2EArcgbg3RGIczLH4a28L2GodXo0jxmZ+IK1nqDyBKNzNZcZ7mLOqq0vAf0MaCoF/Zs/3OML/vXpQdzD7I+T3qhBzSyRyKu4ssu0m7Qvkw1s4b7JIttw0RArYqsZ0oj+JAxTKJ3GxGnWJt+jchmwt6Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776939579; c=relaxed/simple; bh=7oGv+KuomC0hME+fdl3tZpg638rIcvWxxi9tscwETuA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MlhhGBtcInby7gE/cQ8V++5/MhqA6QCOui0BOcj8SD9mkxVwcdgODHUz/WEKdfV23urJ/pc8we5bcm3p/LtxEcv9+btY0U2mm8NmibAyyP3gM7n3/N6Z01rjzQtg62uFTKKkAap8uwE7G2q70SKJVVLSV/HTRTa7HUr+FIed8Nk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UcCqf2Zy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UcCqf2Zy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ADC84C2BCB5; Thu, 23 Apr 2026 10:19:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776939579; bh=7oGv+KuomC0hME+fdl3tZpg638rIcvWxxi9tscwETuA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UcCqf2Zy7ktDDCPU0P3b4VbBQ6Gci2B5bfnqF7SnhYyaAts9MjS+ZQZCUVQ/KhPsH 18MorZjugSCAWpDXVSwn296RNNPoIOZL1EyEyzK0FnoxsK+iFHB31YWAU9IUpzj/b5 EySGnWXx6pqVX5ZLGXu4em2gnb9ht0lHMafrW0BddB0Vpl0g5cfx9Qn/+NTFtHUxin oegU1MpDLmBqfvgum3Rb+3rDiBh+XGcRUbQ/6TvtWlQa9/t1ufcrR8tP6bN/Ws0mNV adk1hEyFvhgGCIBcYJBaPrV7+6Wc7KDJ2Vpe2OD6UVjhQSHNaD8bztqa9y2WUNYEJD 5/qRefepPS2NQ== From: Maxime Ripard Date: Thu, 23 Apr 2026 12:18:37 +0200 Subject: [PATCH v2 24/28] drm/bridge_connector: Implement hw readout for connector Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260423-drm-state-readout-v2-24-8549f87cb978@kernel.org> References: <20260423-drm-state-readout-v2-0-8549f87cb978@kernel.org> In-Reply-To: <20260423-drm-state-readout-v2-0-8549f87cb978@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Simona Vetter , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Jyri Sarha , Tomi Valkeinen Cc: Devarsh Thakkar , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Maxime Ripard X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5687; i=mripard@kernel.org; h=from:subject:message-id; bh=7oGv+KuomC0hME+fdl3tZpg638rIcvWxxi9tscwETuA=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDJkvP356nmd5bNKKuPSLTP5dYksZ+U4s4nsiUr+w8NPUc yWZLmnyHVNZGIQ5GWTFFFmeyISdXt6+uMrBfuUPmDmsTCBDGLg4BWAic18y1gqePjYj4sGGjsmZ GYxy3w8p/2LI/Gqz4UBSwu5nnr0tMmyrvf2fNURsVji9Mu3unI+7bzPWh3Wlv3LZEOW3dV7wdCV h9ZuhR58uPKnaXR7yQarErejvMT/Z49vvqfScjNOfsn3vTBE5AA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D 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, implement a new op for bridge_connector to allow just that. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_bridge_connector.c | 31 ++++++++++++++++++++++++++ include/drm/drm_bridge.h | 27 ++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 4b310fe505b4..43f6de5c1295 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -8,10 +8,11 @@ #include #include #include #include +#include #include #include #include #include #include @@ -64,10 +65,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). @@ -281,15 +290,33 @@ drm_bridge_connector_create_state(struct drm_connector *connector) conn_state); return conn_state; } +static int +drm_bridge_connector_readout_state(struct drm_connector *connector, + struct drm_atomic_sro_state *state, + struct drm_connector_state *conn_state) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *readout = + bridge_connector->bridge_connector_hw_readout; + + if (readout) + readout->funcs->atomic_sro_connector_readout(readout, state, conn_state); + + return 0; +} + static const struct drm_connector_funcs drm_bridge_connector_funcs = { .detect = drm_bridge_connector_detect, .force = drm_bridge_connector_force, .fill_modes = drm_helper_probe_single_connector_modes, .atomic_create_state = drm_bridge_connector_create_state, + .atomic_sro_readout_state = drm_bridge_connector_readout_state, + .atomic_sro_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, }; @@ -831,10 +858,14 @@ 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) { + drm_bridge_put(bridge_connector->bridge_connector_hw_readout); + bridge_connector->bridge_connector_hw_readout = drm_bridge_get(bridge); + } /* * Ensure the last bridge declares OP_EDID or OP_MODES or both. */ if (bridge->ops & DRM_BRIDGE_OP_EDID || bridge->ops & DRM_BRIDGE_OP_MODES) { drm_bridge_put(bridge_connector->bridge_edid); diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 36d558a5cd4d..17c863da5d6d 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -1006,10 +1006,30 @@ struct drm_bridge_funcs { */ int (*dp_audio_mute_stream)(struct drm_bridge *bridge, struct drm_connector *connector, bool enable, int direction); + /** + * @atomic_sro_connector_readout: + * + * This optional hook initializes the &struct drm_connector_state + * based on hardware state. + * + * It is implemented by bridges that set the + * %DRM_BRIDGE_OP_CONNECTOR_HW_READOUT flag in their + * &drm_bridge.ops. When using drm_bridge_connector, the last + * bridge in the chain with this flag set will have its hook + * called to fill the connector state. + * + * RETURNS: + * + * 0 on success, a negative error code otherwise. + */ + int (*atomic_sro_connector_readout)(struct drm_bridge *bridge, + struct drm_atomic_sro_state *state, + struct drm_connector_state *conn_state); + /** * @debugfs_init: * * Allows bridges to create bridge-specific debugfs files. */ @@ -1146,10 +1166,17 @@ enum drm_bridge_ops { * @DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME: The bridge supports * &drm_bridge_funcs->hdmi_write_spd_infoframe and * &drm_bridge_funcs->hdmi_clear_spd_infoframe callbacks. */ DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME = BIT(10), + /** + * @DRM_BRIDGE_OP_CONNECTOR_HW_READOUT: The bridge supports the + * &drm_bridge_funcs.atomic_sro_connector_readout callback to + * fill the connector state from the bridge's own hardware state + * during state readout. + */ + DRM_BRIDGE_OP_CONNECTOR_HW_READOUT = BIT(11), }; /** * struct drm_bridge - central DRM bridge control structure */ -- 2.53.0