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 <bkchan@codeaurora.org>
This commit is contained in:
Benjamin Chan 2016-08-30 22:52:10 -04:00 committed by Gerrit - the friendly Code Review server
parent 9b82a4c589
commit d3d91d38da
2 changed files with 50 additions and 12 deletions

View file

@ -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;
}
}
}

View file

@ -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;
}