OSDN Git Service

msm: mdss: Update backlight filter for AD
authorPing Li <pingli@codeaurora.org>
Wed, 4 May 2016 18:03:09 +0000 (11:03 -0700)
committerGerrit - the friendly Code Review server <code-review@localhost>
Thu, 21 Jul 2016 17:36:44 +0000 (10:36 -0700)
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>
drivers/video/fbdev/msm/mdss_mdp.h
drivers/video/fbdev/msm/mdss_mdp_overlay.c
drivers/video/fbdev/msm/mdss_mdp_pp.c
include/uapi/linux/msm_mdp.h

index d6cd682..da5e7bb 100644 (file)
@@ -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);
index 2baa1b9..e5cdc75 100644 (file)
@@ -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) {
index c4cbc22..a760711 100644 (file)
@@ -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;
index a1237ed..1df65c7 100644 (file)
@@ -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;
 };