[PATCH 2/2] drm/amd/powerplay: put VCN/JPEG into PG ungate state before dpm table setup(V3)
As VCN related dpm table setup needs VCN be in PG ungate state. Same logics applies to JPEG. V2: fix paste typo V3: code cosmetic Change-Id: I0e4d97ebedc132b7d793dc3f36275066ff999eac Signed-off-by: Evan Quan Tested-by: Matt Coffin Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 89 +--- drivers/gpu/drm/amd/powerplay/smu_internal.h | 1 - 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 1b64ca9ecccb..1ced80238f8a 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -133,6 +133,23 @@ int smu_get_dpm_freq_range(struct smu_context *smu, return ret; } +static int smu_dpm_set_vcn_enable_locked(struct smu_context *smu, +bool enable) +{ + struct smu_power_context *smu_power = >smu_power; + struct smu_power_gate *power_gate = _power->power_gate; + int ret = 0; + + if (atomic_read(_gate->vcn_gated) ^ enable) + return 0; + + ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable); + if (!ret) + atomic_set(_gate->vcn_gated, !enable); + + return ret; +} + static int smu_dpm_set_vcn_enable(struct smu_context *smu, bool enable) { @@ -145,19 +162,30 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, mutex_lock(_gate->vcn_gate_lock); - if (atomic_read(_gate->vcn_gated) ^ enable) - goto out; - - ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable); - if (!ret) - atomic_set(_gate->vcn_gated, !enable); + ret = smu_dpm_set_vcn_enable_locked(smu, enable); -out: mutex_unlock(_gate->vcn_gate_lock); return ret; } +static int smu_dpm_set_jpeg_enable_locked(struct smu_context *smu, + bool enable) +{ + struct smu_power_context *smu_power = >smu_power; + struct smu_power_gate *power_gate = _power->power_gate; + int ret = 0; + + if (atomic_read(_gate->jpeg_gated) ^ enable) + return 0; + + ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable); + if (!ret) + atomic_set(_gate->jpeg_gated, !enable); + + return ret; +} + static int smu_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) { @@ -170,14 +198,8 @@ static int smu_dpm_set_jpeg_enable(struct smu_context *smu, mutex_lock(_gate->jpeg_gate_lock); - if (atomic_read(_gate->jpeg_gated) ^ enable) - goto out; - - ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable); - if (!ret) - atomic_set(_gate->jpeg_gated, !enable); + ret = smu_dpm_set_jpeg_enable_locked(smu, enable); -out: mutex_unlock(_gate->jpeg_gate_lock); return ret; @@ -403,6 +425,45 @@ static int smu_early_init(void *handle) return smu_set_funcs(adev); } +static int smu_set_default_dpm_table(struct smu_context *smu) +{ + struct smu_power_context *smu_power = >smu_power; + struct smu_power_gate *power_gate = _power->power_gate; + int vcn_gate, jpeg_gate; + int ret = 0; + + if (!smu->ppt_funcs->set_default_dpm_table) + return 0; + + mutex_lock(_gate->vcn_gate_lock); + mutex_lock(_gate->jpeg_gate_lock); + + vcn_gate = atomic_read(_gate->vcn_gated); + jpeg_gate = atomic_read(_gate->jpeg_gated); + + ret = smu_dpm_set_vcn_enable_locked(smu, true); + if (ret) + goto err0_out; + + ret = smu_dpm_set_jpeg_enable_locked(smu, true); + if (ret) + goto err1_out; + + ret = smu->ppt_funcs->set_default_dpm_table(smu); + if (ret) + dev_err(smu->adev->dev, + "Failed to setup default dpm clock tables!\n"); + + smu_dpm_set_jpeg_enable_locked(smu, !jpeg_gate); +err1_out: + smu_dpm_set_vcn_enable_locked(smu, !vcn_gate); +err0_out: + mutex_unlock(_gate->jpeg_gate_lock); + mutex_unlock(_gate->vcn_gate_lock); + + return ret; +} + static int smu_late_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; diff --git a/drivers/gpu/drm/amd/powerplay/smu_internal.h b/drivers/gpu/drm/amd/powerplay/smu_internal.h index f1d8f247e589..264073d4e263 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_internal.h +++ b/drivers/gpu/drm/amd/powerplay/smu_internal.h @@ -60,7 +60,6 @@ #define smu_disable_all_features_with_exception(smu, mask) smu_ppt_funcs(disable_all_features_with_exception, 0, smu, mask) #define smu_is_dpm_running(smu) smu_ppt_funcs(is_dpm_running, 0 , smu) #define smu_notify_display_change(smu)
Re: [PATCH 2/2] drm/amd/powerplay: put VCN/JPEG into PG ungate state before dpm table setup
On Mon, Aug 3, 2020 at 12:47 AM Evan Quan wrote: > > As VCN related dpm table setup needs VCN be in PG ungate state. Same logics > applies to JPEG. > > Change-Id: I94335efc4e0424cfe0991e984c938998fd8f1287 > Signed-off-by: Evan Quan > --- > drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 38 +- > 1 file changed, 30 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > index 85b04c48bd09..1349d05c5f3d 100644 > --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > @@ -134,7 +134,8 @@ int smu_get_dpm_freq_range(struct smu_context *smu, > } > > static int smu_dpm_set_vcn_enable(struct smu_context *smu, > - bool enable) > + bool enable, > + int *previous_pg_state) > { > struct smu_power_context *smu_power = >smu_power; > struct smu_power_gate *power_gate = _power->power_gate; > @@ -148,6 +149,9 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, > if (atomic_read(_gate->vcn_gated) ^ enable) > goto out; > > + if (previous_pg_state) > + *previous_pg_state = atomic_read(_gate->vcn_gated); > + > ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable); > if (!ret) > atomic_set(_gate->vcn_gated, !enable); > @@ -159,7 +163,8 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, > } > > static int smu_dpm_set_jpeg_enable(struct smu_context *smu, > - bool enable) > + bool enable, > + int *previous_pg_state) > { > struct smu_power_context *smu_power = >smu_power; > struct smu_power_gate *power_gate = _power->power_gate; > @@ -173,6 +178,9 @@ static int smu_dpm_set_jpeg_enable(struct smu_context > *smu, > if (atomic_read(_gate->jpeg_gated) ^ enable) > goto out; > > + if (previous_pg_state) > + *previous_pg_state = atomic_read(_gate->jpeg_gated); > + > ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable); > if (!ret) > atomic_set(_gate->jpeg_gated, !enable); > @@ -212,7 +220,7 @@ int smu_dpm_set_power_gate(struct smu_context *smu, > uint32_t block_type, > */ > case AMD_IP_BLOCK_TYPE_UVD: > case AMD_IP_BLOCK_TYPE_VCN: > - ret = smu_dpm_set_vcn_enable(smu, !gate); > + ret = smu_dpm_set_vcn_enable(smu, !gate, NULL); > if (ret) > dev_err(smu->adev->dev, "Failed to power %s VCN!\n", > gate ? "gate" : "ungate"); > @@ -230,7 +238,7 @@ int smu_dpm_set_power_gate(struct smu_context *smu, > uint32_t block_type, > gate ? "gate" : "ungate"); > break; > case AMD_IP_BLOCK_TYPE_JPEG: > - ret = smu_dpm_set_jpeg_enable(smu, !gate); > + ret = smu_dpm_set_jpeg_enable(smu, !gate, NULL); > if (ret) > dev_err(smu->adev->dev, "Failed to power %s JPEG!\n", > gate ? "gate" : "ungate"); > @@ -407,6 +415,7 @@ static int smu_late_init(void *handle) > { > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > struct smu_context *smu = >smu; > + int vcn_gate, jpeg_gate; > int ret = 0; > > if (!smu->pm_enabled) > @@ -418,6 +427,14 @@ static int smu_late_init(void *handle) > return ret; > } > > + /* > +* 1. Power up VCN/JPEG as the succeeding smu_set_default_dpm_table() > +*needs VCN/JPEG up. > +* 2. Save original gate states and then we can restore back > afterwards. > +*/ > + smu_dpm_set_vcn_enable(smu, true, _gate); > + smu_dpm_set_jpeg_enable(smu, true, _gate); > + > /* > * Set initialized values (get from vbios) to dpm tables context such > as > * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for > each > @@ -429,6 +446,11 @@ static int smu_late_init(void *handle) > return ret; > } > > + /* Restore back to original VCN/JPEG power gate states */ > + smu_dpm_set_vcn_enable(smu, !vcn_gate, NULL); > + smu_dpm_set_jpeg_enable(smu, !vcn_gate, NULL); Copy paste typo. This should be !jpeg_gate. With that fixed, the series is: Reviewed-by: Alex Deucher Alex > + > + > ret = smu_populate_umd_state_clk(smu); > if (ret) { > dev_err(adev->dev, "Failed to populate UMD state clocks!\n"); > @@ -991,8 +1013,8 @@ static int smu_hw_init(void *handle) > > if (smu->is_apu) { > smu_powergate_sdma(>smu, false); > - smu_dpm_set_vcn_enable(smu, true); > -
Re: [PATCH 2/2] drm/amd/powerplay: put VCN/JPEG into PG ungate state before dpm table setup
Thanks Evan! I can confirm that this resolved the following GitLab issue. Thanks for CC'ing me! https://gitlab.freedesktop.org/drm/amd/-/issues/1243 Series is Tested-by: Matt Coffin On 8/2/20 10:46 PM, Evan Quan wrote: > As VCN related dpm table setup needs VCN be in PG ungate state. Same logics > applies to JPEG. > > Change-Id: I94335efc4e0424cfe0991e984c938998fd8f1287 > Signed-off-by: Evan Quan > --- > drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 38 +- > 1 file changed, 30 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > index 85b04c48bd09..1349d05c5f3d 100644 > --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > @@ -134,7 +134,8 @@ int smu_get_dpm_freq_range(struct smu_context *smu, > } > > static int smu_dpm_set_vcn_enable(struct smu_context *smu, > - bool enable) > + bool enable, > + int *previous_pg_state) > { > struct smu_power_context *smu_power = >smu_power; > struct smu_power_gate *power_gate = _power->power_gate; > @@ -148,6 +149,9 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, > if (atomic_read(_gate->vcn_gated) ^ enable) > goto out; > > + if (previous_pg_state) > + *previous_pg_state = atomic_read(_gate->vcn_gated); > + > ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable); > if (!ret) > atomic_set(_gate->vcn_gated, !enable); > @@ -159,7 +163,8 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, > } > > static int smu_dpm_set_jpeg_enable(struct smu_context *smu, > -bool enable) > +bool enable, > +int *previous_pg_state) > { > struct smu_power_context *smu_power = >smu_power; > struct smu_power_gate *power_gate = _power->power_gate; > @@ -173,6 +178,9 @@ static int smu_dpm_set_jpeg_enable(struct smu_context > *smu, > if (atomic_read(_gate->jpeg_gated) ^ enable) > goto out; > > + if (previous_pg_state) > + *previous_pg_state = atomic_read(_gate->jpeg_gated); > + > ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable); > if (!ret) > atomic_set(_gate->jpeg_gated, !enable); > @@ -212,7 +220,7 @@ int smu_dpm_set_power_gate(struct smu_context *smu, > uint32_t block_type, >*/ > case AMD_IP_BLOCK_TYPE_UVD: > case AMD_IP_BLOCK_TYPE_VCN: > - ret = smu_dpm_set_vcn_enable(smu, !gate); > + ret = smu_dpm_set_vcn_enable(smu, !gate, NULL); > if (ret) > dev_err(smu->adev->dev, "Failed to power %s VCN!\n", > gate ? "gate" : "ungate"); > @@ -230,7 +238,7 @@ int smu_dpm_set_power_gate(struct smu_context *smu, > uint32_t block_type, > gate ? "gate" : "ungate"); > break; > case AMD_IP_BLOCK_TYPE_JPEG: > - ret = smu_dpm_set_jpeg_enable(smu, !gate); > + ret = smu_dpm_set_jpeg_enable(smu, !gate, NULL); > if (ret) > dev_err(smu->adev->dev, "Failed to power %s JPEG!\n", > gate ? "gate" : "ungate"); > @@ -407,6 +415,7 @@ static int smu_late_init(void *handle) > { > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > struct smu_context *smu = >smu; > + int vcn_gate, jpeg_gate; > int ret = 0; > > if (!smu->pm_enabled) > @@ -418,6 +427,14 @@ static int smu_late_init(void *handle) > return ret; > } > > + /* > + * 1. Power up VCN/JPEG as the succeeding smu_set_default_dpm_table() > + *needs VCN/JPEG up. > + * 2. Save original gate states and then we can restore back afterwards. > + */ > + smu_dpm_set_vcn_enable(smu, true, _gate); > + smu_dpm_set_jpeg_enable(smu, true, _gate); > + > /* >* Set initialized values (get from vbios) to dpm tables context such as >* gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each > @@ -429,6 +446,11 @@ static int smu_late_init(void *handle) > return ret; > } > > + /* Restore back to original VCN/JPEG power gate states */ > + smu_dpm_set_vcn_enable(smu, !vcn_gate, NULL); > + smu_dpm_set_jpeg_enable(smu, !vcn_gate, NULL); > + > + > ret = smu_populate_umd_state_clk(smu); > if (ret) { > dev_err(adev->dev, "Failed to populate UMD state clocks!\n"); > @@ -991,8 +1013,8 @@ static int smu_hw_init(void *handle) > > if (smu->is_apu) { > smu_powergate_sdma(>smu, false); > - smu_dpm_set_vcn_enable(smu, true); > - smu_dpm_set_jpeg_enable(smu, true); > +
[PATCH 2/2] drm/amd/powerplay: put VCN/JPEG into PG ungate state before dpm table setup
As VCN related dpm table setup needs VCN be in PG ungate state. Same logics applies to JPEG. Change-Id: I94335efc4e0424cfe0991e984c938998fd8f1287 Signed-off-by: Evan Quan --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 38 +- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 85b04c48bd09..1349d05c5f3d 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -134,7 +134,8 @@ int smu_get_dpm_freq_range(struct smu_context *smu, } static int smu_dpm_set_vcn_enable(struct smu_context *smu, - bool enable) + bool enable, + int *previous_pg_state) { struct smu_power_context *smu_power = >smu_power; struct smu_power_gate *power_gate = _power->power_gate; @@ -148,6 +149,9 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, if (atomic_read(_gate->vcn_gated) ^ enable) goto out; + if (previous_pg_state) + *previous_pg_state = atomic_read(_gate->vcn_gated); + ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable); if (!ret) atomic_set(_gate->vcn_gated, !enable); @@ -159,7 +163,8 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, } static int smu_dpm_set_jpeg_enable(struct smu_context *smu, - bool enable) + bool enable, + int *previous_pg_state) { struct smu_power_context *smu_power = >smu_power; struct smu_power_gate *power_gate = _power->power_gate; @@ -173,6 +178,9 @@ static int smu_dpm_set_jpeg_enable(struct smu_context *smu, if (atomic_read(_gate->jpeg_gated) ^ enable) goto out; + if (previous_pg_state) + *previous_pg_state = atomic_read(_gate->jpeg_gated); + ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable); if (!ret) atomic_set(_gate->jpeg_gated, !enable); @@ -212,7 +220,7 @@ int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type, */ case AMD_IP_BLOCK_TYPE_UVD: case AMD_IP_BLOCK_TYPE_VCN: - ret = smu_dpm_set_vcn_enable(smu, !gate); + ret = smu_dpm_set_vcn_enable(smu, !gate, NULL); if (ret) dev_err(smu->adev->dev, "Failed to power %s VCN!\n", gate ? "gate" : "ungate"); @@ -230,7 +238,7 @@ int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type, gate ? "gate" : "ungate"); break; case AMD_IP_BLOCK_TYPE_JPEG: - ret = smu_dpm_set_jpeg_enable(smu, !gate); + ret = smu_dpm_set_jpeg_enable(smu, !gate, NULL); if (ret) dev_err(smu->adev->dev, "Failed to power %s JPEG!\n", gate ? "gate" : "ungate"); @@ -407,6 +415,7 @@ static int smu_late_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = >smu; + int vcn_gate, jpeg_gate; int ret = 0; if (!smu->pm_enabled) @@ -418,6 +427,14 @@ static int smu_late_init(void *handle) return ret; } + /* +* 1. Power up VCN/JPEG as the succeeding smu_set_default_dpm_table() +*needs VCN/JPEG up. +* 2. Save original gate states and then we can restore back afterwards. +*/ + smu_dpm_set_vcn_enable(smu, true, _gate); + smu_dpm_set_jpeg_enable(smu, true, _gate); + /* * Set initialized values (get from vbios) to dpm tables context such as * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each @@ -429,6 +446,11 @@ static int smu_late_init(void *handle) return ret; } + /* Restore back to original VCN/JPEG power gate states */ + smu_dpm_set_vcn_enable(smu, !vcn_gate, NULL); + smu_dpm_set_jpeg_enable(smu, !vcn_gate, NULL); + + ret = smu_populate_umd_state_clk(smu); if (ret) { dev_err(adev->dev, "Failed to populate UMD state clocks!\n"); @@ -991,8 +1013,8 @@ static int smu_hw_init(void *handle) if (smu->is_apu) { smu_powergate_sdma(>smu, false); - smu_dpm_set_vcn_enable(smu, true); - smu_dpm_set_jpeg_enable(smu, true); + smu_dpm_set_vcn_enable(smu, true, NULL); + smu_dpm_set_jpeg_enable(smu, true, NULL); smu_set_gfx_cgpg(>smu, true); } @@ -1132,8 +1154,8 @@ static int smu_hw_fini(void *handle) if (smu->is_apu) { smu_powergate_sdma(>smu, true); - smu_dpm_set_vcn_enable(smu,