From 4dee3c4b32a65d6b140ed506a7a8859d5cab6611 Mon Sep 17 00:00:00 2001 From: Maíra Canal Date: Fri, 24 Mar 2023 13:42:25 -0300 Subject: drm/vkms: remove the need for the primary plane to be visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before commit bc0d7fdefec6 ("drm: vkms: Supports to the case where primary plane doesn't match the CRTC"), the composition was executed on top of the primary plane. Therefore, the primary plane needed to be visible and full screen. After commit bc0d7fdefec6, this is no longer necessary, as the composition is now executed on top of the CRTC. Then, remove the conditional expression that forced the primary plane to be visible and full screen. This allows vkms to accept non-null framebuffers when the CRTC is disabled. This patch was tested with the vkms IGT testlist and all tests passed successfully. Moreover, the tests igt@kms_universal_plane@universal-plane-pipe-a-functional and igt@kms_universal_plane@disable-primary-vs-flip-pipe-a used to fail and now are passing. Signed-off-by: Maíra Canal Reviewed-by: Melissa Wen Signed-off-by: Maíra Canal Link: https://patchwork.freedesktop.org/patch/msgid/20230324164226.256084-2-mcanal@igalia.com --- drivers/gpu/drm/vkms/vkms_plane.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index b3f8a115cc23..458d16865c97 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -153,10 +153,6 @@ static int vkms_plane_atomic_check(struct drm_plane *plane, if (ret != 0) return ret; - /* for now primary plane must be visible and full screen */ - if (!new_plane_state->visible && !can_position) - return -EINVAL; - return 0; } -- cgit v1.2.3 From 4a1b5d183273ef402edb7c7ff58052ae97259a2d Mon Sep 17 00:00:00 2001 From: Maíra Canal Date: Fri, 24 Mar 2023 13:42:26 -0300 Subject: drm/vkms: allow the primary plane to be positioned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before commit bc0d7fdefec6 ("drm: vkms: Supports to the case where primary plane doesn't match the CRTC"), the composition was executed on top of the primary plane. Therefore, the primary plane needed to cover the entire CRTC. After commit bc0d7fdefec6, this is no longer necessary, as the composition is now executed on top of the CRTC. Then, allow the primary plane to be positioned in such a way that it doesn't cover the entire CRTC. This patch was tested with the vkms IGT testlist and all tests passed successfully. Moreover, the test igt@kms_universal_plane@universal-plane-pageflip-windowed-pipe-A used to fail and now is passing. Signed-off-by: Maíra Canal Reviewed-by: Melissa Wen Signed-off-by: Maíra Canal Link: https://patchwork.freedesktop.org/patch/msgid/20230324164226.256084-3-mcanal@igalia.com --- drivers/gpu/drm/vkms/vkms_plane.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 458d16865c97..c41cec7dcb70 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -132,7 +132,6 @@ static int vkms_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); struct drm_crtc_state *crtc_state; - bool can_position = false; int ret; if (!new_plane_state->fb || WARN_ON(!new_plane_state->crtc)) @@ -143,13 +142,10 @@ static int vkms_plane_atomic_check(struct drm_plane *plane, if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); - if (plane->type != DRM_PLANE_TYPE_PRIMARY) - can_position = true; - ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, DRM_PLANE_NO_SCALING, DRM_PLANE_NO_SCALING, - can_position, true); + true, true); if (ret != 0) return ret; -- cgit v1.2.3 From 6fe30712088e9eea58db32a01c9ed69abb13c77b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Apr 2023 12:40:31 +0200 Subject: drm/omapdrm: Include Include to get the contained declarations. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Tomi Valkeinen Reviewed-by: Emil Velikov Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20230403104035.15288-2-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/omap_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 699ed814e021..fb403b44769c 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -6,6 +6,7 @@ #include #include +#include #include #include -- cgit v1.2.3 From 38129bc9260d3394b2e5d4e5eebc6baaeac02e8f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Apr 2023 12:40:32 +0200 Subject: drm/omapdrm: Remove fb from struct omap_fbdev Fbdev's struct fb_helper stores a pointer to the framebuffer. Remove struct omap_fbdev.fb, which contains the same value. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Tomi Valkeinen Reviewed-by: Emil Velikov Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20230403104035.15288-3-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index a6c8542087ec..b3d57fe4e6ac 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -25,7 +25,6 @@ module_param_named(ywrap, ywrap_enabled, bool, 0644); struct omap_fbdev { struct drm_fb_helper base; - struct drm_framebuffer *fb; struct drm_gem_object *bo; bool ywrap_enabled; @@ -170,7 +169,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, DBG("fbi=%p, dev=%p", fbi, dev); - fbdev->fb = fb; helper->fb = fb; fbi->fbops = &omap_fb_ops; @@ -193,7 +191,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres); - DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height); + DBG("allocated %dx%d fb", fb->width, fb->height); return 0; @@ -266,6 +264,7 @@ void omap_fbdev_fini(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct drm_fb_helper *helper = priv->fbdev; + struct drm_framebuffer *fb; struct omap_fbdev *fbdev; DBG(); @@ -273,6 +272,8 @@ void omap_fbdev_fini(struct drm_device *dev) if (!helper) return; + fb = helper->fb; + drm_fb_helper_unregister_info(helper); drm_fb_helper_fini(helper); @@ -284,8 +285,8 @@ void omap_fbdev_fini(struct drm_device *dev) omap_gem_unpin(fbdev->bo); /* this will free the backing object */ - if (fbdev->fb) - drm_framebuffer_remove(fbdev->fb); + if (fb) + drm_framebuffer_remove(fb); drm_fb_helper_unprepare(helper); kfree(fbdev); -- cgit v1.2.3 From 194c9e20954a0b08418aa452be8c4fce5258fe04 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Apr 2023 12:40:33 +0200 Subject: drm/omapdrm: Remove bo from struct omap_fbdev Fbdev's framebuffer stores a pointer to the GEM object. Remove struct omap_fbdev.bo, which contains the same value. No functional changes. v2: * fix commit message (Tomi) Signed-off-by: Thomas Zimmermann Reviewed-by: Tomi Valkeinen Reviewed-by: Emil Velikov Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20230403104035.15288-4-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index b3d57fe4e6ac..d04a20f95e3d 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "omap_drv.h" @@ -25,7 +26,6 @@ module_param_named(ywrap, ywrap_enabled, bool, 0644); struct omap_fbdev { struct drm_fb_helper base; - struct drm_gem_object *bo; bool ywrap_enabled; /* for deferred dmm roll when getting called in atomic ctx */ @@ -37,12 +37,14 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi); static void pan_worker(struct work_struct *work) { struct omap_fbdev *fbdev = container_of(work, struct omap_fbdev, work); - struct fb_info *fbi = fbdev->base.info; + struct drm_fb_helper *helper = &fbdev->base; + struct fb_info *fbi = helper->info; + struct drm_gem_object *bo = drm_gem_fb_get_obj(helper->fb, 0); int npages; /* DMM roll shifts in 4K pages: */ npages = fbi->fix.line_length >> PAGE_SHIFT; - omap_gem_roll(fbdev->bo, fbi->var.yoffset * npages); + omap_gem_roll(bo, fbi->var.yoffset * npages); } static int omap_fbdev_pan_display(struct fb_var_screeninfo *var, @@ -97,6 +99,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, union omap_gem_size gsize; struct fb_info *fbi = NULL; struct drm_mode_fb_cmd2 mode_cmd = {0}; + struct drm_gem_object *bo; dma_addr_t dma_addr; int ret; @@ -127,20 +130,20 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, .bytes = PAGE_ALIGN(mode_cmd.pitches[0] * mode_cmd.height), }; DBG("allocating %d bytes for fb %d", gsize.bytes, dev->primary->index); - fbdev->bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC); - if (!fbdev->bo) { + bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC); + if (!bo) { dev_err(dev->dev, "failed to allocate buffer object\n"); ret = -ENOMEM; goto fail; } - fb = omap_framebuffer_init(dev, &mode_cmd, &fbdev->bo); + fb = omap_framebuffer_init(dev, &mode_cmd, &bo); if (IS_ERR(fb)) { dev_err(dev->dev, "failed to allocate fb\n"); /* note: if fb creation failed, we can't rely on fb destroy * to unref the bo: */ - drm_gem_object_put(fbdev->bo); + drm_gem_object_put(bo); ret = PTR_ERR(fb); goto fail; } @@ -153,7 +156,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, * to it). Then we just need to be sure that we are able to re- * pin it in case of an opps. */ - ret = omap_gem_pin(fbdev->bo, &dma_addr); + ret = omap_gem_pin(bo, &dma_addr); if (ret) { dev_err(dev->dev, "could not pin framebuffer\n"); ret = -ENOMEM; @@ -175,10 +178,10 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, drm_fb_helper_fill_info(fbi, helper, sizes); - fbi->screen_buffer = omap_gem_vaddr(fbdev->bo); - fbi->screen_size = fbdev->bo->size; + fbi->screen_buffer = omap_gem_vaddr(bo); + fbi->screen_size = bo->size; fbi->fix.smem_start = dma_addr; - fbi->fix.smem_len = fbdev->bo->size; + fbi->fix.smem_len = bo->size; /* if we have DMM, then we can use it for scrolling by just * shuffling pages around in DMM rather than doing sw blit. @@ -265,6 +268,7 @@ void omap_fbdev_fini(struct drm_device *dev) struct omap_drm_private *priv = dev->dev_private; struct drm_fb_helper *helper = priv->fbdev; struct drm_framebuffer *fb; + struct drm_gem_object *bo; struct omap_fbdev *fbdev; DBG(); @@ -280,9 +284,11 @@ void omap_fbdev_fini(struct drm_device *dev) fbdev = to_omap_fbdev(helper); + bo = drm_gem_fb_get_obj(fb, 0); + /* unpin the GEM object pinned in omap_fbdev_create() */ - if (fbdev->bo) - omap_gem_unpin(fbdev->bo); + if (bo) + omap_gem_unpin(bo); /* this will free the backing object */ if (fb) -- cgit v1.2.3 From 8e3aac3bba0f3ecc9fd7cc9f99b21d42418bba17 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Apr 2023 12:40:34 +0200 Subject: drm/omapdrm: Remove fbdev from struct omap_drm_private The DRM device stores a pointer to the fbdev helper. Remove struct omap_drm_private.fbdev, which contains the same value. No functional changes. v2: * don't clear dev->fb_helper unnecessarily (Tomi) * include omap_fbdev.h in omap_fbdev.c (kernel test robot) Signed-off-by: Thomas Zimmermann Reviewed-by: Tomi Valkeinen Reviewed-by: Emil Velikov Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20230403104035.15288-5-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/omap_debugfs.c | 6 +++--- drivers/gpu/drm/omapdrm/omap_drv.c | 1 + drivers/gpu/drm/omapdrm/omap_drv.h | 3 --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 8 ++------ 4 files changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c index bfb2ccb40bd1..a3d470468e5b 100644 --- a/drivers/gpu/drm/omapdrm/omap_debugfs.c +++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c @@ -47,15 +47,15 @@ static int fb_show(struct seq_file *m, void *arg) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct omap_drm_private *priv = dev->dev_private; + struct drm_fb_helper *helper = dev->fb_helper; struct drm_framebuffer *fb; seq_printf(m, "fbcon "); - omap_framebuffer_describe(priv->fbdev->fb, m); + omap_framebuffer_describe(helper->fb, m); mutex_lock(&dev->mode_config.fb_lock); list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - if (fb == priv->fbdev->fb) + if (fb == helper->fb) continue; seq_printf(m, "user "); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index fb403b44769c..6a2f446c960f 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -25,6 +25,7 @@ #include "omap_dmm_tiler.h" #include "omap_drv.h" +#include "omap_fbdev.h" #define DRIVER_NAME MODULE_NAME #define DRIVER_DESC "OMAP DRM" diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 825960fd3ea9..4c7217b35f6b 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -21,7 +21,6 @@ #include "omap_crtc.h" #include "omap_encoder.h" #include "omap_fb.h" -#include "omap_fbdev.h" #include "omap_gem.h" #include "omap_irq.h" #include "omap_plane.h" @@ -77,8 +76,6 @@ struct omap_drm_private { struct drm_private_obj glob_obj; - struct drm_fb_helper *fbdev; - struct workqueue_struct *wq; /* lock for obj_list below */ diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index d04a20f95e3d..9ea863781ac6 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -13,6 +13,7 @@ #include #include "omap_drv.h" +#include "omap_fbdev.h" MODULE_PARM_DESC(ywrap, "Enable ywrap scrolling (omap44xx and later, default 'y')"); static bool ywrap_enabled = true; @@ -250,8 +251,6 @@ void omap_fbdev_init(struct drm_device *dev) if (ret) goto fini; - priv->fbdev = helper; - return; fini: @@ -265,8 +264,7 @@ fail: void omap_fbdev_fini(struct drm_device *dev) { - struct omap_drm_private *priv = dev->dev_private; - struct drm_fb_helper *helper = priv->fbdev; + struct drm_fb_helper *helper = dev->fb_helper; struct drm_framebuffer *fb; struct drm_gem_object *bo; struct omap_fbdev *fbdev; @@ -296,6 +294,4 @@ void omap_fbdev_fini(struct drm_device *dev) drm_fb_helper_unprepare(helper); kfree(fbdev); - - priv->fbdev = NULL; } -- cgit v1.2.3 From 9e69bcd88e4593a32c472d878cf02115ef5dac43 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Apr 2023 12:40:35 +0200 Subject: drm/omapdrm: Implement fbdev emulation as in-kernel client Move code from ad-hoc fbdev callbacks into DRM client functions and remove the old callbacks. The functions instruct the client to poll for changed output or restore the display. The DRM core calls both, the old callbacks and the new client helpers, from the same places. The new functions perform the same operation as before, so there's no change in functionality. Replace all code that initializes or releases fbdev emulation throughout the driver. Instead initialize the fbdev client by a single call to omapdrm_fbdev_setup() after omapdrm has registered its DRM device. As in most drivers, omapdrm's fbdev emulation now acts like a regular DRM client. The fbdev client setup consists of the initial preparation and the hot-plugging of the display. The latter creates the fbdev device and sets up the fbdev framebuffer. The setup performs display hot-plugging once. If no display can be detected, DRM probe helpers re-run the detection on each hotplug event. A call to drm_dev_unregister() releases the client automatically. No further action is required within omapdrm. If the fbdev framebuffer has been fully set up, struct fb_ops.fb_destroy implements the release. For partially initialized emulation, the fbdev client reverts the initial setup. v2: * init drm_client in this patch (Tomi) * don't handle non-atomic modesetting (Tomi) Signed-off-by: Thomas Zimmermann Reviewed-by: Tomi Valkeinen Reviewed-by: Emil Velikov Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20230403104035.15288-6-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/omap_drv.c | 11 +-- drivers/gpu/drm/omapdrm/omap_fbdev.c | 132 +++++++++++++++++++++++------------ drivers/gpu/drm/omapdrm/omap_fbdev.h | 9 +-- 3 files changed, 90 insertions(+), 62 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 6a2f446c960f..5ed549726104 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -221,7 +220,6 @@ static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = static const struct drm_mode_config_funcs omap_mode_config_funcs = { .fb_create = omap_framebuffer_create, - .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = omap_atomic_check, .atomic_commit = drm_atomic_helper_commit, }; @@ -654,7 +652,6 @@ static const struct drm_driver omap_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC | DRIVER_RENDER, .open = dev_open, - .lastclose = drm_fb_helper_lastclose, #ifdef CONFIG_DEBUG_FS .debugfs_init = omap_debugfs_init, #endif @@ -743,8 +740,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) goto err_cleanup_modeset; } - omap_fbdev_init(ddev); - drm_kms_helper_poll_init(ddev); /* @@ -755,12 +750,12 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) if (ret) goto err_cleanup_helpers; + omap_fbdev_setup(ddev); + return 0; err_cleanup_helpers: drm_kms_helper_poll_fini(ddev); - - omap_fbdev_fini(ddev); err_cleanup_modeset: omap_modeset_fini(ddev); err_free_overlays: @@ -786,8 +781,6 @@ static void omapdrm_cleanup(struct omap_drm_private *priv) drm_kms_helper_poll_fini(ddev); - omap_fbdev_fini(ddev); - drm_atomic_helper_shutdown(ddev); omap_modeset_fini(ddev); diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 9ea863781ac6..b950e93b3846 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -4,13 +4,14 @@ * Author: Rob Clark */ -#include -#include +#include +#include #include #include #include #include #include +#include #include "omap_drv.h" #include "omap_fbdev.h" @@ -73,6 +74,25 @@ fallback: return drm_fb_helper_pan_display(var, fbi); } +static void omap_fbdev_fb_destroy(struct fb_info *info) +{ + struct drm_fb_helper *helper = info->par; + struct drm_framebuffer *fb = helper->fb; + struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0); + struct omap_fbdev *fbdev = to_omap_fbdev(helper); + + DBG(); + + drm_fb_helper_fini(helper); + + omap_gem_unpin(bo); + drm_framebuffer_remove(fb); + + drm_client_release(&helper->client); + drm_fb_helper_unprepare(helper); + kfree(fbdev); +} + static const struct fb_ops omap_fb_ops = { .owner = THIS_MODULE, @@ -88,6 +108,8 @@ static const struct fb_ops omap_fb_ops = { .fb_fillrect = drm_fb_helper_sys_fillrect, .fb_copyarea = drm_fb_helper_sys_copyarea, .fb_imageblit = drm_fb_helper_sys_imageblit, + + .fb_destroy = omap_fbdev_fb_destroy, }; static int omap_fbdev_create(struct drm_fb_helper *helper, @@ -222,76 +244,94 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi) return fbi->par; } -/* initialize fbdev helper */ -void omap_fbdev_init(struct drm_device *dev) +/* + * struct drm_client + */ + +static void omap_fbdev_client_unregister(struct drm_client_dev *client) { - struct omap_drm_private *priv = dev->dev_private; - struct omap_fbdev *fbdev = NULL; - struct drm_fb_helper *helper; - int ret = 0; + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - if (!priv->num_pipes) - return; + if (fb_helper->info) { + drm_fb_helper_unregister_info(fb_helper); + } else { + drm_client_release(&fb_helper->client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); + } +} - fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); - if (!fbdev) - return; +static int omap_fbdev_client_restore(struct drm_client_dev *client) +{ + drm_fb_helper_lastclose(client->dev); - INIT_WORK(&fbdev->work, pan_worker); + return 0; +} - helper = &fbdev->base; +static int omap_fbdev_client_hotplug(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + struct drm_device *dev = client->dev; + int ret; - drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs); + if (dev->fb_helper) + return drm_fb_helper_hotplug_event(dev->fb_helper); - ret = drm_fb_helper_init(dev, helper); + ret = drm_fb_helper_init(dev, fb_helper); if (ret) - goto fail; + goto err_drm_err; - ret = drm_fb_helper_initial_config(helper); + ret = drm_fb_helper_initial_config(fb_helper); if (ret) - goto fini; - - return; + goto err_drm_fb_helper_fini; -fini: - drm_fb_helper_fini(helper); -fail: - drm_fb_helper_unprepare(helper); - kfree(fbdev); + return 0; - dev_warn(dev->dev, "omap_fbdev_init failed\n"); +err_drm_fb_helper_fini: + drm_fb_helper_fini(fb_helper); +err_drm_err: + drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); + return ret; } -void omap_fbdev_fini(struct drm_device *dev) +static const struct drm_client_funcs omap_fbdev_client_funcs = { + .owner = THIS_MODULE, + .unregister = omap_fbdev_client_unregister, + .restore = omap_fbdev_client_restore, + .hotplug = omap_fbdev_client_hotplug, +}; + +void omap_fbdev_setup(struct drm_device *dev) { - struct drm_fb_helper *helper = dev->fb_helper; - struct drm_framebuffer *fb; - struct drm_gem_object *bo; struct omap_fbdev *fbdev; + struct drm_fb_helper *helper; + int ret; - DBG(); + drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); + drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - if (!helper) + fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); + if (!fbdev) return; + helper = &fbdev->base; - fb = helper->fb; - - drm_fb_helper_unregister_info(helper); + drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs); - drm_fb_helper_fini(helper); + ret = drm_client_init(dev, &helper->client, "fbdev", &omap_fbdev_client_funcs); + if (ret) + goto err_drm_client_init; - fbdev = to_omap_fbdev(helper); + INIT_WORK(&fbdev->work, pan_worker); - bo = drm_gem_fb_get_obj(fb, 0); + ret = omap_fbdev_client_hotplug(&helper->client); + if (ret) + drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - /* unpin the GEM object pinned in omap_fbdev_create() */ - if (bo) - omap_gem_unpin(bo); + drm_client_register(&helper->client); - /* this will free the backing object */ - if (fb) - drm_framebuffer_remove(fb); + return; +err_drm_client_init: drm_fb_helper_unprepare(helper); kfree(fbdev); } diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.h b/drivers/gpu/drm/omapdrm/omap_fbdev.h index 74a68a5a6eab..74c691a8d45f 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.h +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.h @@ -10,16 +10,11 @@ #define __OMAPDRM_FBDEV_H__ struct drm_device; -struct drm_fb_helper; #ifdef CONFIG_DRM_FBDEV_EMULATION -void omap_fbdev_init(struct drm_device *dev); -void omap_fbdev_fini(struct drm_device *dev); +void omap_fbdev_setup(struct drm_device *dev); #else -static inline void omap_fbdev_init(struct drm_device *dev) -{ -} -static inline void omap_fbdev_fini(struct drm_device *dev) +static inline void omap_fbdev_setup(struct drm_device *dev) { } #endif -- cgit v1.2.3 From 5a94aa77bb7f970c6ae35cd7537121501f015a7f Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Thu, 6 Apr 2023 01:37:39 +0900 Subject: drm/scheduler: Fix UAF race in drm_sched_entity_push_job() After a job is pushed into the queue, it is owned by the scheduler core and may be freed at any time, so we can't write nor read the submit timestamp after that point. Fixes oopses observed with the drm/asahi driver, found with kASAN. Signed-off-by: Asahi Lina Link: https://lore.kernel.org/r/20230406-scheduler-uaf-2-v1-1-972531cf0a81@asahilina.net Reviewed-by: Luben Tuikov Signed-off-by: Luben Tuikov --- drivers/gpu/drm/scheduler/sched_entity.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 15d04a0ec623..e0a8890a62e2 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -507,12 +507,19 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) { struct drm_sched_entity *entity = sched_job->entity; bool first; + ktime_t submit_ts; trace_drm_sched_job(sched_job, entity); atomic_inc(entity->rq->sched->score); WRITE_ONCE(entity->last_user, current->group_leader); + + /* + * After the sched_job is pushed into the entity queue, it may be + * completed and freed up at any time. We can no longer access it. + * Make sure to set the submit_ts first, to avoid a race. + */ + sched_job->submit_ts = submit_ts = ktime_get(); first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node); - sched_job->submit_ts = ktime_get(); /* first job wakes up scheduler */ if (first) { @@ -529,7 +536,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) spin_unlock(&entity->rq_lock); if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) - drm_sched_rq_update_fifo(entity, sched_job->submit_ts); + drm_sched_rq_update_fifo(entity, submit_ts); drm_sched_wakeup(entity->rq->sched); } -- cgit v1.2.3 From ca0376ba196ff7ca5fb55e333a94ea23530ee888 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 6 Apr 2023 13:02:34 +0200 Subject: drm/vkms: Drop vkms_connector_destroy() wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helper is just a wrapper that calls drm_connector_cleanup(), there's no need to have another level of indirection. Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Vetter Reviewed-by: Thomas Zimmermann Reviewed-by: Maíra Canal Link: https://patchwork.freedesktop.org/patch/msgid/20230406110235.3092055-2-javierm@redhat.com --- drivers/gpu/drm/vkms/vkms_output.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 991857125bb4..4de6f8ae38be 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -6,14 +6,9 @@ #include #include -static void vkms_connector_destroy(struct drm_connector *connector) -{ - drm_connector_cleanup(connector); -} - static const struct drm_connector_funcs vkms_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = vkms_connector_destroy, + .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -- cgit v1.2.3 From e3adc46da349d4a4cda1c58d8186c5bce0b011fd Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 6 Apr 2023 13:02:35 +0200 Subject: drm/vkms: Remove include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver doesn't use simple-KMS helpers to set a simple display pipeline but only the drm_simple_encoder_init() function to initialize an encoder. That helper is just a wrapper of drm_encoder_init(), but passing a struct drm_encoder_funcs that sets the .destroy handler to drm_encoder_cleanup(). Since the header is only included for this helper and because the connector is initialized with drm_connector_init() as well, do the same for the encoder and drop the header include. Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Vetter Reviewed-by: Thomas Zimmermann Reviewed-by: Maíra Canal Link: https://patchwork.freedesktop.org/patch/msgid/20230406110235.3092055-3-javierm@redhat.com --- drivers/gpu/drm/vkms/vkms_output.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 4de6f8ae38be..5ce70dd946aa 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -4,7 +4,6 @@ #include #include #include -#include static const struct drm_connector_funcs vkms_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, @@ -14,6 +13,10 @@ static const struct drm_connector_funcs vkms_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; +static const struct drm_encoder_funcs vkms_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + static int vkms_conn_get_modes(struct drm_connector *connector) { int count; @@ -86,7 +89,8 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) drm_connector_helper_add(connector, &vkms_conn_helper_funcs); - ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL); + ret = drm_encoder_init(dev, encoder, &vkms_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, NULL); if (ret) { DRM_ERROR("Failed to init encoder\n"); goto err_encoder; -- cgit v1.2.3 From c2ba16cddd6d13bfed8c8f0f288058f2a6eebaec Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 6 Apr 2023 11:12:03 -0400 Subject: drm/vc4: remove unused render_wait variable smatch reports drivers/gpu/drm/vc4/vc4_irq.c:60:1: warning: symbol 'render_wait' was not declared. Should it be static? This variable is not used so remove it. Signed-off-by: Tom Rix Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20230406151203.1953812-1-trix@redhat.com --- drivers/gpu/drm/vc4/vc4_irq.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index 1e6db0121ccd..563b3dfeb9b9 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c @@ -57,8 +57,6 @@ V3D_INT_FLDONE | \ V3D_INT_FRDONE) -DECLARE_WAIT_QUEUE_HEAD(render_wait); - static void vc4_overflow_mem_work(struct work_struct *work) { -- cgit v1.2.3 From ac9aa21bdf40828583f73ae755dcee6bb1e9b3cb Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 29 Dec 2022 15:52:49 +0000 Subject: drm/nouveau/mc/ga100: make ga100_mc_device static Make ga100_mc_device static as it isn't exported, to fix the following sparse warning: drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c:51:1: warning: symbol 'ga100_mc_device' was not declared. Should it be static? Signed-off-by: Ben Dooks Signed-off-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20221229155249.669436-1-ben-linux@fluff.org --- drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c index 1e2eabec1a76..5d28d30d09d5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c @@ -47,7 +47,7 @@ ga100_mc_device_enabled(struct nvkm_mc *mc, u32 mask) return (nvkm_rd32(mc->subdev.device, 0x000600) & mask) == mask; } -const struct nvkm_mc_device_func +static const struct nvkm_mc_device_func ga100_mc_device = { .enabled = ga100_mc_device_enabled, .enable = ga100_mc_device_enable, -- cgit v1.2.3 From b8aa52913b84f8b59816b95c28d03424a100df7f Mon Sep 17 00:00:00 2001 From: ruanjinjie Date: Sat, 24 Sep 2022 15:39:57 +0800 Subject: drm/nouveau/disp: make gv100_disp_core_mthd_base static The symbol is not used outside of the file, so mark it static. Fixes the following warning: ./drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c:591:1: warning: symbol 'gv100_disp_core_mthd_base' was not declared. Should it be static? Signed-off-by: ruanjinjie Reviewed-by: Karol Herbst Signed-off-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20220924073957.4140388-1-ruanjinjie@huawei.com --- drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c index 115d0997fd62..4ebc030e40d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c @@ -606,7 +606,7 @@ gv100_disp_curs = { .user = 73, }; -const struct nvkm_disp_mthd_list +static const struct nvkm_disp_mthd_list gv100_disp_core_mthd_base = { .mthd = 0x0000, .addr = 0x000000, -- cgit v1.2.3 From 490438469d493e8f764bea14d47eaf4c2ae7cc80 Mon Sep 17 00:00:00 2001 From: Martin Krastev Date: Mon, 20 Mar 2023 22:09:47 -0400 Subject: drm/vmwgfx: Drop mksstat_init_record fn as currently unused This internal helper handles a type of mksstat event counter which is currently unused. Remove the routine to avoid compile warnings. Reported-by: kernel test robot Signed-off-by: Martin Krastev Reviewed-by: Maaz Mombasawala Reviewed-by: Zack Rusin Signed-off-by: Zack Rusin Link: https://patchwork.freedesktop.org/patch/msgid/20230321020949.335012-1-zack@kde.org --- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index e76976a95a1e..ca1a3fe44fa5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -702,32 +702,6 @@ static inline void hypervisor_ppn_remove(PPN64 pfn) /* Header to the text description of mksGuestStat instance descriptor */ #define MKSSTAT_KERNEL_DESCRIPTION "vmwgfx" -/** - * mksstat_init_record: Initializes an MKSGuestStatCounter-based record - * for the respective mksGuestStat index. - * - * @stat_idx: Index of the MKSGuestStatCounter-based mksGuestStat record. - * @pstat: Pointer to array of MKSGuestStatCounterTime. - * @pinfo: Pointer to array of MKSGuestStatInfoEntry. - * @pstrs: Pointer to current end of the name/description sequence. - * Return: Pointer to the new end of the names/description sequence. - */ - -static inline char *mksstat_init_record(mksstat_kern_stats_t stat_idx, - MKSGuestStatCounterTime *pstat, MKSGuestStatInfoEntry *pinfo, char *pstrs) -{ - char *const pstrd = pstrs + strlen(mksstat_kern_name_desc[stat_idx][0]) + 1; - strcpy(pstrs, mksstat_kern_name_desc[stat_idx][0]); - strcpy(pstrd, mksstat_kern_name_desc[stat_idx][1]); - - pinfo[stat_idx].name.s = pstrs; - pinfo[stat_idx].description.s = pstrd; - pinfo[stat_idx].flags = MKS_GUEST_STAT_FLAG_NONE; - pinfo[stat_idx].stat.counter = (MKSGuestStatCounter *)&pstat[stat_idx]; - - return pstrd + strlen(mksstat_kern_name_desc[stat_idx][1]) + 1; -} - /** * mksstat_init_record_time: Initializes an MKSGuestStatCounterTime-based record * for the respective mksGuestStat index. -- cgit v1.2.3 From 35d86fb626a2554de5d5916b6e2d47d06b483d37 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 20 Mar 2023 22:09:48 -0400 Subject: drm/vmwgfx: Print errors when running on broken/unsupported configs virtualbox implemented an incomplete version of the svga device which they decided to drop soon after the initial release. The device was always broken in various ways and never supported by vmwgfx. vmwgfx should refuse to load on those configurations but currently drm has no way of reloading fbdev when the specific pci driver refuses to load, which would leave users without a usable fb. Instead of refusing to load print an error and disable a bunch of functionality that virtualbox never implemented to at least get fb to work on their setup. Signed-off-by: Zack Rusin Reviewed-by: Martin Krastev Reviewed-by: Maaz Mombasawala Link: https://patchwork.freedesktop.org/patch/msgid/20230321020949.335012-2-zack@kde.org --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 29 +++++++++++++++++++++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 9 +++++++++ 3 files changed, 40 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 2588615a2a38..8b24ecf60e3e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -45,6 +45,9 @@ #include #include +#ifdef CONFIG_X86 +#include +#endif #include #include #include @@ -897,6 +900,16 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) cap2_names, ARRAY_SIZE(cap2_names)); } + if (!vmwgfx_supported(dev_priv)) { + vmw_disable_backdoor(); + drm_err_once(&dev_priv->drm, + "vmwgfx seems to be running on an unsupported hypervisor."); + drm_err_once(&dev_priv->drm, + "This configuration is likely broken."); + drm_err_once(&dev_priv->drm, + "Please switch to a supported graphics device to avoid problems."); + } + ret = vmw_dma_select_mode(dev_priv); if (unlikely(ret != 0)) { drm_info(&dev_priv->drm, @@ -1320,6 +1333,22 @@ static void vmw_master_drop(struct drm_device *dev, vmw_kms_legacy_hotspot_clear(dev_priv); } +bool vmwgfx_supported(struct vmw_private *vmw) +{ +#if defined(CONFIG_X86) + return hypervisor_is_type(X86_HYPER_VMWARE); +#elif defined(CONFIG_ARM64) + /* + * On aarch64 only svga3 is supported + */ + return vmw->pci_id == VMWGFX_PCI_ID_SVGA3; +#else + drm_warn_once(&vmw->drm, + "vmwgfx is running on an unknown architecture."); + return false; +#endif +} + /** * __vmw_svga_enable - Enable SVGA mode, FIFO and use of VRAM. * diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index fb8f0c0642c0..3810a9984a7f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -773,6 +773,7 @@ static inline u32 vmw_max_num_uavs(struct vmw_private *dev_priv) extern void vmw_svga_enable(struct vmw_private *dev_priv); extern void vmw_svga_disable(struct vmw_private *dev_priv); +bool vmwgfx_supported(struct vmw_private *vmw); /** @@ -1358,6 +1359,7 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst, struct vmw_diff_cpy *diff); /* Host messaging -vmwgfx_msg.c: */ +void vmw_disable_backdoor(void); int vmw_host_get_guestinfo(const char *guest_info_param, char *buffer, size_t *length); __printf(1, 2) int vmw_host_printf(const char *fmt, ...); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index ca1a3fe44fa5..2651fe0ef518 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -1179,3 +1179,12 @@ int vmw_mksstat_remove_ioctl(struct drm_device *dev, void *data, return -EAGAIN; } + +/** + * vmw_disable_backdoor: Disables all backdoor communication + * with the hypervisor. + */ +void vmw_disable_backdoor(void) +{ + vmw_msg_enabled = 0; +} -- cgit v1.2.3 From a37a512db3fa1b65fe9087003e5b2072cefb3667 Mon Sep 17 00:00:00 2001 From: Martin Krastev Date: Mon, 20 Mar 2023 22:09:49 -0400 Subject: drm/vmwgfx: Fix Legacy Display Unit atomic drm support Legacy Display Unit (LDU) fb dirty support used a custom fb dirty callback. Latter handled only the DIRTYFB IOCTL presentation path but not the ADDFB2/PAGE_FLIP/RMFB IOCTL path, common for Wayland compositors. Get rid of the custom callback in favor of drm_atomic_helper_dirtyfb and unify the handling of the presentation paths inside of vmw_ldu_primary_plane_atomic_update. This also homogenizes the fb dirty callbacks across all DUs: LDU, SOU and STDU. Signed-off-by: Martin Krastev Reviewed-by: Maaz Mombasawala Fixes: 2f5544ff0300 ("drm/vmwgfx: Use atomic helper function for dirty fb IOCTL") Cc: # v5.0+ Signed-off-by: Zack Rusin Link: https://patchwork.freedesktop.org/patch/msgid/20230321020949.335012-3-zack@kde.org --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 62 +------------------------------------ drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 5 --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 45 ++++++++++++++++++++++----- 3 files changed, 38 insertions(+), 74 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 5162a7a12792..b62207be3363 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1396,70 +1396,10 @@ static void vmw_framebuffer_bo_destroy(struct drm_framebuffer *framebuffer) kfree(vfbd); } -static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer, - struct drm_file *file_priv, - unsigned int flags, unsigned int color, - struct drm_clip_rect *clips, - unsigned int num_clips) -{ - struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); - struct vmw_framebuffer_bo *vfbd = - vmw_framebuffer_to_vfbd(framebuffer); - struct drm_clip_rect norect; - int ret, increment = 1; - - drm_modeset_lock_all(&dev_priv->drm); - - if (!num_clips) { - num_clips = 1; - clips = &norect; - norect.x1 = norect.y1 = 0; - norect.x2 = framebuffer->width; - norect.y2 = framebuffer->height; - } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) { - num_clips /= 2; - increment = 2; - } - - switch (dev_priv->active_display_unit) { - case vmw_du_legacy: - ret = vmw_kms_ldu_do_bo_dirty(dev_priv, &vfbd->base, 0, 0, - clips, num_clips, increment); - break; - default: - ret = -EINVAL; - WARN_ONCE(true, "Dirty called with invalid display system.\n"); - break; - } - - vmw_cmd_flush(dev_priv, false); - - drm_modeset_unlock_all(&dev_priv->drm); - - return ret; -} - -static int vmw_framebuffer_bo_dirty_ext(struct drm_framebuffer *framebuffer, - struct drm_file *file_priv, - unsigned int flags, unsigned int color, - struct drm_clip_rect *clips, - unsigned int num_clips) -{ - struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); - - if (dev_priv->active_display_unit == vmw_du_legacy && - vmw_cmd_supported(dev_priv)) - return vmw_framebuffer_bo_dirty(framebuffer, file_priv, flags, - color, clips, num_clips); - - return drm_atomic_helper_dirtyfb(framebuffer, file_priv, flags, color, - clips, num_clips); -} - static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = { .create_handle = vmw_framebuffer_bo_create_handle, .destroy = vmw_framebuffer_bo_destroy, - .dirty = vmw_framebuffer_bo_dirty_ext, + .dirty = drm_atomic_helper_dirtyfb, }; /** diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 3de7b4b6a230..db81e635dc06 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -507,11 +507,6 @@ void vmw_du_connector_destroy_state(struct drm_connector *connector, */ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv); int vmw_kms_ldu_close_display(struct vmw_private *dev_priv); -int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, - struct vmw_framebuffer *framebuffer, - unsigned int flags, unsigned int color, - struct drm_clip_rect *clips, - unsigned int num_clips, int increment); int vmw_kms_update_proxy(struct vmw_resource *res, const struct drm_clip_rect *clips, unsigned num_clips, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index c0e42f2ed144..a82fa9700370 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -275,6 +275,7 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = { .atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_destroy_state = vmw_du_crtc_destroy_state, .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, }; @@ -314,6 +315,12 @@ static const struct drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = { }; +static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, + struct vmw_framebuffer *framebuffer, + unsigned int flags, unsigned int color, + struct drm_mode_rect *clips, + unsigned int num_clips); + /* * Legacy Display Plane Functions */ @@ -332,7 +339,6 @@ vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane, struct drm_framebuffer *fb; struct drm_crtc *crtc = new_state->crtc ?: old_state->crtc; - ldu = vmw_crtc_to_ldu(crtc); dev_priv = vmw_priv(plane->dev); fb = new_state->fb; @@ -345,8 +351,31 @@ vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane, vmw_ldu_del_active(dev_priv, ldu); vmw_ldu_commit_list(dev_priv); -} + if (vfb && vmw_cmd_supported(dev_priv)) { + struct drm_mode_rect fb_rect = { + .x1 = 0, + .y1 = 0, + .x2 = vfb->base.width, + .y2 = vfb->base.height + }; + struct drm_mode_rect *damage_rects = drm_plane_get_damage_clips(new_state); + u32 rect_count = drm_plane_get_damage_clips_count(new_state); + int ret; + + if (!damage_rects) { + damage_rects = &fb_rect; + rect_count = 1; + } + + ret = vmw_kms_ldu_do_bo_dirty(dev_priv, vfb, 0, 0, damage_rects, rect_count); + + drm_WARN_ONCE(plane->dev, ret, + "vmw_kms_ldu_do_bo_dirty failed with: ret=%d\n", ret); + + vmw_cmd_flush(dev_priv, false); + } +} static const struct drm_plane_funcs vmw_ldu_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, @@ -577,11 +606,11 @@ int vmw_kms_ldu_close_display(struct vmw_private *dev_priv) } -int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, - struct vmw_framebuffer *framebuffer, - unsigned int flags, unsigned int color, - struct drm_clip_rect *clips, - unsigned int num_clips, int increment) +static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, + struct vmw_framebuffer *framebuffer, + unsigned int flags, unsigned int color, + struct drm_mode_rect *clips, + unsigned int num_clips) { size_t fifo_size; int i; @@ -597,7 +626,7 @@ int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, return -ENOMEM; memset(cmd, 0, fifo_size); - for (i = 0; i < num_clips; i++, clips += increment) { + for (i = 0; i < num_clips; i++, clips++) { cmd[i].header = SVGA_CMD_UPDATE; cmd[i].body.x = clips->x1; cmd[i].body.y = clips->y1; -- cgit v1.2.3 From fd35174e13f98f9232c4aa66689816731d34ca28 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Tue, 21 Mar 2023 14:24:14 -0400 Subject: drm/vmwgfx: remove unused vmw_overlay function clang with W=1 reports drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c:56:35: error: unused function 'vmw_overlay' [-Werror,-Wunused-function] static inline struct vmw_overlay *vmw_overlay(struct drm_device *dev) ^ This function is not used, so remove it. Signed-off-by: Tom Rix Reviewed-by: Nick Desaulniers Signed-off-by: Zack Rusin Link: https://patchwork.freedesktop.org/patch/msgid/20230321182414.1826372-1-trix@redhat.com --- drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index 8d171d71cb8a..7e112319a23c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -53,12 +53,6 @@ struct vmw_overlay { struct vmw_stream stream[VMW_MAX_NUM_STREAMS]; }; -static inline struct vmw_overlay *vmw_overlay(struct drm_device *dev) -{ - struct vmw_private *dev_priv = vmw_priv(dev); - return dev_priv ? dev_priv->overlay_priv : NULL; -} - struct vmw_escape_header { uint32_t cmd; SVGAFifoCmdEscape body; -- cgit v1.2.3