Commit f458579e authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/fb-helper: Instanciate shadow FB if configured in device's mode_config

Generic framebuffer emulation uses a shadow buffer for framebuffers with
dirty() function. If drivers want to use the shadow FB without such a
function, they can now set prefer_shadow or prefer_shadow_fbdev in their
mode_config structures. The former flag is exported to userspace, the
latter flag is fbdev-only.

v3:
	* only schedule dirty worker if fbdev uses shadow fb
	* test shadow fb settings with boolean operators
	* use bool for struct drm_mode_config.prefer_shadow_fbdev
	* fix documentation comments
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Tested-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Link: https://patchwork.freedesktop.org/patch/315834/
parent cf1ca9ae
...@@ -421,7 +421,9 @@ static void drm_fb_helper_dirty_work(struct work_struct *work) ...@@ -421,7 +421,9 @@ static void drm_fb_helper_dirty_work(struct work_struct *work)
return; return;
drm_fb_helper_dirty_blit_real(helper, &clip_copy); drm_fb_helper_dirty_blit_real(helper, &clip_copy);
} }
helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1); if (helper->fb->funcs->dirty)
helper->fb->funcs->dirty(helper->fb, NULL, 0, 0,
&clip_copy, 1);
if (helper->buffer) if (helper->buffer)
drm_client_buffer_vunmap(helper->buffer); drm_client_buffer_vunmap(helper->buffer);
...@@ -613,6 +615,16 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) ...@@ -613,6 +615,16 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
} }
EXPORT_SYMBOL(drm_fb_helper_unlink_fbi); EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
struct drm_framebuffer *fb = fb_helper->fb;
return dev->mode_config.prefer_shadow_fbdev ||
dev->mode_config.prefer_shadow ||
fb->funcs->dirty;
}
static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y, static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y,
u32 width, u32 height) u32 width, u32 height)
{ {
...@@ -620,7 +632,7 @@ static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y, ...@@ -620,7 +632,7 @@ static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y,
struct drm_clip_rect *clip = &helper->dirty_clip; struct drm_clip_rect *clip = &helper->dirty_clip;
unsigned long flags; unsigned long flags;
if (!helper->fb->funcs->dirty) if (!drm_fbdev_use_shadow_fb(helper))
return; return;
spin_lock_irqsave(&helper->dirty_lock, flags); spin_lock_irqsave(&helper->dirty_lock, flags);
...@@ -2213,7 +2225,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, ...@@ -2213,7 +2225,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
drm_fb_helper_fill_info(fbi, fb_helper, sizes); drm_fb_helper_fill_info(fbi, fb_helper, sizes);
if (fb->funcs->dirty) { if (drm_fbdev_use_shadow_fb(fb_helper)) {
struct fb_ops *fbops; struct fb_ops *fbops;
void *shadow; void *shadow;
......
...@@ -852,6 +852,13 @@ struct drm_mode_config { ...@@ -852,6 +852,13 @@ struct drm_mode_config {
/* dumb ioctl parameters */ /* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow; uint32_t preferred_depth, prefer_shadow;
/**
* @prefer_shadow_fbdev:
*
* Hint to framebuffer emulation to prefer shadow-fb rendering.
*/
bool prefer_shadow_fbdev;
/** /**
* @quirk_addfb_prefer_xbgr_30bpp: * @quirk_addfb_prefer_xbgr_30bpp:
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment