From d3d91d38daea55b6ea86cd15621367a0f6866ea8 Mon Sep 17 00:00:00 2001 From: Benjamin Chan Date: Tue, 30 Aug 2016 22:52:10 -0400 Subject: [PATCH] msm: mdss: Correct DSC panel dimension when dest-scaler enabled When destination scaler is enabled, DSC panel dimension should base on the scaler destination dimension, and not using the mixer output dimension. Also move DSC dimension validation after destination scaler setting applied successfully. CRs-Fixed: 1065274 Change-Id: Iee328c847ffc16154e78682515454be6a61b35b4 Signed-off-by: Benjamin Chan --- drivers/video/fbdev/msm/mdss_mdp_ctl.c | 25 +++++++++++++--- drivers/video/fbdev/msm/mdss_mdp_layer.c | 37 +++++++++++++++++++----- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index abc048866313..c6546cd96b53 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -2925,6 +2925,7 @@ static u32 __dsc_get_common_mode(struct mdss_mdp_ctl *ctl, bool mux_3d) static void __dsc_get_pic_dim(struct mdss_mdp_mixer *mixer_l, struct mdss_mdp_mixer *mixer_r, u32 *pic_w, u32 *pic_h) { + struct mdss_data_type *mdata = NULL; bool valid_l = mixer_l && mixer_l->valid_roi; bool valid_r = mixer_r && mixer_r->valid_roi; @@ -2932,13 +2933,29 @@ static void __dsc_get_pic_dim(struct mdss_mdp_mixer *mixer_l, *pic_h = 0; if (valid_l) { - *pic_w = mixer_l->roi.w; - *pic_h = mixer_l->roi.h; + mdata = mixer_l->ctl->mdata; + if (test_bit(MDSS_CAPS_DEST_SCALER, mdata->mdss_caps_map) && + mixer_l->ds && + (mixer_l->ds->flags & DS_ENABLE)) { + *pic_w = mixer_l->ds->scaler.dst_width; + *pic_h = mixer_l->ds->scaler.dst_height; + } else { + *pic_w = mixer_l->roi.w; + *pic_h = mixer_l->roi.h; + } } if (valid_r) { - *pic_w += mixer_r->roi.w; - *pic_h = mixer_r->roi.h; + mdata = mixer_r->ctl->mdata; + if (test_bit(MDSS_CAPS_DEST_SCALER, mdata->mdss_caps_map) && + mixer_r->ds && + (mixer_r->ds->flags & DS_ENABLE)) { + *pic_w += mixer_r->ds->scaler.dst_width; + *pic_h = mixer_r->ds->scaler.dst_height; + } else { + *pic_w += mixer_r->roi.w; + *pic_h = mixer_r->roi.h; + } } } diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c index d3a836ed2519..91d4332700b6 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_layer.c +++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c @@ -137,10 +137,7 @@ static int mdss_mdp_destination_scaler_pre_validate(struct mdss_mdp_ctl *ctl, if ((ds_data->lm_width > get_panel_xres(pinfo)) || (ds_data->lm_height > get_panel_yres(pinfo)) || (ds_data->lm_width == 0) || - (ds_data->lm_height == 0) || - (is_dsc_compression(pinfo) && - !is_lm_configs_dsc_compatible(pinfo, - ds_data->lm_width, ds_data->lm_height))) { + (ds_data->lm_height == 0)) { pr_err("Invalid left LM {%d,%d} setting\n", ds_data->lm_width, ds_data->lm_height); return -EINVAL; @@ -167,10 +164,7 @@ static int mdss_mdp_destination_scaler_pre_validate(struct mdss_mdp_ctl *ctl, if ((ds_data->lm_width > get_panel_xres(pinfo)) || (ds_data->lm_height > get_panel_yres(pinfo)) || (ds_data->lm_width == 0) || - (ds_data->lm_height == 0) || - (is_dsc_compression(pinfo) && - !is_lm_configs_dsc_compatible(pinfo, - ds_data->lm_width, ds_data->lm_height))) { + (ds_data->lm_height == 0)) { pr_err("Invalid right LM {%d,%d} setting\n", ds_data->lm_width, ds_data->lm_height); return -EINVAL; @@ -217,6 +211,8 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd, struct mdss_mdp_ctl *ctl; struct mdss_mdp_destination_scaler *ds_left = NULL; struct mdss_mdp_destination_scaler *ds_right = NULL; + struct mdss_panel_info *pinfo; + u32 scaler_width, scaler_height; if (ds_data) { mdata = mfd_to_mdata(mfd); @@ -293,6 +289,31 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd, if (ds_right) pr_debug("DS_RIGHT: flags=0x%X\n", ds_right->flags); + /* + * When DSC is enabled, make sure the scaler output dimension is + * correctly setup. + */ + pinfo = &ctl->panel_data->panel_info; + scaler_width = 0; + scaler_height = 0; + if (ds_left && ds_left->flags) { + scaler_width += ds_left->scaler.dst_width; + scaler_height = ds_left->scaler.dst_height; + } + if (ds_right && ds_right->flags) { + scaler_width += ds_right->scaler.dst_width; + scaler_height = ds_right->scaler.dst_height; + } + pr_debug("DS output dimension: %dx%d\n", scaler_width, scaler_height); + + if (ds_data[0].flags && (is_dsc_compression(pinfo) && + !is_lm_configs_dsc_compatible(pinfo, + scaler_width, scaler_height))) { + pr_err("Invalid Dest-scaler output width/height: %d/%d\n", + scaler_width, scaler_height); + ret = -EINVAL; + } + return ret; }