summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c')
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c94
1 files changed, 78 insertions, 16 deletions
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 2380759ddf48..624065d3c079 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
@@ -62,6 +62,7 @@ MODULE_FIRMWARE("amdgpu/navi14_smc.bin");
MODULE_FIRMWARE("amdgpu/navi12_smc.bin");
MODULE_FIRMWARE("amdgpu/sienna_cichlid_smc.bin");
MODULE_FIRMWARE("amdgpu/navy_flounder_smc.bin");
+MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_smc.bin");
#define SMU11_VOLTAGE_SCALE 4
@@ -84,7 +85,7 @@ int smu_v11_0_init_microcode(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
const char *chip_name;
- char fw_name[30];
+ char fw_name[SMU_FW_NAME_LEN];
int err = 0;
const struct smc_firmware_header_v1_0 *hdr;
const struct common_firmware_header *header;
@@ -109,6 +110,9 @@ int smu_v11_0_init_microcode(struct smu_context *smu)
case CHIP_NAVY_FLOUNDER:
chip_name = "navy_flounder";
break;
+ case CHIP_DIMGREY_CAVEFISH:
+ chip_name = "dimgrey_cavefish";
+ break;
default:
dev_err(adev->dev, "Unsupported ASIC type %d\n", adev->asic_type);
return -EINVAL;
@@ -212,6 +216,7 @@ int smu_v11_0_check_fw_status(struct smu_context *smu)
int smu_v11_0_check_fw_version(struct smu_context *smu)
{
+ struct amdgpu_device *adev = smu->adev;
uint32_t if_version = 0xff, smu_version = 0xff;
uint16_t smu_major;
uint8_t smu_minor, smu_debug;
@@ -224,6 +229,8 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
smu_major = (smu_version >> 16) & 0xffff;
smu_minor = (smu_version >> 8) & 0xff;
smu_debug = (smu_version >> 0) & 0xff;
+ if (smu->is_apu)
+ adev->pm.fw_version = smu_version;
switch (smu->adev->asic_type) {
case CHIP_ARCTURUS:
@@ -244,6 +251,12 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
case CHIP_NAVY_FLOUNDER:
smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Navy_Flounder;
break;
+ case CHIP_VANGOGH:
+ smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_VANGOGH;
+ break;
+ case CHIP_DIMGREY_CAVEFISH:
+ smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Dimgrey_Cavefish;
+ break;
default:
dev_err(smu->adev->dev, "smu unsupported asic type:%d.\n", smu->adev->asic_type);
smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_INV;
@@ -326,8 +339,7 @@ int smu_v11_0_setup_pptable(struct smu_context *smu)
hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
version_major = le16_to_cpu(hdr->header.header_version_major);
version_minor = le16_to_cpu(hdr->header.header_version_minor);
- if ((version_major == 2 && smu->smu_table.boot_values.pp_table_id > 0) ||
- adev->asic_type == CHIP_NAVY_FLOUNDER) {
+ if (version_major == 2 && smu->smu_table.boot_values.pp_table_id > 0) {
dev_info(adev->dev, "use driver provided pptable %d\n", smu->smu_table.boot_values.pp_table_id);
switch (version_minor) {
case 0:
@@ -425,11 +437,13 @@ int smu_v11_0_fini_smc_tables(struct smu_context *smu)
kfree(smu_table->overdrive_table);
kfree(smu_table->max_sustainable_clocks);
kfree(smu_table->driver_pptable);
+ kfree(smu_table->clocks_table);
smu_table->gpu_metrics_table = NULL;
smu_table->boot_overdrive_table = NULL;
smu_table->overdrive_table = NULL;
smu_table->max_sustainable_clocks = NULL;
smu_table->driver_pptable = NULL;
+ smu_table->clocks_table = NULL;
kfree(smu_table->hardcode_pptable);
smu_table->hardcode_pptable = NULL;
@@ -456,11 +470,11 @@ int smu_v11_0_init_power(struct smu_context *smu)
{
struct smu_power_context *smu_power = &smu->smu_power;
- smu_power->power_context = kzalloc(sizeof(struct smu_11_0_dpm_context),
+ smu_power->power_context = kzalloc(sizeof(struct smu_11_0_power_context),
GFP_KERNEL);
if (!smu_power->power_context)
return -ENOMEM;
- smu_power->power_context_size = sizeof(struct smu_11_0_dpm_context);
+ smu_power->power_context_size = sizeof(struct smu_11_0_power_context);
return 0;
}
@@ -592,6 +606,11 @@ int smu_v11_0_get_vbios_bootup_values(struct smu_context *smu)
(uint8_t)SMU11_SYSPLL1_2_ID,
&smu->smu_table.boot_values.fclk);
+ smu_v11_0_atom_get_smu_clockinfo(smu->adev,
+ (uint8_t)SMU11_SYSPLL3_1_LCLK_ID,
+ (uint8_t)SMU11_SYSPLL3_1_ID,
+ &smu->smu_table.boot_values.lclk);
+
return 0;
}
@@ -699,8 +718,11 @@ int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count)
{
struct amdgpu_device *adev = smu->adev;
- /* Navy_Flounder do not support to change display num currently */
- if (adev->asic_type == CHIP_NAVY_FLOUNDER)
+ /* Navy_Flounder/Dimgrey_Cavefish do not support to change
+ * display num currently
+ */
+ if (adev->asic_type >= CHIP_NAVY_FLOUNDER &&
+ adev->asic_type <= CHIP_DIMGREY_CAVEFISH)
return 0;
return smu_cmn_send_smc_msg_with_param(smu,
@@ -1068,6 +1090,7 @@ int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
case CHIP_NAVI12:
case CHIP_SIENNA_CICHLID:
case CHIP_NAVY_FLOUNDER:
+ case CHIP_DIMGREY_CAVEFISH:
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
return 0;
if (enable)
@@ -1164,7 +1187,12 @@ int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
if (ret)
return ret;
- crystal_clock_freq = amdgpu_asic_get_xclk(adev);
+ /*
+ * crystal_clock_freq div by 4 is required since the fan control
+ * module refers to 25MHz
+ */
+
+ crystal_clock_freq = amdgpu_asic_get_xclk(adev) / 4;
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
WREG32_SOC15(THM, 0, mmCG_TACH_CTRL,
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL),
@@ -1462,6 +1490,9 @@ enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu)
return baco_state;
}
+#define D3HOT_BACO_SEQUENCE 0
+#define D3HOT_BAMACO_SEQUENCE 2
+
int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
{
struct smu_baco_context *smu_baco = &smu->smu_baco;
@@ -1476,15 +1507,34 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
mutex_lock(&smu_baco->mutex);
if (state == SMU_BACO_STATE_ENTER) {
- if (!ras || !ras->supported) {
- data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL);
- data |= 0x80000000;
- WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data);
-
- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 0, NULL);
- } else {
- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 1, NULL);
+ switch (adev->asic_type) {
+ case CHIP_SIENNA_CICHLID:
+ case CHIP_NAVY_FLOUNDER:
+ case CHIP_DIMGREY_CAVEFISH:
+ if (amdgpu_runtime_pm == 2)
+ ret = smu_cmn_send_smc_msg_with_param(smu,
+ SMU_MSG_EnterBaco,
+ D3HOT_BAMACO_SEQUENCE,
+ NULL);
+ else
+ ret = smu_cmn_send_smc_msg_with_param(smu,
+ SMU_MSG_EnterBaco,
+ D3HOT_BACO_SEQUENCE,
+ NULL);
+ break;
+ default:
+ if (!ras || !ras->supported) {
+ data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL);
+ data |= 0x80000000;
+ WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data);
+
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 0, NULL);
+ } else {
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, 1, NULL);
+ }
+ break;
}
+
} else {
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_ExitBaco, NULL);
if (ret)
@@ -1977,6 +2027,18 @@ void smu_v11_0_init_gpu_metrics_v1_0(struct gpu_metrics_v1_0 *gpu_metrics)
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
}
+void smu_v11_0_init_gpu_metrics_v2_0(struct gpu_metrics_v2_0 *gpu_metrics)
+{
+ memset(gpu_metrics, 0xFF, sizeof(struct gpu_metrics_v2_0));
+
+ gpu_metrics->common_header.structure_size =
+ sizeof(struct gpu_metrics_v2_0);
+ gpu_metrics->common_header.format_revision = 2;
+ gpu_metrics->common_header.content_revision = 0;
+
+ gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
+}
+
int smu_v11_0_gfx_ulv_control(struct smu_context *smu,
bool enablement)
{