Skip to content

Commit 9e69bcd

Browse files
tdztomba
authored andcommitted
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 <tzimmermann@suse.de> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230403104035.15288-6-tzimmermann@suse.de
1 parent 8e3aac3 commit 9e69bcd

3 files changed

Lines changed: 90 additions & 62 deletions

File tree

drivers/gpu/drm/omapdrm/omap_drv.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <drm/drm_bridge.h>
1616
#include <drm/drm_bridge_connector.h>
1717
#include <drm/drm_drv.h>
18-
#include <drm/drm_fb_helper.h>
1918
#include <drm/drm_file.h>
2019
#include <drm/drm_ioctl.h>
2120
#include <drm/drm_panel.h>
@@ -221,7 +220,6 @@ static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs =
221220

222221
static const struct drm_mode_config_funcs omap_mode_config_funcs = {
223222
.fb_create = omap_framebuffer_create,
224-
.output_poll_changed = drm_fb_helper_output_poll_changed,
225223
.atomic_check = omap_atomic_check,
226224
.atomic_commit = drm_atomic_helper_commit,
227225
};
@@ -654,7 +652,6 @@ static const struct drm_driver omap_drm_driver = {
654652
.driver_features = DRIVER_MODESET | DRIVER_GEM |
655653
DRIVER_ATOMIC | DRIVER_RENDER,
656654
.open = dev_open,
657-
.lastclose = drm_fb_helper_lastclose,
658655
#ifdef CONFIG_DEBUG_FS
659656
.debugfs_init = omap_debugfs_init,
660657
#endif
@@ -743,8 +740,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
743740
goto err_cleanup_modeset;
744741
}
745742

746-
omap_fbdev_init(ddev);
747-
748743
drm_kms_helper_poll_init(ddev);
749744

750745
/*
@@ -755,12 +750,12 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
755750
if (ret)
756751
goto err_cleanup_helpers;
757752

753+
omap_fbdev_setup(ddev);
754+
758755
return 0;
759756

760757
err_cleanup_helpers:
761758
drm_kms_helper_poll_fini(ddev);
762-
763-
omap_fbdev_fini(ddev);
764759
err_cleanup_modeset:
765760
omap_modeset_fini(ddev);
766761
err_free_overlays:
@@ -786,8 +781,6 @@ static void omapdrm_cleanup(struct omap_drm_private *priv)
786781

787782
drm_kms_helper_poll_fini(ddev);
788783

789-
omap_fbdev_fini(ddev);
790-
791784
drm_atomic_helper_shutdown(ddev);
792785

793786
omap_modeset_fini(ddev);

drivers/gpu/drm/omapdrm/omap_fbdev.c

Lines changed: 86 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
* Author: Rob Clark <rob@ti.com>
55
*/
66

7-
#include <drm/drm_crtc.h>
8-
#include <drm/drm_util.h>
7+
#include <drm/drm_drv.h>
8+
#include <drm/drm_crtc_helper.h>
99
#include <drm/drm_fb_helper.h>
1010
#include <drm/drm_file.h>
1111
#include <drm/drm_fourcc.h>
1212
#include <drm/drm_framebuffer.h>
1313
#include <drm/drm_gem_framebuffer_helper.h>
14+
#include <drm/drm_util.h>
1415

1516
#include "omap_drv.h"
1617
#include "omap_fbdev.h"
@@ -73,6 +74,25 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
7374
return drm_fb_helper_pan_display(var, fbi);
7475
}
7576

77+
static void omap_fbdev_fb_destroy(struct fb_info *info)
78+
{
79+
struct drm_fb_helper *helper = info->par;
80+
struct drm_framebuffer *fb = helper->fb;
81+
struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0);
82+
struct omap_fbdev *fbdev = to_omap_fbdev(helper);
83+
84+
DBG();
85+
86+
drm_fb_helper_fini(helper);
87+
88+
omap_gem_unpin(bo);
89+
drm_framebuffer_remove(fb);
90+
91+
drm_client_release(&helper->client);
92+
drm_fb_helper_unprepare(helper);
93+
kfree(fbdev);
94+
}
95+
7696
static const struct fb_ops omap_fb_ops = {
7797
.owner = THIS_MODULE,
7898

@@ -88,6 +108,8 @@ static const struct fb_ops omap_fb_ops = {
88108
.fb_fillrect = drm_fb_helper_sys_fillrect,
89109
.fb_copyarea = drm_fb_helper_sys_copyarea,
90110
.fb_imageblit = drm_fb_helper_sys_imageblit,
111+
112+
.fb_destroy = omap_fbdev_fb_destroy,
91113
};
92114

93115
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)
222244
return fbi->par;
223245
}
224246

225-
/* initialize fbdev helper */
226-
void omap_fbdev_init(struct drm_device *dev)
247+
/*
248+
* struct drm_client
249+
*/
250+
251+
static void omap_fbdev_client_unregister(struct drm_client_dev *client)
227252
{
228-
struct omap_drm_private *priv = dev->dev_private;
229-
struct omap_fbdev *fbdev = NULL;
230-
struct drm_fb_helper *helper;
231-
int ret = 0;
253+
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
232254

233-
if (!priv->num_pipes)
234-
return;
255+
if (fb_helper->info) {
256+
drm_fb_helper_unregister_info(fb_helper);
257+
} else {
258+
drm_client_release(&fb_helper->client);
259+
drm_fb_helper_unprepare(fb_helper);
260+
kfree(fb_helper);
261+
}
262+
}
235263

236-
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
237-
if (!fbdev)
238-
return;
264+
static int omap_fbdev_client_restore(struct drm_client_dev *client)
265+
{
266+
drm_fb_helper_lastclose(client->dev);
239267

240-
INIT_WORK(&fbdev->work, pan_worker);
268+
return 0;
269+
}
241270

242-
helper = &fbdev->base;
271+
static int omap_fbdev_client_hotplug(struct drm_client_dev *client)
272+
{
273+
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
274+
struct drm_device *dev = client->dev;
275+
int ret;
243276

244-
drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs);
277+
if (dev->fb_helper)
278+
return drm_fb_helper_hotplug_event(dev->fb_helper);
245279

246-
ret = drm_fb_helper_init(dev, helper);
280+
ret = drm_fb_helper_init(dev, fb_helper);
247281
if (ret)
248-
goto fail;
282+
goto err_drm_err;
249283

250-
ret = drm_fb_helper_initial_config(helper);
284+
ret = drm_fb_helper_initial_config(fb_helper);
251285
if (ret)
252-
goto fini;
253-
254-
return;
286+
goto err_drm_fb_helper_fini;
255287

256-
fini:
257-
drm_fb_helper_fini(helper);
258-
fail:
259-
drm_fb_helper_unprepare(helper);
260-
kfree(fbdev);
288+
return 0;
261289

262-
dev_warn(dev->dev, "omap_fbdev_init failed\n");
290+
err_drm_fb_helper_fini:
291+
drm_fb_helper_fini(fb_helper);
292+
err_drm_err:
293+
drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
294+
return ret;
263295
}
264296

265-
void omap_fbdev_fini(struct drm_device *dev)
297+
static const struct drm_client_funcs omap_fbdev_client_funcs = {
298+
.owner = THIS_MODULE,
299+
.unregister = omap_fbdev_client_unregister,
300+
.restore = omap_fbdev_client_restore,
301+
.hotplug = omap_fbdev_client_hotplug,
302+
};
303+
304+
void omap_fbdev_setup(struct drm_device *dev)
266305
{
267-
struct drm_fb_helper *helper = dev->fb_helper;
268-
struct drm_framebuffer *fb;
269-
struct drm_gem_object *bo;
270306
struct omap_fbdev *fbdev;
307+
struct drm_fb_helper *helper;
308+
int ret;
271309

272-
DBG();
310+
drm_WARN(dev, !dev->registered, "Device has not been registered.\n");
311+
drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n");
273312

274-
if (!helper)
313+
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
314+
if (!fbdev)
275315
return;
316+
helper = &fbdev->base;
276317

277-
fb = helper->fb;
278-
279-
drm_fb_helper_unregister_info(helper);
318+
drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs);
280319

281-
drm_fb_helper_fini(helper);
320+
ret = drm_client_init(dev, &helper->client, "fbdev", &omap_fbdev_client_funcs);
321+
if (ret)
322+
goto err_drm_client_init;
282323

283-
fbdev = to_omap_fbdev(helper);
324+
INIT_WORK(&fbdev->work, pan_worker);
284325

285-
bo = drm_gem_fb_get_obj(fb, 0);
326+
ret = omap_fbdev_client_hotplug(&helper->client);
327+
if (ret)
328+
drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
286329

287-
/* unpin the GEM object pinned in omap_fbdev_create() */
288-
if (bo)
289-
omap_gem_unpin(bo);
330+
drm_client_register(&helper->client);
290331

291-
/* this will free the backing object */
292-
if (fb)
293-
drm_framebuffer_remove(fb);
332+
return;
294333

334+
err_drm_client_init:
295335
drm_fb_helper_unprepare(helper);
296336
kfree(fbdev);
297337
}

drivers/gpu/drm/omapdrm/omap_fbdev.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,11 @@
1010
#define __OMAPDRM_FBDEV_H__
1111

1212
struct drm_device;
13-
struct drm_fb_helper;
1413

1514
#ifdef CONFIG_DRM_FBDEV_EMULATION
16-
void omap_fbdev_init(struct drm_device *dev);
17-
void omap_fbdev_fini(struct drm_device *dev);
15+
void omap_fbdev_setup(struct drm_device *dev);
1816
#else
19-
static inline void omap_fbdev_init(struct drm_device *dev)
20-
{
21-
}
22-
static inline void omap_fbdev_fini(struct drm_device *dev)
17+
static inline void omap_fbdev_setup(struct drm_device *dev)
2318
{
2419
}
2520
#endif

0 commit comments

Comments
 (0)