msm: mdss: fix backlight update between unblank and kickoff

The backlight update between unblank and kickoff
call may result in garbage/snow screen on panel
based on panel ram initialized status.

For ex:
  -> Unblank the panel - black frame transfer start,
                         panel is on but ram is still
                         uninitialized.
  -> backlight update - turn on the backlight. It will show
                        data from uninitialized ram because
                        frame transfer is not complete yet.

This can be avoided by blocking the backlight update
request between unblank and first frame kickoff. This
gives guarantee that panel has valid data to display
when backlight was turned on.

Change-Id: I09c707cd10acd53bd6aa0935885269ffc5aec649
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
This commit is contained in:
Dhaval Patel 2015-10-21 10:55:51 -07:00 committed by David Keitel
parent 683be4aae5
commit f97adf46f5
3 changed files with 16 additions and 9 deletions

View file

@ -662,7 +662,7 @@ static int mdss_fb_blanking_mode_switch(struct msm_fb_data_type *mfd, int mode)
unlock_fb_info(mfd->fbi);
mutex_lock(&mfd->bl_lock);
mfd->bl_updated = true;
mfd->allow_bl_update = true;
mdss_fb_set_backlight(mfd, bl_lvl);
mutex_unlock(&mfd->bl_lock);
@ -1472,7 +1472,7 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl)
bool bl_notify_needed = false;
if ((((mdss_fb_is_power_off(mfd) && mfd->dcm_state != DCM_ENTER)
|| !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) ||
|| !mfd->allow_bl_update) && !IS_CALIB_MODE_BL(mfd)) ||
mfd->panel_info->cont_splash_enabled) {
mfd->unset_bl_level = bkl_lvl;
return;
@ -1526,7 +1526,7 @@ void mdss_fb_update_backlight(struct msm_fb_data_type *mfd)
if (!mfd->unset_bl_level)
return;
mutex_lock(&mfd->bl_lock);
if (!mfd->bl_updated) {
if (!mfd->allow_bl_update) {
pdata = dev_get_platdata(&mfd->pdev->dev);
if ((pdata) && (pdata->set_backlight)) {
mfd->bl_level = mfd->unset_bl_level;
@ -1539,7 +1539,7 @@ void mdss_fb_update_backlight(struct msm_fb_data_type *mfd)
NOTIFY_TYPE_BL_AD_ATTEN_UPDATE);
pdata->set_backlight(pdata, temp);
mfd->bl_level_scaled = mfd->unset_bl_level;
mfd->bl_updated = 1;
mfd->allow_bl_update = true;
}
}
mutex_unlock(&mfd->bl_lock);
@ -1645,7 +1645,7 @@ static int mdss_fb_blank_blank(struct msm_fb_data_type *mfd,
mutex_lock(&mfd->bl_lock);
current_bl = mfd->bl_level;
mdss_fb_set_backlight(mfd, 0);
mfd->bl_updated = 0;
mfd->allow_bl_update = false;
mfd->unset_bl_level = current_bl;
mutex_unlock(&mfd->bl_lock);
}
@ -1722,8 +1722,8 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd)
/* Reset the backlight only if the panel was off */
if (mdss_panel_is_power_off(cur_power_state)) {
mutex_lock(&mfd->bl_lock);
if (!mfd->bl_updated) {
mfd->bl_updated = 1;
if (!mfd->allow_bl_update) {
mfd->allow_bl_update = true;
/*
* If in AD calibration mode then frameworks would not
* be allowed to update backlight hence post unblank
@ -1734,6 +1734,13 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd)
mdss_fb_set_backlight(mfd, mfd->unset_bl_level);
else
mdss_fb_set_backlight(mfd, mfd->calib_mode_bl);
/*
* it blocks the backlight update between unblank and
* first kickoff to avoid backlight turn on before black
* frame is transferred to panel through unblank call.
*/
mfd->allow_bl_update = false;
}
mutex_unlock(&mfd->bl_lock);
}

View file

@ -301,7 +301,7 @@ struct msm_fb_data_type {
u32 bl_scale;
u32 bl_min_lvl;
u32 unset_bl_level;
u32 bl_updated;
bool allow_bl_update;
u32 bl_level_scaled;
struct mutex bl_lock;

View file

@ -587,7 +587,7 @@ static int mdss_mdp_splash_thread(void *data)
unlock_fb_info(mfd->fbi);
mutex_lock(&mfd->bl_lock);
mfd->bl_updated = true;
mfd->allow_bl_update = true;
mdss_fb_set_backlight(mfd, mfd->panel_info->bl_max >> 1);
mutex_unlock(&mfd->bl_lock);