From nobody Fri Oct 3 11:14:53 2025 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 5B4C2270576 for ; Tue, 2 Sep 2025 08:33:12 +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=1756801992; cv=none; b=dR8KNIn1tBX9YIhQpS7FHnsxTrSqNkWYRlm1eNpMOIkzJHWnmKkYISCzNpnPFXanOsppKTKqVffHkmHjHS+eOvJulinBJutJa7LWKCn4bP2ncvH4hKc/xgQkgD/6GhDStl8VRBQYH9qbU72POeuiys89Dmr73krltSF1Rh383Jk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756801992; c=relaxed/simple; bh=RSw/FevPuIg72kLXYX+y6FE8T6rOeXx1VhHt9C78V7E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rAqrnmKzHkDQ2D2GlNg7w024Qjfd922MD9FnFCxeFOYxLQUw7ACUS9LNGMQM/7C7ohh2KvOF2v73tRwearKKhNSdPyfiJeXcZDeZlkChzUOKe7g4KnkI2wesSnU6m0cOvyK6Of7N+DAbZGaBH+PdHcChHVvMJVzZjIRBaI30/yA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WbrmIWsV; 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="WbrmIWsV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 99999C4CEF5; Tue, 2 Sep 2025 08:33:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756801991; bh=RSw/FevPuIg72kLXYX+y6FE8T6rOeXx1VhHt9C78V7E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WbrmIWsVxfHKK/d2jEVc/uodasQaXUxSPenru2Sn8bPUmc7lY/els15Tr/ze+Qb3k G+TO8bbbuQ6hxyOE+WstZedrxyQx9be52h+G4IsXZEuJTgrCBJbxW9SMkN47u2FZco efOxGr7BpmEUGFN8u4+WhGokvYzvFRjNXJmnvxxnIxaxxfImQW5gRYSFb5QDve9Hpq 1i4vk+EPbAHfavbvgIMkHpA2p5KE3Q9fw+S/sBYcaZQU03gMdGXFHlOmAXJueatuA1 Yb2evOmGFr7hpkY9bi1IxfWgBUQFCNjmhgbjbznsQzZSl5gRwz1Y1co33CaSqiHLEV ytDu1Lqs+zipg== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:29 +0200 Subject: [PATCH 01/29] drm/atomic: Document atomic state lifetime 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-1-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3774; i=mripard@kernel.org; h=from:subject:message-id; bh=RSw/FevPuIg72kLXYX+y6FE8T6rOeXx1VhHt9C78V7E=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVm+1FDpzW7NSZoNK288LE1UDtSPzzu6+73jK7ce6Z 6GXJabt7JjKwiDMySArpsjyRCbs9PL2xVUO9it/wMxhZQIZwsDFKQAT+cLBWF8w4Ylg6Qq2+2Yf Vgium5h0f94t0Tuqr5ctjXOubktqWfZXOkR0ak906r7d5tqW/zRcXjA2tFvnnek4yT/tceDk0NC Hrzacl2i9HfalbPVJw7OlzRWH42cvPvZj6kenG9FHuCKbWUtkAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D How drm_atomic_state structures and the various entity structures are allocated and freed isn't really trivial, so let's document it. Signed-off-by: Maxime Ripard --- Documentation/gpu/drm-kms.rst | 6 ++++++ drivers/gpu/drm/drm_atomic.c | 45 +++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 51 insertions(+) diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index abfe220764e1edc758a6bc6fb5ff9c8e1c7749ff..dc0f61a3d29e752889077d855a4= bea381f2e2c18 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -280,10 +280,16 @@ structure, ordering of committing state changes to ha= rdware is sequenced using :c:type:`struct drm_crtc_commit `. =20 Read on in this chapter, and also in :ref:`drm_atomic_helper` for more det= ailed coverage of specific topics. =20 +Atomic State Lifetime +--------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :doc: state lifetime + Handling Driver Private State ----------------------------- =20 .. kernel-doc:: drivers/gpu/drm/drm_atomic.c :doc: handling driver private state diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index cd15cf52f0c9144711da5879da57884674aea9e4..b356d26faad4acaa25c1fe6f9bd= 5043b6364ce87 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -44,10 +44,55 @@ #include =20 #include "drm_crtc_internal.h" #include "drm_internal.h" =20 +/** + * DOC: state lifetime + * + * &struct drm_atomic_state represents an update to video pipeline state. + * + * Its lifetime is: + * + * - at reset time, the entity reset implementation will allocate a + * new, default, state and will store it in the entity state pointer. + * + * - whenever a new update is needed: + * + * + we allocate a new &struct drm_atomic_state using drm_atomic_state_a= lloc(). + * + * + we copy the state of each affected entity into our &struct + * drm_atomic_state using drm_atomic_get_plane_state(), + * drm_atomic_get_crtc_state(), drm_atomic_get_connector_state(), or + * drm_atomic_get_private_obj_state(). That state can then be + * modified. + * + * At that point, &struct drm_atomic_state stores three state + * pointers for that particular entity: the old, new, and existing + * (called "state") states. The old state is the state currently + * active in the hardware, ie either the one initialized by reset() + * or a newer one if a commit has been made. The new state is the + * state we just allocated and we might eventually commit to the + * hardware. The existing state points to the state we'll eventually + * have to free, the new state for now. + * + * + Once we run a commit, it is first checked and if the check is + * successful, it is committed. Part of the commit is a call to + * drm_atomic_helper_swap_state() which will turn the new state into + * the active state. Doing so involves updating the entity state + * pointer (&drm_crtc.state or similar) to point to the new state, + * and the existing state will now point to the old state, that used + * to be active but isn't anymore. + * + * + When the commit is done, and when all references to our &struct + * drm_atomic_state are put, drm_atomic_state_clear() runs and will + * free all the old states. + * + * + Now, we don't have any active &struct drm_atomic_state anymore, + * and only the entity active states remain allocated. + */ + void __drm_crtc_commit_free(struct kref *kref) { struct drm_crtc_commit *commit =3D container_of(kref, struct drm_crtc_commit, ref); =20 --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 6CFA22E7167 for ; Tue, 2 Sep 2025 08:33:15 +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=1756801995; cv=none; b=WLDzf9CylcpvpXW60JyKZ3HscypkR3nJK/5DQFyu1F+odYTdq84OxxyzZM0+rh8LWMFwmvH+W5s/tKEjothITms+seoiQALcdFZw3LMoc/vDUa8P0mYfv+XNXlF6eZx1JWYSWiyb/LHkftSusQ9rEqXE5p/lqnjGFrPfIOgQ/SY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756801995; c=relaxed/simple; bh=kj637CfnoTBAP2JHnQ7FgGsKAbZI6lr9iDOVp8nZO54=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NSeGg+x+6B9Gn6+rccEGKBOiugYVMIkOuOQipd9sAl1c8YaGcDhGnCpk8SCsAHkajNhhYMW+6Ns146TXeKM38GMoYHVV7A8avBRA3wX9krdDcZBrY7m3vK2QI1KfJwQy418P2weelBeVzzPJy/7qW+T9lrBVOdsyBdYoyf+eOII= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=acf/IRqR; 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="acf/IRqR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB278C4CEF8; Tue, 2 Sep 2025 08:33:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756801995; bh=kj637CfnoTBAP2JHnQ7FgGsKAbZI6lr9iDOVp8nZO54=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=acf/IRqRy1dKrnhfcpuPZZu44SXxfHaD14eBvgxd4JmMIxSlQ87quAx8LQubSh255 GW1XQW7Zxil7fd5WdQnYdnzWn99MBI0mi4UYjS3wmmNvuM7S88IWe8P5hBknorwid8 rc50C7zdWWy3mKnO9m4ZzwErsy6+xeJXJJmlVvBNNL/sF1eTQEFz9yYfPxZ3ivyMMh ARMNJLDp3SshojoG8Rx/xgCOuoa7cigmtaLmXDpa8RiH1SMuqlZG0DdAIjJpyYz+XI ZfSm/HjAd3JfCtuy57PAmXPAOtmrkbwWGdXSS8PCECrH2Yrtk6rxWToI6CG5JSLmWz 6o1qq/79PfnVw== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:30 +0200 Subject: [PATCH 02/29] drm/atomic: Fix unused but set warning in for_each_old_plane_in_state 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-2-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1285; i=mripard@kernel.org; h=from:subject:message-id; bh=kj637CfnoTBAP2JHnQ7FgGsKAbZI6lr9iDOVp8nZO54=; b=kA0DAAkTJ1/OGaI9vnYByyZiAGi2q7Wjc6mfQDqijIooGWom/m600NFGVJUGNt33Gto+wV8sg IiVBAATCQAdFiEE5BxWy6eHo3pAP6n4J1/OGaI9vnYFAmi2q7UACgkQJ1/OGaI9vnYnbQF/YvG2 Mr1FKSJx5wr1GHBZJIDiihazgl00jO7Xszl0BjZNfpnxCVP6m2FEDiBw2jwBAX44O5ak4Zsn4aM gII9+PMoeUuQ6Dv892qnsDEffFrD+UnaaPoijyzSW5OF2wjpHG0E= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The for_each_old_plane_in_state() macro triggers a compiler warning if the plane parameter passed to it isn't used in the code block. Add a similar workaround than in most other macros. Signed-off-by: Maxime Ripard Reviewed-by: Laurent Pinchart Reviewed-by: Thomas Zimmermann --- include/drm/drm_atomic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 38636a593c9d98cadda85ccd67326cb152f0dd27..689a29bdeb4a06672ab6fffecb5= 13d58ff6e07f9 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -1053,11 +1053,13 @@ void drm_state_dump(struct drm_device *dev, struct = drm_printer *p); for ((__i) =3D 0; \ (__i) < (__state)->dev->mode_config.num_total_plane; \ (__i)++) \ for_each_if ((__state)->planes[__i].ptr && \ ((plane) =3D (__state)->planes[__i].ptr, \ + (void)(plane) /* Only to avoid unused-but-set-variable warning */= , \ (old_plane_state) =3D (__state)->planes[__i].old_state, 1)) + /** * for_each_new_plane_in_state - iterate over all planes in an atomic upda= te * @__state: &struct drm_atomic_state pointer * @plane: &struct drm_plane iteration cursor * @new_plane_state: &struct drm_plane_state iteration cursor for the new = state --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 809292E8E14 for ; Tue, 2 Sep 2025 08:33:18 +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=1756801998; cv=none; b=Ca3apEzAUPMk9UL/9rQN0niHr2Nvj7rn5HkoDaOLfKz0hZZHKl8B8LEqydmuuraj71FdpMadXvw3qw7FwTKVNe467CXTzMcDWn/v5DBHbYmul6jwQc4pYoxDvD8dWssI+v06VvASzWT1F8MzRPr5uO9BD4eNBQ3fn6IprtqjhfA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756801998; c=relaxed/simple; bh=tgHDqH0C2lxD8T1iP02FKrEoh+NLndcjoc9fVjgWywI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PIUeq4ev0JqpqnFsV2eaSEfy4r4D1ZKiJlLrHyeV7CxleRe7vPULz48YcZGT/vduM+8W285zXqWX9sY8+zeZAgp7lek1V12XcPyPGIVzl7HcHZQUnSDSxt9Z7/yg3YuhnsWkRjLFMOjv4QxgW7rTypqCNhjGhfN5c7+l3dgJD/w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GSvf1ZRW; 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="GSvf1ZRW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9CFD8C4CEF8; Tue, 2 Sep 2025 08:33:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756801998; bh=tgHDqH0C2lxD8T1iP02FKrEoh+NLndcjoc9fVjgWywI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GSvf1ZRW043A+UcKUKqeHcK77lMflTHce9vslIVN6tX0h1WQO7X+d209fBd0Fg5IB mb/L0aSOeNYDVIur9m57FnCU92BZ0JrLft879cwqD92WY6N2hPon0s7bAOA3op+Lr6 JJzOqHDthW9vi5gGk7FjvnV8QF1jlNc/cTww3IkFSg1s9ghvysA+OweXqhRESDrr6N hvG3bbz0RSc7qbckco5LgeUYnM3pLSguRa/5XZ1e9sUBT8cJdvVRL2QUtKIU4TSqWK 40+vu2Y7OQ/gCkRLJNluhS94ExUYV+uIzoneeW3pZUB04l0Pf1L24vBfow5oBdTdyg +WMEOwSswVOJw== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:31 +0200 Subject: [PATCH 03/29] drm/atomic: Fix unused but set warning in for_each_old_private_obj_in_state 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-3-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1137; i=mripard@kernel.org; h=from:subject:message-id; bh=tgHDqH0C2lxD8T1iP02FKrEoh+NLndcjoc9fVjgWywI=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVm/1EHQJlu5+OudfzbIK1pk3de3eV6Y8jkm6vfZ7s utU1bDqjqksDMKcDLJiiixPZMJOL29fXOVgv/IHzBxWJpAhDFycAjCRzdKMDW84hRw38p3z4nR9 stLG/9DDWVL+Jf4/erjupE784eMhoXM3W7rG9Op/0WVOgTFvf98WYazTY+H4YOQZmega/d87P32 3bpzdmlSHw6vqT/sGsxU5WPF1nhZb/0Kf3dDcfm7ogb573wE= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The for_each_old_private_obj_in_state() macro triggers a compiler warning if the obj parameter passed to it isn't used in the code block. Add a similar workaround than in most other macros. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- include/drm/drm_atomic.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 689a29bdeb4a06672ab6fffecb513d58ff6e07f9..f13f926d21047e42bb9ac692c2d= d4b88f2ebd91c 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -1112,10 +1112,11 @@ void drm_state_dump(struct drm_device *dev, struct = drm_printer *p); */ #define for_each_old_private_obj_in_state(__state, obj, old_obj_state, __i= ) \ for ((__i) =3D 0; \ (__i) < (__state)->num_private_objs && \ ((obj) =3D (__state)->private_objs[__i].ptr, \ + (void)(obj) /* Only to avoid unused-but-set-variable warning */, \ (old_obj_state) =3D (__state)->private_objs[__i].old_state, 1); \ (__i)++) =20 /** * for_each_new_private_obj_in_state - iterate over all private objects in= an atomic update --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 208062E9733 for ; Tue, 2 Sep 2025 08:33:20 +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=1756802001; cv=none; b=lMLvAWmZqRJSP1wrHhtXjFJ/X73MZA4W2qDyr/m5/NFLEU45swJLBtV+EhMOFAfwu6mSp7Lk9AgkXc+JBJCW5H6FZr1Azci9XZl6Z5C/eksCYxOooIfBQLpbdERbIROqeDpcIh1R6kAiPvoW7+IuaEmN9SrsMf+bjwt+1CB11Xk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802001; c=relaxed/simple; bh=uSx8gxP4bhNu5Nz4ZWIuRfI4kUACjD7tGQ0Jp8coKBs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Voo6Rpnn2UuqByF28ho3SRm+IcULysF675T6KVLqHL/sxdiy/DxoMUZ78tENj9EEbmmQjDregmMopbRteGAAbfPmgo0YG+QfxB7VyToJ8SAo6JVfYEVZPjopd9SMrevRUrPwuIRHGwAHrvXWqu8GwhPi/h8adJZI7FfuUHa5KeI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q7LRzvje; 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="Q7LRzvje" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 608BFC4CEF8; Tue, 2 Sep 2025 08:33:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802000; bh=uSx8gxP4bhNu5Nz4ZWIuRfI4kUACjD7tGQ0Jp8coKBs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Q7LRzvjetM6f92/xddbunTpDsoStUcxjc428/OHH+Lt0A93m0hOnGE7EqXJYteCpt rawRyZzWPW/3l8B/u3ra2ixG0Er5YSEKW4j3d0MO1Kg7jGqFN7cMXVjP4ZzV/xQEAM 8OHjyr7aQmoUBTx8M78Avxxzf++BWrcyrXoI1FMfZECQ6H48EtnrzzS5XrG6EiWn8I JNiB+BZ6Roj8Wo/Mjk7Nbd3S51dJHS6qTJFWkKi5ZpYQQvdaQ0aKB8kyC4lsQSE41g GkNp72SO/MoOAI6PUpiCn6adTefbq26FKusWIAn8KyIgdMXJ12x/HM45GaGXZZv+/I GMV7XQb0Ytz9Q== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:32 +0200 Subject: [PATCH 04/29] drm/atomic_helper: Skip over NULL private_obj pointers 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-4-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=843; i=mripard@kernel.org; h=from:subject:message-id; bh=uSx8gxP4bhNu5Nz4ZWIuRfI4kUACjD7tGQ0Jp8coKBs=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVm/7HLDqv/qMaqFbwnc+T1g19WQfi3Cz1YWF7au+/ 7t2Zeu1yR1TWRiEORlkxRRZnsiEnV7evrjKwX7lD5g5rEwgQxi4OAVgIl+cGGvFXvBlLVgUPGvB 51QX0alme27t0ev+vtOF84T05AnfOdenbp8tEnto+sGZ61/dkN//R2IXY8OxqiXrmNK2/1LbxH2 8t/bzUb7tR/7+2Sdo3J74r/Z37OELdaZhQRJ9V+c9bLVjf7Cw5ygA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/drm_atomic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index b356d26faad4acaa25c1fe6f9bd5043b6364ce87..9b198610791d19c7fd276ca5926= 4a961d21caf43 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -295,10 +295,13 @@ void drm_atomic_state_default_clear(struct drm_atomic= _state *state) } =20 for (i =3D 0; i < state->num_private_objs; i++) { struct drm_private_obj *obj =3D state->private_objs[i].ptr; =20 + if (!obj) + continue; + obj->funcs->atomic_destroy_state(obj, state->private_objs[i].state); state->private_objs[i].ptr =3D NULL; state->private_objs[i].state =3D NULL; state->private_objs[i].old_state =3D NULL; --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 CA3082E9EC9 for ; Tue, 2 Sep 2025 08:33:23 +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=1756802003; cv=none; b=Dxp9U9YbVm50MlA5tv7SVdXXwgGdO+nVcWZOODuIXbN2ueG1j5yiUCiIDMhH/Igp1rQZBKmTyymt7vvpfWy7nSOKt3sNDpg7ZOHVPMB8O0S2n26ctsxXlP7ToZEve1i8xqgufr30p5MFfB1PuqugXz70pKsgjCBhj9bF+I3wNiA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802003; c=relaxed/simple; bh=ymXL3YOVpngIrQ5Uh/MtWSLd5T18BYRz7YHzVv+IsMw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rYK0ohT8J6vIeZIpm4nd5/7lnbeZTOm0SPFosU14OjGddWuKwsiWKbEI7+3y6cK0sDullGJJ+zbq9WoRtAaPCxWVKR27ofvO7Z6x72nlaCop0XaXdKSwKfop7MwcvwcIq3H1wH07GIdsrqYcGRVrqgE1/N55M5c2bf4X++GHYnY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lWexjkhO; 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="lWexjkhO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1FF86C4CEF8; Tue, 2 Sep 2025 08:33:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802003; bh=ymXL3YOVpngIrQ5Uh/MtWSLd5T18BYRz7YHzVv+IsMw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lWexjkhO/JciMGnbiWpcHeqAA0/F8ypD0TOktIDj+RDkjcoDKh8mjvI/A/ERUTJ7C +GstNNrTokBi7tX2wjfOt2pWBVmh6H4fj3FhCtAeEksK2I46WhvbIdYIXMxoHUipZw D8k5FzCe67qrR5sYCmpcq27KPHp1rToIO1Gju/323UlXXTeavKFf5/3ge90z1d+qKU 2KJBYKKo7WMieLXHlIn7ZvoPdxQhWLdksUxQJSZHOO5Cwe4+nDDV7EeihatT/IXwVn E9Nvsdqxxszw3cV3f0Sqyt8SXBykbJoVW5HCyLTu1xkNUthrbq3guGcHDt6fxp9thg Mtwiq5tAzBklQ== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:33 +0200 Subject: [PATCH 05/29] drm/atomic_state_helper: Fix bridge state initialization 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-5-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2006; i=mripard@kernel.org; h=from:subject:message-id; bh=ymXL3YOVpngIrQ5Uh/MtWSLd5T18BYRz7YHzVv+IsMw=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVm+bbJU35eXunS31k8pcFn1SXpW2fumR36/K5y6fV H23sUc4t2MqC4MwJ4OsmCLLE5mw08vbF1c52K/8ATOHlQlkCAMXpwBM5NQUxloR2y2zhB7eUVux 5aGTJefcv/fDT+0Mnv+2LVinmN8tdKv8rOc/e1Occidtm5RafLrtny5jwwzVFNsQtiM1uQpez0T fZIdxr0nN6jiRZhYw48LJ1uaix85VPpsMLer2ax7xUJ4rzjcNAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Bridges implement their state using a drm_private_obj and an hand-crafted reset implementation. Since drm_private_obj doesn't have a set of reset helper like the other states, __drm_atomic_helper_bridge_reset() was initializing both the drm_private_state and the drm_bridge_state structures. This initialization however was missing the drm_private_state.obj pointer to the drm_private_obj the state was allocated for, creating a NULL pointer dereference when trying to access it. Fixes: 751465913f04 ("drm/bridge: Add a drm_bridge_state object") Signed-off-by: Maxime Ripard Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/drm_atomic_state_helper.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/dr= m_atomic_state_helper.c index 7142e163e618ea0d7d9d828e1bd9ff2a6ec0dfeb..b962c342b16aabf4e3bea52a914= e5deb1c2080ce 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -707,10 +707,17 @@ void drm_atomic_helper_connector_destroy_state(struct= drm_connector *connector, __drm_atomic_helper_connector_destroy_state(state); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); =20 +static void __drm_atomic_helper_private_obj_reset(struct drm_private_obj *= obj, + struct drm_private_state *state) +{ + memset(state, 0, sizeof(*state)); + state->obj =3D obj; +} + /** * __drm_atomic_helper_private_obj_duplicate_state - copy atomic private s= tate * @obj: CRTC object * @state: new private object state * @@ -796,10 +803,11 @@ EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state); */ void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, struct drm_bridge_state *state) { memset(state, 0, sizeof(*state)); + __drm_atomic_helper_private_obj_reset(&bridge->base, &state->base); state->bridge =3D bridge; } EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset); =20 /** --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 7D5202EA16D for ; Tue, 2 Sep 2025 08:33:26 +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=1756802006; cv=none; b=m3uH23TKOjad3sy4iZgCxtPtcEvz4QXNIZof/d2AOGK4KVkloliycXXDYUWAwKNIeWk05uLjkQ1dsII1CqJjAjOyHI6EEAayYNlPiSCRsDljtzcS1Dfhs9BoQgwFjtRPauyEfQJVqQSgOHA41MO+7zXPlLBEJIyQXMf6O9uTcjQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802006; c=relaxed/simple; bh=dxIMcnZXqFeVSb69JHsUsUX0GPYjiSufclb+3jXwpPk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=INrRuWTIEovVNEtyF+9xFrIHZ3DRZZBYnBNSqbNBClEr6xVeb7b/ShTzUI+XN57pEicSgCbVy6Rq/uckXnQwYRY5pLbyH3nC6nsHPtseguhctUNE6PHCl4IDmOZ+5ngvD/ZVYKsa/bCj12ujrDfy7zkvxjxRmN9ZHhwm4VCHP+4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RLwRQkRk; 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="RLwRQkRk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ADF74C4CEF8; Tue, 2 Sep 2025 08:33:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802006; bh=dxIMcnZXqFeVSb69JHsUsUX0GPYjiSufclb+3jXwpPk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RLwRQkRkACo8pJRB/IOaydCjEX9xJZO0bdZN0LzGLB4IdrnEX2pQotjgtbY4xlyUW QANwKYBfKiCu74x8HEf8s8GF94BqDmCJOvwNXZ0HkLasguNGBnlmyuC+G1xwm6f237 hFu6JaEqQjuBwOEmqRyyZcLubz0siwI6ziRshnMfOC4x6djhNn6ugvj5uJgXRrNwYD 1+eE67KVo5bwJqnHyQ0/0etHAOJAa05is/4HE0d/cXSpaqk6nBF7aJwj8trVMSurFz NIIQ2rVR1TEs5iSIKArbOCkHpVQ6eXoz3yzssAfTRxv/8lgJ3NBd7rFVJuqIUdj5IX oxA9TGheorNbA== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:34 +0200 Subject: [PATCH 06/29] drm/bridge: Implement atomic_print_state 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-6-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1891; i=mripard@kernel.org; h=from:subject:message-id; bh=dxIMcnZXqFeVSb69JHsUsUX0GPYjiSufclb+3jXwpPk=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVm93P2Qj3zpBa+Nan9cH/k6eHX7So2Azw9FM74QfV zm+rzhyrGMqC4MwJ4OsmCLLE5mw08vbF1c52K/8ATOHlQlkCAMXpwBM5JE6Y31YjCkbr7K8zbPi N4ePhexQ/ju56ezvTZk+is3CtUk7TJJ4/hmHcH3qVv58XXrDqq9xgowNsx9Yz3ebrl9ztibjML9 6ePSv/Vf/P1JTaXJW0/yjKuKgkVH/x+hOAROfgavvhdKVC8sB X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Bridges have some fields in their state worth printing, but we don't provide an atomic_print_state implementation to show those fields. Let's do so. Signed-off-by: Maxime Ripard Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/drm_bridge.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index dd439d55177a867acb7ab73c02182bada44d93c9..e803dfd8fd5aae9c16931445213= df04d8715b9f6 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -370,13 +370,31 @@ drm_bridge_atomic_destroy_priv_state(struct drm_priva= te_obj *obj, struct drm_bridge *bridge =3D drm_priv_to_bridge(obj); =20 bridge->funcs->atomic_destroy_state(bridge, state); } =20 +static void +drm_bridge_atomic_print_priv_state(struct drm_printer *p, + const struct drm_private_state *s) +{ + const struct drm_bridge_state *state =3D + container_of_const(s, struct drm_bridge_state, base); + struct drm_bridge *bridge =3D drm_priv_to_bridge(s->obj); + + drm_printf(p, "bridge: %s", drm_get_connector_type_name(bridge->type)); + drm_printf(p, "\tinput bus configuration:"); + drm_printf(p, "\t\tcode: %04x", state->input_bus_cfg.format); + drm_printf(p, "\t\tflags: %08x", state->input_bus_cfg.flags); + drm_printf(p, "\toutput bus configuration:"); + drm_printf(p, "\t\tcode: %04x", state->output_bus_cfg.format); + drm_printf(p, "\t\tflags: %08x", state->output_bus_cfg.flags); +} + static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = =3D { .atomic_duplicate_state =3D drm_bridge_atomic_duplicate_priv_state, .atomic_destroy_state =3D drm_bridge_atomic_destroy_priv_state, + .atomic_print_state =3D drm_bridge_atomic_print_priv_state, }; =20 static bool drm_bridge_is_atomic(struct drm_bridge *bridge) { return bridge->funcs->atomic_reset !=3D NULL; --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 5ECBF2EA17E for ; Tue, 2 Sep 2025 08:33:28 +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=1756802010; cv=none; b=Zvp07FbJaKPEE0XwhV8gSyMyU0HAIjNNiMfUhAtjwp7MuC7ilZjKz2+dJ87r9vtF6C+KdQXEMffYDorTmPoEnnQupoG+kg88fbp+buLZf+9UDByrJcrXkete+V4HZLE/h2v1dGNyRY2Kj0xc1KPrH4ZxvN0rntjzfl93Jyq1JBw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802010; c=relaxed/simple; bh=1R/cmhynuL7ZkKUF0HfDvx8YnoSqeyk82pR1KuKcrL0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A7nUapiFdj0N+5YrLp04SaEexg+YpCUCWgV66Ggl+37Hr1/EydvgZcGQtHq0PpSiuZrI8htK25pERG8DcZ5mz5uK1dro//zJnpXST8SqTuNXJ3YaUc1nCAIha6Ziw67RbqHHKLyIyfbDlZEIfWC/D2PkMyuh8eGrittzTSrwLYk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rVDAv5rs; 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="rVDAv5rs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E4F0C4CEF7; Tue, 2 Sep 2025 08:33:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802008; bh=1R/cmhynuL7ZkKUF0HfDvx8YnoSqeyk82pR1KuKcrL0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rVDAv5rsYs5Eg2FMQbAnvGb/nmo0/W1SCh+813xyTz0ayU50iPpplEQOh+VWYZy64 sm1ap9xpC4Da6PvBWw5jDvru+wpLDM/2LWu0Mb878h2ZCj8EU7KSBUukSOJCvd9B+z 4a5piVrvodkd3KIDZ47tk/uOPulwzjyKGGjEBTb/wWs1zFeQZaXfYOp4MUhAVwmFQ1 JgOXVfWP4MJZeJGnmvKYujVOjT2D7S8h/tSXDE/d3o1iPKwojKncoVuzeiXKsptcSZ mmO85QXTe+pLOHOHr7vakv/0QXLWR8388MZJvpfqoLixY6lne0Du6amRlrWGca8xYm g3LTEk75Z5jIg== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:35 +0200 Subject: [PATCH 07/29] drm/atomic: Implement drm_atomic_print_old_state 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-7-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3588; i=mripard@kernel.org; h=from:subject:message-id; bh=1R/cmhynuL7ZkKUF0HfDvx8YnoSqeyk82pR1KuKcrL0=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVm9/c31t2Dx/6at9gnwPTixN2/RMXiL83dzp0WceK z/VLIni6ZjKwiDMySArpsjyRCbs9PL2xVUO9it/wMxhZQIZwsDFKQATUf3PWJ9T7tX42PfpbKcn iquSluzj8j3qc/hQqo3T0dkZ/qFCDmc0jXWmFT9StJUr+7+YbY70T8aGB04uqnuDJhc7K+cxTPD OPHfK79xnjqPTtl6verjgVnPzPa34Ux1J259PEnXYY7y7Su8KAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D We currently have a helper to print the new states associated to a drm_atomic_state, but we don't have a variant to print the old state. It's somewhat expected, since we almost never care about what the new state looks like when we commit a new state, but we're about to change that. Signed-off-by: Maxime Ripard Reviewed-by: Laurent Pinchart Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/drm_atomic.c | 45 +++++++++++++++++++++++++++++++++= ++++ drivers/gpu/drm/drm_crtc_internal.h | 2 ++ 2 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 9b198610791d19c7fd276ca59264a961d21caf43..38f2b2633fa992b3543e8c425c7= faeab1ce69765 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1875,10 +1875,55 @@ void drm_atomic_print_new_state(const struct drm_at= omic_state *state, for_each_new_private_obj_in_state(state, obj, obj_state, i) drm_atomic_private_obj_print_state(p, obj_state); } EXPORT_SYMBOL(drm_atomic_print_new_state); =20 +/** + * drm_atomic_print_old_state - prints drm atomic state + * @state: atomic configuration to check + * @p: drm printer + * + * This functions prints the drm atomic state snapshot using the drm print= er + * which is passed to it. This snapshot can be used for debugging purposes. + * + * Note that this function looks into the old state objects and hence its = not + * safe to be used after the call to drm_atomic_helper_commit_hw_done(). + */ +void drm_atomic_print_old_state(const struct drm_atomic_state *state, + struct drm_printer *p) +{ + struct drm_plane *plane; + struct drm_plane_state *plane_state; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + struct drm_connector_state *connector_state; + struct drm_private_obj *obj; + struct drm_private_state *obj_state; + int i; + + if (!p) { + drm_err(state->dev, "invalid drm printer\n"); + return; + } + + drm_dbg_atomic(state->dev, "checking %p\n", state); + + for_each_old_plane_in_state(state, plane, plane_state, i) + drm_atomic_plane_print_state(p, plane_state); + + for_each_old_crtc_in_state(state, crtc, crtc_state, i) + drm_atomic_crtc_print_state(p, crtc_state); + + for_each_old_connector_in_state(state, connector, connector_state, i) + drm_atomic_connector_print_state(p, connector_state); + + for_each_old_private_obj_in_state(state, obj, obj_state, i) + drm_atomic_private_obj_print_state(p, obj_state); +} +EXPORT_SYMBOL(drm_atomic_print_old_state); + static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, bool take_locks) { struct drm_mode_config *config =3D &dev->mode_config; struct drm_plane *plane; diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc= _internal.h index 89706aa8232fc0b2830af67c7588985a29653299..a8139fda1a1015c2ac8d8af3b12= c5ac0b00cfc1a 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -249,10 +249,12 @@ int __drm_atomic_helper_disable_plane(struct drm_plan= e *plane, int __drm_atomic_helper_set_config(struct drm_mode_set *set, struct drm_atomic_state *state); =20 void drm_atomic_print_new_state(const struct drm_atomic_state *state, struct drm_printer *p); +void drm_atomic_print_old_state(const struct drm_atomic_state *state, + struct drm_printer *p); =20 /* drm_atomic_uapi.c */ int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, struct drm_connector *connector, int mode); --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 E37412EA47F for ; Tue, 2 Sep 2025 08:33:31 +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=1756802012; cv=none; b=NAOR2Pxdt0RARY98b3QXIecjy+3iLpTosaZrovwtudOWT+fLuKEn41tEmcA7iBu5XomdCd06LdGsabsE0PJb+XQmVDPgdzvfdIqvk5aPUdBl5O0AQS0FGKiumsX+RGqnjoCGcXfaXPDeP9tUlT8svYmZOBCq4xlA6up92/AvqKg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802012; c=relaxed/simple; bh=LFeGHCO304zdeHgumCSjX6EUrk3szDEz7RjVAng3QuU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DEt1sjGG4H/Bz4jCoKLLG3Wzl+bTG+/JEoR3HD4vRf61mOclgeIkRq/YA4Ns+tpYA6zo3Z7CdcKnPsBu1v/B1jj9FP7i/UGfyCDp/NXSYXXCNULNbUMjbiiuoQs5JaWXJCl2UWph7yaUIOGwt7CJCL7mnYyjHnKIySRiCWKOqN0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rOHZAMRP; 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="rOHZAMRP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 25B72C4CEFA; Tue, 2 Sep 2025 08:33:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802011; bh=LFeGHCO304zdeHgumCSjX6EUrk3szDEz7RjVAng3QuU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rOHZAMRP/UBRLCKs4/YieUn0EkFRq9F1Tryx52shs/O5so9vD9YeiDJEgmKoTL8at +ZjtmCrTiGx8w/R6Swu54MqPdvkNrb8TXx/jwzVR8uPCAhZef3ByCuJ96jfE8AaqAO Mbtw0fNju+Dmpe17ShKQgX1RKOeNk0FwRNjiMQrsjhrmaFE67UJb7kqe8C8kUGyvSA 1U4V9lzPeC8XHHoPO01b1cUez2Uq+6QGfhFwxj+Tz4IM8VPClgOZvhKGi5a1C+COsR BhdL5dJbxh0qZPC3CwG3/zXbLjOT+m+gz4Cm3pwj9tAzMBVRp93WChu8NuFz7CHAzF VR1yTp/wtT7IA== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:36 +0200 Subject: [PATCH 08/29] drm/atomic: Only call atomic_destroy_state on a !NULL pointer 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-8-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3581; i=mripard@kernel.org; h=from:subject:message-id; bh=LFeGHCO304zdeHgumCSjX6EUrk3szDEz7RjVAng3QuU=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu+Qv9mXMrF1oWLUuV3n3mwL7aoOCTxYHfvGuWv1S oHoG3POdExlYRDmZJAVU2R5IhN2enn74ioH+5U/YOawMoEMYeDiFICJ1C5irI/8zcvk0GiR8r5x 8q91HDESKncyrtoEyDDN2fipLpzBKefuEt1H9dP+eVolPuHJ6j/lz9hwVeq7XvZW6dmOy8NW/D6 fkazxNCyqoHlp7MYTb98ti7v+w7B10hKePQs5eLoDVr25zycMAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The drm_atomic_state structure is freed through the drm_atomic_state_put() function, that eventually calls drm_atomic_state_default_clear() by default when there's no active users of that state. It then iterates over all entities with a state, and will call the atomic_destroy_state callback on the state pointer. The state pointer is mostly used these days to point to which of the old or new state needs to be freed, depending on whether the state was committed or not. So it all makes sense. However, with the hardware state readout support approaching, we might have a state, with multiple entities in it, but no state to free because we want them to persist. In such a case, state is going to be NULL, and thus we'll end up with NULL pointer dereference. In order to make it work, let's first test if the state pointer isn't NULL before calling atomic_destroy_state on it. Signed-off-by: Maxime Ripard Reviewed-by: Laurent Pinchart Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/drm_atomic.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 38f2b2633fa992b3543e8c425c7faeab1ce69765..f26678835a94f40da56a8c1297d= 92f226d7ff2e2 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -249,12 +249,14 @@ void drm_atomic_state_default_clear(struct drm_atomic= _state *state) struct drm_connector *connector =3D state->connectors[i].ptr; =20 if (!connector) continue; =20 - connector->funcs->atomic_destroy_state(connector, - state->connectors[i].state); + if (state->connectors[i].state) + connector->funcs->atomic_destroy_state(connector, + state->connectors[i].state); + state->connectors[i].ptr =3D NULL; state->connectors[i].state =3D NULL; state->connectors[i].old_state =3D NULL; state->connectors[i].new_state =3D NULL; drm_connector_put(connector); @@ -264,12 +266,13 @@ void drm_atomic_state_default_clear(struct drm_atomic= _state *state) struct drm_crtc *crtc =3D state->crtcs[i].ptr; =20 if (!crtc) continue; =20 - crtc->funcs->atomic_destroy_state(crtc, - state->crtcs[i].state); + if (state->crtcs[i].state) + crtc->funcs->atomic_destroy_state(crtc, + state->crtcs[i].state); =20 state->crtcs[i].ptr =3D NULL; state->crtcs[i].state =3D NULL; state->crtcs[i].old_state =3D NULL; state->crtcs[i].new_state =3D NULL; @@ -284,12 +287,14 @@ void drm_atomic_state_default_clear(struct drm_atomic= _state *state) struct drm_plane *plane =3D state->planes[i].ptr; =20 if (!plane) continue; =20 - plane->funcs->atomic_destroy_state(plane, - state->planes[i].state); + if (state->planes[i].state) + plane->funcs->atomic_destroy_state(plane, + state->planes[i].state); + state->planes[i].ptr =3D NULL; state->planes[i].state =3D NULL; state->planes[i].old_state =3D NULL; state->planes[i].new_state =3D NULL; } @@ -298,12 +303,14 @@ void drm_atomic_state_default_clear(struct drm_atomic= _state *state) struct drm_private_obj *obj =3D state->private_objs[i].ptr; =20 if (!obj) continue; =20 - obj->funcs->atomic_destroy_state(obj, - state->private_objs[i].state); + if (state->private_objs[i].state) + obj->funcs->atomic_destroy_state(obj, + state->private_objs[i].state); + state->private_objs[i].ptr =3D NULL; state->private_objs[i].state =3D NULL; state->private_objs[i].old_state =3D NULL; state->private_objs[i].new_state =3D NULL; } --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 3E93F2EA727 for ; Tue, 2 Sep 2025 08:33:34 +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=1756802014; cv=none; b=jEfpQ+FjArDGYh1neHzVHFf4HIsWVG5kUD7EfxJcGauIik0vTmIO0fUuCALPQxwiz0Gp7+JfnsXPMcciKHqv+JeAeZZGvSZZp0fI2vZ77tY4rVbn4Usa49BJNhU4kQLR1u/c2bIjz2tNElW6rWehlMt1rIhzoGuH3k1TZB1EKG4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802014; c=relaxed/simple; bh=tYWbhWVz7/WzG6D4UTlvcHo5uy6UD1fyI7Smwm5aU8k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RRBpMTJrxfpMt+e2cFv9ue7oQXidjKqGrwcFmU52FyLnQa8Woi4jqbpGUC8YRP31jlgrF5XsX1sIujE+2RwfjNMoUUgXGYVGufd8PLp68qf1L+hlD/4Kqng2HovMtQmFK9DVDQAaRit3PWFDfN4O7ufEKBtEZy5hEJLa86Ybvko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RBf7VqFj; 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="RBf7VqFj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB198C4CEF5; Tue, 2 Sep 2025 08:33:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802014; bh=tYWbhWVz7/WzG6D4UTlvcHo5uy6UD1fyI7Smwm5aU8k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RBf7VqFjkbBejKpgk+Q2+khPlQSWfhSitMYebCUh3qOFRDn+pIdlqBLKtYTc3DeqX 3PiWTDDioLHNGZ7XwGuF28p1EUGIM1IF0I5gSMaavdA08IZqHnjZppWm5OZP+MS7/Y IuSi0aPDfP9G6yQ+fJiIwH/Ckox4KxRHFzX9teA9jwFDihfDwuM9FesJlbjeZsyGlR 9GWaWOMwGOqylV04i1wLmgV7T0AVZ92R3CYkm5dOyYn7oM7e8JzK7f6CQvpIne0oSK R0goo72AilXhwLylUqhElTudPj2eGLuPQyrdJ8tvRew81LtZ6ds1mh0+RsFh2ZwsOM GQSFcPFT3tfHA== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:37 +0200 Subject: [PATCH 09/29] drm/modeset: Create atomic_reset hook 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-9-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4014; i=mripard@kernel.org; h=from:subject:message-id; bh=tYWbhWVz7/WzG6D4UTlvcHo5uy6UD1fyI7Smwm5aU8k=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu8oULx40VtLxN/qj1Rva+Osx1/svhY1rfOQdazIk 53RfFesYyoLgzAng6yYIssTmbDTy9sXVznYr/wBM4eVCWQIAxenAExEqZSxVmCDr5/x5uBgo9dy v07dzr3qzVynUPhf6dXjCfvvX+wyU02/UChg7bm4W9ZiinFk+glGxjqDhBL2dQZnOi9PYO7u35P /MPzPgZqUaYa5y43Df7PcsEx8feb3kS3PBG98zF18N+rv2iAA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Since we're about to integrate some infrastructure to implement hardware state readout, we need a way to differentiate between drivers wanting to start from a pristine state, with the classic reset sequence, and drivers that want to pickup their initial state from reading out the hardware state. To do so we can create an optional reset hook in drm_mode_config_helper_funcs that will default to the classic reset implementation, and can be setup to a helper we will provide in a later patch to read the hardware state. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_mode_config.c | 32 +++++++++++++++++++++++-----= ---- include/drm/drm_modeset_helper_vtables.h | 13 +++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_c= onfig.c index 25f376869b3a41d47bbe72b0df3e35cad142f3e6..82180760032d3490d63fe831364= 65d2c26551d08 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -27,10 +27,11 @@ #include #include #include #include #include +#include #include #include =20 #include "drm_crtc_internal.h" #include "drm_internal.h" @@ -179,19 +180,11 @@ int drm_mode_getresources(struct drm_device *dev, voi= d *data, drm_connector_list_iter_end(&conn_iter); =20 return ret; } =20 -/** - * drm_mode_config_reset - call ->reset callbacks - * @dev: drm device - * - * This functions calls all the crtc's, encoder's and connector's ->reset - * callback. Drivers can use this in e.g. their driver load or resume code= to - * reset hardware and software state. - */ -void drm_mode_config_reset(struct drm_device *dev) +static void drm_mode_config_reset_pristine(struct drm_device *dev) { struct drm_crtc *crtc; struct drm_plane *plane; struct drm_encoder *encoder; struct drm_connector *connector; @@ -213,10 +206,31 @@ void drm_mode_config_reset(struct drm_device *dev) drm_for_each_connector_iter(connector, &conn_iter) if (connector->funcs->reset) connector->funcs->reset(connector); drm_connector_list_iter_end(&conn_iter); } + +/** + * drm_mode_config_reset - call ->reset callbacks + * @dev: drm device + * + * This functions calls all the crtc's, encoder's and connector's ->reset + * callback. Drivers can use this in e.g. their driver load or resume code= to + * reset hardware and software state. + */ +void drm_mode_config_reset(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { + const struct drm_mode_config_helper_funcs *funcs =3D + dev->mode_config.helper_private; + + if (funcs && funcs->atomic_reset) + return funcs->atomic_reset(dev); + } + + return drm_mode_config_reset_pristine(dev); +} EXPORT_SYMBOL(drm_mode_config_reset); =20 /* * Global properties */ diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_mod= eset_helper_vtables.h index ce7c7aeac887bb8438d73710f16071c97a851839..6d22a7676d6bf49fb78af4d0706= bd91005cef186 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -1561,8 +1561,21 @@ struct drm_mode_config_helper_funcs { * how one should implement this. * * This hook is optional. */ int (*atomic_commit_setup)(struct drm_atomic_state *state); + + /** + * @atomic_reset: + * + * This hook is used to create the initial @drm_atomic_state. + * It's used by drm_mode_config_reset(). + * + * The default implementation will create an empty one, but + * drivers can provide an alternative implementation to, for + * example, read the initial state from hardware to implement + * flicker-free and / or faster boot. + */ + void (*atomic_reset)(struct drm_device *dev); }; =20 #endif --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 2475A2EA749 for ; Tue, 2 Sep 2025 08:33:36 +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=1756802017; cv=none; b=uApBuwpKlqmWGl2nbnPZgGuT7eDsfMUp0x/sSE7GOLepoI1IaQv5ShBFJ1QZ9no8ROMYtAyw/oBAda4tDQ5bH+wwyEKyJxdu4EKAxMxrLosrbYscH0+K+6pZ7WW97kkvKj/pO4pKcZFfayYxZyQskAMkd20osJX/BAXAd9VJUwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802017; c=relaxed/simple; bh=croL+b9x5D5yRalrCr4NVJKnMnkOWQw42RTDVJCtPkE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RZio1imQxz+UlYGdrK21/JSJfHkG/Ry7VZRq26valJZ2S/lpu7MddZJu/VOYR4pYEoFk4KqDGUTe5eW9q286vTcDVkANycVpBesz2KRhQtoA9y6SAb5fZ7XpVMp8RR6kzFQR1HgOWDVshsZAVAo6Or0DoX361jh8H5KK1mPMPHQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tthw+F6P; 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="Tthw+F6P" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5CA42C4CEED; Tue, 2 Sep 2025 08:33:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802016; bh=croL+b9x5D5yRalrCr4NVJKnMnkOWQw42RTDVJCtPkE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Tthw+F6Pp0NZrFVh7WjiUMQtatcYevi4EJzAohZdarnnZXLDF4MM6EjltldZsiGfd tdI+43hSH2b8X3W1bCggwNgSpFjWv2pLut/7pV65BvQElu3cENOJMuYKNx/zO3Xrgf Oq96Ny555ll+ixkS3WLBwzkMCbsECKptaRDRf2JTwI+fy8WxB/Ex+PnzrWge5TE2fB ESQ4QTQHxCK/gK6vTWnBCT09jtYhdu4MLb/klAh7KDahH2O6aj8LJkDgyma+W2cyUW wdXPLbHyyVvBFDCFFHYWcQZz0JumlqYXovERuNauG8qK4+TU6IBwzK4nyZjqaawkNT T+TuE2F6N1B5w== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:38 +0200 Subject: [PATCH 10/29] drm/atomic: Add atomic_state_readout infrastructure 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-10-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=20476; i=mripard@kernel.org; h=from:subject:message-id; bh=croL+b9x5D5yRalrCr4NVJKnMnkOWQw42RTDVJCtPkE=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu88GibLLLyv/Px/75WOE4Ksvp+fUmzyZm5zOnfzb OlviscqOqayMAhzMsiKKbI8kQk7vbx9cZWD/cofMHNYmUCGMHBxCsBE/CoZ6zSeVy2u+Jg81e4d V0ud9ekl87fK1O/7mlsfvZbX7/Lx78r+WfxLzLfOkS8MtKtsbe37xthw7mPEfLVd5eWr7tYvWn0 tJsr3wYH1c9I8g0N4GLedDsxf/K3w4ntvt9m8+o3XTkTelDsAAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D In order to enable drivers to fill their initial state from the hardware state, we need to provide an alternative atomic_reset helper. This helper relies on each state having its own atomic_state_readout() hooks. Each component will thus be able to fill the initial state based on what they can figure out from the hardware. It also allocates a dummy drm_atomic_state to glue the whole thing together so atomic_state_readout implementations can still figure out the state of other related entities. Link: https://lore.kernel.org/dri-devel/CAKMK7uHtqHy_oz4W7F+hmp9iqp7W5Ra8Cx= PvJ=3D9BwmvfU-O0gg@mail.gmail.com/ Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_helper.c | 382 ++++++++++++++++++++++++++++++++= ++++ drivers/gpu/drm/drm_mode_config.c | 1 + include/drm/drm_atomic_helper.h | 1 + include/drm/drm_bridge.h | 21 ++ include/drm/drm_connector.h | 26 +++ include/drm/drm_crtc.h | 19 ++ include/drm/drm_plane.h | 27 +++ 7 files changed, 477 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atom= ic_helper.c index d5ebe6ea0acbc5a08aef7fa41ecb9ed5d8fa8e80..f59512476ebf2b48e1c7034950b= caf99237f03c6 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -45,10 +45,392 @@ #include #include =20 #include "drm_crtc_helper_internal.h" #include "drm_crtc_internal.h" +#include "drm_internal.h" + +static void drm_atomic_set_old_plane_state(struct drm_atomic_state *state, + struct drm_plane *plane, + struct drm_plane_state *plane_state) +{ + int idx =3D drm_plane_index(plane); + + state->planes[idx].old_state =3D plane_state; + state->planes[idx].ptr =3D plane; + + drm_dbg_atomic(plane->dev, "Added [PLANE:%d:%s] %p state to %p\n", + plane->base.id, plane->name, plane_state, state); +} + +static void drm_atomic_set_old_crtc_state(struct drm_atomic_state *state, + struct drm_crtc *crtc, + struct drm_crtc_state *crtc_state) +{ + int idx =3D drm_crtc_index(crtc); + + state->crtcs[idx].old_state =3D crtc_state; + state->crtcs[idx].ptr =3D crtc; + + drm_dbg_atomic(state->dev, "Added [CRTC:%d:%s] %p state to %p\n", + crtc->base.id, crtc->name, crtc_state, state); +} + +static void drm_atomic_set_old_connector_state(struct drm_atomic_state *st= ate, + struct drm_connector *conn, + struct drm_connector_state *conn_state) +{ + int idx =3D drm_connector_index(conn); + + drm_connector_get(conn); + state->connectors[idx].old_state =3D conn_state; + state->connectors[idx].ptr =3D conn; + state->num_connector++; + + drm_dbg_atomic(conn->dev, + "Added [CONNECTOR:%d:%s] %p state to %p\n", + conn->base.id, conn->name, conn_state, state); +} + +static void drm_atomic_set_old_private_obj_state(struct drm_atomic_state *= state, + struct drm_private_obj *obj, + struct drm_private_state *obj_state) +{ + int idx =3D state->num_private_objs; + + memset(&state->private_objs[idx], 0, sizeof(*state->private_objs)); + state->private_objs[idx].old_state =3D obj_state; + state->private_objs[idx].ptr =3D obj; + state->num_private_objs++; + + drm_dbg_atomic(state->dev, + "Added new private object %p state %p to %p\n", obj, + obj_state, state); +} + +static void drm_atomic_set_old_bridge_state(struct drm_atomic_state *state, + struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) +{ + drm_atomic_set_old_private_obj_state(state, &bridge->base, &bridge_state-= >base); +} + +static struct drm_connector_state * +find_connector_state_for_encoder(struct drm_atomic_state *state, + struct drm_encoder *encoder) +{ + struct drm_connector_list_iter conn_iter; + struct drm_connector *connector; + + drm_connector_list_iter_begin(state->dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + struct drm_connector_state *conn_state =3D + drm_atomic_get_old_connector_state(state, connector); + + if (WARN_ON(!conn_state)) + continue; + + if (encoder =3D=3D conn_state->best_encoder) + return conn_state; + } + drm_connector_list_iter_end(&conn_iter); + + return NULL; +} + +/** + * drm_atomic_helper_install_readout_state - Sets the state pointer from t= heir readout state + * @state: drm_atomic_state to initialize the DRM device with. + * + * This function takes a &struct drm_atomic_state initialized by + * drm_atomic_build_readout_state() and sets up the entities state + * pointers (ie, &drm_crtc.state and similar) to properly setup the + * initial state. + */ +static void +drm_atomic_helper_install_readout_state(struct drm_atomic_state *state) +{ + struct drm_connector_state *old_conn_state; + struct drm_private_state *old_obj_state; + struct drm_plane_state *old_plane_state; + struct drm_crtc_state *old_crtc_state; + struct drm_connector *connector; + struct drm_private_obj *obj; + struct drm_plane *plane; + struct drm_crtc *crtc; + unsigned int i; + + for_each_old_connector_in_state(state, connector, old_conn_state, i) { + connector->state =3D old_conn_state; + + drm_connector_put(state->connectors[i].ptr); + state->connectors[i].ptr =3D NULL; + state->connectors[i].old_state =3D NULL; + } + + for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) { + crtc->state =3D old_crtc_state; + + state->crtcs[i].ptr =3D NULL; + state->crtcs[i].old_state =3D NULL; + } + + for_each_old_plane_in_state(state, plane, old_plane_state, i) { + plane->state =3D old_plane_state; + + state->planes[i].ptr =3D NULL; + state->planes[i].old_state =3D NULL; + } + + for_each_old_private_obj_in_state(state, obj, old_obj_state, i) { + obj->state =3D old_obj_state; + + state->private_objs[i].ptr =3D NULL; + state->private_objs[i].old_state =3D NULL; + } +} + +static unsigned int count_private_obj(struct drm_device *dev) +{ + struct drm_mode_config *config =3D &dev->mode_config; + struct drm_private_obj *obj; + unsigned int count =3D 0; + + list_for_each_entry(obj, &config->privobj_list, head) + count++; + + return count; +} + +/** + * drm_atomic_build_readout_state - Creates an initial state from the hard= ware + * @dev: DRM device to build the state for + * + * This function allocates a &struct drm_atomic_state, calls the + * atomic_readout_state callbacks, and fills the global state old states + * by what the callbacks returned. + * + * Returns: + * + * A partially initialized &struct drm_atomic_state on success, an error + * pointer otherwise. + */ +static struct drm_atomic_state * +drm_atomic_build_readout_state(struct drm_device *dev) +{ + struct drm_connector_list_iter conn_iter; + struct drm_atomic_state *state; + struct drm_mode_config *config =3D + &dev->mode_config; + struct drm_connector *connector; + struct drm_printer p =3D + drm_info_printer(dev->dev); + struct drm_encoder *encoder; + struct drm_plane *plane; + struct drm_crtc *crtc; + int ret; + + drm_dbg_kms(dev, "Starting to build atomic state from hardware state.\n"); + + state =3D drm_atomic_state_alloc(dev); + if (WARN_ON(!state)) + return ERR_PTR(-ENOMEM); + + state->connectors =3D kcalloc(config->num_connector, sizeof(*state->conne= ctors), GFP_KERNEL); + if (WARN_ON(!state->connectors)) { + ret =3D -ENOMEM; + goto err_state_put; + } + + state->private_objs =3D kcalloc(count_private_obj(dev), sizeof(*state->pr= ivate_objs), GFP_KERNEL); + if (WARN_ON(!state->private_objs)) { + ret =3D -ENOMEM; + goto err_state_put; + } + + drm_for_each_crtc(crtc, dev) { + const struct drm_crtc_funcs *crtc_funcs =3D + crtc->funcs; + struct drm_crtc_state *crtc_state; + + drm_dbg_kms(dev, "Initializing CRTC %s state.\n", crtc->name); + + if (crtc_funcs->atomic_readout_state) { + crtc_state =3D crtc_funcs->atomic_readout_state(crtc); + } else if (crtc_funcs->reset) { + crtc_funcs->reset(crtc); + + /* + * We don't want to set crtc->state field yet. Let's save and clear it = up. + */ + crtc_state =3D crtc->state; + crtc->state =3D NULL; + } else { + drm_warn(dev, "No CRTC readout or reset implementation."); + continue; + } + + if (WARN_ON(IS_ERR(crtc_state))) { + ret =3D PTR_ERR(crtc_state); + goto err_state_put; + } + + drm_atomic_set_old_crtc_state(state, crtc, crtc_state); + } + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + const struct drm_connector_funcs *conn_funcs =3D + connector->funcs; + struct drm_connector_state *conn_state; + + drm_dbg_kms(dev, "Initializing Connector %s state.\n", connector->name); + + if (conn_funcs->atomic_readout_state) { + conn_state =3D conn_funcs->atomic_readout_state(connector, state); + } else if (conn_funcs->reset) { + conn_funcs->reset(connector); + + /* + * We don't want to set connector->state field yet. Let's save and clea= r it + * up. + */ + conn_state =3D connector->state; + connector->state =3D NULL; + } else { + drm_warn(dev, "No Connector readout or reset implementation."); + continue; + } + + if (WARN_ON(IS_ERR(conn_state))) { + ret =3D PTR_ERR(conn_state); + goto err_state_put; + } + + drm_atomic_set_old_connector_state(state, connector, conn_state); + } + drm_connector_list_iter_end(&conn_iter); + + WARN_ON(state->num_connector !=3D config->num_connector); + + drm_for_each_encoder(encoder, dev) { + struct drm_connector_state *enc_conn_state; + struct drm_crtc_state *enc_crtc_state; + struct drm_bridge *bridge; + + /* + * It works a bit differently for bridges. Because they are + * using a drm_private_state, and because + * drm_atomic_private_obj_init() asks for its initial state when + * initializing, instead of doing it later on through a reset + * call like the other entities, we can't have reset xor + * readout. + * + * We'll need a mandatory reset to create that initial, blank, + * state, and then readout will fill that state later on if the + * driver implements it. + * + * This also means we don't need to call the readout state + * function if we don't have the bridge enabled (ie, if no + * drm_connector_state->best_encoder points to bridge->encoder, + * and / or if drm_connector_state->crtc is NULL). + * + * In such a case, we would get the blank state reset created + * during registration. + */ + + enc_conn_state =3D find_connector_state_for_encoder(state, encoder); + if (!enc_conn_state) + continue; + + enc_crtc_state =3D drm_atomic_get_old_crtc_state(state, enc_conn_state->= crtc); + if (!enc_crtc_state) + continue; + + list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) { + const struct drm_bridge_funcs *bridge_funcs =3D bridge->funcs; + struct drm_bridge_state *bridge_state; + + bridge_state =3D drm_bridge_get_current_state(bridge); + if (WARN_ON(!bridge_state)) { + ret =3D -EINVAL; + goto err_state_put; + } + + if (bridge_funcs->atomic_readout_state) { + ret =3D bridge_funcs->atomic_readout_state(bridge, + bridge_state, + enc_crtc_state, + enc_conn_state); + if (WARN_ON(ret)) + goto err_state_put; + } + + drm_atomic_set_old_bridge_state(state, bridge, bridge_state); + } + } + + drm_for_each_plane(plane, dev) { + const struct drm_plane_funcs *plane_funcs =3D + plane->funcs; + struct drm_plane_state *plane_state; + + drm_dbg_kms(dev, "Initializing Plane %s state.\n", plane->name); + + if (plane_funcs->atomic_readout_state) { + plane_state =3D plane_funcs->atomic_readout_state(plane, state); + } else if (plane_funcs->reset) { + plane_funcs->reset(plane); + + /* + * We don't want to set conn->state field yet. Let's save and clear it = up. + */ + plane_state =3D plane->state; + plane->state =3D NULL; + } else { + drm_warn(dev, "No plane readout or reset implementation."); + continue; + } + + if (WARN_ON(IS_ERR(plane_state))) { + ret =3D PTR_ERR(plane_state); + goto err_state_put; + } + + drm_atomic_set_old_plane_state(state, plane, plane_state); + } + + drm_atomic_print_old_state(state, &p); + + return state; + +err_state_put: + drm_atomic_state_put(state); + return ERR_PTR(ret); +} + +/** + * drm_atomic_helper_readout_state - Builds an initial state from hardware= state + * @dev: DRM device to build the state for + * + * This function creates the initial state for all the entities on a + * @dev. Drivers can use this as their + * &drm_mode_config_helper_funcs.atomic_reset callback to implement + * hardware state readout suppport. + */ +void drm_atomic_helper_readout_state(struct drm_device *dev) +{ + struct drm_atomic_state *state; + + state =3D drm_atomic_build_readout_state(dev); + if (IS_ERR(state)) + return; + + drm_atomic_helper_install_readout_state(state); + drm_atomic_state_put(state); +} +EXPORT_SYMBOL(drm_atomic_helper_readout_state); =20 /** * DOC: overview * * This helper library provides implementations of check and commit functi= ons on diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_c= onfig.c index 82180760032d3490d63fe83136465d2c26551d08..96d38a49be501a0090457cbe961= 35f82bb1358b5 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -26,10 +26,11 @@ #include #include #include #include #include +#include #include #include #include #include =20 diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helpe= r.h index 53382fe93537bbcda9cee8827bc95de9a515efb5..47902a9181727a08581fb808faa= be67d92a755cf 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -45,10 +45,11 @@ =20 struct drm_atomic_state; struct drm_private_obj; struct drm_private_state; =20 +void drm_atomic_helper_readout_state(struct drm_device *dev); int drm_atomic_helper_check_modeset(struct drm_device *dev, struct drm_atomic_state *state); int drm_atomic_helper_check_wb_connector_state(struct drm_connector *conne= ctor, struct drm_atomic_state *state); int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_stat= e, diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 8d9d4fd078e72977677fd992d725261232754e3e..15b63053f01869786831936ba28= b7efc1e55e2e8 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -490,10 +490,31 @@ struct drm_bridge_funcs { * The @atomic_post_disable callback is optional. */ void (*atomic_post_disable)(struct drm_bridge *bridge, struct drm_atomic_state *state); =20 + /** + * @atomic_readout_state: + * + * Initializes,this bridge atomic state. + * + * It's meant to be used by drivers that wants to implement fast + * / flicker-free boot and allows to initialize the atomic state + * from the hardware state left by the firmware. + * + * It's used at initialization time, so drivers must make sure + * that the power state is sensible when accessing the hardware. + * + * RETURNS: + * + * 0 on success, an error code otherwise. + */ + int (*atomic_readout_state)(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state); + /** * @atomic_duplicate_state: * * Duplicate the current bridge state object (which is guaranteed to be * non-NULL). diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 8f34f4b8183d83dccd3e820a444fbf74fb6c16f2..f68bd9627c085c6d2463b847aaa= 245ccc651f27b 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1464,10 +1464,36 @@ struct drm_connector_funcs { * when a connector is being hot-unplugged for drivers that support * connector hotplugging (e.g. DisplayPort MST). */ void (*destroy)(struct drm_connector *connector); =20 + /** + * @atomic_readout_state: + * + * Allocates, initializes, and returns an atomic state for this + * connector. + * + * It's meant to be used by drivers that wants to implement fast + * / flicker-free boot and allows to initialize the atomic state + * from the hardware state left by the firmware. + * + * It's used at initialization time, so drivers must make sure + * that the power state is sensible when accessing the hardware. + * + * The drm_atomic_state being passed is not fully filled. Only + * the CRTC state are there when this hooks is called, and only + * their old state. The only safe operation one can do on this + * state in this hook is calling + * drm_atomic_get_old_crtc_state(). + * + * RETURNS: + * + * An atomic state on success, an error pointer otherwise. + */ + struct drm_connector_state *(*atomic_readout_state)(struct drm_connector = *connector, + struct drm_atomic_state *state); + /** * @atomic_duplicate_state: * * Duplicate the current atomic state for this connector and return it. * The core and helpers guarantee that any atomic state duplicated with diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index caa56e039da2a748cf40ebf45b37158acda439d9..c462bd9b2f7d3ae08e669463717= 002e5f78122fe 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -613,10 +613,29 @@ struct drm_crtc_funcs { * 0 on success or a negative error code on failure. */ int (*set_property)(struct drm_crtc *crtc, struct drm_property *property, uint64_t val); =20 + /** + * @atomic_readout_state: + * + * Allocates, initializes, and returns an atomic state for this + * CRTC. + * + * It's meant to be used by drivers that wants to implement fast + * / flicker-free boot and allows to initialize the atomic state + * from the hardware state left by the firmware. + * + * It's used at initialization time, so drivers must make sure + * that the power state is sensible when accessing the hardware. + * + * RETURNS: + * + * An atomic state on success, an error pointer otherwise. + */ + struct drm_crtc_state *(*atomic_readout_state)(struct drm_crtc *crtc); + /** * @atomic_duplicate_state: * * Duplicate the current atomic state for this CRTC and return it. * The core and helpers guarantee that any atomic state duplicated with diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 01479dd94e76a8389a0c9e9d6744400aa2291064..691a267c857a228f674ef02a63f= b6d1ff9e379a8 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -378,10 +378,37 @@ struct drm_plane_funcs { * 0 on success or a negative error code on failure. */ int (*set_property)(struct drm_plane *plane, struct drm_property *property, uint64_t val); =20 + /** + * @atomic_readout_state: + * + * Allocates, initializes, and returns an atomic state for this + * plane. + * + * It's meant to be used by drivers that wants to implement fast + * / flicker-free boot and allows to initialize the atomic state + * from the hardware state left by the firmware. + * + * It's used at initialization time, so drivers must make sure + * that the power state is sensible when accessing the hardware. + * + * The drm_atomic_state being passed is not fully filled. Only + * the CRTC and connector states are there when this hooks is + * called, and only their old state. The only safe operation one + * can do on this state in this hook is calling + * drm_atomic_get_old_crtc_state() and + * drm_atomic_get_old_connector_state(). + * + * RETURNS: + * + * An atomic state on success, an error pointer otherwise. + */ + struct drm_plane_state *(*atomic_readout_state)(struct drm_plane *plane, + struct drm_atomic_state *state); + /** * @atomic_duplicate_state: * * Duplicate the current atomic state for this plane and return it. * The core and helpers guarantee that any atomic state duplicated with --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 C066D2E62D9 for ; Tue, 2 Sep 2025 08:33: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=1756802019; cv=none; b=ezuo0WvCr8LMnTMeosUEHHO6qWYqCNJ29NL3OTdcB6QCh+r/CYzEjPPmr8kMQ3abWGKFzaqbe4hTfoIkJI8/4Y5nkgkEmwPPimwV12DXWJBpfDvhyvC+NS/GzZ40HEWQsF7N38CjBV8l0+XPU82UTcqCu7rISF7Myez6L7Pqitc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802019; c=relaxed/simple; bh=z+A1qZGL7VMjPd92l+hRCbPOUgjuh0UPwrQCvSvdcls=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UpR/8fLTx5aA8/wKHEzQn3xQg5p9itknWml7llG3UEI6ciPVk05qiGs/n1M5c9ETwV1W2bcNr6lruXWg9PySBSw66RF+8MhBuEYUPvJXt/YkZgGwHNwff/nqY+OJXo/rDhNJBYvdhs4XMQjbgP+ge6bN5fFQiUXDgJNYdRmVqRU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nO1RXdRh; 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="nO1RXdRh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE5F6C4CEF7; Tue, 2 Sep 2025 08:33:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802019; bh=z+A1qZGL7VMjPd92l+hRCbPOUgjuh0UPwrQCvSvdcls=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nO1RXdRhou3rnO387KEmD3xYdnkOSUI1KxHjtDMQZkmuaAydK7rjJtCxMp9k6cssv wSIluBfdrN0EVuGd/9huGJgKEe06fqefwjjknEX33ONongTLFs+9Z9vNIqWfLDizO6 8sCSZpm5BT9rTxD+7aBJ+fuihXCnxExbwi/46KCnsIAWxMwT38zuaKqgXeNNhFY9AC tiuxNzw+pW+gwU6yvYgYOmaZc8bfCwPbnxUWD6YjyKbz+m/ttX1BU4UBgsDGciLiGQ 6VrHR2YnvAhd3QfoWRHvto9OwpgD7SAclsbaxmHWzB+BEwcDhZlPELIZZqZcumEleT 56hvMWnPaRY7Q== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:39 +0200 Subject: [PATCH 11/29] drm/crtc: Drop no_vblank bit field 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-11-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1105; i=mripard@kernel.org; h=from:subject:message-id; bh=z+A1qZGL7VMjPd92l+hRCbPOUgjuh0UPwrQCvSvdcls=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu+svxTk6SFz0nA+r7BBWlfdUbXy0B1NfVqcUa3/Z NYl92/omMrCIMzJICumyPJEJuz08vbFVQ72K3/AzGFlAhnCwMUpABNZqs9YZ68mH/30i+Wl62cu eTz+fO1yEM8E62nTbBMMd8xr91rlraszN/vfhWTn2RJKgukC1XcvMtbX+f/L3P3a7n5N+I5N7DL LruV4Xv2w/5+Xy2kjtr1ufX81LtvMXH3yX+tt0498TBmcmowA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The no_vblank field in drm_crtc_state is defined as a bit-field with a single bit. This will create a syntax issue with the macros we'll introduce next, and most other booleans but the *_changed ones in drm_crtc_state do not use a bit field anyway. Let's drop it. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- include/drm/drm_crtc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c462bd9b2f7d3ae08e669463717002e5f78122fe..11e3299cfad1572c6e507918c7c= ceae7a28ba4cf 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -184,11 +184,11 @@ struct drm_crtc_state { * &drm_crtc_state.no_blank =3D=3D true is valid and usually used when the * writeback connector attached to the CRTC has a new job queued. In * this case the driver will send the VBLANK event on its own when the * writeback job is complete. */ - bool no_vblank : 1; + bool no_vblank; =20 /** * @plane_mask: Bitmask of drm_plane_mask(plane) of planes attached to * this CRTC. */ --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 866FF2EAB7D for ; Tue, 2 Sep 2025 08:33:42 +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=1756802022; cv=none; b=PmYPs9E2hoepuzajT/aiNNmWJoIp9v9C/mhQ7RJRskfCf2/rp9+IsNIQcJQMkgGl/EIi+APMOJFalszHLN2TSG0/bY5GiDPDHixb/sYsEvqQyNr/LIf55NoQkf1R0xlVDB0ftOIyDsvCLctK/rCItEo4jT/wayHohjHto8IZO3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802022; c=relaxed/simple; bh=D+1PlyzQZJSGxoRUBwJ5wrqa9UanKG0XdziPaR9YWbc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N7n8ELDRMlyzNqTG0KdmxZUIIGZ7+ZoOGhiMCmSUE7JePX7E0X8FDYY0Y0KV2EK+qnjjKEkjFtDFjJ1bl4RySChwLhlzK74ShFcbENqG5nIBjMq77RzqsfSrS58YCsKUEzOGeemf1kebZeVy7E2zrUdDUzH0mX2IfVB3ulusRAk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mImlMD6d; 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="mImlMD6d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9039FC4CEF7; Tue, 2 Sep 2025 08:33:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802021; bh=D+1PlyzQZJSGxoRUBwJ5wrqa9UanKG0XdziPaR9YWbc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mImlMD6dQA+/LO6bh0u9xq1eWJH1SZprzLuDqgy42tVX5zvFD8NYbCa33rMt9ey7Y r0UOEFiheZBFJEMuHv3epywusWGGL6+/IA9KUuX63tcRHUcEL+D/gc+AzpdsGHbrg6 biztYhWicNC2vcja/tgIfKX1GS+e2s24FDBfPUl/shXc+CXES40rfvhdD2Q/KRlmvr +hUbJH7bmcow5Gk2LWLSb+iiA5iESZcmJvpJDuDTHsy/Gz7L8KktJLnVd47Ja9T8AQ F7PPNPNXSJ0TUy0Ydq6gjij+kAGdZkNNYfU/HoNWT6PFhmOICLw4pxx8Lqb4yXf4pj Z4Xp+ZrKOT0CA== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:40 +0200 Subject: [PATCH 12/29] drm/atomic_helper: Pass nonblock to commit_tail 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-12-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1814; i=mripard@kernel.org; h=from:subject:message-id; bh=D+1PlyzQZJSGxoRUBwJ5wrqa9UanKG0XdziPaR9YWbc=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu+sb7JzSXG/FjaFYeWW19rHq3Wepl3TvV5aaVXaG b+P48mMjqksDMKcDLJiiixPZMJOL29fXOVgv/IHzBxWJpAhDFycAjARbjHGhmPKpwMMZr3Ktviz VyKuXP1cxmt7Gb/8u2vnKojX7Ix5yBwanv/p+JfHs2zubjr79sW894w1/LwyhuWcV1Y1dEldO/I m6u/XNdxd5x4FpPNJXQ3072fr3JZeUt/gx+e/qYn7osjE51oA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D We'll need to know if a commit is blocking or non-blocking in commit_tail later on, so let's pass it along. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/drm_atomic_helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atom= ic_helper.c index f59512476ebf2b48e1c7034950bcaf99237f03c6..14d9bc282ca570964e494936090= 898b2dc6bee31 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2332,11 +2332,11 @@ void drm_atomic_helper_commit_tail_rpm(struct drm_a= tomic_state *state) =20 drm_atomic_helper_cleanup_planes(dev, state); } EXPORT_SYMBOL(drm_atomic_helper_commit_tail_rpm); =20 -static void commit_tail(struct drm_atomic_state *state) +static void commit_tail(struct drm_atomic_state *state, bool nonblock) { struct drm_device *dev =3D state->dev; const struct drm_mode_config_helper_funcs *funcs; struct drm_crtc_state *new_crtc_state; struct drm_crtc *crtc; @@ -2390,11 +2390,11 @@ static void commit_tail(struct drm_atomic_state *st= ate) static void commit_work(struct work_struct *work) { struct drm_atomic_state *state =3D container_of(work, struct drm_atomic_state, commit_work); - commit_tail(state); + commit_tail(state, true); } =20 /** * drm_atomic_helper_async_check - check if state can be committed asynchr= onously * @dev: DRM device @@ -2610,11 +2610,11 @@ int drm_atomic_helper_commit(struct drm_device *dev, =20 drm_atomic_state_get(state); if (nonblock) queue_work(system_unbound_wq, &state->commit_work); else - commit_tail(state); + commit_tail(state, false); =20 return 0; =20 err: drm_atomic_helper_unprepare_planes(dev, state); --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 9F2262EA743 for ; Tue, 2 Sep 2025 08:33:44 +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=1756802024; cv=none; b=bD5XCcwElzg0jNiHKS+Qcwm6Y4b2VV2wuKHmUnrm2EeXwZEF7uE+lYRVghLdfdVudwZalgzZMgyY7FkXtOC5gPZs8YgxvGib2jOEAFra9U6cjcOPjwgT1AZCS3EFwbXiKYzCWbvtwxgIqQK0aEMYyBpS0cYy2ypmxzPwl+vu0oU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802024; c=relaxed/simple; bh=6b7UDJ+K9JSaJwNLdD3QfXhiSHmFYmCS7AH4OMReX7k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=njwLg8mL72M+5uhGWTy2mGCW35wpt2G+xfjMTnsGxpKdwWcpKvOMgKQsrNR/X8tl9f0LIE2tJB3qn2QXGUSjg1XwbT0/VPh78QXW8meor58WTGlplS1TxWmQPYx/migjbqUPeWrs8DKv2q4PntBsdJ/iEwsLbrAMWZx1PEZIRpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tcKHyCJ7; 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="tcKHyCJ7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 31EA0C4CEED; Tue, 2 Sep 2025 08:33:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802024; bh=6b7UDJ+K9JSaJwNLdD3QfXhiSHmFYmCS7AH4OMReX7k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=tcKHyCJ73DiG2+bV0DmAVYO281tfF1oII6jNu4Ni9UZ+VS33CAFwbj7BPYNLsMqds 76zAP+CNcYC17mW0qd5gUDLCRo5XYuDA4pO17os6WGe5mI7CQ77nVdFzrh9pdR64J1 L/9bS3EkulDu84Wrqb+JNT+1lrFC/bHgljGyH68RrZOLqcHEsf6EdiluZ74cO6N3vl DSwwAPsaLptfPipQ/stUd3WD5HBwwEjZF2NAnN4tsoFK5M8iGoRp/25Ye6iZ5ELfdZ ToXhDSYDYN6d3ZWj7SD9l/aULw/RovpIj4/iQStPWir1ED0htQfNHnW9b8970b7JL8 pnAFSslf9hpDw== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:41 +0200 Subject: [PATCH 13/29] drm/atomic_helper: Compare actual and readout states once the commit is done 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-13-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10708; i=mripard@kernel.org; h=from:subject:message-id; bh=6b7UDJ+K9JSaJwNLdD3QfXhiSHmFYmCS7AH4OMReX7k=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu/ScliyYfPSwLJZzCGr7k9M0bPc/cJi8uPJTxZNY nnFEvGToWMqC4MwJ4OsmCLLE5mw08vbF1c52K/8ATOHlQlkCAMXpwBMhNmPsWHXM713baxThDvu XMk4VlnceZw3JHvl3T3Hgnf7txR+XFYnt/rOamHJrXtXPj3SHKjjU8TYcP7eFYnFa6puCDtXNJV 3cIhermZcs9ojeXemJhvbvz0Xnvxk/Rvwe9Lt9W//Ve6/Unb+NAA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The new atomic state readout infrastructure can be hard to test because getting access to every firmware variation is hard, but also because most firmware setup will be pretty basic and won't test a wide range of features. Noticing whether it was sucessful or not is also not very convenient. In order to make it easier, we can however provide some infrastructure to read out a new state every time a non-blocking commit is made, and compare the readout one with the committed one. And since we do this only on non-blocking commits, the time penalty doesn't matter. To do so, we introduce a new hook for every state, atomic_compare_state, that takes two state instances and is supposed to return whether they are identical or not. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_helper.c | 113 ++++++++++++++++++++++++++++++++= ++++ include/drm/drm_atomic.h | 14 +++++ include/drm/drm_bridge.h | 14 +++++ include/drm/drm_connector.h | 14 +++++ include/drm/drm_crtc.h | 14 +++++ include/drm/drm_plane.h | 14 +++++ 6 files changed, 183 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atom= ic_helper.c index 14d9bc282ca570964e494936090898b2dc6bee31..aa8f52b5d5a5e6146a6472eebaf= 02e675c35ccd2 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -428,10 +428,120 @@ void drm_atomic_helper_readout_state(struct drm_devi= ce *dev) drm_atomic_helper_install_readout_state(state); drm_atomic_state_put(state); } EXPORT_SYMBOL(drm_atomic_helper_readout_state); =20 +static bool drm_atomic_helper_readout_compare(struct drm_atomic_state *com= mitted_state) +{ + struct drm_device *dev =3D committed_state->dev; + struct drm_printer p =3D drm_err_printer(dev, NULL); + struct drm_private_state *new_obj_state; + struct drm_private_obj *obj; + struct drm_plane_state *new_plane_state; + struct drm_plane *plane; + struct drm_crtc_state *new_crtc_state; + struct drm_crtc *crtc; + struct drm_connector_state *new_conn_state; + struct drm_connector *conn; + struct drm_atomic_state *readout_state; + unsigned int i; + bool identical =3D true; + + readout_state =3D drm_atomic_build_readout_state(dev); + if (WARN_ON(IS_ERR(readout_state))) + return false; + + for_each_new_plane_in_state(committed_state, plane, new_plane_state, i) { + const struct drm_plane_funcs *plane_funcs =3D + plane->funcs; + struct drm_plane_state *readout_plane_state; + + readout_plane_state =3D drm_atomic_get_old_plane_state(readout_state, pl= ane); + if (!readout_plane_state) { + identical =3D false; + continue; + } + + if (!plane_funcs->atomic_compare_state) + continue; + + if (!plane_funcs->atomic_compare_state(plane, &p, new_plane_state, reado= ut_plane_state)) { + drm_warn(dev, "[PLANE:%d:%s] Committed and Readout PLANE state don't ma= tch\n", + plane->base.id, plane->name); + identical =3D false; + continue; + } + } + + for_each_new_crtc_in_state(committed_state, crtc, new_crtc_state, i) { + const struct drm_crtc_funcs *crtc_funcs =3D crtc->funcs; + struct drm_crtc_state *readout_crtc_state; + + readout_crtc_state =3D drm_atomic_get_old_crtc_state(readout_state, crtc= ); + if (!readout_crtc_state) { + identical =3D false; + continue; + } + + if (!crtc_funcs->atomic_compare_state) + continue; + + if (!crtc_funcs->atomic_compare_state(crtc, &p, new_crtc_state, readout_= crtc_state)) { + drm_warn(dev, "[CRTC:%d:%s] Committed and Readout CRTC state don't matc= h\n", + crtc->base.id, crtc->name); + identical =3D false; + continue; + } + } + + for_each_new_connector_in_state(committed_state, conn, new_conn_state, i)= { + const struct drm_connector_funcs *conn_funcs =3D + conn->funcs; + struct drm_connector_state *readout_conn_state; + + readout_conn_state =3D drm_atomic_get_old_connector_state(readout_state,= conn); + if (!readout_conn_state) { + identical =3D false; + continue; + } + + if (!conn_funcs->atomic_compare_state) + continue; + + if (!conn_funcs->atomic_compare_state(conn, &p, new_conn_state, readout_= conn_state)) { + drm_warn(dev, "[CONNECTOR:%d:%s] Committed and Readout connector state = don't match\n", + conn->base.id, conn->name); + identical =3D false; + continue; + } + } + + for_each_new_private_obj_in_state(committed_state, obj, new_obj_state, i)= { + const struct drm_private_state_funcs *obj_funcs =3D obj->funcs; + struct drm_private_state *readout_obj_state; + + readout_obj_state =3D drm_atomic_get_old_private_obj_state(readout_state= , obj); + if (!readout_obj_state) { + identical =3D false; + continue; + } + + if (!obj_funcs->atomic_compare_state) + continue; + + if (!obj_funcs->atomic_compare_state(obj, &p, new_obj_state, readout_obj= _state)) { + drm_warn(dev, "Committed and Readout private object state don't match\n= "); + identical =3D false; + continue; + } + } + + drm_atomic_state_put(readout_state); + + return identical; +} + /** * DOC: overview * * This helper library provides implementations of check and commit functi= ons on * top of the CRTC modeset helper callbacks and the plane helper callbacks= . It @@ -2382,10 +2492,13 @@ static void commit_tail(struct drm_atomic_state *st= ate, bool nonblock) (unsigned long)commit_time_ms, new_self_refresh_mask); =20 drm_atomic_helper_commit_cleanup_done(state); =20 + if (!nonblock) + drm_atomic_helper_readout_compare(state); + drm_atomic_state_put(state); } =20 static void commit_work(struct work_struct *work) { diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index f13f926d21047e42bb9ac692c2dd4b88f2ebd91c..d75a9c7e23adf7fa264df766b47= 526f75e9cc753 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -226,10 +226,24 @@ struct drm_private_state_funcs { * Frees the private object state created with @atomic_duplicate_state. */ void (*atomic_destroy_state)(struct drm_private_obj *obj, struct drm_private_state *state); =20 + /** + * @atomic_compare_state + * + * Compares two &struct drm_private_state instances. + * + * RETURNS: + * + * True if the states are identical, false otherwise. + */ + bool (*atomic_compare_state)(struct drm_private_obj *obj, + struct drm_printer *p, + struct drm_private_state *a, + struct drm_private_state *b); + /** * @atomic_print_state: * * If driver subclasses &struct drm_private_state, it should implement * this optional hook for printing additional driver specific state. diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 15b63053f01869786831936ba28b7efc1e55e2e8..5ea63b51a4dd4cb00468afcf7d1= 26c774f63ade0 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -511,10 +511,24 @@ struct drm_bridge_funcs { int (*atomic_readout_state)(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state); =20 + /** + * @atomic_compare_state + * + * Compares two &struct drm_bridge_state instances. + * + * RETURNS: + * + * True if the states are identical, false otherwise. + */ + bool (*atomic_compare_state)(struct drm_bridge *bridge, + struct drm_printer *p, + struct drm_bridge_state *a, + struct drm_bridge_state *b); + /** * @atomic_duplicate_state: * * Duplicate the current bridge state object (which is guaranteed to be * non-NULL). diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index f68bd9627c085c6d2463b847aaa245ccc651f27b..dc2c77b04df9010cbfb2028de8e= f8c747003c489 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1534,10 +1534,24 @@ struct drm_connector_funcs { * This callback is mandatory for atomic drivers. */ void (*atomic_destroy_state)(struct drm_connector *connector, struct drm_connector_state *state); =20 + /** + * @atomic_compare_state + * + * Compares two &struct drm_connector_state instances. + * + * RETURNS: + * + * True if the states are identical, false otherwise. + */ + bool (*atomic_compare_state)(struct drm_connector *connector, + struct drm_printer *p, + struct drm_connector_state *a, + struct drm_connector_state *b); + /** * @atomic_set_property: * * Decode a driver-private property value and store the decoded value * into the passed-in state structure. Since the atomic core decodes all diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 11e3299cfad1572c6e507918c7cceae7a28ba4cf..21c20ecdda40f3d155d3c140e06= b3801270f5262 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -676,10 +676,24 @@ struct drm_crtc_funcs { * This callback is mandatory for atomic drivers. */ void (*atomic_destroy_state)(struct drm_crtc *crtc, struct drm_crtc_state *state); =20 + /** + * @atomic_compare_state + * + * Compares two &struct drm_crtc_state instances. + * + * RETURNS: + * + * True if the states are identical, false otherwise. + */ + bool (*atomic_compare_state)(struct drm_crtc *crtc, + struct drm_printer *p, + struct drm_crtc_state *a, + struct drm_crtc_state *b); + /** * @atomic_set_property: * * Decode a driver-private property value and store the decoded value * into the passed-in state structure. Since the atomic core decodes all diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 691a267c857a228f674ef02a63fb6d1ff9e379a8..c24c10ccc8e8f2ba23e77e279ae= f61ae86e320c7 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -449,10 +449,24 @@ struct drm_plane_funcs { * This callback is mandatory for atomic drivers. */ void (*atomic_destroy_state)(struct drm_plane *plane, struct drm_plane_state *state); =20 + /** + * @atomic_compare_state + * + * Compares two &struct drm_plane_state instances. + * + * RETURNS: + * + * True if the states are identical, false otherwise. + */ + bool (*atomic_compare_state)(struct drm_plane *plane, + struct drm_printer *p, + struct drm_plane_state *a, + struct drm_plane_state *b); + /** * @atomic_set_property: * * Decode a driver-private property value and store the decoded value * into the passed-in state structure. Since the atomic core decodes all --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 456D72EAD18 for ; Tue, 2 Sep 2025 08:33:47 +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=1756802027; cv=none; b=p5tGX6bma7XMyPhBz4KEJLlI3D5IkbiZcVsjfkY9UPh5qs8OHo5P6l/zbqyW81K+lyHx1YhNTakTPtKLRLLizrkgAhwaI9LH1ULrkS4rngCzdWHg1dm6WynAuYKxz88gdegRkl+mkyNNbyNKUvT2vfPE2m5JO8vP4oYpcUwg2yQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802027; c=relaxed/simple; bh=IQtsJhSchjATXRgK9p3uG4wR8tQutxGjvOUIvX+cKZo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mbW8RqxEAzbPS11PIXg15JRS/3wrTyxBMrPW+D1Q4iq59swx8bj5WsEX5vl68P4jZDQt7TTTjXfaIdBpcopyUVSD6o8NTZQ+21KhHTueEmnvgvjwkLfcSEnIJSWcuISLZomPNOjPvFVW7O1abh69d22FXywcdGfDZDBrkkneu3M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q+u3l0zF; 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="Q+u3l0zF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CAA5FC4CEF7; Tue, 2 Sep 2025 08:33:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802027; bh=IQtsJhSchjATXRgK9p3uG4wR8tQutxGjvOUIvX+cKZo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Q+u3l0zForMGuRP44Ds32HevJw+ZJ2jk0iCcXRyFR6FbpmcEKDLyTDsLOOV0r8uXW RUBu2d0dkADn1atPP5n4c5GMbtPnkCHl+EPoEJYSUbxgMKKI/ZnSA6NxkAK0q6KBgs dO8JiGeq1mIMzrylKfswggJPAGNySWkKm/Xo398751s2fCl6eaS6Urm+iA6Iv3+I0q dFlNB4oOn4V/QZg9iyV9k2Nz0nHdLeL4Wbs9s09tFLBbzqvy+UPNRZOAcn4LzTeoJp VG7HnWJLp2BAh3PdNL1InvWG6zn9NovUe5Zk2fT537Sz+z4D69kXxC/a3PFxfoh2bh CCQL9pe0SxcFg== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:42 +0200 Subject: [PATCH 14/29] drm/atomic_state_helper: Provide comparison macros 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-14-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10161; i=mripard@kernel.org; h=from:subject:message-id; bh=IQtsJhSchjATXRgK9p3uG4wR8tQutxGjvOUIvX+cKZo=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu+qvFV4Uj339kn1gOAv7hWBx6+wxm+93zQ9pXzXv fdvtGR0O6ayMAhzMsiKKbI8kQk7vbx9cZWD/cofMHNYmUCGMHBxCsBE7nkxNvy4/yKi9tzrEo0z ccxbvh84FBY6ravziOEDz8VBZZwX1nxjXSlzbmmJ+NZtzdO12t1zlzPWmcvOkL+RE/fSz4mnLNX stZap76/lHNXRHU7zPmhMmX3wGYPAocPdJ/ktu5TteTR29zcBAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D In order to make the implementation of atomic_compare_state easier and reduce the boilerplate, this patch implements a bunch of macros to compare values depending on their type. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_state_helper.c | 19 +++ include/drm/drm_atomic_state_helper.h | 218 ++++++++++++++++++++++++++= ++++ 2 files changed, 237 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/dr= m_atomic_state_helper.c index b962c342b16aabf4e3bea52a914e5deb1c2080ce..78556e0c08d2fa84b16d70243dd= d21617a322014 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -830,5 +830,24 @@ drm_atomic_helper_bridge_reset(struct drm_bridge *brid= ge) =20 __drm_atomic_helper_bridge_reset(bridge, bridge_state); return bridge_state; } EXPORT_SYMBOL(drm_atomic_helper_bridge_reset); + +void __printf(4, 5) +drm_atomic_helper_print_state_mismatch(struct drm_printer *p, + const char *name, + const char *field, + const char *format, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, format); + vaf.fmt =3D format; + vaf.va =3D &args; + + drm_printf(p, "%s configuration mismatch in %s %pV\n", name, field, &vaf); + + va_end(args); +} +EXPORT_SYMBOL(drm_atomic_helper_print_state_mismatch); diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic= _state_helper.h index b9740edb26586d58f99a5223902bb8e333ac75a2..3c6ffa7122cf895f1eda09ec74c= 6537594d4aee3 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -22,19 +22,21 @@ * Authors: * Rob Clark * Daniel Vetter */ =20 +#include #include =20 struct drm_atomic_state; struct drm_bridge; struct drm_bridge_state; struct drm_crtc; struct drm_crtc_state; struct drm_plane; struct drm_plane_state; +struct drm_printer; struct drm_connector; struct drm_connector_state; struct drm_private_obj; struct drm_private_state; struct drm_modeset_acquire_ctx; @@ -95,5 +97,221 @@ void drm_atomic_helper_bridge_destroy_state(struct drm_= bridge *bridge, struct drm_bridge_state *state); void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, struct drm_bridge_state *state); struct drm_bridge_state * drm_atomic_helper_bridge_reset(struct drm_bridge *bridge); + +void __printf(4, 5) +drm_atomic_helper_print_state_mismatch(struct drm_printer *p, + const char *name, + const char *field, + const char *format, ...); + +#define STATE_CHECK_BOOL(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, bool), \ + __stringify(name) " is not a bool"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %s, got %s", \ + str_yes_no(sa->f), \ + str_yes_no(sb->f)); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_DISPLAY_MODE(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, struct drm_display_mode), \ + __stringify(name) " is not a drm_display_mode structure"); \ + if (!drm_mode_equal(&sa->f, &sb->f)) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected " DRM_MODE_FMT ", got " DRM_MODE_FMT, \ + DRM_MODE_ARG(&sa->f), \ + DRM_MODE_ARG(&sb->f)); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_INFOFRAME(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, union hdmi_infoframe), \ + __stringify(name) " is not an hdmi_infoframe union"); \ + if (memcmp(&sa->f, &sb->f, sizeof(union hdmi_infoframe))) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "infoframes don't match"); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_FORMAT_INFO(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, const struct drm_format_info *), \ + __stringify(name) " is not a drm_format_info pointer"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %p4cc, got %p4cc", \ + &sa->f->format, \ + &sb->f->format); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_PROPERTY_BLOB(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, struct drm_property_blob *), \ + __stringify(name) " is not a drm_property_blob pointer"); \ + if (sa->f !=3D sb->f && \ + ((sa->f->length !=3D sb->f->length) || \ + memcmp(sa->f->data, sb->f->data, sa->f->length))) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "blobs don't match"); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_PTR(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %px, got %px", \ + sa->f, sb->f); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_S32(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, (s32)0), \ + __stringify(name) " is not an s32"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %u, got %u", \ + sa->f, sb->f); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_S32_X(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, (s32)0), \ + __stringify(name) " is not an s32"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %x, got %x", \ + sa->f, sb->f); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_U16(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, (u16)0), \ + __stringify(name) " is not a u16"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %u, got %u", \ + sa->f, sb->f); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_U32(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, (u32)0), \ + __stringify(name) " is not a u32"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %u, got %u", \ + sa->f, sb->f); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_U32_16_16(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, (u32)0), \ + __stringify(name) " is not a u32"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %d.%06u, got %d.%06u", \ + sa->f >> 16, ((sa->f && 0xffff) * 15625) >> 10, \ + sb->f >> 16, ((sb->f && 0xffff) * 15625) >> 10); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_U32_X(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, (u32)0), \ + __stringify(name) " is not a u32"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %08x, got %08x", \ + sa->f, sb->f); \ + r =3D false; \ + } \ + } while (0) + +#define STATE_CHECK_U64(r, p, n, sa, sb, f) \ + do { \ + static_assert(__same_type(sa->f, sb->f), \ + __stringify(f) " field types don't match"); \ + static_assert(__same_type(sa->f, (u64)0), \ + __stringify(name) " is not a u64"); \ + if (sa->f !=3D sb->f) { \ + drm_atomic_helper_print_state_mismatch(p, \ + n, \ + __stringify(f), \ + "expected %llu, got %llu", \ + sa->f, sb->f); \ + r =3D false; \ + } \ + } while (0) --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 3F2BF2EB5C4 for ; Tue, 2 Sep 2025 08:33:49 +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=1756802030; cv=none; b=hPOKAZLabMuwCzRRNfQna86SB56cNc+CgxuNMg+1UjbaQJRyrU+QEs4iH8+IyexYAKlxJnMJ3daqkdemR4pPPUZVv0kH6ierCBgA8hz0R0rLFa9D/FHJVqih7+CMvHG+laUsAk2w7qP1uU72byhKhXPI1VrUUAlSAhF7QLjybiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802030; c=relaxed/simple; bh=Eno80nTvgQVQRKC3IR1UZl5LwB2MXbm230kW2xqPWK0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=X2kUk0Bv5JdPvGCaIm8aW9Pbj0Pqh62YZksOzYyZ7Xk5653j3HA17I4+DEBg2uAS9OAqv/D2vet10n1Nw0jD+jkFEIS/+M4XpQvdVbY5Ah9mwmdLdZ2vjmeJJqEjeBKvkqvwhThrPaqpZyfx1DbA6K2XGkiP7D/OaOew+AoTF0s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bw7+V5AJ; 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="bw7+V5AJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73CE5C4CEF7; Tue, 2 Sep 2025 08:33:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802029; bh=Eno80nTvgQVQRKC3IR1UZl5LwB2MXbm230kW2xqPWK0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bw7+V5AJ+zao+9b0eYnpgWGF0NgRrCFO6xe8I0oN9IaMERckWM1IUMxZEIGwSSnKJ 5eG8zbwU8EmvP4ZDzaC8eMflHqG1m/QBMABqbnEa+OgS6ZhegfUmofOFiCb3jDYlGU S013bp7kq43iZeq0sHo21wfPuXNPHeWPbYC+c3QpmgIMAMrMWz3VkJNml1MwRFYVR1 91jn6eN/Twz10PwZscxpUml/DUazt3+GvfTiMSdZ7nbsXlNuJpRZMkUlD2olHUArET 3cmMwyBQcfOBgHMgPMnPPNOpiSIfB7jb2nNehOjySlQlsYBBqCUetSs4X4r2dvYAB7 teDjCqQxGyTuw== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:43 +0200 Subject: [PATCH 15/29] drm/atomic_state_helper: Provide atomic_compare_state helpers 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-15-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=17914; i=mripard@kernel.org; h=from:subject:message-id; bh=Eno80nTvgQVQRKC3IR1UZl5LwB2MXbm230kW2xqPWK0=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu8+/eoTc7TCnzN3Heeu97sySeHVj1ktfIEB8y7f/ xUW8PbA/I6pLAzCnAyyYoosT2TCTi9vX1zlYL/yB8wcViaQIQxcnAIwkRlbGRt26q/hv77eTJZj /orj/J+VQ1POanH8lIps+867eqqN0IkDho8WnvZdMalhaXDlr8K2O1WM9YEsUnor+w1n30v9VXD 9/9HrTRdldTpeit4/8j2qS1l4jfoslo1BH99svT35xKpJFmt2xgIA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Now that we have introduced some new infrastructure to compare state instances, let's provide helpers for the default states. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_state_helper.c | 213 ++++++++++++++++++++++++++= ++++ drivers/gpu/drm/drm_bridge.c | 16 +++ include/drm/drm_atomic_state_helper.h | 19 +++ 3 files changed, 248 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/dr= m_atomic_state_helper.c index 78556e0c08d2fa84b16d70243ddd21617a322014..289a8434db5e973825f8ba4616d= 6d8f00c8f8b0e 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -233,10 +233,48 @@ void drm_atomic_helper_crtc_destroy_state(struct drm_= crtc *crtc, __drm_atomic_helper_crtc_destroy_state(state); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); =20 +/** + * drm_atomic_helper_crtc_compare_state - default &drm_crtc_funcs.atomic_c= ompare_state hook for crtcs + * @crtc: the &struct drm_crtc instance + * @p: the &struct drm_printer to use + * @expected: Expected &struct drm_crtc_state value + * @actual: Actual &struct drm_crtc_state value + * + * Compares @actual to @expected and returns true if they are equal. + */ +bool drm_atomic_helper_crtc_compare_state(struct drm_crtc *crtc, + struct drm_printer *p, + struct drm_crtc_state *expected, + struct drm_crtc_state *actual) +{ + bool ret =3D true; + + STATE_CHECK_PTR(ret, p, crtc->name, expected, actual, crtc); + STATE_CHECK_BOOL(ret, p, crtc->name, expected, actual, enable); + STATE_CHECK_BOOL(ret, p, crtc->name, expected, actual, active); + STATE_CHECK_BOOL(ret, p, crtc->name, expected, actual, no_vblank); + STATE_CHECK_U32(ret, p, crtc->name, expected, actual, plane_mask); + STATE_CHECK_U32(ret, p, crtc->name, expected, actual, connector_mask); + STATE_CHECK_U32(ret, p, crtc->name, expected, actual, encoder_mask); + + STATE_CHECK_DISPLAY_MODE(ret, p, crtc->name, expected, actual, mode); + STATE_CHECK_DISPLAY_MODE(ret, p, crtc->name, expected, actual, adjusted_m= ode); + STATE_CHECK_PROPERTY_BLOB(ret, p, crtc->name, expected, actual, mode_blob= ); + STATE_CHECK_PROPERTY_BLOB(ret, p, crtc->name, expected, actual, degamma_l= ut); + STATE_CHECK_PROPERTY_BLOB(ret, p, crtc->name, expected, actual, ctm); + STATE_CHECK_PROPERTY_BLOB(ret, p, crtc->name, expected, actual, gamma_lut= ); + STATE_CHECK_BOOL(ret, p, crtc->name, expected, actual, vrr_enabled); + STATE_CHECK_BOOL(ret, p, crtc->name, expected, actual, self_refresh_activ= e); + STATE_CHECK_U32(ret, p, crtc->name, expected, actual, scaling_filter); + + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_crtc_compare_state); + /** * __drm_atomic_helper_plane_state_reset - resets plane state to default v= alues * @plane_state: atomic plane state, must not be NULL * @plane: plane object, must not be NULL * @@ -417,10 +455,100 @@ void drm_atomic_helper_plane_destroy_state(struct dr= m_plane *plane, __drm_atomic_helper_plane_destroy_state(state); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); =20 +static bool drm_atomic_helper_fb_compare(struct drm_printer *p, + struct drm_framebuffer *expected, + struct drm_framebuffer *actual) +{ + unsigned int i; + bool ret =3D true; + + STATE_CHECK_FORMAT_INFO(ret, p, "framebuffer", expected, actual, format); + + for (i =3D 0; i < expected->format->num_planes; i++) { + STATE_CHECK_U32(ret, p, "framebuffer", expected, actual, pitches[i]); + STATE_CHECK_U32(ret, p, "framebuffer", expected, actual, offsets[i]); + } + + STATE_CHECK_U64(ret, p, "framebuffer", expected, actual, modifier); + STATE_CHECK_U32(ret, p, "framebuffer", expected, actual, width); + STATE_CHECK_U32(ret, p, "framebuffer", expected, actual, height); + STATE_CHECK_S32_X(ret, p, "framebuffer", expected, actual, flags); + + return ret; +} + +/** + * drm_atomic_helper_plane_compare_state - default &drm_plane_funcs.atomic= _compare_state hook for planes + * @plane: drm plane + * @p: the &drm_printer to use + * @expected: Expected &struct drm_plane_state value + * @actual: Actual &struct drm_plane_state value + * + * Compares @actual to @expected and returns true if they are equal. + */ +bool drm_atomic_helper_plane_compare_state(struct drm_plane *plane, + struct drm_printer *p, + struct drm_plane_state *expected, + struct drm_plane_state *actual) +{ + bool ret =3D true; + + STATE_CHECK_PTR(ret, p, plane->name, expected, actual, plane); + STATE_CHECK_PTR(ret, p, plane->name, expected, actual, crtc); + + if (expected->fb && actual->fb) { + if (!drm_atomic_helper_fb_compare(p, expected->fb, actual->fb)) + ret =3D false; + } else if (!(!expected->fb && !actual->fb)) { + drm_atomic_helper_print_state_mismatch(p, + plane->name, + "fb", + "expected framebuffer is %s, got %s", + expected->fb ? "non-NULL" : "NULL", + actual->fb ? "non-NULL" : "NULL"); + ret =3D false; + } + + STATE_CHECK_S32(ret, p, plane->name, expected, actual, crtc_x); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, crtc_y); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, crtc_w); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, crtc_h); + STATE_CHECK_U32_16_16(ret, p, plane->name, expected, actual, src_x); + STATE_CHECK_U32_16_16(ret, p, plane->name, expected, actual, src_y); + STATE_CHECK_U32_16_16(ret, p, plane->name, expected, actual, src_w); + STATE_CHECK_U32_16_16(ret, p, plane->name, expected, actual, src_h); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, hotspot_x); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, hotspot_y); + STATE_CHECK_U16(ret, p, plane->name, expected, actual, alpha); + STATE_CHECK_U16(ret, p, plane->name, expected, actual, pixel_blend_mode); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, rotation); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, zpos); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, normalized_zpos); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, color_encoding); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, color_range); + + // TODO: damage clips + + STATE_CHECK_BOOL(ret, p, plane->name, expected, actual, ignore_damage_cli= ps); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, src.x1); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, src.x2); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, src.y1); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, src.y2); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, dst.x1); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, dst.x2); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, dst.y1); + STATE_CHECK_S32(ret, p, plane->name, expected, actual, dst.y2); + STATE_CHECK_BOOL(ret, p, plane->name, expected, actual, visible); + STATE_CHECK_U32(ret, p, plane->name, expected, actual, scaling_filter); + + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_plane_compare_state); + /** * __drm_atomic_helper_connector_state_reset - reset the connector state * @conn_state: atomic connector state, must not be NULL * @connector: connectotr object, must not be NULL * @@ -707,10 +835,69 @@ void drm_atomic_helper_connector_destroy_state(struct= drm_connector *connector, __drm_atomic_helper_connector_destroy_state(state); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); =20 +/** + * drm_atomic_helper_connector_compare_state - default &drm_connector_func= s.atomic_compare_state hook for connectors + * @connector: the &struct drm_connector instance + * @p: the &struct drm_printer to use + * @expected: Expected &struct drm_connector_state value + * @actual: Actual &struct drm_connector_state value + * + * Compares @actual to @expected and returns true if they are equal. + */ +bool drm_atomic_helper_connector_compare_state(struct drm_connector *conn, + struct drm_printer *p, + struct drm_connector_state *expected, + struct drm_connector_state *actual) +{ + bool ret =3D true; + + STATE_CHECK_PTR(ret, p, conn->name, expected, actual, connector); + STATE_CHECK_PTR(ret, p, conn->name, expected, actual, crtc); + STATE_CHECK_PTR(ret, p, conn->name, expected, actual, best_encoder); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, link_status); + + STATE_CHECK_U32(ret, p, conn->name, expected, actual, tv.select_subconnec= tor); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, tv.subconnector); + + STATE_CHECK_BOOL(ret, p, conn->name, expected, actual, self_refresh_aware= ); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, picture_aspect_rati= o); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, content_type); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, hdcp_content_type); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, scaling_mode); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, content_protection); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, colorspace); + + /* + * NOTE: We can't check max_bpc and max_requested_bpc because it + * will typically come from userspace and we can't read it out + * from the hardware. + */ + + STATE_CHECK_U32(ret, p, conn->name, expected, actual, privacy_screen_sw_s= tate); + STATE_CHECK_PROPERTY_BLOB(ret, p, conn->name, expected, actual, hdr_outpu= t_metadata); + + STATE_CHECK_U32(ret, p, conn->name, expected, actual, hdmi.broadcast_rgb); + STATE_CHECK_BOOL(ret, p, conn->name, expected, actual, hdmi.infoframes.av= i.set); + STATE_CHECK_INFOFRAME(ret, p, conn->name, expected, actual, hdmi.infofram= es.avi.data); + STATE_CHECK_BOOL(ret, p, conn->name, expected, actual, hdmi.infoframes.hd= r_drm.set); + STATE_CHECK_INFOFRAME(ret, p, conn->name, expected, actual, hdmi.infofram= es.hdr_drm.data); + STATE_CHECK_BOOL(ret, p, conn->name, expected, actual, hdmi.infoframes.sp= d.set); + STATE_CHECK_INFOFRAME(ret, p, conn->name, expected, actual, hdmi.infofram= es.spd.data); + STATE_CHECK_BOOL(ret, p, conn->name, expected, actual, hdmi.infoframes.hd= mi.set); + STATE_CHECK_INFOFRAME(ret, p, conn->name, expected, actual, hdmi.infofram= es.hdmi.data); + STATE_CHECK_BOOL(ret, p, conn->name, expected, actual, hdmi.is_limited_ra= nge); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, hdmi.output_bpc); + STATE_CHECK_U32(ret, p, conn->name, expected, actual, hdmi.output_format); + STATE_CHECK_U64(ret, p, conn->name, expected, actual, hdmi.tmds_char_rate= ); + + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_compare_state); + static void __drm_atomic_helper_private_obj_reset(struct drm_private_obj *= obj, struct drm_private_state *state) { memset(state, 0, sizeof(*state)); state->obj =3D obj; @@ -831,10 +1018,36 @@ drm_atomic_helper_bridge_reset(struct drm_bridge *br= idge) __drm_atomic_helper_bridge_reset(bridge, bridge_state); return bridge_state; } EXPORT_SYMBOL(drm_atomic_helper_bridge_reset); =20 +/** + * drm_atomic_helper_bridge_compare_state - default &drm_bridge_funcs.atom= ic_compare_state hook for bridges + * @bridge: the &struct drm_bridge instance + * @p: the &struct drm_printer to use + * @expected: Expected &struct drm_bridge_state value + * @actual: Actual &struct drm_bridge_state value + * + * Compares @actual to @expected and returns true if they are equal. + */ +bool drm_atomic_helper_bridge_compare_state(struct drm_bridge *bridge, + struct drm_printer *p, + struct drm_bridge_state *expected, + struct drm_bridge_state *actual) +{ + bool ret =3D true; + + STATE_CHECK_PTR(ret, p, "bridge", expected, actual, bridge); + STATE_CHECK_U32_X(ret, p, "bridge", expected, actual, input_bus_cfg.forma= t); + STATE_CHECK_U32_X(ret, p, "bridge", expected, actual, input_bus_cfg.flags= ); + STATE_CHECK_U32_X(ret, p, "bridge", expected, actual, output_bus_cfg.form= at); + STATE_CHECK_U32_X(ret, p, "bridge", expected, actual, output_bus_cfg.flag= s); + + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_bridge_compare_state); + void __printf(4, 5) drm_atomic_helper_print_state_mismatch(struct drm_printer *p, const char *name, const char *field, const char *format, ...) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index e803dfd8fd5aae9c16931445213df04d8715b9f6..5fe5b75773449aeeda2d723c039= 126106c8d5001 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -350,10 +350,25 @@ void drm_bridge_remove(struct drm_bridge *bridge) =20 drm_bridge_put(bridge); } EXPORT_SYMBOL(drm_bridge_remove); =20 +static bool drm_bridge_atomic_compare_priv_state(struct drm_private_obj *o= bj, + struct drm_printer *p, + struct drm_private_state *a, + struct drm_private_state *b) +{ + struct drm_bridge *bridge =3D drm_priv_to_bridge(obj); + struct drm_bridge_state *state_a =3D drm_priv_to_bridge_state(a); + struct drm_bridge_state *state_b =3D drm_priv_to_bridge_state(b); + + if (bridge->funcs->atomic_compare_state) + return bridge->funcs->atomic_compare_state(bridge, p, state_a, state_b); + else + return false; +} + static struct drm_private_state * drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj) { struct drm_bridge *bridge =3D drm_priv_to_bridge(obj); struct drm_bridge_state *state; @@ -388,10 +403,11 @@ drm_bridge_atomic_print_priv_state(struct drm_printer= *p, drm_printf(p, "\t\tcode: %04x", state->output_bus_cfg.format); drm_printf(p, "\t\tflags: %08x", state->output_bus_cfg.flags); } =20 static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = =3D { + .atomic_compare_state =3D drm_bridge_atomic_compare_priv_state, .atomic_duplicate_state =3D drm_bridge_atomic_duplicate_priv_state, .atomic_destroy_state =3D drm_bridge_atomic_destroy_priv_state, .atomic_print_state =3D drm_bridge_atomic_print_priv_state, }; =20 diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic= _state_helper.h index 3c6ffa7122cf895f1eda09ec74c6537594d4aee3..7542b1679a623ddd8bb5ed12e77= 0832f3ccf16ee 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -35,10 +35,11 @@ struct drm_crtc_state; struct drm_plane; struct drm_plane_state; struct drm_printer; struct drm_connector; struct drm_connector_state; +struct drm_printer; struct drm_private_obj; struct drm_private_state; struct drm_modeset_acquire_ctx; struct drm_device; =20 @@ -52,10 +53,14 @@ void __drm_atomic_helper_crtc_duplicate_state(struct dr= m_crtc *crtc, struct drm_crtc_state * drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc); void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state); void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state); +bool drm_atomic_helper_crtc_compare_state(struct drm_crtc *crtc, + struct drm_printer *p, + struct drm_crtc_state *expected, + struct drm_crtc_state *actual); =20 void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *state, struct drm_plane *plane); void __drm_atomic_helper_plane_reset(struct drm_plane *plane, struct drm_plane_state *state); @@ -65,10 +70,14 @@ void __drm_atomic_helper_plane_duplicate_state(struct d= rm_plane *plane, struct drm_plane_state * drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane); void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state= ); void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); +bool drm_atomic_helper_plane_compare_state(struct drm_plane *plane, + struct drm_printer *p, + struct drm_plane_state *expected, + struct drm_plane_state *actual); =20 void __drm_atomic_helper_connector_state_reset(struct drm_connector_state = *conn_state, struct drm_connector *connector); void __drm_atomic_helper_connector_reset(struct drm_connector *connector, struct drm_connector_state *conn_state); @@ -78,10 +87,15 @@ int drm_atomic_helper_connector_tv_check(struct drm_con= nector *connector, struct drm_atomic_state *state); void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *co= nnector); void __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connec= tor, struct drm_connector_state *state); +bool drm_atomic_helper_connector_compare_state(struct drm_connector *conne= ctor, + struct drm_printer *p, + struct drm_connector_state *expected, + struct drm_connector_state *actual); + struct drm_connector_state * drm_atomic_helper_connector_duplicate_state(struct drm_connector *connecto= r); void __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *st= ate); void drm_atomic_helper_connector_destroy_state(struct drm_connector *conne= ctor, @@ -98,10 +112,15 @@ void drm_atomic_helper_bridge_destroy_state(struct drm= _bridge *bridge, void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, struct drm_bridge_state *state); struct drm_bridge_state * drm_atomic_helper_bridge_reset(struct drm_bridge *bridge); =20 +bool drm_atomic_helper_bridge_compare_state(struct drm_bridge *bridge, + struct drm_printer *p, + struct drm_bridge_state *expected, + struct drm_bridge_state *actual); + void __printf(4, 5) drm_atomic_helper_print_state_mismatch(struct drm_printer *p, const char *name, const char *field, const char *format, ...); --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 BD2252EB843 for ; Tue, 2 Sep 2025 08:33:52 +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=1756802032; cv=none; b=deUS4PJrS7yCEem2nZbMkCIJz2Qx17Pnq3hwt+4QP41m9M9RMVUWsjdfUDHRhxLkaZI3P0RpLHib14YyYXeYerjpAyyo5kkzUgmSXAN0ptUIZhaj2CX3YcsBwo0T0oq9AihgqJ3UQ0XhwOzRtQFwF84QEV0V3GkHY2JOY4cXltQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802032; c=relaxed/simple; bh=nznIDz/RwyFHB64jOttfdGvwW1sYq0eP//HxxKXRQ1Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bhCLjbHN3Tw9Qf0pH28OTI4TfbqxuVg9uEPMmNqobNk5LvPQRnGX0iNPBYQ25++xsW2oJpR6mFBUQS1aUABtAXnArINtpV+R6cPyljHVjQuvMf/OuCYg8nr9i97CdQV5z+PegY8ZnhnJrBNlggLH6krHM/xvH3JmBQgdiSitP6Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f3MwPS61; 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="f3MwPS61" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 132B0C4CEED; Tue, 2 Sep 2025 08:33:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802032; bh=nznIDz/RwyFHB64jOttfdGvwW1sYq0eP//HxxKXRQ1Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=f3MwPS61atv4CneDzwNdPsGDTWICZmy+kSOteSJ4gd9jV0Zt+HnoBVbKsI4pcV4Af TEIpiDCZJZhKPDdFESBOcWux1nz53tz5y5hIF9nDHxw22pz3ydUDgVrwNoHhySXfCL wn9Je/Cv/CsVPWY3FekjcLBOd0CHOXn6CsOWEH/HWpd7suAa2qba51LZZvx8mzTToC 22M7GtaGEDWaXBqaONNDun5BsyckydSFiHz/y+9XzbPUKJ11JxP8GtnDbJD+MysY0q 5EKRSTAzE+Xl3HTa96YQSQVE3Drx183QpIN9GQH/TB+enFphcjF//QzhAPtq3iAnRG z9fi7nVcV8hvQ== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:44 +0200 Subject: [PATCH 16/29] drm/encoder: Create get_current_crtc hook 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-16-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1801; i=mripard@kernel.org; h=from:subject:message-id; bh=nznIDz/RwyFHB64jOttfdGvwW1sYq0eP//HxxKXRQ1Q=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu8WzHvutvnvcvMtkSs+bgqcvGdK8Lk3Ajtk/7782 fWRmU1aomMqC4MwJ4OsmCLLE5mw08vbF1c52K/8ATOHlQlkCAMXpwBM5KQPYzXb/eSUrSWhCppq MWldXF9LD0zdf+nx9I5zHS+z9mc6u9+NMDp4fNfufq7ldw7tnsk65x1jw1yGrYYnNjBY6s3cpjb 9pfPDyNLspSuurP96rGLVNQZ2x98Li5QWyChOZDrDxCmrUj39AwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D In order for drivers to implement drm_connectors atomic_state_readout hooks, they need to query the hardware and lookup the CRTC to set drm_connector_state.crtc. It should be easy enough for drivers that are tightly integrated from the CRTC to the connectors, but if the driver uses bridges, there's no coupling between the CRTC and encoder, and the bridge driver. The only thing the bridge has access to is the encoder, but the relationship between a CRTC and an encoder isn't a fixed mapping at the framework level, and thus the bridge can't deduce which CRTC is feeding its encoder. Thus, let's create a new hook for encoders to implement to return the CRTC they are currently connected to. Signed-off-by: Maxime Ripard --- include/drm/drm_encoder.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 977a9381c8ba943b4d3e021635ea14856df8a17d..7abb5e35ac950c941b56fc311a5= 2789bbc427df6 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -86,10 +86,23 @@ struct drm_encoder_funcs { * @debugfs_init: * * Allows encoders to create encoder-specific debugfs files. */ void (*debugfs_init)(struct drm_encoder *encoder, struct dentry *root); + + /** + * @get_current_crtc: + * + * This optional hook is used during initialization to read out + * the initial state by connectors that support atomic state + * hardware readout. + * + * Returns: + * + * The CRTC currently associated with the encoder if enabled, NULL otherw= ise. + */ + struct drm_crtc *(*get_current_crtc)(struct drm_encoder *encoder); }; =20 /** * struct drm_encoder - central DRM encoder structure * @dev: parent DRM device --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 46C1A2EB866 for ; Tue, 2 Sep 2025 08:33:55 +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=1756802035; cv=none; b=mAJsZVsOL4e8MZwYiG6iDOgX3gYhn0Fbt69T11PpLest03+jlfZL9Co6l89VRN4sKT+cFrl7KHAo01yxswH8S3vi2OmabJ1VY5n/B9JY+Qr8GxPilz/P+SvGVgeBCEmk6pUxrDmeFVJZmeugSBaI/So7IIDZFDiPgnmm5T112Wk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802035; c=relaxed/simple; bh=Uf200s2rpSOmJOf+Wvcc44k1xE0ek2fgZ011/JxQ/NQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UAOfg7fbam+sM4evsV+15bOLnWkpgjD0GpfKK9UwP1GcjiqmLcBw2/2/1yiCITydLVCJsyVlmWklsiYNiYxFp8qJpgawCW59dblPEWyheCUjs/urOV8M5hinTHMmZ5W/o2dFoDWBifGQ2Yd/hrppAOmNNQkKldXVCdY8ciwVVb8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k+u/c0ph; 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="k+u/c0ph" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CD536C4CEF8; Tue, 2 Sep 2025 08:33:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802035; bh=Uf200s2rpSOmJOf+Wvcc44k1xE0ek2fgZ011/JxQ/NQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=k+u/c0phwHPAlal5L2Z/qG8E80x7Xi/B8MMKisE3UFs6UWnLtCrVbH323ffp4VQx9 QE4BtrTtBCoQZsaUCYWjQNpMmw+u9WDv+I3fxEz+r08nGHTomeb3t5ghd8mvbyrO6n CXKvEal8o5oVDHSBI7ToeIkUIccX3h9fSCr+Mn0qqFcuWZfRy1TCmsH38n1uieGqIJ qPcM2sKIbMWH4ZoHM4cLcUolmiQ7LXGW/WAlE3zFF2eKk5NA0r3UE3rbVuqr8brrFk RT8PD09uRX73TVMLDJaQp1RF6Dn5slHHU65h6gSi9wQgBqg2Kn4ilm5UzU6hcgwu3u ld9A7Aga+Mhtg== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:45 +0200 Subject: [PATCH 17/29] 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-17-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5532; i=mripard@kernel.org; h=from:subject:message-id; bh=Uf200s2rpSOmJOf+Wvcc44k1xE0ek2fgZ011/JxQ/NQ=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu/RF+a3ymQR1Z+o8PUJs2t9Rqtx2It639e8s+5z9 CZVMUh0TGVhEOZkkBVTZHkiE3Z6efviKgf7lT9g5rAygQxh4OIUgIkkWDPWJ++f8cR7uUbv5Q67 Rz1iZ7iPfnpTv8f1QMkFuZtXlz54wes46eGF0xaK527VXTVJa9yXyNjQk3aBPVkr2DXrXeRJi5B 1jA0JJYxeLTu4dM1OeC06ZTnbUVT+hfAe5xl3fyYZJHBp6gMA 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, let's implement a new op for bridge_connector to allow just that. Signed-off-by: Maxime Ripard --- 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/d= rm/display/drm_bridge_connector.c index 091c5335355a2b6c70dd823df69ce060fd56c4f9..0cf97cd0e554fd5f1101e4afb28= f2a341bd774fb 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); } } =20 -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 =3D to_drm_bridge_connector(connector); + struct drm_connector_state *conn_state; + struct drm_bridge *readout =3D + bridge_connector->bridge_connector_hw_readout; + + if (connector->state) + connector->funcs->atomic_destroy_state(connector, + connector->state); + + conn_state =3D kzalloc(sizeof(*conn_state), GFP_KERNEL); + if (!conn_state) + return ERR_PTR(-ENOMEM); + + __drm_atomic_helper_connector_state_reset(conn_state, connector); =20 - 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; } =20 static const struct drm_connector_funcs drm_bridge_connector_funcs =3D { - .reset =3D drm_bridge_connector_reset, .detect =3D drm_bridge_connector_detect, .force =3D drm_bridge_connector_force, .fill_modes =3D drm_helper_probe_single_connector_modes, + .atomic_readout_state =3D drm_bridge_connector_readout_state, + .atomic_compare_state =3D drm_atomic_helper_connector_compare_state, .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, .debugfs_init =3D drm_bridge_connector_debugfs_init, .oob_hotplug_event =3D drm_bridge_connector_oob_hotplug_event, }; @@ -671,10 +699,12 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, if (!bridge->interlace_allowed) connector->interlace_allowed =3D false; if (!bridge->ycbcr_420_allowed) connector->ycbcr_420_allowed =3D false; =20 + if (bridge->ops & DRM_BRIDGE_OP_CONNECTOR_HW_READOUT) + bridge_connector->bridge_connector_hw_readout =3D bridge; if (bridge->ops & DRM_BRIDGE_OP_EDID) bridge_connector->bridge_edid =3D bridge; if (bridge->ops & DRM_BRIDGE_OP_HPD) bridge_connector->bridge_hpd =3D bridge; if (bridge->ops & DRM_BRIDGE_OP_DETECT) diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 5ea63b51a4dd4cb00468afcf7d126c774f63ade0..7c401e905c023923f1f94daec74= 6b56c3e478b83 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); =20 + /** + * @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 =3D BIT(8), + /** + * @DRM_BRIDGE_OP_CONNECTOR_HW_READOUT: TODO + */ + DRM_BRIDGE_OP_CONNECTOR_HW_READOUT =3D BIT(9), }; =20 /** * struct drm_bridge - central DRM bridge control structure */ --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 738972E762E for ; Tue, 2 Sep 2025 08:33:58 +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=1756802038; cv=none; b=N9Ju21QRXYhbUfiqWADjYjzmj9EDZQEWe5WyWkBqTcd3n0/k47SDEwvBovj3A6P/1fNIvSERfpcg2xPegaeheYhZgPW7EjRUo0e5mSLCI2lkWGdpYpGVUzlCY3pK8AfBJjN5EiVjSwhOEqt2bQ3GvWYmo1IR1kc1AwKqHj50E2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802038; c=relaxed/simple; bh=d/ff0PDuWLbHG6Z1QmLyzIm6dtfVTMyQzlWGkSFNkGg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oRA3U3+KGNAVoejwxwI/noOF21YKF3NoCNhkLH7Tgj+WMdt7oRojEZ7R8kGj5qEs8LzwBfNNYkzsstyefz4v77geqyEY0vTJxoUm7vJm0Xd4WS6X+T3BIYb9pl7lHPKR6mqeUGn0iGuZkc96DdB5ZXAPZjAzls3BHUIzVR+MZ6w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K2F/k5jz; 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="K2F/k5jz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 72E19C4CEED; Tue, 2 Sep 2025 08:33:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802037; bh=d/ff0PDuWLbHG6Z1QmLyzIm6dtfVTMyQzlWGkSFNkGg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=K2F/k5jzK6w96n2awx0veEjVNayfWcUn3hY9VVOb+i4fcI5fTxl8ktwSqm2rUzAuY YHCeV0IWGlWfCkDZSca7zp1nH8lIFLa0rfv8oXXl2yIQWRJePFVu3+wrmJpW1DzHb7 RK9baULFMOzZW7SPfzNvZRAU3Py+I1y2XvxvFixSMZW1HPh0WJOF9vrmZd0rYsuBdc YPjg0rNcyKIwqRLwDQwhF88izsJJsRGIMO0QZyQamJXUidTnfEmbcuZEzxybvIQp7K NWs9yJR8ndnk+uijtsxMnm5JaixpuqHK4Ov/Dg2hB583DQhTSo/jK9SqSNfdXavRJi eesjs/0B+IF+g== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:46 +0200 Subject: [PATCH 18/29] drm/tidss: Convert to drm logging 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-18-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2942; i=mripard@kernel.org; h=from:subject:message-id; bh=d/ff0PDuWLbHG6Z1QmLyzIm6dtfVTMyQzlWGkSFNkGg=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu+5/Yfd7ld+cNceB6dMRoMwO/Fr739zRcnXRG+av vTvXv83HVNZGIQ5GWTFFFmeyISdXt6+uMrBfuUPmDmsTCBDGLg4BWAi918y1js7hGa++eteVeAe OjkxqCvSI+nWrKW7owLvqCpzNfVOfB49O+Z3q9k2MdY138+HGV9Yy1hn2jJFZ6pfQdfdAuWbbRE ZfV8C3k74fHvxrEvdXL9F5h+IP2xa/bl3ncuDhGNJxZ+f/30FAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D DRM drivers should prefer the drm logging functions to the dev logging ones when possible. Let's convert the existing dev_* logs to their drm counterparts. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/tidss/tidss_crtc.c | 4 ++-- drivers/gpu/drm/tidss/tidss_dispc.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tid= ss_crtc.c index da89fd01c3376352840185cd4ac355dd41fd5bb1..f497138ad053ed4be207e12eeee= 6c304e1c949bd 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -101,11 +101,11 @@ static int tidss_crtc_atomic_check(struct drm_crtc *c= rtc, =20 mode =3D &crtc_state->adjusted_mode; =20 ok =3D dispc_vp_mode_valid(dispc, hw_videoport, mode); if (ok !=3D MODE_OK) { - dev_dbg(ddev->dev, "%s: bad mode: %ux%u pclk %u kHz\n", + drm_dbg(ddev, "%s: bad mode: %ux%u pclk %u kHz\n", __func__, mode->hdisplay, mode->vdisplay, mode->clock); return -EINVAL; } =20 if (drm_atomic_crtc_needs_modeset(crtc_state)) @@ -170,11 +170,11 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *= crtc, struct tidss_crtc *tcrtc =3D to_tidss_crtc(crtc); struct drm_device *ddev =3D crtc->dev; struct tidss_device *tidss =3D to_tidss(ddev); unsigned long flags; =20 - dev_dbg(ddev->dev, "%s: %s is %sactive, %s modeset, event %p\n", + drm_dbg(ddev, "%s: %s is %sactive, %s modeset, event %p\n", __func__, crtc->name, crtc->state->active ? "" : "not ", drm_atomic_crtc_needs_modeset(crtc->state) ? "needs" : "doesn't need", crtc->state->event); =20 /* diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/ti= dss_dispc.c index 190d32ed53f84371456ccb997d1898ed5cef9db1..8b1d6b72f303b91fbf86f7d0e35= 1800804757126 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -1063,24 +1063,26 @@ struct dispc_bus_format *dispc_vp_find_bus_fmt(stru= ct dispc_device *dispc, } =20 int dispc_vp_bus_check(struct dispc_device *dispc, u32 hw_videoport, const struct drm_crtc_state *state) { + struct tidss_device *tidss =3D dispc->tidss; + struct drm_device *dev =3D &tidss->ddev; const struct tidss_crtc_state *tstate =3D to_tidss_crtc_state(state); const struct dispc_bus_format *fmt; =20 fmt =3D dispc_vp_find_bus_fmt(dispc, hw_videoport, tstate->bus_format, tstate->bus_flags); if (!fmt) { - dev_dbg(dispc->dev, "%s: Unsupported bus format: %u\n", + drm_dbg(dev, "%s: Unsupported bus format: %u\n", __func__, tstate->bus_format); return -EINVAL; } =20 if (dispc->feat->vp_bus_type[hw_videoport] !=3D DISPC_VP_OLDI_AM65X && fmt->is_oldi_fmt) { - dev_dbg(dispc->dev, "%s: %s is not OLDI-port\n", + drm_dbg(dev, "%s: %s is not OLDI-port\n", __func__, dispc->feat->vp_name[hw_videoport]); return -EINVAL; } =20 return 0; --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 A64E82EBBA8 for ; Tue, 2 Sep 2025 08:34:00 +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=1756802040; cv=none; b=aBMvoCWOJ+Tv4xT1ZHT3QdWb/sCiRav4afKnGOsXyhjU3ohVfeFJ91d6Tc1AvJlGsJuVf+QLu7YqOEZthllF7EfU+wywsKU+zixlOCqEcxlvyqSvTwVuzaOXOiAm7xB8Rjtw6cMfFzjyJ6dq7Wkrm9AtbAjAvIpROk7zRZzNj0U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802040; c=relaxed/simple; bh=7Svl78fdjkekYvvvmJakT3vl7a++rf9bCz2XsnjQV4E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KIBDum4X2ksqw0s0pkQANIeEBdbx/vydU+ZAjPZx8Ef0dtuMyTY5owppZMFgXs3JenAClW+bDFralzNRfVnp4xAntCfvx+aaw2ygKqWKM8BSiXuEfAGWyobUZPhYpqTin2daTltBRk3hqk4Jff+EC1hw/3HC06p0nEHIQAXI4m8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aBdvvzeC; 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="aBdvvzeC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10660C4CEED; Tue, 2 Sep 2025 08:33:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802040; bh=7Svl78fdjkekYvvvmJakT3vl7a++rf9bCz2XsnjQV4E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=aBdvvzeCJyAOacNl9ww7tG7Ycex5uHAurRNP0fc7DQDkETUV/4f56Ve/MPP/VZ8l2 xuusW6a2nReFzaN4V4M7/fmE/D82E/7NkA8bW81kATxnDRHBhXQaAe8DWEukvmsbu4 XxQDTvUzQSBXErRnsRwM50ywtZV6cL+Hqlugqvr39gq36hUO4fPM3um4nSEWj85+Yh OSqIvF/+A4aVu3mNkt+FTFtvB0SgYiOCm49W7qchZ4YuVG92+CUqB70BPfVe+6GQMo WRYRpmDw+YS9P0GpGeportunpvy87rteXc0lJ35RaFTZEoWaOqthkr7yIr5mtaXrzz CQ+asghvEJJ1A== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:47 +0200 Subject: [PATCH 19/29] drm/tidss: Remove ftrace-like logs 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-19-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8372; i=mripard@kernel.org; h=from:subject:message-id; bh=7Svl78fdjkekYvvvmJakT3vl7a++rf9bCz2XsnjQV4E=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu/1KWQUCBYuUm2IkTx9ovBJ0cFH2Y9/RbZarzo46 4vOnoOZHVNZGIQ5GWTFFFmeyISdXt6+uMrBfuUPmDmsTCBDGLg4BWAiLEGMDTvNg1tXM7FOs/o3 ++X+LRWMb940u0p/ts1v3V/w6JfuBlMhjSTvTdO2PMrVnP/m0gzNZ4z1yb8vmJ0U5ZZi2tSZtDT avejikdWv/D+/8zs32zkieNHmPXuDRV7MWikko20kus/0jd1cAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D These logs don't really log any information and create checkpatch warnings. Remove them. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/tidss/tidss_crtc.c | 6 ------ drivers/gpu/drm/tidss/tidss_dispc.c | 4 ---- drivers/gpu/drm/tidss/tidss_drv.c | 16 ---------------- drivers/gpu/drm/tidss/tidss_kms.c | 4 ---- drivers/gpu/drm/tidss/tidss_plane.c | 8 -------- 5 files changed, 38 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tid= ss_crtc.c index f497138ad053ed4be207e12eeee6c304e1c949bd..091f82c86f53bc76c572de47237= 46af2e35ce1c1 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -92,12 +92,10 @@ static int tidss_crtc_atomic_check(struct drm_crtc *crt= c, struct tidss_crtc *tcrtc =3D to_tidss_crtc(crtc); u32 hw_videoport =3D tcrtc->hw_videoport; struct drm_display_mode *mode; enum drm_mode_status ok; =20 - dev_dbg(ddev->dev, "%s\n", __func__); - if (!crtc_state->enable) return 0; =20 mode =3D &crtc_state->adjusted_mode; =20 @@ -326,12 +324,10 @@ static const struct drm_crtc_helper_funcs tidss_crtc_= helper_funcs =3D { static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev =3D crtc->dev; struct tidss_device *tidss =3D to_tidss(ddev); =20 - dev_dbg(ddev->dev, "%s\n", __func__); - tidss_runtime_get(tidss); =20 tidss_irq_enable_vblank(crtc); =20 return 0; @@ -340,12 +336,10 @@ static int tidss_crtc_enable_vblank(struct drm_crtc *= crtc) static void tidss_crtc_disable_vblank(struct drm_crtc *crtc) { struct drm_device *ddev =3D crtc->dev; struct tidss_device *tidss =3D to_tidss(ddev); =20 - dev_dbg(ddev->dev, "%s\n", __func__); - tidss_irq_disable_vblank(crtc); =20 tidss_runtime_put(tidss); } =20 diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/ti= dss_dispc.c index 8b1d6b72f303b91fbf86f7d0e351800804757126..7d94c1142e8083dab00fcf5c652= ae40f98baeabf 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -2863,12 +2863,10 @@ int dispc_runtime_resume(struct dispc_device *dispc) return 0; } =20 void dispc_remove(struct tidss_device *tidss) { - dev_dbg(tidss->dev, "%s\n", __func__); - tidss->dispc =3D NULL; } =20 static int dispc_iomap_resource(struct platform_device *pdev, const char *= name, void __iomem **base) @@ -3006,12 +3004,10 @@ int dispc_init(struct tidss_device *tidss) struct dispc_device *dispc; const struct dispc_features *feat; unsigned int i, num_fourccs; int r =3D 0; =20 - dev_dbg(dev, "%s\n", __func__); - feat =3D tidss->feat; =20 if (feat->subrev !=3D DISPC_K2G) { r =3D dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); if (r) diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tids= s_drv.c index 27d9a8fd541fc164f2fb2535f148432bd7895f46..1c8cc18bc53c3ea3c50368b9f55= ab02a0a02fc77 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -31,45 +31,37 @@ =20 int tidss_runtime_get(struct tidss_device *tidss) { int r; =20 - dev_dbg(tidss->dev, "%s\n", __func__); - r =3D pm_runtime_resume_and_get(tidss->dev); WARN_ON(r < 0); return r; } =20 void tidss_runtime_put(struct tidss_device *tidss) { int r; =20 - dev_dbg(tidss->dev, "%s\n", __func__); - pm_runtime_mark_last_busy(tidss->dev); =20 r =3D pm_runtime_put_autosuspend(tidss->dev); WARN_ON(r < 0); } =20 static int __maybe_unused tidss_pm_runtime_suspend(struct device *dev) { struct tidss_device *tidss =3D dev_get_drvdata(dev); =20 - dev_dbg(dev, "%s\n", __func__); - return dispc_runtime_suspend(tidss->dispc); } =20 static int __maybe_unused tidss_pm_runtime_resume(struct device *dev) { struct tidss_device *tidss =3D dev_get_drvdata(dev); int r; =20 - dev_dbg(dev, "%s\n", __func__); - r =3D dispc_runtime_resume(tidss->dispc); if (r) return r; =20 return 0; @@ -77,21 +69,17 @@ static int __maybe_unused tidss_pm_runtime_resume(struc= t device *dev) =20 static int __maybe_unused tidss_suspend(struct device *dev) { struct tidss_device *tidss =3D dev_get_drvdata(dev); =20 - dev_dbg(dev, "%s\n", __func__); - return drm_mode_config_helper_suspend(&tidss->ddev); } =20 static int __maybe_unused tidss_resume(struct device *dev) { struct tidss_device *tidss =3D dev_get_drvdata(dev); =20 - dev_dbg(dev, "%s\n", __func__); - return drm_mode_config_helper_resume(&tidss->ddev); } =20 static __maybe_unused const struct dev_pm_ops tidss_pm_ops =3D { SET_SYSTEM_SLEEP_PM_OPS(tidss_suspend, tidss_resume) @@ -125,12 +113,10 @@ static int tidss_probe(struct platform_device *pdev) struct tidss_device *tidss; struct drm_device *ddev; int ret; int irq; =20 - dev_dbg(dev, "%s\n", __func__); - tidss =3D devm_drm_dev_alloc(&pdev->dev, &tidss_driver, struct tidss_device, ddev); if (IS_ERR(tidss)) return PTR_ERR(tidss); =20 @@ -226,12 +212,10 @@ static void tidss_remove(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; struct tidss_device *tidss =3D platform_get_drvdata(pdev); struct drm_device *ddev =3D &tidss->ddev; =20 - dev_dbg(dev, "%s\n", __func__); - drm_dev_unregister(ddev); =20 drm_atomic_helper_shutdown(ddev); =20 tidss_irq_uninstall(ddev); diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tids= s_kms.c index c34eb90cddbeac634f281cf163d493ba75b7ea29..86eb5d97410bedced57129c2bbc= d35f1719424c2 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -22,12 +22,10 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *ddev =3D old_state->dev; struct tidss_device *tidss =3D to_tidss(ddev); =20 - dev_dbg(ddev->dev, "%s\n", __func__); - tidss_runtime_get(tidss); =20 drm_atomic_helper_commit_modeset_disables(ddev, old_state); drm_atomic_helper_commit_planes(ddev, old_state, DRM_PLANE_COMMIT_ACTIVE_= ONLY); drm_atomic_helper_commit_modeset_enables(ddev, old_state); @@ -243,12 +241,10 @@ static int tidss_dispc_modeset_init(struct tidss_devi= ce *tidss) int tidss_modeset_init(struct tidss_device *tidss) { struct drm_device *ddev =3D &tidss->ddev; int ret; =20 - dev_dbg(tidss->dev, "%s\n", __func__); - ret =3D drmm_mode_config_init(ddev); if (ret) return ret; =20 ddev->mode_config.min_width =3D 8; diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/ti= dss_plane.c index 142ae81951a0916ccf7d3add1b83b011eca7f6b9..bd10bc1b9961571e6c6dee26698= 149fc9dd135b0 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -40,12 +40,10 @@ static int tidss_plane_atomic_check(struct drm_plane *p= lane, struct drm_crtc_state *crtc_state; u32 hw_plane =3D tplane->hw_plane_id; u32 hw_videoport; int ret; =20 - dev_dbg(ddev->dev, "%s\n", __func__); - if (!new_plane_state->crtc) { /* * The visible field is not reset by the DRM core but only * updated by drm_atomic_helper_check_plane_state(), set it * manually. @@ -122,12 +120,10 @@ static void tidss_plane_atomic_update(struct drm_plan= e *plane, struct tidss_plane *tplane =3D to_tidss_plane(plane); struct drm_plane_state *new_state =3D drm_atomic_get_new_plane_state(stat= e, plane); u32 hw_videoport; =20 - dev_dbg(ddev->dev, "%s\n", __func__); - if (!new_state->visible) { dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false); return; } =20 @@ -141,24 +137,20 @@ static void tidss_plane_atomic_enable(struct drm_plan= e *plane, { struct drm_device *ddev =3D plane->dev; struct tidss_device *tidss =3D to_tidss(ddev); struct tidss_plane *tplane =3D to_tidss_plane(plane); =20 - dev_dbg(ddev->dev, "%s\n", __func__); - dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, true); } =20 static void tidss_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) { struct drm_device *ddev =3D plane->dev; struct tidss_device *tidss =3D to_tidss(ddev); struct tidss_plane *tplane =3D to_tidss_plane(plane); =20 - dev_dbg(ddev->dev, "%s\n", __func__); - dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false); } =20 static void drm_plane_destroy(struct drm_plane *plane) { --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 508902EBDFA for ; Tue, 2 Sep 2025 08:34:03 +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=1756802043; cv=none; b=kHSMW/btaT6eEdpOU6ZwPDBiCEMPzKJPg2hD4sG93AwaR6X8+xpwv2uOWr+QBJxEmsBwi5NNNJhKJC2h7+v92FuAs2CMjL9+xcWWHotn8HSnA+kMQMKkES8UBrCw62432menCBDC5JsRooKvgFlFLqSgwmlqAYh5OcFxDXAiw4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802043; c=relaxed/simple; bh=7htVe8qzOBLCTGcYaqAkeRIfioQ4YdQGYbL+cD4yqKg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GZMip9Ry6dNoPmiy0MKhP+dDnD1koQjC+gNgPzMm/HRGw91FEr7QHh9zNYJeKaKS0/tyGXAjKC+T9nl+LU9JIm7RqRInPPGPcAfieQqTyHqExGAi3EeKvkRIHH7P1JufOzg2etdvm2ffRpAJLleOyK0d5ULH09QOx6DIGrzYhh0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i+wgCC51; 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="i+wgCC51" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D71DCC4CEF7; Tue, 2 Sep 2025 08:34:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802043; bh=7htVe8qzOBLCTGcYaqAkeRIfioQ4YdQGYbL+cD4yqKg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=i+wgCC51chdcj4XnR5i7iqsDbI9+aIZWhAp9XHWAJ8WoRQsqz4UjS1F/FJXZP1KzZ dbYnaXpSYJoYWIB+cggDbM+NvKW3RCIAOMTufO+uvdtn+teYeGhZUs7Qj3IjWmkLjq 2uei/udkcwi6c/dOJiK9d4n0POtKwm/l5VBh8AYujqyv3e96cvQ63G9yP0IXDBSpo3 9wn1R5tMNrKkPxg1/sATxdki2Tl6QeWm3YwgTsk9f/89t/KQ8om8g/fKLzfkvgL5Tb 6TchgWKUBZaFKn46adtqort+67vP5nMMO+uOREsZkCwQ72HR9LfEN6Z4JdexduG38e cw2Ou7b2bEAxQ== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:48 +0200 Subject: [PATCH 20/29] drm/tidss: crtc: Change variable name 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-20-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1477; i=mripard@kernel.org; h=from:subject:message-id; bh=7htVe8qzOBLCTGcYaqAkeRIfioQ4YdQGYbL+cD4yqKg=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu99vm2SV1RxoPFSBRth//zassx67hUrU7vrC7MVy +pNbJw7prIwCHMyyIopsjyRCTu9vH1xlYP9yh8wc1iZQIYwcHEKwERm8DLWCq9p6fb4lTrpxi8W 3h+d1+dOlBDbG9R9RD+Mv0Zly6ybm6Vu1s553d7m3esuL6t1NK+bsWGnUXdKWMuyMgnJ015fLy7 8toVboNbeKqPpWozEXw/LKy4/k51MKuaYPij6+uypN39NPgA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The tidss_crtc_reset() function stores a pointer to struct tidss_crtc_state in a variable called tcrtc, while it uses tcrtc as a pointer to struct tidss_crtc in the rest of the driver. This is confusing, so let's change the variable name. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/tidss/tidss_crtc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tid= ss_crtc.c index 091f82c86f53bc76c572de4723746af2e35ce1c1..db7c5e4225e6247047087a35a2e= 6422950fc0111 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -343,24 +343,24 @@ static void tidss_crtc_disable_vblank(struct drm_crtc= *crtc) tidss_runtime_put(tidss); } =20 static void tidss_crtc_reset(struct drm_crtc *crtc) { - struct tidss_crtc_state *tcrtc; + struct tidss_crtc_state *tstate; =20 if (crtc->state) __drm_atomic_helper_crtc_destroy_state(crtc->state); =20 kfree(crtc->state); =20 - tcrtc =3D kzalloc(sizeof(*tcrtc), GFP_KERNEL); - if (!tcrtc) { + tstate =3D kzalloc(sizeof(*tstate), GFP_KERNEL); + if (!tstate) { crtc->state =3D NULL; return; } =20 - __drm_atomic_helper_crtc_reset(crtc, &tcrtc->base); + __drm_atomic_helper_crtc_reset(crtc, &tstate->base); } =20 static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *= crtc) { struct tidss_crtc_state *state, *current_state; --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 E56382EC0BA for ; Tue, 2 Sep 2025 08:34:05 +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=1756802046; cv=none; b=b9E+SjIle3DI6sYKIcLxgDcczbdQK0Uw9hVQ5drdY1NWD6piwEcO4fwkxq2vioYpwufLwcK/6qhDqAzPYjqQzBtOdCq2XaA484F/zOnuIgIoz4onA5D+roOLSG9y86QgfuTEihXd9i37qxpJedmfY0HhdeExcrBuGOrs1owGUns= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802046; c=relaxed/simple; bh=Sx1SiWBtyvx9TDs81K147uwwCFZefbSRe2g1f7tHAGI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IqRcKk26+vXxYp0yOJUWqUeR1kB9UnIcRMe70TJIRs7DiWBKwuyoel5IokLaSBFNUChYdyTy+eNvHCSxGUkpjXSVgnBoOr2NH2BKd5xYQapeQxUVOc2aTkx0uZCZDSERCLEplTxwtVlwQF3LNAV+kc1+2EuYA+vaf8hONStkG4U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pTK+aPB3; 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="pTK+aPB3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 766BAC4CEF5; Tue, 2 Sep 2025 08:34:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802045; bh=Sx1SiWBtyvx9TDs81K147uwwCFZefbSRe2g1f7tHAGI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pTK+aPB3SO4+njn53esBnhzyx+sUJW1leLBrRvhXiWfmA6QjHepkh7etr+zIYvpZP QQOS2Mh2fLnOUS8j6N1VhhkQL7B3SlzC8XlvGYLRJqW6+nvxPXz+vsM1v2A7dFOBy2 TPYgZS1rb5LQmrKYhO3x3MaflW2nDcbH7KfjqE4OgudAqQ9VC9lGZNRJph9HBdb9ND 7UijJshHlF5eO96T0ZQA69eAlxvoZPDkyjy4i8JnaRf/SxFBtSwzYAG5rzIp4gfZFl SNcENSp+uEfDemz+dudotg9y1lyabhpK+nUSEEKs9QQFpRwCYWSlU33LU+6xIQ1MpC f0YNtT4DEYPzg== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:49 +0200 Subject: [PATCH 21/29] drm/tidss: crtc: Implement destroy_state 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-21-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1923; i=mripard@kernel.org; h=from:subject:message-id; bh=Sx1SiWBtyvx9TDs81K147uwwCFZefbSRe2g1f7tHAGI=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu896ua9wGxF4r+3d5+YP12poCC8evsiC6NHrKvPh HHONsvn6JjKwiDMySArpsjyRCbs9PL2xVUO9it/wMxhZQIZwsDFKQATqStjbFi3/mDxjoupC3+J Cv0K3Ddrp19Z52a1hnLm8lXVQubd1Tcn3WFesyvipvryJTMLjq6J4mGsdyj8uenf2m1rnSz2buR br9zQL2r0+v0rW/5pl8TUXPLsb3b8cP4xr700b9XGxNbvK4x9AQ== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The tidss crtc driver implements its own state, with its own implementation of reset and duplicate_state, but uses the default destroy_state helper. This somewhat works for now because the drm_crtc_state field in tidss_crtc_state is the first field so the offset is 0, but it's pretty fragile and it should really have its own destroy_state implementation. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/tidss/tidss_crtc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tid= ss_crtc.c index db7c5e4225e6247047087a35a2e6422950fc0111..eb431a238b11d22349d61f0e17f= 05994f50d5f2f 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -341,10 +341,19 @@ static void tidss_crtc_disable_vblank(struct drm_crtc= *crtc) tidss_irq_disable_vblank(crtc); =20 tidss_runtime_put(tidss); } =20 +static void tidss_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct tidss_crtc_state *tstate =3D to_tidss_crtc_state(state); + + __drm_atomic_helper_crtc_destroy_state(&tstate->base); + kfree(tstate); +} + static void tidss_crtc_reset(struct drm_crtc *crtc) { struct tidss_crtc_state *tstate; =20 if (crtc->state) @@ -396,11 +405,11 @@ static const struct drm_crtc_funcs tidss_crtc_funcs = =3D { .reset =3D tidss_crtc_reset, .destroy =3D tidss_crtc_destroy, .set_config =3D drm_atomic_helper_set_config, .page_flip =3D drm_atomic_helper_page_flip, .atomic_duplicate_state =3D tidss_crtc_duplicate_state, - .atomic_destroy_state =3D drm_atomic_helper_crtc_destroy_state, + .atomic_destroy_state =3D tidss_crtc_destroy_state, .enable_vblank =3D tidss_crtc_enable_vblank, .disable_vblank =3D tidss_crtc_disable_vblank, }; =20 struct tidss_crtc *tidss_crtc_create(struct tidss_device *tidss, --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 882442EC553 for ; Tue, 2 Sep 2025 08:34:08 +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=1756802048; cv=none; b=D29ls8uKqbNZwWH6I2uX42sf9xr+cQo2Wl41ziFgGa5UCGoPEpejfGbb6HAlqyXD71v8cIiz/EBPAwTA4nlo1PLsUub/ijSfDHwWTNUkuFomaLDfGo1l5D4j3gSbl3CVHr5ZSmHcvBovCR9UkYeKY3UKtEjRgimqLM3rFjN7C1Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802048; c=relaxed/simple; bh=CJPCj8VWwLfpomy9Zok5G16ISXjah6HfvSiZNbxLUwg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IBna6oF4iGh3U1zGAC3Ej5tXTT+cYjqemoZ4KsC5OhgpBs2rQUXDZcZS6ee8fTsphZfNr3axctm84zCSRc6/wYbG6lGW4+jN3Ymoq1FdNLHGhGyuJZqobpGjgKQWkGr9bVgsOMm9OYAJ8YPMRhjVNJkyk6qmF6HPfS7NoU8Zcxs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZR+P5tMY; 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="ZR+P5tMY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18CFDC4CEED; Tue, 2 Sep 2025 08:34:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802048; bh=CJPCj8VWwLfpomy9Zok5G16ISXjah6HfvSiZNbxLUwg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZR+P5tMY49rlPeoRiqsLU64936WnRpKITzZdZVJL8FcfjK5Nu6cykFbn/PbAHNm/Z +cuIk4djsGxLuYOZnO4qujCTC149UOgHCTXfeFZtSX9x+HtCHuMyG8crUTNQV0L+0c shjPKFai7snEiizUOWGjCSR2+D3WjTKDCe4mR6gXbWbX8liL9t4wc4gPE8XielDaz4 QLWEKDsFl6HuPbeNZf+dNrSYNTxReVPpR6T75+CvUF230b7ayDT89TehVcieRB8frJ gt2uqO+TPekQhjjF7DeANlcp/9yJfv/qyolBgJbZzMQRacLNEgbu3JvL2M/QLg4LGa NofaaLQIo6gUw== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:50 +0200 Subject: [PATCH 22/29] drm/tidss: crtc: Cleanup reset implementation 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-22-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1422; i=mripard@kernel.org; h=from:subject:message-id; bh=CJPCj8VWwLfpomy9Zok5G16ISXjah6HfvSiZNbxLUwg=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu/bOmdNXX9s+sodna/7Pwh8OVp9JnNPat4542ZLZ VGB99tOd0xlYRDmZJAVU2R5IhN2enn74ioH+5U/YOawMoEMYeDiFICJHFjF2LDt+3u39Pk/Yous 7sj8t4w/xvX3aBtnzKOTIadYP6+PZvJwOlz52rzs1fwdfvfUuNNEJzE2XJA1UXLt+fR69sTTeVW SZhcNLbwEXu1e5neFf9nDE5Mn/nkd9lFx9wZ+y5tdBT6+hW9aAQ== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The tidss_crtc_reset() function will (rightfully) destroy any pre-existing state. However, the tidss CRTC driver has its own CRTC state structure that subclasses drm_crtc_state, and yet will destroy the previous state by calling __drm_atomic_helper_crtc_destroy_state() and kfree() on its drm_crtc_state pointer. It works only because the drm_crtc_state is the first field in the structure, and thus its offset is 0. It's incredibly fragile however, so let's call our destroy implementation in such a case to deal with it properly. Signed-off-by: Maxime Ripard Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/tidss/tidss_crtc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tid= ss_crtc.c index eb431a238b11d22349d61f0e17f05994f50d5f2f..8fcc6a2f94770ae825eeb2a3b09= 856a2bf2d6a1e 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -355,13 +355,11 @@ static void tidss_crtc_destroy_state(struct drm_crtc = *crtc, static void tidss_crtc_reset(struct drm_crtc *crtc) { struct tidss_crtc_state *tstate; =20 if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); - - kfree(crtc->state); + tidss_crtc_destroy_state(crtc, crtc->state); =20 tstate =3D kzalloc(sizeof(*tstate), GFP_KERNEL); if (!tstate) { crtc->state =3D NULL; return; --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 6F7B42E9741 for ; Tue, 2 Sep 2025 08:34:11 +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=1756802052; cv=none; b=js5TBb8IT8x3NdqOI3CxAkgvnKA/VbJLKuD007e8HfcyEInNtByAiIwmEqd3ufnyCTRXjNPeC5aF6r5Rqc05o/jK/uRAkGSV3ulmL9KXYziAWr+ruTB2UIZmNlw4dUcSAcUPCi41bLs2nbMMeOEkP4l9XcdruqrRFN2n4Pad7ps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802052; c=relaxed/simple; bh=IschafHJlnxfPmLAmtyZZlIURuTFkl8YKzxycliOS4U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=L9snkhEnQbBnunxLvEWq4t4COS+gKOZrgQKudxPQrKMIew6aDgG+5oZp5UhPhmEtMZC+AFBBpmyaNwyr+rPw6pnP5NxijkDmUC0+caomrute9IzqKeM6/xxRRqi9f1cTO5vB+0DLPYPonE6oNQRDzfpjpDaLP2uBIGJpTvpv+Rs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mAkzWtc0; 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="mAkzWtc0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AFB6EC4CEF7; Tue, 2 Sep 2025 08:34:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802051; bh=IschafHJlnxfPmLAmtyZZlIURuTFkl8YKzxycliOS4U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mAkzWtc08wcIQ/JhwLldU+WE3kZGxJ+fJn7+L5uxozbxHTcwKeSdebNb+fSMgwjlX /Wr6th7qQAOCiEV3POxfqLYB2KtbxZ5+loh3TacEDSUxxM9RNWWoXdBaS/7Zr/7ZXA jT/3NlBYyjjehiS0JBi4niie616P8n0/C7/lbhb5cHDwytcUkzP8f5H0+3clL/3mEb YvU0rMupO7EjxWJAOZXXs/8jZhcbmHld61gqgW01LOi04lQgNFbuMIeva/4ZxSL+SR z5eyTqZyo9p6MWZbZdZIOmNCWczmV6i56w2AtspXHJxYKzKMeNSzWQHsF8Pau14EvO DTyBkWF7e/qhA== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:51 +0200 Subject: [PATCH 23/29] drm/tidss: dispc: Add format lookup by hw value 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-23-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2072; i=mripard@kernel.org; h=from:subject:message-id; bh=IschafHJlnxfPmLAmtyZZlIURuTFkl8YKzxycliOS4U=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu/b9qRfbEXn5o8vNp95YTJfQfz+l0DzB/eVN92c9 qpTTGPL/46pLAzCnAyyYoosT2TCTi9vX1zlYL/yB8wcViaQIQxcnAIwEVlZxjqFcoXJ593/xB0R KLmYcNqwPFDzx2H2xwzp847Lyk0vXWrori/LoyjCfjdb91nbrnU77jE29B/aWZglqrt/3uF9B1r eWPny2zAd33RB56uzhyP3jhNH+mbobhaPXs+zwyb7lMyGpAxBAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The tidss dispc driver has a table associating fourcc's and their hardware representation. So far, we only needed to do the fourcc to hardware lookup, but we'll need to do the hardware to fourcc lookup in the future, so let's provide a function to do so. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tidss/tidss_dispc.c | 11 +++++++++++ drivers/gpu/drm/tidss/tidss_dispc.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/ti= dss_dispc.c index 7d94c1142e8083dab00fcf5c652ae40f98baeabf..32248b5f71b7566dc33d7a7db0e= fb26d3a9ed1c3 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -2117,10 +2117,21 @@ static const struct { { DRM_FORMAT_UYVY, 0x3f, }, =20 { DRM_FORMAT_NV12, 0x3d, }, }; =20 +u32 dispc_plane_find_fourcc_by_dss_code(u8 code) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(dispc_color_formats); ++i) + if (dispc_color_formats[i].dss_code =3D=3D code) + return dispc_color_formats[i].fourcc; + + return 0; +} + static void dispc_plane_set_pixel_format(struct dispc_device *dispc, u32 hw_plane, u32 fourcc) { unsigned int i; =20 diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/ti= dss_dispc.h index 60c1b400eb8933dd13efd4ae3d09dc9569eed96f..849ec984026e223de7c8a55a4b5= 672c2262f38c0 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.h +++ b/drivers/gpu/drm/tidss/tidss_dispc.h @@ -146,10 +146,11 @@ int dispc_plane_check(struct dispc_device *dispc, u32= hw_plane, void dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane, const struct drm_plane_state *state, u32 hw_videoport); void dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool ena= ble); const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *l= en); +u32 dispc_plane_find_fourcc_by_dss_code(u8 code); =20 int dispc_init(struct tidss_device *tidss); void dispc_remove(struct tidss_device *tidss); =20 #endif --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 0B2A82EC572 for ; Tue, 2 Sep 2025 08:34:13 +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=1756802054; cv=none; b=Rvhvdy/1K1GmTz50agLDt3yjkodSxVb/B/8sfBIccz2+S4WbLz5RUnMtr30c7hIvKhq8GooGWwX/PubLdbyK0XeTR+VY3fHI22D6dxxq3AOZaqJKpKKUvfntxcNq9DTvOCyZ6oUW7M+CPk21WCBmUCxhMJ8GBsTwZW+rI9y8/iw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802054; c=relaxed/simple; bh=8MPmTxUTV3g1rzAZxNPkLlwzM2lhv8IEy3sLqM4qcjM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A99GobEs5Ttdx30uBfX21eGtU+qrfUWJb6HwykY31uYpMQnQp1r861zMV1boK64jZPPFgpOfs+E7nYIhaiHRLsgtq8cUiqN+Plnb3AyVMspRLGdDvUx/oSImQbQ8Nq0uVO1MVHHOkjdFHEBm2tTBh7+tYMMmkkK0PEys8wPFuNU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NPbTkk3B; 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="NPbTkk3B" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4FB54C4CEED; Tue, 2 Sep 2025 08:34:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802053; bh=8MPmTxUTV3g1rzAZxNPkLlwzM2lhv8IEy3sLqM4qcjM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NPbTkk3BdqK9YFrNnktddrvvZYhOIcwi7pmv6ifLQt/TsekHBob3GXp7dUT3sCxQj eoAiD1gfGnwueKMtFMkSMPUI8SLukB5BjVx4vBFqDF4fK2x/GXBo2WtSypKYOsNR+I ErqiQdYbCsijVZKkAi97pq8yBXHcOlwEHcWZY//gVl96jBKGLEiOJWomzMi5J8LH4F U3qhUp9vmFO7kYlJzWZo8pP3OXOsot2jTO8Hy+xm1cYMqR+smsKuGqIM6m/Lvquudo SXEDVA/qhEa5RwqxPesZU0EDFCjfjwCOqEDhZgp28YNE4GKPeagUW8ste7CG2/ignV LG3GzTNsx+Irw== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:52 +0200 Subject: [PATCH 24/29] drm/tidss: dispc: Improve mode checking logs 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-24-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4279; i=mripard@kernel.org; h=from:subject:message-id; bh=8MPmTxUTV3g1rzAZxNPkLlwzM2lhv8IEy3sLqM4qcjM=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu9vFH0+3zxEZtvCBUJvQ84lz/kWK3Rd3mRfN/fsW JvE7++mdUxlYRDmZJAVU2R5IhN2enn74ioH+5U/YOawMoEMYeDiFICJtD1mbDj7vmd++jkeh5TV 7z45hW3Sf3rjgItJfG54XV5uUOPNDyE9+/IO/blXVRGwb3fKLumEmYwNb0UCm+2D+OMnZzHrGRV uuXFx7qact3EHN7PJ1366xbkk4nkHj1b7/amyjnt04t66pAgDAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The dispc_vp_mode_valid() function checks whether a mode can be handled by the display controller. There's a whole bunch of criteria, and it's not clear when a rejection happens why it did. Let's add a bunch of logs on error to make it clearer. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tidss/tidss_dispc.c | 47 +++++++++++++++++++++++++++++----= ---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/ti= dss_dispc.c index 32248b5f71b7566dc33d7a7db0efb26d3a9ed1c3..ef948e3041e10bc65cf2c4794a4= e4cffa7e3fb3a 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -1349,47 +1349,63 @@ static void dispc_vp_set_default_color(struct dispc= _device *dispc, =20 enum drm_mode_status dispc_vp_mode_valid(struct dispc_device *dispc, u32 hw_videoport, const struct drm_display_mode *mode) { + struct tidss_device *tidss =3D dispc->tidss; + struct drm_device *dev =3D &tidss->ddev; u32 hsw, hfp, hbp, vsw, vfp, vbp; enum dispc_vp_bus_type bus_type; int max_pclk; =20 bus_type =3D dispc->feat->vp_bus_type[hw_videoport]; =20 max_pclk =3D dispc->feat->max_pclk_khz[bus_type]; =20 - if (WARN_ON(max_pclk =3D=3D 0)) + if (WARN_ON(max_pclk =3D=3D 0)) { + drm_dbg(dev, "Invalid maximum pixel clock"); return MODE_BAD; + } =20 - if (mode->clock < dispc->feat->min_pclk_khz) + if (mode->clock < dispc->feat->min_pclk_khz) { + drm_dbg(dev, "Mode pixel clock below hardware minimum pixel clock"); return MODE_CLOCK_LOW; + } =20 - if (mode->clock > max_pclk) + if (mode->clock > max_pclk) { + drm_dbg(dev, "Mode pixel clock above hardware maximum pixel clock"); return MODE_CLOCK_HIGH; + } =20 - if (mode->hdisplay > 4096) + if (mode->hdisplay > 4096) { + drm_dbg(dev, "Number of active horizontal pixels above hardware limits."= ); return MODE_BAD; + } =20 - if (mode->vdisplay > 4096) + if (mode->vdisplay > 4096) { + drm_dbg(dev, "Number of active vertical lines above hardware limits."); return MODE_BAD; + } =20 /* TODO: add interlace support */ - if (mode->flags & DRM_MODE_FLAG_INTERLACE) + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { + drm_dbg(dev, "Interlace modes not suppported."); return MODE_NO_INTERLACE; + } =20 /* * Enforce the output width is divisible by 2. Actually this * is only needed in following cases: * - YUV output selected (BT656, BT1120) * - Dithering enabled * - TDM with TDMCycleFormat =3D=3D 3 * But for simplicity we enforce that always. */ - if ((mode->hdisplay % 2) !=3D 0) + if ((mode->hdisplay % 2) !=3D 0) { + drm_dbg(dev, "Number of active horizontal pixels must be even."); return MODE_BAD_HVALUE; + } =20 hfp =3D mode->hsync_start - mode->hdisplay; hsw =3D mode->hsync_end - mode->hsync_start; hbp =3D mode->htotal - mode->hsync_end; =20 @@ -1397,29 +1413,40 @@ enum drm_mode_status dispc_vp_mode_valid(struct dis= pc_device *dispc, vsw =3D mode->vsync_end - mode->vsync_start; vbp =3D mode->vtotal - mode->vsync_end; =20 if (hsw < 1 || hsw > 256 || hfp < 1 || hfp > 4096 || - hbp < 1 || hbp > 4096) + hbp < 1 || hbp > 4096) { + drm_dbg(dev, + "Horizontal blanking or sync outside of hardware limits (fp: %u, sw: %u= , bp: %u).", + hfp, hsw, hbp); return MODE_BAD_HVALUE; + } =20 if (vsw < 1 || vsw > 256 || - vfp > 4095 || vbp > 4095) + vfp > 4095 || vbp > 4095) { + drm_dbg(dev, + "Vertical blanking or sync outside of hardware limits (fp: %u, sw: %u, = bp: %u).", + vfp, vsw, vbp); return MODE_BAD_VVALUE; + } =20 if (dispc->memory_bandwidth_limit) { const unsigned int bpp =3D 4; u64 bandwidth; =20 bandwidth =3D 1000 * mode->clock; bandwidth =3D bandwidth * mode->hdisplay * mode->vdisplay * bpp; bandwidth =3D div_u64(bandwidth, mode->htotal * mode->vtotal); =20 - if (dispc->memory_bandwidth_limit < bandwidth) + if (dispc->memory_bandwidth_limit < bandwidth) { + drm_dbg(dev, "Required memory bandwidth outside of hardware limits."); return MODE_BAD; + } } =20 + drm_dbg(dev, "Mode is valid."); return MODE_OK; } =20 int dispc_vp_enable_clk(struct dispc_device *dispc, u32 hw_videoport) { --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 761152ECD20 for ; Tue, 2 Sep 2025 08:34:16 +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=1756802056; cv=none; b=NOhiTk6nZSTOMfs+gZ4NnmvUknxzDN4oe56bfUGdQIU6TeUQ8i4BKg+N6ugPr4WwkU54lEGYA49o9jt3YIwe4/8dbecJOdL0cYrEnlRWkXdnFoJahIl1E7UG9v9Eq+0iogPbeI7SgCrR4ho2yiHgBUpazokjFHwgRjQu8H9QgvY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802056; c=relaxed/simple; bh=rt6xHw1/6F4wIZvvIQx12pdyMgsEZs64/BuHhHgoQwY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=skpyybpHaoVgQllpCzXeJxbEz/gKdZqK4Tj8QLokHclhhT6SaUMisqSqdecJovEGk0nU2E0pMhdJm+2WfZLuW8EZlx7tycdWO1sybPlJj9FjHYtESU5tS3Rsyi/n6XQw7m70cSIqm7jGBPB8TRSvXBW9/XKuA+EGI969KkHkjkI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OE9wNu6F; 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="OE9wNu6F" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E1A02C4CEED; Tue, 2 Sep 2025 08:34:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802056; bh=rt6xHw1/6F4wIZvvIQx12pdyMgsEZs64/BuHhHgoQwY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OE9wNu6Fow/wzbcDKpaesIgEoPQDBgwiy3phinjKnfBpJjNYcFqDTaZHjgx22BYrn JuRDoSEXIkqzW0itymk/DH6pMziXluwWwdzaK+iVXOJTtTSQsRvv1yfW/ujpHICsQ0 q4T+b0VOivpxSLB+1qqJILq4qz0cO96bawJs0sp8Zq+p94icSWLdxcEb76PA1qPFhR 4Q2iGyB7eCWpA/9EEsruBBG8cW3I8eIZBu1ihtV/lcSFyxxqcQQRnXDTwbQeAFPxXy m3U5PqVjikq9gendmC5hS6dHCOJoUY4BJOEDz5UJqXN4CvKvEMtsGwr5WwyA+Vy/69 /0D9ukBT7+UuA== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:53 +0200 Subject: [PATCH 25/29] drm/tidss: dispc: Move dispc_device definition to headers 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-25-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3016; i=mripard@kernel.org; h=from:subject:message-id; bh=rt6xHw1/6F4wIZvvIQx12pdyMgsEZs64/BuHhHgoQwY=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVu9vWbVg48IHYQnLPijEmvWE2DJstFfbbHFAdnr2j U3qJgwzO6ayMAhzMsiKKbI8kQk7vbx9cZWD/cofMHNYmUCGMHBxCsBEFu5irE/61DHnc6/J/VVS s56FM9Wvz+cTep4wMWl26IcmAfsrE+96Lti571nNreyAyQl9J8/tj2BsuFGn7jBlyck5LZu2met f/nS6tM74UY9ewYQeyz1dlZ97/CV37Up1TVi52KFgps8lCxklAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D We'll need to access the dispc_device structure from other parts of the driver so let's move it to a header. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tidss/tidss_dispc.c | 33 --------------------------------- drivers/gpu/drm/tidss/tidss_dispc.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/ti= dss_dispc.c index ef948e3041e10bc65cf2c4794a4e4cffa7e3fb3a..2f9cf95d6d0525a02d8adaae968= aa551b7e27077 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -476,43 +476,10 @@ const struct dispc_features dispc_am62l_feats =3D { .vid_order =3D {0}, }; =20 static const u16 *dispc_common_regmap; =20 -struct dss_vp_data { - u32 *gamma_table; -}; - -struct dispc_device { - struct tidss_device *tidss; - struct device *dev; - - void __iomem *base_common; - void __iomem *base_vid[TIDSS_MAX_PLANES]; - void __iomem *base_ovr[TIDSS_MAX_PORTS]; - void __iomem *base_vp[TIDSS_MAX_PORTS]; - - struct regmap *am65x_oldi_io_ctrl; - - struct clk *vp_clk[TIDSS_MAX_PORTS]; - - const struct dispc_features *feat; - - struct clk *fclk; - - bool is_enabled; - - struct dss_vp_data vp_data[TIDSS_MAX_PORTS]; - - u32 *fourccs; - u32 num_fourccs; - - u32 memory_bandwidth_limit; - - struct dispc_errata errata; -}; - static void CH(struct dispc_device *dispc) { WARN_ON((dispc->dev->power.runtime_status !=3D RPM_ACTIVE) && (dispc->dev->power.runtime_status !=3D RPM_RESUMING) && (dispc->dev->power.runtime_status !=3D RPM_SUSPENDING)); diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/ti= dss_dispc.h index 849ec984026e223de7c8a55a4b5672c2262f38c0..f5d5798de1ba550dedbcba36b1e= f41d5ecceaa0c 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.h +++ b/drivers/gpu/drm/tidss/tidss_dispc.h @@ -95,10 +95,43 @@ struct dispc_features { u32 num_vids; struct dispc_vid_info vid_info[TIDSS_MAX_PLANES]; u32 vid_order[TIDSS_MAX_PLANES]; }; =20 +struct dss_vp_data { + u32 *gamma_table; +}; + +struct dispc_device { + struct tidss_device *tidss; + struct device *dev; + + void __iomem *base_common; + void __iomem *base_vid[TIDSS_MAX_PLANES]; + void __iomem *base_ovr[TIDSS_MAX_PORTS]; + void __iomem *base_vp[TIDSS_MAX_PORTS]; + + struct regmap *am65x_oldi_io_ctrl; + + struct clk *vp_clk[TIDSS_MAX_PORTS]; + + const struct dispc_features *feat; + + struct clk *fclk; + + bool is_enabled; + + struct dss_vp_data vp_data[TIDSS_MAX_PORTS]; + + u32 *fourccs; + u32 num_fourccs; + + u32 memory_bandwidth_limit; + + struct dispc_errata errata; +}; + extern const struct dispc_features dispc_k2g_feats; extern const struct dispc_features dispc_am625_feats; extern const struct dispc_features dispc_am62a7_feats; extern const struct dispc_features dispc_am62l_feats; extern const struct dispc_features dispc_am65x_feats; --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 F3B412ECE87 for ; Tue, 2 Sep 2025 08:34:18 +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=1756802059; cv=none; b=V4kD8OZtdZJG6pFceDBgAwXBh93c7H4t3u0Bp6X/nTWPK9mXhx6xPIS3N2tazdXIyaf/ol5zJ9vIKp2H8M4cAHL0NBFkvTmeWXKMZD67r7q+IaZv083nLFoNJwwZZDkM/akWVLCDaL1tfDTSwZgx5efL8nmk1hvaytWRivRKq6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802059; c=relaxed/simple; bh=6y3aIMSfaSkH8Ni+8XNxtNqvzdtes72Di9oihgPJJu4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Sjwoxme5fYAq4INRTOmLjGzHXMDgG2DtZ+IOS4QU+M1Ng02Y9zHw4mRdHcgc06U059yLkCaxDQq+W0la4VTe9VYI5QbVQiL8f/Ogo57I0+G80TOuN+Tyudmie8DakeNJnisJsWRGXZ/vm4UBkAk5SGiYC94144DH570sk5tycPo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ROqW1Pv/; 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="ROqW1Pv/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85923C4CEF7; Tue, 2 Sep 2025 08:34:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802058; bh=6y3aIMSfaSkH8Ni+8XNxtNqvzdtes72Di9oihgPJJu4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ROqW1Pv//GU9c/bbW5HHgd+xBAFtBD8xsXz/Uc4reii0BIBmGEmlQ8OCKuuMpy2J2 N5a9AMJySEOm5nIs0cI2PoQ4JswyEZIqCXYUAlPU+N7RAYJ1OctTqYNjFuMk3mlX+G 5q8yNTUrDTW62lfkJ9fHzMFPc9C5+ObaMNDDziva10aHl/74MqLcxvILq/LWmbftw1 3L/Mb/LU5Gk21uhkUCHrY0s/BkLuKVPPa3dIr0WVvy4wX8bZYHmWiGA5fHgZZ9WFTL pOsYCNgSfGHcySt/9Mxp3701b/7IHBDRl/iR6Qh0qvzifnxP33UZOtGN1W9xlkoV8A 8qRUKfdSGJu+g== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:54 +0200 Subject: [PATCH 26/29] drm/tidss: dispc: make accessors accessible to other parts of the driver 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-26-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2182; i=mripard@kernel.org; h=from:subject:message-id; bh=6y3aIMSfaSkH8Ni+8XNxtNqvzdtes72Di9oihgPJJu4=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVh9wOcr5m3HGpdkK/8tfz3TzrfvioLjNav157wiFp e/MXrLadUxlYRDmZJAVU2R5IhN2enn74ioH+5U/YOawMoEMYeDiFICJ2Iox1llMvyhXm+69pWtJ Tf8ubeHlqYu2xe/1NchjSm8onnc431PkcnzTsQ2Nf1Vf73m28/m3k4z1Qc2b/sxQPfF1q/jC3B2 tRybdXPH13Hc2/sK1KYpFLp82rKvO3hu50Nxpwr3YW0wtt57sAwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tidss/tidss_dispc.c | 4 ++-- drivers/gpu/drm/tidss/tidss_dispc.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/ti= dss_dispc.c index 2f9cf95d6d0525a02d8adaae968aa551b7e27077..18b6beddfe51f9b5c164481ee2e= f0fa289e63318 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -504,11 +504,11 @@ void dispc_vid_write(struct dispc_device *dispc, u32 = hw_plane, u16 reg, u32 val) =20 CH(dispc); iowrite32(val, base + reg); } =20 -static u32 dispc_vid_read(struct dispc_device *dispc, u32 hw_plane, u16 re= g) +u32 dispc_vid_read(struct dispc_device *dispc, u32 hw_plane, u16 reg) { void __iomem *base =3D dispc->base_vid[hw_plane]; =20 CH(dispc); return ioread32(base + reg); @@ -538,11 +538,11 @@ static void dispc_vp_write(struct dispc_device *dispc= , u32 hw_videoport, =20 CH(dispc); iowrite32(val, base + reg); } =20 -static u32 dispc_vp_read(struct dispc_device *dispc, u32 hw_videoport, u16= reg) +u32 dispc_vp_read(struct dispc_device *dispc, u32 hw_videoport, u16 reg) { void __iomem *base =3D dispc->base_vp[hw_videoport]; =20 CH(dispc); return ioread32(base + reg); diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/ti= dss_dispc.h index f5d5798de1ba550dedbcba36b1ef41d5ecceaa0c..b249cd0da331bf801992a7f38ff= 9031a5f8da0b8 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.h +++ b/drivers/gpu/drm/tidss/tidss_dispc.h @@ -181,9 +181,12 @@ void dispc_plane_setup(struct dispc_device *dispc, u32= hw_plane, u32 hw_videoport); void dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool ena= ble); const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *l= en); u32 dispc_plane_find_fourcc_by_dss_code(u8 code); =20 +u32 dispc_vid_read(struct dispc_device *dispc, u32 hw_plane, u16 reg); +u32 dispc_vp_read(struct dispc_device *dispc, u32 hw_videoport, u16 reg); + int dispc_init(struct tidss_device *tidss); void dispc_remove(struct tidss_device *tidss); =20 #endif --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 9E51F2E9759 for ; Tue, 2 Sep 2025 08:34:21 +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=1756802061; cv=none; b=eoAhFLjf6THtE/rWIAyuGTaoXG111UaJUbSg9OBdQvTc4VlLwteyvpOOkQGSuD86jg94dj4GaOoWbeqx3ck3FqvX9rQwF87S+sgvnCYHsJtk3Nvihj9U7Sw2DdyuZBZdzZqAEAm/k9Av9GuPd3UXafExMpsNFSUEaMooh4BdFIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802061; c=relaxed/simple; bh=PYnVTOPYjHAB+rr1Ybb2vBoDMtO6tDXn5T1miNMp3sU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ClhlDXF+ZUh50Djh0gJpcwFA7xSY+HpMfJKRLeQ2fp/J2MGMKWggrF7w6Td8C7naalc5xbz55rzvT061jFqsM+7AHl6duxw5mxIMLZTJuFPjn2XHRBjq5KzbUI41Aov/Bg2tlj4j4sXyr8AdB0z6YOfJsFka5+YdJsYCURayApQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bkU68Fes; 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="bkU68Fes" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 26417C4CEF7; Tue, 2 Sep 2025 08:34:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802061; bh=PYnVTOPYjHAB+rr1Ybb2vBoDMtO6tDXn5T1miNMp3sU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bkU68FesY4AURN/Z1sZ96P6sYCcunBj5g7onNnWkhKwQN+x+7TGXbYhg5et75YzFq UWBLlyz0QNiHURlfHyNoZ37Ttvs+qkjXR5nEzWdV7USkqgtysm4ovqqbHdVFnywAah jUDON8KWs+WS1NQuG4TPTimvC4jDw9SmIlBeoOrRGyBvsOplBoK8lVnH5qABRBCidz TENbs04fkgKuc7BhrnNTcgwpxBp+RTmid3Nf0pvjgtaSSLCKDN+aNVo8GBnrVNwFzT /y95DYDXZ8g7IhYXyGqT32Stdo7Imtngi5q5ckP2FRm3bC0nyyHPn88WIAymXJaDf2 MerRqF2Klu4Ag== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:55 +0200 Subject: [PATCH 27/29] drm/tidss: Implement readout support 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-27-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=19395; i=mripard@kernel.org; h=from:subject:message-id; bh=PYnVTOPYjHAB+rr1Ybb2vBoDMtO6tDXn5T1miNMp3sU=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVh/YXrhLvWnai5wJin2JUtsvpjLOspl231tv+umHT sy7f9137JjKwiDMySArpsjyRCbs9PL2xVUO9it/wMxhZQIZwsDFKQATeXWcseF48Yk7nlkLezJX rXCyMPeVMtL4KKi0IHZB3OmnbtxZzvdLf7wx5PivUrFh95fTpl7X7zI2XAp6Ysgr/FJI9EBAitK Nlk9zn/Aov1u81nr+eyE1uf9NalN5W64Hr39RLn4zom73AdV2AA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D With the hardware readout infrastructure now in place in the KMS framework, we can provide it for the tidss driver. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tidss/tidss_crtc.c | 218 ++++++++++++++++++++++++++++++++= +++- drivers/gpu/drm/tidss/tidss_dispc.c | 48 -------- drivers/gpu/drm/tidss/tidss_kms.c | 3 +- drivers/gpu/drm/tidss/tidss_plane.c | 194 +++++++++++++++++++++++++++++++- 4 files changed, 409 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tid= ss_crtc.c index 8fcc6a2f94770ae825eeb2a3b09856a2bf2d6a1e..454c4db92942c6c781440aff78c= 755e386b2edf3 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -2,18 +2,22 @@ /* * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/ * Author: Tomi Valkeinen */ =20 +#include + #include #include +#include #include #include #include =20 #include "tidss_crtc.h" #include "tidss_dispc.h" +#include "tidss_dispc_regs.h" #include "tidss_drv.h" #include "tidss_irq.h" #include "tidss_plane.h" =20 /* Page flip and frame done IRQs */ @@ -350,24 +354,229 @@ static void tidss_crtc_destroy_state(struct drm_crtc= *crtc, =20 __drm_atomic_helper_crtc_destroy_state(&tstate->base); kfree(tstate); } =20 -static void tidss_crtc_reset(struct drm_crtc *crtc) +static unsigned long calc_pixel_clock_hz(unsigned int htotal, + unsigned int vtotal, + unsigned int refresh, + unsigned int freq_div) { + unsigned long rate =3D (unsigned long)htotal * vtotal * refresh; + + return (rate * 1000) / freq_div; +} + +static const unsigned int refresh_tries[] =3D {30, 50, 60}; +static const unsigned int refresh_factors_tries[] =3D {1000, 1001}; + +static unsigned int tidss_find_closest_refresh_rate_from_clk(struct drm_de= vice *dev, + struct clk *clk, + unsigned int htotal, + unsigned int vtotal, + unsigned long *pixel_clock_hz) +{ + unsigned long actual_clk_rate =3D clk_get_rate(clk); + unsigned long best_clk_rate =3D 0; + unsigned long best_rate_diff =3D ULONG_MAX; + unsigned int best_refresh =3D 0; + unsigned int i, j; + + drm_dbg(dev, "Actual clock rate is %lu\n", actual_clk_rate); + + for (i =3D 0; i < ARRAY_SIZE(refresh_tries); i++) { + for (j =3D 0; j < ARRAY_SIZE(refresh_factors_tries); j++) { + unsigned int try_refresh =3D refresh_tries[i]; + unsigned int try_factor =3D refresh_factors_tries[j]; + unsigned long try_clk_rate =3D calc_pixel_clock_hz(htotal, + vtotal, + try_refresh, + try_factor); + unsigned long diff; + + drm_dbg(dev, "Evaluating refresh %u, factor %u, rate %lu\n", + try_refresh, try_factor, try_clk_rate); + + if (try_clk_rate =3D=3D actual_clk_rate) { + drm_dbg(dev, "Found exact match. Stopping.\n"); + best_refresh =3D try_refresh; + best_clk_rate =3D try_clk_rate; + goto out; + } + + + diff =3D abs_diff(actual_clk_rate, try_clk_rate); + if (diff < best_rate_diff) { + drm_dbg(dev, "Found new candidate. Difference is %lu\n", diff); + best_refresh =3D try_refresh; + best_clk_rate =3D try_clk_rate; + best_rate_diff =3D diff; + } + } + } + +out: + drm_dbg(dev, "Best candidate is %u Hz, pixel clock rate %lu Hz", best_ref= resh, best_clk_rate); + + if (pixel_clock_hz) + *pixel_clock_hz =3D best_clk_rate; + + return best_refresh; +} + +static int tidss_crtc_readout_mode(struct dispc_device *dispc, + struct tidss_crtc *tcrtc, + struct drm_display_mode *mode) +{ + struct tidss_device *tidss =3D dispc->tidss; + struct drm_device *dev =3D &tidss->ddev; + unsigned long pixel_clock; + unsigned int refresh; + u16 hdisplay, hfp, hsw, hbp; + u16 vdisplay, vfp, vsw, vbp; + u32 vp =3D tcrtc->hw_videoport; + u32 val; + + val =3D dispc_vp_read(dispc, vp, DISPC_VP_SIZE_SCREEN); + hdisplay =3D FIELD_GET(DISPC_VP_SIZE_SCREEN_HDISPLAY_MASK, val) + 1; + vdisplay =3D FIELD_GET(DISPC_VP_SIZE_SCREEN_VDISPLAY_MASK, val) + 1; + + mode->hdisplay =3D hdisplay; + mode->vdisplay =3D vdisplay; + + val =3D dispc_vp_read(dispc, vp, DISPC_VP_TIMING_H); + hsw =3D FIELD_GET(DISPC_VP_TIMING_H_SYNC_PULSE_MASK, val) + 1; + hfp =3D FIELD_GET(DISPC_VP_TIMING_H_FRONT_PORCH_MASK, val) + 1; + hbp =3D FIELD_GET(DISPC_VP_TIMING_H_BACK_PORCH_MASK, val) + 1; + + mode->hsync_start =3D hdisplay + hfp; + mode->hsync_end =3D hdisplay + hfp + hsw; + mode->htotal =3D hdisplay + hfp + hsw + hbp; + + val =3D dispc_vp_read(dispc, vp, DISPC_VP_TIMING_V); + vsw =3D FIELD_GET(DISPC_VP_TIMING_V_SYNC_PULSE_MASK, val) + 1; + vfp =3D FIELD_GET(DISPC_VP_TIMING_V_FRONT_PORCH_MASK, val); + vbp =3D FIELD_GET(DISPC_VP_TIMING_V_BACK_PORCH_MASK, val); + + mode->vsync_start =3D vdisplay + vfp; + mode->vsync_end =3D vdisplay + vfp + vsw; + mode->vtotal =3D vdisplay + vfp + vsw + vbp; + + refresh =3D tidss_find_closest_refresh_rate_from_clk(dev, + dispc->vp_clk[vp], + mode->htotal, + mode->vtotal, + &pixel_clock); + if (!refresh) + return -EINVAL; + + mode->clock =3D pixel_clock / 1000; + + val =3D dispc_vp_read(dispc, vp, DISPC_VP_POL_FREQ); + if (FIELD_GET(DISPC_VP_POL_FREQ_IVS_MASK, val)) + mode->flags |=3D DRM_MODE_FLAG_NVSYNC; + else + mode->flags |=3D DRM_MODE_FLAG_PVSYNC; + + if (FIELD_GET(DISPC_VP_POL_FREQ_IHS_MASK, val)) + mode->flags |=3D DRM_MODE_FLAG_NHSYNC; + else + mode->flags |=3D DRM_MODE_FLAG_PHSYNC; + + mode->type |=3D DRM_MODE_TYPE_DRIVER; + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + return 0; +} + +static struct drm_crtc_state * +tidss_crtc_readout_state(struct drm_crtc *crtc) +{ + struct drm_device *ddev =3D crtc->dev; + struct tidss_device *tidss =3D to_tidss(ddev); + struct dispc_device *dispc =3D tidss->dispc; struct tidss_crtc_state *tstate; + struct tidss_crtc *tcrtc =3D + to_tidss_crtc(crtc); + struct drm_display_mode mode; + u32 val; + int ret; =20 if (crtc->state) tidss_crtc_destroy_state(crtc, crtc->state); =20 tstate =3D kzalloc(sizeof(*tstate), GFP_KERNEL); if (!tstate) { - crtc->state =3D NULL; - return; + return ERR_PTR(-ENOMEM); } =20 __drm_atomic_helper_crtc_reset(crtc, &tstate->base); + + tidss_runtime_get(tidss); + + val =3D dispc_vp_read(dispc, tcrtc->hw_videoport, DISPC_VP_CONTROL); + if (!FIELD_GET(DISPC_VP_CONTROL_ENABLE_MASK, val)) + goto out; + + /* + * The display is active, we need to enable our clock to have + * proper reference count. + */ + WARN_ON(dispc_vp_enable_clk(tidss->dispc, tcrtc->hw_videoport)); + + tstate->base.active =3D 1; + tstate->base.enable =3D 1; + + ret =3D tidss_crtc_readout_mode(dispc, tcrtc, &mode); + if (ret) + goto err_runtime_put; + + ret =3D drm_atomic_set_mode_for_crtc(&tstate->base, &mode); + if (WARN_ON(ret)) + goto err_runtime_put; + + drm_mode_copy(&tstate->base.adjusted_mode, &mode); + + val =3D dispc_vp_read(dispc, tcrtc->hw_videoport, DISPC_VP_POL_FREQ); + if (FIELD_GET(DISPC_VP_POL_FREQ_IPC_MASK, val)) + tstate->bus_flags |=3D DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; + + if (FIELD_GET(DISPC_VP_POL_FREQ_IEO_MASK, val)) + tstate->bus_flags |=3D DRM_BUS_FLAG_DE_LOW; + + if (FIELD_GET(DISPC_VP_POL_FREQ_RF_MASK, val)) + tstate->bus_flags |=3D DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE; + + /* + * The active connectors and planes will be filled by their + * respective readout callbacks. + */ + +out: + tidss_runtime_put(tidss); + return &tstate->base; + +err_runtime_put: + tidss_runtime_put(tidss); + kfree(tstate); + return ERR_PTR(ret); +} + +static bool tidss_crtc_compare_state(struct drm_crtc *crtc, + struct drm_printer *p, + struct drm_crtc_state *expected, + struct drm_crtc_state *actual) +{ + struct tidss_crtc_state *t_expected =3D to_tidss_crtc_state(expected); + struct tidss_crtc_state *t_actual =3D to_tidss_crtc_state(actual); + int ret =3D drm_atomic_helper_crtc_compare_state(crtc, p, expected, actua= l); + + STATE_CHECK_U32_X(ret, p, crtc->name, t_expected, t_actual, bus_format); + STATE_CHECK_U32_X(ret, p, crtc->name, t_expected, t_actual, bus_flags); + + return ret; } =20 static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *= crtc) { struct tidss_crtc_state *state, *current_state; @@ -398,14 +607,15 @@ static void tidss_crtc_destroy(struct drm_crtc *crtc) drm_crtc_cleanup(crtc); kfree(tcrtc); } =20 static const struct drm_crtc_funcs tidss_crtc_funcs =3D { - .reset =3D tidss_crtc_reset, .destroy =3D tidss_crtc_destroy, .set_config =3D drm_atomic_helper_set_config, .page_flip =3D drm_atomic_helper_page_flip, + .atomic_readout_state =3D tidss_crtc_readout_state, + .atomic_compare_state =3D tidss_crtc_compare_state, .atomic_duplicate_state =3D tidss_crtc_duplicate_state, .atomic_destroy_state =3D tidss_crtc_destroy_state, .enable_vblank =3D tidss_crtc_enable_vblank, .disable_vblank =3D tidss_crtc_disable_vblank, }; diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/ti= dss_dispc.c index 18b6beddfe51f9b5c164481ee2ef0fa289e63318..e7f6f047574f5b520b00195c2b1= 4d98224db6f19 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -2916,51 +2916,10 @@ static void dispc_init_errata(struct dispc_device *= dispc) dispc->errata.i2000 =3D true; dev_info(dispc->dev, "WA for erratum i2000: YUV formats disabled\n"); } } =20 -/* - * K2G display controller does not support soft reset, so we do a basic ma= nual - * reset here: make sure the IRQs are masked and VPs are disabled. - */ -static void dispc_softreset_k2g(struct dispc_device *dispc) -{ - unsigned long flags; - - spin_lock_irqsave(&dispc->tidss->irq_lock, flags); - dispc_set_irqenable(dispc, 0); - dispc_read_and_clear_irqstatus(dispc); - spin_unlock_irqrestore(&dispc->tidss->irq_lock, flags); - - for (unsigned int vp_idx =3D 0; vp_idx < dispc->feat->num_vps; ++vp_idx) - VP_REG_FLD_MOD(dispc, vp_idx, DISPC_VP_CONTROL, 0, - DISPC_VP_CONTROL_ENABLE_MASK); -} - -static int dispc_softreset(struct dispc_device *dispc) -{ - u32 val; - int ret; - - if (dispc->feat->subrev =3D=3D DISPC_K2G) { - dispc_softreset_k2g(dispc); - return 0; - } - - /* Soft reset */ - REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, DSS_SYSCONFIG_SOFTRESET_MASK); - /* Wait for reset to complete */ - ret =3D readl_poll_timeout(dispc->base_common + DSS_SYSSTATUS, - val, val & 1, 100, 5000); - if (ret) { - dev_err(dispc->dev, "failed to reset dispc\n"); - return ret; - } - - return 0; -} - static int dispc_init_hw(struct dispc_device *dispc) { struct device *dev =3D dispc->dev; int ret; =20 @@ -2974,26 +2933,19 @@ static int dispc_init_hw(struct dispc_device *dispc) if (ret) { dev_err(dev, "Failed to enable DSS fclk\n"); goto err_runtime_suspend; } =20 - ret =3D dispc_softreset(dispc); - if (ret) - goto err_clk_disable; - clk_disable_unprepare(dispc->fclk); ret =3D pm_runtime_set_suspended(dev); if (ret) { dev_err(dev, "Failed to set DSS PM to suspended\n"); return ret; } =20 return 0; =20 -err_clk_disable: - clk_disable_unprepare(dispc->fclk); - err_runtime_suspend: ret =3D pm_runtime_set_suspended(dev); if (ret) { dev_err(dev, "Failed to set DSS PM to suspended\n"); return ret; diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tids= s_kms.c index 86eb5d97410bedced57129c2bbcd35f1719424c2..38c90027c158a392f96012f8882= 4ead091332fb7 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -37,11 +37,12 @@ static void tidss_atomic_commit_tail(struct drm_atomic_= state *old_state) =20 tidss_runtime_put(tidss); } =20 static const struct drm_mode_config_helper_funcs mode_config_helper_funcs = =3D { - .atomic_commit_tail =3D tidss_atomic_commit_tail, + .atomic_commit_tail =3D tidss_atomic_commit_tail, + .atomic_reset =3D drm_atomic_helper_readout_state, }; =20 static int tidss_atomic_check(struct drm_device *ddev, struct drm_atomic_state *state) { diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/ti= dss_plane.c index bd10bc1b9961571e6c6dee26698149fc9dd135b0..037c21354dd170511868baca249= 60ff9295dbea5 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -10,13 +10,15 @@ #include #include #include #include #include +#include =20 #include "tidss_crtc.h" #include "tidss_dispc.h" +#include "tidss_dispc_regs.h" #include "tidss_drv.h" #include "tidss_plane.h" =20 void tidss_plane_error_irq(struct drm_plane *plane, u64 irqstatus) { @@ -173,17 +175,207 @@ static const struct drm_plane_helper_funcs tidss_pri= mary_plane_helper_funcs =3D { .atomic_enable =3D tidss_plane_atomic_enable, .atomic_disable =3D tidss_plane_atomic_disable, .get_scanout_buffer =3D drm_fb_dma_get_scanout_buffer, }; =20 +static const struct drm_framebuffer_funcs tidss_plane_readout_fb_funcs =3D= { + .destroy =3D drm_gem_fb_destroy, +}; + +static struct drm_framebuffer *tidss_plane_readout_fb(struct drm_plane *pl= ane) +{ + struct drm_device *ddev =3D plane->dev; + struct tidss_device *tidss =3D to_tidss(ddev); + struct dispc_device *dispc =3D tidss->dispc; + struct tidss_plane *tplane =3D to_tidss_plane(plane); + const struct drm_format_info *info; + struct drm_framebuffer *fb; + u32 fourcc, val; + int ret; + + fb =3D kzalloc(sizeof(*fb), GFP_KERNEL); + if (!fb) + return ERR_PTR(-ENOMEM); + + fb->dev =3D plane->dev; + + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_ATTRIBUTES); + fourcc =3D + dispc_plane_find_fourcc_by_dss_code(FIELD_GET(DISPC_VID_ATTRIBUTES_FORMA= T_MASK, + val)); + if (!fourcc) { + ret =3D -EINVAL; + goto err_free_fb; + } + + info =3D drm_format_info(fourcc); + if (!info) { + ret =3D -EINVAL; + goto err_free_fb; + } + + // TODO: Figure out YUV and multiplanar formats + if (info->is_yuv) { + ret =3D -EINVAL; + goto err_free_fb; + } + + fb->format =3D info; + + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_PICTURE_SIZE= ); + fb->width =3D FIELD_GET(DISPC_VID_PICTURE_SIZE_MEMSIZEX_MASK, val) + 1; + fb->height =3D FIELD_GET(DISPC_VID_PICTURE_SIZE_MEMSIZEY_MASK, val) + 1; + + // TODO: Figure that out. + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_ROW_INC); + if (val !=3D 1) { + ret =3D -EINVAL; + goto err_free_fb; + } + + fb->pitches[0] =3D fb->width * (drm_format_info_bpp(info, 0) / 8); + + // TODO: Figure out the offsets + fb->offsets[0] =3D 0; + + ret =3D drm_framebuffer_init(plane->dev, fb, &tidss_plane_readout_fb_func= s); + if (ret) { + kfree(fb); + return ERR_PTR(ret); + } + + return fb; + +err_free_fb: + kfree(fb); + return ERR_PTR(ret); +} + +static struct drm_crtc *tidss_plane_readout_crtc(struct drm_plane *plane) +{ + struct drm_device *dev =3D plane->dev; + + if (dev->num_crtcs !=3D 1) + return ERR_PTR(-EINVAL); + + return list_first_entry(&dev->mode_config.crtc_list, struct drm_crtc, hea= d); +} + +static struct drm_plane_state *tidss_plane_atomic_readout_state(struct drm= _plane *plane, + struct drm_atomic_state *state) +{ + struct drm_device *ddev =3D plane->dev; + struct tidss_device *tidss =3D to_tidss(ddev); + struct dispc_device *dispc =3D tidss->dispc; + struct tidss_plane *tplane =3D to_tidss_plane(plane); + struct drm_plane_state *plane_state; + struct drm_crtc_state *crtc_state; + struct drm_framebuffer *fb; + struct drm_crtc *crtc; + bool lite =3D dispc->feat->vid_info[tplane->hw_plane_id].is_lite; + u16 in_w, in_h; + u32 val; + int ret; + + if (plane->state) + drm_atomic_helper_plane_destroy_state(plane, plane->state); + + plane_state =3D kzalloc(sizeof(*plane_state), GFP_KERNEL); + if (!plane_state) + return ERR_PTR(-ENOMEM); + + __drm_atomic_helper_plane_state_reset(plane_state, plane); + + tidss_runtime_get(tidss); + + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_ATTRIBUTES); + if (!FIELD_GET(DISPC_VID_ATTRIBUTES_ENABLE_MASK, val)) { + goto out; + } + + fb =3D tidss_plane_readout_fb(plane); + if (IS_ERR(fb)) { + ret =3D PTR_ERR(fb); + goto err_runtime_pm; + } + + crtc =3D tidss_plane_readout_crtc(plane); + if (IS_ERR(crtc)) { + ret =3D PTR_ERR(crtc); + goto err_runtime_pm; + } + + plane_state->fb =3D fb; + plane_state->crtc =3D crtc; + plane_state->visible =3D true; + + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_PICTURE_SIZE= ); + in_w =3D FIELD_GET(DISPC_VID_PICTURE_SIZE_MEMSIZEX_MASK, val) + 1; + in_h =3D FIELD_GET(DISPC_VID_PICTURE_SIZE_MEMSIZEY_MASK, val) + 1; + plane_state->src_w =3D in_w << 16; + plane_state->src_h =3D in_h << 16; + + if (!lite) { + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_SIZE); + plane_state->crtc_w =3D FIELD_GET(DISPC_VID_SIZE_SIZEX_MASK, val) + 1; + plane_state->crtc_h =3D FIELD_GET(DISPC_VID_SIZE_SIZEY_MASK, val) + 1; + } else { + plane_state->crtc_w =3D in_w; + plane_state->crtc_h =3D in_h; + } + + // TODO: Handle crtc_x/crtc_x/src_x/src_y + // crtc_x/crtc_y are handled by DISPC_OVR_ATTRIBUTES / OVR1_DSS_ATTRIBUTES + + // TODO: Handle zpos, see DISPC_OVR_ATTRIBUTES / OVR1_DSS_ATTRIBUTES + + plane_state->src.x1 =3D 0; + plane_state->src.x2 =3D plane_state->src_w; + plane_state->src.y1 =3D 0; + plane_state->src.y2 =3D plane_state->src_h; + plane_state->dst.x1 =3D 0; + plane_state->dst.x2 =3D plane_state->crtc_w; + plane_state->dst.y1 =3D 0; + plane_state->dst.y2 =3D plane_state->crtc_h; + + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_GLOBAL_ALPHA= ); + plane_state->alpha =3D FIELD_GET(DISPC_VID_GLOBAL_ALPHA_GLOBALALPHA_MASK,= val) << 16; + + val =3D dispc_vid_read(dispc, tplane->hw_plane_id, DISPC_VID_ATTRIBUTES); + if (FIELD_GET(DISPC_VID_ATTRIBUTES_PREMULTIPLYALPHA_MASK, val)) + plane_state->pixel_blend_mode =3D DRM_MODE_BLEND_PREMULTI; + else + plane_state->pixel_blend_mode =3D DRM_MODE_BLEND_COVERAGE; + + // TODO: If YUV, handle color encoding and range + + crtc_state =3D drm_atomic_get_old_crtc_state(state, crtc); + if (!crtc_state) { + ret =3D -ENODEV; + goto err_runtime_pm; + } + + crtc_state->plane_mask |=3D drm_plane_mask(plane); + +out: + tidss_runtime_put(tidss); + return plane_state; + +err_runtime_pm: + tidss_runtime_put(tidss); + kfree(plane_state); + return ERR_PTR(ret); +} + static const struct drm_plane_funcs tidss_plane_funcs =3D { .update_plane =3D drm_atomic_helper_update_plane, .disable_plane =3D drm_atomic_helper_disable_plane, - .reset =3D drm_atomic_helper_plane_reset, .destroy =3D drm_plane_destroy, + .atomic_compare_state =3D drm_atomic_helper_plane_compare_state, .atomic_duplicate_state =3D drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_plane_destroy_state, + .atomic_readout_state =3D tidss_plane_atomic_readout_state, }; =20 struct tidss_plane *tidss_plane_create(struct tidss_device *tidss, u32 hw_plane_id, u32 plane_type, u32 crtc_mask, const u32 *formats, --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 89CB42ED159 for ; Tue, 2 Sep 2025 08:34:24 +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=1756802064; cv=none; b=IenzNTRbtL+LU21rPPBV7zNCgzUc0rnFECA+oRkEJQSJ4YvxwkOdYRrCpDHSY32WrfU2tGtycmXBnBzRDS1ukKimJ4EeDHvwn0eYvERkHeLHbb2m+XHIWbFoa9WZK59T+fArSg7wCgffkcYnIMzgEguk+rH4rsiP/wNko8eCfZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802064; c=relaxed/simple; bh=FvKa2ivxLz16/Yiu4P4OHeqOpBeH6KT8gxfkcoGM39Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BxDdBY0vaiLMifKhec+AURZ2JPaEl0UK60GAkt6Yj4FK2VZBg8ho1EJEWWWS5QP6/pAjqgQCz+TiOd1GfEFk0F9h/9Wvd/aqvF9EgWVx9+7mvYN5Zj0FUrF/jDJv1zMygVdDKx0JbudAnBL6CBMjnAF/g9R2lrdYaS/k4OPgiHs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fa4BbAHc; 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="fa4BbAHc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BC9E3C4CEED; Tue, 2 Sep 2025 08:34:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802064; bh=FvKa2ivxLz16/Yiu4P4OHeqOpBeH6KT8gxfkcoGM39Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fa4BbAHcAfqsB65EzfHlHcC9YA57k8CtW/wMR65eOZJWfw41hdUlwqHDly5AnsJUb 3Fx0yJfA/iXVzAFfkUmt26myliq4hY3ZHtRODstWJ2hjOj5EsE8BScPkloTLCJyS1/ x533o1FK2MAhQJHm9OuvDFeMRSgdLuufeoIwpqKJAP7Gqy/MAmSKNuquzQzAmvn66m uJ3k5rtafRxYhLOUXF6WUavGs3Mc/JTlt9coganSM4nx/IUufN+SPBnFVpqX79fK8z h7f7clNPYYDp33Go0SlM+5LfGxf70G3VMlwSWd0/4AG1EHi2fMBxsBtZYqYn3SulUx KRUQ/4G+Y3qdw== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:56 +0200 Subject: [PATCH 28/29] drm/tidss: encoder: implement get_current_crtc 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-28-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2462; i=mripard@kernel.org; h=from:subject:message-id; bh=FvKa2ivxLz16/Yiu4P4OHeqOpBeH6KT8gxfkcoGM39Q=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVh9ssz+uW2+0puRIyeYIORuRVR9lwnKu1QQmnbxxz 05DbX9Ix1QWBmFOBlkxRZYnMmGnl7cvrnKwX/kDZg4rE8gQBi5OAZiIdg9jwwSLk5bLDsz7yh3+ 4Zy29sUlAnPcOD7FXXV/8NEuUj3X4WdFY6PGLYXJuVMjNudxheTfYqyzdrggq+jcqLBtxfoPDpx lml/qdhkFfxfo2rvi69XHTBMUxa+m39uo84lx1YnDc63e9TsDAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D The tidss driver doesn't really care implement anything with encoders, it just relies on simple encoders, bridges and drm_bridge_connector. In order to figure out the CRTC -> connector association from the hardware state, we do need encoder support though, through the get_current_crtc callback. Since the tidss encoders are always connected to a single CRTC, we don't really need to read the hardware state though, we can simply return the one we know we are always connected to. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tidss/tidss_encoder.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_encoder.c b/drivers/gpu/drm/tidss/= tidss_encoder.c index 81a04f7677701b0b1bee204ac9fc5835ac373950..2cb12ab48a48cec453defcb2619= 15e4663806289 100644 --- a/drivers/gpu/drm/tidss/tidss_encoder.c +++ b/drivers/gpu/drm/tidss/tidss_encoder.c @@ -79,10 +79,29 @@ static const struct drm_bridge_funcs tidss_bridge_funcs= =3D { .atomic_reset =3D drm_atomic_helper_bridge_reset, .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, }; =20 +static struct drm_crtc *tidss_encoder_get_current_crtc(struct drm_encoder = *encoder) +{ + struct drm_crtc *crtc; + + WARN_ON(hweight32(encoder->possible_crtcs) > 1); + + drm_for_each_crtc(crtc, encoder->dev) { + if (encoder->possible_crtcs =3D=3D (1 << drm_crtc_index(crtc))) + return crtc; + } + + return NULL; +} + +static const struct drm_encoder_funcs tidss_encoder_funcs =3D { + .get_current_crtc =3D tidss_encoder_get_current_crtc, + .destroy =3D drm_encoder_cleanup, +}; + int tidss_encoder_create(struct tidss_device *tidss, struct drm_bridge *next_bridge, u32 encoder_type, u32 possible_crtcs) { struct tidss_encoder *t_enc; @@ -93,12 +112,13 @@ int tidss_encoder_create(struct tidss_device *tidss, t_enc =3D devm_drm_bridge_alloc(tidss->dev, struct tidss_encoder, bridge, &tidss_bridge_funcs); if (IS_ERR(t_enc)) return PTR_ERR(t_enc); =20 - ret =3D drm_simple_encoder_init(&tidss->ddev, &t_enc->encoder, - encoder_type); + ret =3D drm_encoder_init(&tidss->ddev, &t_enc->encoder, + &tidss_encoder_funcs, + encoder_type, NULL); if (ret) return ret; =20 t_enc->tidss =3D tidss; t_enc->next_bridge =3D next_bridge; --=20 2.50.1 From nobody Fri Oct 3 11:14:53 2025 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 D0E3D2ECEB9 for ; Tue, 2 Sep 2025 08:34:26 +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=1756802066; cv=none; b=VHwcjm1mtZeFRnH5w1Er4mZ92o9coWNTikO5Fi9VciiashWa5Ks5rB0aM9BugPcEO2n+kYUFE2SyVpL7/13/O1dxOr1GxQXQ/DSEhApwecMAlNDKV7/pMYiLpBHhoiBrn1T6GrI78SnqY0+I3aGCc/Kt2Iqzj5SEnJPn1ifqEC0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756802066; c=relaxed/simple; bh=nreBoH6ThRerXR2wNJa5hb8U1Wgw8f5LJn4gcdb2KpY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Xt7zkCqP/vHUuTdTLWFSPIeIJq8zVpLS5Cdmn9rCYow4SY41f3uH1diNDj00byhk/enq0WfClYEagXRehHlQlVDnVwcs0yYMRgo3glZadvv/xAq9902XecFRI3oZmj3Aa17uv2VVmdxmRVkYGcaFAx0sAzijVzjFZnlIUCHukeo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=b5PU6oYp; 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="b5PU6oYp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6186DC4CEF5; Tue, 2 Sep 2025 08:34:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756802066; bh=nreBoH6ThRerXR2wNJa5hb8U1Wgw8f5LJn4gcdb2KpY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=b5PU6oYphv9O+QNCyshbf1R2+dTpKQkl8jJqMnC38IA+GupA1IZGeAP6v6ydv1VuS i1iK8w+x/GFYmWQzQlmJ3eRzCIqyK6iua9GZARjfIzmqXW7m5hHNW2CHKfvHgwQ2uo r5/qxjFZ8oY+XFTxmQnxYBjyMa9FwAmzDXO26WJXDn+VCOw9A2NWlT5oKdz16RSs8j mneyfwSydEia0VoIV+1KDLq7Defdk3xBtKU6hcf40oqlIVrqOSrBcWZJHRJYIY7+2C vyMyIRPn6AVJwsm6XBtEHOO/sfAka4TWKXKakm6uTv9pbQwMZDjXvo7MhoX+6alcpG /0cGUygBbNo+A== From: Maxime Ripard Date: Tue, 02 Sep 2025 10:32:57 +0200 Subject: [PATCH 29/29] drm/bridge: sii902x: Implement hw state readout 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: quoted-printable Message-Id: <20250902-drm-state-readout-v1-29-14ad5315da3f@kernel.org> References: <20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org> In-Reply-To: <20250902-drm-state-readout-v1-0-14ad5315da3f@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.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3469; i=mripard@kernel.org; h=from:subject:message-id; bh=nreBoH6ThRerXR2wNJa5hb8U1Wgw8f5LJn4gcdb2KpY=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDBnbVh/U9Zm/efutmxbKefuehdkHG+67+WPnq8gv176u6 vd/Jyor2zGVhUGYk0FWTJHliUzY6eXti6sc7Ff+gJnDygQyhIGLUwAmovCLsaHv0nqvrh1bpsUv qfryTEkj5ESnoil/xqKlTDtl7y45ZffZYV6BcG1o9awAVznDDieHHMaGxtBjSjxGyefzmS6tPj5 RRmyL+aQw0c1PuNdEv5pipXJaeamOaMb5hmyWnB8PbGt2eD8FAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Let's implement the hardware state readout for the sii902x bridge now that we have all the infrastructure in place. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/sii902x.c | 51 ++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii9= 02x.c index d537b1d036fb09ce55a690a0809dcc28fc0f41be..5ffceb9131540d2cb1b82a74b4f= 7cec9bc7fd8ca 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -540,17 +540,66 @@ sii902x_bridge_mode_valid(struct drm_bridge *bridge, return MODE_CLOCK_HIGH; =20 return MODE_OK; } =20 +static int sii902x_bridge_connector_hw_readout(struct drm_bridge *bridge, + struct drm_atomic_state *state, + struct drm_connector_state *conn_state) +{ + struct sii902x *sii902x =3D bridge_to_sii902x(bridge); + struct drm_connector *connector =3D conn_state->connector; + struct drm_crtc_state *crtc_state; + struct drm_encoder *encoder; + struct drm_crtc *crtc; + + if (regmap_test_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA, SII902X_SYS_= CTRL_PWR_DWN)) + return 0; + + encoder =3D bridge->encoder; + crtc =3D encoder->funcs->get_current_crtc(encoder); + if (!crtc) + return -ENODEV; + + crtc_state =3D drm_atomic_get_old_crtc_state(state, crtc); + if (!crtc_state) + return -ENODEV; + + crtc_state->encoder_mask |=3D drm_encoder_mask(encoder); + crtc_state->connector_mask |=3D drm_connector_mask(connector); + + conn_state->crtc =3D crtc; + conn_state->best_encoder =3D encoder; + + return 0; +} + +static int sii902x_bridge_readout_state(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct sii902x *sii902x =3D bridge_to_sii902x(bridge); + + if (regmap_test_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA, SII902X_SYS_= CTRL_PWR_DWN)) + return 0; + + /* bridge_state is pretty trivial, we don't have anything to do here */ + + return 0; +} + static const struct drm_bridge_funcs sii902x_bridge_funcs =3D { .attach =3D sii902x_bridge_attach, .mode_set =3D sii902x_bridge_mode_set, .atomic_disable =3D sii902x_bridge_atomic_disable, .atomic_enable =3D sii902x_bridge_atomic_enable, + .connector_hw_readout =3D sii902x_bridge_connector_hw_readout, .detect =3D sii902x_bridge_detect, .edid_read =3D sii902x_bridge_edid_read, + .atomic_compare_state =3D drm_atomic_helper_bridge_compare_state, + .atomic_readout_state =3D sii902x_bridge_readout_state, .atomic_reset =3D drm_atomic_helper_bridge_reset, .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, .atomic_get_input_bus_fmts =3D sii902x_bridge_atomic_get_input_bus_fmts, .atomic_check =3D sii902x_bridge_atomic_check, @@ -1136,11 +1185,11 @@ static int sii902x_init(struct sii902x *sii902x) if (ret) goto err_unreg_audio; =20 sii902x->bridge.of_node =3D dev->of_node; sii902x->bridge.timings =3D &default_sii902x_timings; - sii902x->bridge.ops =3D DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID; + sii902x->bridge.ops =3D DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_B= RIDGE_OP_CONNECTOR_HW_READOUT; sii902x->bridge.type =3D DRM_MODE_CONNECTOR_HDMIA; =20 if (sii902x->i2c->irq > 0) sii902x->bridge.ops |=3D DRM_BRIDGE_OP_HPD; =20 --=20 2.50.1