Merge tag 'drm-next-2022-01-07' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / drivers / gpu / drm / tiny / simpledrm.c
index 5a6e898..04146da 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <linux/clk.h>
 #include <linux/of_clk.h>
+#include <linux/minmax.h>
 #include <linux/platform_data/simplefb.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
@@ -570,8 +571,8 @@ static const uint32_t simpledrm_default_formats[] = {
        //DRM_FORMAT_XRGB1555,
        //DRM_FORMAT_ARGB1555,
        DRM_FORMAT_RGB888,
-       //DRM_FORMAT_XRGB2101010,
-       //DRM_FORMAT_ARGB2101010,
+       DRM_FORMAT_XRGB2101010,
+       DRM_FORMAT_ARGB2101010,
 };
 
 static const uint64_t simpledrm_format_modifiers[] = {
@@ -641,16 +642,25 @@ simpledrm_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
        struct drm_framebuffer *fb = plane_state->fb;
        void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */
        struct drm_device *dev = &sdev->dev;
+       void __iomem *dst = sdev->screen_base;
+       struct drm_rect src_clip, dst_clip;
        int idx;
 
        if (!fb)
                return;
 
+       drm_rect_fp_to_int(&src_clip, &plane_state->src);
+
+       dst_clip = plane_state->dst;
+       if (!drm_rect_intersect(&dst_clip, &src_clip))
+               return;
+
        if (!drm_dev_enter(dev, &idx))
                return;
 
-       drm_fb_blit_dstclip(sdev->screen_base, sdev->pitch,
-                           sdev->format->format, vmap, fb);
+       dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip);
+       drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip);
+
        drm_dev_exit(idx);
 }
 
@@ -680,20 +690,25 @@ simpledrm_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
        void *vmap = shadow_plane_state->data[0].vaddr; /* TODO: Use mapping abstraction */
        struct drm_framebuffer *fb = plane_state->fb;
        struct drm_device *dev = &sdev->dev;
-       struct drm_rect clip;
+       void __iomem *dst = sdev->screen_base;
+       struct drm_rect src_clip, dst_clip;
        int idx;
 
        if (!fb)
                return;
 
-       if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &clip))
+       if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &src_clip))
+               return;
+
+       dst_clip = plane_state->dst;
+       if (!drm_rect_intersect(&dst_clip, &src_clip))
                return;
 
        if (!drm_dev_enter(dev, &idx))
                return;
 
-       drm_fb_blit_rect_dstclip(sdev->screen_base, sdev->pitch,
-                                sdev->format->format, vmap, fb, &clip);
+       dst += drm_fb_clip_offset(sdev->pitch, sdev->format, &dst_clip);
+       drm_fb_blit_toio(dst, sdev->pitch, sdev->format->format, vmap, fb, &src_clip);
 
        drm_dev_exit(idx);
 }
@@ -758,6 +773,7 @@ static int simpledrm_device_init_modeset(struct simpledrm_device *sdev)
        struct drm_display_mode *mode = &sdev->mode;
        struct drm_connector *connector = &sdev->connector;
        struct drm_simple_display_pipe *pipe = &sdev->pipe;
+       unsigned long max_width, max_height;
        const uint32_t *formats;
        size_t nformats;
        int ret;
@@ -766,10 +782,13 @@ static int simpledrm_device_init_modeset(struct simpledrm_device *sdev)
        if (ret)
                return ret;
 
+       max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH);
+       max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT);
+
        dev->mode_config.min_width = mode->hdisplay;
-       dev->mode_config.max_width = mode->hdisplay;
+       dev->mode_config.max_width = max_width;
        dev->mode_config.min_height = mode->vdisplay;
-       dev->mode_config.max_height = mode->vdisplay;
+       dev->mode_config.max_height = max_height;
        dev->mode_config.prefer_shadow_fbdev = true;
        dev->mode_config.preferred_depth = sdev->format->cpp[0] * 8;
        dev->mode_config.funcs = &simpledrm_mode_config_funcs;
@@ -788,6 +807,8 @@ static int simpledrm_device_init_modeset(struct simpledrm_device *sdev)
        if (ret)
                return ret;
 
+       drm_plane_enable_fb_damage_clips(&pipe->plane);
+
        drm_mode_config_reset(dev);
 
        return 0;