aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/4504-drm-amdgpu-Add-runtime-VCN-PG-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/4504-drm-amdgpu-Add-runtime-VCN-PG-support.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/4504-drm-amdgpu-Add-runtime-VCN-PG-support.patch132
1 files changed, 132 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/4504-drm-amdgpu-Add-runtime-VCN-PG-support.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/4504-drm-amdgpu-Add-runtime-VCN-PG-support.patch
new file mode 100644
index 00000000..844a4312
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/4504-drm-amdgpu-Add-runtime-VCN-PG-support.patch
@@ -0,0 +1,132 @@
+From 489c820a19bfcdb0b384d7bca7158427e2856664 Mon Sep 17 00:00:00 2001
+From: Rex Zhu <Rex.Zhu@amd.com>
+Date: Wed, 16 May 2018 20:18:22 +0800
+Subject: [PATCH 4504/5725] drm/amdgpu: Add runtime VCN PG support
+
+Enable support for dynamically powering up/down VCN on demand.
+
+Change-Id: I41fce19c737d78294544b33ce219edb21769989a
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 16 +++++++++-------
+ drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 32 +++++++++++++++++++++-----------
+ 2 files changed, 30 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+index ab4aa04..21425669 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+@@ -215,11 +215,11 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
+ }
+
+ if (fences == 0) {
+- if (adev->pm.dpm_enabled) {
+- /* might be used when with pg/cg
++ if (adev->pm.dpm_enabled)
+ amdgpu_dpm_enable_uvd(adev, false);
+- */
+- }
++ else
++ amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
++ AMD_PG_STATE_GATE);
+ } else {
+ schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
+ }
+@@ -231,9 +231,11 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
+ bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
+
+ if (set_clocks && adev->pm.dpm_enabled) {
+- /* might be used when with pg/cg
+- amdgpu_dpm_enable_uvd(adev, true);
+- */
++ if (adev->pm.dpm_enabled)
++ amdgpu_dpm_enable_uvd(adev, true);
++ else
++ amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
++ AMD_PG_STATE_UNGATE);
+ }
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+index 5f660cd..0f1570e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+@@ -35,7 +35,6 @@
+ #include "mmhub/mmhub_9_1_offset.h"
+ #include "mmhub/mmhub_9_1_sh_mask.h"
+
+-static int vcn_v1_0_start(struct amdgpu_device *adev);
+ static int vcn_v1_0_stop(struct amdgpu_device *adev);
+ static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
+ static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
+@@ -156,10 +155,6 @@ static int vcn_v1_0_hw_init(void *handle)
+ struct amdgpu_ring *ring = &adev->vcn.ring_dec;
+ int i, r;
+
+- r = vcn_v1_0_start(adev);
+- if (r)
+- goto done;
+-
+ ring->ready = true;
+ r = amdgpu_ring_test_ring(ring);
+ if (r) {
+@@ -195,11 +190,9 @@ static int vcn_v1_0_hw_fini(void *handle)
+ {
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ struct amdgpu_ring *ring = &adev->vcn.ring_dec;
+- int r;
+
+- r = vcn_v1_0_stop(adev);
+- if (r)
+- return r;
++ if (RREG32_SOC15(VCN, 0, mmUVD_STATUS))
++ vcn_v1_0_stop(adev);
+
+ ring->ready = false;
+
+@@ -791,7 +784,7 @@ static int vcn_v1_0_stop(struct amdgpu_device *adev)
+ WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
+ ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
+
+- /* enable clock gating */
++ WREG32_SOC15(VCN, 0, mmUVD_STATUS, 0);
+
+ vcn_v1_0_enable_clock_gating(adev);
+ vcn_1_0_enable_static_power_gating(adev);
+@@ -1216,6 +1209,23 @@ static void vcn_v1_0_dec_ring_insert_nop(struct amdgpu_ring *ring, uint32_t coun
+ }
+ }
+
++static int vcn_v1_0_set_powergating_state(void *handle,
++ enum amd_powergating_state state)
++{
++ /* This doesn't actually powergate the VCN block.
++ * That's done in the dpm code via the SMC. This
++ * just re-inits the block as necessary. The actual
++ * gating still happens in the dpm code. We should
++ * revisit this when there is a cleaner line between
++ * the smc and the hw blocks
++ */
++ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
++
++ if (state == AMD_PG_STATE_GATE)
++ return vcn_v1_0_stop(adev);
++ else
++ return vcn_v1_0_start(adev);
++}
+
+ static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
+ .name = "vcn_v1_0",
+@@ -1234,7 +1244,7 @@ static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
+ .soft_reset = NULL /* vcn_v1_0_soft_reset */,
+ .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */,
+ .set_clockgating_state = vcn_v1_0_set_clockgating_state,
+- .set_powergating_state = NULL /* vcn_v1_0_set_powergating_state */,
++ .set_powergating_state = vcn_v1_0_set_powergating_state,
+ };
+
+ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
+--
+2.7.4
+