diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 91 |
3 files changed, 68 insertions, 33 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 4219395883b6..7d68663c89ca 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -158,6 +158,7 @@ struct mdss_data_type { u32 nintf; u32 pp_bus_hdl; + struct mdss_mdp_ad *ad_off; struct mdss_ad_info *ad_cfgs; u32 nad_cfgs; struct workqueue_struct *ad_calc_wq; diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 1afc7d894eb6..b328aae91c5b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -277,9 +277,13 @@ struct pp_hist_col_info { spinlock_t hist_lock; }; -struct mdss_ad_info { +struct mdss_mdp_ad { char __iomem *base; u8 num; +}; + +struct mdss_ad_info { + u8 num; u32 sts; u32 state; u32 ad_data; @@ -294,6 +298,7 @@ struct mdss_ad_info { struct completion comp; u32 last_str; u32 last_bl; + u32 bl_data; u32 calc_itr; uint32_t bl_bright_shift; uint32_t bl_lin[AD_BL_LIN_LEN]; @@ -593,7 +598,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, struct mdss_ad_init_cfg *init_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_off); +int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets); int mdss_mdp_calib_mode(struct msm_fb_data_type *mfd, struct mdss_calib_cfg *cfg); diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index c7cc825070cc..6eca6ec9e464 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -367,9 +367,12 @@ static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, struct mdss_ad_info **ad); static int pp_update_ad_input(struct msm_fb_data_type *mfd); static void pp_ad_vsync_handler(struct mdss_mdp_ctl *ctl, ktime_t t); -static void pp_ad_cfg_write(struct mdss_ad_info *ad); -static void pp_ad_init_write(struct mdss_ad_info *ad); -static void pp_ad_input_write(struct mdss_ad_info *ad, u32 bl_lvl); +static void pp_ad_cfg_write(struct mdss_mdp_ad *ad_hw, + struct mdss_ad_info *ad); +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 int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd); static void pp_ad_cfg_lut(char __iomem *addr, u32 *data); @@ -1564,9 +1567,9 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) ad = &mdata->ad_cfgs[dspp_num]; if (PP_AD_STATE_CFG & ad->state) - pp_ad_cfg_write(ad); + pp_ad_cfg_write(&mdata->ad_off[dspp_num], ad); if (PP_AD_STATE_INIT & ad->state) - pp_ad_init_write(ad); + pp_ad_init_write(&mdata->ad_off[dspp_num], ad); if ((PP_AD_STATE_DATA & ad->state) && (ad->sts & PP_STS_ENABLE)) { bl = ad->bl_mfd->bl_level; @@ -1575,7 +1578,8 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) bl = ad->bl_lin[bl >> ad->bl_bright_shift]; bl = bl << ad->bl_bright_shift; } - pp_ad_input_write(ad, bl); + ad->bl_data = bl; + pp_ad_input_write(&mdata->ad_off[dspp_num], ad); } if ((PP_AD_STATE_VSYNC & ad->state) && ad->calc_itr) ctl->add_vsync_handler(ctl, &ad->handle); @@ -3694,23 +3698,26 @@ error: return ret; } -static void pp_ad_input_write(struct mdss_ad_info *ad, u32 bl_lvl) +static void pp_ad_input_write(struct mdss_mdp_ad *ad_hw, + struct mdss_ad_info *ad) { - char __iomem *base = ad->base; + char __iomem *base; + + base = ad_hw->base; switch (ad->cfg.mode) { case MDSS_AD_MODE_AUTO_BL: writel_relaxed(ad->ad_data, base + MDSS_MDP_REG_AD_AL); break; case MDSS_AD_MODE_AUTO_STR: - writel_relaxed(bl_lvl, base + MDSS_MDP_REG_AD_BL); + writel_relaxed(ad->bl_data, base + MDSS_MDP_REG_AD_BL); writel_relaxed(ad->ad_data, base + MDSS_MDP_REG_AD_AL); break; case MDSS_AD_MODE_TARG_STR: - writel_relaxed(bl_lvl, base + MDSS_MDP_REG_AD_BL); + writel_relaxed(ad->bl_data, base + MDSS_MDP_REG_AD_BL); writel_relaxed(ad->ad_data, base + MDSS_MDP_REG_AD_TARG_STR); break; case MDSS_AD_MODE_MAN_STR: - writel_relaxed(bl_lvl, base + MDSS_MDP_REG_AD_BL); + writel_relaxed(ad->bl_data, base + MDSS_MDP_REG_AD_BL); writel_relaxed(ad->ad_data, base + MDSS_MDP_REG_AD_STR_MAN); break; default: @@ -3719,10 +3726,12 @@ static void pp_ad_input_write(struct mdss_ad_info *ad, u32 bl_lvl) } } -static void pp_ad_init_write(struct mdss_ad_info *ad) +static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad) { u32 temp; - char __iomem *base = ad->base; + char __iomem *base; + + base = ad_hw->base; writel_relaxed(ad->init.i_control[0] & 0x1F, base + MDSS_MDP_REG_AD_CON_CTRL_0); writel_relaxed(ad->init.i_control[1] << 8, @@ -3760,10 +3769,12 @@ static void pp_ad_init_write(struct mdss_ad_info *ad) } #define MDSS_PP_AD_DEF_CALIB 0x6E -static void pp_ad_cfg_write(struct mdss_ad_info *ad) +static void pp_ad_cfg_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad) { - char __iomem *base = ad->base; + char __iomem *base; u32 temp, temp_calib = MDSS_PP_AD_DEF_CALIB; + + base = ad_hw->base; switch (ad->cfg.mode) { case MDSS_AD_MODE_AUTO_BL: temp = ad->cfg.backlight_max << 16; @@ -3816,9 +3827,10 @@ 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; - char __iomem *base; + struct mdss_data_type *mdata; u32 temp; u32 bypass = MDSS_PP_AD_BYPASS_DEF, bl; @@ -3833,8 +3845,8 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) bl_mfd = mfd; } - - base = ad->base; + 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) { @@ -3864,16 +3876,17 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) bl = ad->bl_lin[bl >> ad->bl_bright_shift]; bl = bl << ad->bl_bright_shift; } + ad->bl_data = bl; } mutex_unlock(&bl_mfd->bl_lock); - pp_ad_input_write(ad, bl); + pp_ad_input_write(ad_hw, ad); } 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); + pp_ad_cfg_write(ad_hw, ad); if (!MDSS_AD_MODE_DATA_MATCH(ad->cfg.mode, ad->ad_data_mode)) { ad->sts &= ~PP_AD_STS_DIRTY_DATA; @@ -3884,7 +3897,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); + pp_ad_init_write(ad_hw, ad); } /* update ad screen size if it has changed since last configuration */ @@ -3899,7 +3912,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) ad->init.frame_h = ctl->height; temp = ad->init.frame_w << 16; temp |= ad->init.frame_h & 0xFFFF; - writel_relaxed(temp, base + MDSS_MDP_REG_AD_FRAME_SIZE); + writel_relaxed(temp, ad_hw->base + MDSS_MDP_REG_AD_FRAME_SIZE); } if ((ad->sts & PP_STS_ENABLE) && PP_AD_STATE_IS_READY(ad->state)) { @@ -3942,7 +3955,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) } ad->state &= ~PP_AD_STATE_RUN; } - writel_relaxed(bypass, base); + writel_relaxed(bypass, ad_hw->base); if (PP_AD_STS_DIRTY_VSYNC & ad->sts) { pr_debug("dirty vsync, calc_itr = %d", ad->calc_itr); @@ -3974,6 +3987,8 @@ static void pp_ad_calc_worker(struct work_struct *work) struct mdss_ad_info *ad; struct mdss_mdp_ctl *ctl; struct msm_fb_data_type *mfd, *bl_mfd; + struct mdss_data_type *mdata; + char __iomem *base; u32 bl, calc_done = 0; ad = container_of(work, struct mdss_ad_info, calc_work); @@ -3985,6 +4000,9 @@ static void pp_ad_calc_worker(struct work_struct *work) mfd = ad->mfd; bl_mfd = ad->bl_mfd; ctl = mfd_to_ctl(ad->mfd); + mdata = mfd_to_mdata(ad->mfd); + + base = mdata->ad_off[ad->num].base; if ((ad->cfg.mode == MDSS_AD_MODE_AUTO_STR) && (ad->last_bl == 0)) { mutex_unlock(&ad->lock); @@ -3994,20 +4012,20 @@ static void pp_ad_calc_worker(struct work_struct *work) if (PP_AD_STATE_RUN & ad->state) { /* Kick off calculation */ ad->calc_itr--; - writel_relaxed(1, ad->base + MDSS_MDP_REG_AD_START_CALC); + writel_relaxed(1, base + MDSS_MDP_REG_AD_START_CALC); } if (ad->state & PP_AD_STATE_RUN) { do { - calc_done = readl_relaxed(ad->base + + calc_done = readl_relaxed(base + MDSS_MDP_REG_AD_CALC_DONE); if (!calc_done) usleep(MDSS_PP_AD_SLEEP); } while (!calc_done && (ad->state & PP_AD_STATE_RUN)); if (calc_done) { - ad->last_str = 0xFF & readl_relaxed(ad->base + + ad->last_str = 0xFF & readl_relaxed(base + MDSS_MDP_REG_AD_STR_OUT); if (MDSS_AD_RUNNING_AUTO_BL(ad)) { - bl = 0xFFFF & readl_relaxed(ad->base + + bl = 0xFFFF & readl_relaxed(base + MDSS_MDP_REG_AD_BL_OUT); if (ad->state & PP_AD_STATE_BL_LIN) { bl = bl >> ad->bl_bright_shift; @@ -4061,23 +4079,34 @@ static void pp_ad_cfg_lut(char __iomem *addr, u32 *data) addr + ((PP_AD_LUT_LEN - 1) * 2)); } -int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_off) +int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) { u32 i; int rc = 0; - mdata->ad_cfgs = devm_kzalloc(&mdata->pdev->dev, - sizeof(struct mdss_ad_info) * mdata->nad_cfgs, + mdata->ad_off = devm_kzalloc(&mdata->pdev->dev, + sizeof(struct mdss_mdp_ad) * mdata->nad_cfgs, GFP_KERNEL); + if (!mdata->ad_off) { + pr_err("unable to setup assertive display hw:devm_kzalloc fail\n"); + return -ENOMEM; + } + + mdata->ad_cfgs = devm_kzalloc(&mdata->pdev->dev, + sizeof(struct mdss_ad_info) * mdata->nad_cfgs, + GFP_KERNEL); + if (!mdata->ad_cfgs) { pr_err("unable to setup assertive display:devm_kzalloc fail\n"); + devm_kfree(&mdata->pdev->dev, mdata->ad_off); return -ENOMEM; } mdata->ad_calc_wq = create_singlethread_workqueue("ad_calc_wq"); for (i = 0; i < mdata->nad_cfgs; i++) { - mdata->ad_cfgs[i].base = mdata->mdp_base + ad_off[i]; + 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].calc_itr = 0; mdata->ad_cfgs[i].last_str = 0xFFFFFFFF; |
