@@ -449,12 +449,13 @@ static int drm_fb_helper_damage_blit(struct drm_fb_helper *fb_helper,
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);