Commit 2e069391 authored by Huang Rui's avatar Huang Rui Committed by Alex Deucher

drm/amd/powerplay: implement interface to set watermarks for clock ranges

This patch implements inteferface to set watermarks table for clock ranges on
smu 11. It fills watermark table before it is written to SMC.
Signed-off-by: default avatarHuang Rui <ray.huang@amd.com>
Reviewed-by: default avatarKevin Wang <Kevin1.Wang@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 367eeed4
......@@ -548,9 +548,6 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp,
wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
if (!pp_funcs || !pp_funcs->set_watermarks_for_clocks_ranges)
return;
for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
if (ranges->reader_wm_sets[i].wm_inst > 3)
wm_dce_clocks[i].wm_set_id = WM_SET_A;
......@@ -583,7 +580,13 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp,
ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
}
pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges);
if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
&wm_with_clock_ranges);
else if (adev->smu.funcs &&
adev->smu.funcs->set_watermarks_for_clock_ranges)
smu_set_watermarks_for_clock_ranges(&adev->smu,
&wm_with_clock_ranges);
}
void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
......
......@@ -329,6 +329,7 @@ static int smu_sw_init(void *handle)
bitmap_zero(smu->smu_feature.supported, SMU_FEATURE_MAX);
bitmap_zero(smu->smu_feature.enabled, SMU_FEATURE_MAX);
bitmap_zero(smu->smu_feature.allowed, SMU_FEATURE_MAX);
smu->watermarks_bitmap = 0;
ret = smu_init_microcode(smu);
if (ret) {
......
......@@ -235,6 +235,11 @@ struct smu_context
uint32_t default_power_limit;
bool support_power_containment;
bool disable_watermark;
#define WATERMARKS_EXIST (1 << 0)
#define WATERMARKS_LOADED (1 << 1)
uint32_t watermarks_bitmap;
};
struct pptable_funcs {
......@@ -320,6 +325,8 @@ struct smu_funcs
int (*get_current_shallow_sleep_clocks)(struct smu_context *smu,
struct smu_clock_info *clocks);
int (*notify_smu_enable_pwe)(struct smu_context *smu);
int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
};
#define smu_init_microcode(smu) \
......@@ -439,6 +446,8 @@ struct smu_funcs
((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0)
#define smu_notify_smu_enable_pwe(smu) \
((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0)
#define smu_set_watermarks_for_clock_ranges(smu, clock_ranges) \
((smu)->funcs->set_watermarks_for_clock_ranges ? (smu)->funcs->set_watermarks_for_clock_ranges((smu), (clock_ranges)) : 0)
extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
......
......@@ -1167,6 +1167,85 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
return ret;
}
static int smu_v11_0_set_watermarks_table(struct smu_context *smu,
Watermarks_t *table, struct
dm_pp_wm_sets_with_clock_ranges_soc15
*clock_ranges)
{
int i;
if (!table || !clock_ranges)
return -EINVAL;
if (clock_ranges->num_wm_dmif_sets > 4 ||
clock_ranges->num_wm_mcif_sets > 4)
return -EINVAL;
for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) {
table->WatermarkRow[1][i].MinClock =
cpu_to_le16((uint16_t)
(clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz /
1000));
table->WatermarkRow[1][i].MaxClock =
cpu_to_le16((uint16_t)
(clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz /
1000));
table->WatermarkRow[1][i].MinUclk =
cpu_to_le16((uint16_t)
(clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz /
1000));
table->WatermarkRow[1][i].MaxUclk =
cpu_to_le16((uint16_t)
(clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz /
1000));
table->WatermarkRow[1][i].WmSetting = (uint8_t)
clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
}
for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) {
table->WatermarkRow[0][i].MinClock =
cpu_to_le16((uint16_t)
(clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz /
1000));
table->WatermarkRow[0][i].MaxClock =
cpu_to_le16((uint16_t)
(clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz /
1000));
table->WatermarkRow[0][i].MinUclk =
cpu_to_le16((uint16_t)
(clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz /
1000));
table->WatermarkRow[0][i].MaxUclk =
cpu_to_le16((uint16_t)
(clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz /
1000));
table->WatermarkRow[0][i].WmSetting = (uint8_t)
clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
}
return 0;
}
static int
smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct
dm_pp_wm_sets_with_clock_ranges_soc15
*clock_ranges)
{
int ret = 0;
struct smu_table *watermarks = &smu->smu_table.tables[TABLE_WATERMARKS];
Watermarks_t *table = watermarks->cpu_addr;
if (!smu->disable_watermark &&
smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT) &&
smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
smu_v11_0_set_watermarks_table(smu, table, clock_ranges);
smu->watermarks_bitmap |= WATERMARKS_EXIST;
smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
}
return ret;
}
static const struct smu_funcs smu_v11_0_funcs = {
.init_microcode = smu_v11_0_init_microcode,
.load_microcode = smu_v11_0_load_microcode,
......@@ -1202,6 +1281,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
.read_sensor = smu_v11_0_read_sensor,
.set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
.set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges,
};
void smu_v11_0_set_smu_funcs(struct smu_context *smu)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment