diff options
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu')
26 files changed, 556 insertions, 495 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index ce41a8309582..f005a90c35af 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -618,7 +618,7 @@ static int smu_set_funcs(struct amdgpu_device *adev) adev->pm.pp_feature &= ~PP_GFXOFF_MASK; arcturus_set_ppt_funcs(smu); /* OD is not supported on Arcturus */ - smu->od_enabled =false; + smu->od_enabled = false; break; case IP_VERSION(13, 0, 2): aldebaran_set_ppt_funcs(smu); @@ -1581,9 +1581,9 @@ static int smu_disable_dpms(struct smu_context *smu) /* * For SMU 13.0.4/11, PMFW will handle the features disablement properly - * for gpu reset case. Driver involvement is unnecessary. + * for gpu reset and S0i3 cases. Driver involvement is unnecessary. */ - if (amdgpu_in_reset(adev)) { + if (amdgpu_in_reset(adev) || adev->in_s0ix) { switch (adev->ip_versions[MP1_HWIP][0]) { case IP_VERSION(13, 0, 4): case IP_VERSION(13, 0, 11): @@ -1648,7 +1648,7 @@ static int smu_hw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = adev->powerplay.pp_handle; - if (amdgpu_sriov_vf(adev)&& !amdgpu_sriov_is_pp_one_vf(adev)) + if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return 0; smu_dpm_set_vcn_enable(smu, false); @@ -1700,7 +1700,7 @@ static int smu_suspend(void *handle) int ret; uint64_t count; - if (amdgpu_sriov_vf(adev)&& !amdgpu_sriov_is_pp_one_vf(adev)) + if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return 0; if (!smu->pm_enabled) @@ -2217,8 +2217,7 @@ const struct amd_ip_funcs smu_ip_funcs = { .set_powergating_state = smu_set_powergating_state, }; -const struct amdgpu_ip_block_version smu_v11_0_ip_block = -{ +const struct amdgpu_ip_block_version smu_v11_0_ip_block = { .type = AMD_IP_BLOCK_TYPE_SMC, .major = 11, .minor = 0, @@ -2226,8 +2225,7 @@ const struct amdgpu_ip_block_version smu_v11_0_ip_block = .funcs = &smu_ip_funcs, }; -const struct amdgpu_ip_block_version smu_v12_0_ip_block = -{ +const struct amdgpu_ip_block_version smu_v12_0_ip_block = { .type = AMD_IP_BLOCK_TYPE_SMC, .major = 12, .minor = 0, @@ -2235,8 +2233,7 @@ const struct amdgpu_ip_block_version smu_v12_0_ip_block = .funcs = &smu_ip_funcs, }; -const struct amdgpu_ip_block_version smu_v13_0_ip_block = -{ +const struct amdgpu_ip_block_version smu_v13_0_ip_block = { .type = AMD_IP_BLOCK_TYPE_SMC, .major = 13, .minor = 0, @@ -2337,7 +2334,7 @@ int smu_get_power_limit(void *handle, if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; - switch(pp_power_type) { + switch (pp_power_type) { case PP_PWR_TYPE_SUSTAINED: limit_type = SMU_DEFAULT_PPT_LIMIT; break; @@ -2349,7 +2346,7 @@ int smu_get_power_limit(void *handle, break; } - switch(pp_limit_level){ + switch (pp_limit_level) { case PP_PWR_LIMIT_CURRENT: limit_level = SMU_PPT_LIMIT_CURRENT; break; @@ -2595,7 +2592,7 @@ static int smu_read_sensor(void *handle, *size = 4; break; case AMDGPU_PP_SENSOR_VCN_POWER_STATE: - *(uint32_t *)data = atomic_read(&smu->smu_power.power_gate.vcn_gated) ? 0: 1; + *(uint32_t *)data = atomic_read(&smu->smu_power.power_gate.vcn_gated) ? 0 : 1; *size = 4; break; case AMDGPU_PP_SENSOR_MIN_FAN_RPM: @@ -2868,7 +2865,7 @@ static int smu_set_xgmi_pstate(void *handle, if (smu->ppt_funcs->set_xgmi_pstate) ret = smu->ppt_funcs->set_xgmi_pstate(smu, pstate); - if(ret) + if (ret) dev_err(smu->adev->dev, "Failed to set XGMI pstate!\n"); return ret; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 6e2069dcb6b9..95eb8a5eb54f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -200,29 +200,25 @@ struct smu_power_state { struct smu_hw_power_state hardware; }; -enum smu_power_src_type -{ +enum smu_power_src_type { SMU_POWER_SOURCE_AC, SMU_POWER_SOURCE_DC, SMU_POWER_SOURCE_COUNT, }; -enum smu_ppt_limit_type -{ +enum smu_ppt_limit_type { SMU_DEFAULT_PPT_LIMIT = 0, SMU_FAST_PPT_LIMIT, }; -enum smu_ppt_limit_level -{ +enum smu_ppt_limit_level { SMU_PPT_LIMIT_MIN = -1, SMU_PPT_LIMIT_CURRENT, SMU_PPT_LIMIT_DEFAULT, SMU_PPT_LIMIT_MAX, }; -enum smu_memory_pool_size -{ +enum smu_memory_pool_size { SMU_MEMORY_POOL_SIZE_ZERO = 0, SMU_MEMORY_POOL_SIZE_256_MB = 0x10000000, SMU_MEMORY_POOL_SIZE_512_MB = 0x20000000, @@ -282,8 +278,7 @@ struct smu_clock_info { uint32_t max_bus_bandwidth; }; -struct smu_bios_boot_up_values -{ +struct smu_bios_boot_up_values { uint32_t revision; uint32_t gfxclk; uint32_t uclk; @@ -305,8 +300,7 @@ struct smu_bios_boot_up_values uint32_t firmware_caps; }; -enum smu_table_id -{ +enum smu_table_id { SMU_TABLE_PPTABLE = 0, SMU_TABLE_WATERMARKS, SMU_TABLE_CUSTOM_DPM, @@ -326,8 +320,7 @@ enum smu_table_id SMU_TABLE_COUNT, }; -struct smu_table_context -{ +struct smu_table_context { void *power_play_table; uint32_t power_play_table_size; void *hardcode_pptable; @@ -390,8 +383,7 @@ struct smu_power_context { }; #define SMU_FEATURE_MAX (64) -struct smu_feature -{ +struct smu_feature { uint32_t feature_num; DECLARE_BITMAP(supported, SMU_FEATURE_MAX); DECLARE_BITMAP(allowed, SMU_FEATURE_MAX); @@ -416,21 +408,18 @@ struct mclock_latency_table { struct mclk_latency_entries entries[MAX_REGULAR_DPM_NUM]; }; -enum smu_reset_mode -{ +enum smu_reset_mode { SMU_RESET_MODE_0, SMU_RESET_MODE_1, SMU_RESET_MODE_2, }; -enum smu_baco_state -{ +enum smu_baco_state { SMU_BACO_STATE_ENTER = 0, SMU_BACO_STATE_EXIT, }; -struct smu_baco_context -{ +struct smu_baco_context { uint32_t state; bool platform_support; bool maco_support; @@ -478,8 +467,7 @@ struct stb_context { #define WORKLOAD_POLICY_MAX 7 -struct smu_context -{ +struct smu_context { struct amdgpu_device *adev; struct amdgpu_irq_src irq_source; @@ -1398,6 +1386,7 @@ typedef enum { METRICS_PCIE_RATE, METRICS_PCIE_WIDTH, METRICS_CURR_FANPWM, + METRICS_CURR_SOCKETPOWER, } MetricsMember_t; enum smu_cmn2asic_mapping_type { diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h index 7589faa0232d..779c2524806c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h @@ -23,7 +23,7 @@ #ifndef __SMU13_DRIVER_IF_V13_0_5_H__ #define __SMU13_DRIVER_IF_V13_0_5_H__ -#define SMU13_0_5_DRIVER_IF_VERSION 4 +#define SMU13_0_5_DRIVER_IF_VERSION 5 // Throttler Status Bitmask #define THROTTLER_STATUS_BIT_SPL 0 @@ -103,7 +103,6 @@ typedef struct { uint16_t ThrottlerStatus; uint16_t CurrentSocketPower; //[mW] - uint16_t spare1; } SmuMetrics_t; //Freq in MHz diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h index beab6d7b28b7..630132c4a76b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h @@ -52,8 +52,7 @@ static unsigned int DbiPrbs7[] = //4096 bytes, 256 byte aligned -static unsigned int NoDbiPrbs7[] = -{ +static unsigned int NoDbiPrbs7[] = { 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f00f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f0f0f0, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f00f0f, 0xf0f00f0f, 0x0f0f0f0f, 0xf0f0f0f0, 0xf0f0f0f0, 0x0f0f0f0f, 0xf0f00f0f, 0x0f0f0f0f, 0xf0f00f0f, 0xf0f0f0f0, 0x0f0f0f0f, 0xf0f0f0f0, 0xf0f00f0f, 0xf0f00f0f, 0xf0f00f0f, 0x0f0ff0f0, 0xf0f0f0f0, 0xf0f0f0f0, 0x0f0ff0f0, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f0f0f0, 0xf0f00f0f, 0x0f0f0f0f, 0xf0f00f0f, 0x0f0ff0f0, 0x0f0f0f0f, 0xf0f0f0f0, 0x0f0ff0f0, 0xf0f00f0f, 0xf0f00f0f, 0xf0f0f0f0, 0x0f0ff0f0, 0xf0f0f0f0, 0xf0f00f0f, 0xf0f0f0f0, 0x0f0f0f0f, 0x0f0ff0f0, 0xf0f00f0f, @@ -121,8 +120,7 @@ static unsigned int NoDbiPrbs7[] = }; // 4096 bytes, 256 byte aligned -static unsigned int DbiPrbs7[] = -{ +static unsigned int DbiPrbs7[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x00000000, 0xffffffff, 0x00000000, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x00000000, 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffff0000, 0xffffffff, 0x00000000, 0xffff0000, 0x0000ffff, 0x0000ffff, 0x00000000, 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000, 0xffffffff, 0xffff0000, 0x0000ffff, diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h index d466db6f0ad4..a0e5ad0381d6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h @@ -64,11 +64,9 @@ #define LINK_SPEED_MAX 3 static const __maybe_unused uint16_t link_width[] = {0, 1, 2, 4, 8, 12, 16}; -static const __maybe_unused uint16_t link_speed[] = {25, 50, 80, 160}; static const -struct smu_temperature_range __maybe_unused smu11_thermal_policy[] = -{ +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}, }; @@ -96,8 +94,8 @@ struct smu_11_0_dpm_table { }; struct smu_11_0_pcie_table { - uint8_t pcie_gen[MAX_PCIE_CONF]; - uint8_t pcie_lane[MAX_PCIE_CONF]; + uint8_t pcie_gen[MAX_PCIE_CONF]; + uint8_t pcie_lane[MAX_PCIE_CONF]; }; struct smu_11_0_dpm_tables { diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h index 0116e3d04fad..df7430876e0c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h @@ -101,8 +101,7 @@ enum SMU_11_0_ODSETTING_ID { }; #define SMU_11_0_MAX_ODSETTING 32 //Maximum Number of ODSettings -struct smu_11_0_overdrive_table -{ +struct smu_11_0_overdrive_table { uint8_t revision; //Revision = SMU_11_0_PP_OVERDRIVE_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t feature_count; //Total number of supported features @@ -127,8 +126,7 @@ enum SMU_11_0_PPCLOCK_ID { }; #define SMU_11_0_MAX_PPCLOCK 16 //Maximum Number of PP Clocks -struct smu_11_0_power_saving_clock_table -{ +struct smu_11_0_power_saving_clock_table { uint8_t revision; //Revision = SMU_11_0_PP_POWERSAVINGCLOCK_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t count; //power_saving_clock_count = SMU_11_0_PPCLOCK_COUNT @@ -136,8 +134,7 @@ struct smu_11_0_power_saving_clock_table uint32_t min[SMU_11_0_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Minimum array In MHz }; -struct smu_11_0_powerplay_table -{ +struct smu_11_0_powerplay_table { struct atom_common_table_header header; uint8_t table_revision; uint16_t table_size; //Driver portion table size. The offset to smc_pptable including header size @@ -145,14 +142,14 @@ struct smu_11_0_powerplay_table uint32_t golden_revision; uint16_t format_id; uint32_t platform_caps; //POWERPLAYABLE::ulPlatformCaps - + uint8_t thermal_controller_type; //one of SMU_11_0_PP_THERMALCONTROLLER uint16_t small_power_limit1; uint16_t small_power_limit2; uint16_t boost_power_limit; - uint16_t od_turbo_power_limit; //Power limit setting for Turbo mode in Performance UI Tuning. - uint16_t od_power_save_power_limit; //Power limit setting for PowerSave/Optimal mode in Performance UI Tuning. + uint16_t od_turbo_power_limit; //Power limit setting for Turbo mode in Performance UI Tuning. + uint16_t od_power_save_power_limit; //Power limit setting for PowerSave/Optimal mode in Performance UI Tuning. uint16_t software_shutdown_temp; uint16_t reserve[6]; //Zero filled field reserved for future use diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h index 6a0ac0bbaace..355c156d871a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h @@ -295,5 +295,9 @@ int smu_v13_0_get_pptable_from_firmware(struct smu_context *smu, uint32_t *size, uint32_t pptable_id); +int smu_v13_0_update_pcie_parameters(struct smu_context *smu, + uint32_t pcie_gen_cap, + uint32_t pcie_width_cap); + #endif #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h index eadbe0149cae..eb694f9f556d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h @@ -41,8 +41,7 @@ #define SMU_13_0_7_PP_OVERDRIVE_VERSION 0x83 // OverDrive 8 Table Version 0.2 #define SMU_13_0_7_PP_POWERSAVINGCLOCK_VERSION 0x01 // Power Saving Clock Table Version 1.00 -enum SMU_13_0_7_ODFEATURE_CAP -{ +enum SMU_13_0_7_ODFEATURE_CAP { SMU_13_0_7_ODCAP_GFXCLK_LIMITS = 0, SMU_13_0_7_ODCAP_UCLK_LIMITS, SMU_13_0_7_ODCAP_POWER_LIMIT, @@ -62,8 +61,7 @@ enum SMU_13_0_7_ODFEATURE_CAP SMU_13_0_7_ODCAP_COUNT, }; -enum SMU_13_0_7_ODFEATURE_ID -{ +enum SMU_13_0_7_ODFEATURE_ID { SMU_13_0_7_ODFEATURE_GFXCLK_LIMITS = 1 << SMU_13_0_7_ODCAP_GFXCLK_LIMITS, //GFXCLK Limit feature SMU_13_0_7_ODFEATURE_UCLK_LIMITS = 1 << SMU_13_0_7_ODCAP_UCLK_LIMITS, //UCLK Limit feature SMU_13_0_7_ODFEATURE_POWER_LIMIT = 1 << SMU_13_0_7_ODCAP_POWER_LIMIT, //Power Limit feature @@ -85,8 +83,7 @@ enum SMU_13_0_7_ODFEATURE_ID #define SMU_13_0_7_MAX_ODFEATURE 32 //Maximum Number of OD Features -enum SMU_13_0_7_ODSETTING_ID -{ +enum SMU_13_0_7_ODSETTING_ID { SMU_13_0_7_ODSETTING_GFXCLKFMAX = 0, SMU_13_0_7_ODSETTING_GFXCLKFMIN, SMU_13_0_7_ODSETTING_UCLKFMIN, @@ -123,8 +120,7 @@ enum SMU_13_0_7_ODSETTING_ID }; #define SMU_13_0_7_MAX_ODSETTING 64 //Maximum Number of ODSettings -enum SMU_13_0_7_PWRMODE_SETTING -{ +enum SMU_13_0_7_PWRMODE_SETTING { SMU_13_0_7_PMSETTING_POWER_LIMIT_QUIET = 0, SMU_13_0_7_PMSETTING_POWER_LIMIT_BALANCE, SMU_13_0_7_PMSETTING_POWER_LIMIT_TURBO, @@ -144,8 +140,7 @@ enum SMU_13_0_7_PWRMODE_SETTING }; #define SMU_13_0_7_MAX_PMSETTING 32 //Maximum Number of PowerMode Settings -struct smu_13_0_7_overdrive_table -{ +struct smu_13_0_7_overdrive_table { uint8_t revision; //Revision = SMU_13_0_7_PP_OVERDRIVE_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t feature_count; //Total number of supported features @@ -156,8 +151,7 @@ struct smu_13_0_7_overdrive_table int16_t pm_setting[SMU_13_0_7_MAX_PMSETTING]; //Optimized power mode feature settings }; -enum SMU_13_0_7_PPCLOCK_ID -{ +enum SMU_13_0_7_PPCLOCK_ID { SMU_13_0_7_PPCLOCK_GFXCLK = 0, SMU_13_0_7_PPCLOCK_SOCCLK, SMU_13_0_7_PPCLOCK_UCLK, @@ -175,8 +169,7 @@ enum SMU_13_0_7_PPCLOCK_ID }; #define SMU_13_0_7_MAX_PPCLOCK 16 //Maximum Number of PP Clocks -struct smu_13_0_7_powerplay_table -{ +struct smu_13_0_7_powerplay_table { struct atom_common_table_header header; //For PLUM_BONITO, header.format_revision = 15, header.content_revision = 0 uint8_t table_revision; //For PLUM_BONITO, table_revision = 2 uint8_t padding; 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 9cd005131f56..704a2b577a0e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -598,7 +598,7 @@ static int arcturus_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; @@ -1130,7 +1130,7 @@ static int arcturus_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = arcturus_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -1169,6 +1169,7 @@ static int arcturus_read_sensor(struct smu_context *smu, ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1482,7 +1483,7 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu, return ret; if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) && - (smu_version >=0x360d00)) { + (smu_version >= 0x360d00)) { ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -2113,7 +2114,6 @@ static int arcturus_i2c_xfer(struct i2c_adapter *i2c_adap, } mutex_lock(&adev->pm.mutex); r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true); - mutex_unlock(&adev->pm.mutex); if (r) goto fail; @@ -2130,6 +2130,7 @@ static int arcturus_i2c_xfer(struct i2c_adapter *i2c_adap, } r = num_msgs; fail: + mutex_unlock(&adev->pm.mutex); kfree(req); return r; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c index ca4d97b7f576..9548bd3c624b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c @@ -154,10 +154,14 @@ cyan_skillfish_get_smu_metrics_data(struct smu_context *smu, case METRICS_CURR_UCLK: *value = metrics->Current.MemclkFrequency; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->Current.CurrentSocketPower << 8) / 1000; break; + case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->Average.CurrentSocketPower << 8) / + 1000; + break; case METRICS_TEMPERATURE_EDGE: *value = metrics->Current.GfxTemperature / 100 * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; @@ -208,12 +212,18 @@ static int cyan_skillfish_read_sensor(struct smu_context *smu, *(uint32_t *)data *= 100; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = cyan_skillfish_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_TEMPERATURE_HOTSPOT, 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 c94d825a871b..18487ae10bcf 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -136,7 +136,7 @@ static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 0), MSG_MAP(BacoAudioD3PME, PPSMC_MSG_BacoAudioD3PME, 0), MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0), - MSG_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE,PPSMC_MSG_DALDisableDummyPstateChange, 0), + MSG_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE, PPSMC_MSG_DALDisableDummyPstateChange, 0), MSG_MAP(DAL_ENABLE_DUMMY_PSTATE_CHANGE, PPSMC_MSG_DALEnableDummyPstateChange, 0), MSG_MAP(GetVoltageByDpm, PPSMC_MSG_GetVoltageByDpm, 0), MSG_MAP(GetVoltageByDpmOverdrive, PPSMC_MSG_GetVoltageByDpmOverdrive, 0), @@ -556,7 +556,7 @@ static int navi10_get_legacy_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_legacy_t *metrics = (SmuMetrics_legacy_t *)smu_table->metrics_table; int ret = 0; @@ -642,7 +642,7 @@ static int navi10_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; @@ -731,7 +731,7 @@ static int navi12_get_legacy_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_NV12_legacy_t *metrics = (SmuMetrics_NV12_legacy_t *)smu_table->metrics_table; int ret = 0; @@ -817,7 +817,7 @@ static int navi12_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_NV12_t *metrics = (SmuMetrics_NV12_t *)smu_table->metrics_table; int ret = 0; @@ -1686,7 +1686,7 @@ static int navi10_force_clk_levels(struct smu_context *smu, return 0; break; case SMU_DCEFCLK: - dev_info(smu->adev->dev,"Setting DCEFCLK min/max dpm level is not supported!\n"); + dev_info(smu->adev->dev, "Setting DCEFCLK min/max dpm level is not supported!\n"); break; default: @@ -2182,7 +2182,7 @@ static int navi10_read_sensor(struct smu_context *smu, struct smu_table_context *table_context = &smu->smu_table; PPTable_t *pptable = table_context->driver_pptable; - if(!data || !size) + if (!data || !size) return -EINVAL; switch (sensor) { @@ -2202,7 +2202,7 @@ static int navi10_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = navi1x_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -2240,6 +2240,7 @@ static int navi10_read_sensor(struct smu_context *smu, ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -2317,15 +2318,15 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu, uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal; uint32_t max_memory_clock = max_sustainable_clocks->uclock; - if(smu->disable_uclk_switch == disable_memory_clock_switch) + if (smu->disable_uclk_switch == disable_memory_clock_switch) return 0; - if(disable_memory_clock_switch) + if (disable_memory_clock_switch) ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, max_memory_clock, 0); else ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_memory_clock, 0); - if(!ret) + if (!ret) smu->disable_uclk_switch = disable_memory_clock_switch; return ret; @@ -2559,7 +2560,8 @@ static int navi10_set_default_od_settings(struct smu_context *smu) return 0; } -static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) { +static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) +{ int i; int ret = 0; struct smu_table_context *table_context = &smu->smu_table; @@ -3021,7 +3023,6 @@ static int navi10_i2c_xfer(struct i2c_adapter *i2c_adap, } mutex_lock(&adev->pm.mutex); r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true); - mutex_unlock(&adev->pm.mutex); if (r) goto fail; @@ -3038,6 +3039,7 @@ static int navi10_i2c_xfer(struct i2c_adapter *i2c_adap, } r = num_msgs; fail: + mutex_unlock(&adev->pm.mutex); kfree(req); return r; } @@ -3368,7 +3370,7 @@ static ssize_t navi1x_get_gpu_metrics(struct smu_context *smu, ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && smu_version > 0x002A3B00)) ret = navi10_get_gpu_metrics(smu, table); else - ret =navi10_get_legacy_gpu_metrics(smu, table); + ret = navi10_get_legacy_gpu_metrics(smu, table); break; } 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 f7ed3e655e39..4bb289f9b4b8 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 @@ -588,7 +588,9 @@ err0_out: return -ENOMEM; } -static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu) +static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu, + bool use_metrics_v3, + bool use_metrics_v2) { struct smu_table_context *smu_table= &smu->smu_table; SmuMetricsExternal_t *metrics_ext = @@ -596,13 +598,11 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s uint32_t throttler_status = 0; int i; - if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu->smc_fw_version >= 0x3A4900)) { + if (use_metrics_v3) { for (i = 0; i < THROTTLER_COUNT; i++) throttler_status |= (metrics_ext->SmuMetrics_V3.ThrottlingPercentage[i] ? 1U << i : 0); - } else if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu->smc_fw_version >= 0x3A4300)) { + } else if (use_metrics_v2) { for (i = 0; i < THROTTLER_COUNT; i++) throttler_status |= (metrics_ext->SmuMetrics_V2.ThrottlingPercentage[i] ? 1U << i : 0); @@ -864,7 +864,7 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu, metrics->TemperatureVrSoc) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; case METRICS_THROTTLER_STATUS: - *value = sienna_cichlid_get_throttler_status_locked(smu); + *value = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); break; case METRICS_CURR_FANSPEED: *value = use_metrics_v3 ? metrics_v3->CurrFanSpeed : @@ -1902,7 +1902,7 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = sienna_cichlid_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -1927,12 +1927,16 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, *size = 4; break; case AMDGPU_PP_SENSOR_GFX_MCLK: - ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data); + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_CURR_UCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; case AMDGPU_PP_SENSOR_GFX_SCLK: - ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data); + ret = sienna_cichlid_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXCLK, + (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; break; @@ -1958,6 +1962,7 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, ret = -EOPNOTSUPP; } break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -2077,89 +2082,36 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context return ret; } -static void sienna_cichlid_get_override_pcie_settings(struct smu_context *smu, - uint32_t *gen_speed_override, - uint32_t *lane_width_override) -{ - struct amdgpu_device *adev = smu->adev; - - *gen_speed_override = 0xff; - *lane_width_override = 0xff; - - switch (adev->pdev->device) { - case 0x73A0: - case 0x73A1: - case 0x73A2: - case 0x73A3: - case 0x73AB: - case 0x73AE: - /* Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 */ - *lane_width_override = 6; - break; - case 0x73E0: - case 0x73E1: - case 0x73E3: - *lane_width_override = 4; - break; - case 0x7420: - case 0x7421: - case 0x7422: - case 0x7423: - case 0x7424: - *lane_width_override = 3; - break; - default: - break; - } -} - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap) { struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; - uint32_t gen_speed_override, lane_width_override; - uint8_t *table_member1, *table_member2; - uint32_t min_gen_speed, max_gen_speed; - uint32_t min_lane_width, max_lane_width; - uint32_t smu_pcie_arg; + u32 smu_pcie_arg; int ret, i; - GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1); - GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2); + /* PCIE gen speed and lane width override */ + if (!amdgpu_device_pcie_dynamic_switching_supported()) { + if (pcie_table->pcie_gen[NUM_LINK_LEVELS - 1] < pcie_gen_cap) + pcie_gen_cap = pcie_table->pcie_gen[NUM_LINK_LEVELS - 1]; - sienna_cichlid_get_override_pcie_settings(smu, - &gen_speed_override, - &lane_width_override); + if (pcie_table->pcie_lane[NUM_LINK_LEVELS - 1] < pcie_width_cap) + pcie_width_cap = pcie_table->pcie_lane[NUM_LINK_LEVELS - 1]; - /* PCIE gen speed override */ - if (gen_speed_override != 0xff) { - min_gen_speed = MIN(pcie_gen_cap, gen_speed_override); - max_gen_speed = MIN(pcie_gen_cap, gen_speed_override); - } else { - min_gen_speed = MAX(0, table_member1[0]); - max_gen_speed = MIN(pcie_gen_cap, table_member1[1]); - min_gen_speed = min_gen_speed > max_gen_speed ? - max_gen_speed : min_gen_speed; - } - pcie_table->pcie_gen[0] = min_gen_speed; - pcie_table->pcie_gen[1] = max_gen_speed; - - /* PCIE lane width override */ - if (lane_width_override != 0xff) { - min_lane_width = MIN(pcie_width_cap, lane_width_override); - max_lane_width = MIN(pcie_width_cap, lane_width_override); + /* Force all levels to use the same settings */ + for (i = 0; i < NUM_LINK_LEVELS; i++) { + pcie_table->pcie_gen[i] = pcie_gen_cap; + pcie_table->pcie_lane[i] = pcie_width_cap; + } } else { - min_lane_width = MAX(1, table_member2[0]); - max_lane_width = MIN(pcie_width_cap, table_member2[1]); - min_lane_width = min_lane_width > max_lane_width ? - max_lane_width : min_lane_width; + for (i = 0; i < NUM_LINK_LEVELS; i++) { + if (pcie_table->pcie_gen[i] > pcie_gen_cap) + pcie_table->pcie_gen[i] = pcie_gen_cap; + if (pcie_table->pcie_lane[i] > pcie_width_cap) + pcie_table->pcie_lane[i] = pcie_width_cap; + } } - pcie_table->pcie_lane[0] = min_lane_width; - pcie_table->pcie_lane[1] = max_lane_width; for (i = 0; i < NUM_LINK_LEVELS; i++) { smu_pcie_arg = (i << 16 | @@ -3842,7 +3794,6 @@ static int sienna_cichlid_i2c_xfer(struct i2c_adapter *i2c_adap, } mutex_lock(&adev->pm.mutex); r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true); - mutex_unlock(&adev->pm.mutex); if (r) goto fail; @@ -3859,6 +3810,7 @@ static int sienna_cichlid_i2c_xfer(struct i2c_adapter *i2c_adap, } r = num_msgs; fail: + mutex_unlock(&adev->pm.mutex); kfree(req); return r; } @@ -4066,7 +4018,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_dclk1 = use_metrics_v3 ? metrics_v3->CurrClock[PPCLK_DCLK_1] : use_metrics_v2 ? metrics_v2->CurrClock[PPCLK_DCLK_1] : metrics->CurrClock[PPCLK_DCLK_1]; - gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu); + gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); gpu_metrics->indep_throttle_status = smu_cmn_get_indep_throttler_status(gpu_metrics->throttle_status, sienna_cichlid_throttler_map); 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 067b4e0b026c..201cec599842 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -390,6 +390,10 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu, *value = metrics->Current.UvdActivity; break; case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->Average.CurrentSocketPower << 8) / + 1000; + break; + case METRICS_CURR_SOCKETPOWER: *value = (metrics->Current.CurrentSocketPower << 8) / 1000; break; @@ -1536,12 +1540,18 @@ static int vangogh_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = vangogh_common_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = vangogh_common_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: ret = vangogh_common_get_smu_metrics_data(smu, METRICS_TEMPERATURE_EDGE, @@ -1854,6 +1864,86 @@ static ssize_t vangogh_get_gpu_metrics_v2_3(struct smu_context *smu, return sizeof(struct gpu_metrics_v2_3); } +static ssize_t vangogh_get_gpu_metrics_v2_4(struct smu_context *smu, + void **table) +{ + SmuMetrics_t metrics; + struct smu_table_context *smu_table = &smu->smu_table; + struct gpu_metrics_v2_4 *gpu_metrics = + (struct gpu_metrics_v2_4 *)smu_table->gpu_metrics_table; + int ret = 0; + + ret = smu_cmn_get_metrics_table(smu, &metrics, true); + if (ret) + return ret; + + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 4); + + gpu_metrics->temperature_gfx = metrics.Current.GfxTemperature; + gpu_metrics->temperature_soc = metrics.Current.SocTemperature; + memcpy(&gpu_metrics->temperature_core[0], + &metrics.Current.CoreTemperature[0], + sizeof(uint16_t) * 4); + gpu_metrics->temperature_l3[0] = metrics.Current.L3Temperature[0]; + + gpu_metrics->average_temperature_gfx = metrics.Average.GfxTemperature; + gpu_metrics->average_temperature_soc = metrics.Average.SocTemperature; + memcpy(&gpu_metrics->average_temperature_core[0], + &metrics.Average.CoreTemperature[0], + sizeof(uint16_t) * 4); + gpu_metrics->average_temperature_l3[0] = metrics.Average.L3Temperature[0]; + + gpu_metrics->average_gfx_activity = metrics.Current.GfxActivity; + gpu_metrics->average_mm_activity = metrics.Current.UvdActivity; + + gpu_metrics->average_socket_power = metrics.Current.CurrentSocketPower; + gpu_metrics->average_cpu_power = metrics.Current.Power[0]; + gpu_metrics->average_soc_power = metrics.Current.Power[1]; + gpu_metrics->average_gfx_power = metrics.Current.Power[2]; + + gpu_metrics->average_cpu_voltage = metrics.Current.Voltage[0]; + gpu_metrics->average_soc_voltage = metrics.Current.Voltage[1]; + gpu_metrics->average_gfx_voltage = metrics.Current.Voltage[2]; + + gpu_metrics->average_cpu_current = metrics.Current.Current[0]; + gpu_metrics->average_soc_current = metrics.Current.Current[1]; + gpu_metrics->average_gfx_current = metrics.Current.Current[2]; + + memcpy(&gpu_metrics->average_core_power[0], + &metrics.Average.CorePower[0], + sizeof(uint16_t) * 4); + + gpu_metrics->average_gfxclk_frequency = metrics.Average.GfxclkFrequency; + gpu_metrics->average_socclk_frequency = metrics.Average.SocclkFrequency; + gpu_metrics->average_uclk_frequency = metrics.Average.MemclkFrequency; + gpu_metrics->average_fclk_frequency = metrics.Average.MemclkFrequency; + gpu_metrics->average_vclk_frequency = metrics.Average.VclkFrequency; + gpu_metrics->average_dclk_frequency = metrics.Average.DclkFrequency; + + gpu_metrics->current_gfxclk = metrics.Current.GfxclkFrequency; + gpu_metrics->current_socclk = metrics.Current.SocclkFrequency; + gpu_metrics->current_uclk = metrics.Current.MemclkFrequency; + gpu_metrics->current_fclk = metrics.Current.MemclkFrequency; + gpu_metrics->current_vclk = metrics.Current.VclkFrequency; + gpu_metrics->current_dclk = metrics.Current.DclkFrequency; + + memcpy(&gpu_metrics->current_coreclk[0], + &metrics.Current.CoreFrequency[0], + sizeof(uint16_t) * 4); + gpu_metrics->current_l3clk[0] = metrics.Current.L3Frequency[0]; + + gpu_metrics->throttle_status = metrics.Current.ThrottlerStatus; + gpu_metrics->indep_throttle_status = + smu_cmn_get_indep_throttler_status(metrics.Current.ThrottlerStatus, + vangogh_throttler_map); + + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + + *table = (void *)gpu_metrics; + + return sizeof(struct gpu_metrics_v2_4); +} + static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, void **table) { @@ -1923,23 +2013,34 @@ static ssize_t vangogh_common_get_gpu_metrics(struct smu_context *smu, { uint32_t if_version; uint32_t smu_version; + uint32_t smu_program; + uint32_t fw_version; int ret = 0; ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) { + if (ret) return ret; - } - if (smu_version >= 0x043F3E00) { - if (if_version < 0x3) - ret = vangogh_get_legacy_gpu_metrics_v2_3(smu, table); + smu_program = (smu_version >> 24) & 0xff; + fw_version = smu_version & 0xffffff; + if (smu_program == 6) { + if (fw_version >= 0x3F0800) + ret = vangogh_get_gpu_metrics_v2_4(smu, table); else ret = vangogh_get_gpu_metrics_v2_3(smu, table); + } else { - if (if_version < 0x3) - ret = vangogh_get_legacy_gpu_metrics(smu, table); - else - ret = vangogh_get_gpu_metrics(smu, table); + if (smu_version >= 0x043F3E00) { + if (if_version < 0x3) + ret = vangogh_get_legacy_gpu_metrics_v2_3(smu, table); + else + ret = vangogh_get_gpu_metrics_v2_3(smu, table); + } else { + if (if_version < 0x3) + ret = vangogh_get_legacy_gpu_metrics(smu, table); + else + ret = vangogh_get_gpu_metrics(smu, table); + } } return ret; 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 8a8ba25c9ad7..c8119491c516 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -262,15 +262,15 @@ static int renoir_get_profiling_clk_mask(struct smu_context *smu, /* mclk levels are in reverse order */ *mclk_mask = NUM_MEMCLK_DPM_LEVELS - 1; } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { - if(sclk_mask) + if (sclk_mask) /* The sclk as gfxclk and has three level about max/min/current */ *sclk_mask = 3 - 1; - if(mclk_mask) + if (mclk_mask) /* mclk levels are in reverse order */ *mclk_mask = 0; - if(soc_mask) + if (soc_mask) *soc_mask = NUM_SOCCLK_DPM_LEVELS - 1; } @@ -1197,7 +1197,7 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->AverageUvdActivity / 100; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1)) && (adev->pm.fw_version >= 0x40000f)) || ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0)) && (adev->pm.fw_version >= 0x373200))) *value = metrics->CurrentSocketPower << 8; @@ -1297,9 +1297,9 @@ static int renoir_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = renoir_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; @@ -1315,6 +1315,7 @@ static int renoir_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; 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 c788aa7a99a9..5e408a195860 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 @@ -205,7 +205,8 @@ int smu_v12_0_set_default_dpm_tables(struct smu_context *smu) return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); } -int smu_v12_0_mode2_reset(struct smu_context *smu){ +int smu_v12_0_mode2_reset(struct smu_context *smu) +{ return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, SMU_RESET_MODE_2, NULL); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index e80f122d8aec..cc3169400c9b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -94,8 +94,7 @@ */ #define SUPPORT_BAD_CHANNEL_INFO_MSG_VERSION 0x00443300 -static const struct smu_temperature_range smu13_thermal_policy[] = -{ +static const struct smu_temperature_range smu13_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; @@ -196,7 +195,7 @@ static const struct cmn2asic_mapping aldebaran_feature_mask_map[SMU_FEATURE_COUN ALDEBARAN_FEA_MAP(SMU_FEATURE_FW_CTF_BIT, FEATURE_FW_CTF_BIT), ALDEBARAN_FEA_MAP(SMU_FEATURE_THERMAL_BIT, FEATURE_THERMAL_BIT), ALDEBARAN_FEA_MAP(SMU_FEATURE_OUT_OF_BAND_MONITOR_BIT, FEATURE_OUT_OF_BAND_MONITOR_BIT), - ALDEBARAN_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT,FEATURE_XGMI_PER_LINK_PWR_DWN), + ALDEBARAN_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT, FEATURE_XGMI_PER_LINK_PWR_DWN), ALDEBARAN_FEA_MAP(SMU_FEATURE_DF_CSTATE_BIT, FEATURE_DF_CSTATE), }; @@ -580,7 +579,7 @@ static int aldebaran_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; @@ -626,9 +625,10 @@ static int aldebaran_get_smu_metrics_data(struct smu_context *smu, break; case METRICS_AVERAGE_SOCKETPOWER: /* Valid power data is available only from primary die */ - *value = aldebaran_is_primary(smu) ? - metrics->AverageSocketPower << 8 : - 0; + if (aldebaran_is_primary(smu)) + *value = metrics->AverageSocketPower << 8; + else + ret = -EOPNOTSUPP; break; case METRICS_TEMPERATURE_EDGE: *value = metrics->TemperatureEdge * @@ -1095,16 +1095,6 @@ static int aldebaran_get_current_activity_percent(struct smu_context *smu, return ret; } -static int aldebaran_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return aldebaran_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, - value); -} - static int aldebaran_thermal_get_temperature(struct smu_context *smu, enum amd_pp_sensors sensor, uint32_t *value) @@ -1158,8 +1148,10 @@ static int aldebaran_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: - ret = aldebaran_get_gpu_power(smu, (uint32_t *)data); + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: + ret = aldebaran_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: @@ -1184,6 +1176,7 @@ static int aldebaran_read_sensor(struct smu_context *smu, ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1525,7 +1518,6 @@ static int aldebaran_i2c_xfer(struct i2c_adapter *i2c_adap, } mutex_lock(&adev->pm.mutex); r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true); - mutex_unlock(&adev->pm.mutex); if (r) goto fail; @@ -1542,6 +1534,7 @@ static int aldebaran_i2c_xfer(struct i2c_adapter *i2c_adap, } r = num_msgs; fail: + mutex_unlock(&adev->pm.mutex); kfree(req); return r; } @@ -1906,8 +1899,7 @@ static int aldebaran_mode1_reset(struct smu_context *smu) smu_cmn_get_smc_version(smu, NULL, &smu_version); if (smu_version < 0x00440700) { ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL); - } - else { + } else { /* fatal error triggered by ras, PMFW supports the flag from 68.44.0 */ if ((smu_version >= 0x00442c00) && ras && @@ -2116,7 +2108,7 @@ static const struct pptable_funcs aldebaran_ppt_funcs = { .register_irq_handler = smu_v13_0_register_irq_handler, .set_azalia_d3_pme = smu_v13_0_set_azalia_d3_pme, .get_max_sustainable_clocks_by_dc = smu_v13_0_get_max_sustainable_clocks_by_dc, - .baco_is_support= aldebaran_is_baco_supported, + .baco_is_support = aldebaran_is_baco_supported, .get_dpm_ultimate_freq = smu_v13_0_get_dpm_ultimate_freq, .set_soft_freq_limited_range = aldebaran_set_soft_freq_limited_range, .od_edit_dpm_table = aldebaran_usr_edit_dpm_table, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 3856da6c3f3d..f1282fc4b90a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -83,7 +83,6 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin"); #define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE static const int link_width[] = {0, 1, 2, 4, 8, 12, 16}; -static const int link_speed[] = {25, 50, 80, 160}; const int pmfw_decoded_link_speed[5] = {1, 2, 3, 4, 5}; const int pmfw_decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16}; @@ -1121,7 +1120,7 @@ smu_v13_0_display_clock_voltage_request(struct smu_context *smu, ret = smu_v13_0_set_hard_freq_limited_range(smu, clk_select, clk_freq, 0); - if(clk_select == SMU_UCLK) + if (clk_select == SMU_UCLK) smu->hard_min_uclk_req_from_dal = clk_freq; } @@ -1437,8 +1436,7 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev, return 0; } -static const struct amdgpu_irq_src_funcs smu_v13_0_irq_funcs = -{ +static const struct amdgpu_irq_src_funcs smu_v13_0_irq_funcs = { .set = smu_v13_0_set_irq_state, .process = smu_v13_0_irq_process, }; @@ -1933,7 +1931,7 @@ static int smu_v13_0_get_dpm_level_count(struct smu_context *smu, ret = smu_v13_0_get_dpm_freq_by_index(smu, clk_type, 0xff, value); /* SMU v13.0.2 FW returns 0 based max level, increment by one for it */ - if((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) && (!ret && value)) + if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) && (!ret && value)) ++(*value); return ret; @@ -2264,7 +2262,7 @@ int smu_v13_0_baco_set_state(struct smu_context *smu, if (state == SMU_BACO_STATE_ENTER) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, - smu_baco->maco_support ? + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? BACO_SEQ_BAMACO : BACO_SEQ_BACO, NULL); } else { @@ -2424,3 +2422,51 @@ int smu_v13_0_mode1_reset(struct smu_context *smu) return ret; } + +int smu_v13_0_update_pcie_parameters(struct smu_context *smu, + uint32_t pcie_gen_cap, + uint32_t pcie_width_cap) +{ + struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; + struct smu_13_0_pcie_table *pcie_table = + &dpm_context->dpm_tables.pcie_table; + int num_of_levels = pcie_table->num_of_link_levels; + uint32_t smu_pcie_arg; + int ret, i; + + if (!amdgpu_device_pcie_dynamic_switching_supported()) { + if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap) + pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1]; + + if (pcie_table->pcie_lane[num_of_levels - 1] < pcie_width_cap) + pcie_width_cap = pcie_table->pcie_lane[num_of_levels - 1]; + + /* Force all levels to use the same settings */ + for (i = 0; i < num_of_levels; i++) { + pcie_table->pcie_gen[i] = pcie_gen_cap; + pcie_table->pcie_lane[i] = pcie_width_cap; + } + } else { + for (i = 0; i < num_of_levels; i++) { + if (pcie_table->pcie_gen[i] > pcie_gen_cap) + pcie_table->pcie_gen[i] = pcie_gen_cap; + if (pcie_table->pcie_lane[i] > pcie_width_cap) + pcie_table->pcie_lane[i] = pcie_width_cap; + } + } + + for (i = 0; i < num_of_levels; i++) { + smu_pcie_arg = i << 16; + smu_pcie_arg |= pcie_table->pcie_gen[i] << 8; + smu_pcie_arg |= pcie_table->pcie_lane[i]; + + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_OverridePcieParameters, + smu_pcie_arg, + NULL); + if (ret) + return ret; + } + + return 0; +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 124287cbbff8..8b7403ba89d7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -96,6 +96,14 @@ */ #define SUPPORT_ECCTABLE_SMU_13_0_10_VERSION 0x00502200 +#define PP_OD_FEATURE_GFXCLK_FMIN 0 +#define PP_OD_FEATURE_GFXCLK_FMAX 1 +#define PP_OD_FEATURE_UCLK_FMIN 2 +#define PP_OD_FEATURE_UCLK_FMAX 3 +#define PP_OD_FEATURE_GFX_VF_CURVE 4 + +#define LINK_SPEED_MAX 3 + static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -332,10 +340,13 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) table_context->power_play_table; struct smu_baco_context *smu_baco = &smu->smu_baco; PPTable_t *pptable = smu->smu_table.driver_pptable; +#if 0 + PPTable_t *pptable = smu->smu_table.driver_pptable; const OverDriveLimits_t * const overdrive_upperlimits = &pptable->SkuTable.OverDriveLimitsBasicMax; const OverDriveLimits_t * const overdrive_lowerlimits = &pptable->SkuTable.OverDriveLimitsMin; +#endif if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC) smu->dc_controlled_by_gpio = true; @@ -347,18 +358,30 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) smu_baco->maco_support = true; + /* + * We are in the transition to a new OD mechanism. + * Disable the OD feature support for SMU13 temporarily. + * TODO: get this reverted when new OD mechanism online + */ +#if 0 if (!overdrive_lowerlimits->FeatureCtrlMask || !overdrive_upperlimits->FeatureCtrlMask) smu->od_enabled = false; - table_context->thermal_controller_type = - powerplay_table->thermal_controller_type; - /* * Instead of having its own buffer space and get overdrive_table copied, * smu->od_settings just points to the actual overdrive_table */ smu->od_settings = &powerplay_table->overdrive_table; +#else + smu->od_enabled = false; +#endif + + table_context->thermal_controller_type = + powerplay_table->thermal_controller_type; + + smu->adev->pm.no_fan = + !(pptable->SkuTable.FeaturesToRun[0] & (1 << FEATURE_FAN_CONTROL_BIT)); return 0; } @@ -932,7 +955,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_0_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -976,6 +999,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1043,7 +1067,6 @@ static bool smu_v13_0_0_is_od_feature_supported(struct smu_context *smu, static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, int od_feature_bit, - bool lower_boundary, int32_t *min, int32_t *max) { @@ -1055,29 +1078,28 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, int32_t od_min_setting, od_max_setting; switch (od_feature_bit) { - case PP_OD_FEATURE_GFXCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->GfxclkFmin; - od_max_setting = overdrive_upperlimits->GfxclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->GfxclkFmax; - od_max_setting = overdrive_upperlimits->GfxclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMIN: + od_min_setting = overdrive_lowerlimits->GfxclkFmin; + od_max_setting = overdrive_upperlimits->GfxclkFmin; break; - case PP_OD_FEATURE_UCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->UclkFmin; - od_max_setting = overdrive_upperlimits->UclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->UclkFmax; - od_max_setting = overdrive_upperlimits->UclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMAX: + od_min_setting = overdrive_lowerlimits->GfxclkFmax; + od_max_setting = overdrive_upperlimits->GfxclkFmax; break; - case PP_OD_FEATURE_GFX_VF_CURVE_BIT: + case PP_OD_FEATURE_UCLK_FMIN: + od_min_setting = overdrive_lowerlimits->UclkFmin; + od_max_setting = overdrive_upperlimits->UclkFmin; + break; + case PP_OD_FEATURE_UCLK_FMAX: + od_min_setting = overdrive_lowerlimits->UclkFmax; + od_max_setting = overdrive_upperlimits->UclkFmax; + break; + case PP_OD_FEATURE_GFX_VF_CURVE: od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary; od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary; break; default: + od_min_setting = od_max_setting = INT_MAX; break; } @@ -1140,7 +1162,6 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, (OverDriveTableExternal_t *)smu->smu_table.overdrive_table; struct smu_13_0_dpm_table *single_dpm_table; struct smu_13_0_pcie_table *pcie_table; - const int link_width[] = {0, 1, 2, 4, 8, 12, 16}; uint32_t gen_speed, lane_width; int i, curr_freq, size = 0; int32_t min_value, max_value; @@ -1256,7 +1277,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, (pcie_table->pcie_lane[i] == 6) ? "x16" : "", pcie_table->clk_freq[i], (gen_speed == DECODE_GEN_SPEED(pcie_table->pcie_gen[i])) && - (lane_width == DECODE_LANE_WIDTH(link_width[pcie_table->pcie_lane[i]])) ? + (lane_width == DECODE_LANE_WIDTH(pcie_table->pcie_lane[i])) ? "*" : ""); break; @@ -1304,13 +1325,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &min_value, NULL); smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", @@ -1319,13 +1338,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &min_value, NULL); smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", @@ -1334,8 +1351,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &min_value, &max_value); size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", @@ -1359,7 +1375,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, OverDriveTableExternal_t *od_table = (OverDriveTableExternal_t *)table_context->overdrive_table; struct amdgpu_device *adev = smu->adev; - uint32_t offset_of_featurectrlmask; + uint32_t offset_of_voltageoffset; int32_t minimum, maximum; uint32_t feature_ctrlmask; int i, ret = 0; @@ -1380,8 +1396,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1397,8 +1412,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1443,8 +1457,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1460,8 +1473,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1502,8 +1514,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, return -EINVAL; smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &minimum, &maximum); if (input[1] < minimum || @@ -1533,10 +1544,10 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, * It does not contain actual informations about user's custom * settings. Thus we do not cache it. */ - offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask); - if (memcmp((u8 *)od_table + offset_of_featurectrlmask, - table_context->user_overdrive_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) { + offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary); + if (memcmp((u8 *)od_table + offset_of_voltageoffset, + table_context->user_overdrive_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) { smu_v13_0_0_dump_od_table(smu, od_table); ret = smu_v13_0_0_upload_overdrive_table(smu, od_table); @@ -1546,9 +1557,9 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, } od_table->OverDriveTable.FeatureCtrlMask = 0; - memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask, - (u8 *)od_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask); + memcpy(table_context->user_overdrive_table + offset_of_voltageoffset, + (u8 *)od_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset); if (!memcmp(table_context->user_overdrive_table, table_context->boot_overdrive_table, @@ -1645,37 +1656,6 @@ static int smu_v13_0_0_force_clk_levels(struct smu_context *smu, return ret; } -static int smu_v13_0_0_update_pcie_parameters(struct smu_context *smu, - uint32_t pcie_gen_cap, - uint32_t pcie_width_cap) -{ - struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; - struct smu_13_0_pcie_table *pcie_table = - &dpm_context->dpm_tables.pcie_table; - uint32_t smu_pcie_arg; - int ret, i; - - for (i = 0; i < pcie_table->num_of_link_levels; i++) { - if (pcie_table->pcie_gen[i] > pcie_gen_cap) - pcie_table->pcie_gen[i] = pcie_gen_cap; - if (pcie_table->pcie_lane[i] > pcie_width_cap) - pcie_table->pcie_lane[i] = pcie_width_cap; - - smu_pcie_arg = i << 16; - smu_pcie_arg |= pcie_table->pcie_gen[i] << 8; - smu_pcie_arg |= pcie_table->pcie_lane[i]; - - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_OverridePcieParameters, - smu_pcie_arg, - NULL); - if (ret) - return ret; - } - - return 0; -} - static const struct smu_temperature_range smu13_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, @@ -1765,7 +1745,7 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency; gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency; - gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK]; + gpu_metrics->current_gfxclk = gpu_metrics->average_gfxclk_frequency; gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK]; gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK]; gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0]; @@ -1782,7 +1762,10 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = metrics->AvgFanRpm; gpu_metrics->pcie_link_width = metrics->PcieWidth; - gpu_metrics->pcie_link_speed = metrics->PcieRate; + if ((metrics->PcieRate - 1) > LINK_SPEED_MAX) + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1); + else + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate); gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); @@ -2228,7 +2211,8 @@ static int smu_v13_0_0_baco_enter(struct smu_context *smu) if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) return smu_v13_0_baco_set_armd3_sequence(smu, - smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO); else return smu_v13_0_baco_enter(smu); } @@ -2320,7 +2304,6 @@ static int smu_v13_0_0_i2c_xfer(struct i2c_adapter *i2c_adap, } mutex_lock(&adev->pm.mutex); r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true); - mutex_unlock(&adev->pm.mutex); if (r) goto fail; @@ -2337,6 +2320,7 @@ static int smu_v13_0_0_i2c_xfer(struct i2c_adapter *i2c_adap, } r = num_msgs; fail: + mutex_unlock(&adev->pm.mutex); kfree(req); return r; } @@ -2654,7 +2638,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = { .feature_is_enabled = smu_cmn_feature_is_enabled, .print_clk_levels = smu_v13_0_0_print_clk_levels, .force_clk_levels = smu_v13_0_0_force_clk_levels, - .update_pcie_parameters = smu_v13_0_0_update_pcie_parameters, + .update_pcie_parameters = smu_v13_0_update_pcie_parameters, .get_thermal_temperature_range = smu_v13_0_0_get_thermal_temperature_range, .register_irq_handler = smu_v13_0_register_irq_handler, .enable_thermal_alert = smu_v13_0_enable_thermal_alert, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c index ef37dda9908f..626591f54bc4 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -257,7 +257,7 @@ static ssize_t smu_v13_0_4_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_gfx_activity = metrics.GfxActivity; gpu_metrics->average_mm_activity = metrics.UvdActivity; - gpu_metrics->average_socket_power = metrics.CurrentSocketPower; + gpu_metrics->average_socket_power = metrics.AverageSocketPower; gpu_metrics->average_gfx_power = metrics.Power[0]; gpu_metrics->average_soc_power = metrics.Power[1]; memcpy(&gpu_metrics->average_core_power[0], @@ -321,6 +321,9 @@ static int smu_v13_0_4_get_smu_metrics_data(struct smu_context *smu, *value = metrics->UvdActivity; break; case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->AverageSocketPower << 8) / 1000; + break; + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -569,12 +572,18 @@ static int smu_v13_0_4_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_4_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = smu_v13_0_4_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: ret = smu_v13_0_4_get_smu_metrics_data(smu, METRICS_TEMPERATURE_EDGE, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c index 42f110602eb1..c6e7c2115a26 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c @@ -75,7 +75,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_5_message_map[SMU_MSG_MAX_COUNT] = MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), - MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu , 1), + MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1), MSG_MAP(GetGfxclkFrequency, PPSMC_MSG_GetGfxclkFrequency, 1), MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 1), @@ -288,7 +288,7 @@ static int smu_v13_0_5_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->UvdActivity; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -332,9 +332,9 @@ static int smu_v13_0_5_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = smu_v13_0_5_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; @@ -388,6 +388,7 @@ static int smu_v13_0_5_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 6ef12252beb5..6ed9cd0a1e4e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -80,17 +80,23 @@ /* possible frequency drift (1Mhz) */ #define EPSILON 1 -#define smnPCIE_ESM_CTRL 0x193D0 -#define smnPCIE_LC_LINK_WIDTH_CNTL 0x1ab40288 +#define smnPCIE_ESM_CTRL 0x93D0 +#define smnPCIE_LC_LINK_WIDTH_CNTL 0x1a340288 #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4 +#define MAX_LINK_WIDTH 6 + +#define smnPCIE_LC_SPEED_CNTL 0x1a340290 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5 +#define LINK_SPEED_MAX 4 static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), - MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 1), - MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 1), + MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0), + MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0), MSG_MAP(RequestI2cTransaction, PPSMC_MSG_RequestI2cTransaction, 0), MSG_MAP(GetMetricsTable, PPSMC_MSG_GetMetricsTable, 1), MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1), @@ -101,8 +107,8 @@ static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COU MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0), MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0), MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0), - MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 0), - MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 0), + MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 1), + MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 1), MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1), MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0), MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 1), @@ -121,8 +127,8 @@ static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COU MSG_MAP(EnableDeterminism, PPSMC_MSG_EnableDeterminism, 0), MSG_MAP(DisableDeterminism, PPSMC_MSG_DisableDeterminism, 0), MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), - MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxDpmFreq, 0), - MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxDpmFreq, 0), + MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxDpmFreq, 1), + MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxDpmFreq, 1), MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxClk, 0), MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 0), MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareForDriverUnload, 0), @@ -325,14 +331,24 @@ static int smu_v13_0_6_setup_driver_pptable(struct smu_context *smu) MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table; struct PPTable_t *pptable = (struct PPTable_t *)smu_table->driver_pptable; - int ret; - int i; + int ret, i, retry = 100; /* Store one-time values in driver PPTable */ if (!pptable->Init) { - ret = smu_v13_0_6_get_metrics_table(smu, NULL, false); - if (ret) - return ret; + while (retry--) { + ret = smu_v13_0_6_get_metrics_table(smu, NULL, true); + if (ret) + return ret; + + /* Ensure that metrics have been updated */ + if (metrics->AccumulationCounter) + break; + + usleep_range(1000, 1100); + } + + if (!retry) + return -ETIME; pptable->MaxSocketPowerLimit = SMUQ10_TO_UINT(metrics->MaxSocketPowerLimit); @@ -704,20 +720,23 @@ static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_MEMACTIVITY: *value = SMUQ10_TO_UINT(metrics->DramBandwidthUtilization); break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = SMUQ10_TO_UINT(metrics->SocketPower) << 8; break; case METRICS_TEMPERATURE_HOTSPOT: - *value = SMUQ10_TO_UINT(metrics->MaxSocketTemperature); + *value = SMUQ10_TO_UINT(metrics->MaxSocketTemperature) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; case METRICS_TEMPERATURE_MEM: - *value = SMUQ10_TO_UINT(metrics->MaxHbmTemperature); + *value = SMUQ10_TO_UINT(metrics->MaxHbmTemperature) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; /* This is the max of all VRs and not just SOC VR. * No need to define another data type for the same. */ case METRICS_TEMPERATURE_VRSOC: - *value = SMUQ10_TO_UINT(metrics->MaxVrTemperature); + *value = SMUQ10_TO_UINT(metrics->MaxVrTemperature) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; default: *value = UINT_MAX; @@ -772,8 +791,6 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, struct smu_13_0_dpm_table *single_dpm_table; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; struct smu_13_0_dpm_context *dpm_context = NULL; - uint32_t display_levels; - uint32_t freq_values[3] = { 0 }; uint32_t min_clk, max_clk; smu_cmn_get_sysfs_buf(&buf, &size); @@ -798,50 +815,24 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, return ret; } - single_dpm_table = &(dpm_context->dpm_tables.gfx_table); - ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, - "Attempt to get gfx clk levels Failed!"); - return ret; - } - - display_levels = clocks.num_levels; - min_clk = pstate_table->gfxclk_pstate.curr.min; max_clk = pstate_table->gfxclk_pstate.curr.max; - freq_values[0] = min_clk; - freq_values[1] = max_clk; - - /* fine-grained dpm has only 2 levels */ - if (now > min_clk && now < max_clk) { - display_levels = clocks.num_levels + 1; - freq_values[2] = max_clk; - freq_values[1] = now; - } - - /* - * For DPM disabled case, there will be only one clock level. - * And it's safe to assume that is always the current clock. - */ - if (display_levels == clocks.num_levels) { - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at( - buf, size, "%d: %uMhz %s\n", i, - freq_values[i], - (clocks.num_levels == 1) ? - "*" : - (smu_v13_0_6_freqs_in_same_level( - freq_values[i], now) ? - "*" : - "")); + if (!smu_v13_0_6_freqs_in_same_level(now, min_clk) && + !smu_v13_0_6_freqs_in_same_level(now, max_clk)) { + size += sysfs_emit_at(buf, size, "0: %uMhz\n", + min_clk); + size += sysfs_emit_at(buf, size, "1: %uMhz *\n", + now); + size += sysfs_emit_at(buf, size, "2: %uMhz\n", + max_clk); } else { - for (i = 0; i < display_levels; i++) - size += sysfs_emit_at(buf, size, - "%d: %uMhz %s\n", i, - freq_values[i], - i == 1 ? "*" : ""); + size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", + min_clk, + smu_v13_0_6_freqs_in_same_level(now, min_clk) ? "*" : ""); + size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", + max_clk, + smu_v13_0_6_freqs_in_same_level(now, max_clk) ? "*" : ""); } break; @@ -1154,15 +1145,6 @@ static int smu_v13_0_6_get_current_activity_percent(struct smu_context *smu, return ret; } -static int smu_v13_0_6_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return smu_v13_0_6_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, - value); -} - static int smu_v13_0_6_thermal_get_temperature(struct smu_context *smu, enum amd_pp_sensors sensor, uint32_t *value) @@ -1208,8 +1190,10 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: - ret = smu_v13_0_6_get_gpu_power(smu, (uint32_t *)data); + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = smu_v13_0_6_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: @@ -1235,6 +1219,7 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; @@ -1248,9 +1233,9 @@ static int smu_v13_0_6_get_power_limit(struct smu_context *smu, uint32_t *default_power_limit, uint32_t *max_power_limit) { - struct smu_table_context *smu_table = &smu->smu_table; - struct PPTable_t *pptable = - (struct PPTable_t *)smu_table->driver_pptable; + struct smu_table_context *smu_table = &smu->smu_table; + struct PPTable_t *pptable = + (struct PPTable_t *)smu_table->driver_pptable; uint32_t power_limit = 0; int ret; @@ -1366,8 +1351,7 @@ static int smu_v13_0_6_set_irq_state(struct amdgpu_device *adev, return 0; } -static const struct amdgpu_irq_src_funcs smu_v13_0_6_irq_funcs = -{ +static const struct amdgpu_irq_src_funcs smu_v13_0_6_irq_funcs = { .set = smu_v13_0_6_set_irq_state, .process = smu_v13_0_6_irq_process, }; @@ -1414,6 +1398,9 @@ static int smu_v13_0_6_system_features_control(struct smu_context *smu, struct amdgpu_device *adev = smu->adev; int ret = 0; + if (amdgpu_sriov_vf(adev)) + return 0; + if (enable) { if (!(adev->flags & AMD_IS_APU)) ret = smu_v13_0_system_features_control(smu, enable); @@ -1763,7 +1750,6 @@ static int smu_v13_0_6_i2c_xfer(struct i2c_adapter *i2c_adap, } mutex_lock(&adev->pm.mutex); r = smu_v13_0_6_request_i2c_xfer(smu, req); - mutex_unlock(&adev->pm.mutex); if (r) goto fail; @@ -1780,6 +1766,7 @@ static int smu_v13_0_6_i2c_xfer(struct i2c_adapter *i2c_adap, } r = num_msgs; fail: + mutex_unlock(&adev->pm.mutex); kfree(req); return r; } @@ -1948,6 +1935,7 @@ smu_v13_0_6_get_current_pcie_link_width_level(struct smu_context *smu) static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; + uint32_t speed_level; uint32_t esm_ctrl; /* TODO: confirm this on real target */ @@ -1955,7 +1943,13 @@ static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu) if ((esm_ctrl >> 15) & 0x1FFFF) return (((esm_ctrl >> 8) & 0x3F) + 128); - return smu_v13_0_get_current_pcie_link_speed(smu); + speed_level = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & + PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) + >> PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; + if (speed_level > LINK_SPEED_MAX) + speed_level = 0; + + return pcie_gen_to_speed(speed_level + 1); } static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table) @@ -1966,6 +1960,7 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table struct amdgpu_device *adev = smu->adev; int ret = 0, inst0, xcc0; MetricsTable_t *metrics; + u16 link_width_level; inst0 = adev->sdma.instance[0].aid_id; xcc0 = GET_INST(GC, 0); @@ -1993,9 +1988,8 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table gpu_metrics->average_socket_power = SMUQ10_TO_UINT(metrics->SocketPower); - /* Energy is reported in 15.625mJ units */ - gpu_metrics->energy_accumulator = - SMUQ10_TO_UINT(metrics->SocketEnergyAcc); + /* Energy counter reported in 15.259uJ (2^-16) units */ + gpu_metrics->energy_accumulator = metrics->SocketEnergyAcc; gpu_metrics->current_gfxclk = SMUQ10_TO_UINT(metrics->GfxclkFrequency[xcc0]); @@ -2017,8 +2011,12 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table gpu_metrics->throttle_status = 0; if (!(adev->flags & AMD_IS_APU)) { + link_width_level = smu_v13_0_6_get_current_pcie_link_width_level(smu); + if (link_width_level > MAX_LINK_WIDTH) + link_width_level = 0; + gpu_metrics->pcie_link_width = - smu_v13_0_6_get_current_pcie_link_width_level(smu); + DECODE_LANE_WIDTH(link_width_level); gpu_metrics->pcie_link_speed = smu_v13_0_6_get_current_pcie_link_speed(smu); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index cda4e818aab7..94ef5b4d116d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -72,6 +72,14 @@ #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000 +#define PP_OD_FEATURE_GFXCLK_FMIN 0 +#define PP_OD_FEATURE_GFXCLK_FMAX 1 +#define PP_OD_FEATURE_UCLK_FMIN 2 +#define PP_OD_FEATURE_UCLK_FMAX 3 +#define PP_OD_FEATURE_GFX_VF_CURVE 4 + +#define LINK_SPEED_MAX 3 + static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -323,10 +331,12 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu) struct smu_baco_context *smu_baco = &smu->smu_baco; PPTable_t *smc_pptable = table_context->driver_pptable; BoardTable_t *BoardTable = &smc_pptable->BoardTable; +#if 0 const OverDriveLimits_t * const overdrive_upperlimits = &smc_pptable->SkuTable.OverDriveLimitsBasicMax; const OverDriveLimits_t * const overdrive_lowerlimits = &smc_pptable->SkuTable.OverDriveLimitsMin; +#endif if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC) smu->dc_controlled_by_gpio = true; @@ -338,18 +348,22 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu) if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) smu_baco->maco_support = true; +#if 0 if (!overdrive_lowerlimits->FeatureCtrlMask || !overdrive_upperlimits->FeatureCtrlMask) smu->od_enabled = false; - table_context->thermal_controller_type = - powerplay_table->thermal_controller_type; - /* * Instead of having its own buffer space and get overdrive_table copied, * smu->od_settings just points to the actual overdrive_table */ smu->od_settings = &powerplay_table->overdrive_table; +#else + smu->od_enabled = false; +#endif + + table_context->thermal_controller_type = + powerplay_table->thermal_controller_type; return 0; } @@ -386,8 +400,7 @@ static int smu_v13_0_7_check_fw_status(struct smu_context *smu) } #ifndef atom_smc_dpm_info_table_13_0_7 -struct atom_smc_dpm_info_table_13_0_7 -{ +struct atom_smc_dpm_info_table_13_0_7 { struct atom_common_table_header table_header; BoardTable_t BoardTable; }; @@ -494,7 +507,7 @@ static int smu_v13_0_7_tables_init(struct smu_context *smu) PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, sizeof(DpmActivityMonitorCoeffIntExternal_t), PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM); + AMDGPU_GEM_DOMAIN_VRAM); SMU_TABLE_INIT(tables, SMU_TABLE_COMBO_PPTABLE, MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); @@ -728,7 +741,7 @@ static int smu_v13_0_7_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics); int ret = 0; @@ -923,7 +936,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_7_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -949,7 +962,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, break; case AMDGPU_PP_SENSOR_GFX_MCLK: ret = smu_v13_0_7_get_smu_metrics_data(smu, - METRICS_AVERAGE_UCLK, + METRICS_CURR_UCLK, (uint32_t *)data); *(uint32_t *)data *= 100; *size = 4; @@ -967,6 +980,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1034,7 +1048,6 @@ static bool smu_v13_0_7_is_od_feature_supported(struct smu_context *smu, static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, int od_feature_bit, - bool lower_boundary, int32_t *min, int32_t *max) { @@ -1046,29 +1059,28 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, int32_t od_min_setting, od_max_setting; switch (od_feature_bit) { - case PP_OD_FEATURE_GFXCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->GfxclkFmin; - od_max_setting = overdrive_upperlimits->GfxclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->GfxclkFmax; - od_max_setting = overdrive_upperlimits->GfxclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMIN: + od_min_setting = overdrive_lowerlimits->GfxclkFmin; + od_max_setting = overdrive_upperlimits->GfxclkFmin; break; - case PP_OD_FEATURE_UCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->UclkFmin; - od_max_setting = overdrive_upperlimits->UclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->UclkFmax; - od_max_setting = overdrive_upperlimits->UclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMAX: + od_min_setting = overdrive_lowerlimits->GfxclkFmax; + od_max_setting = overdrive_upperlimits->GfxclkFmax; + break; + case PP_OD_FEATURE_UCLK_FMIN: + od_min_setting = overdrive_lowerlimits->UclkFmin; + od_max_setting = overdrive_upperlimits->UclkFmin; break; - case PP_OD_FEATURE_GFX_VF_CURVE_BIT: + case PP_OD_FEATURE_UCLK_FMAX: + od_min_setting = overdrive_lowerlimits->UclkFmax; + od_max_setting = overdrive_upperlimits->UclkFmax; + break; + case PP_OD_FEATURE_GFX_VF_CURVE: od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary; od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary; break; default: + od_min_setting = od_max_setting = INT_MAX; break; } @@ -1294,13 +1306,11 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &min_value, NULL); smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", @@ -1309,13 +1319,11 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &min_value, NULL); smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", @@ -1324,8 +1332,7 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &min_value, &max_value); size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", @@ -1349,7 +1356,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, OverDriveTableExternal_t *od_table = (OverDriveTableExternal_t *)table_context->overdrive_table; struct amdgpu_device *adev = smu->adev; - uint32_t offset_of_featurectrlmask; + uint32_t offset_of_voltageoffset; int32_t minimum, maximum; uint32_t feature_ctrlmask; int i, ret = 0; @@ -1370,8 +1377,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1387,8 +1393,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1433,8 +1438,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1450,8 +1454,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1492,8 +1495,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, return -EINVAL; smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &minimum, &maximum); if (input[1] < minimum || @@ -1523,10 +1525,10 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, * It does not contain actual informations about user's custom * settings. Thus we do not cache it. */ - offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask); - if (memcmp((u8 *)od_table + offset_of_featurectrlmask, - table_context->user_overdrive_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) { + offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary); + if (memcmp((u8 *)od_table + offset_of_voltageoffset, + table_context->user_overdrive_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) { smu_v13_0_7_dump_od_table(smu, od_table); ret = smu_v13_0_7_upload_overdrive_table(smu, od_table); @@ -1536,9 +1538,9 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, } od_table->OverDriveTable.FeatureCtrlMask = 0; - memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask, - (u8 *)od_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask); + memcpy(table_context->user_overdrive_table + offset_of_voltageoffset, + (u8 *)od_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset); if (!memcmp(table_context->user_overdrive_table, table_context->boot_overdrive_table, @@ -1635,39 +1637,7 @@ static int smu_v13_0_7_force_clk_levels(struct smu_context *smu, return ret; } -static int smu_v13_0_7_update_pcie_parameters(struct smu_context *smu, - uint32_t pcie_gen_cap, - uint32_t pcie_width_cap) -{ - struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; - struct smu_13_0_pcie_table *pcie_table = - &dpm_context->dpm_tables.pcie_table; - uint32_t smu_pcie_arg; - int ret, i; - - for (i = 0; i < pcie_table->num_of_link_levels; i++) { - if (pcie_table->pcie_gen[i] > pcie_gen_cap) - pcie_table->pcie_gen[i] = pcie_gen_cap; - if (pcie_table->pcie_lane[i] > pcie_width_cap) - pcie_table->pcie_lane[i] = pcie_width_cap; - - smu_pcie_arg = i << 16; - smu_pcie_arg |= pcie_table->pcie_gen[i] << 8; - smu_pcie_arg |= pcie_table->pcie_lane[i]; - - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_OverridePcieParameters, - smu_pcie_arg, - NULL); - if (ret) - return ret; - } - - return 0; -} - -static const struct smu_temperature_range smu13_thermal_policy[] = -{ +static const struct smu_temperature_range smu13_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; @@ -1768,7 +1738,10 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = metrics->AvgFanRpm; gpu_metrics->pcie_link_width = metrics->PcieWidth; - gpu_metrics->pcie_link_speed = metrics->PcieRate; + if ((metrics->PcieRate - 1) > LINK_SPEED_MAX) + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1); + else + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate); gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); @@ -2166,7 +2139,8 @@ static int smu_v13_0_7_baco_enter(struct smu_context *smu) if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) return smu_v13_0_baco_set_armd3_sequence(smu, - smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO); else return smu_v13_0_baco_enter(smu); } @@ -2234,7 +2208,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { .feature_is_enabled = smu_cmn_feature_is_enabled, .print_clk_levels = smu_v13_0_7_print_clk_levels, .force_clk_levels = smu_v13_0_7_force_clk_levels, - .update_pcie_parameters = smu_v13_0_7_update_pcie_parameters, + .update_pcie_parameters = smu_v13_0_update_pcie_parameters, .get_thermal_temperature_range = smu_v13_0_7_get_thermal_temperature_range, .register_irq_handler = smu_v13_0_register_irq_handler, .enable_thermal_alert = smu_v13_0_enable_thermal_alert, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index a1be2029ba4a..2e74d749efdd 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -365,7 +365,7 @@ static int yellow_carp_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->UvdActivity; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -423,9 +423,9 @@ static int yellow_carp_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = yellow_carp_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; @@ -479,6 +479,7 @@ static int yellow_carp_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index 3ecb900e6ecd..12618a583e97 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -39,6 +39,8 @@ #define MP1_C2PMSG_90__CONTENT_MASK 0xFFFFFFFFL +const int link_speed[] = {25, 50, 80, 160, 320, 640}; + #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) #type static const char * const __smu_message_names[] = { @@ -691,7 +693,7 @@ int smu_cmn_feature_set_enabled(struct smu_context *smu, #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(fea) #fea -static const char* __smu_feature_names[] = { +static const char *__smu_feature_names[] = { SMU_FEATURE_MASKS }; @@ -927,7 +929,7 @@ int smu_cmn_get_metrics_table(struct smu_context *smu, void *metrics_table, bool bypass_cache) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size; int ret = 0; @@ -969,7 +971,7 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev) struct metrics_table_header *header = (struct metrics_table_header *)table; uint16_t structure_size; -#define METRICS_VERSION(a, b) ((a << 16) | b ) +#define METRICS_VERSION(a, b) ((a << 16) | b) switch (METRICS_VERSION(frev, crev)) { case METRICS_VERSION(1, 0): @@ -996,6 +998,9 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev) case METRICS_VERSION(2, 3): structure_size = sizeof(struct gpu_metrics_v2_3); break; + case METRICS_VERSION(2, 4): + structure_size = sizeof(struct gpu_metrics_v2_4); + break; default: return; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index d7cd358a53bd..cc590e27d88a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -30,6 +30,14 @@ #define FDO_PWM_MODE_STATIC 1 #define FDO_PWM_MODE_STATIC_RPM 5 +extern const int link_speed[]; + +/* Helper to Convert from PCIE Gen 1/2/3/4/5/6 to 0.1 GT/s speed units */ +static inline int pcie_gen_to_speed(uint32_t gen) +{ + return ((gen == 0) ? link_speed[0] : link_speed[gen - 1]); +} + int smu_cmn_send_msg_without_waiting(struct smu_context *smu, uint16_t msg_index, uint32_t param); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h index ceb13c838067..bcc42abfc768 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h @@ -61,14 +61,14 @@ #define smu_feature_get_enabled_mask(smu, mask) smu_ppt_funcs(get_enabled_mask, -EOPNOTSUPP, smu, mask) #define smu_feature_is_enabled(smu, mask) smu_ppt_funcs(feature_is_enabled, 0, smu, mask) #define smu_disable_all_features_with_exception(smu, mask) smu_ppt_funcs(disable_all_features_with_exception, 0, smu, mask) -#define smu_is_dpm_running(smu) smu_ppt_funcs(is_dpm_running, 0 , smu) +#define smu_is_dpm_running(smu) smu_ppt_funcs(is_dpm_running, 0, smu) #define smu_notify_display_change(smu) smu_ppt_funcs(notify_display_change, 0, smu) #define smu_populate_umd_state_clk(smu) smu_ppt_funcs(populate_umd_state_clk, 0, smu) #define smu_enable_thermal_alert(smu) smu_ppt_funcs(enable_thermal_alert, 0, smu) #define smu_disable_thermal_alert(smu) smu_ppt_funcs(disable_thermal_alert, 0, smu) #define smu_smc_read_sensor(smu, sensor, data, size) smu_ppt_funcs(read_sensor, -EINVAL, smu, sensor, data, size) #define smu_pre_display_config_changed(smu) smu_ppt_funcs(pre_display_config_changed, 0, smu) -#define smu_display_config_changed(smu) smu_ppt_funcs(display_config_changed, 0 , smu) +#define smu_display_config_changed(smu) smu_ppt_funcs(display_config_changed, 0, smu) #define smu_apply_clocks_adjust_rules(smu) smu_ppt_funcs(apply_clocks_adjust_rules, 0, smu) #define smu_notify_smc_display_config(smu) smu_ppt_funcs(notify_smc_display_config, 0, smu) #define smu_run_btc(smu) smu_ppt_funcs(run_btc, 0, smu) |