diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index dd31f5cb06f6..a1fb3cab2a6a 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -3525,10 +3525,15 @@ static void _sde_cp_crtc_queue_ltm_buffer(struct sde_crtc *sde_crtc, void *cfg) struct sde_hw_cp_cfg *hw_cfg = cfg; struct drm_msm_ltm_buffer *buf; struct drm_msm_ltm_stats_data *ltm_data = NULL; + struct sde_ltm_buffer *free_buf; u32 i; bool found = false, already = false; unsigned long irq_flags; struct sde_ltm_buffer *buffer = NULL, *n = NULL; + u64 addr = 0; + bool submit_buf = false; + uint32_t num_mixers = 0; + struct sde_hw_dspp *hw_dspp = NULL; if (!sde_crtc || !cfg) { DRM_ERROR("invalid parameters sde_crtc %pK cfg %pK\n", sde_crtc, @@ -3541,6 +3546,7 @@ static void _sde_cp_crtc_queue_ltm_buffer(struct sde_crtc *sde_crtc, void *cfg) DRM_ERROR("invalid parameters payload %pK\n", buf); return; } + num_mixers = sde_crtc->num_mixers; spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags); if (!sde_crtc->ltm_buffer_cnt) { @@ -3549,6 +3555,8 @@ static void _sde_cp_crtc_queue_ltm_buffer(struct sde_crtc *sde_crtc, void *cfg) return; } + if (list_empty(&sde_crtc->ltm_buf_free)) + submit_buf = true; for (i = 0; i < LTM_BUFFER_SIZE; i++) { if (sde_crtc->ltm_buffers[i] && buf->fd == sde_crtc->ltm_buffers[i]->drm_fb_id) { @@ -3569,6 +3577,20 @@ static void _sde_cp_crtc_queue_ltm_buffer(struct sde_crtc *sde_crtc, void *cfg) found = true; } } + if (submit_buf && found) { + free_buf = list_first_entry(&sde_crtc->ltm_buf_free, + struct sde_ltm_buffer, node); + addr = free_buf->iova + free_buf->offset; + + for (i = 0; i < num_mixers; i++) { + hw_dspp = sde_crtc->mixers[i].hw_dspp; + if (!hw_dspp) { + DRM_ERROR("invalid dspp for mixer %d\n", i); + break; + } + hw_dspp->ops.setup_ltm_hist_buffer(hw_dspp, addr); + } + } spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags); if (!found)