drm/omap: handle incompatible buffer stride and pixel size
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 25 Sep 2014 19:24:28 +0000 (19:24 +0000)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Tue, 24 Mar 2015 11:50:55 +0000 (13:50 +0200)
omapdrm doesn't check if the pitch of the framebuffer and the color
format's bits-per-pixel are compatible. omapdss requires that the stride
of a buffer is an integer number of pixels

For example, when using modetest with a display that has x resolution of
1280, and using packed 24 RGB mode (3 bytes per pixel), modetest
allocates a buffer with a byte stride of 4 * 1280 = 5120. But 5120 / 3 =
1706.666... pixels, which causes wrong colors and a tilt on the screen.

Add a check into omapdrm to return an error if the user tries to use
such a combination.

Note: this is not a HW requirement at least for non-rotation use cases,
but a SW driver requirement. In the future we should study if also
rotation use cases are fine with any stride size, and if so, change the
driver to allow these strides.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/gpu/drm/omapdrm/omap_fb.c

index 3c6488e897888f94fa3135d92d885c48704bc723..b2c1a29cc12b4601885da18f4f0cf230f7557f69 100644 (file)
@@ -423,6 +423,14 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
                        goto fail;
                }
 
+               if (pitch % format->planes[i].stride_bpp != 0) {
+                       dev_err(dev->dev,
+                               "buffer pitch (%d bytes) is not a multiple of pixel size (%d bytes)\n",
+                               pitch, format->planes[i].stride_bpp);
+                       ret = -EINVAL;
+                       goto fail;
+               }
+
                size = pitch * mode_cmd->height / format->planes[i].sub_y;
 
                if (size > (omap_gem_mmap_size(bos[i]) - mode_cmd->offsets[i])) {