aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Huang <JinHuiEric.Huang@amd.com>2016-01-22 14:32:41 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-02-10 14:17:01 -0500
commit5d37a63d2612a4f2eb77784a41b9a7a7d1d4315e (patch)
treee56ced7636bd31e49761881dd3a7ee66ddce57c5
parentd7341ef66870fc85361d6c66edd8aee58a7a9a9b (diff)
drm/amd/powerplay: add some hwmgr functions for sysfs interface on Tonga
Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
index 44a925006479..bc83fa35ec46 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
@@ -6018,6 +6018,125 @@ static int tonga_get_fan_control_mode(struct pp_hwmgr *hwmgr)
6018 CG_FDO_CTRL2, FDO_PWM_MODE); 6018 CG_FDO_CTRL2, FDO_PWM_MODE);
6019} 6019}
6020 6020
6021static int tonga_get_pp_table(struct pp_hwmgr *hwmgr, char **table)
6022{
6023 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
6024
6025 *table = (char *)&data->smc_state_table;
6026
6027 return sizeof(struct SMU72_Discrete_DpmTable);
6028}
6029
6030static int tonga_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size)
6031{
6032 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
6033
6034 void *table = (void *)&data->smc_state_table;
6035
6036 memcpy(table, buf, size);
6037
6038 return 0;
6039}
6040
6041static int tonga_force_clock_level(struct pp_hwmgr *hwmgr,
6042 enum pp_clock_type type, int level)
6043{
6044 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
6045
6046 if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
6047 return -EINVAL;
6048
6049 switch (type) {
6050 case PP_SCLK:
6051 if (!data->sclk_dpm_key_disabled)
6052 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
6053 PPSMC_MSG_SCLKDPM_SetEnabledMask,
6054 (1 << level));
6055 break;
6056 case PP_MCLK:
6057 if (!data->mclk_dpm_key_disabled)
6058 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
6059 PPSMC_MSG_MCLKDPM_SetEnabledMask,
6060 (1 << level));
6061 break;
6062 case PP_PCIE:
6063 if (!data->pcie_dpm_key_disabled)
6064 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
6065 PPSMC_MSG_PCIeDPM_ForceLevel,
6066 (1 << level));
6067 break;
6068 default:
6069 break;
6070 }
6071
6072 return 0;
6073}
6074
6075static int tonga_print_clock_levels(struct pp_hwmgr *hwmgr,
6076 enum pp_clock_type type, char *buf)
6077{
6078 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
6079 struct tonga_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
6080 struct tonga_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
6081 struct tonga_single_dpm_table *pcie_table = &(data->dpm_table.pcie_speed_table);
6082 int i, now, size = 0;
6083 uint32_t clock, pcie_speed;
6084
6085 switch (type) {
6086 case PP_SCLK:
6087 smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency);
6088 clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
6089
6090 for (i = 0; i < sclk_table->count; i++) {
6091 if (clock > sclk_table->dpm_levels[i].value)
6092 continue;
6093 break;
6094 }
6095 now = i;
6096
6097 for (i = 0; i < sclk_table->count; i++)
6098 size += sprintf(buf + size, "%d: %uMhz %s\n",
6099 i, sclk_table->dpm_levels[i].value / 100,
6100 (i == now) ? "*" : "");
6101 break;
6102 case PP_MCLK:
6103 smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency);
6104 clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
6105
6106 for (i = 0; i < mclk_table->count; i++) {
6107 if (clock > mclk_table->dpm_levels[i].value)
6108 continue;
6109 break;
6110 }
6111 now = i;
6112
6113 for (i = 0; i < mclk_table->count; i++)
6114 size += sprintf(buf + size, "%d: %uMhz %s\n",
6115 i, mclk_table->dpm_levels[i].value / 100,
6116 (i == now) ? "*" : "");
6117 break;
6118 case PP_PCIE:
6119 pcie_speed = tonga_get_current_pcie_speed(hwmgr);
6120 for (i = 0; i < pcie_table->count; i++) {
6121 if (pcie_speed != pcie_table->dpm_levels[i].value)
6122 continue;
6123 break;
6124 }
6125 now = i;
6126
6127 for (i = 0; i < pcie_table->count; i++)
6128 size += sprintf(buf + size, "%d: %s %s\n", i,
6129 (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x8" :
6130 (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" :
6131 (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "",
6132 (i == now) ? "*" : "");
6133 break;
6134 default:
6135 break;
6136 }
6137 return size;
6138}
6139
6021static const struct pp_hwmgr_func tonga_hwmgr_funcs = { 6140static const struct pp_hwmgr_func tonga_hwmgr_funcs = {
6022 .backend_init = &tonga_hwmgr_backend_init, 6141 .backend_init = &tonga_hwmgr_backend_init,
6023 .backend_fini = &tonga_hwmgr_backend_fini, 6142 .backend_fini = &tonga_hwmgr_backend_fini,
@@ -6055,6 +6174,10 @@ static const struct pp_hwmgr_func tonga_hwmgr_funcs = {
6055 .check_states_equal = tonga_check_states_equal, 6174 .check_states_equal = tonga_check_states_equal,
6056 .set_fan_control_mode = tonga_set_fan_control_mode, 6175 .set_fan_control_mode = tonga_set_fan_control_mode,
6057 .get_fan_control_mode = tonga_get_fan_control_mode, 6176 .get_fan_control_mode = tonga_get_fan_control_mode,
6177 .get_pp_table = tonga_get_pp_table,
6178 .set_pp_table = tonga_set_pp_table,
6179 .force_clock_level = tonga_force_clock_level,
6180 .print_clock_levels = tonga_print_clock_levels,
6058}; 6181};
6059 6182
6060int tonga_hwmgr_init(struct pp_hwmgr *hwmgr) 6183int tonga_hwmgr_init(struct pp_hwmgr *hwmgr)