aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tiny/simpledrm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tiny/simpledrm.c')
-rw-r--r--drivers/gpu/drm/tiny/simpledrm.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 481b48bde047..04146da2d1d8 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -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>
@@ -458,7 +459,7 @@ static struct drm_display_mode simpledrm_mode(unsigned int width,
{
struct drm_display_mode mode = { SIMPLEDRM_MODE(width, height) };
- mode.clock = 60 /* Hz */ * mode.hdisplay * mode.vdisplay;
+ mode.clock = mode.hdisplay * mode.vdisplay * 60 / 1000 /* kHz */;
drm_mode_set_name(&mode);
return mode;
@@ -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;