From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8FE6CFE51FF for ; Fri, 24 Apr 2026 10:20:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=LnrE5/pH5hN5lFUnkAWF52nIdixuOf8uoCUilYQK91k=; b=qcN5Vvhw0iRMAysoyAoNfGyRMg w64EO7ZcEKL13iohWI/F5ZcP8X4M6ZnADQ8bi+6FsrwE9nVk5rb/VFF69ZyhCwSfJKRLFdFSQlMzE tTQ83Rz6nOOuXf2L/obkqRVDFanyw9OQ8avC5KFcFeq8AoqiqN6FW+y520S/z3kbJAqjQu2Yx3Na5 /ruGnZzNzL9JlqgqwgSb0sXJTf9yrzYqWkvIIw12jCuefmolGg5kwdLID1uC6jahuyndmc2sVj2X1 Jn92U/owlMWxpeguuosOP3feIZOzcqes9OVmQyPlCSeYCb5r1AqlSpsxPUKhfGx77Lb0UxGEPSxMB hVw10ttA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wGDdb-0000000D1Dv-0Hl9; Fri, 24 Apr 2026 10:19:55 +0000 Received: from tor.source.kernel.org ([172.105.4.254]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wGDdT-0000000D13k-1DQr for linux-arm-kernel@lists.infradead.org; Fri, 24 Apr 2026 10:19:47 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id AD97E60132; Fri, 24 Apr 2026 10:19:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D47ACC2BCC6; Fri, 24 Apr 2026 10:19:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777025986; bh=GPSuO+k93xDNsKFjLSxcI43DLn10Nslmx9LZXhVCeTU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dxs2SdXhUyfHXYoyj26xpJ1FvMTlg27SYUpsmLacaqLeB6VD0RLkxhrERGzMJcB7K M2paatOxlg28F6owua+Ia4bO24YLhas668fwYGg53iRSesqrGuzpbJgeb07HF7TP0a bDYgudQXmvXO7JBeVeFnMXtOwrJB1sD6lyX1KgFOsVNEohGde0/Idi5y/d9lhde7DB HzHXP+OjINYimTGSLls1vyFtanoB21SB7jQNoKxAh1EJrS0zb992NHRgyqYX1xVHU9 rVyQuA1xW1gZ+v7ZtlUf/MUHG5d+PITJzTjW9hnPby8rn2k68rHDN1sHbyFAJjHp96 u2cb/b7yrftQw== From: Maxime Ripard Date: Fri, 24 Apr 2026 12:18:56 +0200 Subject: [PATCH v3 16/20] drm/mode-config: Create drm_mode_config_create_initial_state() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260424-drm-mode-config-init-v3-16-8b68d9db0d8b@kernel.org> References: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org> In-Reply-To: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Simona Vetter , Jonathan Corbet , Shuah Khan , Dmitry Baryshkov , Jyri Sarha , Tomi Valkeinen , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Simon Ser , Harry Wentland , Melissa Wen , Sebastian Wick , Alex Hung , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Chen-Yu Tsai , Samuel Holland , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance Cc: dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Daniel Stone , intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6023; i=mripard@kernel.org; h=from:subject:message-id; bh=GPSuO+k93xDNsKFjLSxcI43DLn10Nslmx9LZXhVCeTU=; b=owGbwMvMwCmsHn9OcpHtvjLG02pJDJmvnftVZJxtBE+7bU78J5aZ8neyRPIxp/bEGyrTH2bxh OsaK8t1TGVhEOZkkBVTZHkiE3Z6efviKgf7lT9g5rAygQxh4OIUgIkU2zLWqWjYz577l0Xgr0Bl 8YVAzY2xs+6+KUq8E3lGqW3SHhlvo9O/ppn85b1z1mpltS/fre8fGRvW+2x6HXpU6td5SZFz/6e 4rU63TJ6WUb742u0ExxvVdd9XxTU477lQzV4V8NFzs9jiG/MB X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org drm_mode_config_reset() can be used to create the initial state, but also to return to the initial state, when doing a suspend/resume cycle for example. It also affects both the software and the hardware, and drivers can choose to reset the hardware as well. Most will just create an empty state and the synchronisation between hardware and software states will effectively be done when the first commit is done. That dual role can be harmful, since some objects do need to be initialized but also need to be preserved across a suspend/resume cycle. drm_private_obj are such objects for example. Thus, create another helper for drivers to call to initialize their state when the driver is loaded, so we can make drm_mode_config_reset() only about handling suspend/resume and similar. Reviewed-by: Dmitry Baryshkov Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic.c | 12 +++++- drivers/gpu/drm/drm_mode_config.c | 87 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_mode_config.h | 1 + 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 253a00f450b0..f31b6147e682 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -59,12 +59,20 @@ * when preparing the update and kept alive as long as they are active * in the device. * * Their respective lifetimes are: * - * - at reset time, the object reset implementation will allocate a new - * default state and will store it in the object state pointer. + * - at driver initialization time, the driver will allocate an initial, + * pristine, state and will store it using + * drm_mode_config_create_initial_state(). Historically, this was one + * of drm_mode_config_reset() job, so one might still encounter it in + * a driver. + * + * - at reset time, for example during suspend/resume, + * drm_mode_config_reset() will reset the software and hardware state + * to a known default and will store it in the object's state pointer. + * Not all objects are affected by drm_mode_config_reset() though. * * - whenever a new update is needed: * * + A new &struct drm_atomic_state is allocated using * drm_atomic_state_alloc(). diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 92ff907f2485..a43eb825671b 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -21,10 +21,11 @@ */ #include #include +#include #include #include #include #include #include @@ -281,10 +282,96 @@ void drm_mode_config_reset(struct drm_device *dev) } drm_connector_list_iter_end(&conn_iter); } EXPORT_SYMBOL(drm_mode_config_reset); +/** + * drm_mode_config_create_initial_state - Allocates the initial state + * @dev: drm device + * + * This functions creates the initial state for all the objects. Drivers + * can use this in e.g. probe to initialize their software state. + * + * It has two main differences with drm_mode_config_reset(): the reset() + * hooks aren't called and thus the hardware will be left untouched, but + * also the &drm_private_obj structures will be initialized as opposed + * to drm_mode_config_reset() that skips them. + * + * Returns: 0 on success, negative error value on failure. + */ +int drm_mode_config_create_initial_state(struct drm_device *dev) +{ + struct drm_crtc *crtc; + struct drm_colorop *colorop; + struct drm_plane *plane; + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + struct drm_private_obj *privobj; + int ret; + + drm_for_each_privobj(privobj, dev) { + struct drm_private_state *privobj_state; + + if (privobj->state) + continue; + + if (!privobj->funcs->atomic_create_state) + continue; + + privobj_state = privobj->funcs->atomic_create_state(privobj); + if (IS_ERR(privobj_state)) + return PTR_ERR(privobj_state); + + privobj->state = privobj_state; + } + + drm_for_each_colorop(colorop, dev) { + struct drm_colorop_state *colorop_state; + + if (colorop->state) + continue; + + colorop_state = drm_atomic_helper_colorop_create_state(colorop); + if (IS_ERR(colorop_state)) + return PTR_ERR(colorop_state); + + colorop->state = colorop_state; + } + + drm_for_each_plane(plane, dev) { + if (plane->state) + continue; + + ret = drm_mode_config_plane_create_state(plane); + if (ret) + return ret; + } + + drm_for_each_crtc(crtc, dev) { + if (crtc->state) + continue; + + ret = drm_mode_config_crtc_create_state(crtc); + if (ret) + return ret; + } + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + if (connector->state) + continue; + + ret = drm_mode_config_connector_create_state(connector); + if (ret) + return ret; + } + drm_connector_list_iter_end(&conn_iter); + + return 0; +} +EXPORT_SYMBOL(drm_mode_config_create_initial_state); + /* * Global properties */ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = { { DRM_PLANE_TYPE_OVERLAY, "Overlay" }, diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 687c0ee163d2..00009250fde4 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -1005,9 +1005,10 @@ int __must_check drmm_mode_config_init(struct drm_device *dev); static inline int drm_mode_config_init(struct drm_device *dev) { return drmm_mode_config_init(dev); } +int drm_mode_config_create_initial_state(struct drm_device *dev); void drm_mode_config_reset(struct drm_device *dev); void drm_mode_config_cleanup(struct drm_device *dev); #endif -- 2.53.0