From 7377b0c45405efff818d96c2f508d4b80f3d94d3 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 19 Aug 2020 14:46:20 +0800 Subject: [PATCH] msm: venc: reject unsupported sessions with VPSS enabled Reject any sessions with non-multiple 8 of resolution and rotation/flip is enabled. Change-Id: Ifac0cc8884461fe8d2502e92481643d9443aa527 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 69 +++++++++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + msm/vidc/msm_vidc_internal.h | 7 ++++ msm/vidc/msm_vidc_platform.c | 18 +++++++++ msm/vidc/msm_vidc_res_parse.c | 2 + msm/vidc/msm_vidc_resources.h | 2 + 6 files changed, 99 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index faea1871f65f..5277fb34ca6a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4039,6 +4039,9 @@ int msm_venc_check_dynamic_flip_constraints(struct msm_vidc_inst *inst) /* Reject dynamic flip with scalar enabled */ s_vpr_e(inst->sid, "Unsupported dynamic flip with scalar\n"); rc = -EINVAL; + } else if (handle_vpss_restrictions(inst)) { + s_vpr_e(inst->sid, "Unsupported resolution for dynamic flip\n"); + rc = -EINVAL; } return rc; @@ -4825,6 +4828,69 @@ int check_blur_restrictions(struct msm_vidc_inst *inst) return 0; } +int handle_vpss_restrictions(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *rotation = NULL; + struct v4l2_ctrl *hflip = NULL; + struct v4l2_ctrl *vflip = NULL; + struct v4l2_format *f; + struct msm_vidc_vpss_capability *vpss_caps; + u32 vpss_caps_count; + bool rotation_flip_enable = false; + u32 i,input_height, input_width; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + + vpss_caps = inst->core->resources.vpss_caps; + vpss_caps_count = inst->core->resources.vpss_caps_count; + + /* check customer specified VPSS resolutions */ + if (vpss_caps) { + for (i = 0; i < vpss_caps_count; i++) { + if (input_width == vpss_caps[i].width && + input_height == vpss_caps[i].height) { + s_vpr_h(inst->sid, + "supported resolution found for VPSS, width = %d, height = %d\n", + input_width, input_height); + return 0; + } + } + } + + /* check rotation and flip contraint for VPSS + * any rotation or flip sessions with non-multiple of 8 + * resolution is rejected. + */ + rotation = get_ctrl(inst, V4L2_CID_ROTATE); + hflip = get_ctrl(inst, V4L2_CID_HFLIP); + vflip = get_ctrl(inst, V4L2_CID_VFLIP); + if (rotation->val != 0 || + hflip->val != V4L2_MPEG_MSM_VIDC_DISABLE || + vflip->val != V4L2_MPEG_MSM_VIDC_DISABLE) + rotation_flip_enable = true; + + if (rotation_flip_enable) { + if ((input_width & 7) != 0) { + s_vpr_e(inst->sid, "Unsupported width = %d for VPSS\n", + input_width); + return -ENOTSUPP; + } + if ((input_height & 7) != 0) { + s_vpr_e(inst->sid, "Unsupported height = %d for VPSS\n", + input_height); + return -ENOTSUPP; + } + } + return 0; +} + int msm_venc_set_properties(struct msm_vidc_inst *inst) { int rc = 0; @@ -4836,6 +4902,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = handle_all_intra_restrictions(inst); + if (rc) + goto exit; + rc = handle_vpss_restrictions(inst); if (rc) goto exit; rc = msm_venc_set_frame_size(inst); diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index 4f5689fe50d1..e172bf748336 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -49,4 +49,5 @@ int check_blur_restrictions(struct msm_vidc_inst *inst); int msm_venc_set_frame_quality(struct msm_vidc_inst *inst); int msm_venc_set_image_grid(struct msm_vidc_inst *inst); int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable); +int handle_vpss_restrictions(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 26e3239351b3..b54f981e6017 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -229,6 +229,11 @@ struct msm_vidc_codec_capability { u32 default_value; }; +struct msm_vidc_vpss_capability { + u32 width; + u32 height; +}; + struct msm_vidc_codec { enum hal_domain domain; enum hal_video_codec codec; @@ -296,6 +301,8 @@ struct msm_vidc_platform_data { uint32_t codecs_count; struct msm_vidc_codec_capability *codec_caps; uint32_t codec_caps_count; + struct msm_vidc_vpss_capability *vpss_caps; + uint32_t vpss_caps_count; struct msm_vidc_csc_coeff csc_data; struct msm_vidc_efuse_data *efuse_data; unsigned int efuse_data_length; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 5165cc5fec50..710944785d82 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -747,6 +747,16 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; +/* Generally Iris2 VPSS only support 8 multiple encoding if + * rotation/flip is enabled, however customer can require specific + * resolution supports and expand capabilities here. + */ +static struct msm_vidc_vpss_capability vpss_capabilities[] = { + /* {supported width, supported height,} */ + {3840, 1644}, + {1644, 3840}, +}; + /* * Custom conversion coefficients for resolution: 176x144 negative * coeffs are converted to s4.9 format @@ -1498,6 +1508,8 @@ static struct msm_vidc_platform_data lahaina_data = { .codecs_count = ARRAY_SIZE(default_codecs), .codec_caps = lahaina_capabilities, .codec_caps_count = ARRAY_SIZE(lahaina_capabilities), + .vpss_caps = vpss_capabilities, + .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), }; static struct msm_vidc_platform_data bengal_data = { @@ -1520,6 +1532,8 @@ static struct msm_vidc_platform_data bengal_data = { .codecs_count = ARRAY_SIZE(bengal_codecs), .codec_caps = bengal_capabilities_v0, .codec_caps_count = ARRAY_SIZE(bengal_capabilities_v0), + .vpss_caps = NULL, + .vpss_caps_count = 0, }; static struct msm_vidc_platform_data shima_data = { @@ -1542,6 +1556,8 @@ static struct msm_vidc_platform_data shima_data = { .codecs_count = ARRAY_SIZE(shima_codecs), .codec_caps = shima_capabilities_v0, .codec_caps_count = ARRAY_SIZE(shima_capabilities_v0), + .vpss_caps = vpss_capabilities, + .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), }; static struct msm_vidc_platform_data holi_data = { @@ -1564,6 +1580,8 @@ static struct msm_vidc_platform_data holi_data = { .codecs_count = ARRAY_SIZE(holi_codecs), .codec_caps = holi_capabilities, .codec_caps_count = ARRAY_SIZE(holi_capabilities), + .vpss_caps = NULL, + .vpss_caps_count = 0, }; static const struct of_device_id msm_vidc_dt_device[] = { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index b730636ef31e..1aa93ac5bb75 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -733,6 +733,8 @@ int read_platform_resources_from_drv_data( res->codec_data = platform_data->codec_data; res->allowed_clks_tbl = platform_data->clock_data; res->allowed_clks_tbl_size = platform_data->clock_data_length; + res->vpss_caps = platform_data->vpss_caps; + res->vpss_caps_count = platform_data->vpss_caps_count; res->sku_version = platform_data->sku_version; res->mem_limit_tbl = memory_limit_tbl_mbytes; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 5add5ec54373..7a2916cd62ac 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -194,6 +194,8 @@ struct msm_vidc_platform_resources { uint32_t codecs_count; struct msm_vidc_codec_capability *codec_caps; uint32_t codec_caps_count; + struct msm_vidc_vpss_capability *vpss_caps; + uint32_t vpss_caps_count; struct msm_vidc_csc_coeff *csc_coeff_data; struct msm_vidc_mem_cdsp mem_cdsp; uint32_t vpu_ver;