From: Mark Yao Date: Wed, 23 Nov 2016 08:03:51 +0000 (+0800) Subject: drm/rockchip: support 10bit yuv format X-Git-Tag: firefly_0821_release~1222 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=931337c856399c09149ec51d72c40ec37d9024eb drm/rockchip: support 10bit yuv format Change-Id: I7c1f9c3b0a4b8e711d8ce198af9b94bd7639bf17 Signed-off-by: Mark Yao --- diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index 22dd5bcefda9..3f5f8c42fda4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -168,6 +168,8 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, unsigned int width = mode_cmd->width / (i ? hsub : 1); unsigned int height = mode_cmd->height / (i ? vsub : 1); unsigned int min_size; + unsigned int bpp = + drm_format_plane_bpp(mode_cmd->pixel_format, i); obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[i]); @@ -178,9 +180,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, } min_size = (height - 1) * mode_cmd->pitches[i] + - mode_cmd->offsets[i] + - width * drm_format_plane_cpp(mode_cmd->pixel_format, i); - + mode_cmd->offsets[i] + roundup(width * bpp, 8) / 8; if (obj->size < min_size) { drm_gem_object_unreference_unlocked(obj); ret = -EINVAL; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index b5e8126fd719..e45a8b7f33fc 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -328,10 +328,13 @@ 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_NV12_10: return VOP_FMT_YUV420SP; case DRM_FORMAT_NV16: + case DRM_FORMAT_NV16_10: return VOP_FMT_YUV422SP; case DRM_FORMAT_NV24: + case DRM_FORMAT_NV24_10: return VOP_FMT_YUV444SP; default: DRM_ERROR("unsupport format[%08x]\n", format); @@ -343,8 +346,23 @@ static bool is_yuv_support(uint32_t format) { switch (format) { case DRM_FORMAT_NV12: + case DRM_FORMAT_NV12_10: case DRM_FORMAT_NV16: + case DRM_FORMAT_NV16_10: case DRM_FORMAT_NV24: + case DRM_FORMAT_NV24_10: + return true; + default: + return false; + } +} + +static bool is_yuv_10bit(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_NV12_10: + case DRM_FORMAT_NV16_10: + case DRM_FORMAT_NV24_10: return true; default: return false; @@ -863,7 +881,7 @@ static int vop_plane_atomic_check(struct drm_plane *plane, if (is_yuv_support(fb->pixel_format) && ((src->x1 >> 16) % 2)) return -EINVAL; - offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0); + offset = (src->x1 >> 16) * drm_format_plane_bpp(fb->pixel_format, 0) / 8; if (state->rotation & BIT(DRM_REFLECT_Y)) offset += ((src->y2 >> 16) - 1) * fb->pitches[0]; else @@ -874,9 +892,9 @@ static int vop_plane_atomic_check(struct drm_plane *plane, if (is_yuv_support(fb->pixel_format)) { int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format); int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format); - int bpp = drm_format_plane_cpp(fb->pixel_format, 1); + int bpp = drm_format_plane_bpp(fb->pixel_format, 1); - offset = (src->x1 >> 16) * bpp / hsub; + offset = (src->x1 >> 16) * bpp / hsub / 8; offset += (src->y1 >> 16) * fb->pitches[1] / vsub; dma_addr = rockchip_fb_get_dma_addr(fb, 1); @@ -970,6 +988,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2); VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst); } + VOP_WIN_SET(vop, win, fmt_10, is_yuv_10bit(fb->pixel_format)); scl_vop_cal_scl_fac(vop, win, actual_w, actual_h, drm_rect_width(dest), drm_rect_height(dest), diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 349338ed01cd..85a3bc67d2b6 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -212,6 +212,7 @@ struct vop_win_phy { struct vop_reg gate; struct vop_reg enable; struct vop_reg format; + struct vop_reg fmt_10; struct vop_reg xmirror; struct vop_reg ymirror; struct vop_reg rb_swap; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 85fc43d45e07..edf4454441da 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -53,6 +53,9 @@ static const uint32_t formats_win_full[] = { DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV24, + DRM_FORMAT_NV12_10, + DRM_FORMAT_NV16_10, + DRM_FORMAT_NV24_10, }; static const uint32_t formats_win_lite[] = { @@ -104,6 +107,7 @@ static const struct vop_win_phy rk3288_win01_data = { .nformats = ARRAY_SIZE(formats_win_full), .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 4), .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), .xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1), .ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1),