diff options
| author | Abhinav Kumar <abhinavk@codeaurora.org> | 2017-10-13 18:43:52 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-10-17 19:19:44 -0700 |
| commit | cf2cb1c388d1038952f776e2b36837c8e3695a49 (patch) | |
| tree | f48e1495e2269fa2fa7086aa7323390563002db4 /drivers/gpu | |
| parent | 88f238f1774c00b1ceaab59f038832ace54e3e3f (diff) | |
drm/msm/sde: align bandwidth/clock updates with frame done
Align clock and bandwidth updates witf frame done event for
video mode panels.
Also move perf state update to atomic check to make perf data
persistent over state duplication.
Change-Id: I5ef02dd78ce6a62cf49f1f105344764fdb3a24da
Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_core_perf.c | 70 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_crtc.c | 7 |
2 files changed, 44 insertions, 33 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.c b/drivers/gpu/drm/msm/sde/sde_core_perf.c index 0ba644d5519d..4d98b89fd007 100644 --- a/drivers/gpu/drm/msm/sde/sde_core_perf.c +++ b/drivers/gpu/drm/msm/sde/sde_core_perf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -75,6 +75,31 @@ static bool _sde_core_video_mode_intf_connected(struct drm_crtc *crtc) return false; } +static void _sde_core_perf_calc_crtc(struct drm_crtc *crtc, + struct drm_crtc_state *state, + struct sde_core_perf_params *perf) +{ + struct sde_crtc_state *sde_cstate; + + if (!crtc || !state || !perf) { + SDE_ERROR("invalid parameters\n"); + return; + } + + sde_cstate = to_sde_crtc_state(state); + memset(perf, 0, sizeof(struct sde_core_perf_params)); + + perf->bw_ctl = sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_AB); + perf->max_per_pipe_ib = + sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_IB); + perf->core_clk_rate = + sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_CLK); + + SDE_DEBUG("crtc=%d clk_rate=%u ib=%llu ab=%llu\n", + crtc->base.id, perf->core_clk_rate, + perf->max_per_pipe_ib, perf->bw_ctl); +} + int sde_core_perf_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -102,7 +127,11 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc, sde_cstate = to_sde_crtc_state(state); - bw_sum_of_intfs = sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_AB); + /* swap state and obtain new values */ + sde_cstate->cur_perf = sde_cstate->new_perf; + _sde_core_perf_calc_crtc(crtc, state, &sde_cstate->new_perf); + + bw_sum_of_intfs = sde_cstate->new_perf.bw_ctl; drm_for_each_crtc(tmp_crtc, crtc->dev) { if (_sde_core_perf_crtc_is_power_on(tmp_crtc) && @@ -110,7 +139,7 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc, struct sde_crtc_state *tmp_cstate = to_sde_crtc_state(tmp_crtc->state); - bw_sum_of_intfs += tmp_cstate->cur_perf.bw_ctl; + bw_sum_of_intfs += tmp_cstate->new_perf.bw_ctl; } } @@ -126,11 +155,11 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc, SDE_DEBUG("final threshold bw limit = %d\n", threshold); if (!threshold) { - sde_cstate->cur_perf.bw_ctl = 0; + sde_cstate->new_perf = sde_cstate->cur_perf; SDE_ERROR("no bandwidth limits specified\n"); return -E2BIG; } else if (bw > threshold) { - sde_cstate->cur_perf.bw_ctl = 0; + sde_cstate->new_perf = sde_cstate->cur_perf; SDE_DEBUG("exceeds bandwidth: %ukb > %ukb\n", bw, threshold); return -E2BIG; } @@ -138,26 +167,6 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc, return 0; } -static void _sde_core_perf_calc_crtc(struct sde_kms *kms, - struct drm_crtc *crtc, - struct sde_core_perf_params *perf) -{ - struct sde_crtc_state *sde_cstate; - - sde_cstate = to_sde_crtc_state(crtc->state); - memset(perf, 0, sizeof(struct sde_core_perf_params)); - - perf->bw_ctl = sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_AB); - perf->max_per_pipe_ib = - sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_IB); - perf->core_clk_rate = - sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_CLK); - - SDE_DEBUG("crtc=%d clk_rate=%u ib=%llu ab=%llu\n", - crtc->base.id, perf->core_clk_rate, - perf->max_per_pipe_ib, perf->bw_ctl); -} - static u64 _sde_core_perf_crtc_calc_client_vote(struct sde_kms *kms, struct drm_crtc *crtc, struct sde_core_perf_params *perf, bool nrt_client, u32 core_clk) @@ -175,13 +184,13 @@ static u64 _sde_core_perf_crtc_calc_client_vote(struct sde_kms *kms, to_sde_crtc_state(tmp_crtc->state); perf->max_per_pipe_ib = max(perf->max_per_pipe_ib, - sde_cstate->cur_perf.max_per_pipe_ib); + sde_cstate->new_perf.max_per_pipe_ib); - bw_sum_of_intfs += sde_cstate->cur_perf.bw_ctl; + bw_sum_of_intfs += sde_cstate->new_perf.bw_ctl; SDE_DEBUG("crtc=%d bw=%llu\n", tmp_crtc->base.id, - sde_cstate->cur_perf.bw_ctl); + sde_cstate->new_perf.bw_ctl); } } @@ -308,7 +317,7 @@ static u32 _sde_core_perf_get_core_clk_rate(struct sde_kms *kms) drm_for_each_crtc(crtc, kms->dev) { if (_sde_core_perf_crtc_is_power_on(crtc)) { sde_cstate = to_sde_crtc_state(crtc->state); - clk_rate = max(sde_cstate->cur_perf.core_clk_rate, + clk_rate = max(sde_cstate->new_perf.core_clk_rate, clk_rate); clk_rate = clk_round_rate(kms->perf.core_clk, clk_rate); } @@ -357,9 +366,6 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, new = &sde_cstate->new_perf; if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) { - if (params_changed) - _sde_core_perf_calc_crtc(kms, crtc, new); - /* * cases for bus bandwidth update. * 1. new bandwidth vote or writeback output vote diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index e99eba0dadb7..f66c135c9fae 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -473,6 +473,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) struct sde_crtc_frame_event *fevent; struct drm_crtc *crtc; struct sde_crtc *sde_crtc; + struct sde_crtc_state *cstate; struct sde_kms *sde_kms; unsigned long flags; @@ -482,13 +483,14 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) } fevent = container_of(work, struct sde_crtc_frame_event, work); - if (!fevent->crtc) { + if (!fevent->crtc || !fevent->crtc->state) { SDE_ERROR("invalid crtc\n"); return; } crtc = fevent->crtc; sde_crtc = to_sde_crtc(crtc); + cstate = to_sde_crtc_state(crtc->state); sde_kms = _sde_crtc_get_kms(crtc); if (!sde_kms) { @@ -522,6 +524,9 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) } else { SDE_EVT32(DRMID(crtc), fevent->event, 2); } + + if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE) + sde_core_perf_crtc_update(crtc, 0, false); } else { SDE_ERROR("crtc%d ts:%lld unknown event %u\n", crtc->base.id, ktime_to_ns(fevent->ts), |
