diff options
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0222-drm-amdgpu-enable-uvd-dpm-and-powergating.patch')
-rw-r--r-- | meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0222-drm-amdgpu-enable-uvd-dpm-and-powergating.patch | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0222-drm-amdgpu-enable-uvd-dpm-and-powergating.patch b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0222-drm-amdgpu-enable-uvd-dpm-and-powergating.patch new file mode 100644 index 00000000..43644b8c --- /dev/null +++ b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0222-drm-amdgpu-enable-uvd-dpm-and-powergating.patch @@ -0,0 +1,187 @@ +From 564ea7900cffbe2eddb3bcfb09b700ad7942aef4 Mon Sep 17 00:00:00 2001 +From: Sonny Jiang <sonny.jiang@amd.com> +Date: Tue, 12 May 2015 16:13:35 -0400 +Subject: [PATCH 0222/1050] drm/amdgpu: enable uvd dpm and powergating +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Enable UVD dpm (dynamic power management) and powergating. UVD dpm dynamically scales the UVD +clocks on demand. Powergating turns off the power to the block when it's not in use. + +Signed-off-by: Sonny Jiang <sonny.jiang@amd.com> +Acked-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 90 ++++++++++++++++++++++++++++++++++++- + drivers/gpu/drm/amd/amdgpu/cz_dpm.h | 2 + + drivers/gpu/drm/amd/amdgpu/vi.c | 2 +- + 3 files changed, 91 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +index adf4dbc..2649b50 100644 +--- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c ++++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +@@ -42,6 +42,8 @@ + #include "bif/bif_5_1_d.h" + #include "gfx_v8_0.h" + ++static void cz_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate); ++ + static struct cz_ps *cz_get_ps(struct amdgpu_ps *rps) + { + struct cz_ps *ps = rps->ps_priv; +@@ -474,6 +476,7 @@ static int cz_dpm_init(struct amdgpu_device *adev) + return ret; + + pi->dpm_enabled = true; ++ pi->uvd_dynamic_pg = false; + + return 0; + } +@@ -546,6 +549,15 @@ static int cz_dpm_early_init(struct amdgpu_device *adev) + return 0; + } + ++ ++static int cz_dpm_late_init(struct amdgpu_device *adev) ++{ ++ /* powerdown unused blocks for now */ ++ cz_dpm_powergate_uvd(adev, true); ++ ++ return 0; ++} ++ + static int cz_dpm_sw_init(struct amdgpu_device *adev) + { + int ret = 0; +@@ -1260,6 +1272,9 @@ static int cz_dpm_disable(struct amdgpu_device *adev) + return -EINVAL; + } + ++ /* powerup blocks */ ++ cz_dpm_powergate_uvd(adev, false); ++ + cz_clear_voting_clients(adev); + cz_stop_dpm(adev); + cz_update_current_ps(adev, adev->pm.dpm.boot_ps); +@@ -1677,9 +1692,80 @@ static uint32_t cz_dpm_get_mclk(struct amdgpu_device *adev, bool low) + return pi->sys_info.bootup_uma_clk; + } + ++static int cz_enable_uvd_dpm(struct amdgpu_device *adev, bool enable) ++{ ++ struct cz_power_info *pi = cz_get_pi(adev); ++ int ret = 0; ++ ++ if (enable && pi->caps_uvd_dpm ) { ++ pi->dpm_flags |= DPMFlags_UVD_Enabled; ++ DRM_DEBUG("UVD DPM Enabled.\n"); ++ ++ ret = cz_send_msg_to_smc_with_parameter(adev, ++ PPSMC_MSG_EnableAllSmuFeatures, UVD_DPM_MASK); ++ } else { ++ pi->dpm_flags &= ~DPMFlags_UVD_Enabled; ++ DRM_DEBUG("UVD DPM Stopped\n"); ++ ++ ret = cz_send_msg_to_smc_with_parameter(adev, ++ PPSMC_MSG_DisableAllSmuFeatures, UVD_DPM_MASK); ++ } ++ ++ return ret; ++} ++ ++static int cz_update_uvd_dpm(struct amdgpu_device *adev, bool gate) ++{ ++ return cz_enable_uvd_dpm(adev, !gate); ++} ++ ++ ++static void cz_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate) ++{ ++ struct cz_power_info *pi = cz_get_pi(adev); ++ int ret; ++ ++ if (pi->uvd_power_gated == gate) ++ return; ++ ++ pi->uvd_power_gated = gate; ++ ++ if (gate) { ++ if (pi->caps_uvd_pg) { ++ /* disable clockgating so we can properly shut down the block */ ++ ret = amdgpu_set_clockgating_state(adev, AMDGPU_IP_BLOCK_TYPE_UVD, ++ AMDGPU_CG_STATE_UNGATE); ++ /* shutdown the UVD block */ ++ ret = amdgpu_set_powergating_state(adev, AMDGPU_IP_BLOCK_TYPE_UVD, ++ AMDGPU_PG_STATE_GATE); ++ /* XXX: check for errors */ ++ } ++ cz_update_uvd_dpm(adev, gate); ++ if (pi->caps_uvd_pg) ++ /* power off the UVD block */ ++ cz_send_msg_to_smc(adev, PPSMC_MSG_UVDPowerOFF); ++ } else { ++ if (pi->caps_uvd_pg) { ++ /* power on the UVD block */ ++ if (pi->uvd_dynamic_pg) ++ cz_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_UVDPowerON, 1); ++ else ++ cz_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_UVDPowerON, 0); ++ /* re-init the UVD block */ ++ ret = amdgpu_set_powergating_state(adev, AMDGPU_IP_BLOCK_TYPE_UVD, ++ AMDGPU_PG_STATE_UNGATE); ++ /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */ ++ ret = amdgpu_set_clockgating_state(adev, AMDGPU_IP_BLOCK_TYPE_UVD, ++ AMDGPU_CG_STATE_GATE); ++ /* XXX: check for errors */ ++ } ++ cz_update_uvd_dpm(adev, gate); ++ } ++} ++ + const struct amdgpu_ip_funcs cz_dpm_ip_funcs = { + .early_init = cz_dpm_early_init, +- .late_init = NULL, ++ .late_init = cz_dpm_late_init, + .sw_init = cz_dpm_sw_init, + .sw_fini = cz_dpm_sw_fini, + .hw_init = cz_dpm_hw_init, +@@ -1707,7 +1793,7 @@ static const struct amdgpu_dpm_funcs cz_dpm_funcs = { + cz_dpm_debugfs_print_current_performance_level, + .force_performance_level = cz_dpm_force_dpm_level, + .vblank_too_short = NULL, +- .powergate_uvd = NULL, ++ .powergate_uvd = cz_dpm_powergate_uvd, + }; + + static void cz_dpm_set_funcs(struct amdgpu_device *adev) +diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.h b/drivers/gpu/drm/amd/amdgpu/cz_dpm.h +index ed6449d..782a741 100644 +--- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.h ++++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.h +@@ -221,6 +221,8 @@ struct cz_power_info { + bool uvd_power_down; + bool vce_power_down; + bool acp_power_down; ++ ++ bool uvd_dynamic_pg; + }; + + /* cz_smc.c */ +diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c +index 20a1598..59a073a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vi.c ++++ b/drivers/gpu/drm/amd/amdgpu/vi.c +@@ -1266,7 +1266,7 @@ static int vi_common_early_init(struct amdgpu_device *adev) + case CHIP_CARRIZO: + adev->has_uvd = true; + adev->cg_flags = 0; +- adev->pg_flags = 0; ++ adev->pg_flags = AMDGPU_PG_SUPPORT_UVD; + adev->external_rev_id = adev->rev_id + 0x1; + if (amdgpu_smc_load_fw && smc_enabled) + adev->firmware.smu_load = true; +-- +1.9.1 + |