Merge "drm/msm/sde: align bandwidth/clock updates with frame done"

This commit is contained in:
Linux Build Service Account 2017-10-18 11:08:20 -07:00 committed by Gerrit - the friendly Code Review server
commit 66a8b75dd2
2 changed files with 44 additions and 33 deletions

View file

@ -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

View file

@ -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),