diff options
Diffstat (limited to 'drivers/gpu/drm/rockchip/rockchip_drm_vop.c')
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index e1ea50c8fd39..066299894d04 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -272,6 +272,18 @@ static bool has_uv_swapped(uint32_t format) } } +static bool is_fmt_10(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_NV15: + case DRM_FORMAT_NV20: + case DRM_FORMAT_NV30: + return true; + default: + return false; + } +} + static enum vop_data_format vop_convert_format(uint32_t format) { switch (format) { @@ -287,12 +299,15 @@ static enum vop_data_format vop_convert_format(uint32_t format) case DRM_FORMAT_BGR565: return VOP_FMT_RGB565; case DRM_FORMAT_NV12: + case DRM_FORMAT_NV15: case DRM_FORMAT_NV21: return VOP_FMT_YUV420SP; case DRM_FORMAT_NV16: + case DRM_FORMAT_NV20: case DRM_FORMAT_NV61: return VOP_FMT_YUV422SP; case DRM_FORMAT_NV24: + case DRM_FORMAT_NV30: case DRM_FORMAT_NV42: return VOP_FMT_YUV444SP; default: @@ -939,7 +954,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane, dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start; dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); - offset = (src->x1 >> 16) * fb->format->cpp[0]; + if (fb->format->char_per_block[0]) + offset = drm_format_info_min_pitch(fb->format, 0, + src->x1 >> 16); + else + offset = (src->x1 >> 16) * fb->format->cpp[0]; + offset += (src->y1 >> 16) * fb->pitches[0]; dma_addr = rk_obj->dma_addr + offset + fb->offsets[0]; @@ -965,6 +985,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, } VOP_WIN_SET(vop, win, format, format); + VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format)); VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4)); VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); @@ -974,15 +995,16 @@ static void vop_plane_atomic_update(struct drm_plane *plane, (new_state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0); if (is_yuv) { - int hsub = fb->format->hsub; - int vsub = fb->format->vsub; - int bpp = fb->format->cpp[1]; - uv_obj = fb->obj[1]; rk_uv_obj = to_rockchip_obj(uv_obj); - offset = (src->x1 >> 16) * bpp / hsub; - offset += (src->y1 >> 16) * fb->pitches[1] / vsub; + if (fb->format->char_per_block[1]) + offset = drm_format_info_min_pitch(fb->format, 1, + src->x1 >> 16); + else + offset = (src->x1 >> 16) * fb->format->cpp[1]; + offset /= fb->format->hsub; + offset += (src->y1 >> 16) * fb->pitches[1] / fb->format->vsub; dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); |