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>
This commit is contained in:
@@ -5073,6 +5073,125 @@ static int fiji_get_fan_control_mode(struct pp_hwmgr *hwmgr)
|
|||||||
CG_FDO_CTRL2, FDO_PWM_MODE);
|
CG_FDO_CTRL2, FDO_PWM_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fiji_get_pp_table(struct pp_hwmgr *hwmgr, char **table)
|
||||||
|
{
|
||||||
|
struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
|
||||||
|
|
||||||
|
*table = (char *)&data->smc_state_table;
|
||||||
|
|
||||||
|
return sizeof(struct SMU73_Discrete_DpmTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fiji_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size)
|
||||||
|
{
|
||||||
|
struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
|
||||||
|
|
||||||
|
void *table = (void *)&data->smc_state_table;
|
||||||
|
|
||||||
|
memcpy(table, buf, size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fiji_force_clock_level(struct pp_hwmgr *hwmgr,
|
||||||
|
enum pp_clock_type type, int level)
|
||||||
|
{
|
||||||
|
struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
|
||||||
|
|
||||||
|
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PP_SCLK:
|
||||||
|
if (!data->sclk_dpm_key_disabled)
|
||||||
|
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
|
||||||
|
PPSMC_MSG_SCLKDPM_SetEnabledMask,
|
||||||
|
(1 << level));
|
||||||
|
break;
|
||||||
|
case PP_MCLK:
|
||||||
|
if (!data->mclk_dpm_key_disabled)
|
||||||
|
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
|
||||||
|
PPSMC_MSG_MCLKDPM_SetEnabledMask,
|
||||||
|
(1 << level));
|
||||||
|
break;
|
||||||
|
case PP_PCIE:
|
||||||
|
if (!data->pcie_dpm_key_disabled)
|
||||||
|
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
|
||||||
|
PPSMC_MSG_PCIeDPM_ForceLevel,
|
||||||
|
(1 << level));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr,
|
||||||
|
enum pp_clock_type type, char *buf)
|
||||||
|
{
|
||||||
|
struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
|
||||||
|
struct fiji_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
|
||||||
|
struct fiji_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
|
||||||
|
struct fiji_single_dpm_table *pcie_table = &(data->dpm_table.pcie_speed_table);
|
||||||
|
int i, now, size = 0;
|
||||||
|
uint32_t clock, pcie_speed;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PP_SCLK:
|
||||||
|
smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency);
|
||||||
|
clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
|
||||||
|
|
||||||
|
for (i = 0; i < sclk_table->count; i++) {
|
||||||
|
if (clock > sclk_table->dpm_levels[i].value)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
now = i;
|
||||||
|
|
||||||
|
for (i = 0; i < sclk_table->count; i++)
|
||||||
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
||||||
|
i, sclk_table->dpm_levels[i].value / 100,
|
||||||
|
(i == now) ? "*" : "");
|
||||||
|
break;
|
||||||
|
case PP_MCLK:
|
||||||
|
smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency);
|
||||||
|
clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
|
||||||
|
|
||||||
|
for (i = 0; i < mclk_table->count; i++) {
|
||||||
|
if (clock > mclk_table->dpm_levels[i].value)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
now = i;
|
||||||
|
|
||||||
|
for (i = 0; i < mclk_table->count; i++)
|
||||||
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
||||||
|
i, mclk_table->dpm_levels[i].value / 100,
|
||||||
|
(i == now) ? "*" : "");
|
||||||
|
break;
|
||||||
|
case PP_PCIE:
|
||||||
|
pcie_speed = fiji_get_current_pcie_speed(hwmgr);
|
||||||
|
for (i = 0; i < pcie_table->count; i++) {
|
||||||
|
if (pcie_speed != pcie_table->dpm_levels[i].value)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
now = i;
|
||||||
|
|
||||||
|
for (i = 0; i < pcie_table->count; i++)
|
||||||
|
size += sprintf(buf + size, "%d: %s %s\n", i,
|
||||||
|
(pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x1" :
|
||||||
|
(pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" :
|
||||||
|
(pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "",
|
||||||
|
(i == now) ? "*" : "");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
|
static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
|
||||||
.backend_init = &fiji_hwmgr_backend_init,
|
.backend_init = &fiji_hwmgr_backend_init,
|
||||||
.backend_fini = &tonga_hwmgr_backend_fini,
|
.backend_fini = &tonga_hwmgr_backend_fini,
|
||||||
@@ -5108,6 +5227,10 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
|
|||||||
.register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt,
|
.register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt,
|
||||||
.set_fan_control_mode = fiji_set_fan_control_mode,
|
.set_fan_control_mode = fiji_set_fan_control_mode,
|
||||||
.get_fan_control_mode = fiji_get_fan_control_mode,
|
.get_fan_control_mode = fiji_get_fan_control_mode,
|
||||||
|
.get_pp_table = fiji_get_pp_table,
|
||||||
|
.set_pp_table = fiji_set_pp_table,
|
||||||
|
.force_clock_level = fiji_force_clock_level,
|
||||||
|
.print_clock_levels = fiji_print_clock_levels,
|
||||||
};
|
};
|
||||||
|
|
||||||
int fiji_hwmgr_init(struct pp_hwmgr *hwmgr)
|
int fiji_hwmgr_init(struct pp_hwmgr *hwmgr)
|
||||||
|
Reference in New Issue
Block a user