From b1f0629512eeaf299109b58ebd7465a0a42cc436 Mon Sep 17 00:00:00 2001 From: Ping Li Date: Mon, 31 Aug 2015 12:36:50 -0700 Subject: [PATCH] msm: mdss: Correct the AD backlight calculation formulas The previous AD backlight calculation formulas assume that the BL_LIN, BL_LIN_INV and BL_ATT LUTs are monotonically increasing, which can cause miscalculation when non monotonic LUTs are used. This patch fixes the problem by removing the above assumption. Change-Id: Ifee9dc067de8c6dbd24aac407ba702a13241f782 Signed-off-by: Ping Li --- drivers/video/fbdev/msm/mdss_mdp_pp.c | 43 +++++++++++++-------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index 0bbdf9cd94fc..1e459aaffdb4 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -5808,10 +5808,11 @@ static int pp_ad_attenuate_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out) return -EINVAL; } 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); + bl_att = ((ad->bl_att_lut[n + 1] - ad->bl_att_lut[n]) * + (bl - lut_interval * n) + (ad->bl_att_lut[n] * lut_interval)) / + lut_interval; + pr_debug("n = %u, bl_att_lut[%u] = %u, bl_att_lut[%u] = %u, bl_att = %u\n", + n, n, ad->bl_att_lut[n], n + 1, ad->bl_att_lut[n + 1], bl_att); if (ad->init.alpha_base) *bl_out = (ad->init.alpha * bl_att + (ad->init.alpha_base - ad->init.alpha) * bl) / @@ -5834,6 +5835,7 @@ static int pp_ad_linearize_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out, { u32 n; + uint32_t *bl_lut = NULL; int ret = -EINVAL; if (bl < 0 || bl > ad->bl_mfd->panel_info->bl_max) { @@ -5843,6 +5845,14 @@ static int pp_ad_linearize_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out, } pr_debug("bl_in = %d, inv = %d\n", bl, inv); + if (inv == MDP_PP_AD_BL_LINEAR_INV) { + bl_lut = ad->bl_lin; + } else if (inv == MDP_PP_AD_BL_LINEAR) { + bl_lut = ad->bl_lin_inv; + } else { + pr_err("invalid inv param: inv = %d\n", inv); + return -EINVAL; + } /* map panel backlight range to AD backlight range */ linear_map(bl, &bl, ad->bl_mfd->panel_info->bl_max, @@ -5850,30 +5860,19 @@ static int pp_ad_linearize_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out, pr_debug("Before linearization = %d\n", bl); n = bl * (AD_BL_LIN_LEN - 1) / MDSS_MDP_AD_BL_SCALE; - pr_debug("n = %d\n", n); + pr_debug("n = %u\n", n); if (n > (AD_BL_LIN_LEN - 1)) { pr_err("Invalid index for BL linearization: %d.\n", n); return ret; } else if (n == (AD_BL_LIN_LEN - 1)) { - if (inv == MDP_PP_AD_BL_LINEAR_INV) - *bl_out = ad->bl_lin_inv[n]; - else if (inv == MDP_PP_AD_BL_LINEAR) - *bl_out = ad->bl_lin[n]; + *bl_out = bl_lut[n]; } else { /* linear piece-wise interpolation */ - if (inv == MDP_PP_AD_BL_LINEAR_INV) { - *bl_out = bl * (AD_BL_LIN_LEN - 1) * - (ad->bl_lin_inv[n + 1] - ad->bl_lin_inv[n]) / - MDSS_MDP_AD_BL_SCALE - n * - (ad->bl_lin_inv[n + 1] - ad->bl_lin_inv[n]) + - ad->bl_lin_inv[n]; - } else if (inv == MDP_PP_AD_BL_LINEAR) { - *bl_out = bl * (AD_BL_LIN_LEN - 1) * - (ad->bl_lin[n + 1] - ad->bl_lin[n]) / - MDSS_MDP_AD_BL_SCALE - - n * (ad->bl_lin[n + 1] - ad->bl_lin[n]) + - ad->bl_lin[n]; - } + *bl_out = ((bl_lut[n + 1] - bl_lut[n]) * + (bl - n * MDSS_MDP_AD_BL_SCALE / + (AD_BL_LIN_LEN - 1)) + bl_lut[n] * + MDSS_MDP_AD_BL_SCALE / (AD_BL_LIN_LEN - 1)) * + (AD_BL_LIN_LEN - 1) / MDSS_MDP_AD_BL_SCALE; } pr_debug("After linearization = %d\n", *bl_out);