diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 48 | ||||
| -rw-r--r-- | include/uapi/linux/msm_mdp.h | 7 |
3 files changed, 54 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 95e780303d97..320258464037 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -309,6 +309,7 @@ struct mdss_ad_info { uint32_t bl_bright_shift; uint32_t bl_lin[AD_BL_LIN_LEN]; uint32_t bl_lin_inv[AD_BL_LIN_LEN]; + uint32_t bl_att_lut[AD_BL_ATT_LUT_LEN]; }; struct pp_sts_type { diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index 3089afeba306..9f5a0ae2e7f4 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -418,6 +418,7 @@ 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_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); @@ -1794,6 +1795,7 @@ 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); } ad->bl_data = bl; pp_ad_input_write(&mdata->ad_off[dspp_num], ad); @@ -4038,7 +4040,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, { struct mdss_ad_info *ad; struct msm_fb_data_type *bl_mfd; - int lin_ret = -1, inv_ret = -1, ret = 0; + int lin_ret = -1, inv_ret = -1, att_ret = -1, ret = 0; u32 ratio_temp, shift = 0, last_ops; ret = mdss_mdp_get_ad(mfd, &ad); @@ -4087,6 +4089,23 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, } else ad->state |= PP_AD_STATE_BL_LIN; + if ((init_cfg->params.init.bl_att_len == AD_BL_ATT_LUT_LEN) && + (init_cfg->params.init.bl_att_lut)) { + att_ret = copy_from_user(&ad->bl_att_lut, + init_cfg->params.init.bl_att_lut, + init_cfg->params.init.bl_att_len * + sizeof(uint32_t)); + if (att_ret) + ret = -ENOMEM; + } else { + ret = -EINVAL; + } + if (ret) { + ad->state &= ~PP_AD_STATE_BL_LIN; + goto ad_config_exit; + } else + ad->state |= PP_AD_STATE_BL_LIN; + ad->sts |= PP_AD_STS_DIRTY_INIT; } else if (init_cfg->ops & MDP_PP_AD_CFG) { memcpy(&ad->cfg, &init_cfg->params.cfg, @@ -4513,6 +4532,7 @@ 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); } ad->bl_data = bl; } @@ -4587,6 +4607,8 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) AD_BL_LIN_LEN); memset(&ad->bl_lin_inv, 0, sizeof(uint32_t) * AD_BL_LIN_LEN); + memset(&ad->bl_att_lut, 0, sizeof(uint32_t) * + AD_BL_ATT_LUT_LEN); memset(&ad->init, 0, sizeof(struct mdss_ad_init)); memset(&ad->cfg, 0, sizeof(struct mdss_ad_cfg)); mutex_lock(&bl_mfd->bl_lock); @@ -4732,6 +4754,30 @@ 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) +{ + u32 shift = 0, ratio_temp = 0; + u32 n, lut_interval, bl_att, out; + + ratio_temp = ad->cfg.backlight_max / (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); + bl_att = ad->bl_att_lut[n] + (bl - lut_interval * n) * + (ad->bl_att_lut[n + 1] - ad->bl_att_lut[n]) / + lut_interval; + if (ad->init.alpha_base) + out = (ad->init.alpha * bl_att + + (ad->init.alpha_base - ad->init.alpha) * bl) / + ad->init.alpha_base; + else + out = bl; + return out; +} + int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) { u32 i; diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index 683ca1111244..fc06f2aea74c 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -827,7 +827,8 @@ enum { #define MDSS_PP_SPLIT_MASK 0x30000000 #define MDSS_MAX_BL_BRIGHTNESS 255 -#define AD_BL_LIN_LEN (MDSS_MAX_BL_BRIGHTNESS + 1) +#define AD_BL_LIN_LEN 256 +#define AD_BL_ATT_LUT_LEN 33 #define MDSS_AD_MODE_AUTO_BL 0x0 #define MDSS_AD_MODE_AUTO_STR 0x1 @@ -856,9 +857,13 @@ struct mdss_ad_init { uint16_t frame_h; uint8_t logo_v; uint8_t logo_h; + uint32_t alpha; + uint32_t alpha_base; uint32_t bl_lin_len; + uint32_t bl_att_len; uint32_t *bl_lin; uint32_t *bl_lin_inv; + uint32_t *bl_att_lut; }; #define MDSS_AD_BL_CTRL_MODE_EN 1 |
