diff options
author | Oleg Matcovschi <omatcovschi@google.com> | 2023-11-06 17:58:56 -0800 |
---|---|---|
committer | Leo Chen <yinchiuan@google.com> | 2023-12-01 03:21:38 +0000 |
commit | 491274747498fd0030098b079995062aa1697f33 (patch) | |
tree | 038e717f96138528da42b8aea56d132754b4c024 | |
parent | 7cc51fb279cb5143c8ea23bfc2d16b900fc81880 (diff) | |
download | display-491274747498fd0030098b079995062aa1697f33.tar.gz |
dqe: take into account decon hw state on hibernation_enter
Bug: 297983015
Test: adb logcat | egrep -i "histogram"
Change-Id: I8596a4c1d0b294bc96a8e0b87fe3cb2b6c763064
Signed-off-by: Oleg Matcovschi <omatcovschi@google.com>
Signed-off-by: Leo Chen <yinchiuan@google.com>
-rw-r--r-- | samsung/exynos_drm_dqe.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/samsung/exynos_drm_dqe.c b/samsung/exynos_drm_dqe.c index e776107..ba4a384 100644 --- a/samsung/exynos_drm_dqe.c +++ b/samsung/exynos_drm_dqe.c @@ -344,13 +344,37 @@ int histogram_chan_set_state(struct exynos_dqe *dqe, const enum exynos_histogram return 0; } +static void histogram_chan_handle_event_locked(struct exynos_dqe *dqe, uint32_t hist_id, + bool force_collect) +{ + struct histogram_chan_state *hist_chan = &dqe->state.hist_chan[hist_id]; + histogram_chan_callback hist_cb = hist_chan->cb; + struct exynos_drm_pending_histogram_event *e = hist_chan->event; + + if (!e && !hist_cb && !force_collect) + return; + + histogram_chan_collect_bins_locked(dqe, hist_id, &hist_chan->bins); + + /* handle DRM request */ + if (e) { + pr_debug("decon%u histogram%u: handle event(0x%pK), rstate(%s)\n", dqe->decon->id, + hist_id, e, str_run_state(hist_chan->run_state)); + memcpy(&e->event.bins, &hist_chan->bins, sizeof(e->event.bins)); + histogram_chan_emmit_event_locked(dqe, hist_id); + } + + /* handle LHBM request. TODO: review if LHBM can be moved to DRM fw. */ + if (hist_cb) + (hist_cb)(dqe->decon->id, hist_id, &hist_chan->bins); +} + /* This function runs in interrupt context */ void handle_histogram_event(struct exynos_dqe *dqe) { - uint32_t id, hist_id; + uint32_t hist_id; spin_lock(&dqe->state.histogram_slock); - id = dqe->decon->id; /* * histogram engine data is available after first frame done. @@ -358,27 +382,12 @@ void handle_histogram_event(struct exynos_dqe *dqe) */ for (hist_id = 0; hist_id < HISTOGRAM_MAX; hist_id++) { struct histogram_chan_state *hist_chan = &dqe->state.hist_chan[hist_id]; - histogram_chan_callback hist_cb = hist_chan->cb; - struct exynos_drm_pending_histogram_event *e = hist_chan->event; /* skip if histogram channel is disabled */ if (hist_chan->run_state == HSTATE_DISABLED) continue; - /* handle DRM request */ - if (e) { - pr_debug("histogram: handle event(0x%pK), rstate(%s)\n", - e, str_run_state(hist_chan->run_state)); - histogram_chan_collect_bins_locked(dqe, hist_id, &hist_chan->bins); - memcpy(&e->event.bins, &hist_chan->bins, sizeof(e->event.bins)); - histogram_chan_emmit_event_locked(dqe, hist_id); - } - - /* handle LHBM request. TODO: review if LHBM can be moved to DRM fw. */ - if (hist_cb) { - histogram_chan_collect_bins_locked(dqe, hist_id, &hist_chan->bins); - (hist_cb)(id, hist_id, &hist_chan->bins); - } + histogram_chan_handle_event_locked(dqe, hist_id, false); if ((atomic_read(&dqe->decon->frames_pending) == 0) && (dqe->decon->config.mode.op_mode != DECON_VIDEO_MODE)) @@ -795,11 +804,14 @@ void exynos_dqe_hibernation_enter(struct exynos_dqe *dqe) unsigned long flags; enum exynos_histogram_id hist_id; struct histogram_chan_state *hist_chan; + bool decon_idle; if (!dqe->state.enabled) return; spin_lock_irqsave(&dqe->state.histogram_slock, flags); + decon_idle = decon_reg_is_idle(dqe->decon->id); + for (hist_id = 0; hist_id < HISTOGRAM_MAX; hist_id++) { hist_chan = &dqe->state.hist_chan[hist_id]; @@ -807,8 +819,20 @@ void exynos_dqe_hibernation_enter(struct exynos_dqe *dqe) histogram_chan_collect_bins_locked(dqe, hist_id, &hist_chan->bins); histogram_chan_set_run_state_locked(dqe, hist_id, HSTATE_HIBERNATION); } else if (hist_chan->run_state == HSTATE_PENDING_FRAMEDONE) { - /* mark as disabled to avoid start_pending_framedone related issues */ - histogram_chan_set_run_state_locked(dqe, hist_id, HSTATE_DISABLED); + if (!decon_idle) { + /* mark as disabled to avoid start_pending_framedone + * related issues + */ + pr_warn("decon%u histogram%u: pending framedone during hibernation\n", + dqe->decon->id, hist_id); + histogram_chan_set_run_state_locked(dqe, hist_id, HSTATE_DISABLED); + } else { + pr_debug("decon%u histogram%u: decon is already idle\n", + dqe->decon->id, hist_id); + histogram_chan_handle_event_locked(dqe, hist_id, true); + histogram_chan_set_run_state_locked(dqe, hist_id, + HSTATE_HIBERNATION); + } } } spin_unlock_irqrestore(&dqe->state.histogram_slock, flags); |