summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c7
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c20
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c14
5 files changed, 34 insertions, 10 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index cb9cc08140f0..0613ad786092 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -555,6 +555,7 @@ struct mdss_mdp_ctl {
bool switch_with_handoff;
struct mdss_mdp_avr_info avr_info;
bool commit_in_progress;
+ struct mutex ds_lock;
};
struct mdss_mdp_mixer {
@@ -1969,6 +1970,7 @@ void mdss_mdp_enable_hw_irq(struct mdss_data_type *mdata);
void mdss_mdp_disable_hw_irq(struct mdss_data_type *mdata);
void mdss_mdp_set_supported_formats(struct mdss_data_type *mdata);
+int mdss_mdp_dest_scaler_setup_locked(struct mdss_mdp_mixer *mixer);
#ifdef CONFIG_FB_MSM_MDP_NONE
struct mdss_data_type *mdss_mdp_get_mdata(void)
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index ffbf156e9eed..8b31ff648942 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -2407,6 +2407,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata,
mutex_init(&ctl->flush_lock);
mutex_init(&ctl->rsrc_lock);
spin_lock_init(&ctl->spin_lock);
+ mutex_init(&ctl->ds_lock);
BLOCKING_INIT_NOTIFIER_HEAD(&ctl->notifier_head);
pr_debug("alloc ctl_num=%d\n", ctl->num);
break;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index 0eb82dd8371d..c9e32d69d444 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -399,6 +399,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
ctl = mfd_to_ctl(mfd);
sctl = mdss_mdp_get_split_ctl(ctl);
+ mutex_lock(&ctl->ds_lock);
if (ctl->mixer_left)
ds_left = ctl->mixer_left->ds;
@@ -412,6 +413,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
case DS_DUAL_MODE:
if (!ds_left || !ds_right) {
pr_err("Cannot support DUAL mode dest scaling\n");
+ mutex_unlock(&ctl->ds_lock);
return -EINVAL;
}
@@ -457,6 +459,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
case DS_LEFT:
if (!ds_left) {
pr_err("LM in ctl does not support Destination Scaler\n");
+ mutex_unlock(&ctl->ds_lock);
return -EINVAL;
}
ds_left->flags &= ~(DS_DUAL_MODE|DS_RIGHT);
@@ -486,6 +489,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
case DS_RIGHT:
if (!ds_right) {
pr_err("Cannot setup DS_RIGHT because only single DS assigned to ctl\n");
+ mutex_unlock(&ctl->ds_lock);
return -EINVAL;
}
@@ -522,7 +526,6 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
ds_right->src_height, ds_right->flags);
break;
}
-
} else {
pr_err("NULL destionation scaler data\n");
return -EFAULT;
@@ -559,6 +562,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
goto reset_mixer;
}
+ mutex_unlock(&ctl->ds_lock);
return ret;
reset_mixer:
@@ -592,6 +596,7 @@ reset_mixer:
ctl->mixer_right->height);
}
+ mutex_unlock(&ctl->ds_lock);
return ret;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 9864d611e8e4..a5e2dccb2501 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1471,6 +1471,23 @@ static void __unstage_pipe_and_clean_buf(struct msm_fb_data_type *mfd,
__pipe_buf_mark_cleanup(mfd, buf);
}
+static int __dest_scaler_setup(struct msm_fb_data_type *mfd)
+{
+ struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
+
+ mutex_lock(&ctl->ds_lock);
+
+ if (ctl->mixer_left)
+ mdss_mdp_dest_scaler_setup_locked(ctl->mixer_left);
+
+ if (ctl->mixer_right)
+ mdss_mdp_dest_scaler_setup_locked(ctl->mixer_right);
+
+ mutex_unlock(&ctl->ds_lock);
+
+ return 0;
+}
+
static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
{
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
@@ -2394,6 +2411,9 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
mutex_unlock(&mdp5_data->list_lock);
mdp5_data->kickoff_released = false;
+ ATRACE_BEGIN("dest_scaler_programming");
+ ret = __dest_scaler_setup(mfd);
+ ATRACE_END("dest_scaler_programming");
if (mfd->panel.type == WRITEBACK_PANEL) {
ATRACE_BEGIN("wb_kickoff");
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index d83bedacec28..7212de8a43f9 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -2559,7 +2559,7 @@ dspp_exit:
return ret;
}
-static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)
+int mdss_mdp_dest_scaler_setup_locked(struct mdss_mdp_mixer *mixer)
{
struct mdss_mdp_ctl *ctl;
struct mdss_data_type *mdata;
@@ -2618,7 +2618,8 @@ static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)
writel_relaxed(op_mode, MDSS_MDP_REG_DEST_SCALER_OP_MODE + ds_offset);
- if (ds->flags & DS_SCALE_UPDATE) {
+ if ((ds->flags & DS_SCALE_UPDATE) ||
+ (ds->flags & DS_ENHANCER_UPDATE)) {
ret = mdss_mdp_qseed3_setup(&ds->scaler,
ds->scaler_base, ds->lut_base,
&dest_scaler_fmt);
@@ -2631,11 +2632,6 @@ static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)
* for each commit if there is no change.
*/
ds->flags &= ~DS_SCALE_UPDATE;
- }
-
- if (ds->flags & DS_ENHANCER_UPDATE) {
- mdss_mdp_scaler_detail_enhance_cfg(&ds->scaler.detail_enhance,
- ds->scaler_base);
ds->flags &= ~DS_ENHANCER_UPDATE;
}
@@ -2643,7 +2639,9 @@ static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)
if (ds->flags & (DS_ENABLE | DS_VALIDATE)) {
pr_debug("FLUSH[%d]: flags:%X, op_mode:%x\n",
ds->num, ds->flags, op_mode);
+ mutex_lock(&ctl->flush_lock);
ctl->flush_bits |= BIT(13 + ds->num);
+ mutex_unlock(&ctl->flush_lock);
}
ds->flags &= ~DS_VALIDATE;
@@ -2760,13 +2758,11 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
}
if (ctl->mixer_left) {
- pp_dest_scaler_setup(ctl->mixer_left);
pp_mixer_setup(ctl->mixer_left);
pp_dspp_setup(disp_num, ctl->mixer_left);
pp_ppb_setup(ctl->mixer_left);
}
if (ctl->mixer_right) {
- pp_dest_scaler_setup(ctl->mixer_right);
pp_mixer_setup(ctl->mixer_right);
pp_dspp_setup(disp_num, ctl->mixer_right);
pp_ppb_setup(ctl->mixer_right);