summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c')
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c
index 331b0aba4a13..65d3a4893958 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c
@@ -2219,6 +2219,42 @@ static void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
smu_data->power_tune_defaults = &tonga_power_tune_data_set_array[0];
}
+static void tonga_save_default_power_profile(struct pp_hwmgr *hwmgr)
+{
+ struct tonga_smumgr *data = (struct tonga_smumgr *)(hwmgr->smumgr->backend);
+ struct SMU72_Discrete_GraphicsLevel *levels =
+ data->smc_state_table.GraphicsLevel;
+ unsigned min_level = 1;
+
+ hwmgr->default_gfx_power_profile.activity_threshold =
+ be16_to_cpu(levels[0].ActivityLevel);
+ hwmgr->default_gfx_power_profile.up_hyst = levels[0].UpHyst;
+ hwmgr->default_gfx_power_profile.down_hyst = levels[0].DownHyst;
+ hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE;
+
+ hwmgr->default_compute_power_profile = hwmgr->default_gfx_power_profile;
+ hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE;
+
+ /* Workaround compute SDMA instability: disable lowest SCLK
+ * DPM level. Optimize compute power profile: Use only highest
+ * 2 power levels (if more than 2 are available), Hysteresis:
+ * 0ms up, 5ms down
+ */
+ if (data->smc_state_table.GraphicsDpmLevelCount > 2)
+ min_level = data->smc_state_table.GraphicsDpmLevelCount - 2;
+ else if (data->smc_state_table.GraphicsDpmLevelCount == 2)
+ min_level = 1;
+ else
+ min_level = 0;
+ hwmgr->default_compute_power_profile.min_sclk =
+ be32_to_cpu(levels[min_level].SclkFrequency);
+ hwmgr->default_compute_power_profile.up_hyst = 0;
+ hwmgr->default_compute_power_profile.down_hyst = 5;
+
+ hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile;
+ hwmgr->compute_power_profile = hwmgr->default_compute_power_profile;
+}
+
/**
* Initializes the SMC table and uploads it
*
@@ -2468,6 +2504,8 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE((!result),
"Failed to populate initialize MC Reg table !", return result);
+ tonga_save_default_power_profile(hwmgr);
+
return 0;
}
@@ -2657,7 +2695,7 @@ uint32_t tonga_get_offsetof(uint32_t type, uint32_t member)
return offsetof(SMU72_Discrete_DpmTable, LowSclkInterruptThreshold);
}
}
- pr_warning("can't get the offset of type %x member %x\n", type, member);
+ pr_warn("can't get the offset of type %x member %x\n", type, member);
return 0;
}
@@ -2681,7 +2719,7 @@ uint32_t tonga_get_mac_definition(uint32_t value)
case SMU_MAX_LEVELS_MVDD:
return SMU72_MAX_LEVELS_MVDD;
}
- pr_warning("can't get the mac value %x\n", value);
+ pr_warn("can't get the mac value %x\n", value);
return 0;
}
@@ -3210,3 +3248,28 @@ bool tonga_is_dpm_running(struct pp_hwmgr *hwmgr)
CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON))
? true : false;
}
+
+int tonga_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
+ struct amd_pp_profile *request)
+{
+ struct tonga_smumgr *smu_data = (struct tonga_smumgr *)
+ (hwmgr->smumgr->backend);
+ struct SMU72_Discrete_GraphicsLevel *levels =
+ smu_data->smc_state_table.GraphicsLevel;
+ uint32_t array = smu_data->smu7_data.dpm_table_start +
+ offsetof(SMU72_Discrete_DpmTable, GraphicsLevel);
+ uint32_t array_size = sizeof(struct SMU72_Discrete_GraphicsLevel) *
+ SMU72_MAX_LEVELS_GRAPHICS;
+ uint32_t i;
+
+ for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) {
+ levels[i].ActivityLevel =
+ cpu_to_be16(request->activity_threshold);
+ levels[i].EnabledForActivity = 1;
+ levels[i].UpHyst = request->up_hyst;
+ levels[i].DownHyst = request->down_hyst;
+ }
+
+ return smu7_copy_bytes_to_smc(hwmgr->smumgr, array, (uint8_t *)levels,
+ array_size, SMC_RAM_END);
+}
OpenPOWER on IntegriCloud