From c4df6e4277503f0d05e261c3cae0c282fdca4437 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 15 May 2017 11:09:25 +0300 Subject: drm/omap: fix YUV422 rotation with TILER TILER rotation with YUV422 pixelformats does not work at the moment. All other pixel formats work, because the pixelformat's pixel size is equal to tiler unit size (e.g. XR24's pixel size is 32 bits, and the TILER unit size that has to be used is 32 bits). For YUV422 formats this is not the case, as the TILER unit size has to be 32 bits, but the pixel size is 16 bits. The end result is OCP errors and sync losts. This patch adds the code to adjust the variables for YUV422 formats. We could make the code more generic by passing around the pixel format, rotation type, angle and the tiler unit size, which would allow us to do calculations without special case for YUV422. However, this would make the code more complex, and at least for now this is much more easier to handle with these two special cases for YUV422. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/omap_fb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/gpu/drm/omapdrm/omap_fb.c') diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index c7a805702b54..ddf7a457951b 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -184,16 +184,30 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, orient = drm_rotation_to_tiler(state->rotation); + /* + * omap_gem_rotated_paddr() wants the x & y in tiler units. + * Usually tiler unit size is the same as the pixel size, except + * for YUV422 formats, for which the tiler unit size is 32 bits + * and pixel size is 16 bits. + */ + if (fb->format->format == DRM_FORMAT_UYVY || + fb->format->format == DRM_FORMAT_YUYV) { + x /= 2; + w /= 2; + } + /* adjust x,y offset for invert: */ if (orient & MASK_Y_INVERT) y += h - 1; if (orient & MASK_X_INVERT) x += w - 1; + /* Note: x and y are in TILER units, not pixels */ omap_gem_rotated_dma_addr(plane->bo, orient, x, y, &info->paddr); info->rotation_type = OMAP_DSS_ROT_TILER; info->rotation = state->rotation ?: DRM_MODE_ROTATE_0; + /* Note: stride in TILER units, not pixels */ info->screen_width = omap_gem_tiled_stride(plane->bo, orient); } else { switch (state->rotation & DRM_MODE_ROTATE_MASK) { -- cgit v1.2.3