diff options
author | Dave Airlie <airlied@redhat.com> | 2020-12-10 16:55:41 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-12-10 16:55:53 +1000 |
commit | b10733527bfd864605c33ab2e9a886eec317ec39 (patch) | |
tree | d7d671d2fa69e628e2ac898ba8e9ab10c6481c3c /drivers/gpu/drm/amd/pm | |
parent | 60f2f74978e69fdb63e7a26179cbd5c50d4845c2 (diff) | |
parent | f8aab60422c371425365d386dfd51e0c6c5b1041 (diff) | |
download | lwn-b10733527bfd864605c33ab2e9a886eec317ec39.tar.gz lwn-b10733527bfd864605c33ab2e9a886eec317ec39.zip |
Merge tag 'amd-drm-next-5.11-2020-12-09' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.11-2020-12-09:
amdgpu:
- SR-IOV fixes
- Navy Flounder updates
- Sienna Cichlid updates
- Dimgrey Cavefish updates
- Vangogh updates
- Misc SMU fixes
- Misc display fixes
- Last big hunk of W=1 warning fixes
- Cursor validation fixes
- CI BACO updates
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201210045344.21566-1-alexander.deucher@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/amd/pm')
53 files changed, 1103 insertions, 1182 deletions
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 17a45baff638..8fb12afe3c96 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -1168,6 +1168,9 @@ int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev, { int ret = 0; + if (amdgpu_sriov_vf(adev)) + return 0; + if (is_support_sw_smu(adev)) ret = smu_switch_power_profile(&adev->smu, type, en); else if (adev->powerplay.pp_funcs && diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h index 9724d6fd82f4..89be49a43500 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h @@ -99,7 +99,7 @@ struct smu_state_display_block { bool enable_vari_bright; }; -struct smu_state_memroy_block { +struct smu_state_memory_block { bool dll_off; uint8_t m3arb; uint8_t unused[3]; @@ -146,7 +146,7 @@ struct smu_power_state { struct smu_state_validation_block validation; struct smu_state_pcie_block pcie; struct smu_state_display_block display; - struct smu_state_memroy_block memory; + struct smu_state_memory_block memory; struct smu_state_software_algorithm_block software; struct smu_uvd_clocks uvd_clocks; struct smu_hw_power_state hardware; @@ -459,6 +459,11 @@ struct smu_context unsigned fan_max_rpm; unsigned manual_fan_speed_rpm; + + uint32_t gfx_default_hard_min_freq; + uint32_t gfx_default_soft_max_freq; + uint32_t gfx_actual_hard_min_freq; + uint32_t gfx_actual_soft_max_freq; }; struct i2c_adapter; @@ -576,6 +581,8 @@ struct pptable_funcs { int (*post_init)(struct smu_context *smu); void (*interrupt_work)(struct smu_context *smu); int (*gpo_control)(struct smu_context *smu, bool enablement); + int (*gfx_state_change_set)(struct smu_context *smu, uint32_t state); + int (*set_fine_grain_gfx_freq_parameters)(struct smu_context *smu); }; typedef enum { @@ -606,6 +613,8 @@ typedef enum { METRICS_TEMPERATURE_VRMEM, METRICS_THROTTLER_STATUS, METRICS_CURR_FANSPEED, + METRICS_VOLTAGE_VDDSOC, + METRICS_VOLTAGE_VDDGFX, } MetricsMember_t; enum smu_cmn2asic_mapping_type { @@ -764,6 +773,7 @@ int smu_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value); ssize_t smu_sys_get_gpu_metrics(struct smu_context *smu, void **table); int smu_enable_mgpu_fan_boost(struct smu_context *smu); +int smu_gfx_state_change_set(struct smu_context *smu, uint32_t state); #endif #endif diff --git a/drivers/gpu/drm/amd/pm/inc/hwmgr.h b/drivers/gpu/drm/amd/pm/inc/hwmgr.h index 7e29ec2902dc..490371bd2520 100644 --- a/drivers/gpu/drm/amd/pm/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/pm/inc/hwmgr.h @@ -366,6 +366,7 @@ struct pp_hwmgr_func { int (*disable_power_features_for_compute_performance)(struct pp_hwmgr *hwmgr, bool disable); ssize_t (*get_gpu_metrics)(struct pp_hwmgr *hwmgr, void **table); + int (*gfx_state_change)(struct pp_hwmgr *hwmgr, uint32_t state); }; struct pp_table_func { @@ -827,5 +828,9 @@ int hwmgr_handle_task(struct pp_hwmgr *hwmgr, #define PHM_ENTIRE_REGISTER_MASK 0xFFFFFFFFU +int smu7_init_function_pointers(struct pp_hwmgr *hwmgr); +int smu8_init_function_pointers(struct pp_hwmgr *hwmgr); +int vega12_hwmgr_init(struct pp_hwmgr *hwmgr); +int vega20_hwmgr_init(struct pp_hwmgr *hwmgr); #endif /* _HWMGR_H_ */ diff --git a/drivers/gpu/drm/amd/pm/inc/pp_thermal.h b/drivers/gpu/drm/amd/pm/inc/pp_thermal.h index 3e30768f9e1c..f7c41185097e 100644 --- a/drivers/gpu/drm/amd/pm/inc/pp_thermal.h +++ b/drivers/gpu/drm/amd/pm/inc/pp_thermal.h @@ -25,13 +25,13 @@ #include "power_state.h" -static const struct PP_TemperatureRange SMU7ThermalWithDelayPolicy[] = +static const struct PP_TemperatureRange __maybe_unused SMU7ThermalWithDelayPolicy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; -static const struct PP_TemperatureRange SMU7ThermalPolicy[] = +static const struct PP_TemperatureRange __maybe_unused SMU7ThermalPolicy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, diff --git a/drivers/gpu/drm/amd/pm/inc/rv_ppsmc.h b/drivers/gpu/drm/amd/pm/inc/rv_ppsmc.h index df4677da736c..4c7e08ba5fa4 100644 --- a/drivers/gpu/drm/amd/pm/inc/rv_ppsmc.h +++ b/drivers/gpu/drm/amd/pm/inc/rv_ppsmc.h @@ -83,7 +83,8 @@ #define PPSMC_MSG_SetSoftMaxVcn 0x34 #define PPSMC_MSG_PowerGateMmHub 0x35 #define PPSMC_MSG_SetRccPfcPmeRestoreRegister 0x36 -#define PPSMC_Message_Count 0x37 +#define PPSMC_MSG_GpuChangeState 0x37 +#define PPSMC_Message_Count 0x42 typedef uint16_t PPSMC_Result; typedef int PPSMC_Msg; diff --git a/drivers/gpu/drm/amd/pm/inc/smu10.h b/drivers/gpu/drm/amd/pm/inc/smu10.h index b96520528240..9e837a5014c5 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu10.h +++ b/drivers/gpu/drm/amd/pm/inc/smu10.h @@ -136,14 +136,12 @@ #define FEATURE_CORE_CSTATES_MASK (1 << FEATURE_CORE_CSTATES_BIT) /* Workload bits */ -#define WORKLOAD_DEFAULT_BIT 0 -#define WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT 1 -#define WORKLOAD_PPLIB_POWER_SAVING_BIT 2 -#define WORKLOAD_PPLIB_VIDEO_BIT 3 -#define WORKLOAD_PPLIB_VR_BIT 4 -#define WORKLOAD_PPLIB_COMPUTE_BIT 5 -#define WORKLOAD_PPLIB_CUSTOM_BIT 6 -#define WORKLOAD_PPLIB_COUNT 7 +#define WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT 0 +#define WORKLOAD_PPLIB_VIDEO_BIT 2 +#define WORKLOAD_PPLIB_VR_BIT 3 +#define WORKLOAD_PPLIB_COMPUTE_BIT 4 +#define WORKLOAD_PPLIB_CUSTOM_BIT 5 +#define WORKLOAD_PPLIB_COUNT 6 typedef struct { /* MP1_EXT_SCRATCH0 */ diff --git a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h index e418a46603c8..fa95147b5a63 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h +++ b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h @@ -27,9 +27,9 @@ // *** IMPORTANT *** // SMU TEAM: Always increment the interface version if // any structure is changed in this file -#define SMU11_DRIVER_IF_VERSION 0x3A +#define SMU11_DRIVER_IF_VERSION 0x3B -#define PPTABLE_Sienna_Cichlid_SMU_VERSION 6 +#define PPTABLE_Sienna_Cichlid_SMU_VERSION 7 #define NUM_GFXCLK_DPM_LEVELS 16 #define NUM_SMNCLK_DPM_LEVELS 2 @@ -437,6 +437,7 @@ typedef enum { PIECEWISE_LINEAR_FUSED_MODEL = 0, PIECEWISE_LINEAR_PP_MODEL, QUADRATIC_PP_MODEL, + PERPART_PIECEWISE_LINEAR_PP_MODEL, } DfllDroopModelSelect_e; typedef struct { @@ -612,7 +613,9 @@ typedef struct { uint16_t SmnclkDpmFreq [NUM_SMNCLK_DPM_LEVELS]; // in MHz uint16_t SmnclkDpmVoltage [NUM_SMNCLK_DPM_LEVELS]; // mV(Q2) - uint32_t PaddingAPCC[4]; + uint32_t PaddingAPCC; + uint16_t PerPartDroopVsetGfxDfll[NUM_PIECE_WISE_LINEAR_DROOP_MODEL_VF_POINTS]; //In mV(Q2) + uint16_t PaddingPerPartDroop; // SECTION: Throttler settings uint32_t ThrottlerControlMask; // See Throtter masks defines @@ -667,7 +670,9 @@ typedef struct { uint16_t FreqTablePhyclk [NUM_PHYCLK_DPM_LEVELS ]; // In MHz uint16_t FreqTableDtbclk [NUM_DTBCLK_DPM_LEVELS ]; // In MHz uint16_t FreqTableFclk [NUM_FCLK_DPM_LEVELS ]; // In MHz - uint32_t Paddingclks[16]; + uint32_t Paddingclks; + + DroopInt_t PerPartDroopModelGfxDfll[NUM_PIECE_WISE_LINEAR_DROOP_MODEL_VF_POINTS]; //GHz ->Vstore in IEEE float format uint32_t DcModeMaxFreq [PPCLK_COUNT ]; // In MHz @@ -1221,7 +1226,8 @@ typedef struct { #define WORKLOAD_PPLIB_VR_BIT 4 #define WORKLOAD_PPLIB_COMPUTE_BIT 5 #define WORKLOAD_PPLIB_CUSTOM_BIT 6 -#define WORKLOAD_PPLIB_COUNT 7 +#define WORKLOAD_PPLIB_W3D_BIT 7 +#define WORKLOAD_PPLIB_COUNT 8 // These defines are used with the following messages: diff --git a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_vangogh.h b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_vangogh.h index 8f438c80132e..1c19eae93ff1 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_vangogh.h +++ b/drivers/gpu/drm/amd/pm/inc/smu11_driver_if_vangogh.h @@ -142,6 +142,12 @@ typedef struct { uint8_t NumDfPstatesEnabled; uint8_t NumDpmLevelsEnabled; + uint8_t NumDcfclkLevelsEnabled; + uint8_t NumDispClkLevelsEnabled; //applies to both dispclk and dppclk + uint8_t NumSocClkLevelsEnabled; + + uint8_t IspClkLevelsEnabled; //applies to both ispiclk and ispxclk + uint8_t VcnClkLevelsEnabled; //applies to both vclk/dclk uint8_t spare[2]; } DpmClocks_t; diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h index dc06459af91c..e5aa0725147c 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h @@ -30,10 +30,10 @@ #define SMU11_DRIVER_IF_VERSION_NV10 0x36 #define SMU11_DRIVER_IF_VERSION_NV12 0x36 #define SMU11_DRIVER_IF_VERSION_NV14 0x36 -#define SMU11_DRIVER_IF_VERSION_Sienna_Cichlid 0x3A -#define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0x5 +#define SMU11_DRIVER_IF_VERSION_Sienna_Cichlid 0x3B +#define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0xC #define SMU11_DRIVER_IF_VERSION_VANGOGH 0x02 -#define SMU11_DRIVER_IF_VERSION_Dimgrey_Cavefish 0xB +#define SMU11_DRIVER_IF_VERSION_Dimgrey_Cavefish 0xF /* MP Apertures */ #define MP0_Public 0x03800000 @@ -58,7 +58,8 @@ #define CTF_OFFSET_HOTSPOT 5 #define CTF_OFFSET_MEM 5 -static const struct smu_temperature_range smu11_thermal_policy[] = +static const +struct smu_temperature_range __maybe_unused smu11_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, @@ -276,6 +277,8 @@ int smu_v11_0_get_current_pcie_link_speed(struct smu_context *smu); void smu_v11_0_init_gpu_metrics_v1_0(struct gpu_metrics_v1_0 *gpu_metrics); +void smu_v11_0_init_gpu_metrics_v2_0(struct gpu_metrics_v2_0 *gpu_metrics); + int smu_v11_0_gfx_ulv_control(struct smu_context *smu, bool enablement); diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_5_pmfw.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_5_pmfw.h index 99a406984135..22edd88b8117 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_5_pmfw.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_5_pmfw.h @@ -90,14 +90,16 @@ #define FEATURE_ATHUB_PG_BIT 56 #define FEATURE_ECO_DEEPCSTATE_BIT 57 #define FEATURE_CC6_BIT 58 -#define NUM_FEATURES 59 +#define FEATURE_GFX_EDC_BIT 59 +#define NUM_FEATURES 60 typedef struct { // MP1_EXT_SCRATCH0 uint32_t DpmHandlerID : 8; uint32_t ActivityMonitorID : 8; uint32_t DpmTimerID : 8; - uint32_t spare0 : 8; + uint32_t DpmHubID : 4; + uint32_t DpmHubTask : 4; // MP1_EXT_SCRATCH1 uint32_t GfxStatus : 2; uint32_t GfxoffStatus : 8; @@ -109,9 +111,10 @@ typedef struct { uint32_t spare1 : 16; // MP1_EXT_SCRATCH2 uint32_t P2JobHandler : 32; - // MP1_EXT_SCRATCH3 -// uint32_t spare2 : 32; + // MP1_EXT_SCRATCH3: used for postcodes + // MP1_EXT_SCRATCH4:6 are used by Kernel + // MP1_EXT_SCRATCH7: used by HW } FwStatus_t; diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h index 1ada0eb64663..7e69b3bd311b 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h @@ -97,9 +97,16 @@ #define PPSMC_MSG_StopDramLogging 0x3F #define PPSMC_MSG_SetSoftMinCclk 0x40 #define PPSMC_MSG_SetSoftMaxCclk 0x41 -#define PPSMC_Message_Count 0x42 +#define PPSMC_MSG_SetDfPstateActiveLevel 0x42 +#define PPSMC_MSG_SetDfPstateSoftMinLevel 0x43 +#define PPSMC_MSG_SetCclkPolicy 0x44 +#define PPSMC_MSG_DramLogSetDramAddrHigh 0x45 +#define PPSMC_MSG_DramLogSetDramBufferSize 0x46 +#define PPSMC_MSG_RequestActiveWgp 0x47 +#define PPSMC_MSG_QueryActiveWgp 0x48 +#define PPSMC_Message_Count 0x49 -//Argument for PPSMC_MSG_GpuChangeState +//Argument for PPSMC_MSG_GfxDeviceDriverReset enum { MODE1_RESET = 1, MODE2_RESET = 2 diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c index eab9768029c1..e0d288208220 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c @@ -1629,6 +1629,24 @@ static ssize_t pp_get_gpu_metrics(void *handle, void **table) return size; } +static int pp_gfx_state_change_set(void *handle, uint32_t state) +{ + struct pp_hwmgr *hwmgr = handle; + + if (!hwmgr || !hwmgr->pm_en) + return -EINVAL; + + if (hwmgr->hwmgr_func->gfx_state_change == NULL) { + pr_info_ratelimited("%s was not implemented.\n", __func__); + return -EINVAL; + } + + mutex_lock(&hwmgr->smu_lock); + hwmgr->hwmgr_func->gfx_state_change(hwmgr, state); + mutex_unlock(&hwmgr->smu_lock); + return 0; +} + static const struct amd_pm_funcs pp_dpm_funcs = { .load_firmware = pp_dpm_load_fw, .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, @@ -1691,4 +1709,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = { .set_df_cstate = pp_set_df_cstate, .set_xgmi_pstate = pp_set_xgmi_pstate, .get_gpu_metrics = pp_get_gpu_metrics, + .gfx_state_change_set = pp_gfx_state_change_set, }; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c index 1f9b9facdf1f..25b5831a15cd 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c @@ -223,11 +223,11 @@ int phm_register_irq_handlers(struct pp_hwmgr *hwmgr) } /** -* Initializes the thermal controller subsystem. -* -* @param pHwMgr the address of the powerplay hardware manager. -* @exception PP_Result_Failed if any of the paramters is NULL, otherwise the return value from the dispatcher. -*/ + * phm_start_thermal_controller - Initializes the thermal controller subsystem. + * + * @hwmgr: the address of the powerplay hardware manager. + * Exception PP_Result_Failed if any of the paramters is NULL, otherwise the return value from the dispatcher. + */ int phm_start_thermal_controller(struct pp_hwmgr *hwmgr) { int ret = 0; @@ -371,13 +371,14 @@ int phm_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_s /** -* Gets Clock Info. -* -* @param pHwMgr the address of the powerplay hardware manager. -* @param pPowerState the address of the Power State structure. -* @param pClockInfo the address of PP_ClockInfo structure where the result will be returned. -* @exception PP_Result_Failed if any of the paramters is NULL, otherwise the return value from the back-end. -*/ + * phm_get_clock_info + * + * @hwmgr: the address of the powerplay hardware manager. + * @state: the address of the Power State structure. + * @pclock_info: the address of PP_ClockInfo structure where the result will be returned. + * @designation: PHM performance level designation + * Exception PP_Result_Failed if any of the paramters is NULL, otherwise the return value from the back-end. + */ int phm_get_clock_info(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, struct pp_clock_info *pclock_info, PHM_PerformanceLevelDesignation designation) { @@ -514,34 +515,3 @@ int phm_set_active_display_count(struct pp_hwmgr *hwmgr, uint32_t count) return hwmgr->hwmgr_func->set_active_display_count(hwmgr, count); } - -int phm_set_min_deep_sleep_dcefclk(struct pp_hwmgr *hwmgr, uint32_t clock) -{ - PHM_FUNC_CHECK(hwmgr); - - if (!hwmgr->hwmgr_func->set_min_deep_sleep_dcefclk) - return -EINVAL; - - return hwmgr->hwmgr_func->set_min_deep_sleep_dcefclk(hwmgr, clock); -} - -int phm_set_hard_min_dcefclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t clock) -{ - PHM_FUNC_CHECK(hwmgr); - - if (!hwmgr->hwmgr_func->set_hard_min_dcefclk_by_freq) - return -EINVAL; - - return hwmgr->hwmgr_func->set_hard_min_dcefclk_by_freq(hwmgr, clock); -} - -int phm_set_hard_min_fclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t clock) -{ - PHM_FUNC_CHECK(hwmgr); - - if (!hwmgr->hwmgr_func->set_hard_min_fclk_by_freq) - return -EINVAL; - - return hwmgr->hwmgr_func->set_hard_min_fclk_by_freq(hwmgr, clock); -} - diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c index 739e215ec8b7..6a7de8b898fa 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c @@ -46,11 +46,7 @@ extern const struct pp_smumgr_func vega12_smu_funcs; extern const struct pp_smumgr_func smu10_smu_funcs; extern const struct pp_smumgr_func vega20_smu_funcs; -extern int smu7_init_function_pointers(struct pp_hwmgr *hwmgr); -extern int smu8_init_function_pointers(struct pp_hwmgr *hwmgr); extern int vega10_hwmgr_init(struct pp_hwmgr *hwmgr); -extern int vega12_hwmgr_init(struct pp_hwmgr *hwmgr); -extern int vega20_hwmgr_init(struct pp_hwmgr *hwmgr); extern int smu10_init_function_pointers(struct pp_hwmgr *hwmgr); static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c index 31a32a79cfc2..67d7da0b6fed 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c @@ -74,6 +74,13 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr) for (i = 0; i < table_entries; i++) { result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state); + if (result) { + kfree(hwmgr->request_ps); + kfree(hwmgr->ps); + hwmgr->request_ps = NULL; + hwmgr->ps = NULL; + return -EINVAL; + } if (state->classification.flags & PP_StateClassificationFlag_Boot) { hwmgr->boot_ps = state; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c index c2fee6796bd9..83a6504e093c 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c @@ -92,11 +92,11 @@ static int atomctrl_retrieve_ac_timing( } /** - * Get memory clock AC timing registers index from VBIOS table + * atomctrl_set_mc_reg_address_table - Get memory clock AC timing registers index from VBIOS table * VBIOS set end of memory clock AC timing registers by ucPreRegDataLength bit6 = 1 - * @param reg_block the address ATOM_INIT_REG_BLOCK - * @param table the address of MCRegTable - * @return 0 + * @reg_block: the address ATOM_INIT_REG_BLOCK + * @table: the address of MCRegTable + * Return: 0 */ static int atomctrl_set_mc_reg_address_table( ATOM_INIT_REG_BLOCK *reg_block, @@ -203,7 +203,7 @@ int atomctrl_initialize_mc_reg_table_v2_2( return result; } -/** +/* * Set DRAM timings based on engine clock and memory clock. */ int atomctrl_set_engine_dram_timings_rv770( @@ -229,7 +229,7 @@ int atomctrl_set_engine_dram_timings_rv770( (uint32_t *)&engine_clock_parameters); } -/** +/* * Private Function to get the PowerPlay Table Address. * WARNING: The tabled returned by this function is in * dynamically allocated memory. @@ -274,12 +274,13 @@ static const ATOM_VOLTAGE_OBJECT_V3 *atomctrl_lookup_voltage_type_v3( return NULL; } -/** atomctrl_get_memory_pll_dividers_si(). +/** + * atomctrl_get_memory_pll_dividers_si(). * - * @param hwmgr input parameter: pointer to HwMgr - * @param clock_value input parameter: memory clock - * @param dividers output parameter: memory PLL dividers - * @param strobe_mode input parameter: 1 for strobe mode, 0 for performance mode + * @hwmgr: input parameter: pointer to HwMgr + * @clock_value: input parameter: memory clock + * @dividers: output parameter: memory PLL dividers + * @strobe_mode: input parameter: 1 for strobe mode, 0 for performance mode */ int atomctrl_get_memory_pll_dividers_si( struct pp_hwmgr *hwmgr, @@ -326,11 +327,12 @@ int atomctrl_get_memory_pll_dividers_si( return result; } -/** atomctrl_get_memory_pll_dividers_vi(). +/** + * atomctrl_get_memory_pll_dividers_vi(). * - * @param hwmgr input parameter: pointer to HwMgr - * @param clock_value input parameter: memory clock - * @param dividers output parameter: memory PLL dividers + * @hwmgr: input parameter: pointer to HwMgr + * @clock_value: input parameter: memory clock + * @dividers: output parameter: memory PLL dividers */ int atomctrl_get_memory_pll_dividers_vi(struct pp_hwmgr *hwmgr, uint32_t clock_value, pp_atomctrl_memory_clock_param *mpll_param) @@ -512,7 +514,7 @@ int atomctrl_get_dfs_pll_dividers_vi( return result; } -/** +/* * Get the reference clock in 10KHz */ uint32_t atomctrl_get_reference_clock(struct pp_hwmgr *hwmgr) @@ -535,7 +537,7 @@ uint32_t atomctrl_get_reference_clock(struct pp_hwmgr *hwmgr) return clock; } -/** +/* * Returns true if the given voltage type is controlled by GPIO pins. * voltage_type is one of SET_VOLTAGE_TYPE_ASIC_VDDC, * SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ. @@ -630,7 +632,7 @@ static bool atomctrl_lookup_gpio_pin( return false; } -/** +/* * Private Function to get the PowerPlay Table Address. * WARNING: The tabled returned by this function is in * dynamically allocated memory. @@ -653,7 +655,7 @@ static ATOM_GPIO_PIN_LUT *get_gpio_lookup_table(void *device) return (ATOM_GPIO_PIN_LUT *)table_address; } -/** +/* * Returns 1 if the given pin id find in lookup table. */ bool atomctrl_get_pp_assign_pin( @@ -699,7 +701,7 @@ int atomctrl_calculate_voltage_evv_on_sclk( fInt fMargin_RO_a, fMargin_RO_b, fMargin_RO_c, fMargin_fixed, fMargin_FMAX_mean, fMargin_Plat_mean, fMargin_FMAX_sigma, fMargin_Plat_sigma, fMargin_DC_sigma; fInt fLkg_FT, repeat; fInt fMicro_FMAX, fMicro_CR, fSigma_FMAX, fSigma_CR, fSigma_DC, fDC_SCLK, fSquared_Sigma_DC, fSquared_Sigma_CR, fSquared_Sigma_FMAX; - fInt fRLL_LoadLine, fPowerDPMx, fDerateTDP, fVDDC_base, fA_Term, fC_Term, fB_Term, fRO_DC_margin; + fInt fRLL_LoadLine, fDerateTDP, fVDDC_base, fA_Term, fC_Term, fB_Term, fRO_DC_margin; fInt fRO_fused, fCACm_fused, fCACb_fused, fKv_m_fused, fKv_b_fused, fKt_Beta_fused, fFT_Lkg_V0NORM; fInt fSclk_margin, fSclk, fEVV_V; fInt fV_min, fV_max, fT_prod, fLKG_Factor, fT_FT, fV_FT, fV_x, fTDP_Power, fTDP_Power_right, fTDP_Power_left, fTDP_Current, fV_NL; @@ -731,36 +733,28 @@ int atomctrl_calculate_voltage_evv_on_sclk( switch (dpm_level) { case 1: - fPowerDPMx = Convert_ULONG_ToFraction(le16_to_cpu(getASICProfilingInfo->usPowerDpm1)); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM1), 1000); break; case 2: - fPowerDPMx = Convert_ULONG_ToFraction(le16_to_cpu(getASICProfilingInfo->usPowerDpm2)); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM2), 1000); break; case 3: - fPowerDPMx = Convert_ULONG_ToFraction(le16_to_cpu(getASICProfilingInfo->usPowerDpm3)); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM3), 1000); break; case 4: - fPowerDPMx = Convert_ULONG_ToFraction(le16_to_cpu(getASICProfilingInfo->usPowerDpm4)); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM4), 1000); break; case 5: - fPowerDPMx = Convert_ULONG_ToFraction(le16_to_cpu(getASICProfilingInfo->usPowerDpm5)); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM5), 1000); break; case 6: - fPowerDPMx = Convert_ULONG_ToFraction(le16_to_cpu(getASICProfilingInfo->usPowerDpm6)); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM6), 1000); break; case 7: - fPowerDPMx = Convert_ULONG_ToFraction(le16_to_cpu(getASICProfilingInfo->usPowerDpm7)); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM7), 1000); break; default: pr_err("DPM Level not supported\n"); - fPowerDPMx = Convert_ULONG_ToFraction(1); fDerateTDP = GetScaledFraction(le32_to_cpu(getASICProfilingInfo->ulTdpDerateDPM0), 1000); } @@ -1109,14 +1103,15 @@ int atomctrl_calculate_voltage_evv_on_sclk( return result; } -/** atomctrl_get_voltage_evv_on_sclk gets voltage via call to ATOM COMMAND table. - * @param hwmgr input: pointer to hwManager - * @param voltage_type input: type of EVV voltage VDDC or VDDGFX - * @param sclk input: in 10Khz unit. DPM state SCLK frequency - * which is define in PPTable SCLK/VDDC dependence - * table associated with this virtual_voltage_Id - * @param virtual_voltage_Id input: voltage id which match per voltage DPM state: 0xff01, 0xff02.. 0xff08 - * @param voltage output: real voltage level in unit of mv +/** + * atomctrl_get_voltage_evv_on_sclk gets voltage via call to ATOM COMMAND table. + * @hwmgr: input: pointer to hwManager + * @voltage_type: input: type of EVV voltage VDDC or VDDGFX + * @sclk: input: in 10Khz unit. DPM state SCLK frequency + * which is define in PPTable SCLK/VDDC dependence + * table associated with this virtual_voltage_Id + * @virtual_voltage_Id: input: voltage id which match per voltage DPM state: 0xff01, 0xff02.. 0xff08 + * @voltage: output: real voltage level in unit of mv */ int atomctrl_get_voltage_evv_on_sclk( struct pp_hwmgr *hwmgr, @@ -1150,9 +1145,9 @@ int atomctrl_get_voltage_evv_on_sclk( /** * atomctrl_get_voltage_evv gets voltage via call to ATOM COMMAND table. - * @param hwmgr input: pointer to hwManager - * @param virtual_voltage_id input: voltage id which match per voltage DPM state: 0xff01, 0xff02.. 0xff08 - * @param voltage output: real voltage level in unit of mv + * @hwmgr: input: pointer to hwManager + * @virtual_voltage_id: input: voltage id which match per voltage DPM state: 0xff01, 0xff02.. 0xff08 + * @voltage: output: real voltage level in unit of mv */ int atomctrl_get_voltage_evv(struct pp_hwmgr *hwmgr, uint16_t virtual_voltage_id, @@ -1195,7 +1190,7 @@ int atomctrl_get_voltage_evv(struct pp_hwmgr *hwmgr, return result; } -/** +/* * Get the mpll reference clock in 10KHz */ uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr) @@ -1228,7 +1223,7 @@ uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr) return clock; } -/** +/* * Get the asic internal spread spectrum table */ static ATOM_ASIC_INTERNAL_SS_INFO *asic_internal_ss_get_ss_table(void *device) @@ -1256,7 +1251,7 @@ bool atomctrl_is_asic_internal_ss_supported(struct pp_hwmgr *hwmgr) return false; } -/** +/* * Get the asic internal spread spectrum assignment */ static int asic_internal_ss_get_ss_asignment(struct pp_hwmgr *hwmgr, @@ -1319,7 +1314,7 @@ static int asic_internal_ss_get_ss_asignment(struct pp_hwmgr *hwmgr, return entry_found ? 0 : 1; } -/** +/* * Get the memory clock spread spectrum info */ int atomctrl_get_memory_clock_spread_spectrum( @@ -1330,7 +1325,8 @@ int atomctrl_get_memory_clock_spread_spectrum( return asic_internal_ss_get_ss_asignment(hwmgr, ASIC_INTERNAL_MEMORY_SS, memory_clock, ssInfo); } -/** + +/* * Get the engine clock spread spectrum info */ int atomctrl_get_engine_clock_spread_spectrum( diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c index 615cf2c09e54..a47a47238e2b 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c @@ -68,11 +68,11 @@ static struct atom_voltage_objects_info_v4_1 *pp_atomfwctrl_get_voltage_info_tab return (struct atom_voltage_objects_info_v4_1 *)table_address; } -/** -* Returns TRUE if the given voltage type is controlled by GPIO pins. -* voltage_type is one of SET_VOLTAGE_TYPE_ASIC_VDDC, SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ. -* voltage_mode is one of ATOM_SET_VOLTAGE, ATOM_SET_VOLTAGE_PHASE -*/ +/* + * Returns TRUE if the given voltage type is controlled by GPIO pins. + * voltage_type is one of SET_VOLTAGE_TYPE_ASIC_VDDC, SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ. + * voltage_mode is one of ATOM_SET_VOLTAGE, ATOM_SET_VOLTAGE_PHASE + */ bool pp_atomfwctrl_is_voltage_controlled_by_gpio_v4(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint8_t voltage_mode) { @@ -202,9 +202,9 @@ static bool pp_atomfwctrl_lookup_gpio_pin( return false; } -/** -* Returns TRUE if the given pin id find in lookup table. -*/ +/* + * Returns TRUE if the given pin id find in lookup table. + */ bool pp_atomfwctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pin_id, struct pp_atomfwctrl_gpio_pin_assignment *gpio_pin_assignment) @@ -224,10 +224,10 @@ bool pp_atomfwctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, return ret; } -/** -* Enter to SelfRefresh mode. -* @param hwmgr -*/ +/* + * Enter to SelfRefresh mode. + * @param hwmgr + */ int pp_atomfwctrl_enter_self_refresh(struct pp_hwmgr *hwmgr) { /* 0 - no action diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h index 8f50a038396c..dac29fe6cfc6 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h @@ -333,14 +333,14 @@ static fInt fMultiply (fInt X, fInt Y) /* Uses 64-bit integers (int64_t) */ { fInt Product; int64_t tempProduct; + + /*The following is for a very specific common case: Non-zero number with ONLY fractional portion*/ + /* TEMPORARILY DISABLED - CAN BE USED TO IMPROVE PRECISION bool X_LessThanOne, Y_LessThanOne; X_LessThanOne = (X.partial.real == 0 && X.partial.decimal != 0 && X.full >= 0); Y_LessThanOne = (Y.partial.real == 0 && Y.partial.decimal != 0 && Y.full >= 0); - /*The following is for a very specific common case: Non-zero number with ONLY fractional portion*/ - /* TEMPORARILY DISABLED - CAN BE USED TO IMPROVE PRECISION - if (X_LessThanOne && Y_LessThanOne) { Product.full = X.full * Y.full; return Product diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c index 801a56502670..741e03ad5311 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c @@ -32,10 +32,10 @@ #include "pptable_v1_0.h" /** - * Private Function used during initialization. - * @param hwmgr Pointer to the hardware manager. - * @param setIt A flag indication if the capability should be set (TRUE) or reset (FALSE). - * @param cap Which capability to set/reset. + * set_hw_cap - Private Function used during initialization. + * @hwmgr: Pointer to the hardware manager. + * @setIt: A flag indication if the capability should be set (TRUE) or reset (FALSE). + * @cap: Which capability to set/reset. */ static void set_hw_cap(struct pp_hwmgr *hwmgr, bool setIt, enum phm_platform_caps cap) { @@ -47,10 +47,10 @@ static void set_hw_cap(struct pp_hwmgr *hwmgr, bool setIt, enum phm_platform_cap /** - * Private Function used during initialization. - * @param hwmgr Pointer to the hardware manager. - * @param powerplay_caps the bit array (from BIOS) of capability bits. - * @exception the current implementation always returns 1. + * set_platform_caps - Private Function used during initialization. + * @hwmgr: Pointer to the hardware manager. + * @powerplay_caps: the bit array (from BIOS) of capability bits. + * Exception: the current implementation always returns 1. */ static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps) { @@ -128,7 +128,7 @@ static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps) return 0; } -/** +/* * Private Function to get the PowerPlay Table Address. */ static const void *get_powerplay_table(struct pp_hwmgr *hwmgr) @@ -191,10 +191,10 @@ static int get_vddc_lookup_table( } /** - * Private Function used during initialization. + * get_platform_power_management_table - Private Function used during initialization. * Initialize Platform Power Management Parameter table - * @param hwmgr Pointer to the hardware manager. - * @param atom_ppm_table Pointer to PPM table in VBIOS + * @hwmgr: Pointer to the hardware manager. + * @atom_ppm_table: Pointer to PPM table in VBIOS */ static int get_platform_power_management_table( struct pp_hwmgr *hwmgr, @@ -234,10 +234,10 @@ static int get_platform_power_management_table( } /** - * Private Function used during initialization. + * init_dpm_2_parameters - Private Function used during initialization. * Initialize TDP limits for DPM2 - * @param hwmgr Pointer to the hardware manager. - * @param powerplay_table Pointer to the PowerPlay Table. + * @hwmgr: Pointer to the hardware manager. + * @powerplay_table: Pointer to the PowerPlay Table. */ static int init_dpm_2_parameters( struct pp_hwmgr *hwmgr, @@ -779,10 +779,10 @@ static int get_gpio_table(struct pp_hwmgr *hwmgr, return 0; } /** - * Private Function used during initialization. + * init_clock_voltage_dependency - Private Function used during initialization. * Initialize clock voltage dependency - * @param hwmgr Pointer to the hardware manager. - * @param powerplay_table Pointer to the PowerPlay Table. + * @hwmgr: Pointer to the hardware manager. + * @powerplay_table: Pointer to the PowerPlay Table. */ static int init_clock_voltage_dependency( struct pp_hwmgr *hwmgr, @@ -871,15 +871,16 @@ static int init_clock_voltage_dependency( return result; } -/** Retrieves the (signed) Overdrive limits from VBIOS. +/** + * init_over_drive_limits - Retrieves the (signed) Overdrive limits from VBIOS. * The max engine clock, memory clock and max temperature come from the firmware info table. * * The information is placed into the platform descriptor. * - * @param hwmgr source of the VBIOS table and owner of the platform descriptor to be updated. - * @param powerplay_table the address of the PowerPlay table. + * @hwmgr: source of the VBIOS table and owner of the platform descriptor to be updated. + * @powerplay_table: the address of the PowerPlay table. * - * @return 1 as long as the firmware info table was present and of a supported version. + * Return: 1 as long as the firmware info table was present and of a supported version. */ static int init_over_drive_limits( struct pp_hwmgr *hwmgr, @@ -898,11 +899,11 @@ static int init_over_drive_limits( } /** - * Private Function used during initialization. + * init_thermal_controller - Private Function used during initialization. * Inspect the PowerPlay table for obvious signs of corruption. - * @param hwmgr Pointer to the hardware manager. - * @param powerplay_table Pointer to the PowerPlay Table. - * @exception This implementation always returns 1. + * @hwmgr: Pointer to the hardware manager. + * @powerplay_table: Pointer to the PowerPlay Table. + * Exception: This implementation always returns 1. */ static int init_thermal_controller( struct pp_hwmgr *hwmgr, @@ -1108,11 +1109,11 @@ static int init_thermal_controller( } /** - * Private Function used during initialization. + * check_powerplay_tables - Private Function used during initialization. * Inspect the PowerPlay table for obvious signs of corruption. - * @param hwmgr Pointer to the hardware manager. - * @param powerplay_table Pointer to the PowerPlay Table. - * @exception 2 if the powerplay table is incorrect. + * @hwmgr: Pointer to the hardware manager. + * @powerplay_table: Pointer to the PowerPlay Table. + * Exception: 2 if the powerplay table is incorrect. */ static int check_powerplay_tables( struct pp_hwmgr *hwmgr, @@ -1255,9 +1256,9 @@ int get_number_of_powerplay_table_entries_v1_0(struct pp_hwmgr *hwmgr) return (uint32_t)(state_arrays->ucNumEntries); } -/** -* Private function to convert flags stored in the BIOS to software flags in PowerPlay. -*/ +/* + * Private function to convert flags stored in the BIOS to software flags in PowerPlay. + */ static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr, uint16_t classification, uint16_t classification2) { @@ -1356,13 +1357,13 @@ static int ppt_get_vce_state_table_entry_v1_0(struct pp_hwmgr *hwmgr, uint32_t i } /** -* Create a Power State out of an entry in the PowerPlay table. -* This function is called by the hardware back-end. -* @param hwmgr Pointer to the hardware manager. -* @param entry_index The index of the entry to be extracted from the table. -* @param power_state The address of the PowerState instance being created. -* @return -1 if the entry cannot be retrieved. -*/ + * get_powerplay_table_entry_v1_0 - Create a Power State out of an entry in the PowerPlay table. + * This function is called by the hardware back-end. + * @hwmgr: Pointer to the hardware manager. + * @entry_index: The index of the entry to be extracted from the table. + * @power_state: The address of the PowerState instance being created. + * Return: -1 if the entry cannot be retrieved. + */ int get_powerplay_table_entry_v1_0(struct pp_hwmgr *hwmgr, uint32_t entry_index, struct pp_power_state *power_state, int (*call_back_func)(struct pp_hwmgr *, void *, diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c index 48d550d26c6a..182118e3fd5f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c @@ -24,6 +24,8 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/slab.h> +#include <linux/pci.h> + #include <drm/amdgpu_drm.h> #include "processpptables.h" #include <atom-types.h> @@ -980,6 +982,8 @@ static int init_thermal_controller( struct pp_hwmgr *hwmgr, const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table) { + struct amdgpu_device *adev = hwmgr->adev; + hwmgr->thermal_controller.ucType = powerplay_table->sThermalController.ucType; hwmgr->thermal_controller.ucI2cLine = @@ -1004,7 +1008,104 @@ static int init_thermal_controller( ATOM_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType, PHM_PlatformCaps_ThermalController); - hwmgr->thermal_controller.use_hw_fan_control = 1; + if (powerplay_table->usTableSize >= sizeof(ATOM_PPLIB_POWERPLAYTABLE3)) { + const ATOM_PPLIB_POWERPLAYTABLE3 *powerplay_table3 = + (const ATOM_PPLIB_POWERPLAYTABLE3 *)powerplay_table; + + if (0 == le16_to_cpu(powerplay_table3->usFanTableOffset)) { + hwmgr->thermal_controller.use_hw_fan_control = 1; + return 0; + } else { + const ATOM_PPLIB_FANTABLE *fan_table = + (const ATOM_PPLIB_FANTABLE *)(((unsigned long)powerplay_table) + + le16_to_cpu(powerplay_table3->usFanTableOffset)); + + if (1 <= fan_table->ucFanTableFormat) { + hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst = + fan_table->ucTHyst; + hwmgr->thermal_controller.advanceFanControlParameters.usTMin = + le16_to_cpu(fan_table->usTMin); + hwmgr->thermal_controller.advanceFanControlParameters.usTMed = + le16_to_cpu(fan_table->usTMed); + hwmgr->thermal_controller.advanceFanControlParameters.usTHigh = + le16_to_cpu(fan_table->usTHigh); + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin = + le16_to_cpu(fan_table->usPWMMin); + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed = + le16_to_cpu(fan_table->usPWMMed); + hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh = + le16_to_cpu(fan_table->usPWMHigh); + hwmgr->thermal_controller.advanceFanControlParameters.usTMax = 10900; + hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay = 100000; + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + } + + if (2 <= fan_table->ucFanTableFormat) { + const ATOM_PPLIB_FANTABLE2 *fan_table2 = + (const ATOM_PPLIB_FANTABLE2 *)(((unsigned long)powerplay_table) + + le16_to_cpu(powerplay_table3->usFanTableOffset)); + hwmgr->thermal_controller.advanceFanControlParameters.usTMax = + le16_to_cpu(fan_table2->usTMax); + } + + if (3 <= fan_table->ucFanTableFormat) { + const ATOM_PPLIB_FANTABLE3 *fan_table3 = + (const ATOM_PPLIB_FANTABLE3 *) (((unsigned long)powerplay_table) + + le16_to_cpu(powerplay_table3->usFanTableOffset)); + + hwmgr->thermal_controller.advanceFanControlParameters.ucFanControlMode = + fan_table3->ucFanControlMode; + + if ((3 == fan_table->ucFanTableFormat) && + (0x67B1 == adev->pdev->device)) + hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM = + 47; + else + hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM = + le16_to_cpu(fan_table3->usFanPWMMax); + + hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity = + 4836; + hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity = + le16_to_cpu(fan_table3->usFanOutputSensitivity); + } + + if (6 <= fan_table->ucFanTableFormat) { + const ATOM_PPLIB_FANTABLE4 *fan_table4 = + (const ATOM_PPLIB_FANTABLE4 *)(((unsigned long)powerplay_table) + + le16_to_cpu(powerplay_table3->usFanTableOffset)); + + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_FanSpeedInTableIsRPM); + + hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanRPM = + le16_to_cpu(fan_table4->usFanRPMMax); + } + + if (7 <= fan_table->ucFanTableFormat) { + const ATOM_PPLIB_FANTABLE5 *fan_table5 = + (const ATOM_PPLIB_FANTABLE5 *)(((unsigned long)powerplay_table) + + le16_to_cpu(powerplay_table3->usFanTableOffset)); + + if (0x67A2 == adev->pdev->device || + 0x67A9 == adev->pdev->device || + 0x67B9 == adev->pdev->device) { + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_GeminiRegulatorFanControlSupport); + hwmgr->thermal_controller.advanceFanControlParameters.usFanCurrentLow = + le16_to_cpu(fan_table5->usFanCurrentLow); + hwmgr->thermal_controller.advanceFanControlParameters.usFanCurrentHigh = + le16_to_cpu(fan_table5->usFanCurrentHigh); + hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMLow = + le16_to_cpu(fan_table5->usFanRPMLow); + hwmgr->thermal_controller.advanceFanControlParameters.usFanRPMHigh = + le16_to_cpu(fan_table5->usFanRPMHigh); + } + } + } + } return 0; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index cf60f3992303..e57e64bbacdc 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -130,9 +130,10 @@ static int smu10_construct_max_power_limits_table(struct pp_hwmgr *hwmgr, static int smu10_init_dynamic_state_adjustment_rule_settings( struct pp_hwmgr *hwmgr) { + int count = 8; struct phm_clock_voltage_dependency_table *table_clk_vlt; - table_clk_vlt = kzalloc(struct_size(table_clk_vlt, entries, 7), + table_clk_vlt = kzalloc(struct_size(table_clk_vlt, entries, count), GFP_KERNEL); if (NULL == table_clk_vlt) { @@ -140,7 +141,7 @@ static int smu10_init_dynamic_state_adjustment_rule_settings( return -ENOMEM; } - table_clk_vlt->count = 8; + table_clk_vlt->count = count; table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_0; table_clk_vlt->entries[0].v = 0; table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_1; @@ -1297,15 +1298,9 @@ static int conv_power_profile_to_pplib_workload(int power_profile) int pplib_workload = 0; switch (power_profile) { - case PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT: - pplib_workload = WORKLOAD_DEFAULT_BIT; - break; case PP_SMC_POWER_PROFILE_FULLSCREEN3D: pplib_workload = WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT; break; - case PP_SMC_POWER_PROFILE_POWERSAVING: - pplib_workload = WORKLOAD_PPLIB_POWER_SAVING_BIT; - break; case PP_SMC_POWER_PROFILE_VIDEO: pplib_workload = WORKLOAD_PPLIB_VIDEO_BIT; break; @@ -1315,6 +1310,9 @@ static int conv_power_profile_to_pplib_workload(int power_profile) case PP_SMC_POWER_PROFILE_COMPUTE: pplib_workload = WORKLOAD_PPLIB_COMPUTE_BIT; break; + case PP_SMC_POWER_PROFILE_CUSTOM: + pplib_workload = WORKLOAD_PPLIB_CUSTOM_BIT; + break; } return pplib_workload; @@ -1438,6 +1436,13 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, return 0; } +static int smu10_gfx_state_change(struct pp_hwmgr *hwmgr, uint32_t state) +{ + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GpuChangeState, state, NULL); + + return 0; +} + static const struct pp_hwmgr_func smu10_hwmgr_funcs = { .backend_init = smu10_hwmgr_backend_init, .backend_fini = smu10_hwmgr_backend_fini, @@ -1484,6 +1489,7 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = { .set_power_profile_mode = smu10_set_power_profile_mode, .asic_reset = smu10_asic_reset, .set_fine_grain_clk_vol = smu10_set_fine_grain_clk_vol, + .gfx_state_change = smu10_gfx_state_change, }; int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index 53111c6bbcc9..82676c086ce4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -193,10 +193,10 @@ static const struct smu7_power_state *cast_const_phw_smu7_power_state( } /** - * Find the MC microcode version and store it in the HwMgr struct + * smu7_get_mc_microcode_version - Find the MC microcode version and store it in the HwMgr struct * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_get_mc_microcode_version(struct pp_hwmgr *hwmgr) { @@ -233,11 +233,11 @@ static int smu7_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr) } /** -* Enable voltage control -* -* @param pHwMgr the address of the powerplay hardware manager. -* @return always PP_Result_OK -*/ + * smu7_enable_smc_voltage_controller - Enable voltage control + * + * @hwmgr the address of the powerplay hardware manager. + * Return: always PP_Result_OK + */ static int smu7_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr) { if (hwmgr->chip_id >= CHIP_POLARIS10 && @@ -255,10 +255,10 @@ static int smu7_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr) } /** -* Checks if we want to support voltage control -* -* @param hwmgr the address of the powerplay hardware manager. -*/ + * smu7_voltage_control - Checks if we want to support voltage control + * + * @hwmgr: the address of the powerplay hardware manager. + */ static bool smu7_voltage_control(const struct pp_hwmgr *hwmgr) { const struct smu7_hwmgr *data = @@ -268,11 +268,11 @@ static bool smu7_voltage_control(const struct pp_hwmgr *hwmgr) } /** -* Enable voltage control -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_enable_voltage_control - Enable voltage control + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_enable_voltage_control(struct pp_hwmgr *hwmgr) { /* enable voltage control */ @@ -306,11 +306,11 @@ static int phm_get_svi2_voltage_table_v0(pp_atomctrl_voltage_table *voltage_tabl /** -* Create Voltage Tables. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_construct_voltage_tables - Create Voltage Tables. + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_construct_voltage_tables(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -418,11 +418,11 @@ static int smu7_construct_voltage_tables(struct pp_hwmgr *hwmgr) } /** -* Programs static screed detection parameters -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_program_static_screen_threshold_parameters - Programs static screed detection parameters + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_program_static_screen_threshold_parameters( struct pp_hwmgr *hwmgr) { @@ -441,11 +441,11 @@ static int smu7_program_static_screen_threshold_parameters( } /** -* Setup display gap for glitch free memory clock switching. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_enable_display_gap - Setup display gap for glitch free memory clock switching. + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_enable_display_gap(struct pp_hwmgr *hwmgr) { uint32_t display_gap = @@ -465,11 +465,11 @@ static int smu7_enable_display_gap(struct pp_hwmgr *hwmgr) } /** -* Programs activity state transition voting clients -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_program_voting_clients - Programs activity state transition voting clients + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_program_voting_clients(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -560,12 +560,12 @@ static int smu7_reset_to_default(struct pp_hwmgr *hwmgr) } /** -* Initial switch from ARB F0->F1 -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -* This function is to be called from the SetPowerState table. -*/ + * smu7_initial_switch_from_arbf0_to_f1 - Initial switch from ARB F0->F1 + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + * This function is to be called from the SetPowerState table. + */ static int smu7_initial_switch_from_arbf0_to_f1(struct pp_hwmgr *hwmgr) { return smu7_copy_and_switch_arb_sets(hwmgr, @@ -1917,11 +1917,11 @@ static int smu7_calculate_ro_range(struct pp_hwmgr *hwmgr) } /** -* Get Leakage VDDC based on leakage ID. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ + * smu7_get_evv_voltages - Get Leakage VDDC based on leakage ID. + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 + */ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -2017,11 +2017,11 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr) } /** - * Change virtual leakage voltage to actual value. + * smu7_patch_ppt_v1_with_vdd_leakage - Change virtual leakage voltage to actual value. * - * @param hwmgr the address of the powerplay hardware manager. - * @param pointer to changing voltage - * @param pointer to leakage table + * @hwmgr: the address of the powerplay hardware manager. + * @voltage: pointer to changing voltage + * @leakage_table: pointer to leakage table */ static void smu7_patch_ppt_v1_with_vdd_leakage(struct pp_hwmgr *hwmgr, uint16_t *voltage, struct smu7_leakage_voltage *leakage_table) @@ -2043,13 +2043,13 @@ static void smu7_patch_ppt_v1_with_vdd_leakage(struct pp_hwmgr *hwmgr, } /** -* Patch voltage lookup table by EVV leakages. -* -* @param hwmgr the address of the powerplay hardware manager. -* @param pointer to voltage lookup table -* @param pointer to leakage table -* @return always 0 -*/ + * smu7_patch_lookup_table_with_leakage - Patch voltage lookup table by EVV leakages. + * + * @hwmgr: the address of the powerplay hardware manager. + * @lookup_table: pointer to voltage lookup table + * @leakage_table: pointer to leakage table + * Return: always 0 + */ static int smu7_patch_lookup_table_with_leakage(struct pp_hwmgr *hwmgr, phm_ppt_v1_voltage_lookup_table *lookup_table, struct smu7_leakage_voltage *leakage_table) @@ -2500,11 +2500,11 @@ static int smu7_thermal_parameter_init(struct pp_hwmgr *hwmgr) } /** - * Change virtual leakage voltage to actual value. + * smu7_patch_ppt_v0_with_vdd_leakage - Change virtual leakage voltage to actual value. * - * @param hwmgr the address of the powerplay hardware manager. - * @param pointer to changing voltage - * @param pointer to leakage table + * @hwmgr: the address of the powerplay hardware manager. + * @voltage: pointer to changing voltage + * @leakage_table: pointer to leakage table */ static void smu7_patch_ppt_v0_with_vdd_leakage(struct pp_hwmgr *hwmgr, uint32_t *voltage, struct smu7_leakage_voltage *leakage_table) @@ -4440,11 +4440,11 @@ smu7_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr) } /** -* Programs the display gap -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always OK -*/ + * smu7_program_display_gap - Programs the display gap + * + * @hwmgr: the address of the powerplay hardware manager. + * Return: always OK + */ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -4498,12 +4498,12 @@ static int smu7_display_configuration_changed_task(struct pp_hwmgr *hwmgr) } /** -* Set maximum target operating fan output RPM -* -* @param hwmgr: the address of the powerplay hardware manager. -* @param usMaxFanRpm: max operating fan RPM value. -* @return The response that came from the SMC. -*/ + * smu7_set_max_fan_rpm_output - Set maximum target operating fan output RPM + * + * @hwmgr: the address of the powerplay hardware manager. + * @usMaxFanRpm: max operating fan RPM value. + * Return: The response that came from the SMC. + */ static int smu7_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_rpm) { hwmgr->thermal_controller. @@ -4698,10 +4698,10 @@ static int smu7_read_clock_registers(struct pp_hwmgr *hwmgr) } /** - * Find out if memory is GDDR5. + * smu7_get_memory_type - Find out if memory is GDDR5. * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_get_memory_type(struct pp_hwmgr *hwmgr) { @@ -4714,10 +4714,10 @@ static int smu7_get_memory_type(struct pp_hwmgr *hwmgr) } /** - * Enables Dynamic Power Management by SMC + * smu7_enable_acpi_power_management - Enables Dynamic Power Management by SMC * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_enable_acpi_power_management(struct pp_hwmgr *hwmgr) { @@ -4728,10 +4728,10 @@ static int smu7_enable_acpi_power_management(struct pp_hwmgr *hwmgr) } /** - * Initialize PowerGating States for different engines + * smu7_init_power_gate_state - Initialize PowerGating States for different engines * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 + * @hwmgr: the address of the powerplay hardware manager. + * Return: always 0 */ static int smu7_init_power_gate_state(struct pp_hwmgr *hwmgr) { diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c index e3d9d969d86a..0d38d4206848 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c @@ -103,11 +103,11 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) } /** -* Set Fan Speed Control to static mode, so that the user can decide what speed to use. -* @param hwmgr the address of the powerplay hardware manager. -* mode the fan control mode, 0 default, 1 by percent, 5, by RPM -* @exception Should always succeed. -*/ + * smu7_fan_ctrl_set_static_mode - Set Fan Speed Control to static mode, so that the user can decide what speed to use. + * @hwmgr: the address of the powerplay hardware manager. + * @mode: the fan control mode, 0 default, 1 by percent, 5, by RPM + * Exception: Should always succeed. + */ int smu7_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode) { if (hwmgr->fan_ctrl_is_in_default_mode) { @@ -130,8 +130,8 @@ int smu7_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode) /** * Reset Fan Speed Control to default mode. -* @param hwmgr the address of the powerplay hardware manager. -* @exception Should always succeed. +* @hwmgr: the address of the powerplay hardware manager. +* Exception: Should always succeed. */ int smu7_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr) { @@ -199,11 +199,11 @@ int smu7_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr) } /** -* Set Fan Speed in percent. -* @param hwmgr the address of the powerplay hardware manager. -* @param speed is the percentage value (0% - 100%) to be set. -* @exception Fails is the 100% setting appears to be 0. -*/ + * smu7_fan_ctrl_set_fan_speed_percent - Set Fan Speed in percent. + * @hwmgr: the address of the powerplay hardware manager. + * @speed: is the percentage value (0% - 100%) to be set. + * Exception: Fails is the 100% setting appears to be 0. + */ int smu7_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed) { @@ -237,9 +237,9 @@ int smu7_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, } /** -* Reset Fan Speed to default. -* @param hwmgr the address of the powerplay hardware manager. -* @exception Always succeeds. +* smu7_fan_ctrl_reset_fan_speed_to_default - Reset Fan Speed to default. +* @hwmgr: the address of the powerplay hardware manager. +* Exception: Always succeeds. */ int smu7_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr) { @@ -259,11 +259,11 @@ int smu7_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr) } /** -* Set Fan Speed in RPM. -* @param hwmgr the address of the powerplay hardware manager. -* @param speed is the percentage value (min - max) to be set. -* @exception Fails is the speed not lie between min and max. -*/ + * smu7_fan_ctrl_set_fan_speed_rpm - Set Fan Speed in RPM. + * @hwmgr: the address of the powerplay hardware manager. + * @speed: is the percentage value (min - max) to be set. + * Exception: Fails is the speed not lie between min and max. + */ int smu7_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) { uint32_t tach_period; @@ -291,10 +291,10 @@ int smu7_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) } /** -* Reads the remote temperature from the SIslands thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * smu7_thermal_get_temperature - Reads the remote temperature from the SIslands thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ int smu7_thermal_get_temperature(struct pp_hwmgr *hwmgr) { int temp; @@ -314,12 +314,13 @@ int smu7_thermal_get_temperature(struct pp_hwmgr *hwmgr) } /** -* Set the requested temperature range for high and low alert signals -* -* @param hwmgr The address of the hardware manager. -* @param range Temperature range to be programmed for high and low alert signals -* @exception PP_Result_BadInput if the input data is not valid. -*/ + * smu7_thermal_set_temperature_range - Set the requested temperature range for high and low alert signals + * + * @hwmgr: The address of the hardware manager. + * @low_temp: Temperature to be programmed for high alert signals + * @high_temp: Temperature to be programmed for low alert signals + * Exception: PP_Result_BadInput if the input data is not valid. + */ static int smu7_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, int low_temp, int high_temp) { @@ -350,10 +351,10 @@ static int smu7_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, } /** -* Programs thermal controller one-time setting registers -* -* @param hwmgr The address of the hardware manager. -*/ + * smu7_thermal_initialize - Programs thermal controller one-time setting registers + * + * @hwmgr: The address of the hardware manager. + */ static int smu7_thermal_initialize(struct pp_hwmgr *hwmgr) { if (hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) @@ -369,10 +370,10 @@ static int smu7_thermal_initialize(struct pp_hwmgr *hwmgr) } /** -* Enable thermal alerts on the RV770 thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * smu7_thermal_enable_alert - Enable thermal alerts on the RV770 thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ static void smu7_thermal_enable_alert(struct pp_hwmgr *hwmgr) { uint32_t alert; @@ -388,9 +389,9 @@ static void smu7_thermal_enable_alert(struct pp_hwmgr *hwmgr) } /** -* Disable thermal alerts on the RV770 thermal controller. -* @param hwmgr The address of the hardware manager. -*/ + * smu7_thermal_disable_alert - Disable thermal alerts on the RV770 thermal controller. + * @hwmgr: The address of the hardware manager. + */ int smu7_thermal_disable_alert(struct pp_hwmgr *hwmgr) { uint32_t alert; @@ -406,10 +407,10 @@ int smu7_thermal_disable_alert(struct pp_hwmgr *hwmgr) } /** -* Uninitialize the thermal controller. -* Currently just disables alerts. -* @param hwmgr The address of the hardware manager. -*/ + * smu7_thermal_stop_thermal_controller - Uninitialize the thermal controller. + * Currently just disables alerts. + * @hwmgr: The address of the hardware manager. + */ int smu7_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) { int result = smu7_thermal_disable_alert(hwmgr); @@ -421,14 +422,10 @@ int smu7_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) } /** -* Start the fan control on the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ + * smu7_thermal_start_smc_fan_control - Start the fan control on the SMC. + * @hwmgr: the address of the powerplay hardware manager. + * Return: result from set temperature range routine + */ static int smu7_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr) { /* If the fantable setup has failed we could have disabled diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c index 2a0ca5194bbe..bfe80ac0ad8c 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c @@ -103,7 +103,7 @@ uint32_t phm_set_field_to_u32(u32 offset, u32 original_data, u32 field, u32 size return original_data; } -/** +/* * Returns once the part of the register indicated by the mask has * reached the given value. */ @@ -132,7 +132,7 @@ int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index, } -/** +/* * Returns once the part of the register indicated by the mask has * reached the given value.The indirect space is described by giving * the memory-mapped index of the indirect index register. @@ -486,9 +486,9 @@ int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr, } /** - * Initialize Dynamic State Adjustment Rule Settings + * phm_initializa_dynamic_state_adjustment_rule_settings - Initialize Dynamic State Adjustment Rule Settings * - * @param hwmgr the address of the powerplay hardware manager. + * @hwmgr: the address of the powerplay hardware manager. */ int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr) { diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 7eada3098ffc..1b47f94e0331 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -3141,6 +3141,8 @@ static int vega10_get_pp_table_entry(struct pp_hwmgr *hwmgr, result = vega10_get_powerplay_table_entry(hwmgr, entry_index, state, vega10_get_pp_table_entry_callback_func); + if (result) + return result; /* * This is the earliest time we have all the dependency table diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c index 535404de78a2..95b988823f50 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c @@ -1145,7 +1145,7 @@ static int init_dpm_2_parameters( return result; } -int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr) +static int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr) { int result = 0; const ATOM_Vega10_POWERPLAYTABLE *powerplay_table; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c index 952cd3d7240e..9b46b27bd30c 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c @@ -118,12 +118,12 @@ int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) } /** -* Set Fan Speed Control to static mode, -* so that the user can decide what speed to use. -* @param hwmgr the address of the powerplay hardware manager. -* mode the fan control mode, 0 default, 1 by percent, 5, by RPM -* @exception Should always succeed. -*/ + * vega10_fan_ctrl_set_static_mode - Set Fan Speed Control to static mode, + * so that the user can decide what speed to use. + * @hwmgr: the address of the powerplay hardware manager. + * @mode: the fan control mode, 0 default, 1 by percent, 5, by RPM + * Exception: Should always succeed. + */ int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode) { struct amdgpu_device *adev = hwmgr->adev; @@ -149,10 +149,10 @@ int vega10_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode) } /** -* Reset Fan Speed Control to default mode. -* @param hwmgr the address of the powerplay hardware manager. -* @exception Should always succeed. -*/ + * vega10_fan_ctrl_set_default_mode - Reset Fan Speed Control to default mode. + * @hwmgr: the address of the powerplay hardware manager. + * Exception: Should always succeed. + */ int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -173,11 +173,10 @@ int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr) } /** - * @fn vega10_enable_fan_control_feature - * @brief Enables the SMC Fan Control Feature. + * vega10_enable_fan_control_feature - Enables the SMC Fan Control Feature. * - * @param hwmgr - the address of the powerplay hardware manager. - * @return 0 on success. -1 otherwise. + * @hwmgr: the address of the powerplay hardware manager. + * Return: 0 on success. -1 otherwise. */ static int vega10_enable_fan_control_feature(struct pp_hwmgr *hwmgr) { @@ -242,11 +241,11 @@ int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr) } /** -* Set Fan Speed in percent. -* @param hwmgr the address of the powerplay hardware manager. -* @param speed is the percentage value (0% - 100%) to be set. -* @exception Fails is the 100% setting appears to be 0. -*/ + * vega10_fan_ctrl_set_fan_speed_percent - Set Fan Speed in percent. + * @hwmgr: the address of the powerplay hardware manager. + * @speed: is the percentage value (0% - 100%) to be set. + * Exception: Fails is the 100% setting appears to be 0. + */ int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed) { @@ -282,10 +281,10 @@ int vega10_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, } /** -* Reset Fan Speed to default. -* @param hwmgr the address of the powerplay hardware manager. -* @exception Always succeeds. -*/ + * vega10_fan_ctrl_reset_fan_speed_to_default - Reset Fan Speed to default. + * @hwmgr: the address of the powerplay hardware manager. + * Exception: Always succeeds. + */ int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr) { if (hwmgr->thermal_controller.fanInfo.bNoFan) @@ -298,11 +297,11 @@ int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr) } /** -* Set Fan Speed in RPM. -* @param hwmgr the address of the powerplay hardware manager. -* @param speed is the percentage value (min - max) to be set. -* @exception Fails is the speed not lie between min and max. -*/ + * vega10_fan_ctrl_set_fan_speed_rpm - Set Fan Speed in RPM. + * @hwmgr: the address of the powerplay hardware manager. + * @speed: is the percentage value (min - max) to be set. + * Exception: Fails is the speed not lie between min and max. + */ int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) { struct amdgpu_device *adev = hwmgr->adev; @@ -331,10 +330,10 @@ int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) } /** -* Reads the remote temperature from the SIslands thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * vega10_thermal_get_temperature - Reads the remote temperature from the SIslands thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -353,13 +352,13 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr) } /** -* Set the requested temperature range for high and low alert signals -* -* @param hwmgr The address of the hardware manager. -* @param range Temperature range to be programmed for -* high and low alert signals -* @exception PP_Result_BadInput if the input data is not valid. -*/ + * vega10_thermal_set_temperature_range - Set the requested temperature range for high and low alert signals + * + * @hwmgr: The address of the hardware manager. + * @range: Temperature range to be programmed for + * high and low alert signals + * Exception: PP_Result_BadInput if the input data is not valid. + */ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { @@ -406,10 +405,10 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, } /** -* Programs thermal controller one-time setting registers -* -* @param hwmgr The address of the hardware manager. -*/ + * vega10_thermal_initialize - Programs thermal controller one-time setting registers + * + * @hwmgr: The address of the hardware manager. + */ static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -429,10 +428,10 @@ static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr) } /** -* Enable thermal alerts on the RV770 thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * vega10_thermal_enable_alert - Enable thermal alerts on the RV770 thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -461,9 +460,9 @@ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr) } /** -* Disable thermal alerts on the RV770 thermal controller. -* @param hwmgr The address of the hardware manager. -*/ + * vega10_thermal_disable_alert - Disable thermal alerts on the RV770 thermal controller. + * @hwmgr: The address of the hardware manager. + */ int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -488,10 +487,10 @@ int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr) } /** -* Uninitialize the thermal controller. -* Currently just disables alerts. -* @param hwmgr The address of the hardware manager. -*/ + * vega10_thermal_stop_thermal_controller - Uninitialize the thermal controller. + * Currently just disables alerts. + * @hwmgr: The address of the hardware manager. + */ int vega10_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) { int result = vega10_thermal_disable_alert(hwmgr); @@ -503,14 +502,10 @@ int vega10_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) } /** -* Set up the fan table to control the fan using the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ + * vega10_thermal_setup_fan_table - Set up the fan table to control the fan using the SMC. + * @hwmgr: the address of the powerplay hardware manager. + * Return: result from set temperature range routine + */ static int vega10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) { int ret; @@ -606,14 +601,10 @@ int vega10_enable_mgpu_fan_boost(struct pp_hwmgr *hwmgr) } /** -* Start the fan control on the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ + * vega10_thermal_start_smc_fan_control - Start the fan control on the SMC. + * @hwmgr: the address of the powerplay hardware manager. + * Return: result from set temperature range routine + */ static int vega10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr) { /* If the fantable setup has failed we could have disabled diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c index 740e2fc7a034..1e79baab753e 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c @@ -252,12 +252,11 @@ static int init_powerplay_table_information( phm_copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_max, powerplay_table->PowerSavingClockMax, ATOM_VEGA12_PPCLOCK_COUNT); phm_copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_min, powerplay_table->PowerSavingClockMin, ATOM_VEGA12_PPCLOCK_COUNT); - pptable_information->smc_pptable = kmalloc(sizeof(PPTable_t), GFP_KERNEL); + pptable_information->smc_pptable = kmemdup(&(powerplay_table->smcPPTable), + sizeof(PPTable_t), GFP_KERNEL); if (pptable_information->smc_pptable == NULL) return -ENOMEM; - memcpy(pptable_information->smc_pptable, &(powerplay_table->smcPPTable), sizeof(PPTable_t)); - result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable)); return result; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c index 7ace439dcde7..0dc16f25a463 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c @@ -60,11 +60,10 @@ int vega12_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) } /** - * @fn vega12_enable_fan_control_feature - * @brief Enables the SMC Fan Control Feature. + * vega12_enable_fan_control_feature -Enables the SMC Fan Control Feature. * - * @param hwmgr - the address of the powerplay hardware manager. - * @return 0 on success. -1 otherwise. + * @hwmgr: the address of the powerplay hardware manager. + * Return: 0 on success. -1 otherwise. */ static int vega12_enable_fan_control_feature(struct pp_hwmgr *hwmgr) { @@ -129,20 +128,20 @@ int vega12_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr) } /** -* Reset Fan Speed to default. -* @param hwmgr the address of the powerplay hardware manager. -* @exception Always succeeds. -*/ + * vega12_fan_ctrl_reset_fan_speed_to_default - Reset Fan Speed to default. + * @hwmgr: the address of the powerplay hardware manager. + * Exception Always succeeds. + */ int vega12_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr) { return vega12_fan_ctrl_start_smc_fan_control(hwmgr); } /** -* Reads the remote temperature from the SIslands thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * vega12_thermal_get_temperature - Reads the remote temperature from the SIslands thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -160,13 +159,13 @@ int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr) } /** -* Set the requested temperature range for high and low alert signals -* -* @param hwmgr The address of the hardware manager. -* @param range Temperature range to be programmed for -* high and low alert signals -* @exception PP_Result_BadInput if the input data is not valid. -*/ + * Set the requested temperature range for high and low alert signals + * + * @hwmgr: The address of the hardware manager. + * @range: Temperature range to be programmed for + * high and low alert signals + * Exception: PP_Result_BadInput if the input data is not valid. + */ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { @@ -200,10 +199,10 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, } /** -* Enable thermal alerts on the RV770 thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * vega12_thermal_enable_alert - Enable thermal alerts on the RV770 thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ static int vega12_thermal_enable_alert(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -219,9 +218,9 @@ static int vega12_thermal_enable_alert(struct pp_hwmgr *hwmgr) } /** -* Disable thermal alerts on the RV770 thermal controller. -* @param hwmgr The address of the hardware manager. -*/ + * vega12_thermal_disable_alert - Disable thermal alerts on the RV770 thermal controller. + * @hwmgr: The address of the hardware manager. + */ int vega12_thermal_disable_alert(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -232,10 +231,10 @@ int vega12_thermal_disable_alert(struct pp_hwmgr *hwmgr) } /** -* Uninitialize the thermal controller. -* Currently just disables alerts. -* @param hwmgr The address of the hardware manager. -*/ + * vega12_thermal_stop_thermal_controller - Uninitialize the thermal controller. + * Currently just disables alerts. + * @hwmgr: The address of the hardware manager. + */ int vega12_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) { int result = vega12_thermal_disable_alert(hwmgr); @@ -244,14 +243,9 @@ int vega12_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) } /** -* Set up the fan table to control the fan using the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ + * vega12_thermal_setup_fan_table - Set up the fan table to control the fan using the SMC. + * @hwmgr: the address of the powerplay hardware manager. + */ static int vega12_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) { int ret; @@ -267,14 +261,10 @@ static int vega12_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) } /** -* Start the fan control on the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ + * vega12_thermal_start_smc_fan_control - Start the fan control on the SMC. + * @hwmgr: the address of the powerplay hardware manager. + * Return: result from set temperature range routine + */ static int vega12_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr) { /* If the fantable setup has failed we could have disabled diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c index 364162ddaa9c..269dd7e95a44 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c @@ -209,10 +209,10 @@ int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) } /** -* Reads the remote temperature from the SIslands thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * vega20_thermal_get_temperature - Reads the remote temperature from the SIslands thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -230,13 +230,12 @@ int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr) } /** -* Set the requested temperature range for high and low alert signals -* -* @param hwmgr The address of the hardware manager. -* @param range Temperature range to be programmed for -* high and low alert signals -* @exception PP_Result_BadInput if the input data is not valid. -*/ + * vega20_thermal_set_temperature_range - Set the requested temperature range for high and low alert signals + * + * @hwmgr: The address of the hardware manager. + * @range: Temperature range to be programmed for high and low alert signals + * Exception: PP_Result_BadInput if the input data is not valid. + */ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { @@ -270,10 +269,10 @@ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, } /** -* Enable thermal alerts on the RV770 thermal controller. -* -* @param hwmgr The address of the hardware manager. -*/ + * vega20_thermal_enable_alert - Enable thermal alerts on the RV770 thermal controller. + * + * @hwmgr: The address of the hardware manager. + */ static int vega20_thermal_enable_alert(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -289,9 +288,9 @@ static int vega20_thermal_enable_alert(struct pp_hwmgr *hwmgr) } /** -* Disable thermal alerts on the RV770 thermal controller. -* @param hwmgr The address of the hardware manager. -*/ + * vega20_thermal_disable_alert - Disable thermal alerts on the RV770 thermal controller. + * @hwmgr: The address of the hardware manager. + */ int vega20_thermal_disable_alert(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; @@ -302,10 +301,10 @@ int vega20_thermal_disable_alert(struct pp_hwmgr *hwmgr) } /** -* Uninitialize the thermal controller. -* Currently just disables alerts. -* @param hwmgr The address of the hardware manager. -*/ + * vega20_thermal_stop_thermal_controller - Uninitialize the thermal controller. + * Currently just disables alerts. + * @hwmgr: The address of the hardware manager. + */ int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) { int result = vega20_thermal_disable_alert(hwmgr); @@ -314,14 +313,9 @@ int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr) } /** -* Set up the fan table to control the fan using the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ + * vega20_thermal_setup_fan_table - Set up the fan table to control the fan using the SMC. + * @hwmgr: the address of the powerplay hardware manager. + */ static int vega20_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) { int ret; diff --git a/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c b/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c index 4b3faaccecb9..66daabebee35 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c +++ b/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c @@ -1675,14 +1675,13 @@ static void kv_dpm_powergate_uvd(void *handle, bool gate) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct kv_power_info *pi = kv_get_pi(adev); - int ret; pi->uvd_power_gated = gate; if (gate) { /* stop the UVD block */ - ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD, - AMD_PG_STATE_GATE); + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD, + AMD_PG_STATE_GATE); kv_update_uvd_dpm(adev, gate); if (pi->caps_uvd_pg) /* power off the UVD block */ @@ -1694,8 +1693,8 @@ static void kv_dpm_powergate_uvd(void *handle, bool gate) /* re-init the UVD block */ kv_update_uvd_dpm(adev, gate); - ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD, - AMD_PG_STATE_UNGATE); + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD, + AMD_PG_STATE_UNGATE); } } @@ -1703,14 +1702,13 @@ static void kv_dpm_powergate_vce(void *handle, bool gate) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct kv_power_info *pi = kv_get_pi(adev); - int ret; pi->vce_power_gated = gate; if (gate) { /* stop the VCE block */ - ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, - AMD_PG_STATE_GATE); + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_GATE); kv_enable_vce_dpm(adev, false); if (pi->caps_vce_pg) /* power off the VCE block */ amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF); @@ -1719,8 +1717,8 @@ static void kv_dpm_powergate_vce(void *handle, bool gate) amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); kv_enable_vce_dpm(adev, true); /* re-init the VCE block */ - ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, - AMD_PG_STATE_UNGATE); + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_UNGATE); } } diff --git a/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c b/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c index b5986d19dc08..afa1711c9620 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c @@ -6200,8 +6200,8 @@ static void si_request_link_speed_change_before_state_change(struct amdgpu_devic case AMDGPU_PCIE_GEN2: if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN2, false) == 0) break; + fallthrough; #endif - /* fall through */ default: si_pi->force_pcie_gen = si_get_current_pcie_speed(adev); break; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c index 329bf4d44bbc..93a1c7248e26 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c @@ -2193,7 +2193,7 @@ static int ci_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) res = ci_copy_bytes_to_smc(hwmgr, ci_data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), SMC_RAM_END); - return 0; + return res; } static int ci_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c index fef9d3906fcc..02c094a06605 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c @@ -1090,7 +1090,7 @@ static int fiji_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) } -/** +/* * MCLK Frequency Ratio * SEQ_CG_RESP Bit[31:24] - 0x0 * Bit[27:24] \96 DDR3 Frequency ratio @@ -1600,20 +1600,19 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, static int fiji_populate_smc_boot_level(struct pp_hwmgr *hwmgr, struct SMU73_Discrete_DpmTable *table) { - int result = 0; struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); table->GraphicsBootLevel = 0; table->MemoryBootLevel = 0; /* find boot level from dpm table */ - result = phm_find_boot_level(&(data->dpm_table.sclk_table), - data->vbios_boot_state.sclk_bootup_value, - (uint32_t *)&(table->GraphicsBootLevel)); + phm_find_boot_level(&(data->dpm_table.sclk_table), + data->vbios_boot_state.sclk_bootup_value, + (uint32_t *)&(table->GraphicsBootLevel)); - result = phm_find_boot_level(&(data->dpm_table.mclk_table), - data->vbios_boot_state.mclk_bootup_value, - (uint32_t *)&(table->MemoryBootLevel)); + phm_find_boot_level(&(data->dpm_table.mclk_table), + data->vbios_boot_state.mclk_bootup_value, + (uint32_t *)&(table->MemoryBootLevel)); table->BootVddc = data->vbios_boot_state.vddc_bootup_value * VOLTAGE_SCALE; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c index 431ad2fd38df..03df35dee8ba 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c @@ -2082,7 +2082,7 @@ static int iceland_init_smc_table(struct pp_hwmgr *hwmgr) return 0; } -int iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) +static int iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) { struct smu7_smumgr *smu7_data = (struct smu7_smumgr *)(hwmgr->smu_backend); SMU71_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; @@ -2156,7 +2156,7 @@ int iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) res = smu7_copy_bytes_to_smc(hwmgr, smu7_data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), SMC_RAM_END); - return 0; + return res; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c index d4253b1116c2..45214a364baa 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c @@ -2142,7 +2142,7 @@ static int polaris10_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) return 0; } -int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr) +static int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -2372,6 +2372,7 @@ static int polaris10_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) break; case SMU_BIF_TABLE: polaris10_update_bif_smc_table(hwmgr); + break; default: break; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c index ea2279bb8cbf..47b34c6ca924 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c @@ -139,8 +139,7 @@ static int smu10_copy_table_from_smc(struct pp_hwmgr *hwmgr, priv->smu_tables.entry[table_id].table_id, NULL); - /* flush hdp cache */ - amdgpu_asic_flush_hdp(adev, NULL); + amdgpu_asic_invalidate_hdp(adev, NULL); memcpy(table, (uint8_t *)priv->smu_tables.entry[table_id].table, priv->smu_tables.entry[table_id].size); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu9_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu9_smumgr.c index 8a9aee85043e..23e5de3c4ec1 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu9_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu9_smumgr.c @@ -22,6 +22,7 @@ */ #include "smumgr.h" +#include "smu9_smumgr.h" #include "vega10_inc.h" #include "soc15_common.h" #include "pp_debug.h" diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c index 4bfadb49521b..04b561f5d932 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c @@ -2545,7 +2545,7 @@ static int tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) (uint32_t)sizeof(fan_table), SMC_RAM_END); - return 0; + return res; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c index daf122f24f23..a70d73896649 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c @@ -60,8 +60,7 @@ static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr, priv->smu_tables.entry[table_id].table_id, NULL); - /* flush hdp cache */ - amdgpu_asic_flush_hdp(adev, NULL); + amdgpu_asic_invalidate_hdp(adev, NULL); memcpy(table, priv->smu_tables.entry[table_id].table, priv->smu_tables.entry[table_id].size); @@ -209,13 +208,11 @@ static int vega10_smu_init(struct pp_hwmgr *hwmgr) int ret; struct cgs_firmware_info info = {0}; - if (!amdgpu_sriov_vf((struct amdgpu_device *)hwmgr->adev)) { - ret = cgs_get_firmware_info(hwmgr->device, - CGS_UCODE_ID_SMU, - &info); - if (ret || !info.kptr) - return -EINVAL; - } + ret = cgs_get_firmware_info(hwmgr->device, + CGS_UCODE_ID_SMU, + &info); + if (ret || !info.kptr) + return -EINVAL; priv = kzalloc(sizeof(struct vega10_smumgr), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c index f54df76537e4..b52ce135d84d 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c @@ -68,8 +68,7 @@ static int vega12_copy_table_from_smc(struct pp_hwmgr *hwmgr, "[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!", return -EINVAL); - /* flush hdp cache */ - amdgpu_asic_flush_hdp(adev, NULL); + amdgpu_asic_invalidate_hdp(adev, NULL); memcpy(table, priv->smu_tables.entry[table_id].table, priv->smu_tables.entry[table_id].size); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c index cf43629d29d2..741fbc87467f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c @@ -192,8 +192,7 @@ static int vega20_copy_table_from_smc(struct pp_hwmgr *hwmgr, "[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!", return ret); - /* flush hdp cache */ - amdgpu_asic_flush_hdp(adev, NULL); + amdgpu_asic_invalidate_hdp(adev, NULL); memcpy(table, priv->smu_tables.entry[table_id].table, priv->smu_tables.entry[table_id].size); @@ -307,8 +306,7 @@ int vega20_get_activity_monitor_coeff(struct pp_hwmgr *hwmgr, "[GetActivityMonitor] Attempt to Transfer Table From SMU Failed!", return ret); - /* flush hdp cache */ - amdgpu_asic_flush_hdp(adev, NULL); + amdgpu_asic_invalidate_hdp(adev, NULL); memcpy(table, priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].table, priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].size); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c index 38a5cdcf5896..7d024d3facef 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c @@ -2246,7 +2246,7 @@ static int vegam_update_sclk_threshold(struct pp_hwmgr *hwmgr) return result; } -int vegam_thermal_avfs_enable(struct pp_hwmgr *hwmgr) +static int vegam_thermal_avfs_enable(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); int ret; diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 39990790ed67..cf999b7a2164 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -405,6 +405,8 @@ static int smu_set_funcs(struct amdgpu_device *adev) break; case CHIP_VANGOGH: vangogh_set_ppt_funcs(smu); + /* enable the OD by default to allow the fine grain tuning function */ + smu->od_enabled = true; break; default: return -EINVAL; @@ -474,6 +476,8 @@ static int smu_late_init(void *handle) struct smu_context *smu = &adev->smu; int ret = 0; + smu_set_fine_grain_gfx_freq_parameters(smu); + if (adev->asic_type == CHIP_VANGOGH) return 0; @@ -843,7 +847,7 @@ static int smu_sw_init(void *handle) smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; smu->smu_dpm.requested_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; - if (!amdgpu_sriov_vf(adev)) { + if (!amdgpu_sriov_vf(adev) || (adev->asic_type != CHIP_NAVI12)) { ret = smu_init_microcode(smu); if (ret) { dev_err(adev->dev, "Failed to load smu firmware!\n"); @@ -914,11 +918,15 @@ static int smu_smc_hw_setup(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; uint32_t pcie_gen = 0, pcie_width = 0; - int ret; + int ret = 0; if (adev->in_suspend && smu_is_dpm_running(smu)) { dev_info(adev->dev, "dpm has been enabled\n"); - return 0; + /* this is needed specifically */ + if ((adev->asic_type >= CHIP_SIENNA_CICHLID) && + (adev->asic_type <= CHIP_DIMGREY_CAVEFISH)) + ret = smu_system_features_control(smu, true); + return ret; } ret = smu_init_display_count(smu, 0); @@ -1179,7 +1187,7 @@ static int smu_disable_dpms(struct smu_context *smu) */ if (smu->uploading_custom_pp_table && (adev->asic_type >= CHIP_NAVI10) && - (adev->asic_type <= CHIP_NAVY_FLOUNDER)) + (adev->asic_type <= CHIP_DIMGREY_CAVEFISH)) return 0; /* @@ -2529,3 +2537,15 @@ int smu_enable_mgpu_fan_boost(struct smu_context *smu) return ret; } + +int smu_gfx_state_change_set(struct smu_context *smu, uint32_t state) +{ + int ret = 0; + + mutex_lock(&smu->mutex); + if (smu->ppt_funcs->gfx_state_change_set) + ret = smu->ppt_funcs->gfx_state_change_set(smu, state); + mutex_unlock(&smu->mutex); + + return ret; +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 4fd850e58004..cd7b411457ff 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1000,77 +1000,6 @@ static int arcturus_get_thermal_temperature_range(struct smu_context *smu, return 0; } -static int arcturus_get_current_activity_percent(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = arcturus_get_smu_metrics_data(smu, - METRICS_AVERAGE_GFXACTIVITY, - value); - break; - case AMDGPU_PP_SENSOR_MEM_LOAD: - ret = arcturus_get_smu_metrics_data(smu, - METRICS_AVERAGE_MEMACTIVITY, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n"); - return -EINVAL; - } - - return ret; -} - -static int arcturus_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return arcturus_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, - value); -} - -static int arcturus_thermal_get_temperature(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: - ret = arcturus_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_HOTSPOT, - value); - break; - case AMDGPU_PP_SENSOR_EDGE_TEMP: - ret = arcturus_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_EDGE, - value); - break; - case AMDGPU_PP_SENSOR_MEM_TEMP: - ret = arcturus_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_MEM, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n"); - return -EINVAL; - } - - return ret; -} - static int arcturus_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, void *data, uint32_t *size) @@ -1092,21 +1021,39 @@ static int arcturus_read_sensor(struct smu_context *smu, *size = 4; break; case AMDGPU_PP_SENSOR_MEM_LOAD: + ret = arcturus_get_smu_metrics_data(smu, + METRICS_AVERAGE_MEMACTIVITY, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = arcturus_get_current_activity_percent(smu, - sensor, - (uint32_t *)data); + ret = arcturus_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXACTIVITY, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GPU_POWER: - ret = arcturus_get_gpu_power(smu, (uint32_t *)data); + ret = arcturus_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: + ret = arcturus_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_HOTSPOT, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: + ret = arcturus_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_EDGE, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_MEM_TEMP: - ret = arcturus_thermal_get_temperature(smu, sensor, - (uint32_t *)data); + ret = arcturus_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_MEM, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GFX_MCLK: diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index ef1a62e86a0e..51e83123f72a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -1302,44 +1302,6 @@ static int navi10_display_config_changed(struct smu_context *smu) return ret; } -static int navi10_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return navi10_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, - value); -} - -static int navi10_get_current_activity_percent(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = navi10_get_smu_metrics_data(smu, - METRICS_AVERAGE_GFXACTIVITY, - value); - break; - case AMDGPU_PP_SENSOR_MEM_LOAD: - ret = navi10_get_smu_metrics_data(smu, - METRICS_AVERAGE_MEMACTIVITY, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n"); - return -EINVAL; - } - - return ret; -} - static bool navi10_is_dpm_running(struct smu_context *smu) { int ret = 0; @@ -1652,39 +1614,6 @@ static int navi10_set_watermarks_table(struct smu_context *smu, return 0; } -static int navi10_thermal_get_temperature(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: - ret = navi10_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_HOTSPOT, - value); - break; - case AMDGPU_PP_SENSOR_EDGE_TEMP: - ret = navi10_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_EDGE, - value); - break; - case AMDGPU_PP_SENSOR_MEM_TEMP: - ret = navi10_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_MEM, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n"); - return -EINVAL; - } - - return ret; -} - static int navi10_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, void *data, uint32_t *size) @@ -1703,18 +1632,39 @@ static int navi10_read_sensor(struct smu_context *smu, *size = 4; break; case AMDGPU_PP_SENSOR_MEM_LOAD: + ret = navi10_get_smu_metrics_data(smu, + METRICS_AVERAGE_MEMACTIVITY, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = navi10_get_current_activity_percent(smu, sensor, (uint32_t *)data); + ret = navi10_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXACTIVITY, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GPU_POWER: - ret = navi10_get_gpu_power(smu, (uint32_t *)data); + ret = navi10_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: + ret = navi10_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_HOTSPOT, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: + ret = navi10_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_EDGE, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_MEM_TEMP: - ret = navi10_thermal_get_temperature(smu, sensor, (uint32_t *)data); + ret = navi10_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_MEM, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GFX_MCLK: @@ -2325,210 +2275,6 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) return 0; } -static void navi10_fill_i2c_req(SwI2cRequest_t *req, bool write, - uint8_t address, uint32_t numbytes, - uint8_t *data) -{ - int i; - - req->I2CcontrollerPort = 0; - req->I2CSpeed = 2; - req->SlaveAddress = address; - req->NumCmds = numbytes; - - for (i = 0; i < numbytes; i++) { - SwI2cCmd_t *cmd = &req->SwI2cCmds[i]; - - /* First 2 bytes are always write for lower 2b EEPROM address */ - if (i < 2) - cmd->Cmd = 1; - else - cmd->Cmd = write; - - - /* Add RESTART for read after address filled */ - cmd->CmdConfig |= (i == 2 && !write) ? CMDCONFIG_RESTART_MASK : 0; - - /* Add STOP in the end */ - cmd->CmdConfig |= (i == (numbytes - 1)) ? CMDCONFIG_STOP_MASK : 0; - - /* Fill with data regardless if read or write to simplify code */ - cmd->RegisterAddr = data[i]; - } -} - -static int navi10_i2c_read_data(struct i2c_adapter *control, - uint8_t address, - uint8_t *data, - uint32_t numbytes) -{ - uint32_t i, ret = 0; - SwI2cRequest_t req; - struct amdgpu_device *adev = to_amdgpu_device(control); - struct smu_table_context *smu_table = &adev->smu.smu_table; - struct smu_table *table = &smu_table->driver_table; - - if (numbytes > MAX_SW_I2C_COMMANDS) { - dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n", - numbytes, MAX_SW_I2C_COMMANDS); - return -EINVAL; - } - - memset(&req, 0, sizeof(req)); - navi10_fill_i2c_req(&req, false, address, numbytes, data); - - mutex_lock(&adev->smu.mutex); - /* Now read data starting with that address */ - ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, - true); - mutex_unlock(&adev->smu.mutex); - - if (!ret) { - SwI2cRequest_t *res = (SwI2cRequest_t *)table->cpu_addr; - - /* Assume SMU fills res.SwI2cCmds[i].Data with read bytes */ - for (i = 0; i < numbytes; i++) - data[i] = res->SwI2cCmds[i].Data; - - dev_dbg(adev->dev, "navi10_i2c_read_data, address = %x, bytes = %d, data :", - (uint16_t)address, numbytes); - - print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, - 8, 1, data, numbytes, false); - } else - dev_err(adev->dev, "navi10_i2c_read_data - error occurred :%x", ret); - - return ret; -} - -static int navi10_i2c_write_data(struct i2c_adapter *control, - uint8_t address, - uint8_t *data, - uint32_t numbytes) -{ - uint32_t ret; - SwI2cRequest_t req; - struct amdgpu_device *adev = to_amdgpu_device(control); - - if (numbytes > MAX_SW_I2C_COMMANDS) { - dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n", - numbytes, MAX_SW_I2C_COMMANDS); - return -EINVAL; - } - - memset(&req, 0, sizeof(req)); - navi10_fill_i2c_req(&req, true, address, numbytes, data); - - mutex_lock(&adev->smu.mutex); - ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, true); - mutex_unlock(&adev->smu.mutex); - - if (!ret) { - dev_dbg(adev->dev, "navi10_i2c_write(), address = %x, bytes = %d , data: ", - (uint16_t)address, numbytes); - - print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, - 8, 1, data, numbytes, false); - /* - * According to EEPROM spec there is a MAX of 10 ms required for - * EEPROM to flush internal RX buffer after STOP was issued at the - * end of write transaction. During this time the EEPROM will not be - * responsive to any more commands - so wait a bit more. - */ - msleep(10); - - } else - dev_err(adev->dev, "navi10_i2c_write- error occurred :%x", ret); - - return ret; -} - -static int navi10_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - uint32_t i, j, ret, data_size, data_chunk_size, next_eeprom_addr = 0; - uint8_t *data_ptr, data_chunk[MAX_SW_I2C_COMMANDS] = { 0 }; - - for (i = 0; i < num; i++) { - /* - * SMU interface allows at most MAX_SW_I2C_COMMANDS bytes of data at - * once and hence the data needs to be spliced into chunks and sent each - * chunk separately - */ - data_size = msgs[i].len - 2; - data_chunk_size = MAX_SW_I2C_COMMANDS - 2; - next_eeprom_addr = (msgs[i].buf[0] << 8 & 0xff00) | (msgs[i].buf[1] & 0xff); - data_ptr = msgs[i].buf + 2; - - for (j = 0; j < data_size / data_chunk_size; j++) { - /* Insert the EEPROM dest addess, bits 0-15 */ - data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff); - data_chunk[1] = (next_eeprom_addr & 0xff); - - if (msgs[i].flags & I2C_M_RD) { - ret = navi10_i2c_read_data(i2c_adap, - (uint8_t)msgs[i].addr, - data_chunk, MAX_SW_I2C_COMMANDS); - - memcpy(data_ptr, data_chunk + 2, data_chunk_size); - } else { - - memcpy(data_chunk + 2, data_ptr, data_chunk_size); - - ret = navi10_i2c_write_data(i2c_adap, - (uint8_t)msgs[i].addr, - data_chunk, MAX_SW_I2C_COMMANDS); - } - - if (ret) { - num = -EIO; - goto fail; - } - - next_eeprom_addr += data_chunk_size; - data_ptr += data_chunk_size; - } - - if (data_size % data_chunk_size) { - data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff); - data_chunk[1] = (next_eeprom_addr & 0xff); - - if (msgs[i].flags & I2C_M_RD) { - ret = navi10_i2c_read_data(i2c_adap, - (uint8_t)msgs[i].addr, - data_chunk, (data_size % data_chunk_size) + 2); - - memcpy(data_ptr, data_chunk + 2, data_size % data_chunk_size); - } else { - memcpy(data_chunk + 2, data_ptr, data_size % data_chunk_size); - - ret = navi10_i2c_write_data(i2c_adap, - (uint8_t)msgs[i].addr, - data_chunk, (data_size % data_chunk_size) + 2); - } - - if (ret) { - num = -EIO; - goto fail; - } - } - } - -fail: - return num; -} - -static u32 navi10_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - - -static const struct i2c_algorithm navi10_i2c_algo = { - .master_xfer = navi10_i2c_xfer, - .functionality = navi10_i2c_func, -}; - static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, void **table) { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 0600befc6e4c..db0f2a476c23 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -1119,44 +1119,6 @@ static int sienna_cichlid_display_config_changed(struct smu_context *smu) return ret; } -static int sienna_cichlid_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return sienna_cichlid_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, - value); -} - -static int sienna_cichlid_get_current_activity_percent(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = sienna_cichlid_get_smu_metrics_data(smu, - METRICS_AVERAGE_GFXACTIVITY, - value); - break; - case AMDGPU_PP_SENSOR_MEM_LOAD: - ret = sienna_cichlid_get_smu_metrics_data(smu, - METRICS_AVERAGE_MEMACTIVITY, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n"); - return -EINVAL; - } - - return ret; -} - static bool sienna_cichlid_is_dpm_running(struct smu_context *smu) { int ret = 0; @@ -1468,39 +1430,6 @@ static int sienna_cichlid_set_watermarks_table(struct smu_context *smu, return 0; } -static int sienna_cichlid_thermal_get_temperature(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: - ret = sienna_cichlid_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_HOTSPOT, - value); - break; - case AMDGPU_PP_SENSOR_EDGE_TEMP: - ret = sienna_cichlid_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_EDGE, - value); - break; - case AMDGPU_PP_SENSOR_MEM_TEMP: - ret = sienna_cichlid_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_MEM, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n"); - return -EINVAL; - } - - return ret; -} - static int sienna_cichlid_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, void *data, uint32_t *size) @@ -1519,18 +1448,39 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, *size = 4; break; case AMDGPU_PP_SENSOR_MEM_LOAD: + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_AVERAGE_MEMACTIVITY, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = sienna_cichlid_get_current_activity_percent(smu, sensor, (uint32_t *)data); + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXACTIVITY, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GPU_POWER: - ret = sienna_cichlid_get_gpu_power(smu, (uint32_t *)data); + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_HOTSPOT, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_EDGE, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_MEM_TEMP: - ret = sienna_cichlid_thermal_get_temperature(smu, sensor, (uint32_t *)data); + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_MEM, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GFX_MCLK: @@ -1805,11 +1755,6 @@ static void sienna_cichlid_dump_pptable(struct smu_context *smu) dev_info(smu->adev->dev, "SmnclkDpmFreq[%d] = 0x%x\n", i, pptable->SmnclkDpmFreq[i]); dev_info(smu->adev->dev, "SmnclkDpmVoltage[%d] = 0x%x\n", i, pptable->SmnclkDpmVoltage[i]); } - dev_info(smu->adev->dev, "PaddingAPCC[0] = 0x%x\n", pptable->PaddingAPCC[0]); - dev_info(smu->adev->dev, "PaddingAPCC[1] = 0x%x\n", pptable->PaddingAPCC[1]); - dev_info(smu->adev->dev, "PaddingAPCC[2] = 0x%x\n", pptable->PaddingAPCC[2]); - dev_info(smu->adev->dev, "PaddingAPCC[3] = 0x%x\n", pptable->PaddingAPCC[3]); - dev_info(smu->adev->dev, "ThrottlerControlMask = 0x%x\n", pptable->ThrottlerControlMask); dev_info(smu->adev->dev, "FwDStateMask = 0x%x\n", pptable->FwDStateMask); @@ -2036,23 +1981,6 @@ static void sienna_cichlid_dump_pptable(struct smu_context *smu) for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) dev_info(smu->adev->dev, " .[%02d] = 0x%x\n", i, pptable->FreqTableFclk[i]); - dev_info(smu->adev->dev, "Paddingclks[0] = 0x%x\n", pptable->Paddingclks[0]); - dev_info(smu->adev->dev, "Paddingclks[1] = 0x%x\n", pptable->Paddingclks[1]); - dev_info(smu->adev->dev, "Paddingclks[2] = 0x%x\n", pptable->Paddingclks[2]); - dev_info(smu->adev->dev, "Paddingclks[3] = 0x%x\n", pptable->Paddingclks[3]); - dev_info(smu->adev->dev, "Paddingclks[4] = 0x%x\n", pptable->Paddingclks[4]); - dev_info(smu->adev->dev, "Paddingclks[5] = 0x%x\n", pptable->Paddingclks[5]); - dev_info(smu->adev->dev, "Paddingclks[6] = 0x%x\n", pptable->Paddingclks[6]); - dev_info(smu->adev->dev, "Paddingclks[7] = 0x%x\n", pptable->Paddingclks[7]); - dev_info(smu->adev->dev, "Paddingclks[8] = 0x%x\n", pptable->Paddingclks[8]); - dev_info(smu->adev->dev, "Paddingclks[9] = 0x%x\n", pptable->Paddingclks[9]); - dev_info(smu->adev->dev, "Paddingclks[10] = 0x%x\n", pptable->Paddingclks[10]); - dev_info(smu->adev->dev, "Paddingclks[11] = 0x%x\n", pptable->Paddingclks[11]); - dev_info(smu->adev->dev, "Paddingclks[12] = 0x%x\n", pptable->Paddingclks[12]); - dev_info(smu->adev->dev, "Paddingclks[13] = 0x%x\n", pptable->Paddingclks[13]); - dev_info(smu->adev->dev, "Paddingclks[14] = 0x%x\n", pptable->Paddingclks[14]); - dev_info(smu->adev->dev, "Paddingclks[15] = 0x%x\n", pptable->Paddingclks[15]); - dev_info(smu->adev->dev, "DcModeMaxFreq\n"); dev_info(smu->adev->dev, " .PPCLK_GFXCLK = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_GFXCLK]); dev_info(smu->adev->dev, " .PPCLK_SOCCLK = 0x%x\n", pptable->DcModeMaxFreq[PPCLK_SOCCLK]); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index b6453ee6f8e6..624065d3c079 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -216,6 +216,7 @@ int smu_v11_0_check_fw_status(struct smu_context *smu) int smu_v11_0_check_fw_version(struct smu_context *smu) { + struct amdgpu_device *adev = smu->adev; uint32_t if_version = 0xff, smu_version = 0xff; uint16_t smu_major; uint8_t smu_minor, smu_debug; @@ -228,6 +229,8 @@ int smu_v11_0_check_fw_version(struct smu_context *smu) smu_major = (smu_version >> 16) & 0xffff; smu_minor = (smu_version >> 8) & 0xff; smu_debug = (smu_version >> 0) & 0xff; + if (smu->is_apu) + adev->pm.fw_version = smu_version; switch (smu->adev->asic_type) { case CHIP_ARCTURUS: @@ -336,8 +339,7 @@ int smu_v11_0_setup_pptable(struct smu_context *smu) hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; version_major = le16_to_cpu(hdr->header.header_version_major); version_minor = le16_to_cpu(hdr->header.header_version_minor); - if ((version_major == 2 && smu->smu_table.boot_values.pp_table_id > 0) || - adev->asic_type == CHIP_DIMGREY_CAVEFISH) { + if (version_major == 2 && smu->smu_table.boot_values.pp_table_id > 0) { dev_info(adev->dev, "use driver provided pptable %d\n", smu->smu_table.boot_values.pp_table_id); switch (version_minor) { case 0: @@ -435,11 +437,13 @@ int smu_v11_0_fini_smc_tables(struct smu_context *smu) kfree(smu_table->overdrive_table); kfree(smu_table->max_sustainable_clocks); kfree(smu_table->driver_pptable); + kfree(smu_table->clocks_table); smu_table->gpu_metrics_table = NULL; smu_table->boot_overdrive_table = NULL; smu_table->overdrive_table = NULL; smu_table->max_sustainable_clocks = NULL; smu_table->driver_pptable = NULL; + smu_table->clocks_table = NULL; kfree(smu_table->hardcode_pptable); smu_table->hardcode_pptable = NULL; @@ -466,11 +470,11 @@ int smu_v11_0_init_power(struct smu_context *smu) { struct smu_power_context *smu_power = &smu->smu_power; - smu_power->power_context = kzalloc(sizeof(struct smu_11_0_dpm_context), + smu_power->power_context = kzalloc(sizeof(struct smu_11_0_power_context), GFP_KERNEL); if (!smu_power->power_context) return -ENOMEM; - smu_power->power_context_size = sizeof(struct smu_11_0_dpm_context); + smu_power->power_context_size = sizeof(struct smu_11_0_power_context); return 0; } @@ -1183,7 +1187,12 @@ int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu, if (ret) return ret; - crystal_clock_freq = amdgpu_asic_get_xclk(adev); + /* + * crystal_clock_freq div by 4 is required since the fan control + * module refers to 25MHz + */ + + crystal_clock_freq = amdgpu_asic_get_xclk(adev) / 4; tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed); WREG32_SOC15(THM, 0, mmCG_TACH_CTRL, REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL), @@ -1481,6 +1490,9 @@ enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu) return baco_state; } +#define D3HOT_BACO_SEQUENCE 0 +#define D3HOT_BAMACO_SEQUENCE 2 + int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state) { struct smu_baco_context *smu_baco = &smu->smu_baco; @@ -1495,15 +1507,34 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state) mutex_lock(&smu_baco->mutex); if (state == SMU_BACO_STATE_ENTER) { - if (!ras || !ras->supported) { - data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); - data |= 0x80000000; - WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); - - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 0, NULL); - } else { - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 1, NULL); + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + if (amdgpu_runtime_pm == 2) + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_EnterBaco, + D3HOT_BAMACO_SEQUENCE, + NULL); + else + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_EnterBaco, + D3HOT_BACO_SEQUENCE, + NULL); + break; + default: + if (!ras || !ras->supported) { + data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); + data |= 0x80000000; + WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 0, NULL); + } else { + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 1, NULL); + } + break; } + } else { ret = smu_cmn_send_smc_msg(smu, SMU_MSG_ExitBaco, NULL); if (ret) @@ -1996,6 +2027,18 @@ void smu_v11_0_init_gpu_metrics_v1_0(struct gpu_metrics_v1_0 *gpu_metrics) gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); } +void smu_v11_0_init_gpu_metrics_v2_0(struct gpu_metrics_v2_0 *gpu_metrics) +{ + memset(gpu_metrics, 0xFF, sizeof(struct gpu_metrics_v2_0)); + + gpu_metrics->common_header.structure_size = + sizeof(struct gpu_metrics_v2_0); + gpu_metrics->common_header.format_revision = 2; + gpu_metrics->common_header.content_revision = 0; + + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); +} + int smu_v11_0_gfx_ulv_control(struct smu_context *smu, bool enablement) { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 83a1b0a04eb1..a81e5c823211 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -200,8 +200,14 @@ static int vangogh_tables_init(struct smu_context *smu) if (!smu_table->watermarks_table) goto err2_out; + smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + if (!smu_table->clocks_table) + goto err3_out; + return 0; +err3_out: + kfree(smu_table->clocks_table); err2_out: kfree(smu_table->gpu_metrics_table); err1_out: @@ -259,6 +265,12 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu, case METRICS_THROTTLER_STATUS: *value = metrics->ThrottlerStatus; break; + case METRICS_VOLTAGE_VDDGFX: + *value = metrics->Voltage[2]; + break; + case METRICS_VOLTAGE_VDDSOC: + *value = metrics->Voltage[1]; + break; default: *value = UINT_MAX; break; @@ -390,91 +402,33 @@ static bool vangogh_is_dpm_running(struct smu_context *smu) return !!(feature_enabled & SMC_DPM_FEATURE); } -static int vangogh_get_current_activity_percent(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = vangogh_get_smu_metrics_data(smu, - METRICS_AVERAGE_GFXACTIVITY, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n"); - return -EINVAL; - } - - return 0; -} - -static int vangogh_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return vangogh_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, - value); -} - -static int vangogh_thermal_get_temperature(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - - if (!value) - return -EINVAL; - - switch (sensor) { - case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: - ret = vangogh_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_HOTSPOT, - value); - break; - case AMDGPU_PP_SENSOR_EDGE_TEMP: - ret = vangogh_get_smu_metrics_data(smu, - METRICS_TEMPERATURE_EDGE, - value); - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n"); - return -EINVAL; - } - - return ret; -} - -static int vangogh_get_current_clk_freq_by_table(struct smu_context *smu, - enum smu_clk_type clk_type, - uint32_t *value) +static int vangogh_print_fine_grain_clk(struct smu_context *smu, + enum smu_clk_type clk_type, char *buf) { - MetricsMember_t member_type; + int size = 0; switch (clk_type) { - case SMU_GFXCLK: - member_type = METRICS_AVERAGE_GFXCLK; - break; - case SMU_MCLK: - case SMU_UCLK: - member_type = METRICS_AVERAGE_UCLK; + case SMU_OD_SCLK: + if (smu->od_enabled) { + size = sprintf(buf, "%s:\n", "OD_SCLK"); + size += sprintf(buf + size, "0: %10uMhz\n", + (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); + size += sprintf(buf + size, "1: %10uMhz\n", + (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + } break; - case SMU_SOCCLK: - member_type = METRICS_AVERAGE_SOCCLK; + case SMU_OD_RANGE: + if (smu->od_enabled) { + size = sprintf(buf, "%s:\n", "OD_RANGE"); + size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n", + smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq); + } break; default: - return -EINVAL; + break; } - return vangogh_get_smu_metrics_data(smu, - member_type, - value); + return size; } static int vangogh_read_sensor(struct smu_context *smu, @@ -489,30 +443,53 @@ static int vangogh_read_sensor(struct smu_context *smu, mutex_lock(&smu->sensor_lock); switch (sensor) { case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = vangogh_get_current_activity_percent(smu, sensor, (uint32_t *)data); + ret = vangogh_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXACTIVITY, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GPU_POWER: - ret = vangogh_get_gpu_power(smu, (uint32_t *)data); + ret = vangogh_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_EDGE_TEMP: + ret = vangogh_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_EDGE, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: - ret = vangogh_thermal_get_temperature(smu, sensor, (uint32_t *)data); + ret = vangogh_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_HOTSPOT, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GFX_MCLK: - ret = vangogh_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data); + ret = vangogh_get_smu_metrics_data(smu, + METRICS_AVERAGE_UCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; case AMDGPU_PP_SENSOR_GFX_SCLK: - ret = vangogh_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data); + ret = vangogh_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; case AMDGPU_PP_SENSOR_VDDGFX: - ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); + ret = vangogh_get_smu_metrics_data(smu, + METRICS_VOLTAGE_VDDGFX, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_VDDNB: + ret = vangogh_get_smu_metrics_data(smu, + METRICS_VOLTAGE_VDDSOC, + (uint32_t *)data); *size = 4; break; default: @@ -584,6 +561,167 @@ static int vangogh_set_watermarks_table(struct smu_context *smu, return 0; } +static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, + void **table) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct gpu_metrics_v2_0 *gpu_metrics = + (struct gpu_metrics_v2_0 *)smu_table->gpu_metrics_table; + SmuMetrics_t metrics; + int ret = 0; + + ret = smu_cmn_get_metrics_table(smu, &metrics, true); + if (ret) + return ret; + + smu_v11_0_init_gpu_metrics_v2_0(gpu_metrics); + + gpu_metrics->temperature_gfx = metrics.GfxTemperature; + gpu_metrics->temperature_soc = metrics.SocTemperature; + memcpy(&gpu_metrics->temperature_core[0], + &metrics.CoreTemperature[0], + sizeof(uint16_t) * 8); + gpu_metrics->temperature_l3[0] = metrics.L3Temperature[0]; + gpu_metrics->temperature_l3[1] = metrics.L3Temperature[1]; + + gpu_metrics->average_gfx_activity = metrics.GfxActivity; + gpu_metrics->average_mm_activity = metrics.UvdActivity; + + gpu_metrics->average_socket_power = metrics.CurrentSocketPower; + gpu_metrics->average_cpu_power = metrics.Power[0]; + gpu_metrics->average_soc_power = metrics.Power[1]; + memcpy(&gpu_metrics->average_core_power[0], + &metrics.CorePower[0], + sizeof(uint16_t) * 8); + + gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; + gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; + gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency; + gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; + + memcpy(&gpu_metrics->current_coreclk[0], + &metrics.CoreFrequency[0], + sizeof(uint16_t) * 8); + gpu_metrics->current_l3clk[0] = metrics.L3Frequency[0]; + gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1]; + + gpu_metrics->throttle_status = metrics.ThrottlerStatus; + + *table = (void *)gpu_metrics; + + return sizeof(struct gpu_metrics_v2_0); +} + +static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, + long input[], uint32_t size) +{ + int ret = 0; + + if (!smu->od_enabled) { + dev_warn(smu->adev->dev, "Fine grain is not enabled!\n"); + return -EINVAL; + } + + switch (type) { + case PP_OD_EDIT_SCLK_VDDC_TABLE: + if (size != 2) { + dev_err(smu->adev->dev, "Input parameter number not correct\n"); + return -EINVAL; + } + + if (input[0] == 0) { + if (input[1] < smu->gfx_default_hard_min_freq) { + dev_warn(smu->adev->dev, "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", + input[1], smu->gfx_default_hard_min_freq); + return -EINVAL; + } + smu->gfx_actual_hard_min_freq = input[1]; + } else if (input[0] == 1) { + if (input[1] > smu->gfx_default_soft_max_freq) { + dev_warn(smu->adev->dev, "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", + input[1], smu->gfx_default_soft_max_freq); + return -EINVAL; + } + smu->gfx_actual_soft_max_freq = input[1]; + } else { + return -EINVAL; + } + break; + case PP_OD_RESTORE_DEFAULT_TABLE: + if (size != 0) { + dev_err(smu->adev->dev, "Input parameter number not correct\n"); + return -EINVAL; + } else { + smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; + smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, + smu->gfx_actual_hard_min_freq, NULL); + if (ret) { + dev_err(smu->adev->dev, "Restore the default hard min sclk failed!"); + return ret; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, + smu->gfx_actual_soft_max_freq, NULL); + if (ret) { + dev_err(smu->adev->dev, "Restore the default soft max sclk failed!"); + return ret; + } + } + break; + case PP_OD_COMMIT_DPM_TABLE: + if (size != 0) { + dev_err(smu->adev->dev, "Input parameter number not correct\n"); + return -EINVAL; + } else { + if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) { + dev_err(smu->adev->dev, "The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n", + smu->gfx_actual_hard_min_freq, smu->gfx_actual_soft_max_freq); + return -EINVAL; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, + smu->gfx_actual_hard_min_freq, NULL); + if (ret) { + dev_err(smu->adev->dev, "Set hard min sclk failed!"); + return ret; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, + smu->gfx_actual_soft_max_freq, NULL); + if (ret) { + dev_err(smu->adev->dev, "Set soft max sclk failed!"); + return ret; + } + } + break; + default: + return -ENOSYS; + } + + return ret; +} + +static int vangogh_set_default_dpm_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + + return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); +} + +static int vangogh_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) +{ + DpmClocks_t *clk_table = smu->smu_table.clocks_table; + + smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; + smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; + smu->gfx_actual_hard_min_freq = 0; + smu->gfx_actual_soft_max_freq = 0; + + return 0; +} + static const struct pptable_funcs vangogh_ppt_funcs = { .check_fw_status = smu_v11_0_check_fw_status, @@ -605,8 +743,12 @@ static const struct pptable_funcs vangogh_ppt_funcs = { .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .set_watermarks_table = vangogh_set_watermarks_table, .set_driver_table_location = smu_v11_0_set_driver_table_location, - .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception, .interrupt_work = smu_v11_0_interrupt_work, + .get_gpu_metrics = vangogh_get_gpu_metrics, + .od_edit_dpm_table = vangogh_od_edit_dpm_table, + .print_clk_levels = vangogh_print_fine_grain_clk, + .set_default_dpm_table = vangogh_set_default_dpm_tables, + .set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters, }; void vangogh_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index 66c1026489be..dc75db8af371 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -170,7 +170,7 @@ err0_out: return -ENOMEM; } -/** +/* * This interface just for getting uclk ultimate freq and should't introduce * other likewise function result in overmuch callback. */ @@ -492,28 +492,6 @@ static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) return ret; } -static int renoir_get_current_clk_freq_by_table(struct smu_context *smu, - enum smu_clk_type clk_type, - uint32_t *value) -{ - int ret = 0, clk_id = 0; - SmuMetrics_t metrics; - - ret = smu_cmn_get_metrics_table(smu, &metrics, false); - if (ret) - return ret; - - clk_id = smu_cmn_to_asic_specific_index(smu, - CMN2ASIC_MAPPING_CLK, - clk_type); - if (clk_id < 0) - return clk_id; - - *value = metrics.ClockFrequency[clk_id]; - - return ret; -} - static int renoir_force_dpm_limit_value(struct smu_context *smu, bool highest) { int ret = 0, i = 0; @@ -574,89 +552,7 @@ static int renoir_unforce_dpm_levels(struct smu_context *smu) { return ret; } -static int renoir_get_gpu_temperature(struct smu_context *smu, uint32_t *value) -{ - int ret = 0; - SmuMetrics_t metrics; - - if (!value) - return -EINVAL; - - ret = smu_cmn_get_metrics_table(smu, &metrics, false); - if (ret) - return ret; - - *value = (metrics.GfxTemperature / 100) * - SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; - - return 0; -} - -static int renoir_get_current_activity_percent(struct smu_context *smu, - enum amd_pp_sensors sensor, - uint32_t *value) -{ - int ret = 0; - SmuMetrics_t metrics; - - if (!value) - return -EINVAL; - - ret = smu_cmn_get_metrics_table(smu, &metrics, false); - if (ret) - return ret; - - switch (sensor) { - case AMDGPU_PP_SENSOR_GPU_LOAD: - *value = metrics.AverageGfxActivity / 100; - break; - default: - dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n"); - return -EINVAL; - } - - return 0; -} - -static int renoir_get_vddc(struct smu_context *smu, uint32_t *value, - unsigned int index) -{ - int ret = 0; - SmuMetrics_t metrics; - - if (index >= 2) - return -EINVAL; - - if (!value) - return -EINVAL; - - ret = smu_cmn_get_metrics_table(smu, &metrics, false); - if (ret) - return ret; - - *value = metrics.Voltage[index]; - - return 0; -} - -static int renoir_get_power(struct smu_context *smu, uint32_t *value) -{ - int ret = 0; - SmuMetrics_t metrics; - - if (!value) - return -EINVAL; - - ret = smu_cmn_get_metrics_table(smu, &metrics, false); - if (ret) - return ret; - - *value = metrics.CurrentSocketPower << 8; - - return 0; -} - -/** +/* * This interface get dpm clock table for dc */ static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table) @@ -1011,6 +907,71 @@ static int renoir_get_power_profile_mode(struct smu_context *smu, return size; } +static int renoir_get_smu_metrics_data(struct smu_context *smu, + MetricsMember_t member, + uint32_t *value) +{ + struct smu_table_context *smu_table = &smu->smu_table; + + SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; + int ret = 0; + + mutex_lock(&smu->metrics_lock); + + ret = smu_cmn_get_metrics_table_locked(smu, + NULL, + false); + if (ret) { + mutex_unlock(&smu->metrics_lock); + return ret; + } + + switch (member) { + case METRICS_AVERAGE_GFXCLK: + *value = metrics->ClockFrequency[CLOCK_GFXCLK]; + break; + case METRICS_AVERAGE_SOCCLK: + *value = metrics->ClockFrequency[CLOCK_SOCCLK]; + break; + case METRICS_AVERAGE_UCLK: + *value = metrics->ClockFrequency[CLOCK_FCLK]; + break; + case METRICS_AVERAGE_GFXACTIVITY: + *value = metrics->AverageGfxActivity / 100; + break; + case METRICS_AVERAGE_VCNACTIVITY: + *value = metrics->AverageUvdActivity / 100; + break; + case METRICS_AVERAGE_SOCKETPOWER: + *value = metrics->CurrentSocketPower << 8; + break; + case METRICS_TEMPERATURE_EDGE: + *value = (metrics->GfxTemperature / 100) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + break; + case METRICS_TEMPERATURE_HOTSPOT: + *value = (metrics->SocTemperature / 100) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + break; + case METRICS_THROTTLER_STATUS: + *value = metrics->ThrottlerStatus; + break; + case METRICS_VOLTAGE_VDDGFX: + *value = metrics->Voltage[0]; + break; + case METRICS_VOLTAGE_VDDSOC: + *value = metrics->Voltage[1]; + break; + default: + *value = UINT_MAX; + break; + } + + mutex_unlock(&smu->metrics_lock); + + return ret; +} + static int renoir_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, void *data, uint32_t *size) @@ -1023,33 +984,53 @@ static int renoir_read_sensor(struct smu_context *smu, mutex_lock(&smu->sensor_lock); switch (sensor) { case AMDGPU_PP_SENSOR_GPU_LOAD: - ret = renoir_get_current_activity_percent(smu, sensor, (uint32_t *)data); + ret = renoir_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXACTIVITY, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_EDGE_TEMP: + ret = renoir_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_EDGE, + (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_TEMP: - ret = renoir_get_gpu_temperature(smu, (uint32_t *)data); + case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: + ret = renoir_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_HOTSPOT, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GFX_MCLK: - ret = renoir_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data); + ret = renoir_get_smu_metrics_data(smu, + METRICS_AVERAGE_UCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; case AMDGPU_PP_SENSOR_GFX_SCLK: - ret = renoir_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data); + ret = renoir_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; case AMDGPU_PP_SENSOR_VDDGFX: - ret = renoir_get_vddc(smu, (uint32_t *)data, 0); + ret = renoir_get_smu_metrics_data(smu, + METRICS_VOLTAGE_VDDGFX, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_VDDNB: - ret = renoir_get_vddc(smu, (uint32_t *)data, 1); + ret = renoir_get_smu_metrics_data(smu, + METRICS_VOLTAGE_VDDSOC, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_GPU_POWER: - ret = renoir_get_power(smu, (uint32_t *)data); + ret = renoir_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; default: @@ -1136,6 +1117,12 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu, return sizeof(struct gpu_metrics_v2_0); } +static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state) +{ + + return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GpuChangeState, state, NULL); +} + static const struct pptable_funcs renoir_ppt_funcs = { .set_power_state = NULL, .print_clk_levels = renoir_print_clk_levels, @@ -1171,6 +1158,7 @@ static const struct pptable_funcs renoir_ppt_funcs = { .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, .get_gpu_metrics = renoir_get_gpu_metrics, + .gfx_state_change_set = renoir_gfx_state_change_set, }; void renoir_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c index 660f403d5770..522d55004655 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c @@ -71,6 +71,7 @@ int smu_v12_0_check_fw_status(struct smu_context *smu) int smu_v12_0_check_fw_version(struct smu_context *smu) { + struct amdgpu_device *adev = smu->adev; uint32_t if_version = 0xff, smu_version = 0xff; uint16_t smu_major; uint8_t smu_minor, smu_debug; @@ -83,6 +84,8 @@ int smu_v12_0_check_fw_version(struct smu_context *smu) smu_major = (smu_version >> 16) & 0xffff; smu_minor = (smu_version >> 8) & 0xff; smu_debug = (smu_version >> 0) & 0xff; + if (smu->is_apu) + adev->pm.fw_version = smu_version; /* * 1. if_version mismatch is not critical as our fw is designed diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index dc28f22aeb38..f8260769061c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -655,7 +655,7 @@ int smu_cmn_update_table(struct smu_context *smu, return ret; if (!drv2smu) { - amdgpu_asic_flush_hdp(adev, NULL); + amdgpu_asic_invalidate_hdp(adev, NULL); memcpy(table_data, table->cpu_addr, table_size); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h index f7be2d1a0ff2..68d9464ababc 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h @@ -90,6 +90,7 @@ #define smu_get_fan_parameters(smu) smu_ppt_funcs(get_fan_parameters, 0, smu) #define smu_post_init(smu) smu_ppt_funcs(post_init, 0, smu) #define smu_gpo_control(smu, enablement) smu_ppt_funcs(gpo_control, 0, smu, enablement) +#define smu_set_fine_grain_gfx_freq_parameters(smu) smu_ppt_funcs(set_fine_grain_gfx_freq_parameters, 0, smu) #endif #endif |