summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorCarl Vanderlip <carlv@codeaurora.org>2013-10-17 19:17:59 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:23:19 -0700
commit6b9c8beae3734ceccaf71e895e83a3fbb76e693b (patch)
treeeaafb2cd594c11a8be400b5c50133b95cee9b333 /drivers
parentf3e87acf5eee5329530195e1e8445780e77052fc (diff)
msm: mdss: Separate AD info from AD hardware base address
Splitting the AD info struct, which is used primarily to store state, from the hardware blocks. Functionality is preserved by passing the structures containing hardware information to the functions that execute the register writes. This change is necessary for dual pipe operation where one AD state machine controls more than one AD hardware block. Change-Id: Ia0d8be6b70d121095df2bbaa102b7dedd26f2302 Signed-off-by: Carl Vanderlip <carlv@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/fbdev/msm/mdss.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h9
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c91
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;