|
@@ -2049,6 +2049,41 @@ static int _sde_cp_crtc_update_pu_features(struct drm_crtc *crtc, bool *need_flu
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void _sde_clear_ltm_merge_mode(struct sde_crtc *sde_crtc)
|
|
|
+{
|
|
|
+ u32 num_mixers = 0, i = 0;
|
|
|
+ struct sde_hw_ctl *ctl = NULL;
|
|
|
+ struct sde_hw_dspp *hw_dspp = NULL;
|
|
|
+ unsigned long irq_flags;
|
|
|
+
|
|
|
+ num_mixers = sde_crtc->num_mixers;
|
|
|
+ if (!num_mixers) {
|
|
|
+ DRM_ERROR("no mixers for this crtc\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags);
|
|
|
+ if (!sde_crtc->ltm_merge_clear_pending) {
|
|
|
+ spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ _sde_cp_dspp_flush_helper(sde_crtc, SDE_CP_CRTC_DSPP_LTM_HIST_CTL);
|
|
|
+ for (i = 0; i < num_mixers; i++) {
|
|
|
+ hw_dspp = sde_crtc->mixers[i].hw_dspp;
|
|
|
+ ctl = sde_crtc->mixers[i].hw_ctl;
|
|
|
+ if (!hw_dspp || !ctl || i >= DSPP_MAX)
|
|
|
+ continue;
|
|
|
+ if (hw_dspp->ops.clear_ltm_merge_mode)
|
|
|
+ hw_dspp->ops.clear_ltm_merge_mode(hw_dspp);
|
|
|
+ if (ctl->ops.update_bitmask_dspp)
|
|
|
+ ctl->ops.update_bitmask_dspp(ctl, hw_dspp->idx, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ sde_crtc->ltm_merge_clear_pending = false;
|
|
|
+ spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags);
|
|
|
+}
|
|
|
+
|
|
|
void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
|
|
|
{
|
|
|
struct sde_crtc *sde_crtc = NULL;
|
|
@@ -2086,6 +2121,7 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
|
|
|
|
|
|
_sde_cp_flush_properties(crtc);
|
|
|
mutex_lock(&sde_crtc->crtc_cp_lock);
|
|
|
+ _sde_clear_ltm_merge_mode(sde_crtc);
|
|
|
|
|
|
if (list_empty(&sde_crtc->cp_dirty_list) &&
|
|
|
list_empty(&sde_crtc->ad_dirty) &&
|
|
@@ -2554,6 +2590,7 @@ void sde_cp_crtc_destroy_properties(struct drm_crtc *crtc)
|
|
|
}
|
|
|
sde_crtc->ltm_buffer_cnt = 0;
|
|
|
sde_crtc->ltm_hist_en = false;
|
|
|
+ sde_crtc->ltm_merge_clear_pending = false;
|
|
|
sde_crtc->hist_irq_idx = -1;
|
|
|
|
|
|
mutex_destroy(&sde_crtc->crtc_cp_lock);
|
|
@@ -2711,6 +2748,7 @@ void sde_cp_crtc_clear(struct drm_crtc *crtc)
|
|
|
}
|
|
|
sde_crtc->ltm_buffer_cnt = 0;
|
|
|
sde_crtc->ltm_hist_en = false;
|
|
|
+ sde_crtc->ltm_merge_clear_pending = false;
|
|
|
sde_crtc->hist_irq_idx = -1;
|
|
|
INIT_LIST_HEAD(&sde_crtc->ltm_buf_free);
|
|
|
INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy);
|
|
@@ -4104,6 +4142,7 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc,
|
|
|
|
|
|
spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags);
|
|
|
sde_crtc->ltm_hist_en = false;
|
|
|
+ sde_crtc->ltm_merge_clear_pending = true;
|
|
|
INIT_LIST_HEAD(&sde_crtc->ltm_buf_free);
|
|
|
INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy);
|
|
|
for (i = 0; i < sde_crtc->ltm_buffer_cnt; i++)
|
|
@@ -4175,7 +4214,7 @@ static void _sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx)
|
|
|
hw_dspp->ops.setup_ltm_hist_ctrl(hw_dspp, NULL, false,
|
|
|
0);
|
|
|
}
|
|
|
-
|
|
|
+ sde_crtc->ltm_merge_clear_pending = true;
|
|
|
spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags);
|
|
|
DRM_DEBUG_DRIVER("LTM histogram is disabled\n");
|
|
|
return;
|