|
@@ -1875,38 +1875,20 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static int vega20_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx_freq)
|
|
|
|
|
|
+static int vega20_get_current_clk_freq(struct pp_hwmgr *hwmgr,
|
|
|
|
+ PPCLK_e clk_id, uint32_t *clk_freq)
|
|
{
|
|
{
|
|
- uint32_t gfx_clk = 0;
|
|
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
- *gfx_freq = 0;
|
|
|
|
|
|
+ *clk_freq = 0;
|
|
|
|
|
|
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
|
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
|
- PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16))) == 0,
|
|
|
|
- "[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!",
|
|
|
|
|
|
+ PPSMC_MSG_GetDpmClockFreq, (clk_id << 16))) == 0,
|
|
|
|
+ "[GetCurrentClkFreq] Attempt to get Current Frequency Failed!",
|
|
return ret);
|
|
return ret);
|
|
- gfx_clk = smum_get_argument(hwmgr);
|
|
|
|
|
|
+ *clk_freq = smum_get_argument(hwmgr);
|
|
|
|
|
|
- *gfx_freq = gfx_clk * 100;
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int vega20_get_current_mclk_freq(struct pp_hwmgr *hwmgr, uint32_t *mclk_freq)
|
|
|
|
-{
|
|
|
|
- uint32_t mem_clk = 0;
|
|
|
|
- int ret = 0;
|
|
|
|
-
|
|
|
|
- *mclk_freq = 0;
|
|
|
|
-
|
|
|
|
- PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
|
|
|
- PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16))) == 0,
|
|
|
|
- "[GetCurrentMClkFreq] Attempt to get Current MCLK Frequency Failed!",
|
|
|
|
- return ret);
|
|
|
|
- mem_clk = smum_get_argument(hwmgr);
|
|
|
|
-
|
|
|
|
- *mclk_freq = mem_clk * 100;
|
|
|
|
|
|
+ *clk_freq = *clk_freq * 100;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1937,12 +1919,16 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx,
|
|
|
|
|
|
switch (idx) {
|
|
switch (idx) {
|
|
case AMDGPU_PP_SENSOR_GFX_SCLK:
|
|
case AMDGPU_PP_SENSOR_GFX_SCLK:
|
|
- ret = vega20_get_current_gfx_clk_freq(hwmgr, (uint32_t *)value);
|
|
|
|
|
|
+ ret = vega20_get_current_clk_freq(hwmgr,
|
|
|
|
+ PPCLK_GFXCLK,
|
|
|
|
+ (uint32_t *)value);
|
|
if (!ret)
|
|
if (!ret)
|
|
*size = 4;
|
|
*size = 4;
|
|
break;
|
|
break;
|
|
case AMDGPU_PP_SENSOR_GFX_MCLK:
|
|
case AMDGPU_PP_SENSOR_GFX_MCLK:
|
|
- ret = vega20_get_current_mclk_freq(hwmgr, (uint32_t *)value);
|
|
|
|
|
|
+ ret = vega20_get_current_clk_freq(hwmgr,
|
|
|
|
+ PPCLK_UCLK,
|
|
|
|
+ (uint32_t *)value);
|
|
if (!ret)
|
|
if (!ret)
|
|
*size = 4;
|
|
*size = 4;
|
|
break;
|
|
break;
|
|
@@ -2012,7 +1998,6 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
|
|
if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
|
|
if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
|
|
switch (clk_type) {
|
|
switch (clk_type) {
|
|
case amd_pp_dcef_clock:
|
|
case amd_pp_dcef_clock:
|
|
- clk_freq = clock_req->clock_freq_in_khz / 100;
|
|
|
|
clk_select = PPCLK_DCEFCLK;
|
|
clk_select = PPCLK_DCEFCLK;
|
|
break;
|
|
break;
|
|
case amd_pp_disp_clock:
|
|
case amd_pp_disp_clock:
|
|
@@ -2041,11 +2026,20 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int vega20_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
|
|
|
|
+ PHM_PerformanceLevelDesignation designation, uint32_t index,
|
|
|
|
+ PHM_PerformanceLevel *level)
|
|
|
|
+{
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int vega20_notify_smc_display_config_after_ps_adjustment(
|
|
static int vega20_notify_smc_display_config_after_ps_adjustment(
|
|
struct pp_hwmgr *hwmgr)
|
|
struct pp_hwmgr *hwmgr)
|
|
{
|
|
{
|
|
struct vega20_hwmgr *data =
|
|
struct vega20_hwmgr *data =
|
|
(struct vega20_hwmgr *)(hwmgr->backend);
|
|
(struct vega20_hwmgr *)(hwmgr->backend);
|
|
|
|
+ struct vega20_single_dpm_table *dpm_table =
|
|
|
|
+ &data->dpm_table.mem_table;
|
|
struct PP_Clocks min_clocks = {0};
|
|
struct PP_Clocks min_clocks = {0};
|
|
struct pp_display_clock_request clock_req;
|
|
struct pp_display_clock_request clock_req;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
@@ -2063,7 +2057,7 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
|
|
|
|
|
|
if (data->smu_features[GNLD_DPM_DCEFCLK].supported) {
|
|
if (data->smu_features[GNLD_DPM_DCEFCLK].supported) {
|
|
clock_req.clock_type = amd_pp_dcef_clock;
|
|
clock_req.clock_type = amd_pp_dcef_clock;
|
|
- clock_req.clock_freq_in_khz = min_clocks.dcefClock;
|
|
|
|
|
|
+ clock_req.clock_freq_in_khz = min_clocks.dcefClock * 10;
|
|
if (!vega20_display_clock_voltage_request(hwmgr, &clock_req)) {
|
|
if (!vega20_display_clock_voltage_request(hwmgr, &clock_req)) {
|
|
if (data->smu_features[GNLD_DS_DCEFCLK].supported)
|
|
if (data->smu_features[GNLD_DS_DCEFCLK].supported)
|
|
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(
|
|
PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(
|
|
@@ -2076,6 +2070,15 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (data->smu_features[GNLD_DPM_UCLK].enabled) {
|
|
|
|
+ dpm_table->dpm_state.hard_min_level = min_clocks.memoryClock / 100;
|
|
|
|
+ PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
|
|
|
+ PPSMC_MSG_SetHardMinByFreq,
|
|
|
|
+ (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level)),
|
|
|
|
+ "[SetHardMinFreq] Set hard min uclk failed!",
|
|
|
|
+ return ret);
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2353,7 +2356,7 @@ static int vega20_get_sclks(struct pp_hwmgr *hwmgr,
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
for (i = 0; i < count; i++) {
|
|
clocks->data[i].clocks_in_khz =
|
|
clocks->data[i].clocks_in_khz =
|
|
- dpm_table->dpm_levels[i].value * 100;
|
|
|
|
|
|
+ dpm_table->dpm_levels[i].value * 1000;
|
|
clocks->data[i].latency_in_us = 0;
|
|
clocks->data[i].latency_in_us = 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2383,7 +2386,7 @@ static int vega20_get_memclocks(struct pp_hwmgr *hwmgr,
|
|
for (i = 0; i < count; i++) {
|
|
for (i = 0; i < count; i++) {
|
|
clocks->data[i].clocks_in_khz =
|
|
clocks->data[i].clocks_in_khz =
|
|
data->mclk_latency_table.entries[i].frequency =
|
|
data->mclk_latency_table.entries[i].frequency =
|
|
- dpm_table->dpm_levels[i].value * 100;
|
|
|
|
|
|
+ dpm_table->dpm_levels[i].value * 1000;
|
|
clocks->data[i].latency_in_us =
|
|
clocks->data[i].latency_in_us =
|
|
data->mclk_latency_table.entries[i].latency =
|
|
data->mclk_latency_table.entries[i].latency =
|
|
vega20_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value);
|
|
vega20_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value);
|
|
@@ -2408,7 +2411,7 @@ static int vega20_get_dcefclocks(struct pp_hwmgr *hwmgr,
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
for (i = 0; i < count; i++) {
|
|
clocks->data[i].clocks_in_khz =
|
|
clocks->data[i].clocks_in_khz =
|
|
- dpm_table->dpm_levels[i].value * 100;
|
|
|
|
|
|
+ dpm_table->dpm_levels[i].value * 1000;
|
|
clocks->data[i].latency_in_us = 0;
|
|
clocks->data[i].latency_in_us = 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2431,7 +2434,7 @@ static int vega20_get_socclocks(struct pp_hwmgr *hwmgr,
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
for (i = 0; i < count; i++) {
|
|
clocks->data[i].clocks_in_khz =
|
|
clocks->data[i].clocks_in_khz =
|
|
- dpm_table->dpm_levels[i].value * 100;
|
|
|
|
|
|
+ dpm_table->dpm_levels[i].value * 1000;
|
|
clocks->data[i].latency_in_us = 0;
|
|
clocks->data[i].latency_in_us = 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2582,11 +2585,11 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- if (input_clk < clocks.data[0].clocks_in_khz / 100 ||
|
|
|
|
|
|
+ if (input_clk < clocks.data[0].clocks_in_khz / 1000 ||
|
|
input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) {
|
|
input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) {
|
|
pr_info("clock freq %d is not within allowed range [%d - %d]\n",
|
|
pr_info("clock freq %d is not within allowed range [%d - %d]\n",
|
|
input_clk,
|
|
input_clk,
|
|
- clocks.data[0].clocks_in_khz / 100,
|
|
|
|
|
|
+ clocks.data[0].clocks_in_khz / 1000,
|
|
od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
|
|
od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
@@ -2726,7 +2729,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|
|
|
|
|
switch (type) {
|
|
switch (type) {
|
|
case PP_SCLK:
|
|
case PP_SCLK:
|
|
- ret = vega20_get_current_gfx_clk_freq(hwmgr, &now);
|
|
|
|
|
|
+ ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now);
|
|
PP_ASSERT_WITH_CODE(!ret,
|
|
PP_ASSERT_WITH_CODE(!ret,
|
|
"Attempt to get current gfx clk Failed!",
|
|
"Attempt to get current gfx clk Failed!",
|
|
return ret);
|
|
return ret);
|
|
@@ -2738,12 +2741,12 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|
|
|
|
|
for (i = 0; i < clocks.num_levels; i++)
|
|
for (i = 0; i < clocks.num_levels; i++)
|
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
|
- i, clocks.data[i].clocks_in_khz / 100,
|
|
|
|
|
|
+ i, clocks.data[i].clocks_in_khz / 1000,
|
|
(clocks.data[i].clocks_in_khz == now) ? "*" : "");
|
|
(clocks.data[i].clocks_in_khz == now) ? "*" : "");
|
|
break;
|
|
break;
|
|
|
|
|
|
case PP_MCLK:
|
|
case PP_MCLK:
|
|
- ret = vega20_get_current_mclk_freq(hwmgr, &now);
|
|
|
|
|
|
+ ret = vega20_get_current_clk_freq(hwmgr, PPCLK_UCLK, &now);
|
|
PP_ASSERT_WITH_CODE(!ret,
|
|
PP_ASSERT_WITH_CODE(!ret,
|
|
"Attempt to get current mclk freq Failed!",
|
|
"Attempt to get current mclk freq Failed!",
|
|
return ret);
|
|
return ret);
|
|
@@ -2755,7 +2758,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|
|
|
|
|
for (i = 0; i < clocks.num_levels; i++)
|
|
for (i = 0; i < clocks.num_levels; i++)
|
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
|
- i, clocks.data[i].clocks_in_khz / 100,
|
|
|
|
|
|
+ i, clocks.data[i].clocks_in_khz / 1000,
|
|
(clocks.data[i].clocks_in_khz == now) ? "*" : "");
|
|
(clocks.data[i].clocks_in_khz == now) ? "*" : "");
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -2820,7 +2823,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|
return ret);
|
|
return ret);
|
|
|
|
|
|
size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
|
|
size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
|
|
- clocks.data[0].clocks_in_khz / 100,
|
|
|
|
|
|
+ clocks.data[0].clocks_in_khz / 1000,
|
|
od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
|
|
od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3476,6 +3479,8 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
|
|
vega20_set_watermarks_for_clocks_ranges,
|
|
vega20_set_watermarks_for_clocks_ranges,
|
|
.display_clock_voltage_request =
|
|
.display_clock_voltage_request =
|
|
vega20_display_clock_voltage_request,
|
|
vega20_display_clock_voltage_request,
|
|
|
|
+ .get_performance_level =
|
|
|
|
+ vega20_get_performance_level,
|
|
/* UMD pstate, profile related */
|
|
/* UMD pstate, profile related */
|
|
.force_dpm_level =
|
|
.force_dpm_level =
|
|
vega20_dpm_force_dpm_level,
|
|
vega20_dpm_force_dpm_level,
|