Message ID | 20240924071734.98201-81-tzimmermann@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm: Provide client setup helper and convert drivers | expand |
On 24/09/2024 10:13, Thomas Zimmermann wrote: > Rework fbdev probing to support fbdev_probe in struct drm_driver > and remove the old fb_probe callback. Provide an initializer macro > for struct drm_driver that sets the callback according to the kernel > configuration. > > Call drm_client_setup() to run the kernel's default client setup > for DRM. Set fbdev_probe in struct drm_driver, so that the client > setup can start the common fbdev client. > > The omapdrm driver specifies a preferred color mode of 32. As this > is the default if no format has been given, leave it out entirely. > > v5: > - select DRM_CLIENT_SELECTION > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> > Acked-by: Javier Martinez Canillas <javierm@redhat.com> > --- > drivers/gpu/drm/omapdrm/Kconfig | 1 + > drivers/gpu/drm/omapdrm/omap_drv.c | 1 + > drivers/gpu/drm/omapdrm/omap_fbdev.c | 131 ++++++--------------------- > drivers/gpu/drm/omapdrm/omap_fbdev.h | 8 ++ > 4 files changed, 39 insertions(+), 102 deletions(-) Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Tomi > diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig > index fbd9af758581..9d4016bd0f44 100644 > --- a/drivers/gpu/drm/omapdrm/Kconfig > +++ b/drivers/gpu/drm/omapdrm/Kconfig > @@ -4,6 +4,7 @@ config DRM_OMAP > depends on MMU > depends on DRM && OF > depends on ARCH_OMAP2PLUS || (COMPILE_TEST && PAGE_SIZE_LESS_THAN_64KB) > + select DRM_CLIENT_SELECTION > select DRM_KMS_HELPER > select DRM_DISPLAY_HELPER > select DRM_BRIDGE_CONNECTOR > diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c > index a982378aa141..1796cd20a877 100644 > --- a/drivers/gpu/drm/omapdrm/omap_drv.c > +++ b/drivers/gpu/drm/omapdrm/omap_drv.c > @@ -647,6 +647,7 @@ static const struct drm_driver omap_drm_driver = { > .gem_prime_import = omap_gem_prime_import, > .dumb_create = omap_gem_dumb_create, > .dumb_map_offset = omap_gem_dumb_map_offset, > + OMAP_FBDEV_DRIVER_OPS, > .ioctls = ioctls, > .num_ioctls = DRM_OMAP_NUM_IOCTLS, > .fops = &omapdriver_fops, > diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c > index 044e80403c3b..f4bd0c6e3f34 100644 > --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c > +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c > @@ -6,6 +6,7 @@ > > #include <linux/fb.h> > > +#include <drm/drm_client_setup.h> > #include <drm/drm_drv.h> > #include <drm/drm_crtc_helper.h> > #include <drm/drm_fb_helper.h> > @@ -124,8 +125,32 @@ static const struct fb_ops omap_fb_ops = { > .fb_destroy = omap_fbdev_fb_destroy, > }; > > -static int omap_fbdev_create(struct drm_fb_helper *helper, > - struct drm_fb_helper_surface_size *sizes) > +static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) > +{ > + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) > + return 0; > + > + if (helper->fb->funcs->dirty) > + return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); > + > + return 0; > +} > + > +static const struct drm_fb_helper_funcs omap_fbdev_helper_funcs = { > + .fb_dirty = omap_fbdev_dirty, > +}; > + > +static struct drm_fb_helper *get_fb(struct fb_info *fbi) > +{ > + if (!fbi || strcmp(fbi->fix.id, MODULE_NAME)) { > + /* these are not the fb's you're looking for */ > + return NULL; > + } > + return fbi->par; > +} > + > +int omap_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes) > { > struct drm_device *dev = helper->dev; > struct omap_drm_private *priv = dev->dev_private; > @@ -207,6 +232,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, > > DBG("fbi=%p, dev=%p", fbi, dev); > > + helper->funcs = &omap_fbdev_helper_funcs; > helper->fb = fb; > > fbi->fbops = &omap_fb_ops; > @@ -253,94 +279,10 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, > return ret; > } > > -static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) > -{ > - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) > - return 0; > - > - if (helper->fb->funcs->dirty) > - return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); > - > - return 0; > -} > - > -static const struct drm_fb_helper_funcs omap_fb_helper_funcs = { > - .fb_probe = omap_fbdev_create, > - .fb_dirty = omap_fbdev_dirty, > -}; > - > -static struct drm_fb_helper *get_fb(struct fb_info *fbi) > -{ > - if (!fbi || strcmp(fbi->fix.id, MODULE_NAME)) { > - /* these are not the fb's you're looking for */ > - return NULL; > - } > - return fbi->par; > -} > - > -/* > - * struct drm_client > - */ > - > -static void omap_fbdev_client_unregister(struct drm_client_dev *client) > -{ > - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); > - > - 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); > - } > -} > - > -static int omap_fbdev_client_restore(struct drm_client_dev *client) > -{ > - drm_fb_helper_lastclose(client->dev); > - > - return 0; > -} > - > -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; > - > - if (dev->fb_helper) > - return drm_fb_helper_hotplug_event(dev->fb_helper); > - > - ret = drm_fb_helper_init(dev, fb_helper); > - if (ret) > - goto err_drm_err; > - > - ret = drm_fb_helper_initial_config(fb_helper); > - if (ret) > - goto err_drm_fb_helper_fini; > - > - return 0; > - > -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; > -} > - > -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 omap_fbdev *fbdev; > - struct drm_fb_helper *helper; > - int ret; > > drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); > drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); > @@ -353,20 +295,5 @@ void omap_fbdev_setup(struct drm_device *dev) > > priv->fbdev = fbdev; > > - helper = kzalloc(sizeof(*helper), GFP_KERNEL); > - if (!helper) > - return; > - drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs); > - > - ret = drm_client_init(dev, &helper->client, "fbdev", &omap_fbdev_client_funcs); > - if (ret) > - goto err_drm_client_init; > - > - drm_client_register(&helper->client); > - > - return; > - > -err_drm_client_init: > - drm_fb_helper_unprepare(helper); > - kfree(helper); > + drm_client_setup(dev, NULL); > } > diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.h b/drivers/gpu/drm/omapdrm/omap_fbdev.h > index 74c691a8d45f..283e35b42ada 100644 > --- a/drivers/gpu/drm/omapdrm/omap_fbdev.h > +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.h > @@ -10,10 +10,18 @@ > #define __OMAPDRM_FBDEV_H__ > > struct drm_device; > +struct drm_fb_helper; > +struct drm_fb_helper_surface_size; > > #ifdef CONFIG_DRM_FBDEV_EMULATION > +int omap_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes); > +#define OMAP_FBDEV_DRIVER_OPS \ > + .fbdev_probe = omap_fbdev_driver_fbdev_probe > void omap_fbdev_setup(struct drm_device *dev); > #else > +#define OMAP_FBDEV_DRIVER_OPS \ > + .fbdev_probe = NULL > static inline void omap_fbdev_setup(struct drm_device *dev) > { > }
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index fbd9af758581..9d4016bd0f44 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig @@ -4,6 +4,7 @@ config DRM_OMAP depends on MMU depends on DRM && OF depends on ARCH_OMAP2PLUS || (COMPILE_TEST && PAGE_SIZE_LESS_THAN_64KB) + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index a982378aa141..1796cd20a877 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -647,6 +647,7 @@ static const struct drm_driver omap_drm_driver = { .gem_prime_import = omap_gem_prime_import, .dumb_create = omap_gem_dumb_create, .dumb_map_offset = omap_gem_dumb_map_offset, + OMAP_FBDEV_DRIVER_OPS, .ioctls = ioctls, .num_ioctls = DRM_OMAP_NUM_IOCTLS, .fops = &omapdriver_fops, diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 044e80403c3b..f4bd0c6e3f34 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -6,6 +6,7 @@ #include <linux/fb.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> @@ -124,8 +125,32 @@ static const struct fb_ops omap_fb_ops = { .fb_destroy = omap_fbdev_fb_destroy, }; -static int omap_fbdev_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) +static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) +{ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) + return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + + return 0; +} + +static const struct drm_fb_helper_funcs omap_fbdev_helper_funcs = { + .fb_dirty = omap_fbdev_dirty, +}; + +static struct drm_fb_helper *get_fb(struct fb_info *fbi) +{ + if (!fbi || strcmp(fbi->fix.id, MODULE_NAME)) { + /* these are not the fb's you're looking for */ + return NULL; + } + return fbi->par; +} + +int omap_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) { struct drm_device *dev = helper->dev; struct omap_drm_private *priv = dev->dev_private; @@ -207,6 +232,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, DBG("fbi=%p, dev=%p", fbi, dev); + helper->funcs = &omap_fbdev_helper_funcs; helper->fb = fb; fbi->fbops = &omap_fb_ops; @@ -253,94 +279,10 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, return ret; } -static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) -{ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - if (helper->fb->funcs->dirty) - return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); - - return 0; -} - -static const struct drm_fb_helper_funcs omap_fb_helper_funcs = { - .fb_probe = omap_fbdev_create, - .fb_dirty = omap_fbdev_dirty, -}; - -static struct drm_fb_helper *get_fb(struct fb_info *fbi) -{ - if (!fbi || strcmp(fbi->fix.id, MODULE_NAME)) { - /* these are not the fb's you're looking for */ - return NULL; - } - return fbi->par; -} - -/* - * struct drm_client - */ - -static void omap_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - 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); - } -} - -static int omap_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -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; -} - -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 omap_fbdev *fbdev; - struct drm_fb_helper *helper; - int ret; drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); @@ -353,20 +295,5 @@ void omap_fbdev_setup(struct drm_device *dev) priv->fbdev = fbdev; - helper = kzalloc(sizeof(*helper), GFP_KERNEL); - if (!helper) - return; - drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs); - - ret = drm_client_init(dev, &helper->client, "fbdev", &omap_fbdev_client_funcs); - if (ret) - goto err_drm_client_init; - - drm_client_register(&helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(helper); - kfree(helper); + drm_client_setup(dev, NULL); } diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.h b/drivers/gpu/drm/omapdrm/omap_fbdev.h index 74c691a8d45f..283e35b42ada 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.h +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.h @@ -10,10 +10,18 @@ #define __OMAPDRM_FBDEV_H__ struct drm_device; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; #ifdef CONFIG_DRM_FBDEV_EMULATION +int omap_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); +#define OMAP_FBDEV_DRIVER_OPS \ + .fbdev_probe = omap_fbdev_driver_fbdev_probe void omap_fbdev_setup(struct drm_device *dev); #else +#define OMAP_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL static inline void omap_fbdev_setup(struct drm_device *dev) { }