diff options
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 90 |
1 files changed, 60 insertions, 30 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index c7c0c0a8532b..3dfda1e3830b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -449,12 +449,13 @@ out: static void drm_fb_helper_damage_work(struct work_struct *work) { struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, damage_work); + struct drm_device *dev = helper->dev; struct drm_clip_rect *clip = &helper->damage_clip; struct drm_clip_rect clip_copy; unsigned long flags; int ret; - if (!helper->funcs->fb_dirty) + if (drm_WARN_ON_ONCE(dev, !helper->funcs->fb_dirty)) return; spin_lock_irqsave(&helper->damage_lock, flags); @@ -659,16 +660,12 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_fini); -static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y, +static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y, u32 width, u32 height) { - struct drm_fb_helper *helper = info->par; struct drm_clip_rect *clip = &helper->damage_clip; unsigned long flags; - if (!helper->funcs->fb_dirty) - return; - spin_lock_irqsave(&helper->damage_lock, flags); clip->x1 = min_t(u32, clip->x1, x); clip->y1 = min_t(u32, clip->y1, y); @@ -718,6 +715,7 @@ static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, */ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist) { + struct drm_fb_helper *helper = info->par; unsigned long start, end, min_off, max_off; struct fb_deferred_io_pageref *pageref; struct drm_rect damage_area; @@ -733,17 +731,19 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli if (min_off >= max_off) return; - /* - * As we can only track pages, we might reach beyond the end - * of the screen and account for non-existing scanlines. Hence, - * keep the covered memory area within the screen buffer. - */ - max_off = min(max_off, info->screen_size); + if (helper->funcs->fb_dirty) { + /* + * As we can only track pages, we might reach beyond the end + * of the screen and account for non-existing scanlines. Hence, + * keep the covered memory area within the screen buffer. + */ + max_off = min(max_off, info->screen_size); - drm_fb_helper_memory_range_to_clip(info, min_off, max_off - min_off, &damage_area); - drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + drm_fb_helper_memory_range_to_clip(info, min_off, max_off - min_off, &damage_area); + drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + } } EXPORT_SYMBOL(drm_fb_helper_deferred_io); @@ -877,6 +877,7 @@ static ssize_t drm_fb_helper_write_screen_buffer(struct fb_info *info, const cha ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { + struct drm_fb_helper *helper = info->par; loff_t pos = *ppos; ssize_t ret; struct drm_rect damage_area; @@ -885,10 +886,12 @@ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, if (ret <= 0) return ret; - drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); - drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + if (helper->funcs->fb_dirty) { + drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); + drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + } return ret; } @@ -904,8 +907,12 @@ EXPORT_SYMBOL(drm_fb_helper_sys_write); void drm_fb_helper_sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { + struct drm_fb_helper *helper = info->par; + sys_fillrect(info, rect); - drm_fb_helper_damage(info, rect->dx, rect->dy, rect->width, rect->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, rect->height); } EXPORT_SYMBOL(drm_fb_helper_sys_fillrect); @@ -919,8 +926,12 @@ EXPORT_SYMBOL(drm_fb_helper_sys_fillrect); void drm_fb_helper_sys_copyarea(struct fb_info *info, const struct fb_copyarea *area) { + struct drm_fb_helper *helper = info->par; + sys_copyarea(info, area); - drm_fb_helper_damage(info, area->dx, area->dy, area->width, area->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, area->dx, area->dy, area->width, area->height); } EXPORT_SYMBOL(drm_fb_helper_sys_copyarea); @@ -934,8 +945,12 @@ EXPORT_SYMBOL(drm_fb_helper_sys_copyarea); void drm_fb_helper_sys_imageblit(struct fb_info *info, const struct fb_image *image) { + struct drm_fb_helper *helper = info->par; + sys_imageblit(info, image); - drm_fb_helper_damage(info, image->dx, image->dy, image->width, image->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, image->dx, image->dy, image->width, image->height); } EXPORT_SYMBOL(drm_fb_helper_sys_imageblit); @@ -1035,6 +1050,7 @@ static ssize_t fb_write_screen_base(struct fb_info *info, const char __user *buf ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { + struct drm_fb_helper *helper = info->par; loff_t pos = *ppos; ssize_t ret; struct drm_rect damage_area; @@ -1043,10 +1059,12 @@ ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, if (ret <= 0) return ret; - drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); - drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + if (helper->funcs->fb_dirty) { + drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); + drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + } return ret; } @@ -1062,8 +1080,12 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_write); void drm_fb_helper_cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { + struct drm_fb_helper *helper = info->par; + cfb_fillrect(info, rect); - drm_fb_helper_damage(info, rect->dx, rect->dy, rect->width, rect->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, rect->height); } EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect); @@ -1077,8 +1099,12 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect); void drm_fb_helper_cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { + struct drm_fb_helper *helper = info->par; + cfb_copyarea(info, area); - drm_fb_helper_damage(info, area->dx, area->dy, area->width, area->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, area->dx, area->dy, area->width, area->height); } EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea); @@ -1092,8 +1118,12 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea); void drm_fb_helper_cfb_imageblit(struct fb_info *info, const struct fb_image *image) { + struct drm_fb_helper *helper = info->par; + cfb_imageblit(info, image); - drm_fb_helper_damage(info, image->dx, image->dy, image->width, image->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, image->dx, image->dy, image->width, image->height); } EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); |