summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-02-07 17:37:07 +0000
committerJyri Sarha <jsarha@ti.com>2016-02-25 16:39:29 +0200
commit6f206e9d2a965771e99bca4c22dbadac1b58a0e8 (patch)
tree58a645d30eaf0d50c833c3541daeb9eed9960a85 /drivers/gpu/drm/tilcdc
parent3d19306a8240a163f6b02bb46213c277d6d44e08 (diff)
downloadop-kernel-dev-6f206e9d2a965771e99bca4c22dbadac1b58a0e8.zip
op-kernel-dev-6f206e9d2a965771e99bca4c22dbadac1b58a0e8.tar.gz
drm/tilcdc: verify fb pitch
LCDC hardware does not support fb pitch that is different (i.e. larger) than the screen size. The driver currently does no checks for this, and the results of too big pitch are are flickering and lower fps. This issue easily happens when using libdrm's modetest tool with non-32 bpp modes. As modetest always allocated 4 bytes per pixel, it implies a bigger pitch for 16 or 24 bpp modes. This patch adds a check to reject pitches the hardware cannot support. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Signed-off-by: Darren Etheridge <detheridge@ti.com> Signed-off-by: Jyri Sarha <jsarha@ti.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index aaf8989..6485e1c 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -151,6 +151,22 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
kfree(tilcdc_crtc);
}
+static int tilcdc_verify_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb)
+{
+ struct drm_device *dev = crtc->dev;
+ unsigned int depth, bpp;
+
+ drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
+
+ if (fb->pitches[0] != crtc->mode.hdisplay * bpp / 8) {
+ dev_err(dev->dev,
+ "Invalid pitch: fb and crtc widths must be the same");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
@@ -158,6 +174,11 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
+ int r;
+
+ r = tilcdc_verify_fb(crtc, fb);
+ if (r)
+ return r;
if (tilcdc_crtc->event) {
dev_err(dev->dev, "already pending page flip!\n");
@@ -272,6 +293,10 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
if (WARN_ON(!info))
return -EINVAL;
+ ret = tilcdc_verify_fb(crtc, crtc->primary->fb);
+ if (ret)
+ return ret;
+
pm_runtime_get_sync(dev->dev);
/* Configure the Burst Size and fifo threshold of DMA: */
@@ -431,6 +456,12 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
+ int r;
+
+ r = tilcdc_verify_fb(crtc, crtc->primary->fb);
+ if (r)
+ return r;
+
update_scanout(crtc);
return 0;
}
OpenPOWER on IntegriCloud