diff options
Diffstat (limited to 'drivers/gpu/drm/tiny/simpledrm.c')
-rw-r--r-- | drivers/gpu/drm/tiny/simpledrm.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index ea5b3239a659..18489779fb8a 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -470,40 +470,45 @@ static const uint64_t simpledrm_primary_plane_format_modifiers[] = { }; static void simpledrm_primary_plane_helper_atomic_update(struct drm_plane *plane, - struct drm_atomic_state *old_state) + struct drm_atomic_state *state) { - struct drm_plane_state *plane_state = plane->state; - struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(old_state, plane); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_framebuffer *fb = plane_state->fb; struct drm_device *dev = plane->dev; struct simpledrm_device *sdev = simpledrm_device_of_dev(dev); - struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base); - struct drm_rect src_clip, dst_clip; - int idx; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect damage; + int ret, idx; - if (!fb) + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) return; - if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &src_clip)) - return; + if (!drm_dev_enter(dev, &idx)) + goto out_drm_gem_fb_end_cpu_access; - dst_clip = plane_state->dst; - if (!drm_rect_intersect(&dst_clip, &src_clip)) - return; + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + struct iosys_map dst = IOSYS_MAP_INIT_VADDR(sdev->screen_base); + struct drm_rect dst_clip = plane_state->dst; - if (!drm_dev_enter(dev, &idx)) - return; + if (!drm_rect_intersect(&dst_clip, &damage)) + continue; - iosys_map_incr(&dst, drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip)); - drm_fb_blit(&dst, &sdev->pitch, sdev->format->format, shadow_plane_state->data, fb, - &src_clip); + iosys_map_incr(&dst, drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip)); + drm_fb_blit(&dst, &sdev->pitch, sdev->format->format, shadow_plane_state->data, fb, + &damage); + } drm_dev_exit(idx); +out_drm_gem_fb_end_cpu_access: + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); } static void simpledrm_primary_plane_helper_atomic_disable(struct drm_plane *plane, - struct drm_atomic_state *old_state) + struct drm_atomic_state *state) { struct drm_device *dev = plane->dev; struct simpledrm_device *sdev = simpledrm_device_of_dev(dev); @@ -687,8 +692,11 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, drm_err(dev, "no simplefb configuration found\n"); return ERR_PTR(-ENODEV); } - if (!stride) - stride = DIV_ROUND_UP(drm_format_info_bpp(format, 0) * width, 8); + if (!stride) { + stride = drm_format_info_min_pitch(format, 0, width); + if (drm_WARN_ON(dev, !stride)) + return ERR_PTR(-EINVAL); + } sdev->mode = simpledrm_mode(width, height); sdev->format = format; |