Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/powerplay: add hwmgr's functions for Fiji sysfs interfaces.

These add the interfaces for manual clock control.

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>

authored by

Eric Huang and committed by
Alex Deucher
b9c1a77e f3898ea1

+123
+123
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
··· 5073 5073 CG_FDO_CTRL2, FDO_PWM_MODE); 5074 5074 } 5075 5075 5076 + static int fiji_get_pp_table(struct pp_hwmgr *hwmgr, char **table) 5077 + { 5078 + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 5079 + 5080 + *table = (char *)&data->smc_state_table; 5081 + 5082 + return sizeof(struct SMU73_Discrete_DpmTable); 5083 + } 5084 + 5085 + static int fiji_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size) 5086 + { 5087 + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 5088 + 5089 + void *table = (void *)&data->smc_state_table; 5090 + 5091 + memcpy(table, buf, size); 5092 + 5093 + return 0; 5094 + } 5095 + 5096 + static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, 5097 + enum pp_clock_type type, int level) 5098 + { 5099 + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 5100 + 5101 + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 5102 + return -EINVAL; 5103 + 5104 + switch (type) { 5105 + case PP_SCLK: 5106 + if (!data->sclk_dpm_key_disabled) 5107 + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 5108 + PPSMC_MSG_SCLKDPM_SetEnabledMask, 5109 + (1 << level)); 5110 + break; 5111 + case PP_MCLK: 5112 + if (!data->mclk_dpm_key_disabled) 5113 + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 5114 + PPSMC_MSG_MCLKDPM_SetEnabledMask, 5115 + (1 << level)); 5116 + break; 5117 + case PP_PCIE: 5118 + if (!data->pcie_dpm_key_disabled) 5119 + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 5120 + PPSMC_MSG_PCIeDPM_ForceLevel, 5121 + (1 << level)); 5122 + break; 5123 + default: 5124 + break; 5125 + } 5126 + 5127 + return 0; 5128 + } 5129 + 5130 + static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr, 5131 + enum pp_clock_type type, char *buf) 5132 + { 5133 + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 5134 + struct fiji_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); 5135 + struct fiji_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); 5136 + struct fiji_single_dpm_table *pcie_table = &(data->dpm_table.pcie_speed_table); 5137 + int i, now, size = 0; 5138 + uint32_t clock, pcie_speed; 5139 + 5140 + switch (type) { 5141 + case PP_SCLK: 5142 + smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency); 5143 + clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); 5144 + 5145 + for (i = 0; i < sclk_table->count; i++) { 5146 + if (clock > sclk_table->dpm_levels[i].value) 5147 + continue; 5148 + break; 5149 + } 5150 + now = i; 5151 + 5152 + for (i = 0; i < sclk_table->count; i++) 5153 + size += sprintf(buf + size, "%d: %uMhz %s\n", 5154 + i, sclk_table->dpm_levels[i].value / 100, 5155 + (i == now) ? "*" : ""); 5156 + break; 5157 + case PP_MCLK: 5158 + smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency); 5159 + clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); 5160 + 5161 + for (i = 0; i < mclk_table->count; i++) { 5162 + if (clock > mclk_table->dpm_levels[i].value) 5163 + continue; 5164 + break; 5165 + } 5166 + now = i; 5167 + 5168 + for (i = 0; i < mclk_table->count; i++) 5169 + size += sprintf(buf + size, "%d: %uMhz %s\n", 5170 + i, mclk_table->dpm_levels[i].value / 100, 5171 + (i == now) ? "*" : ""); 5172 + break; 5173 + case PP_PCIE: 5174 + pcie_speed = fiji_get_current_pcie_speed(hwmgr); 5175 + for (i = 0; i < pcie_table->count; i++) { 5176 + if (pcie_speed != pcie_table->dpm_levels[i].value) 5177 + continue; 5178 + break; 5179 + } 5180 + now = i; 5181 + 5182 + for (i = 0; i < pcie_table->count; i++) 5183 + size += sprintf(buf + size, "%d: %s %s\n", i, 5184 + (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x1" : 5185 + (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" : 5186 + (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "", 5187 + (i == now) ? "*" : ""); 5188 + break; 5189 + default: 5190 + break; 5191 + } 5192 + return size; 5193 + } 5194 + 5076 5195 static const struct pp_hwmgr_func fiji_hwmgr_funcs = { 5077 5196 .backend_init = &fiji_hwmgr_backend_init, 5078 5197 .backend_fini = &tonga_hwmgr_backend_fini, ··· 5227 5108 .register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt, 5228 5109 .set_fan_control_mode = fiji_set_fan_control_mode, 5229 5110 .get_fan_control_mode = fiji_get_fan_control_mode, 5111 + .get_pp_table = fiji_get_pp_table, 5112 + .set_pp_table = fiji_set_pp_table, 5113 + .force_clock_level = fiji_force_clock_level, 5114 + .print_clock_levels = fiji_print_clock_levels, 5230 5115 }; 5231 5116 5232 5117 int fiji_hwmgr_init(struct pp_hwmgr *hwmgr)