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 <pingli@codeaurora.org>
This commit is contained in:
Ping Li 2015-08-31 12:36:50 -07:00 committed by David Keitel
parent f97adf46f5
commit b1f0629512

View file

@ -5808,10 +5808,11 @@ static int pp_ad_attenuate_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out)
return -EINVAL; return -EINVAL;
} }
lut_interval = (MDSS_MDP_AD_BL_SCALE + 1) / (AD_BL_ATT_LUT_LEN - 1); 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) * bl_att = ((ad->bl_att_lut[n + 1] - ad->bl_att_lut[n]) *
(ad->bl_att_lut[n + 1] - ad->bl_att_lut[n]) / (bl - lut_interval * n) + (ad->bl_att_lut[n] * lut_interval)) /
lut_interval; lut_interval;
pr_debug("n = %d, bl_att = %d\n", n, bl_att); 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) if (ad->init.alpha_base)
*bl_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 - 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; u32 n;
uint32_t *bl_lut = NULL;
int ret = -EINVAL; int ret = -EINVAL;
if (bl < 0 || bl > ad->bl_mfd->panel_info->bl_max) { 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); 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 */ /* map panel backlight range to AD backlight range */
linear_map(bl, &bl, ad->bl_mfd->panel_info->bl_max, 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); pr_debug("Before linearization = %d\n", bl);
n = bl * (AD_BL_LIN_LEN - 1) / MDSS_MDP_AD_BL_SCALE; 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)) { if (n > (AD_BL_LIN_LEN - 1)) {
pr_err("Invalid index for BL linearization: %d.\n", n); pr_err("Invalid index for BL linearization: %d.\n", n);
return ret; return ret;
} else if (n == (AD_BL_LIN_LEN - 1)) { } else if (n == (AD_BL_LIN_LEN - 1)) {
if (inv == MDP_PP_AD_BL_LINEAR_INV) *bl_out = bl_lut[n];
*bl_out = ad->bl_lin_inv[n];
else if (inv == MDP_PP_AD_BL_LINEAR)
*bl_out = ad->bl_lin[n];
} else { } else {
/* linear piece-wise interpolation */ /* linear piece-wise interpolation */
if (inv == MDP_PP_AD_BL_LINEAR_INV) { *bl_out = ((bl_lut[n + 1] - bl_lut[n]) *
*bl_out = bl * (AD_BL_LIN_LEN - 1) * (bl - n * MDSS_MDP_AD_BL_SCALE /
(ad->bl_lin_inv[n + 1] - ad->bl_lin_inv[n]) / (AD_BL_LIN_LEN - 1)) + bl_lut[n] *
MDSS_MDP_AD_BL_SCALE - n * MDSS_MDP_AD_BL_SCALE / (AD_BL_LIN_LEN - 1)) *
(ad->bl_lin_inv[n + 1] - ad->bl_lin_inv[n]) + (AD_BL_LIN_LEN - 1) / MDSS_MDP_AD_BL_SCALE;
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];
}
} }
pr_debug("After linearization = %d\n", *bl_out); pr_debug("After linearization = %d\n", *bl_out);