diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0109-drm-amd-powerplay-add-multimedia-power-gating-suppor.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0109-drm-amd-powerplay-add-multimedia-power-gating-suppor.patch | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0109-drm-amd-powerplay-add-multimedia-power-gating-suppor.patch b/common/recipes-kernel/linux/files/0109-drm-amd-powerplay-add-multimedia-power-gating-suppor.patch new file mode 100644 index 00000000..7640c2e6 --- /dev/null +++ b/common/recipes-kernel/linux/files/0109-drm-amd-powerplay-add-multimedia-power-gating-suppor.patch @@ -0,0 +1,382 @@ +From 8394b210923b4ee9757b3505c6a3e59d41613266 Mon Sep 17 00:00:00 2001 +From: Eric Huang <JinHuiEric.Huang@amd.com> +Date: Fri, 20 Nov 2015 15:58:11 -0500 +Subject: [PATCH 0109/1110] drm/amd/powerplay: add multimedia power gating + support for Fiji. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Acked-by: Jammy Zhou <Jammy.Zhou@amd.com> +Acked-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com> +--- + drivers/gpu/drm/amd/powerplay/hwmgr/Makefile | 3 +- + .../amd/powerplay/hwmgr/fiji_clockpowergating.c | 114 ++++++++++++++++++ + .../amd/powerplay/hwmgr/fiji_clockpowergating.h | 35 ++++++ + drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | 127 ++++++++++++++++++++- + drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h | 5 + + 5 files changed, 281 insertions(+), 3 deletions(-) + create mode 100644 drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.c + create mode 100644 drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.h + +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile +index cea032c..269fd82 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile +@@ -7,7 +7,8 @@ HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ + cz_clockpowergating.o \ + tonga_processpptables.o ppatomctrl.o \ + tonga_hwmgr.o pppcielanes.o tonga_thermal.o\ +- fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o ++ fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \ ++ fiji_clockpowergating.o + + AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) + +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.c +new file mode 100644 +index 0000000..e68edf0 +--- /dev/null ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.c +@@ -0,0 +1,114 @@ ++/* ++ * Copyright 2015 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "hwmgr.h" ++#include "fiji_clockpowergating.h" ++#include "fiji_ppsmc.h" ++#include "fiji_hwmgr.h" ++ ++int fiji_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ ++ data->uvd_power_gated = false; ++ data->vce_power_gated = false; ++ data->samu_power_gated = false; ++ data->acp_power_gated = false; ++ ++ return 0; ++} ++ ++int fiji_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ ++ if (data->uvd_power_gated == bgate) ++ return 0; ++ ++ data->uvd_power_gated = bgate; ++ ++ if (bgate) ++ fiji_update_uvd_dpm(hwmgr, true); ++ else ++ fiji_update_uvd_dpm(hwmgr, false); ++ ++ return 0; ++} ++ ++int fiji_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ struct phm_set_power_state_input states; ++ const struct pp_power_state *pcurrent; ++ struct pp_power_state *requested; ++ ++ if (data->vce_power_gated == bgate) ++ return 0; ++ ++ data->vce_power_gated = bgate; ++ ++ pcurrent = hwmgr->current_ps; ++ requested = hwmgr->request_ps; ++ ++ states.pcurrent_state = &(pcurrent->hardware); ++ states.pnew_state = &(requested->hardware); ++ ++ fiji_update_vce_dpm(hwmgr, &states); ++ fiji_enable_disable_vce_dpm(hwmgr, !bgate); ++ ++ return 0; ++} ++ ++int fiji_phm_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ ++ if (data->samu_power_gated == bgate) ++ return 0; ++ ++ data->samu_power_gated = bgate; ++ ++ if (bgate) ++ fiji_update_samu_dpm(hwmgr, true); ++ else ++ fiji_update_samu_dpm(hwmgr, false); ++ ++ return 0; ++} ++ ++int fiji_phm_powergate_acp(struct pp_hwmgr *hwmgr, bool bgate) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ ++ if (data->acp_power_gated == bgate) ++ return 0; ++ ++ data->acp_power_gated = bgate; ++ ++ if (bgate) ++ fiji_update_acp_dpm(hwmgr, true); ++ else ++ fiji_update_acp_dpm(hwmgr, false); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.h b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.h +new file mode 100644 +index 0000000..33af5f5 +--- /dev/null ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_clockpowergating.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright 2015 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef _FIJI_CLOCK_POWER_GATING_H_ ++#define _FIJI_CLOCK_POWER_GATING_H_ ++ ++#include "fiji_hwmgr.h" ++#include "pp_asicblocks.h" ++ ++extern int fiji_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate); ++extern int fiji_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate); ++extern int fiji_phm_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate); ++extern int fiji_phm_powergate_acp(struct pp_hwmgr *hwmgr, bool bgate); ++extern int fiji_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr); ++#endif /* _TONGA_CLOCK_POWER_GATING_H_ */ +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +index 5ef92e1..b616e16 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +@@ -51,6 +51,8 @@ + #include "pp_acpi.h" + #include "amd_pcie_helpers.h" + ++#include "fiji_clockpowergating.h" ++ + #define VOLTAGE_SCALE 4 + #define SMC_RAM_END 0x40000 + #define VDDC_VDDCI_DELTA 300 +@@ -4385,14 +4387,70 @@ static int fiji_generate_dpm_level_enable_mask( + return 0; + } + +-static int fiji_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) ++int fiji_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable) ++{ ++ return smum_send_msg_to_smc(hwmgr->smumgr, enable ? ++ (PPSMC_Msg)PPSMC_MSG_UVDDPM_Enable : ++ (PPSMC_Msg)PPSMC_MSG_UVDDPM_Disable); ++} ++ ++int fiji_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) + { + return smum_send_msg_to_smc(hwmgr->smumgr, enable? + PPSMC_MSG_VCEDPM_Enable : + PPSMC_MSG_VCEDPM_Disable); + } + +-static int fiji_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input) ++int fiji_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable) ++{ ++ return smum_send_msg_to_smc(hwmgr->smumgr, enable? ++ PPSMC_MSG_SAMUDPM_Enable : ++ PPSMC_MSG_SAMUDPM_Disable); ++} ++ ++int fiji_enable_disable_acp_dpm(struct pp_hwmgr *hwmgr, bool enable) ++{ ++ return smum_send_msg_to_smc(hwmgr->smumgr, enable? ++ PPSMC_MSG_ACPDPM_Enable : ++ PPSMC_MSG_ACPDPM_Disable); ++} ++ ++int fiji_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ uint32_t mm_boot_level_offset, mm_boot_level_value; ++ struct phm_ppt_v1_information *table_info = ++ (struct phm_ppt_v1_information *)(hwmgr->pptable); ++ ++ if (!bgate) { ++ data->smc_state_table.UvdBootLevel = 0; ++ if (table_info->mm_dep_table->count > 0) ++ data->smc_state_table.UvdBootLevel = ++ (uint8_t) (table_info->mm_dep_table->count - 1); ++ mm_boot_level_offset = data->dpm_table_start + ++ offsetof(SMU73_Discrete_DpmTable, UvdBootLevel); ++ mm_boot_level_offset /= 4; ++ mm_boot_level_offset *= 4; ++ mm_boot_level_value = cgs_read_ind_register(hwmgr->device, ++ CGS_IND_REG__SMC, mm_boot_level_offset); ++ mm_boot_level_value &= 0x00FFFFFF; ++ mm_boot_level_value |= data->smc_state_table.UvdBootLevel << 24; ++ cgs_write_ind_register(hwmgr->device, ++ CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); ++ ++ if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, ++ PHM_PlatformCaps_UVDDPM) || ++ phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, ++ PHM_PlatformCaps_StablePState)) ++ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, ++ PPSMC_MSG_UVDDPM_SetEnabledMask, ++ (uint32_t)(1 << data->smc_state_table.UvdBootLevel)); ++ } ++ ++ return fiji_enable_disable_uvd_dpm(hwmgr, !bgate); ++} ++ ++int fiji_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input) + { + const struct phm_set_power_state_input *states = + (const struct phm_set_power_state_input *)input; +@@ -4438,6 +4496,68 @@ static int fiji_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input) + return 0; + } + ++int fiji_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ uint32_t mm_boot_level_offset, mm_boot_level_value; ++ struct phm_ppt_v1_information *table_info = ++ (struct phm_ppt_v1_information *)(hwmgr->pptable); ++ ++ if (!bgate) { ++ data->smc_state_table.SamuBootLevel = ++ (uint8_t) (table_info->mm_dep_table->count - 1); ++ mm_boot_level_offset = data->dpm_table_start + ++ offsetof(SMU73_Discrete_DpmTable, SamuBootLevel); ++ mm_boot_level_offset /= 4; ++ mm_boot_level_offset *= 4; ++ mm_boot_level_value = cgs_read_ind_register(hwmgr->device, ++ CGS_IND_REG__SMC, mm_boot_level_offset); ++ mm_boot_level_value &= 0xFFFFFF00; ++ mm_boot_level_value |= data->smc_state_table.SamuBootLevel << 0; ++ cgs_write_ind_register(hwmgr->device, ++ CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); ++ ++ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, ++ PHM_PlatformCaps_StablePState)) ++ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, ++ PPSMC_MSG_SAMUDPM_SetEnabledMask, ++ (uint32_t)(1 << data->smc_state_table.SamuBootLevel)); ++ } ++ ++ return fiji_enable_disable_samu_dpm(hwmgr, !bgate); ++} ++ ++int fiji_update_acp_dpm(struct pp_hwmgr *hwmgr, bool bgate) ++{ ++ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); ++ uint32_t mm_boot_level_offset, mm_boot_level_value; ++ struct phm_ppt_v1_information *table_info = ++ (struct phm_ppt_v1_information *)(hwmgr->pptable); ++ ++ if (!bgate) { ++ data->smc_state_table.AcpBootLevel = ++ (uint8_t) (table_info->mm_dep_table->count - 1); ++ mm_boot_level_offset = data->dpm_table_start + ++ offsetof(SMU73_Discrete_DpmTable, AcpBootLevel); ++ mm_boot_level_offset /= 4; ++ mm_boot_level_offset *= 4; ++ mm_boot_level_value = cgs_read_ind_register(hwmgr->device, ++ CGS_IND_REG__SMC, mm_boot_level_offset); ++ mm_boot_level_value &= 0xFFFF00FF; ++ mm_boot_level_value |= data->smc_state_table.AcpBootLevel << 8; ++ cgs_write_ind_register(hwmgr->device, ++ CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); ++ ++ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, ++ PHM_PlatformCaps_StablePState)) ++ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, ++ PPSMC_MSG_ACPDPM_SetEnabledMask, ++ (uint32_t)(1 << data->smc_state_table.AcpBootLevel)); ++ } ++ ++ return fiji_enable_disable_acp_dpm(hwmgr, !bgate); ++} ++ + static int fiji_update_sclk_threshold(struct pp_hwmgr *hwmgr) + { + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); +@@ -4747,6 +4867,9 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = { + .get_sclk = &fiji_dpm_get_sclk, + .get_mclk = &fiji_dpm_get_mclk, + .print_current_perforce_level = &fiji_print_current_perforce_level, ++ .powergate_uvd = &fiji_phm_powergate_uvd, ++ .powergate_vce = &fiji_phm_powergate_vce, ++ .disable_clock_power_gating = &fiji_phm_disable_clock_power_gating, + }; + + int fiji_hwmgr_init(struct pp_hwmgr *hwmgr) +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h +index 22d985e..cd1e88a 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h +@@ -339,6 +339,11 @@ enum Fiji_I2CLineID { + extern int tonga_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr); + extern int tonga_hwmgr_backend_fini(struct pp_hwmgr *hwmgr); + extern int tonga_get_mc_microcode_version (struct pp_hwmgr *hwmgr); ++int fiji_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input); ++int fiji_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate); ++int fiji_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate); ++int fiji_update_acp_dpm(struct pp_hwmgr *hwmgr, bool bgate); ++int fiji_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable); + + #define PP_HOST_TO_SMC_UL(X) cpu_to_be32(X) + #define PP_SMC_TO_HOST_UL(X) be32_to_cpu(X) +-- +2.7.4 + |