Loading msm/sde/sde_core_perf.c +112 −92 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ Loading Loading @@ -807,50 +807,15 @@ static u64 _sde_core_perf_get_core_clk_rate(struct sde_kms *kms) return clk_rate; } void sde_core_perf_crtc_update(struct drm_crtc *crtc, int params_changed, bool stop_req) static void _sde_core_perf_crtc_update_check(struct drm_crtc *crtc, int params_changed, int *update_bus, int *update_clk, int *update_llcc) { struct sde_core_perf_params *new, *old; int update_bus = 0, update_clk = 0, update_llcc = 0; u64 clk_rate = 0; struct sde_crtc *sde_crtc; struct sde_crtc_state *sde_cstate; int ret, i; struct msm_drm_private *priv; struct sde_kms *kms; if (!crtc) { SDE_ERROR("invalid crtc\n"); return; } kms = _sde_crtc_get_kms(crtc); if (!kms || !kms->catalog) { SDE_ERROR("invalid kms\n"); return; } priv = kms->dev->dev_private; sde_crtc = to_sde_crtc(crtc); sde_cstate = to_sde_crtc_state(crtc->state); SDE_DEBUG("crtc:%d stop_req:%d core_clk:%llu\n", crtc->base.id, stop_req, kms->perf.core_clk_rate); mutex_lock(&sde_core_perf_lock); /* * cache the performance numbers in the crtc prior to the * crtc kickoff, so the same numbers are used during the * perf update that happens post kickoff. */ if (params_changed) memcpy(&sde_crtc->new_perf, &sde_cstate->new_perf, sizeof(struct sde_core_perf_params)); old = &sde_crtc->cur_perf; new = &sde_crtc->new_perf; if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) { struct sde_kms *kms = _sde_crtc_get_kms(crtc); struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_core_perf_params *old = &sde_crtc->cur_perf; struct sde_core_perf_params *new = &sde_crtc->new_perf; int i; /* * cases for the llcc update. Loading @@ -870,7 +835,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, new->llcc_active, old->llcc_active); old->llcc_active = new->llcc_active; update_llcc = 1; *update_llcc = 1; } for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) { Loading @@ -892,7 +857,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, crtc->base.id, params_changed, new->bw_ctl[i], old->bw_ctl[i]); old->bw_ctl[i] = new->bw_ctl[i]; update_bus |= BIT(i); *update_bus |= BIT(i); } if ((params_changed && Loading @@ -909,7 +874,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, old->max_per_pipe_ib[i]); old->max_per_pipe_ib[i] = new->max_per_pipe_ib[i]; update_bus |= BIT(i); *update_bus |= BIT(i); } /* display rsc override during solver mode */ Loading @@ -924,24 +889,78 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, old->bw_ctl[i] = new->bw_ctl[i]; old->max_per_pipe_ib[i] = new->max_per_pipe_ib[i]; update_bus |= BIT(i); *update_bus |= BIT(i); /* * reduce bw vote is not required in solver * mode */ } else if (!params_changed) { update_bus &= ~BIT(i); *update_bus &= ~BIT(i); } } } if (kms->perf.perf_tune.mode_changed && kms->perf.perf_tune.min_core_clk) new->core_clk_rate = kms->perf.perf_tune.min_core_clk; if ((params_changed && (new->core_clk_rate > old->core_clk_rate)) || (!params_changed && new->core_clk_rate && (new->core_clk_rate < old->core_clk_rate))) { (new->core_clk_rate < old->core_clk_rate)) || kms->perf.perf_tune.mode_changed) { old->core_clk_rate = new->core_clk_rate; update_clk = 1; *update_clk = 1; kms->perf.perf_tune.mode_changed = false; } } void sde_core_perf_crtc_update(struct drm_crtc *crtc, int params_changed, bool stop_req) { struct sde_core_perf_params *new, *old; int update_bus = 0, update_clk = 0, update_llcc = 0; u64 clk_rate = 0; struct sde_crtc *sde_crtc; struct sde_crtc_state *sde_cstate; int ret, i; struct msm_drm_private *priv; struct sde_kms *kms; if (!crtc) { SDE_ERROR("invalid crtc\n"); return; } kms = _sde_crtc_get_kms(crtc); if (!kms || !kms->catalog) { SDE_ERROR("invalid kms\n"); return; } priv = kms->dev->dev_private; sde_crtc = to_sde_crtc(crtc); sde_cstate = to_sde_crtc_state(crtc->state); SDE_DEBUG("crtc:%d stop_req:%d core_clk:%llu\n", crtc->base.id, stop_req, kms->perf.core_clk_rate); mutex_lock(&sde_core_perf_lock); /* * cache the performance numbers in the crtc prior to the * crtc kickoff, so the same numbers are used during the * perf update that happens post kickoff. */ if (params_changed) memcpy(&sde_crtc->new_perf, &sde_cstate->new_perf, sizeof(struct sde_core_perf_params)); old = &sde_crtc->cur_perf; new = &sde_crtc->new_perf; if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) { _sde_core_perf_crtc_update_check(crtc, params_changed, &update_bus, &update_clk, &update_llcc); } else { SDE_DEBUG("crtc=%d disable\n", crtc->base.id); memset(old, 0, sizeof(*old)); Loading Loading @@ -1114,6 +1133,7 @@ static ssize_t _sde_core_perf_mode_write(struct file *file, DRM_INFO("normal performance mode\n"); } perf->perf_tune.mode = perf_mode; perf->perf_tune.mode_changed = true; return count; } Loading msm/sde/sde_core_perf.h +3 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef _SDE_CORE_PERF_H_ Loading Loading @@ -47,11 +47,13 @@ struct sde_core_perf_params { * @mode: performance mode * @min_core_clk: minimum core clock * @min_bus_vote: minimum bus vote * @mode_changed: indicate if clock tuning strategy changed */ struct sde_core_perf_tune { u32 mode; u64 min_core_clk; u64 min_bus_vote; bool mode_changed; }; /** Loading Loading
msm/sde/sde_core_perf.c +112 −92 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ Loading Loading @@ -807,50 +807,15 @@ static u64 _sde_core_perf_get_core_clk_rate(struct sde_kms *kms) return clk_rate; } void sde_core_perf_crtc_update(struct drm_crtc *crtc, int params_changed, bool stop_req) static void _sde_core_perf_crtc_update_check(struct drm_crtc *crtc, int params_changed, int *update_bus, int *update_clk, int *update_llcc) { struct sde_core_perf_params *new, *old; int update_bus = 0, update_clk = 0, update_llcc = 0; u64 clk_rate = 0; struct sde_crtc *sde_crtc; struct sde_crtc_state *sde_cstate; int ret, i; struct msm_drm_private *priv; struct sde_kms *kms; if (!crtc) { SDE_ERROR("invalid crtc\n"); return; } kms = _sde_crtc_get_kms(crtc); if (!kms || !kms->catalog) { SDE_ERROR("invalid kms\n"); return; } priv = kms->dev->dev_private; sde_crtc = to_sde_crtc(crtc); sde_cstate = to_sde_crtc_state(crtc->state); SDE_DEBUG("crtc:%d stop_req:%d core_clk:%llu\n", crtc->base.id, stop_req, kms->perf.core_clk_rate); mutex_lock(&sde_core_perf_lock); /* * cache the performance numbers in the crtc prior to the * crtc kickoff, so the same numbers are used during the * perf update that happens post kickoff. */ if (params_changed) memcpy(&sde_crtc->new_perf, &sde_cstate->new_perf, sizeof(struct sde_core_perf_params)); old = &sde_crtc->cur_perf; new = &sde_crtc->new_perf; if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) { struct sde_kms *kms = _sde_crtc_get_kms(crtc); struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_core_perf_params *old = &sde_crtc->cur_perf; struct sde_core_perf_params *new = &sde_crtc->new_perf; int i; /* * cases for the llcc update. Loading @@ -870,7 +835,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, new->llcc_active, old->llcc_active); old->llcc_active = new->llcc_active; update_llcc = 1; *update_llcc = 1; } for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) { Loading @@ -892,7 +857,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, crtc->base.id, params_changed, new->bw_ctl[i], old->bw_ctl[i]); old->bw_ctl[i] = new->bw_ctl[i]; update_bus |= BIT(i); *update_bus |= BIT(i); } if ((params_changed && Loading @@ -909,7 +874,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, old->max_per_pipe_ib[i]); old->max_per_pipe_ib[i] = new->max_per_pipe_ib[i]; update_bus |= BIT(i); *update_bus |= BIT(i); } /* display rsc override during solver mode */ Loading @@ -924,24 +889,78 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc, old->bw_ctl[i] = new->bw_ctl[i]; old->max_per_pipe_ib[i] = new->max_per_pipe_ib[i]; update_bus |= BIT(i); *update_bus |= BIT(i); /* * reduce bw vote is not required in solver * mode */ } else if (!params_changed) { update_bus &= ~BIT(i); *update_bus &= ~BIT(i); } } } if (kms->perf.perf_tune.mode_changed && kms->perf.perf_tune.min_core_clk) new->core_clk_rate = kms->perf.perf_tune.min_core_clk; if ((params_changed && (new->core_clk_rate > old->core_clk_rate)) || (!params_changed && new->core_clk_rate && (new->core_clk_rate < old->core_clk_rate))) { (new->core_clk_rate < old->core_clk_rate)) || kms->perf.perf_tune.mode_changed) { old->core_clk_rate = new->core_clk_rate; update_clk = 1; *update_clk = 1; kms->perf.perf_tune.mode_changed = false; } } void sde_core_perf_crtc_update(struct drm_crtc *crtc, int params_changed, bool stop_req) { struct sde_core_perf_params *new, *old; int update_bus = 0, update_clk = 0, update_llcc = 0; u64 clk_rate = 0; struct sde_crtc *sde_crtc; struct sde_crtc_state *sde_cstate; int ret, i; struct msm_drm_private *priv; struct sde_kms *kms; if (!crtc) { SDE_ERROR("invalid crtc\n"); return; } kms = _sde_crtc_get_kms(crtc); if (!kms || !kms->catalog) { SDE_ERROR("invalid kms\n"); return; } priv = kms->dev->dev_private; sde_crtc = to_sde_crtc(crtc); sde_cstate = to_sde_crtc_state(crtc->state); SDE_DEBUG("crtc:%d stop_req:%d core_clk:%llu\n", crtc->base.id, stop_req, kms->perf.core_clk_rate); mutex_lock(&sde_core_perf_lock); /* * cache the performance numbers in the crtc prior to the * crtc kickoff, so the same numbers are used during the * perf update that happens post kickoff. */ if (params_changed) memcpy(&sde_crtc->new_perf, &sde_cstate->new_perf, sizeof(struct sde_core_perf_params)); old = &sde_crtc->cur_perf; new = &sde_crtc->new_perf; if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) { _sde_core_perf_crtc_update_check(crtc, params_changed, &update_bus, &update_clk, &update_llcc); } else { SDE_DEBUG("crtc=%d disable\n", crtc->base.id); memset(old, 0, sizeof(*old)); Loading Loading @@ -1114,6 +1133,7 @@ static ssize_t _sde_core_perf_mode_write(struct file *file, DRM_INFO("normal performance mode\n"); } perf->perf_tune.mode = perf_mode; perf->perf_tune.mode_changed = true; return count; } Loading
msm/sde/sde_core_perf.h +3 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef _SDE_CORE_PERF_H_ Loading Loading @@ -47,11 +47,13 @@ struct sde_core_perf_params { * @mode: performance mode * @min_core_clk: minimum core clock * @min_bus_vote: minimum bus vote * @mode_changed: indicate if clock tuning strategy changed */ struct sde_core_perf_tune { u32 mode; u64 min_core_clk; u64 min_bus_vote; bool mode_changed; }; /** Loading