summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/pm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/pm')
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_pm.c114
-rw-r--r--drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h57
-rw-r--r--drivers/gpu/drm/amd/pm/inc/smu_v11_0.h3
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c34
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c59
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c123
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c86
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c11
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c51
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c63
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c116
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c37
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c63
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h5
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_internal.h4
15 files changed, 609 insertions, 217 deletions
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index b2335a1d3f98..769f58d5ae1a 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -411,7 +411,8 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev,
struct amdgpu_device *adev = drm_to_adev(ddev);
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
struct pp_states_info data;
- int i, buf_len, ret;
+ uint32_t i;
+ int buf_len, ret;
if (amdgpu_in_reset(adev))
return -EPERM;
@@ -433,9 +434,9 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev,
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
- buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums);
+ buf_len = sysfs_emit(buf, "states: %d\n", data.nums);
for (i = 0; i < data.nums; i++)
- buf_len += snprintf(buf + buf_len, PAGE_SIZE, "%d %s\n", i,
+ buf_len += sysfs_emit_at(buf, buf_len, "%d %s\n", i,
(data.states[i] == POWER_STATE_TYPE_INTERNAL_BOOT) ? "boot" :
(data.states[i] == POWER_STATE_TYPE_BATTERY) ? "battery" :
(data.states[i] == POWER_STATE_TYPE_BALANCED) ? "balanced" :
@@ -923,7 +924,7 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
size += amdgpu_dpm_print_clock_levels(adev, OD_RANGE, buf+size);
size += amdgpu_dpm_print_clock_levels(adev, OD_CCLK, buf+size);
} else {
- size = snprintf(buf, PAGE_SIZE, "\n");
+ size = sysfs_emit(buf, "\n");
}
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
@@ -1009,7 +1010,7 @@ static ssize_t amdgpu_get_pp_features(struct device *dev,
if (adev->powerplay.pp_funcs->get_ppfeature_status)
size = amdgpu_dpm_get_ppfeature_status(adev, buf);
else
- size = snprintf(buf, PAGE_SIZE, "\n");
+ size = sysfs_emit(buf, "\n");
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
@@ -1070,7 +1071,7 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct device *dev,
if (adev->powerplay.pp_funcs->print_clock_levels)
size = amdgpu_dpm_print_clock_levels(adev, type, buf);
else
- size = snprintf(buf, PAGE_SIZE, "\n");
+ size = sysfs_emit(buf, "\n");
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
@@ -1469,7 +1470,7 @@ static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
if (adev->powerplay.pp_funcs->get_power_profile_mode)
size = amdgpu_dpm_get_power_profile_mode(adev, buf);
else
- size = snprintf(buf, PAGE_SIZE, "\n");
+ size = sysfs_emit(buf, "\n");
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
@@ -2901,14 +2902,15 @@ static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev,
return sprintf(buf, "%i\n", 0);
}
-static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+
+static ssize_t amdgpu_hwmon_show_power_cap_generic(struct device *dev,
+ struct device_attribute *attr,
+ char *buf,
+ enum pp_power_limit_level pp_limit_level)
{
struct amdgpu_device *adev = dev_get_drvdata(dev);
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
enum pp_power_type power_type = to_sensor_dev_attr(attr)->index;
- enum pp_power_limit_level pp_limit_level = PP_PWR_LIMIT_MAX;
uint32_t limit;
ssize_t size;
int r;
@@ -2918,22 +2920,22 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
if (adev->in_suspend && !adev->in_runpm)
return -EPERM;
+ if ( !(pp_funcs && pp_funcs->get_power_limit))
+ return -ENODATA;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
- if (pp_funcs && pp_funcs->get_power_limit)
- r = pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit,
- pp_limit_level, power_type);
- else
- r = -ENODATA;
+ r = pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit,
+ pp_limit_level, power_type);
if (!r)
- size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
+ size = sysfs_emit(buf, "%u\n", limit * 1000000);
else
- size = snprintf(buf, PAGE_SIZE, "\n");
+ size = sysfs_emit(buf, "\n");
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -2941,85 +2943,31 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
return size;
}
-static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
+
+static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct amdgpu_device *adev = dev_get_drvdata(dev);
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- enum pp_power_type power_type = to_sensor_dev_attr(attr)->index;
- enum pp_power_limit_level pp_limit_level = PP_PWR_LIMIT_CURRENT;
- uint32_t limit;
- ssize_t size;
- int r;
+ return amdgpu_hwmon_show_power_cap_generic(dev, attr, buf, PP_PWR_LIMIT_MAX);
- if (amdgpu_in_reset(adev))
- return -EPERM;
- if (adev->in_suspend && !adev->in_runpm)
- return -EPERM;
-
- r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
- if (r < 0) {
- pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
- return r;
- }
-
- if (pp_funcs && pp_funcs->get_power_limit)
- r = pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit,
- pp_limit_level, power_type);
- else
- r = -ENODATA;
-
- if (!r)
- size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
- else
- size = snprintf(buf, PAGE_SIZE, "\n");
+}
- pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
- pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
+static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return amdgpu_hwmon_show_power_cap_generic(dev, attr, buf, PP_PWR_LIMIT_CURRENT);
- return size;
}
static ssize_t amdgpu_hwmon_show_power_cap_default(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct amdgpu_device *adev = dev_get_drvdata(dev);
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- enum pp_power_type power_type = to_sensor_dev_attr(attr)->index;
- enum pp_power_limit_level pp_limit_level = PP_PWR_LIMIT_DEFAULT;
- uint32_t limit;
- ssize_t size;
- int r;
-
- if (amdgpu_in_reset(adev))
- return -EPERM;
- if (adev->in_suspend && !adev->in_runpm)
- return -EPERM;
+ return amdgpu_hwmon_show_power_cap_generic(dev, attr, buf, PP_PWR_LIMIT_DEFAULT);
- r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
- if (r < 0) {
- pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
- return r;
- }
-
- if (pp_funcs && pp_funcs->get_power_limit)
- r = pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit,
- pp_limit_level, power_type);
- else
- r = -ENODATA;
-
- if (!r)
- size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
- else
- size = snprintf(buf, PAGE_SIZE, "\n");
-
- pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
- pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
-
- return size;
}
+
static ssize_t amdgpu_hwmon_show_power_label(struct device *dev,
struct device_attribute *attr,
char *buf)
diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
index 2f7f688424aa..3e89852e4820 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
@@ -35,6 +35,48 @@
#define SMU_DPM_USER_PROFILE_RESTORE (1 << 0)
+// Power Throttlers
+#define SMU_THROTTLER_PPT0_BIT 0
+#define SMU_THROTTLER_PPT1_BIT 1
+#define SMU_THROTTLER_PPT2_BIT 2
+#define SMU_THROTTLER_PPT3_BIT 3
+#define SMU_THROTTLER_SPL_BIT 4
+#define SMU_THROTTLER_FPPT_BIT 5
+#define SMU_THROTTLER_SPPT_BIT 6
+#define SMU_THROTTLER_SPPT_APU_BIT 7
+
+// Current Throttlers
+#define SMU_THROTTLER_TDC_GFX_BIT 16
+#define SMU_THROTTLER_TDC_SOC_BIT 17
+#define SMU_THROTTLER_TDC_MEM_BIT 18
+#define SMU_THROTTLER_TDC_VDD_BIT 19
+#define SMU_THROTTLER_TDC_CVIP_BIT 20
+#define SMU_THROTTLER_EDC_CPU_BIT 21
+#define SMU_THROTTLER_EDC_GFX_BIT 22
+#define SMU_THROTTLER_APCC_BIT 23
+
+// Temperature
+#define SMU_THROTTLER_TEMP_GPU_BIT 32
+#define SMU_THROTTLER_TEMP_CORE_BIT 33
+#define SMU_THROTTLER_TEMP_MEM_BIT 34
+#define SMU_THROTTLER_TEMP_EDGE_BIT 35
+#define SMU_THROTTLER_TEMP_HOTSPOT_BIT 36
+#define SMU_THROTTLER_TEMP_SOC_BIT 37
+#define SMU_THROTTLER_TEMP_VR_GFX_BIT 38
+#define SMU_THROTTLER_TEMP_VR_SOC_BIT 39
+#define SMU_THROTTLER_TEMP_VR_MEM0_BIT 40
+#define SMU_THROTTLER_TEMP_VR_MEM1_BIT 41
+#define SMU_THROTTLER_TEMP_LIQUID0_BIT 42
+#define SMU_THROTTLER_TEMP_LIQUID1_BIT 43
+#define SMU_THROTTLER_VRHOT0_BIT 44
+#define SMU_THROTTLER_VRHOT1_BIT 45
+#define SMU_THROTTLER_PROCHOT_CPU_BIT 46
+#define SMU_THROTTLER_PROCHOT_GFX_BIT 47
+
+// Other
+#define SMU_THROTTLER_PPM_BIT 56
+#define SMU_THROTTLER_FIT_BIT 57
+
struct smu_hw_power_state {
unsigned int magic;
};
@@ -723,7 +765,10 @@ struct pptable_funcs {
/**
* @get_power_limit: Get the device's power limits.
*/
- int (*get_power_limit)(struct smu_context *smu);
+ int (*get_power_limit)(struct smu_context *smu,
+ uint32_t *current_power_limit,
+ uint32_t *default_power_limit,
+ uint32_t *max_power_limit);
/**
* @get_ppt_limit: Get the device's ppt limits.
@@ -932,7 +977,9 @@ struct pptable_funcs {
* @disable_all_features_with_exception: Disable all features with
* exception to those in &mask.
*/
- int (*disable_all_features_with_exception)(struct smu_context *smu, enum smu_feature_mask mask);
+ int (*disable_all_features_with_exception)(struct smu_context *smu,
+ bool no_hw_disablement,
+ enum smu_feature_mask mask);
/**
* @notify_display_change: Enable fast memory clock switching.
@@ -1185,6 +1232,12 @@ struct pptable_funcs {
*/
int (*wait_for_event)(struct smu_context *smu,
enum smu_event_type event, uint64_t event_arg);
+
+ /**
+ * @sned_hbm_bad_pages_num: message SMU to update bad page number
+ * of SMUBUS table.
+ */
+ int (*send_hbm_bad_pages_num)(struct smu_context *smu, uint32_t size);
};
typedef enum {
diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
index a3b28979bc82..1962a5877191 100644
--- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
@@ -244,6 +244,9 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
int smu_v11_0_baco_enter(struct smu_context *smu);
int smu_v11_0_baco_exit(struct smu_context *smu);
+int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu,
+ enum smu_v11_0_baco_seq baco_seq);
+
int smu_v11_0_mode1_reset(struct smu_context *smu);
int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index b4ea8b233240..ebe672142808 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -688,7 +688,10 @@ static int smu_late_init(void *handle)
return ret;
}
- ret = smu_get_asic_power_limits(smu);
+ ret = smu_get_asic_power_limits(smu,
+ &smu->current_power_limit,
+ &smu->default_power_limit,
+ &smu->max_power_limit);
if (ret) {
dev_err(adev->dev, "Failed to get asic power limits!\n");
return ret;
@@ -1379,15 +1382,20 @@ static int smu_disable_dpms(struct smu_context *smu)
if (smu->uploading_custom_pp_table &&
(adev->asic_type >= CHIP_NAVI10) &&
(adev->asic_type <= CHIP_DIMGREY_CAVEFISH))
- return 0;
+ return smu_disable_all_features_with_exception(smu,
+ true,
+ SMU_FEATURE_COUNT);
/*
* For Sienna_Cichlid, PMFW will handle the features disablement properly
* on BACO in. Driver involvement is unnecessary.
*/
- if ((adev->asic_type == CHIP_SIENNA_CICHLID) &&
+ if (((adev->asic_type == CHIP_SIENNA_CICHLID) ||
+ ((adev->asic_type >= CHIP_NAVI10) && (adev->asic_type <= CHIP_NAVI12))) &&
use_baco)
- return 0;
+ return smu_disable_all_features_with_exception(smu,
+ true,
+ SMU_FEATURE_BACO_BIT);
/*
* For gpu reset, runpm and hibernation through BACO,
@@ -1395,6 +1403,7 @@ static int smu_disable_dpms(struct smu_context *smu)
*/
if (use_baco && smu_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT)) {
ret = smu_disable_all_features_with_exception(smu,
+ false,
SMU_FEATURE_BACO_BIT);
if (ret)
dev_err(adev->dev, "Failed to disable smu features except BACO.\n");
@@ -1444,10 +1453,14 @@ static int smu_hw_fini(void *handle)
if (smu->is_apu) {
smu_powergate_sdma(&adev->smu, true);
- smu_dpm_set_vcn_enable(smu, false);
- smu_dpm_set_jpeg_enable(smu, false);
}
+ smu_dpm_set_vcn_enable(smu, false);
+ smu_dpm_set_jpeg_enable(smu, false);
+
+ adev->vcn.cur_state = AMD_PG_STATE_GATE;
+ adev->jpeg.cur_state = AMD_PG_STATE_GATE;
+
if (!smu->pm_enabled)
return 0;
@@ -2232,6 +2245,15 @@ int smu_get_power_limit(void *handle,
} else {
switch (limit_level) {
case SMU_PPT_LIMIT_CURRENT:
+ if ((smu->adev->asic_type == CHIP_ALDEBARAN) ||
+ (smu->adev->asic_type == CHIP_SIENNA_CICHLID) ||
+ (smu->adev->asic_type == CHIP_NAVY_FLOUNDER) ||
+ (smu->adev->asic_type == CHIP_DIMGREY_CAVEFISH) ||
+ (smu->adev->asic_type == CHIP_BEIGE_GOBY))
+ ret = smu_get_asic_power_limits(smu,
+ &smu->current_power_limit,
+ NULL,
+ NULL);
*limit = smu->current_power_limit;
break;
case SMU_PPT_LIMIT_DEFAULT:
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 5959019f51ad..094df6f87cfc 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
@@ -211,6 +211,26 @@ static const struct cmn2asic_mapping arcturus_workload_map[PP_SMC_POWER_PROFILE_
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
};
+static const uint8_t arcturus_throttler_map[] = {
+ [THROTTLER_TEMP_EDGE_BIT] = (SMU_THROTTLER_TEMP_EDGE_BIT),
+ [THROTTLER_TEMP_HOTSPOT_BIT] = (SMU_THROTTLER_TEMP_HOTSPOT_BIT),
+ [THROTTLER_TEMP_MEM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
+ [THROTTLER_TEMP_VR_GFX_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
+ [THROTTLER_TEMP_VR_MEM_BIT] = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
+ [THROTTLER_TEMP_VR_SOC_BIT] = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
+ [THROTTLER_TDC_GFX_BIT] = (SMU_THROTTLER_TDC_GFX_BIT),
+ [THROTTLER_TDC_SOC_BIT] = (SMU_THROTTLER_TDC_SOC_BIT),
+ [THROTTLER_PPT0_BIT] = (SMU_THROTTLER_PPT0_BIT),
+ [THROTTLER_PPT1_BIT] = (SMU_THROTTLER_PPT1_BIT),
+ [THROTTLER_PPT2_BIT] = (SMU_THROTTLER_PPT2_BIT),
+ [THROTTLER_PPT3_BIT] = (SMU_THROTTLER_PPT3_BIT),
+ [THROTTLER_PPM_BIT] = (SMU_THROTTLER_PPM_BIT),
+ [THROTTLER_FIT_BIT] = (SMU_THROTTLER_FIT_BIT),
+ [THROTTLER_APCC_BIT] = (SMU_THROTTLER_APCC_BIT),
+ [THROTTLER_VRHOT0_BIT] = (SMU_THROTTLER_VRHOT0_BIT),
+ [THROTTLER_VRHOT1_BIT] = (SMU_THROTTLER_VRHOT1_BIT),
+};
+
static int arcturus_tables_init(struct smu_context *smu)
{
struct smu_table_context *smu_table = &smu->smu_table;
@@ -237,7 +257,7 @@ static int arcturus_tables_init(struct smu_context *smu)
return -ENOMEM;
smu_table->metrics_time = 0;
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_1);
+ smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_3);
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table) {
kfree(smu_table->metrics_table);
@@ -1174,7 +1194,10 @@ static int arcturus_get_fan_parameters(struct smu_context *smu)
return 0;
}
-static int arcturus_get_power_limit(struct smu_context *smu)
+static int arcturus_get_power_limit(struct smu_context *smu,
+ uint32_t *current_power_limit,
+ uint32_t *default_power_limit,
+ uint32_t *max_power_limit)
{
struct smu_11_0_powerplay_table *powerplay_table =
(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
@@ -1190,17 +1213,24 @@ static int arcturus_get_power_limit(struct smu_context *smu)
power_limit =
pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
}
- smu->current_power_limit = smu->default_power_limit = power_limit;
- if (smu->od_enabled) {
- od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+ if (current_power_limit)
+ *current_power_limit = power_limit;
+ if (default_power_limit)
+ *default_power_limit = power_limit;
+
+ if (max_power_limit) {
+ if (smu->od_enabled) {
+ od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
- dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+ dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+
+ power_limit *= (100 + od_percent);
+ power_limit /= 100;
+ }
- power_limit *= (100 + od_percent);
- power_limit /= 100;
+ *max_power_limit = power_limit;
}
- smu->max_power_limit = power_limit;
return 0;
}
@@ -2278,8 +2308,8 @@ static ssize_t arcturus_get_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v1_1 *gpu_metrics =
- (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v1_3 *gpu_metrics =
+ (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
SmuMetrics_t metrics;
int ret = 0;
@@ -2289,7 +2319,7 @@ static ssize_t arcturus_get_gpu_metrics(struct smu_context *smu,
if (ret)
return ret;
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
gpu_metrics->temperature_edge = metrics.TemperatureEdge;
gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
@@ -2318,6 +2348,9 @@ static ssize_t arcturus_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ arcturus_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2330,7 +2363,7 @@ static ssize_t arcturus_get_gpu_metrics(struct smu_context *smu,
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v1_1);
+ return sizeof(struct gpu_metrics_v1_3);
}
static const struct pptable_funcs arcturus_ppt_funcs = {
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 74a8c676e22c..1ba42b69ce74 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
@@ -80,10 +80,10 @@ static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh, 0),
MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0),
MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0),
- MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 1),
- MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 1),
- MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 1),
- MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 1),
+ MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 0),
+ MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 0),
+ MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 0),
+ MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 0),
MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow, 1),
MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1),
MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 1),
@@ -238,6 +238,28 @@ static struct cmn2asic_mapping navi10_workload_map[PP_SMC_POWER_PROFILE_COUNT] =
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
};
+static const uint8_t navi1x_throttler_map[] = {
+ [THROTTLER_TEMP_EDGE_BIT] = (SMU_THROTTLER_TEMP_EDGE_BIT),
+ [THROTTLER_TEMP_HOTSPOT_BIT] = (SMU_THROTTLER_TEMP_HOTSPOT_BIT),
+ [THROTTLER_TEMP_MEM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
+ [THROTTLER_TEMP_VR_GFX_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
+ [THROTTLER_TEMP_VR_MEM0_BIT] = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
+ [THROTTLER_TEMP_VR_MEM1_BIT] = (SMU_THROTTLER_TEMP_VR_MEM1_BIT),
+ [THROTTLER_TEMP_VR_SOC_BIT] = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
+ [THROTTLER_TEMP_LIQUID0_BIT] = (SMU_THROTTLER_TEMP_LIQUID0_BIT),
+ [THROTTLER_TEMP_LIQUID1_BIT] = (SMU_THROTTLER_TEMP_LIQUID1_BIT),
+ [THROTTLER_TDC_GFX_BIT] = (SMU_THROTTLER_TDC_GFX_BIT),
+ [THROTTLER_TDC_SOC_BIT] = (SMU_THROTTLER_TDC_SOC_BIT),
+ [THROTTLER_PPT0_BIT] = (SMU_THROTTLER_PPT0_BIT),
+ [THROTTLER_PPT1_BIT] = (SMU_THROTTLER_PPT1_BIT),
+ [THROTTLER_PPT2_BIT] = (SMU_THROTTLER_PPT2_BIT),
+ [THROTTLER_PPT3_BIT] = (SMU_THROTTLER_PPT3_BIT),
+ [THROTTLER_FIT_BIT] = (SMU_THROTTLER_FIT_BIT),
+ [THROTTLER_PPM_BIT] = (SMU_THROTTLER_PPM_BIT),
+ [THROTTLER_APCC_BIT] = (SMU_THROTTLER_APCC_BIT),
+};
+
+
static bool is_asic_secure(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
@@ -446,30 +468,6 @@ static int navi10_store_powerplay_table(struct smu_context *smu)
return 0;
}
-static int navi10_set_mp1_state(struct smu_context *smu,
- enum pp_mp1_state mp1_state)
-{
- struct amdgpu_device *adev = smu->adev;
- uint32_t mp1_fw_flags;
- int ret = 0;
-
- ret = smu_cmn_set_mp1_state(smu, mp1_state);
- if (ret)
- return ret;
-
- if (mp1_state == PP_MP1_STATE_UNLOAD) {
- mp1_fw_flags = RREG32_PCIE(MP1_Public |
- (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
-
- mp1_fw_flags &= ~MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK;
-
- WREG32_PCIE(MP1_Public |
- (smnMP1_FIRMWARE_FLAGS & 0xffffffff), mp1_fw_flags);
- }
-
- return 0;
-}
-
static int navi10_setup_pptable(struct smu_context *smu)
{
int ret = 0;
@@ -2138,7 +2136,10 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu,
return ret;
}
-static int navi10_get_power_limit(struct smu_context *smu)
+static int navi10_get_power_limit(struct smu_context *smu,
+ uint32_t *current_power_limit,
+ uint32_t *default_power_limit,
+ uint32_t *max_power_limit)
{
struct smu_11_0_powerplay_table *powerplay_table =
(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
@@ -2155,18 +2156,25 @@ static int navi10_get_power_limit(struct smu_context *smu)
power_limit =
pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
}
- smu->current_power_limit = smu->default_power_limit = power_limit;
- if (smu->od_enabled &&
- navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
- od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+ if (current_power_limit)
+ *current_power_limit = power_limit;
+ if (default_power_limit)
+ *default_power_limit = power_limit;
- dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+ if (max_power_limit) {
+ if (smu->od_enabled &&
+ navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
+ od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
- power_limit *= (100 + od_percent);
- power_limit /= 100;
+ dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+
+ power_limit *= (100 + od_percent);
+ power_limit /= 100;
+ }
+
+ *max_power_limit = power_limit;
}
- smu->max_power_limit = power_limit;
return 0;
}
@@ -2257,6 +2265,29 @@ static int navi10_overdrive_get_gfx_clk_base_voltage(struct smu_context *smu,
return 0;
}
+static int navi10_baco_enter(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+
+ if (adev->in_runpm)
+ return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
+ else
+ return smu_v11_0_baco_enter(smu);
+}
+
+static int navi10_baco_exit(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+
+ if (adev->in_runpm) {
+ /* Wait for PMFW handling for the Dstate change */
+ msleep(10);
+ return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
+ } else {
+ return smu_v11_0_baco_exit(smu);
+ }
+}
+
static int navi10_set_default_od_settings(struct smu_context *smu)
{
OverDriveTable_t *od_table =
@@ -2676,6 +2707,9 @@ static ssize_t navi10_get_legacy_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2753,6 +2787,9 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2829,6 +2866,9 @@ static ssize_t navi12_get_legacy_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -2911,6 +2951,9 @@ static ssize_t navi12_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ navi1x_throttler_map);
gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
@@ -3095,8 +3138,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.baco_is_support = smu_v11_0_baco_is_support,
.baco_get_state = smu_v11_0_baco_get_state,
.baco_set_state = smu_v11_0_baco_set_state,
- .baco_enter = smu_v11_0_baco_enter,
- .baco_exit = smu_v11_0_baco_exit,
+ .baco_enter = navi10_baco_enter,
+ .baco_exit = navi10_baco_exit,
.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
.set_default_od_settings = navi10_set_default_od_settings,
@@ -3112,7 +3155,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.get_fan_parameters = navi10_get_fan_parameters,
.post_init = navi10_post_smu_init,
.interrupt_work = smu_v11_0_interrupt_work,
- .set_mp1_state = navi10_set_mp1_state,
+ .set_mp1_state = smu_cmn_set_mp1_state,
};
void navi10_set_ppt_funcs(struct smu_context *smu)
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 f01e919e1f89..c751f717a0da 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
@@ -239,6 +239,27 @@ static struct cmn2asic_mapping sienna_cichlid_workload_map[PP_SMC_POWER_PROFILE_
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
};
+static const uint8_t sienna_cichlid_throttler_map[] = {
+ [THROTTLER_TEMP_EDGE_BIT] = (SMU_THROTTLER_TEMP_EDGE_BIT),
+ [THROTTLER_TEMP_HOTSPOT_BIT] = (SMU_THROTTLER_TEMP_HOTSPOT_BIT),
+ [THROTTLER_TEMP_MEM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
+ [THROTTLER_TEMP_VR_GFX_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
+ [THROTTLER_TEMP_VR_MEM0_BIT] = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
+ [THROTTLER_TEMP_VR_MEM1_BIT] = (SMU_THROTTLER_TEMP_VR_MEM1_BIT),
+ [THROTTLER_TEMP_VR_SOC_BIT] = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
+ [THROTTLER_TEMP_LIQUID0_BIT] = (SMU_THROTTLER_TEMP_LIQUID0_BIT),
+ [THROTTLER_TEMP_LIQUID1_BIT] = (SMU_THROTTLER_TEMP_LIQUID1_BIT),
+ [THROTTLER_TDC_GFX_BIT] = (SMU_THROTTLER_TDC_GFX_BIT),
+ [THROTTLER_TDC_SOC_BIT] = (SMU_THROTTLER_TDC_SOC_BIT),
+ [THROTTLER_PPT0_BIT] = (SMU_THROTTLER_PPT0_BIT),
+ [THROTTLER_PPT1_BIT] = (SMU_THROTTLER_PPT1_BIT),
+ [THROTTLER_PPT2_BIT] = (SMU_THROTTLER_PPT2_BIT),
+ [THROTTLER_PPT3_BIT] = (SMU_THROTTLER_PPT3_BIT),
+ [THROTTLER_FIT_BIT] = (SMU_THROTTLER_FIT_BIT),
+ [THROTTLER_PPM_BIT] = (SMU_THROTTLER_PPM_BIT),
+ [THROTTLER_APCC_BIT] = (SMU_THROTTLER_APCC_BIT),
+};
+
static int
sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu,
uint32_t *feature_mask, uint32_t num)
@@ -449,7 +470,7 @@ static int sienna_cichlid_tables_init(struct smu_context *smu)
goto err0_out;
smu_table->metrics_time = 0;
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_1);
+ smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_3);
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table)
goto err1_out;
@@ -1770,7 +1791,10 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context
return ret;
}
-static int sienna_cichlid_get_power_limit(struct smu_context *smu)
+static int sienna_cichlid_get_power_limit(struct smu_context *smu,
+ uint32_t *current_power_limit,
+ uint32_t *default_power_limit,
+ uint32_t *max_power_limit)
{
struct smu_11_0_7_powerplay_table *powerplay_table =
(struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table;
@@ -1783,17 +1807,23 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu)
power_limit =
table_member[PPT_THROTTLER_PPT0];
}
- smu->current_power_limit = smu->default_power_limit = power_limit;
- if (smu->od_enabled) {
- od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
+ if (current_power_limit)
+ *current_power_limit = power_limit;
+ if (default_power_limit)
+ *default_power_limit = power_limit;
+
+ if (max_power_limit) {
+ if (smu->od_enabled) {
+ od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
- dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
+ dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
- power_limit *= (100 + od_percent);
- power_limit /= 100;
+ power_limit *= (100 + od_percent);
+ power_limit /= 100;
+ }
+ *max_power_limit = power_limit;
}
- smu->max_power_limit = power_limit;
return 0;
}
@@ -2100,6 +2130,29 @@ static int sienna_cichlid_run_btc(struct smu_context *smu)
return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
}
+static int sienna_cichlid_baco_enter(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+
+ if (adev->in_runpm)
+ return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
+ else
+ return smu_v11_0_baco_enter(smu);
+}
+
+static int sienna_cichlid_baco_exit(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+
+ if (adev->in_runpm) {
+ /* Wait for PMFW handling for the Dstate change */
+ msleep(10);
+ return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
+ } else {
+ return smu_v11_0_baco_exit(smu);
+ }
+}
+
static bool sienna_cichlid_is_mode1_reset_supported(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
@@ -3620,8 +3673,8 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v1_1 *gpu_metrics =
- (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v1_3 *gpu_metrics =
+ (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
SmuMetricsExternal_t metrics_external;
SmuMetrics_t *metrics =
&(metrics_external.SmuMetrics);
@@ -3635,7 +3688,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
if (ret)
return ret;
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
gpu_metrics->temperature_edge = metrics->TemperatureEdge;
gpu_metrics->temperature_hotspot = metrics->TemperatureHotspot;
@@ -3670,6 +3723,9 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk1 = metrics->CurrClock[PPCLK_DCLK_1];
gpu_metrics->throttle_status = metrics->ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics->ThrottlerStatus,
+ sienna_cichlid_throttler_map);
gpu_metrics->current_fan_speed = metrics->CurrFanSpeed;
@@ -3692,7 +3748,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v1_1);
+ return sizeof(struct gpu_metrics_v1_3);
}
static int sienna_cichlid_enable_mgpu_fan_boost(struct smu_context *smu)
@@ -3875,8 +3931,8 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
.baco_is_support = smu_v11_0_baco_is_support,
.baco_get_state = smu_v11_0_baco_get_state,
.baco_set_state = smu_v11_0_baco_set_state,
- .baco_enter = smu_v11_0_baco_enter,
- .baco_exit = smu_v11_0_baco_exit,
+ .baco_enter = sienna_cichlid_baco_enter,
+ .baco_exit = sienna_cichlid_baco_exit,
.mode1_reset_is_support = sienna_cichlid_is_mode1_reset_supported,
.mode1_reset = smu_v11_0_mode1_reset,
.get_dpm_ultimate_freq = sienna_cichlid_get_dpm_ultimate_freq,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
index e1e1c268f661..388c5cb5c647 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
@@ -1474,7 +1474,8 @@ int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu)
return smu_cmn_send_smc_msg(smu, SMU_MSG_BacoAudioD3PME, NULL);
}
-static int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu, enum smu_v11_0_baco_seq baco_seq)
+int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu,
+ enum smu_v11_0_baco_seq baco_seq)
{
return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq, NULL);
}
@@ -1578,16 +1579,8 @@ out:
int smu_v11_0_baco_enter(struct smu_context *smu)
{
- struct amdgpu_device *adev = smu->adev;
int ret = 0;
- /* Arcturus does not need this audio workaround */
- if (adev->asic_type != CHIP_ARCTURUS) {
- ret = smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
- if (ret)
- return ret;
- }
-
ret = smu_v11_0_baco_set_state(smu, SMU_BACO_STATE_ENTER);
if (ret)
return ret;
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 77f532a49e37..18681dc458da 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
@@ -190,6 +190,20 @@ static struct cmn2asic_mapping vangogh_workload_map[PP_SMC_POWER_PROFILE_COUNT]
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
};
+static const uint8_t vangogh_throttler_map[] = {
+ [THROTTLER_STATUS_BIT_SPL] = (SMU_THROTTLER_SPL_BIT),
+ [THROTTLER_STATUS_BIT_FPPT] = (SMU_THROTTLER_FPPT_BIT),
+ [THROTTLER_STATUS_BIT_SPPT] = (SMU_THROTTLER_SPPT_BIT),
+ [THROTTLER_STATUS_BIT_SPPT_APU] = (SMU_THROTTLER_SPPT_APU_BIT),
+ [THROTTLER_STATUS_BIT_THM_CORE] = (SMU_THROTTLER_TEMP_CORE_BIT),
+ [THROTTLER_STATUS_BIT_THM_GFX] = (SMU_THROTTLER_TEMP_GPU_BIT),
+ [THROTTLER_STATUS_BIT_THM_SOC] = (SMU_THROTTLER_TEMP_SOC_BIT),
+ [THROTTLER_STATUS_BIT_TDC_VDD] = (SMU_THROTTLER_TDC_VDD_BIT),
+ [THROTTLER_STATUS_BIT_TDC_SOC] = (SMU_THROTTLER_TDC_SOC_BIT),
+ [THROTTLER_STATUS_BIT_TDC_GFX] = (SMU_THROTTLER_TDC_GFX_BIT),
+ [THROTTLER_STATUS_BIT_TDC_CVIP] = (SMU_THROTTLER_TDC_CVIP_BIT),
+};
+
static int vangogh_tables_init(struct smu_context *smu)
{
struct smu_table_context *smu_table = &smu->smu_table;
@@ -226,7 +240,7 @@ static int vangogh_tables_init(struct smu_context *smu)
goto err0_out;
smu_table->metrics_time = 0;
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_1);
+ smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table)
goto err1_out;
@@ -1632,8 +1646,8 @@ static ssize_t vangogh_get_legacy_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v2_1 *gpu_metrics =
- (struct gpu_metrics_v2_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v2_2 *gpu_metrics =
+ (struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
SmuMetrics_legacy_t metrics;
int ret = 0;
@@ -1641,7 +1655,7 @@ static ssize_t vangogh_get_legacy_gpu_metrics(struct smu_context *smu,
if (ret)
return ret;
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
gpu_metrics->temperature_gfx = metrics.GfxTemperature;
gpu_metrics->temperature_soc = metrics.SocTemperature;
@@ -1674,20 +1688,23 @@ static ssize_t vangogh_get_legacy_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_l3clk[0] = metrics.L3Frequency[0];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ vangogh_throttler_map);
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v2_1);
+ return sizeof(struct gpu_metrics_v2_2);
}
static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v2_1 *gpu_metrics =
- (struct gpu_metrics_v2_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v2_2 *gpu_metrics =
+ (struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
SmuMetrics_t metrics;
int ret = 0;
@@ -1695,7 +1712,7 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu,
if (ret)
return ret;
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
gpu_metrics->temperature_gfx = metrics.Current.GfxTemperature;
gpu_metrics->temperature_soc = metrics.Current.SocTemperature;
@@ -1735,12 +1752,15 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu,
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_1);
+ return sizeof(struct gpu_metrics_v2_2);
}
static ssize_t vangogh_common_get_gpu_metrics(struct smu_context *smu,
@@ -2051,7 +2071,10 @@ static int vangogh_mode2_reset(struct smu_context *smu)
return vangogh_mode_reset(smu, SMU_RESET_MODE_2);
}
-static int vangogh_get_power_limit(struct smu_context *smu)
+static int vangogh_get_power_limit(struct smu_context *smu,
+ uint32_t *current_power_limit,
+ uint32_t *default_power_limit,
+ uint32_t *max_power_limit)
{
struct smu_11_5_power_context *power_context =
smu->smu_power.power_context;
@@ -2067,8 +2090,12 @@ static int vangogh_get_power_limit(struct smu_context *smu)
return ret;
}
/* convert from milliwatt to watt */
- smu->current_power_limit = smu->default_power_limit = ppt_limit / 1000;
- smu->max_power_limit = 29;
+ if (current_power_limit)
+ *current_power_limit = ppt_limit / 1000;
+ if (default_power_limit)
+ *default_power_limit = ppt_limit / 1000;
+ if (max_power_limit)
+ *max_power_limit = 29;
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPPTLimit, &ppt_limit);
if (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 1c399c4ab4dc..9a9c24a6ec35 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
@@ -128,6 +128,22 @@ static struct cmn2asic_mapping renoir_workload_map[PP_SMC_POWER_PROFILE_COUNT] =
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
};
+static const uint8_t renoir_throttler_map[] = {
+ [THROTTLER_STATUS_BIT_SPL] = (SMU_THROTTLER_SPL_BIT),
+ [THROTTLER_STATUS_BIT_FPPT] = (SMU_THROTTLER_FPPT_BIT),
+ [THROTTLER_STATUS_BIT_SPPT] = (SMU_THROTTLER_SPPT_BIT),
+ [THROTTLER_STATUS_BIT_SPPT_APU] = (SMU_THROTTLER_SPPT_APU_BIT),
+ [THROTTLER_STATUS_BIT_THM_CORE] = (SMU_THROTTLER_TEMP_CORE_BIT),
+ [THROTTLER_STATUS_BIT_THM_GFX] = (SMU_THROTTLER_TEMP_GPU_BIT),
+ [THROTTLER_STATUS_BIT_THM_SOC] = (SMU_THROTTLER_TEMP_SOC_BIT),
+ [THROTTLER_STATUS_BIT_TDC_VDD] = (SMU_THROTTLER_TDC_VDD_BIT),
+ [THROTTLER_STATUS_BIT_TDC_SOC] = (SMU_THROTTLER_TDC_SOC_BIT),
+ [THROTTLER_STATUS_BIT_PROCHOT_CPU] = (SMU_THROTTLER_PROCHOT_CPU_BIT),
+ [THROTTLER_STATUS_BIT_PROCHOT_GFX] = (SMU_THROTTLER_PROCHOT_GFX_BIT),
+ [THROTTLER_STATUS_BIT_EDC_CPU] = (SMU_THROTTLER_EDC_CPU_BIT),
+ [THROTTLER_STATUS_BIT_EDC_GFX] = (SMU_THROTTLER_EDC_GFX_BIT),
+};
+
static int renoir_init_smc_tables(struct smu_context *smu)
{
struct smu_table_context *smu_table = &smu->smu_table;
@@ -153,7 +169,7 @@ static int renoir_init_smc_tables(struct smu_context *smu)
if (!smu_table->watermarks_table)
goto err2_out;
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_1);
+ smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table)
goto err3_out;
@@ -1164,6 +1180,28 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu,
case METRICS_VOLTAGE_VDDSOC:
*value = metrics->Voltage[1];
break;
+ case METRICS_SS_APU_SHARE:
+ /* return the percentage of APU power with respect to APU's power limit.
+ * percentage is reported, this isn't boost value. Smartshift power
+ * boost/shift is only when the percentage is more than 100.
+ */
+ if (metrics->StapmOriginalLimit > 0)
+ *value = (metrics->ApuPower * 100) / metrics->StapmOriginalLimit;
+ else
+ *value = 0;
+ break;
+ case METRICS_SS_DGPU_SHARE:
+ /* return the percentage of dGPU power with respect to dGPU's power limit.
+ * percentage is reported, this isn't boost value. Smartshift power
+ * boost/shift is only when the percentage is more than 100.
+ */
+ if ((metrics->dGpuPower > 0) &&
+ (metrics->StapmCurrentLimit > metrics->StapmOriginalLimit))
+ *value = (metrics->dGpuPower * 100) /
+ (metrics->StapmCurrentLimit - metrics->StapmOriginalLimit);
+ else
+ *value = 0;
+ break;
default:
*value = UINT_MAX;
break;
@@ -1235,6 +1273,18 @@ static int renoir_read_sensor(struct smu_context *smu,
(uint32_t *)data);
*size = 4;
break;
+ case AMDGPU_PP_SENSOR_SS_APU_SHARE:
+ ret = renoir_get_smu_metrics_data(smu,
+ METRICS_SS_APU_SHARE,
+ (uint32_t *)data);
+ *size = 4;
+ break;
+ case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
+ ret = renoir_get_smu_metrics_data(smu,
+ METRICS_SS_DGPU_SHARE,
+ (uint32_t *)data);
+ *size = 4;
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -1264,8 +1314,8 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v2_1 *gpu_metrics =
- (struct gpu_metrics_v2_1 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v2_2 *gpu_metrics =
+ (struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
SmuMetrics_t metrics;
int ret = 0;
@@ -1273,7 +1323,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
if (ret)
return ret;
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
gpu_metrics->temperature_gfx = metrics.GfxTemperature;
gpu_metrics->temperature_soc = metrics.SocTemperature;
@@ -1311,6 +1361,9 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ renoir_throttler_map);
gpu_metrics->fan_pwm = metrics.FanPwm;
@@ -1318,7 +1371,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v2_1);
+ return sizeof(struct gpu_metrics_v2_2);
}
static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state)
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 6ee9c4186f02..9316a726195c 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
@@ -191,6 +191,20 @@ static const struct cmn2asic_mapping aldebaran_table_map[SMU_TABLE_COUNT] = {
TAB_MAP(I2C_COMMANDS),
};
+static const uint8_t aldebaran_throttler_map[] = {
+ [THROTTLER_PPT0_BIT] = (SMU_THROTTLER_PPT0_BIT),
+ [THROTTLER_PPT1_BIT] = (SMU_THROTTLER_PPT1_BIT),
+ [THROTTLER_TDC_GFX_BIT] = (SMU_THROTTLER_TDC_GFX_BIT),
+ [THROTTLER_TDC_SOC_BIT] = (SMU_THROTTLER_TDC_SOC_BIT),
+ [THROTTLER_TDC_HBM_BIT] = (SMU_THROTTLER_TDC_MEM_BIT),
+ [THROTTLER_TEMP_GPU_BIT] = (SMU_THROTTLER_TEMP_GPU_BIT),
+ [THROTTLER_TEMP_MEM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
+ [THROTTLER_TEMP_VR_GFX_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
+ [THROTTLER_TEMP_VR_SOC_BIT] = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
+ [THROTTLER_TEMP_VR_MEM_BIT] = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
+ [THROTTLER_APCC_BIT] = (SMU_THROTTLER_APCC_BIT),
+};
+
static int aldebaran_tables_init(struct smu_context *smu)
{
struct smu_table_context *smu_table = &smu->smu_table;
@@ -213,7 +227,7 @@ static int aldebaran_tables_init(struct smu_context *smu)
return -ENOMEM;
smu_table->metrics_time = 0;
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_2);
+ smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_3);
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table) {
kfree(smu_table->metrics_table);
@@ -510,6 +524,16 @@ static int aldebaran_freqs_in_same_level(int32_t frequency1,
return (abs(frequency1 - frequency2) <= EPSILON);
}
+static bool aldebaran_is_primary(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+
+ if (adev->smuio.funcs && adev->smuio.funcs->get_die_id)
+ return adev->smuio.funcs->get_die_id(adev) == 0;
+
+ return true;
+}
+
static int aldebaran_get_smu_metrics_data(struct smu_context *smu,
MetricsMember_t member,
uint32_t *value)
@@ -563,7 +587,10 @@ static int aldebaran_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->AverageUclkActivity;
break;
case METRICS_AVERAGE_SOCKETPOWER:
- *value = metrics->AverageSocketPower << 8;
+ /* Valid power data is available only from primary die */
+ *value = aldebaran_is_primary(smu) ?
+ metrics->AverageSocketPower << 8 :
+ 0;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->TemperatureEdge *
@@ -1132,7 +1159,10 @@ static int aldebaran_read_sensor(struct smu_context *smu,
return ret;
}
-static int aldebaran_get_power_limit(struct smu_context *smu)
+static int aldebaran_get_power_limit(struct smu_context *smu,
+ uint32_t *current_power_limit,
+ uint32_t *default_power_limit,
+ uint32_t *max_power_limit)
{
PPTable_t *pptable = smu->smu_table.driver_pptable;
uint32_t power_limit = 0;
@@ -1141,24 +1171,46 @@ static int aldebaran_get_power_limit(struct smu_context *smu)
if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT))
return -EINVAL;
- ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetPptLimit, &power_limit);
+ /* Valid power data is available only from primary die.
+ * For secondary die show the value as 0.
+ */
+ if (aldebaran_is_primary(smu)) {
+ ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetPptLimit,
+ &power_limit);
- if (ret) {
- /* the last hope to figure out the ppt limit */
- if (!pptable) {
- dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
- return -EINVAL;
+ if (ret) {
+ /* the last hope to figure out the ppt limit */
+ if (!pptable) {
+ dev_err(smu->adev->dev,
+ "Cannot get PPT limit due to pptable missing!");
+ return -EINVAL;
+ }
+ power_limit = pptable->PptLimit;
}
- power_limit = pptable->PptLimit;
}
- smu->current_power_limit = smu->default_power_limit = power_limit;
- if (pptable)
- smu->max_power_limit = pptable->PptLimit;
+ if (current_power_limit)
+ *current_power_limit = power_limit;
+ if (default_power_limit)
+ *default_power_limit = power_limit;
+
+ if (max_power_limit) {
+ if (pptable)
+ *max_power_limit = pptable->PptLimit;
+ }
return 0;
}
+static int aldebaran_set_power_limit(struct smu_context *smu, uint32_t n)
+{
+ /* Power limit can be set only through primary die */
+ if (aldebaran_is_primary(smu))
+ return smu_v13_0_set_power_limit(smu, n);
+
+ return -EINVAL;
+}
+
static int aldebaran_system_features_control(struct smu_context *smu, bool enable)
{
int ret;
@@ -1706,8 +1758,8 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
void **table)
{
struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v1_2 *gpu_metrics =
- (struct gpu_metrics_v1_2 *)smu_table->gpu_metrics_table;
+ struct gpu_metrics_v1_3 *gpu_metrics =
+ (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table;
SmuMetrics_t metrics;
int i, ret = 0;
@@ -1717,7 +1769,7 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
if (ret)
return ret;
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 2);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
gpu_metrics->temperature_edge = metrics.TemperatureEdge;
gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
@@ -1730,10 +1782,16 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->average_umc_activity = metrics.AverageUclkActivity;
gpu_metrics->average_mm_activity = 0;
- gpu_metrics->average_socket_power = metrics.AverageSocketPower;
- gpu_metrics->energy_accumulator =
+ /* Valid power data is available only from primary die */
+ if (aldebaran_is_primary(smu)) {
+ gpu_metrics->average_socket_power = metrics.AverageSocketPower;
+ gpu_metrics->energy_accumulator =
(uint64_t)metrics.EnergyAcc64bitHigh << 32 |
metrics.EnergyAcc64bitLow;
+ } else {
+ gpu_metrics->average_socket_power = 0;
+ gpu_metrics->energy_accumulator = 0;
+ }
gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency;
gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
@@ -1748,6 +1806,9 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
gpu_metrics->throttle_status = metrics.ThrottlerStatus;
+ gpu_metrics->indep_throttle_status =
+ smu_cmn_get_indep_throttler_status(metrics.ThrottlerStatus,
+ aldebaran_throttler_map);
gpu_metrics->current_fan_speed = 0;
@@ -1769,7 +1830,7 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
*table = (void *)gpu_metrics;
- return sizeof(struct gpu_metrics_v1_2);
+ return sizeof(struct gpu_metrics_v1_3);
}
static int aldebaran_mode2_reset(struct smu_context *smu)
@@ -1862,6 +1923,20 @@ static int aldebaran_set_mp1_state(struct smu_context *smu,
}
}
+static int aldebaran_smu_send_hbm_bad_page_num(struct smu_context *smu,
+ uint32_t size)
+{
+ int ret = 0;
+
+ /* message SMU to update the bad page number on SMUBUS */
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetNumBadHbmPagesRetired, size, NULL);
+ if (ret)
+ dev_err(smu->adev->dev, "[%s] failed to message SMU to update HBM bad pages number\n",
+ __func__);
+
+ return ret;
+}
+
static const struct pptable_funcs aldebaran_ppt_funcs = {
/* init dpm */
.get_allowed_feature_mask = aldebaran_get_allowed_feature_mask,
@@ -1898,7 +1973,7 @@ static const struct pptable_funcs aldebaran_ppt_funcs = {
.get_enabled_mask = smu_cmn_get_enabled_mask,
.feature_is_enabled = smu_cmn_feature_is_enabled,
.disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
- .set_power_limit = smu_v13_0_set_power_limit,
+ .set_power_limit = aldebaran_set_power_limit,
.init_max_sustainable_clocks = smu_v13_0_init_max_sustainable_clocks,
.enable_thermal_alert = smu_v13_0_enable_thermal_alert,
.disable_thermal_alert = smu_v13_0_disable_thermal_alert,
@@ -1924,6 +1999,7 @@ static const struct pptable_funcs aldebaran_ppt_funcs = {
.wait_for_event = smu_v13_0_wait_for_event,
.i2c_init = aldebaran_i2c_control_init,
.i2c_fini = aldebaran_i2c_control_fini,
+ .send_hbm_bad_pages_num = aldebaran_smu_send_hbm_bad_page_num,
};
void aldebaran_set_ppt_funcs(struct smu_context *smu)
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 0cd7902d5172..18a1ffdca227 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
@@ -189,10 +189,11 @@ err0_out:
static int yellow_carp_system_features_control(struct smu_context *smu, bool en)
{
struct smu_feature *feature = &smu->smu_feature;
+ struct amdgpu_device *adev = smu->adev;
uint32_t feature_mask[2];
int ret = 0;
- if (!en)
+ if (!en && !adev->in_s0ix)
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
bitmap_zero(feature->enabled, feature->feature_num);
@@ -356,6 +357,28 @@ static int yellow_carp_get_smu_metrics_data(struct smu_context *smu,
case METRICS_VOLTAGE_VDDSOC:
*value = metrics->Voltage[1];
break;
+ case METRICS_SS_APU_SHARE:
+ /* return the percentage of APU power with respect to APU's power limit.
+ * percentage is reported, this isn't boost value. Smartshift power
+ * boost/shift is only when the percentage is more than 100.
+ */
+ if (metrics->StapmOpnLimit > 0)
+ *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit;
+ else
+ *value = 0;
+ break;
+ case METRICS_SS_DGPU_SHARE:
+ /* return the percentage of dGPU power with respect to dGPU's power limit.
+ * percentage is reported, this isn't boost value. Smartshift power
+ * boost/shift is only when the percentage is more than 100.
+ */
+ if ((metrics->dGpuPower > 0) &&
+ (metrics->StapmCurrentLimit > metrics->StapmOpnLimit))
+ *value = (metrics->dGpuPower * 100) /
+ (metrics->StapmCurrentLimit - metrics->StapmOpnLimit);
+ else
+ *value = 0;
+ break;
default:
*value = UINT_MAX;
break;
@@ -427,6 +450,18 @@ static int yellow_carp_read_sensor(struct smu_context *smu,
(uint32_t *)data);
*size = 4;
break;
+ case AMDGPU_PP_SENSOR_SS_APU_SHARE:
+ ret = yellow_carp_get_smu_metrics_data(smu,
+ METRICS_SS_APU_SHARE,
+ (uint32_t *)data);
+ *size = 4;
+ break;
+ case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
+ ret = yellow_carp_get_smu_metrics_data(smu,
+ METRICS_SS_DGPU_SHARE,
+ (uint32_t *)data);
+ *size = 4;
+ break;
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 0882a1dd6797..e802f9a95f08 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -398,6 +398,19 @@ int smu_cmn_get_enabled_32_bits_mask(struct smu_context *smu,
}
+uint64_t smu_cmn_get_indep_throttler_status(
+ const unsigned long dep_status,
+ const uint8_t *throttler_map)
+{
+ uint64_t indep_status = 0;
+ uint8_t dep_bit = 0;
+
+ for_each_set_bit(dep_bit, &dep_status, 32)
+ indep_status |= 1ULL << throttler_map[dep_bit];
+
+ return indep_status;
+}
+
int smu_cmn_feature_update_enable_state(struct smu_context *smu,
uint64_t feature_mask,
bool enabled)
@@ -575,23 +588,52 @@ int smu_cmn_set_pp_feature_mask(struct smu_context *smu,
return ret;
}
+/**
+ * smu_cmn_disable_all_features_with_exception - disable all dpm features
+ * except this specified by
+ * @mask
+ *
+ * @smu: smu_context pointer
+ * @no_hw_disablement: whether real dpm disablement should be performed
+ * true: update the cache(about dpm enablement state) only
+ * false: real dpm disablement plus cache update
+ * @mask: the dpm feature which should not be disabled
+ * SMU_FEATURE_COUNT: no exception, all dpm features
+ * to disable
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ */
int smu_cmn_disable_all_features_with_exception(struct smu_context *smu,
+ bool no_hw_disablement,
enum smu_feature_mask mask)
{
+ struct smu_feature *feature = &smu->smu_feature;
uint64_t features_to_disable = U64_MAX;
int skipped_feature_id;
- skipped_feature_id = smu_cmn_to_asic_specific_index(smu,
- CMN2ASIC_MAPPING_FEATURE,
- mask);
- if (skipped_feature_id < 0)
- return -EINVAL;
+ if (mask != SMU_FEATURE_COUNT) {
+ skipped_feature_id = smu_cmn_to_asic_specific_index(smu,
+ CMN2ASIC_MAPPING_FEATURE,
+ mask);
+ if (skipped_feature_id < 0)
+ return -EINVAL;
- features_to_disable &= ~(1ULL << skipped_feature_id);
+ features_to_disable &= ~(1ULL << skipped_feature_id);
+ }
- return smu_cmn_feature_update_enable_state(smu,
- features_to_disable,
- 0);
+ if (no_hw_disablement) {
+ mutex_lock(&feature->mutex);
+ bitmap_andnot(feature->enabled, feature->enabled,
+ (unsigned long *)(&features_to_disable), SMU_FEATURE_MAX);
+ mutex_unlock(&feature->mutex);
+
+ return 0;
+ } else {
+ return smu_cmn_feature_update_enable_state(smu,
+ features_to_disable,
+ 0);
+ }
}
int smu_cmn_get_smc_version(struct smu_context *smu,
@@ -773,6 +815,9 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev)
case METRICS_VERSION(2, 1):
structure_size = sizeof(struct gpu_metrics_v2_1);
break;
+ case METRICS_VERSION(2, 2):
+ structure_size = sizeof(struct gpu_metrics_v2_2);
+ 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 da6ff6f024f9..9add5f16ff56 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
@@ -60,6 +60,10 @@ int smu_cmn_get_enabled_32_bits_mask(struct smu_context *smu,
uint32_t *feature_mask,
uint32_t num);
+uint64_t smu_cmn_get_indep_throttler_status(
+ const unsigned long dep_status,
+ const uint8_t *throttler_map);
+
int smu_cmn_feature_update_enable_state(struct smu_context *smu,
uint64_t feature_mask,
bool enabled);
@@ -75,6 +79,7 @@ int smu_cmn_set_pp_feature_mask(struct smu_context *smu,
uint64_t new_mask);
int smu_cmn_disable_all_features_with_exception(struct smu_context *smu,
+ bool no_hw_disablement,
enum smu_feature_mask mask);
int smu_cmn_get_smc_version(struct smu_context *smu,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h
index 68d9464ababc..59f9cfff3d61 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h
@@ -57,7 +57,7 @@
#define smu_feature_set_allowed_mask(smu) smu_ppt_funcs(set_allowed_mask, 0, smu)
#define smu_feature_get_enabled_mask(smu, mask, num) smu_ppt_funcs(get_enabled_mask, 0, smu, mask, num)
#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_disable_all_features_with_exception(smu, no_hw_disablement, mask) smu_ppt_funcs(disable_all_features_with_exception, 0, smu, no_hw_disablement, mask)
#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)
@@ -82,7 +82,7 @@
#define smu_i2c_fini(smu, control) smu_ppt_funcs(i2c_fini, 0, smu, control)
#define smu_get_unique_id(smu) smu_ppt_funcs(get_unique_id, 0, smu)
#define smu_log_thermal_throttling(smu) smu_ppt_funcs(log_thermal_throttling_event, 0, smu)
-#define smu_get_asic_power_limits(smu) smu_ppt_funcs(get_power_limit, 0, smu)
+#define smu_get_asic_power_limits(smu, current, default, max) smu_ppt_funcs(get_power_limit, 0, smu, current, default, max)
#define smu_get_pp_feature_mask(smu, buf) smu_ppt_funcs(get_pp_feature_mask, 0, smu, buf)
#define smu_set_pp_feature_mask(smu, new_mask) smu_ppt_funcs(set_pp_feature_mask, 0, smu, new_mask)
#define smu_gfx_ulv_control(smu, enablement) smu_ppt_funcs(gfx_ulv_control, 0, smu, enablement)