Loading drivers/video/msm/mdss/mdss_fb.c +29 −11 Original line number Diff line number Diff line Loading @@ -951,6 +951,8 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) struct mdss_panel_data *pdata; int (*update_ad_input)(struct msm_fb_data_type *mfd); u32 temp = bkl_lvl; int ret = -EINVAL; bool is_bl_changed = (bkl_lvl != mfd->bl_level); if (((!mfd->panel_power_on && mfd->dcm_state != DCM_ENTER) || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) { Loading @@ -963,6 +965,12 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) pdata = dev_get_platdata(&mfd->pdev->dev); if ((pdata) && (pdata->set_backlight)) { if (mfd->mdp.ad_attenuate_bl && is_bl_changed) { ret = (*mfd->mdp.ad_attenuate_bl)(bkl_lvl, &temp, mfd); if (ret) pr_err("Failed to attenuate BL\n"); } mfd->bl_level_prev_scaled = mfd->bl_level_scaled; if (!IS_CALIB_MODE_BL(mfd)) mdss_fb_scale_bl(mfd, &temp); Loading @@ -982,7 +990,7 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) mfd->bl_level = bkl_lvl; mfd->bl_level_scaled = temp; if (mfd->mdp.update_ad_input) { if (mfd->mdp.update_ad_input && is_bl_changed) { update_ad_input = mfd->mdp.update_ad_input; mutex_unlock(&mfd->bl_lock); /* Will trigger ad_setup which will grab bl_lock */ Loading @@ -996,21 +1004,31 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) void mdss_fb_update_backlight(struct msm_fb_data_type *mfd) { struct mdss_panel_data *pdata; int ret = 0; u32 temp; if (mfd->unset_bl_level) { if (!mfd->unset_bl_level) return; mutex_lock(&mfd->bl_lock); if (!mfd->bl_updated) { pdata = dev_get_platdata(&mfd->pdev->dev); if ((pdata) && (pdata->set_backlight)) { mfd->bl_level = mfd->unset_bl_level; pdata->set_backlight(pdata, mfd->bl_level); temp = mfd->bl_level; if (mfd->mdp.ad_attenuate_bl) { ret = (*mfd->mdp.ad_attenuate_bl)(temp, &temp, mfd); if (ret) pr_err("Failed to attenuate BL\n"); } pdata->set_backlight(pdata, temp); mfd->bl_level_scaled = mfd->unset_bl_level; mfd->bl_updated = 1; } } mutex_unlock(&mfd->bl_lock); } } static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable) Loading drivers/video/msm/mdss/mdss_fb.h +2 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,8 @@ struct msm_mdp_interface { int (*do_histogram)(struct msm_fb_data_type *mfd, struct mdp_histogram *hist); int (*update_ad_input)(struct msm_fb_data_type *mfd); int (*ad_attenuate_bl)(u32 bl, u32 *bl_out, struct msm_fb_data_type *mfd); int (*panel_register_done)(struct mdss_panel_data *pdata); u32 (*fb_stride)(u32 fb_index, u32 xres, int bpp); int (*splash_init_fnc)(struct msm_fb_data_type *mfd); Loading drivers/video/msm/mdss/mdss_mdp_hwio.h +1 −0 Original line number Diff line number Diff line Loading @@ -402,6 +402,7 @@ enum mdss_mdp_writeback_index { #define MDSS_MDP_MAX_AD_AL 65535 #define MDSS_MDP_MAX_AD_STR 255 #define MDSS_MDP_AD_BL_SCALE 4095 #define MDSS_MDP_REG_AD_BYPASS 0x000 #define MDSS_MDP_REG_AD_CTRL_0 0x004 Loading drivers/video/msm/mdss/mdss_mdp_pp.c +68 −17 Original line number Diff line number Diff line Loading @@ -403,7 +403,8 @@ static void pp_ad_bypass_config(struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode); static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd); static void pp_ad_cfg_lut(char __iomem *addr, u32 *data); static u32 pp_ad_attenuate_bl(u32 bl, struct mdss_ad_info *ad); static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out, struct msm_fb_data_type *mfd); static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num); static inline bool pp_sts_is_enabled(u32 sts, int side); static inline void pp_sts_set_split_bits(u32 *sts, u32 bits); Loading @@ -418,6 +419,19 @@ static inline void mdss_mdp_pp_get_dcm_state(struct mdss_mdp_pipe *pipe, *dcm_state = pipe->mixer_left->ctl->mfd->dcm_state; } inline int linear_map(int in, int *out, int in_max, int out_max) { if (in < 0 || !out || in_max <= 0 || out_max <= 0) return -EINVAL; *out = ((in * out_max) / in_max); pr_debug("in = %d, out = %d, in_max = %d, out_max = %d\n", in, *out, in_max, out_max); if ((in > 0) && (*out == 0)) *out = 1; return 0; } int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx, struct mdp_csc_cfg *data) { Loading Loading @@ -1794,9 +1808,13 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) if (ad->state & PP_AD_STATE_BL_LIN) { bl = ad->bl_lin[bl >> ad->bl_bright_shift]; bl = bl << ad->bl_bright_shift; bl = pp_ad_attenuate_bl(bl, ad); ret = pp_ad_attenuate_bl(bl, &bl, ad->mfd); if (ret) pr_err("Failed to attenuate BL\n"); } ad->bl_data = bl; linear_map(bl, &ad->bl_data, ad->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) Loading Loading @@ -4201,11 +4219,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, } else if (init_cfg->ops & MDP_PP_AD_CFG) { memcpy(&ad->cfg, &init_cfg->params.cfg, sizeof(struct mdss_ad_cfg)); /* * TODO: specify panel independent range of input from cfg, * scale input backlight_scale to panel bl_max's range */ ad->cfg.backlight_scale = bl_mfd->panel_info->bl_max; ad->cfg.backlight_scale = MDSS_MDP_AD_BL_SCALE; ad->sts |= PP_AD_STS_DIRTY_CFG; } Loading Loading @@ -4620,9 +4634,13 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) if (ad->state & PP_AD_STATE_BL_LIN) { bl = ad->bl_lin[bl >> ad->bl_bright_shift]; bl = bl << ad->bl_bright_shift; bl = pp_ad_attenuate_bl(bl, ad); ret = pp_ad_attenuate_bl(bl, &bl, ad->mfd); if (ret) pr_err("Failed to attenuate BL\n"); } ad->bl_data = bl; linear_map(bl, &ad->bl_data, ad->bl_mfd->panel_info->bl_max, MDSS_MDP_AD_BL_SCALE); } mutex_unlock(&bl_mfd->bl_lock); ad->reg_sts |= PP_AD_STS_DIRTY_DATA; Loading Loading @@ -4672,6 +4690,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) if (bl_mfd != mfd) bl_mfd->ext_ad_ctrl = mfd->index; bl_mfd->mdp.update_ad_input = pp_update_ad_input; bl_mfd->mdp.ad_attenuate_bl = pp_ad_attenuate_bl; bl_mfd->ext_bl_ctrl = ad->cfg.bl_ctrl_mode; mutex_unlock(&bl_mfd->bl_lock); Loading Loading @@ -4701,6 +4720,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) memset(&ad->cfg, 0, sizeof(struct mdss_ad_cfg)); mutex_lock(&bl_mfd->bl_lock); bl_mfd->mdp.update_ad_input = NULL; bl_mfd->mdp.ad_attenuate_bl = NULL; bl_mfd->ext_bl_ctrl = 0; bl_mfd->ext_ad_ctrl = -1; mutex_unlock(&bl_mfd->bl_lock); Loading Loading @@ -4842,28 +4862,59 @@ static void pp_ad_cfg_lut(char __iomem *addr, u32 *data) addr + ((PP_AD_LUT_LEN - 1) * 2)); } static u32 pp_ad_attenuate_bl(u32 bl, struct mdss_ad_info *ad) static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out, struct msm_fb_data_type *mfd) { u32 shift = 0, ratio_temp = 0; u32 n, lut_interval, bl_att, out; u32 n, lut_interval, bl_att; int ret = -1; struct mdss_ad_info *ad; ratio_temp = ad->cfg.backlight_max / (AD_BL_ATT_LUT_LEN - 1); if (bl < 0) { pr_err("Invalid backlight input\n"); return ret; } ret = mdss_mdp_get_ad(mfd, &ad); if (ret || !ad) { pr_err("Failed to get the ad.\n"); return ret; } pr_debug("bl_in = %d\n", bl); /* map panel backlight range to AD backlight range */ linear_map(bl, &bl, ad->bl_mfd->panel_info->bl_max, MDSS_MDP_AD_BL_SCALE); pr_debug("Before attenuation = %d\n", bl); ratio_temp = MDSS_MDP_AD_BL_SCALE / (AD_BL_ATT_LUT_LEN - 1); while (ratio_temp > 0) { ratio_temp = ratio_temp >> 1; shift++; } n = bl >> shift; lut_interval = (ad->cfg.backlight_max + 1) / (AD_BL_ATT_LUT_LEN - 1); if (n >= AD_BL_ATT_LUT_LEN) { pr_err("Invalid index for BL attenuation: %d.\n", n); return ret; } lut_interval = (MDSS_MDP_AD_BL_SCALE + 1) / (AD_BL_ATT_LUT_LEN - 1); bl_att = ad->bl_att_lut[n] + (bl - lut_interval * n) * (ad->bl_att_lut[n + 1] - ad->bl_att_lut[n]) / lut_interval; pr_debug("n = %d, bl_att = %d\n", n, bl_att); if (ad->init.alpha_base) out = (ad->init.alpha * bl_att + *bl_out = (ad->init.alpha * bl_att + (ad->init.alpha_base - ad->init.alpha) * bl) / ad->init.alpha_base; else out = bl; return out; *bl_out = bl; pr_debug("After attenuation = %d\n", *bl_out); /* map AD backlight range back to panel backlight range */ linear_map(*bl_out, bl_out, MDSS_MDP_AD_BL_SCALE, ad->bl_mfd->panel_info->bl_max); pr_debug("bl_out = %d\n", *bl_out); return 0; } int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) Loading Loading
drivers/video/msm/mdss/mdss_fb.c +29 −11 Original line number Diff line number Diff line Loading @@ -951,6 +951,8 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) struct mdss_panel_data *pdata; int (*update_ad_input)(struct msm_fb_data_type *mfd); u32 temp = bkl_lvl; int ret = -EINVAL; bool is_bl_changed = (bkl_lvl != mfd->bl_level); if (((!mfd->panel_power_on && mfd->dcm_state != DCM_ENTER) || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) { Loading @@ -963,6 +965,12 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) pdata = dev_get_platdata(&mfd->pdev->dev); if ((pdata) && (pdata->set_backlight)) { if (mfd->mdp.ad_attenuate_bl && is_bl_changed) { ret = (*mfd->mdp.ad_attenuate_bl)(bkl_lvl, &temp, mfd); if (ret) pr_err("Failed to attenuate BL\n"); } mfd->bl_level_prev_scaled = mfd->bl_level_scaled; if (!IS_CALIB_MODE_BL(mfd)) mdss_fb_scale_bl(mfd, &temp); Loading @@ -982,7 +990,7 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) mfd->bl_level = bkl_lvl; mfd->bl_level_scaled = temp; if (mfd->mdp.update_ad_input) { if (mfd->mdp.update_ad_input && is_bl_changed) { update_ad_input = mfd->mdp.update_ad_input; mutex_unlock(&mfd->bl_lock); /* Will trigger ad_setup which will grab bl_lock */ Loading @@ -996,21 +1004,31 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) void mdss_fb_update_backlight(struct msm_fb_data_type *mfd) { struct mdss_panel_data *pdata; int ret = 0; u32 temp; if (mfd->unset_bl_level) { if (!mfd->unset_bl_level) return; mutex_lock(&mfd->bl_lock); if (!mfd->bl_updated) { pdata = dev_get_platdata(&mfd->pdev->dev); if ((pdata) && (pdata->set_backlight)) { mfd->bl_level = mfd->unset_bl_level; pdata->set_backlight(pdata, mfd->bl_level); temp = mfd->bl_level; if (mfd->mdp.ad_attenuate_bl) { ret = (*mfd->mdp.ad_attenuate_bl)(temp, &temp, mfd); if (ret) pr_err("Failed to attenuate BL\n"); } pdata->set_backlight(pdata, temp); mfd->bl_level_scaled = mfd->unset_bl_level; mfd->bl_updated = 1; } } mutex_unlock(&mfd->bl_lock); } } static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable) Loading
drivers/video/msm/mdss/mdss_fb.h +2 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,8 @@ struct msm_mdp_interface { int (*do_histogram)(struct msm_fb_data_type *mfd, struct mdp_histogram *hist); int (*update_ad_input)(struct msm_fb_data_type *mfd); int (*ad_attenuate_bl)(u32 bl, u32 *bl_out, struct msm_fb_data_type *mfd); int (*panel_register_done)(struct mdss_panel_data *pdata); u32 (*fb_stride)(u32 fb_index, u32 xres, int bpp); int (*splash_init_fnc)(struct msm_fb_data_type *mfd); Loading
drivers/video/msm/mdss/mdss_mdp_hwio.h +1 −0 Original line number Diff line number Diff line Loading @@ -402,6 +402,7 @@ enum mdss_mdp_writeback_index { #define MDSS_MDP_MAX_AD_AL 65535 #define MDSS_MDP_MAX_AD_STR 255 #define MDSS_MDP_AD_BL_SCALE 4095 #define MDSS_MDP_REG_AD_BYPASS 0x000 #define MDSS_MDP_REG_AD_CTRL_0 0x004 Loading
drivers/video/msm/mdss/mdss_mdp_pp.c +68 −17 Original line number Diff line number Diff line Loading @@ -403,7 +403,8 @@ static void pp_ad_bypass_config(struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode); static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd); static void pp_ad_cfg_lut(char __iomem *addr, u32 *data); static u32 pp_ad_attenuate_bl(u32 bl, struct mdss_ad_info *ad); static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out, struct msm_fb_data_type *mfd); static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num); static inline bool pp_sts_is_enabled(u32 sts, int side); static inline void pp_sts_set_split_bits(u32 *sts, u32 bits); Loading @@ -418,6 +419,19 @@ static inline void mdss_mdp_pp_get_dcm_state(struct mdss_mdp_pipe *pipe, *dcm_state = pipe->mixer_left->ctl->mfd->dcm_state; } inline int linear_map(int in, int *out, int in_max, int out_max) { if (in < 0 || !out || in_max <= 0 || out_max <= 0) return -EINVAL; *out = ((in * out_max) / in_max); pr_debug("in = %d, out = %d, in_max = %d, out_max = %d\n", in, *out, in_max, out_max); if ((in > 0) && (*out == 0)) *out = 1; return 0; } int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx, struct mdp_csc_cfg *data) { Loading Loading @@ -1794,9 +1808,13 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) if (ad->state & PP_AD_STATE_BL_LIN) { bl = ad->bl_lin[bl >> ad->bl_bright_shift]; bl = bl << ad->bl_bright_shift; bl = pp_ad_attenuate_bl(bl, ad); ret = pp_ad_attenuate_bl(bl, &bl, ad->mfd); if (ret) pr_err("Failed to attenuate BL\n"); } ad->bl_data = bl; linear_map(bl, &ad->bl_data, ad->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) Loading Loading @@ -4201,11 +4219,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, } else if (init_cfg->ops & MDP_PP_AD_CFG) { memcpy(&ad->cfg, &init_cfg->params.cfg, sizeof(struct mdss_ad_cfg)); /* * TODO: specify panel independent range of input from cfg, * scale input backlight_scale to panel bl_max's range */ ad->cfg.backlight_scale = bl_mfd->panel_info->bl_max; ad->cfg.backlight_scale = MDSS_MDP_AD_BL_SCALE; ad->sts |= PP_AD_STS_DIRTY_CFG; } Loading Loading @@ -4620,9 +4634,13 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) if (ad->state & PP_AD_STATE_BL_LIN) { bl = ad->bl_lin[bl >> ad->bl_bright_shift]; bl = bl << ad->bl_bright_shift; bl = pp_ad_attenuate_bl(bl, ad); ret = pp_ad_attenuate_bl(bl, &bl, ad->mfd); if (ret) pr_err("Failed to attenuate BL\n"); } ad->bl_data = bl; linear_map(bl, &ad->bl_data, ad->bl_mfd->panel_info->bl_max, MDSS_MDP_AD_BL_SCALE); } mutex_unlock(&bl_mfd->bl_lock); ad->reg_sts |= PP_AD_STS_DIRTY_DATA; Loading Loading @@ -4672,6 +4690,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) if (bl_mfd != mfd) bl_mfd->ext_ad_ctrl = mfd->index; bl_mfd->mdp.update_ad_input = pp_update_ad_input; bl_mfd->mdp.ad_attenuate_bl = pp_ad_attenuate_bl; bl_mfd->ext_bl_ctrl = ad->cfg.bl_ctrl_mode; mutex_unlock(&bl_mfd->bl_lock); Loading Loading @@ -4701,6 +4720,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) memset(&ad->cfg, 0, sizeof(struct mdss_ad_cfg)); mutex_lock(&bl_mfd->bl_lock); bl_mfd->mdp.update_ad_input = NULL; bl_mfd->mdp.ad_attenuate_bl = NULL; bl_mfd->ext_bl_ctrl = 0; bl_mfd->ext_ad_ctrl = -1; mutex_unlock(&bl_mfd->bl_lock); Loading Loading @@ -4842,28 +4862,59 @@ static void pp_ad_cfg_lut(char __iomem *addr, u32 *data) addr + ((PP_AD_LUT_LEN - 1) * 2)); } static u32 pp_ad_attenuate_bl(u32 bl, struct mdss_ad_info *ad) static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out, struct msm_fb_data_type *mfd) { u32 shift = 0, ratio_temp = 0; u32 n, lut_interval, bl_att, out; u32 n, lut_interval, bl_att; int ret = -1; struct mdss_ad_info *ad; ratio_temp = ad->cfg.backlight_max / (AD_BL_ATT_LUT_LEN - 1); if (bl < 0) { pr_err("Invalid backlight input\n"); return ret; } ret = mdss_mdp_get_ad(mfd, &ad); if (ret || !ad) { pr_err("Failed to get the ad.\n"); return ret; } pr_debug("bl_in = %d\n", bl); /* map panel backlight range to AD backlight range */ linear_map(bl, &bl, ad->bl_mfd->panel_info->bl_max, MDSS_MDP_AD_BL_SCALE); pr_debug("Before attenuation = %d\n", bl); ratio_temp = MDSS_MDP_AD_BL_SCALE / (AD_BL_ATT_LUT_LEN - 1); while (ratio_temp > 0) { ratio_temp = ratio_temp >> 1; shift++; } n = bl >> shift; lut_interval = (ad->cfg.backlight_max + 1) / (AD_BL_ATT_LUT_LEN - 1); if (n >= AD_BL_ATT_LUT_LEN) { pr_err("Invalid index for BL attenuation: %d.\n", n); return ret; } lut_interval = (MDSS_MDP_AD_BL_SCALE + 1) / (AD_BL_ATT_LUT_LEN - 1); bl_att = ad->bl_att_lut[n] + (bl - lut_interval * n) * (ad->bl_att_lut[n + 1] - ad->bl_att_lut[n]) / lut_interval; pr_debug("n = %d, bl_att = %d\n", n, bl_att); if (ad->init.alpha_base) out = (ad->init.alpha * bl_att + *bl_out = (ad->init.alpha * bl_att + (ad->init.alpha_base - ad->init.alpha) * bl) / ad->init.alpha_base; else out = bl; return out; *bl_out = bl; pr_debug("After attenuation = %d\n", *bl_out); /* map AD backlight range back to panel backlight range */ linear_map(*bl_out, bl_out, MDSS_MDP_AD_BL_SCALE, ad->bl_mfd->panel_info->bl_max); pr_debug("bl_out = %d\n", *bl_out); return 0; } int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) Loading