diff options
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.patch | 132 |
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 + |