From 5da5175faea66690aa4d8bbd0e49f80c597edf1f Mon Sep 17 00:00:00 2001 From: Mark Yao Date: Thu, 19 Jan 2017 17:14:06 +0800 Subject: [PATCH] drm/rockchip: vop: add display input/output limit Change-Id: If218ca6d2de5c05b6f8ed417cefa437c62c31935 Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 35 ++++++++++++++++++--- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 8 +++++ drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 26 +++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index ce906e87e6b9..7e8079ec2782 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -448,11 +448,6 @@ static void scl_vop_cal_scl_fac(struct vop *vop, struct vop_win *win, if (!win->phy->scl) return; - if (dst_w > 3840) { - DRM_ERROR("Maximum destination width (3840) exceeded\n"); - return; - } - if (!win->phy->scl->ext) { VOP_SCL_SET(vop, win, scale_yrgb_x, scl_cal_scale2(src_w, dst_w)); @@ -902,6 +897,8 @@ static int vop_plane_atomic_check(struct drm_plane *plane, struct vop_win *win = to_vop_win(plane); struct vop_plane_state *vop_plane_state = to_vop_plane_state(state); struct drm_crtc_state *crtc_state; + const struct vop_data *vop_data; + struct vop *vop; bool visible; int ret; struct drm_rect *dest = &vop_plane_state->dest; @@ -954,6 +951,29 @@ static int vop_plane_atomic_check(struct drm_plane *plane, if (vop_plane_state->format < 0) return vop_plane_state->format; + vop = to_vop(crtc); + vop_data = vop->data; + + if (drm_rect_width(src) >> 16 > vop_data->max_input_fb.width || + drm_rect_height(src) >> 16 > vop_data->max_input_fb.height) { + DRM_ERROR("Invalid source: %dx%d. max input: %dx%d\n", + drm_rect_width(src) >> 16, + drm_rect_height(src) >> 16, + vop_data->max_input_fb.width, + vop_data->max_input_fb.height); + return -EINVAL; + } + + if (drm_rect_width(dest) >> 16 > vop_data->max_input_fb.width || + drm_rect_height(dest) >> 16 > vop_data->max_input_fb.height) { + DRM_ERROR("Invalid destination: %dx%d. max output: %dx%d\n", + drm_rect_width(dest), + drm_rect_height(dest), + vop_data->max_output_fb.width, + vop_data->max_output_fb.height); + return -EINVAL; + } + /* * Src.x1 can be odd when do clip, but yuv plane start point * need align with 2 pixel. @@ -1396,6 +1416,11 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode) { struct vop *vop = to_vop(crtc); + const struct vop_data *vop_data = vop->data; + + if (mode->hdisplay > vop_data->max_disably_output.width || + mode->vdisplay > vop_data->max_disably_output.height) + return false; adjusted_mode->clock = clk_round_rate(vop->dclk, mode->clock * 1000) / 1000; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index de9685093aca..14174bc3d97a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -248,6 +248,11 @@ struct vop_win_data { #define VOP_FEATURE_OUTPUT_10BIT BIT(0) #define VOP_FEATURE_AFBDC BIT(1) +struct vop_rect { + int width; + int height; +}; + struct vop_data { const struct vop_reg_data *init_table; unsigned int table_size; @@ -257,6 +262,9 @@ struct vop_data { const struct vop_csc_table *csc_table; unsigned int win_size; uint32_t version; + struct vop_rect max_input_fb; + struct vop_rect max_output_fb; + struct vop_rect max_disably_output; u64 feature; }; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index e64fbed9b494..11e950891114 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -266,6 +266,14 @@ static const struct vop_intr rk3288_vop_intr = { static const struct vop_data rk3288_vop = { .version = VOP_VERSION(3, 1), .feature = VOP_FEATURE_OUTPUT_10BIT, + .max_input_fb = { 4096, 8192}, + .max_output_fb = { 3840, 2160}, + /* + * TODO: rk3288 have two vop, big one support 3840x2160, + * little one only support 2560x1600. + * Now force use 3840x2160. + */ + .max_disably_output = { 3840, 2160}, .intr = &rk3288_vop_intr, .ctrl = &rk3288_ctrl_data, .win = rk3288_vop_win_data, @@ -369,6 +377,9 @@ static const struct vop_win_data rk3368_vop_win_data[] = { static const struct vop_data rk3368_vop = { .version = VOP_VERSION(3, 2), .feature = VOP_FEATURE_OUTPUT_10BIT, + .max_input_fb = { 4096, 8192}, + .max_output_fb = { 4096, 2160}, + .max_disably_output = { 4096, 2160}, .intr = &rk3368_vop_intr, .ctrl = &rk3288_ctrl_data, .win = rk3368_vop_win_data, @@ -388,6 +399,9 @@ static const struct vop_intr rk3366_vop_intr = { static const struct vop_data rk3366_vop = { .version = VOP_VERSION(3, 4), .feature = VOP_FEATURE_OUTPUT_10BIT, + .max_input_fb = { 4096, 8192}, + .max_output_fb = { 4096, 2160}, + .max_disably_output = { 4096, 2160}, .intr = &rk3366_vop_intr, .ctrl = &rk3288_ctrl_data, .win = rk3368_vop_win_data, @@ -497,6 +511,9 @@ static const struct vop_data rk3399_vop_big = { .version = VOP_VERSION(3, 5), .csc_table = &rk3399_csc_table, .feature = VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_AFBDC, + .max_input_fb = { 4096, 8192}, + .max_output_fb = { 4096, 2160}, + .max_disably_output = { 4096, 2160}, .intr = &rk3366_vop_intr, .ctrl = &rk3288_ctrl_data, .win = rk3399_vop_win_data, @@ -518,6 +535,9 @@ static const struct vop_win_data rk3399_vop_lit_win_data[] = { static const struct vop_data rk3399_vop_lit = { .version = VOP_VERSION(3, 6), .csc_table = &rk3399_csc_table, + .max_input_fb = { 4096, 8192}, + .max_output_fb = { 2560, 1600}, + .max_disably_output = { 2560, 1600}, .intr = &rk3366_vop_intr, .ctrl = &rk3288_ctrl_data, .win = rk3399_vop_lit_win_data, @@ -527,6 +547,9 @@ static const struct vop_data rk3399_vop_lit = { static const struct vop_data rk322x_vop = { .version = VOP_VERSION(3, 7), .feature = VOP_FEATURE_OUTPUT_10BIT, + .max_input_fb = { 4096, 8192}, + .max_output_fb = { 4096, 2160}, + .max_disably_output = { 4096, 2160}, .intr = &rk3366_vop_intr, .ctrl = &rk3288_ctrl_data, .win = rk3368_vop_win_data, @@ -611,6 +634,9 @@ static const struct vop_ctrl rk3036_ctrl_data = { static const struct vop_data rk3036_vop = { .version = VOP_VERSION(2, 2), + .max_input_fb = { 1920, 1080}, + .max_output_fb = { 1920, 1080}, + .max_disably_output = { 1920, 1080}, .ctrl = &rk3036_ctrl_data, .intr = &rk3036_intr, .win = rk3036_vop_win_data, -- 2.34.1