From patchwork Mon Oct 18 14:28:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 12566655 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11150C433F5 for ; Mon, 18 Oct 2021 14:29:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED82D60F9F for ; Mon, 18 Oct 2021 14:29:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232301AbhJRObR (ORCPT ); Mon, 18 Oct 2021 10:31:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232085AbhJRObE (ORCPT ); Mon, 18 Oct 2021 10:31:04 -0400 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EEA4FC061768 for ; Mon, 18 Oct 2021 07:28:52 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id i12so41686676wrb.7 for ; Mon, 18 Oct 2021 07:28:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xos3ri9U1H5jfjvfpqCdoDexrK3BD8+5TNiS9KWIjfA=; b=GLW3EEI9lukBqzBc/zyjjDzTIKDJ3eKjmMcbRO/8JpwkfZfesNYatflwlIj3vVvKOU sLxUFTlzKMYR8BgqG5jqZpK1+DNZjW2GTKafHXI/Cm8xfOuoiC02yx9HQsGtB24j5Bie 9fb7kLEH7gOmdzS0j6HR7C8gC0HsGyiNd2G3frJiC3+D6XmDce2yL5obD36/+j5iSpGA SptJT9PxrwqWwk6w76YbyBVqg1I3d6lusZyZdgVa4z9wWgp9RAgrM9spiGmOY4G5CpH1 eN3CzbloqRHQD98rYZSrzJgRxhbADDTryVc9LnTXidID1IcaFhrpvy0tFTyaIMOTVk5+ hh1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xos3ri9U1H5jfjvfpqCdoDexrK3BD8+5TNiS9KWIjfA=; b=4gjpsuH+gq8+XGYYTjJ8LygV67PAEOSqOX8o258f2pT1N6IrDdRdHn6kUBIZw3C1Nt UClDxoF/YKQLCQpe0fybL0nYc3EmVZV4OqfZlz4RFsoa8gOrKb0QkDXBDwqI/Zga8s83 H1eScG9TET3WRUggf44giCH3/8Ywyrujr1dBB8Av2kUlKcOLwYjj4HlWfXHdLWbkETzq 9frRWpMFaynyA4mU9tyvP8+9tQfX1FfyPPGPVhAFWyenhW/RukZabD/zaVGJkOmyBdRn qXQZkZ6+UI3Jg6TXoDoNBb/tWxEyVfOyHAJBzlqQu6pij8csUNRC5GEl5YHgXfkYd+VE zBEw== X-Gm-Message-State: AOAM532qE8gt03iDbaOz06+40rPEyzkL6OIx0KnMmv8Kr7LFUWQb1J3/ eIrp+dTKnAfzYI8UDppfRIdN2JTbTutGWg== X-Google-Smtp-Source: ABdhPJyJrKVMY4U+6f9+E3SwdX8lIo6v9rUOYfVwSuyg0dVOL4VbjTOM6DJlPlDP52jI3pbKMSmQwg== X-Received: by 2002:adf:9c11:: with SMTP id f17mr36970821wrc.147.1634567331452; Mon, 18 Oct 2021 07:28:51 -0700 (PDT) Received: from localhost.localdomain ([2001:861:44c0:66c0:2dd7:d5eb:6e87:f924]) by smtp.gmail.com with ESMTPSA id b3sm12908495wrp.52.2021.10.18.07.28.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Oct 2021 07:28:50 -0700 (PDT) From: Neil Armstrong To: tomba@kernel.org Cc: linux-omap@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, khilman@baylibre.com, Benoit Parrot , Neil Armstrong Subject: [PATCH v6 6/9] drm/omap: Add global state as a private atomic object Date: Mon, 18 Oct 2021 16:28:39 +0200 Message-Id: <20211018142842.2511200-7-narmstrong@baylibre.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211018142842.2511200-1-narmstrong@baylibre.com> References: <20211018142842.2511200-1-narmstrong@baylibre.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6382; i=narmstrong@baylibre.com; h=from:subject; bh=Fvw9so5WoaGI+JrbPfR7R3ztRakTQgT6adrx2fLhJCE=; b=owEBbQKS/ZANAwAKAXfc29rIyEnRAcsmYgBhbYSFDkEAMiQ6vpnQFtXgplKartZDABGPywqVCAu8 lmAkVNeJAjMEAAEKAB0WIQQ9U8YmyFYF/h30LIt33NvayMhJ0QUCYW2EhQAKCRB33NvayMhJ0VCmD/ oCgpOOPNnG6UYoUupvQyH9TpyMWGjszGCV2c2HmPBaH3WekKOXmEYcmyOgs5rKYtHK0qkDk5UK3XZR OQsvPyv5U3Sjw8m0HeFvD3K6AKmgGKhMb3r1g5iFo2ZqOrAH0osqR15Dn1/A0S36CBAHT0on4UGC7z t6GxO+qle95D/r8DEashEUSIzs6CtQFvD4Cryhk9H8aQv8AmNXCcC/3MB1He5jTTV+FVTElct21f6T 1Kx9KdTSPJuYwZ+9gKBpmlJmM5t0ClPgjfUj2xdg3Rv5zpgkZonqP2WDLgY/0kHr//YMdLRSv6shHG 15SjB2Jxq60y45GnKnxL7f7qLXDl/XXr6qdPQ4ZBSS5lmxTqbh2dKkek6RYRQ4e5Xgd5OmjGYBhaPn RqEwoHLG/n5V313kbCZIBO/TCVm6JoMnd6Vzyus2pWJfc6FS46srUMPICm82Qo6OShp/spDVLDen6G EPbCjP3aQqBvQ4I50PZiqxC+z8ZteDVwALHSC3rLpQs69oXOJXdmo0CPzCNYTfp62d9mtCg06RHMnp Kd7GaTtQIYz3KplOSivmQOgjvo/EDdjXftm5Z2fsIvGo1kdWzHMZbTda58MITazgzZ7dPrKt5jzrWC 3jbMBRbUrnCpKNUCLxheUmF40vle9deXCxzZRglaAyT8kUSl3DGG62XZ/7iA== X-Developer-Key: i=narmstrong@baylibre.com; a=openpgp; fpr=89EC3D058446217450F22848169AB7B1A4CFF8AE Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From: Benoit Parrot Global shared resources (like hw overlays) for omapdrm are implemented as a part of atomic state using the drm_private_obj infrastructure available in the atomic core. omap_global_state is introduced as a drm atomic private object. The two funcs omap_get_global_state() and omap_get_existing_global_state() are the two variants that will be used to access omap_global_state. drm_mode_config_init() needs to be called earlier because it creates/initializes the private_obj link list maintained by the atomic framework. The private_obj link list has to exist prior to calling drm_atomic_private_obj_init(). Similarly the cleanup handler are reordered appropriately. Signed-off-by: Benoit Parrot Signed-off-by: Neil Armstrong --- drivers/gpu/drm/omapdrm/omap_drv.c | 91 +++++++++++++++++++++++++++++- drivers/gpu/drm/omapdrm/omap_drv.h | 17 ++++++ 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index b994014b22e8..c7912374d393 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -128,6 +128,82 @@ static const struct drm_mode_config_funcs omap_mode_config_funcs = { .atomic_commit = drm_atomic_helper_commit, }; +/* Global/shared object state funcs */ + +/* + * This is a helper that returns the private state currently in operation. + * Note that this would return the "old_state" if called in the atomic check + * path, and the "new_state" after the atomic swap has been done. + */ +struct omap_global_state * +omap_get_existing_global_state(struct omap_drm_private *priv) +{ + return to_omap_global_state(priv->glob_obj.state); +} + +/* + * This acquires the modeset lock set aside for global state, creates + * a new duplicated private object state. + */ +struct omap_global_state *__must_check +omap_get_global_state(struct drm_atomic_state *s) +{ + struct omap_drm_private *priv = s->dev->dev_private; + struct drm_private_state *priv_state; + + priv_state = drm_atomic_get_private_obj_state(s, &priv->glob_obj); + if (IS_ERR(priv_state)) + return ERR_CAST(priv_state); + + return to_omap_global_state(priv_state); +} + +static struct drm_private_state * +omap_global_duplicate_state(struct drm_private_obj *obj) +{ + struct omap_global_state *state; + + state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); + if (!state) + return NULL; + + __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); + + return &state->base; +} + +static void omap_global_destroy_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + struct omap_global_state *omap_state = to_omap_global_state(state); + + kfree(omap_state); +} + +static const struct drm_private_state_funcs omap_global_state_funcs = { + .atomic_duplicate_state = omap_global_duplicate_state, + .atomic_destroy_state = omap_global_destroy_state, +}; + +static int omap_global_obj_init(struct drm_device *dev) +{ + struct omap_drm_private *priv = dev->dev_private; + struct omap_global_state *state; + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + drm_atomic_private_obj_init(dev, &priv->glob_obj, &state->base, + &omap_global_state_funcs); + return 0; +} + +static void omap_global_obj_fini(struct omap_drm_private *priv) +{ + drm_atomic_private_obj_fini(&priv->glob_obj); +} + static void omap_disconnect_pipelines(struct drm_device *ddev) { struct omap_drm_private *priv = ddev->dev_private; @@ -231,8 +307,6 @@ static int omap_modeset_init(struct drm_device *dev) if (!omapdss_stack_is_ready()) return -EPROBE_DEFER; - drm_mode_config_init(dev); - ret = omap_modeset_init_properties(dev); if (ret < 0) return ret; @@ -583,10 +657,16 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) omap_gem_init(ddev); - ret = omap_hwoverlays_init(priv); + drm_mode_config_init(ddev); + + ret = omap_global_obj_init(ddev); if (ret) goto err_gem_deinit; + ret = omap_hwoverlays_init(priv); + if (ret) + goto err_free_priv_obj; + ret = omap_modeset_init(ddev); if (ret) { dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret); @@ -624,7 +704,10 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) omap_modeset_fini(ddev); err_free_overlays: omap_hwoverlays_destroy(priv); +err_free_priv_obj: + omap_global_obj_fini(priv); err_gem_deinit: + drm_mode_config_cleanup(ddev); omap_gem_deinit(ddev); destroy_workqueue(priv->wq); omap_disconnect_pipelines(ddev); @@ -649,6 +732,8 @@ static void omapdrm_cleanup(struct omap_drm_private *priv) omap_modeset_fini(ddev); omap_hwoverlays_destroy(priv); + omap_global_obj_fini(priv); + drm_mode_config_cleanup(ddev); omap_gem_deinit(ddev); destroy_workqueue(priv->wq); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index b4d9c2062723..a3079aad7ae3 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -14,6 +14,7 @@ #include "dss/omapdss.h" #include "dss/dss.h" +#include #include #include @@ -41,6 +42,16 @@ struct omap_drm_pipeline { unsigned int alias_id; }; +/* + * Global private object state for tracking resources that are shared across + * multiple kms objects (planes/crtcs/etc). + */ +#define to_omap_global_state(x) container_of(x, struct omap_global_state, base) + +struct omap_global_state { + struct drm_private_state base; +}; + struct omap_drm_private { struct drm_device *ddev; struct device *dev; @@ -61,6 +72,8 @@ struct omap_drm_private { unsigned int num_ovls; struct omap_hw_overlay *overlays[8]; + struct drm_private_obj glob_obj; + struct drm_fb_helper *fbdev; struct workqueue_struct *wq; @@ -89,4 +102,8 @@ struct omap_drm_private { void omap_debugfs_init(struct drm_minor *minor); +struct omap_global_state * __must_check omap_get_global_state(struct drm_atomic_state *s); + +struct omap_global_state *omap_get_existing_global_state(struct omap_drm_private *priv); + #endif /* __OMAPDRM_DRV_H__ */