diff options
| author | Carl Vanderlip <carlv@codeaurora.org> | 2013-10-18 15:34:20 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:23:23 -0700 |
| commit | 3a5af245d73ecb7d69c6dfe8260644cb522ae4e3 (patch) | |
| tree | 42a9e207331f2b700feea6c6b1b5548ce618012a /drivers/video/fbdev | |
| parent | f974b39842413dd88c71a0e0332c44e7b06f8a7b (diff) | |
msm: mdss: Relocate Assertive Display register access
Move the register writes for Assertive Display (AD) into the dspp_setup
function. This separates the state of AD from the configuration of the
hardware and adds to the implementation of dual pipe AD feature.
Change-Id: I9f21f9461b3d4ae3c29ad52e17ad33d8e6e4b904
Signed-off-by: Carl Vanderlip <carlv@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 60 |
2 files changed, 48 insertions, 13 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index b328aae91c5b..07ccb652bb8b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -285,6 +285,7 @@ struct mdss_mdp_ad { struct mdss_ad_info { u8 num; u32 sts; + u32 reg_sts; u32 state; u32 ad_data; u32 ad_data_mode; diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index b605a8e0afae..d932fdb89fa8 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -373,6 +373,7 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad); static void pp_ad_input_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad); +static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode); static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd); static void pp_ad_cfg_lut(char __iomem *addr, u32 *data); @@ -1388,12 +1389,14 @@ static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) { - u32 flags, dspp_num, opmode = 0; + u32 ad_flags, flags, dspp_num, opmode = 0, ad_bypass; struct mdp_pgc_lut_data *pgc_config; struct pp_sts_type *pp_sts; char __iomem *base, *addr; int ret = 0; struct mdss_data_type *mdata; + struct mdss_ad_info *ad = NULL; + struct mdss_mdp_ad *ad_hw = NULL; struct mdss_mdp_ctl *ctl; u32 mixer_cnt; u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; @@ -1423,15 +1426,21 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id); if (dspp_num < mdata->nad_cfgs && (mixer_cnt != 2)) { ret = mdss_mdp_ad_setup(ctl->mfd); + ad = &mdata->ad_cfgs[disp_num]; + ad_flags = ad->reg_sts; + ad_hw = &mdata->ad_off[dspp_num]; if (ret < 0) pr_warn("ad_setup(dspp%d) returns %d", dspp_num, ret); + } else { + ad_flags = 0; } + /* call calibration specific processing here */ if (ctl->mfd->calib_mode) goto flush_exit; /* nothing to update */ - if ((!flags) && (!(opmode)) && (ret <= 0)) + if ((!flags) && (!(opmode)) && (ret <= 0) && (!ad_flags)) goto dspp_exit; ret = 0; @@ -1485,6 +1494,20 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) pp_sts->pgc_sts |= PP_STS_ENABLE; } + if (ad_hw) { + mutex_lock(&ad->lock); + ad_flags = ad->reg_sts; + if (ad_flags & PP_AD_STS_DIRTY_DATA) + pp_ad_input_write(ad_hw, ad); + if (ad_flags & PP_AD_STS_DIRTY_INIT) + pp_ad_init_write(ad_hw, ad); + if (ad_flags & PP_AD_STS_DIRTY_CFG) + pp_ad_cfg_write(ad_hw, ad); + pp_ad_bypass_config(ad, &ad_bypass); + writel_relaxed(ad_bypass, ad_hw->base); + mutex_unlock(&ad->lock); + } + pp_dspp_opmode_config(pp_sts, &opmode, mdata->mdp_rev); flush_exit: writel_relaxed(opmode, base + MDSS_MDP_REG_DSPP_OP_MODE); @@ -1523,6 +1546,7 @@ error: /* call only when holding and mfd->lock */ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl) { + struct mdss_data_type *mdata = ctl->mdata; u32 disp_num; if ((!ctl->mfd) || (!mdss_pp_res)) return -EINVAL; @@ -1540,8 +1564,11 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl) pp_dspp_setup(disp_num, ctl->mixer_right); } /* clear dirty flag */ - if (disp_num < MDSS_BLOCK_DISP_NUM) + if (disp_num < MDSS_BLOCK_DISP_NUM) { mdss_pp_res->pp_disp_flags[disp_num] = 0; + if (disp_num < mdata->nad_cfgs) + mdata->ad_cfgs[disp_num].reg_sts = 0; + } mutex_unlock(&mdss_pp_mutex); return 0; @@ -3823,15 +3850,21 @@ static void pp_ad_vsync_handler(struct mdss_mdp_ctl *ctl, ktime_t t) } #define MDSS_PP_AD_BYPASS_DEF 0x101 +static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode) +{ + if (ad->reg_sts & PP_STS_ENABLE) + *opmode = 0; + else + *opmode = MDSS_PP_AD_BYPASS_DEF; +} + static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) { int ret = 0; struct mdss_ad_info *ad; - struct mdss_mdp_ad *ad_hw; struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); struct msm_fb_data_type *bl_mfd; struct mdss_data_type *mdata; - u32 temp; u32 bypass = MDSS_PP_AD_BYPASS_DEF, bl; ret = mdss_mdp_get_ad(mfd, &ad); @@ -3846,7 +3879,6 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) } mdata = mfd_to_mdata(mfd); - ad_hw = &mdata->ad_off[ad->num]; mutex_lock(&ad->lock); if (ad->sts != last_sts || ad->state != last_state) { @@ -3879,14 +3911,14 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) ad->bl_data = bl; } mutex_unlock(&bl_mfd->bl_lock); - pp_ad_input_write(ad_hw, ad); + ad->reg_sts |= PP_AD_STS_DIRTY_DATA; } if (ad->sts & PP_AD_STS_DIRTY_CFG) { ad->sts &= ~PP_AD_STS_DIRTY_CFG; ad->state |= PP_AD_STATE_CFG; - pp_ad_cfg_write(ad_hw, ad); + ad->reg_sts |= PP_AD_STS_DIRTY_CFG; if (!MDSS_AD_MODE_DATA_MATCH(ad->cfg.mode, ad->ad_data_mode)) { ad->sts &= ~PP_AD_STS_DIRTY_DATA; @@ -3897,7 +3929,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) if (ad->sts & PP_AD_STS_DIRTY_INIT) { ad->sts &= ~PP_AD_STS_DIRTY_INIT; ad->state |= PP_AD_STATE_INIT; - pp_ad_init_write(ad_hw, ad); + ad->reg_sts |= PP_AD_STS_DIRTY_INIT; } /* update ad screen size if it has changed since last configuration */ @@ -3910,9 +3942,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) ctl->height); ad->init.frame_w = ctl->width; ad->init.frame_h = ctl->height; - temp = ad->init.frame_w << 16; - temp |= ad->init.frame_h & 0xFFFF; - writel_relaxed(temp, ad_hw->base + MDSS_MDP_REG_AD_FRAME_SIZE); + ad->reg_sts |= PP_AD_STS_DIRTY_INIT; } if ((ad->sts & PP_STS_ENABLE) && PP_AD_STATE_IS_READY(ad->state)) { @@ -3955,7 +3985,10 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) } ad->state &= ~PP_AD_STATE_RUN; } - writel_relaxed(bypass, ad_hw->base); + if (!bypass) + ad->reg_sts |= PP_STS_ENABLE; + else + ad->reg_sts &= ~PP_STS_ENABLE; if (PP_AD_STS_DIRTY_VSYNC & ad->sts) { pr_debug("dirty vsync, calc_itr = %d", ad->calc_itr); @@ -4108,6 +4141,7 @@ int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) mdata->ad_off[i].base = mdata->mdp_base + ad_offsets[i]; mdata->ad_off[i].num = i; mdata->ad_cfgs[i].num = i; + mdata->ad_cfgs[i].reg_sts = 0; mdata->ad_cfgs[i].calc_itr = 0; mdata->ad_cfgs[i].last_str = 0xFFFFFFFF; mdata->ad_cfgs[i].last_bl = 0; |
