summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorPing Li <pingli@codeaurora.org>2015-08-31 12:36:50 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:47:40 -0700
commitb1f0629512eeaf299109b58ebd7465a0a42cc436 (patch)
tree50ed3274fc32ab06629650bab3cbdb2ab0cc5027 /drivers/video/fbdev
parentf97adf46f51a0e6629db292b162b850b0faad497 (diff)
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>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c43
1 files 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);