diff options
author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 |
---|---|---|
committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 |
commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/gpu/drm/omapdrm | |
parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/gpu/drm/omapdrm')
-rw-r--r-- | drivers/gpu/drm/omapdrm/Kconfig | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_debugfs.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_fbdev.c | 163 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_fbdev.h | 9 |
6 files changed, 113 insertions, 83 deletions
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index 455e1a91f0e5..76ded1568bd0 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig @@ -2,7 +2,7 @@ config DRM_OMAP tristate "OMAP DRM" depends on DRM && OF - depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM + depends on ARCH_OMAP2PLUS select DRM_KMS_HELPER select VIDEOMODE_HELPERS select HDMI 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 699ed814e021..5ed549726104 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -6,6 +6,7 @@ #include <linux/dma-mapping.h> #include <linux/platform_device.h> +#include <linux/of.h> #include <linux/sort.h> #include <linux/sys_soc.h> @@ -14,7 +15,6 @@ #include <drm/drm_bridge.h> #include <drm/drm_bridge_connector.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> #include <drm/drm_panel.h> @@ -24,6 +24,7 @@ #include "omap_dmm_tiler.h" #include "omap_drv.h" +#include "omap_fbdev.h" #define DRIVER_NAME MODULE_NAME #define DRIVER_DESC "OMAP DRM" @@ -219,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, }; @@ -652,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 @@ -741,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); /* @@ -753,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: @@ -784,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_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 a6c8542087ec..b950e93b3846 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -4,14 +4,17 @@ * Author: Rob Clark <[email protected]> */ -#include <drm/drm_crtc.h> -#include <drm/drm_util.h> +#include <drm/drm_drv.h> +#include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> #include <drm/drm_file.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> +#include <drm/drm_gem_framebuffer_helper.h> +#include <drm/drm_util.h> #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; @@ -25,8 +28,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; /* for deferred dmm roll when getting called in atomic ctx */ @@ -38,12 +39,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, @@ -71,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, @@ -86,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, @@ -98,6 +122,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; @@ -128,20 +153,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; } @@ -154,7 +179,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; @@ -170,17 +195,16 @@ 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; 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. @@ -193,7 +217,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; @@ -220,75 +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; - - priv->fbdev = helper; - - 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 omap_drm_private *priv = dev->dev_private; - struct drm_fb_helper *helper = priv->fbdev; 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; - 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; + + INIT_WORK(&fbdev->work, pan_worker); - fbdev = to_omap_fbdev(helper); + 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 (fbdev->bo) - omap_gem_unpin(fbdev->bo); + drm_client_register(&helper->client); - /* this will free the backing object */ - if (fbdev->fb) - drm_framebuffer_remove(fbdev->fb); + return; +err_drm_client_init: drm_fb_helper_unprepare(helper); kfree(fbdev); - - priv->fbdev = NULL; } 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 |