[PATCH 2/2] drm/amd/powerplay: put VCN/JPEG into PG ungate state before dpm table setup(V3)

2020-08-05 Thread Evan Quan
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

2020-08-04 Thread Alex Deucher
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

2020-08-03 Thread Matt Coffin
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

2020-08-02 Thread Evan Quan
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,