Loading drivers/video/msm/mdss/mdss_mdp.h +4 −2 Original line number Diff line number Diff line Loading @@ -1088,7 +1088,7 @@ int mdss_mdp_pp_init(struct device *dev); void mdss_mdp_pp_term(struct device *dev); int mdss_mdp_pp_overlay_init(struct msm_fb_data_type *mfd); int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 mixer_num); int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd); int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl); int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl); Loading @@ -1103,6 +1103,8 @@ int mdss_mdp_smp_setup(struct mdss_data_type *mdata, u32 cnt, u32 size); void mdss_hw_init(struct mdss_data_type *mdata); int mdss_mdp_mfd_valid_dspp(struct msm_fb_data_type *mfd); int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback); int mdss_mdp_pa_v2_config(struct mdp_pa_v2_cfg_data *config, u32 *copyback); int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *cfg_ptr, u32 *copyback); Loading drivers/video/msm/mdss/mdss_mdp_ctl.c +3 −10 Original line number Diff line number Diff line Loading @@ -3023,9 +3023,7 @@ static void mdss_mdp_ctl_restore_sub(struct mdss_mdp_ctl *ctl) MDSS_MDP_REG_DISP_INTF_SEL); if (ctl->mixer_left) { mdss_mdp_pp_resume(ctl, ctl->mixer_left->num); if (ctl->mixer_right) mdss_mdp_pp_resume(ctl, ctl->mixer_right->num); mdss_mdp_pp_resume(ctl->mfd); if (ctl->panel_data->panel_info.compression_mode == COMPRESSION_DSC) { Loading Loading @@ -3113,12 +3111,6 @@ static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff) mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(i), 0); } mixer = ctl->mixer_left; if (mixer) { mdss_mdp_pp_resume(ctl, mixer->num); mixer->params_changed++; } temp = readl_relaxed(ctl->mdata->mdp_base + MDSS_MDP_REG_DISP_INTF_SEL); temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8)); Loading @@ -3128,7 +3120,9 @@ static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff) writel_relaxed(temp, ctl->mdata->mdp_base + MDSS_MDP_REG_DISP_INTF_SEL); mixer = ctl->mixer_left; if (mixer) { mixer->params_changed++; outsize = (mixer->height << 16) | mixer->width; mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, outsize); Loading Loading @@ -3203,7 +3197,6 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff) struct mdss_mdp_mixer *mixer = ctl->mixer_right; u32 out; mdss_mdp_pp_resume(ctl, mixer->num); mixer->params_changed++; out = (mixer->height << 16) | mixer->width; mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, out); Loading drivers/video/msm/mdss/mdss_mdp_overlay.c +26 −6 Original line number Diff line number Diff line Loading @@ -1362,6 +1362,14 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd) } } /* Restore any previously configured PP features by resetting the dirty * bits for enabled features. The dirty bits will be consumed during the * first display commit when the PP hardware blocks are updated */ rc = mdss_mdp_pp_resume(mfd); if (rc && (rc != -EPERM) && (rc != -ENODEV)) pr_err("PP resume err %d\n", rc); /* * Increment the overlay active count prior to calling ctl_start. * This is needed to ensure that if idle power collapse kicks in Loading Loading @@ -3517,6 +3525,11 @@ static int mdss_mdp_pp_ioctl(struct msm_fb_data_type *mfd, mdp_pp.op != mdp_op_calib_dcm_state)) return -EPERM; if (!mdss_mdp_mfd_valid_dspp(mfd)) { pr_err("invalid display num %d for PP config\n", mfd->index); return -EPERM; } switch (mdp_pp.op) { case mdp_op_pa_cfg: ret = mdss_mdp_pa_config(&mdp_pp.data.pa_cfg_data, Loading Loading @@ -4232,6 +4245,7 @@ static struct mdss_mdp_ctl *__mdss_mdp_overlay_ctl_init( int rc = 0; struct mdss_mdp_ctl *ctl; struct mdss_panel_data *pdata; struct mdss_overlay_private *mdp5_data; if (!mfd) return ERR_PTR(-EINVAL); Loading @@ -4243,6 +4257,12 @@ static struct mdss_mdp_ctl *__mdss_mdp_overlay_ctl_init( goto error; } mdp5_data = mfd_to_mdp5_data(mfd); if (!mdp5_data) { rc = -EINVAL; goto error; } ctl = mdss_mdp_ctl_init(pdata, mfd); if (IS_ERR_OR_NULL(ctl)) { pr_err("Unable to initialize ctl for fb%d\n", Loading Loading @@ -4270,10 +4290,12 @@ static struct mdss_mdp_ctl *__mdss_mdp_overlay_ctl_init( } } mdp5_data->ctl = ctl; rc = mdss_mdp_pp_default_overlay_config(mfd, pdata); if (rc) { pr_err("Unable to set default postprocessing configs for fb%d\n", mfd->index); pr_err("Unable to set default postprocessing configs for fb%d ret %d\n", mfd->index, rc); rc = 0; } Loading Loading @@ -4304,7 +4326,6 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) ctl = __mdss_mdp_overlay_ctl_init(mfd); if (IS_ERR_OR_NULL(ctl)) return PTR_ERR(ctl); mdp5_data->ctl = ctl; } else { ctl = mdp5_data->ctl; } Loading @@ -4319,7 +4340,7 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) if (mdss_fb_is_power_on(mfd)) { pr_debug("panel was never turned off\n"); rc = mdss_mdp_ctl_start(mdp5_data->ctl, false); rc = mdss_mdp_ctl_start(ctl, false); goto panel_on; } Loading @@ -4333,7 +4354,7 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) rc = mdss_mdp_overlay_kickoff(mfd, NULL); } } else { rc = mdss_mdp_ctl_setup(mdp5_data->ctl); rc = mdss_mdp_ctl_setup(ctl); if (rc) goto end; } Loading Loading @@ -4548,7 +4569,6 @@ static int mdss_mdp_overlay_handoff(struct msm_fb_data_type *mfd) rc = PTR_ERR(ctl); goto error; } mdp5_data->ctl = ctl; } else { ctl = mdp5_data->ctl; } Loading drivers/video/msm/mdss/mdss_mdp_pp.c +138 −125 Original line number Diff line number Diff line Loading @@ -316,7 +316,7 @@ static int pp_read_pa_v2_regs(char __iomem *addr, static void pp_read_pa_mem_col_regs(char __iomem *addr, struct mdp_pa_mem_col_cfg *mem_col_cfg); static struct msm_fb_data_type *mdss_get_mfd_from_index(int index); static int mdss_ad_init_checks(struct msm_fb_data_type *mfd); static int mdss_mdp_mfd_valid_ad(struct msm_fb_data_type *mfd); static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, struct mdss_ad_info **ad); static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd); Loading @@ -343,7 +343,8 @@ static int pp_update_pcc_pipe_setup(struct mdss_mdp_pipe *pipe, u32 location); static void mdss_mdp_hist_irq_set_mask(u32 irq); static void mdss_mdp_hist_irq_clear_mask(u32 irq); static void mdss_mdp_hist_intr_notify(u32 disp); static int mdss_mdp_panel_default_dither_config(u32 panel_bpp, u32 disp_num); static int mdss_mdp_panel_default_dither_config(struct msm_fb_data_type *mfd, u32 panel_bpp); static u32 last_sts, last_state; Loading Loading @@ -2000,28 +2001,26 @@ exit: * Set dirty and write bits on features that were enabled so they will be * reconfigured */ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd) { u32 flags = 0, disp_num, bl, ret = 0; u32 flags = 0, disp_num, ret = 0; struct pp_sts_type pp_sts; struct mdss_ad_info *ad; struct mdss_data_type *mdata; struct msm_fb_data_type *bl_mfd; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); struct mdp_pa_v2_cfg_data *pa_v2_cache_cfg = NULL; if (!ctl || !ctl->mdata || !ctl->mfd) { pr_err("invalid input: ctl = 0x%p, mdata = 0x%p, mfd = 0x%p\n", ctl, (!ctl) ? NULL : ctl->mdata, (!ctl) ? NULL : ctl->mfd); return -EPERM; if (!mfd) { pr_err("invalid input: mfd = 0x%p\n", mfd); return -EINVAL; } mdata = ctl->mdata; if (dspp_num >= mdata->ndspp) { pr_err("invalid dspp_num %d\n", dspp_num); return -EINVAL; if (!mdss_mdp_mfd_valid_dspp(mfd)) { pr_warn("PP not supported on display num %d hw config\n", mfd->index); return -EPERM; } disp_num = ctl->mfd->index; disp_num = mfd->index; pp_sts = mdss_pp_res->pp_disp_sts[disp_num]; if (pp_sts.pa_sts & PP_STS_ENABLE) { Loading Loading @@ -2095,42 +2094,26 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) mdss_pp_res->pp_disp_flags[disp_num] |= flags; mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_RESUME_COMMIT; if (dspp_num < mdata->nad_cfgs) { ret = mdss_mdp_get_ad(ctl->mfd, &ad); if (ret) { pr_warn("Failed to get AD info, err = %d\n", ret); return ret; } if (ctl->mfd->panel_info->type == WRITEBACK_PANEL) { bl_mfd = mdss_get_mfd_from_index(0); if (!bl_mfd) { ret = -EINVAL; pr_warn("Failed to get primary FB bl handle, err = %d\n", ret); ret = mdss_mdp_get_ad(mfd, &ad); if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } } else { bl_mfd = ctl->mfd; } mutex_lock(&ad->lock); bl = bl_mfd->ad_bl_level; if (PP_AD_STATE_CFG & ad->state) pp_ad_cfg_write(&mdata->ad_off[dspp_num], ad); ad->sts |= PP_AD_STS_DIRTY_CFG; if (PP_AD_STATE_INIT & ad->state) pp_ad_init_write(&mdata->ad_off[dspp_num], ad, ctl); ad->sts |= PP_AD_STS_DIRTY_INIT; if ((PP_AD_STATE_DATA & ad->state) && (ad->sts & PP_STS_ENABLE)) { ad->last_bl = bl; linear_map(bl, &ad->bl_data, bl_mfd->panel_info->bl_max, MDSS_MDP_AD_BL_SCALE); pp_ad_input_write(&mdata->ad_off[dspp_num], ad); } if ((PP_AD_STATE_VSYNC & ad->state) && ad->calc_itr) ctl->ops.add_vsync_handler(ctl, &ad->handle); (ad->sts & PP_STS_ENABLE)) ad->sts |= PP_AD_STS_DIRTY_DATA; mutex_unlock(&ad->lock); } return 0; } Loading Loading @@ -2389,8 +2372,7 @@ int mdss_mdp_pp_default_overlay_config(struct msm_fb_data_type *mfd, return -EINVAL; } ret = mdss_mdp_panel_default_dither_config(pdata->panel_info.bpp, mfd->index); ret = mdss_mdp_panel_default_dither_config(mfd, pdata->panel_info.bpp); if (ret) pr_err("Unable to configure default dither on fb%d\n", mfd->index); Loading @@ -2407,9 +2389,10 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, struct mdss_ad_info *ad; ret = mdss_mdp_get_ad(mfd, &ad); if (ret == -ENODEV) { pr_debug("AD not supported on device.\n"); return ret; if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); Loading Loading @@ -3044,6 +3027,12 @@ int mdss_mdp_limited_lut_igc_config(struct mdss_mdp_ctl *ctl) if (!ctl) return -EINVAL; if (!mdss_mdp_mfd_valid_dspp(ctl->mfd)) { pr_warn("IGC not supported on display num %d hw configuration\n", ctl->mfd->index); return 0; } config.len = IGC_LUT_ENTRIES; config.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE; config.block = (ctl->mfd->index) + MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -3585,19 +3574,23 @@ enhist_config_exit: return ret; } static int mdss_mdp_panel_default_dither_config(u32 panel_bpp, u32 disp_num) static int mdss_mdp_panel_default_dither_config(struct msm_fb_data_type *mfd, u32 panel_bpp) { int ret = 0; struct mdp_dither_cfg_data dither = { .block = disp_num + MDP_LOGICAL_BLOCK_DISP_0, .flags = MDP_PP_OPS_DISABLE, }; struct mdp_dither_cfg_data dither; struct mdp_pp_feature_version dither_version = { .pp_feature = DITHER, }; struct mdp_dither_data_v1_7 dither_data; dither.block = disp_num + MDP_LOGICAL_BLOCK_DISP_0; if (!mdss_mdp_mfd_valid_dspp(mfd)) { pr_warn("dither config not supported on display num %d\n", mfd->index); return 0; } dither.block = mfd->index + MDP_LOGICAL_BLOCK_DISP_0; dither.flags = MDP_PP_OPS_DISABLE; ret = mdss_mdp_pp_get_version(&dither_version); Loading Loading @@ -4741,67 +4734,42 @@ static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num) return -EINVAL; } static int mdss_ad_init_checks(struct msm_fb_data_type *mfd) static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, struct mdss_ad_info **ret_ad) { u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; u32 mixer_num; u32 ret = -EINVAL; int i = 0; struct mdss_data_type *mdata = mfd_to_mdata(mfd); struct msm_fb_data_type *ad_mfd = mfd; if (ad_mfd->ext_ad_ctrl >= 0) ad_mfd = mdss_get_mfd_from_index(ad_mfd->ext_ad_ctrl); int ret = 0; struct mdss_data_type *mdata; struct mdss_mdp_ctl *ctl = NULL; if (!ad_mfd || !mdata) return ret; *ret_ad = NULL; if (!mfd) { pr_err("invalid parameter mfd %p\n", mfd); return -EINVAL; } mdata = mfd_to_mdata(mfd); if (mdata->nad_cfgs == 0) { pr_debug("Assertive Display not supported by device\n"); return -ENODEV; } if (ad_mfd->panel_info->type == DTV_PANEL) { pr_debug("AD not supported on external display\n"); return ret; } mixer_num = mdss_mdp_get_ctl_mixers(ad_mfd->index, mixer_id); if (!mixer_num) { pr_debug("no mixers connected, %d\n", mixer_num); return -EHOSTDOWN; } if (mixer_num > mdata->nmax_concurrent_ad_hw) { pr_debug("too many mixers, not supported, %d > %d\n", mixer_num, mdata->nmax_concurrent_ad_hw); return ret; } do { if (mixer_id[i] >= mdata->nad_cfgs) { pr_err("invalid mixer input, %d\n", mixer_id[i]); return ret; if (!mdss_mdp_mfd_valid_ad(mfd)) { pr_warn("AD not supported on display num %d hw config\n", mfd->index); return -EPERM; } i++; } while (i < mixer_num); return mixer_id[0]; if (mfd->panel_info->type == DTV_PANEL) { pr_debug("AD not supported on external display\n"); return -EPERM; } static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, struct mdss_ad_info **ret_ad) { int ad_num, ret = 0; struct mdss_data_type *mdata; struct mdss_ad_info *ad = NULL; mdata = mfd_to_mdata(mfd); ad_num = mdss_ad_init_checks(mfd); if (ad_num >= 0) ad = &mdata->ad_cfgs[ad_num]; ctl = mfd_to_ctl(mfd); if ((ctl) && (ctl->mixer_left)) *ret_ad = &mdata->ad_cfgs[ctl->mixer_left->num]; else ret = ad_num; *ret_ad = ad; ret = -EPERM; return ret; } Loading @@ -4810,22 +4778,21 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd) { int ret; struct mdss_ad_info *ad; struct mdss_mdp_ctl *ctl; if (!mfd) { pr_err("Invalid mfd\n"); return -EINVAL; } ctl = mfd_to_ctl(mfd); if (!ctl) { pr_err("Invalid ctl\n"); return -EINVAL; } ret = mdss_mdp_get_ad(mfd, &ad); if (ret || !ad) { pr_err("Fail to get ad: ret = %d, ad = 0x%p\n", ret, ad); return -EINVAL; if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } pr_debug("AD backlight level changed (%d), trigger update to AD\n", mfd->ad_bl_level); Loading @@ -4852,8 +4819,15 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, u32 last_ops; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) if (ret == -ENODEV || ret == -EPERM) { pr_err("AD not supported on device, disp num %d\n", mfd->index); return ret; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } if (mfd->panel_info->type == WRITEBACK_PANEL) { bl_mfd = mdss_get_mfd_from_index(0); if (!bl_mfd) Loading Loading @@ -4956,8 +4930,15 @@ int mdss_mdp_ad_input(struct msm_fb_data_type *mfd, u32 bl; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) if (ret == -ENODEV || ret == -EPERM) { pr_err("AD not supported on device, disp num %d\n", mfd->index); return ret; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } mutex_lock(&ad->lock); if ((!PP_AD_STATE_IS_INITCFG(ad->state) && Loading Loading @@ -5282,10 +5263,14 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) u32 bypass = MDSS_PP_AD_BYPASS_DEF, bl; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) { ret = -EINVAL; pr_debug("failed to get ad_info, err = %d\n", ret); goto exit; if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } if (mfd->panel_info->type == WRITEBACK_PANEL) { bl_mfd = mdss_get_mfd_from_index(0); Loading Loading @@ -6448,3 +6433,31 @@ void mdss_mdp_free_layer_pp_info(struct mdp_input_layer *layer) kfree(pp_info->pcc_cfg_data.cfg_payload); kfree(pp_info); } int mdss_mdp_mfd_valid_dspp(struct msm_fb_data_type *mfd) { struct mdss_mdp_ctl *ctl = NULL; int valid_dspp = false; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); ctl = mfd_to_ctl(mfd); valid_dspp = (ctl) && (ctl->mixer_left) && (ctl->mixer_left->num < mdata->ndspp); if ((ctl) && (ctl->mixer_right)) valid_dspp &= (ctl->mixer_right->num < mdata->ndspp); return valid_dspp; } static int mdss_mdp_mfd_valid_ad(struct msm_fb_data_type *mfd) { struct mdss_mdp_ctl *ctl = NULL; int valid_ad = false; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); ctl = mfd_to_ctl(mfd); valid_ad = (ctl) && (ctl->mixer_left) && (ctl->mixer_left->num < mdata->nad_cfgs); if ((ctl) && (ctl->mixer_right)) valid_ad &= (ctl->mixer_right->num < mdata->nad_cfgs); return valid_ad; } Loading
drivers/video/msm/mdss/mdss_mdp.h +4 −2 Original line number Diff line number Diff line Loading @@ -1088,7 +1088,7 @@ int mdss_mdp_pp_init(struct device *dev); void mdss_mdp_pp_term(struct device *dev); int mdss_mdp_pp_overlay_init(struct msm_fb_data_type *mfd); int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 mixer_num); int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd); int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl); int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl); Loading @@ -1103,6 +1103,8 @@ int mdss_mdp_smp_setup(struct mdss_data_type *mdata, u32 cnt, u32 size); void mdss_hw_init(struct mdss_data_type *mdata); int mdss_mdp_mfd_valid_dspp(struct msm_fb_data_type *mfd); int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback); int mdss_mdp_pa_v2_config(struct mdp_pa_v2_cfg_data *config, u32 *copyback); int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *cfg_ptr, u32 *copyback); Loading
drivers/video/msm/mdss/mdss_mdp_ctl.c +3 −10 Original line number Diff line number Diff line Loading @@ -3023,9 +3023,7 @@ static void mdss_mdp_ctl_restore_sub(struct mdss_mdp_ctl *ctl) MDSS_MDP_REG_DISP_INTF_SEL); if (ctl->mixer_left) { mdss_mdp_pp_resume(ctl, ctl->mixer_left->num); if (ctl->mixer_right) mdss_mdp_pp_resume(ctl, ctl->mixer_right->num); mdss_mdp_pp_resume(ctl->mfd); if (ctl->panel_data->panel_info.compression_mode == COMPRESSION_DSC) { Loading Loading @@ -3113,12 +3111,6 @@ static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff) mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(i), 0); } mixer = ctl->mixer_left; if (mixer) { mdss_mdp_pp_resume(ctl, mixer->num); mixer->params_changed++; } temp = readl_relaxed(ctl->mdata->mdp_base + MDSS_MDP_REG_DISP_INTF_SEL); temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8)); Loading @@ -3128,7 +3120,9 @@ static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff) writel_relaxed(temp, ctl->mdata->mdp_base + MDSS_MDP_REG_DISP_INTF_SEL); mixer = ctl->mixer_left; if (mixer) { mixer->params_changed++; outsize = (mixer->height << 16) | mixer->width; mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, outsize); Loading Loading @@ -3203,7 +3197,6 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff) struct mdss_mdp_mixer *mixer = ctl->mixer_right; u32 out; mdss_mdp_pp_resume(ctl, mixer->num); mixer->params_changed++; out = (mixer->height << 16) | mixer->width; mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, out); Loading
drivers/video/msm/mdss/mdss_mdp_overlay.c +26 −6 Original line number Diff line number Diff line Loading @@ -1362,6 +1362,14 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd) } } /* Restore any previously configured PP features by resetting the dirty * bits for enabled features. The dirty bits will be consumed during the * first display commit when the PP hardware blocks are updated */ rc = mdss_mdp_pp_resume(mfd); if (rc && (rc != -EPERM) && (rc != -ENODEV)) pr_err("PP resume err %d\n", rc); /* * Increment the overlay active count prior to calling ctl_start. * This is needed to ensure that if idle power collapse kicks in Loading Loading @@ -3517,6 +3525,11 @@ static int mdss_mdp_pp_ioctl(struct msm_fb_data_type *mfd, mdp_pp.op != mdp_op_calib_dcm_state)) return -EPERM; if (!mdss_mdp_mfd_valid_dspp(mfd)) { pr_err("invalid display num %d for PP config\n", mfd->index); return -EPERM; } switch (mdp_pp.op) { case mdp_op_pa_cfg: ret = mdss_mdp_pa_config(&mdp_pp.data.pa_cfg_data, Loading Loading @@ -4232,6 +4245,7 @@ static struct mdss_mdp_ctl *__mdss_mdp_overlay_ctl_init( int rc = 0; struct mdss_mdp_ctl *ctl; struct mdss_panel_data *pdata; struct mdss_overlay_private *mdp5_data; if (!mfd) return ERR_PTR(-EINVAL); Loading @@ -4243,6 +4257,12 @@ static struct mdss_mdp_ctl *__mdss_mdp_overlay_ctl_init( goto error; } mdp5_data = mfd_to_mdp5_data(mfd); if (!mdp5_data) { rc = -EINVAL; goto error; } ctl = mdss_mdp_ctl_init(pdata, mfd); if (IS_ERR_OR_NULL(ctl)) { pr_err("Unable to initialize ctl for fb%d\n", Loading Loading @@ -4270,10 +4290,12 @@ static struct mdss_mdp_ctl *__mdss_mdp_overlay_ctl_init( } } mdp5_data->ctl = ctl; rc = mdss_mdp_pp_default_overlay_config(mfd, pdata); if (rc) { pr_err("Unable to set default postprocessing configs for fb%d\n", mfd->index); pr_err("Unable to set default postprocessing configs for fb%d ret %d\n", mfd->index, rc); rc = 0; } Loading Loading @@ -4304,7 +4326,6 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) ctl = __mdss_mdp_overlay_ctl_init(mfd); if (IS_ERR_OR_NULL(ctl)) return PTR_ERR(ctl); mdp5_data->ctl = ctl; } else { ctl = mdp5_data->ctl; } Loading @@ -4319,7 +4340,7 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) if (mdss_fb_is_power_on(mfd)) { pr_debug("panel was never turned off\n"); rc = mdss_mdp_ctl_start(mdp5_data->ctl, false); rc = mdss_mdp_ctl_start(ctl, false); goto panel_on; } Loading @@ -4333,7 +4354,7 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) rc = mdss_mdp_overlay_kickoff(mfd, NULL); } } else { rc = mdss_mdp_ctl_setup(mdp5_data->ctl); rc = mdss_mdp_ctl_setup(ctl); if (rc) goto end; } Loading Loading @@ -4548,7 +4569,6 @@ static int mdss_mdp_overlay_handoff(struct msm_fb_data_type *mfd) rc = PTR_ERR(ctl); goto error; } mdp5_data->ctl = ctl; } else { ctl = mdp5_data->ctl; } Loading
drivers/video/msm/mdss/mdss_mdp_pp.c +138 −125 Original line number Diff line number Diff line Loading @@ -316,7 +316,7 @@ static int pp_read_pa_v2_regs(char __iomem *addr, static void pp_read_pa_mem_col_regs(char __iomem *addr, struct mdp_pa_mem_col_cfg *mem_col_cfg); static struct msm_fb_data_type *mdss_get_mfd_from_index(int index); static int mdss_ad_init_checks(struct msm_fb_data_type *mfd); static int mdss_mdp_mfd_valid_ad(struct msm_fb_data_type *mfd); static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, struct mdss_ad_info **ad); static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd); Loading @@ -343,7 +343,8 @@ static int pp_update_pcc_pipe_setup(struct mdss_mdp_pipe *pipe, u32 location); static void mdss_mdp_hist_irq_set_mask(u32 irq); static void mdss_mdp_hist_irq_clear_mask(u32 irq); static void mdss_mdp_hist_intr_notify(u32 disp); static int mdss_mdp_panel_default_dither_config(u32 panel_bpp, u32 disp_num); static int mdss_mdp_panel_default_dither_config(struct msm_fb_data_type *mfd, u32 panel_bpp); static u32 last_sts, last_state; Loading Loading @@ -2000,28 +2001,26 @@ exit: * Set dirty and write bits on features that were enabled so they will be * reconfigured */ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd) { u32 flags = 0, disp_num, bl, ret = 0; u32 flags = 0, disp_num, ret = 0; struct pp_sts_type pp_sts; struct mdss_ad_info *ad; struct mdss_data_type *mdata; struct msm_fb_data_type *bl_mfd; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); struct mdp_pa_v2_cfg_data *pa_v2_cache_cfg = NULL; if (!ctl || !ctl->mdata || !ctl->mfd) { pr_err("invalid input: ctl = 0x%p, mdata = 0x%p, mfd = 0x%p\n", ctl, (!ctl) ? NULL : ctl->mdata, (!ctl) ? NULL : ctl->mfd); return -EPERM; if (!mfd) { pr_err("invalid input: mfd = 0x%p\n", mfd); return -EINVAL; } mdata = ctl->mdata; if (dspp_num >= mdata->ndspp) { pr_err("invalid dspp_num %d\n", dspp_num); return -EINVAL; if (!mdss_mdp_mfd_valid_dspp(mfd)) { pr_warn("PP not supported on display num %d hw config\n", mfd->index); return -EPERM; } disp_num = ctl->mfd->index; disp_num = mfd->index; pp_sts = mdss_pp_res->pp_disp_sts[disp_num]; if (pp_sts.pa_sts & PP_STS_ENABLE) { Loading Loading @@ -2095,42 +2094,26 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) mdss_pp_res->pp_disp_flags[disp_num] |= flags; mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_RESUME_COMMIT; if (dspp_num < mdata->nad_cfgs) { ret = mdss_mdp_get_ad(ctl->mfd, &ad); if (ret) { pr_warn("Failed to get AD info, err = %d\n", ret); return ret; } if (ctl->mfd->panel_info->type == WRITEBACK_PANEL) { bl_mfd = mdss_get_mfd_from_index(0); if (!bl_mfd) { ret = -EINVAL; pr_warn("Failed to get primary FB bl handle, err = %d\n", ret); ret = mdss_mdp_get_ad(mfd, &ad); if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } } else { bl_mfd = ctl->mfd; } mutex_lock(&ad->lock); bl = bl_mfd->ad_bl_level; if (PP_AD_STATE_CFG & ad->state) pp_ad_cfg_write(&mdata->ad_off[dspp_num], ad); ad->sts |= PP_AD_STS_DIRTY_CFG; if (PP_AD_STATE_INIT & ad->state) pp_ad_init_write(&mdata->ad_off[dspp_num], ad, ctl); ad->sts |= PP_AD_STS_DIRTY_INIT; if ((PP_AD_STATE_DATA & ad->state) && (ad->sts & PP_STS_ENABLE)) { ad->last_bl = bl; linear_map(bl, &ad->bl_data, bl_mfd->panel_info->bl_max, MDSS_MDP_AD_BL_SCALE); pp_ad_input_write(&mdata->ad_off[dspp_num], ad); } if ((PP_AD_STATE_VSYNC & ad->state) && ad->calc_itr) ctl->ops.add_vsync_handler(ctl, &ad->handle); (ad->sts & PP_STS_ENABLE)) ad->sts |= PP_AD_STS_DIRTY_DATA; mutex_unlock(&ad->lock); } return 0; } Loading Loading @@ -2389,8 +2372,7 @@ int mdss_mdp_pp_default_overlay_config(struct msm_fb_data_type *mfd, return -EINVAL; } ret = mdss_mdp_panel_default_dither_config(pdata->panel_info.bpp, mfd->index); ret = mdss_mdp_panel_default_dither_config(mfd, pdata->panel_info.bpp); if (ret) pr_err("Unable to configure default dither on fb%d\n", mfd->index); Loading @@ -2407,9 +2389,10 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, struct mdss_ad_info *ad; ret = mdss_mdp_get_ad(mfd, &ad); if (ret == -ENODEV) { pr_debug("AD not supported on device.\n"); return ret; if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); Loading Loading @@ -3044,6 +3027,12 @@ int mdss_mdp_limited_lut_igc_config(struct mdss_mdp_ctl *ctl) if (!ctl) return -EINVAL; if (!mdss_mdp_mfd_valid_dspp(ctl->mfd)) { pr_warn("IGC not supported on display num %d hw configuration\n", ctl->mfd->index); return 0; } config.len = IGC_LUT_ENTRIES; config.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE; config.block = (ctl->mfd->index) + MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -3585,19 +3574,23 @@ enhist_config_exit: return ret; } static int mdss_mdp_panel_default_dither_config(u32 panel_bpp, u32 disp_num) static int mdss_mdp_panel_default_dither_config(struct msm_fb_data_type *mfd, u32 panel_bpp) { int ret = 0; struct mdp_dither_cfg_data dither = { .block = disp_num + MDP_LOGICAL_BLOCK_DISP_0, .flags = MDP_PP_OPS_DISABLE, }; struct mdp_dither_cfg_data dither; struct mdp_pp_feature_version dither_version = { .pp_feature = DITHER, }; struct mdp_dither_data_v1_7 dither_data; dither.block = disp_num + MDP_LOGICAL_BLOCK_DISP_0; if (!mdss_mdp_mfd_valid_dspp(mfd)) { pr_warn("dither config not supported on display num %d\n", mfd->index); return 0; } dither.block = mfd->index + MDP_LOGICAL_BLOCK_DISP_0; dither.flags = MDP_PP_OPS_DISABLE; ret = mdss_mdp_pp_get_version(&dither_version); Loading Loading @@ -4741,67 +4734,42 @@ static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num) return -EINVAL; } static int mdss_ad_init_checks(struct msm_fb_data_type *mfd) static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, struct mdss_ad_info **ret_ad) { u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; u32 mixer_num; u32 ret = -EINVAL; int i = 0; struct mdss_data_type *mdata = mfd_to_mdata(mfd); struct msm_fb_data_type *ad_mfd = mfd; if (ad_mfd->ext_ad_ctrl >= 0) ad_mfd = mdss_get_mfd_from_index(ad_mfd->ext_ad_ctrl); int ret = 0; struct mdss_data_type *mdata; struct mdss_mdp_ctl *ctl = NULL; if (!ad_mfd || !mdata) return ret; *ret_ad = NULL; if (!mfd) { pr_err("invalid parameter mfd %p\n", mfd); return -EINVAL; } mdata = mfd_to_mdata(mfd); if (mdata->nad_cfgs == 0) { pr_debug("Assertive Display not supported by device\n"); return -ENODEV; } if (ad_mfd->panel_info->type == DTV_PANEL) { pr_debug("AD not supported on external display\n"); return ret; } mixer_num = mdss_mdp_get_ctl_mixers(ad_mfd->index, mixer_id); if (!mixer_num) { pr_debug("no mixers connected, %d\n", mixer_num); return -EHOSTDOWN; } if (mixer_num > mdata->nmax_concurrent_ad_hw) { pr_debug("too many mixers, not supported, %d > %d\n", mixer_num, mdata->nmax_concurrent_ad_hw); return ret; } do { if (mixer_id[i] >= mdata->nad_cfgs) { pr_err("invalid mixer input, %d\n", mixer_id[i]); return ret; if (!mdss_mdp_mfd_valid_ad(mfd)) { pr_warn("AD not supported on display num %d hw config\n", mfd->index); return -EPERM; } i++; } while (i < mixer_num); return mixer_id[0]; if (mfd->panel_info->type == DTV_PANEL) { pr_debug("AD not supported on external display\n"); return -EPERM; } static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, struct mdss_ad_info **ret_ad) { int ad_num, ret = 0; struct mdss_data_type *mdata; struct mdss_ad_info *ad = NULL; mdata = mfd_to_mdata(mfd); ad_num = mdss_ad_init_checks(mfd); if (ad_num >= 0) ad = &mdata->ad_cfgs[ad_num]; ctl = mfd_to_ctl(mfd); if ((ctl) && (ctl->mixer_left)) *ret_ad = &mdata->ad_cfgs[ctl->mixer_left->num]; else ret = ad_num; *ret_ad = ad; ret = -EPERM; return ret; } Loading @@ -4810,22 +4778,21 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd) { int ret; struct mdss_ad_info *ad; struct mdss_mdp_ctl *ctl; if (!mfd) { pr_err("Invalid mfd\n"); return -EINVAL; } ctl = mfd_to_ctl(mfd); if (!ctl) { pr_err("Invalid ctl\n"); return -EINVAL; } ret = mdss_mdp_get_ad(mfd, &ad); if (ret || !ad) { pr_err("Fail to get ad: ret = %d, ad = 0x%p\n", ret, ad); return -EINVAL; if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } pr_debug("AD backlight level changed (%d), trigger update to AD\n", mfd->ad_bl_level); Loading @@ -4852,8 +4819,15 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, u32 last_ops; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) if (ret == -ENODEV || ret == -EPERM) { pr_err("AD not supported on device, disp num %d\n", mfd->index); return ret; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } if (mfd->panel_info->type == WRITEBACK_PANEL) { bl_mfd = mdss_get_mfd_from_index(0); if (!bl_mfd) Loading Loading @@ -4956,8 +4930,15 @@ int mdss_mdp_ad_input(struct msm_fb_data_type *mfd, u32 bl; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) if (ret == -ENODEV || ret == -EPERM) { pr_err("AD not supported on device, disp num %d\n", mfd->index); return ret; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } mutex_lock(&ad->lock); if ((!PP_AD_STATE_IS_INITCFG(ad->state) && Loading Loading @@ -5282,10 +5263,14 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) u32 bypass = MDSS_PP_AD_BYPASS_DEF, bl; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) { ret = -EINVAL; pr_debug("failed to get ad_info, err = %d\n", ret); goto exit; if (ret == -ENODEV || ret == -EPERM) { pr_debug("AD not supported on device, disp num %d\n", mfd->index); return 0; } else if (ret || !ad) { pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", ret, ad); return ret; } if (mfd->panel_info->type == WRITEBACK_PANEL) { bl_mfd = mdss_get_mfd_from_index(0); Loading Loading @@ -6448,3 +6433,31 @@ void mdss_mdp_free_layer_pp_info(struct mdp_input_layer *layer) kfree(pp_info->pcc_cfg_data.cfg_payload); kfree(pp_info); } int mdss_mdp_mfd_valid_dspp(struct msm_fb_data_type *mfd) { struct mdss_mdp_ctl *ctl = NULL; int valid_dspp = false; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); ctl = mfd_to_ctl(mfd); valid_dspp = (ctl) && (ctl->mixer_left) && (ctl->mixer_left->num < mdata->ndspp); if ((ctl) && (ctl->mixer_right)) valid_dspp &= (ctl->mixer_right->num < mdata->ndspp); return valid_dspp; } static int mdss_mdp_mfd_valid_ad(struct msm_fb_data_type *mfd) { struct mdss_mdp_ctl *ctl = NULL; int valid_ad = false; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); ctl = mfd_to_ctl(mfd); valid_ad = (ctl) && (ctl->mixer_left) && (ctl->mixer_left->num < mdata->nad_cfgs); if ((ctl) && (ctl->mixer_right)) valid_ad &= (ctl->mixer_right->num < mdata->nad_cfgs); return valid_ad; }