summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPing Li <pingli@codeaurora.org>2016-05-04 11:03:09 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-07-21 10:36:44 -0700
commitd1e486c5fa1511c98b14c0882c13688fef4edd26 (patch)
tree646b836ea2293ba39fd9675e94de8c52526fc346
parent9e4b3ba4afcff08bce320513610955391ab95806 (diff)
msm: mdss: Update backlight filter for AD
A new post-processing ioctl is added to pass AD backlight threshold and AD backlight low limit to driver. AD backlight low limit is used to prevent very small backlight value been sent to AD core, which will cause over-sensitivity for AD core. Change-Id: I6e4222728d805d5b1d07cce4bf4648219cdaf587 Signed-off-by: Ping Li <pingli@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h4
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c46
-rw-r--r--include/uapi/linux/msm_mdp.h9
4 files changed, 54 insertions, 8 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index d6cd6825e262..da5e7bb8a343 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -678,6 +678,8 @@ struct mdss_ad_info {
bool last_calib_valid;
u32 ipc_frame_count;
u32 bl_data;
+ u32 bl_min_delta;
+ u32 bl_low_limit;
u32 calc_itr;
uint32_t bl_lin[AD_BL_LIN_LEN];
uint32_t bl_lin_inv[AD_BL_LIN_LEN];
@@ -1733,6 +1735,8 @@ void mdss_mdp_hist_intr_done(u32 isr);
int mdss_mdp_ad_config(struct msm_fb_data_type *mfd,
struct mdss_ad_init_cfg *init_cfg);
+int mdss_mdp_ad_bl_config(struct msm_fb_data_type *mfd,
+ struct mdss_ad_bl_cfg *ad_bl_cfg);
int mdss_mdp_ad_input(struct msm_fb_data_type *mfd,
struct mdss_ad_input *input, int wait);
int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 2baa1b9cd8b5..e5cdc750193e 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -4109,6 +4109,9 @@ static int mdss_mdp_pp_ioctl(struct msm_fb_data_type *mfd,
case mdp_op_ad_cfg:
ret = mdss_mdp_ad_config(mfd, &mdp_pp.data.ad_init_cfg);
break;
+ case mdp_op_ad_bl_cfg:
+ ret = mdss_mdp_ad_bl_config(mfd, &mdp_pp.data.ad_bl_cfg);
+ break;
case mdp_op_ad_input:
ret = mdss_mdp_ad_input(mfd, &mdp_pp.data.ad_input, 1);
if (ret > 0) {
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index c4cbc220baf8..a760711e7501 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -3073,22 +3073,22 @@ int mdss_mdp_pp_default_overlay_config(struct msm_fb_data_type *mfd,
return ret;
}
-static bool pp_ad_bl_threshold_check(int al_thresh, int base, int prev_bl,
+static bool pp_ad_bl_threshold_check(int bl_min_delta, int base, int prev_bl,
int curr_bl)
{
- int bl_thresh = 0, diff = 0;
+ int bl_delta_factor = 0, diff = 0;
bool ret = false;
- pr_debug("al_thresh = %d, base = %d\n", al_thresh, base);
+ pr_debug("bl_min_delta = %d, base = %d\n", bl_min_delta, base);
if (base <= 0) {
pr_debug("Invalid base for threshold calculation %d\n", base);
return ret;
}
- bl_thresh = (curr_bl * al_thresh) / (base * 4);
+ bl_delta_factor = (curr_bl * bl_min_delta) / base;
diff = (curr_bl > prev_bl) ? (curr_bl - prev_bl) : (prev_bl - curr_bl);
- ret = (diff > bl_thresh) ? true : false;
- pr_debug("prev_bl =%d, curr_bl = %d, bl_thresh = %d, diff = %d, ret = %d\n",
- prev_bl, curr_bl, bl_thresh, diff, ret);
+ ret = (diff > bl_delta_factor) ? true : false;
+ pr_debug("prev_bl =%d, curr_bl = %d, bl_delta_factor = %d, diff = %d, ret = %d\n",
+ prev_bl, curr_bl, bl_delta_factor, diff, ret);
return ret;
}
@@ -3163,7 +3163,10 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out,
ad_bl_out = temp;
}
- if (pp_ad_bl_threshold_check(ad->init.al_thresh, ad->init.alpha_base,
+ /* update AD backlight based on AD BL low limit */
+ ad_bl_out = (ad_bl_out < ad->bl_low_limit ?
+ ad->bl_low_limit : ad_bl_out);
+ if (pp_ad_bl_threshold_check(ad->bl_min_delta, ad->init.alpha_base,
ad->last_bl, ad_bl_out)) {
mfd->ad_bl_level = ad_bl_out;
pr_debug("backlight send to AD block: %d\n", mfd->ad_bl_level);
@@ -5747,6 +5750,29 @@ ad_config_exit:
return ret;
}
+int mdss_mdp_ad_bl_config(struct msm_fb_data_type *mfd,
+ struct mdss_ad_bl_cfg *ad_bl_cfg)
+{
+ int ret = 0;
+ struct mdss_ad_info *ad;
+
+ ret = mdss_mdp_get_ad(mfd, &ad);
+ if (ret == -ENODEV || ret == -EPERM) {
+ pr_debug("AD not supported on device, disp num %d\n",
+ mfd->index);
+ return ret;
+ } else if (ret || !ad) {
+ pr_err("Failed to get ad info: ret = %d\n", ret);
+ return ret;
+ }
+
+ mutex_lock(&ad->lock);
+ ad->bl_min_delta = ad_bl_cfg->bl_min_delta;
+ ad->bl_low_limit = ad_bl_cfg->bl_low_limit;
+ mutex_unlock(&ad->lock);
+ return 0;
+}
+
int mdss_mdp_ad_input(struct msm_fb_data_type *mfd,
struct mdss_ad_input *input, int wait) {
int ret = 0;
@@ -6293,6 +6319,8 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd)
ad->last_calib_valid = false;
ad->last_ad_data_valid = false;
ad->ipc_frame_count = 0;
+ ad->bl_min_delta = 0;
+ ad->bl_low_limit = 0;
ad->calc_itr = 0;
ad->calc_hw_num = PP_AD_BAD_HW_NUM;
memset(&ad->last_calib, 0, sizeof(ad->last_calib));
@@ -6556,6 +6584,8 @@ int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets)
mdata->ad_cfgs[i].last_str = 0xFFFFFFFF;
mdata->ad_cfgs[i].last_bl = 0;
mdata->ad_cfgs[i].last_ad_data = 0;
+ mdata->ad_cfgs[i].bl_low_limit = 0;
+ mdata->ad_cfgs[i].bl_min_delta = 0;
memset(mdata->ad_cfgs[i].last_calib, 0,
sizeof(mdata->ad_cfgs[i].last_calib));
mdata->ad_cfgs[i].last_calib_valid = false;
diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h
index a1237ed996a5..1df65c7f90b3 100644
--- a/include/uapi/linux/msm_mdp.h
+++ b/include/uapi/linux/msm_mdp.h
@@ -1176,6 +1176,11 @@ struct mdss_ad_cfg {
uint32_t bl_ctrl_mode;
};
+struct mdss_ad_bl_cfg {
+ uint32_t bl_min_delta;
+ uint32_t bl_low_limit;
+};
+
/* ops uses standard MDP_PP_* flags */
struct mdss_ad_init_cfg {
uint32_t ops;
@@ -1220,11 +1225,14 @@ enum {
mdp_op_calib_dcm_state,
mdp_op_max,
mdp_op_pa_dither_cfg,
+ mdp_op_ad_bl_cfg,
mdp_op_pp_max = 255,
};
#define mdp_op_pa_dither_cfg mdp_op_pa_dither_cfg
#define mdp_op_pp_max mdp_op_pp_max
+#define mdp_op_ad_bl_cfg mdp_op_ad_bl_cfg
+
enum {
WB_FORMAT_NV12,
WB_FORMAT_RGB_565,
@@ -1254,6 +1262,7 @@ struct msmfb_mdp_pp {
struct mdss_ad_input ad_input;
struct mdp_calib_config_buffer calib_buffer;
struct mdp_calib_dcm_state calib_dcm;
+ struct mdss_ad_bl_cfg ad_bl_cfg;
} data;
};