Skip to content

Commit 3b718dc

Browse files
Austin Zhengalexdeucher
authored andcommitted
drm/amd/display: Filter out AC mode frequencies on DC mode systems
Why: Limit maximum clock speeds to DC mode limits for DC mode systems How: Store DC mode limits when individual clocks are initialized and cap the values when building the clock table Acked-by: Stylon Wang <[email protected]> Signed-off-by: Austin Zheng <[email protected]> Reviewed-by: Alvin Lee <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 24e52fc commit 3b718dc

File tree

5 files changed

+216
-83
lines changed

5 files changed

+216
-83
lines changed

drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,23 +182,32 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
182182
dcn32_init_single_clock(clk_mgr, PPCLK_DCFCLK,
183183
&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
184184
&num_entries_per_clk->num_dcfclk_levels);
185+
clk_mgr_base->bw_params->dc_mode_limit.dcfclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DCFCLK);
185186

186187
/* SOCCLK */
187188
dcn32_init_single_clock(clk_mgr, PPCLK_SOCCLK,
188189
&clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz,
189190
&num_entries_per_clk->num_socclk_levels);
191+
clk_mgr_base->bw_params->dc_mode_limit.socclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_SOCCLK);
190192

191193
/* DTBCLK */
192-
if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch)
194+
if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch) {
193195
dcn32_init_single_clock(clk_mgr, PPCLK_DTBCLK,
194196
&clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz,
195197
&num_entries_per_clk->num_dtbclk_levels);
198+
clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz =
199+
dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DTBCLK);
200+
}
196201

197202
/* DISPCLK */
198203
dcn32_init_single_clock(clk_mgr, PPCLK_DISPCLK,
199204
&clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz,
200205
&num_entries_per_clk->num_dispclk_levels);
201206
num_levels = num_entries_per_clk->num_dispclk_levels;
207+
clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DISPCLK);
208+
//HW recommends limit of 1950 MHz in display clock for all DCN3.2.x
209+
if (clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz > 1950)
210+
clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = 1950;
202211

203212
if (num_entries_per_clk->num_dcfclk_levels &&
204213
num_entries_per_clk->num_dtbclk_levels &&
@@ -817,13 +826,15 @@ static void dcn32_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base)
817826
dcn32_init_single_clock(clk_mgr, PPCLK_UCLK,
818827
&clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz,
819828
&num_entries_per_clk->num_memclk_levels);
829+
clk_mgr_base->bw_params->dc_mode_limit.memclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_UCLK);
820830

821831
/* memclk must have at least one level */
822832
num_entries_per_clk->num_memclk_levels = num_entries_per_clk->num_memclk_levels ? num_entries_per_clk->num_memclk_levels : 1;
823833

824834
dcn32_init_single_clock(clk_mgr, PPCLK_FCLK,
825835
&clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz,
826836
&num_entries_per_clk->num_fclk_levels);
837+
clk_mgr_base->bw_params->dc_mode_limit.fclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_FCLK);
827838

828839
if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) {
829840
num_levels = num_entries_per_clk->num_memclk_levels;

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,7 @@ struct dc_debug_options {
897897
uint32_t fpo_vactive_min_active_margin_us;
898898
uint32_t fpo_vactive_max_blank_us;
899899
bool enable_legacy_fast_update;
900+
bool disable_dc_mode_overwrite;
900901
};
901902

902903
struct gpu_info_soc_bounding_box_v1_0;

drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c

Lines changed: 100 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,14 +2325,48 @@ void dcn32_patch_dpm_table(struct clk_bw_params *bw_params)
23252325
bw_params->clk_table.entries[0].memclk_mhz = dcn3_2_soc.clock_limits[0].dram_speed_mts / 16;
23262326
}
23272327

2328-
static int build_synthetic_soc_states(struct clk_bw_params *bw_params,
2328+
/*
2329+
* override_max_clk_values - Overwrite the max clock frequencies with the max DC mode timings
2330+
* Input:
2331+
* max_clk_limit - struct containing the desired clock timings
2332+
* Output:
2333+
* curr_clk_limit - struct containing the timings that need to be overwritten
2334+
* Return: 0 upon success, non-zero for failure
2335+
*/
2336+
static int override_max_clk_values(struct clk_limit_table_entry *max_clk_limit,
2337+
struct clk_limit_table_entry *curr_clk_limit)
2338+
{
2339+
if (NULL == max_clk_limit || NULL == curr_clk_limit)
2340+
return -1; //invalid parameters
2341+
2342+
//only overwrite if desired max clock frequency is initialized
2343+
if (max_clk_limit->dcfclk_mhz != 0)
2344+
curr_clk_limit->dcfclk_mhz = max_clk_limit->dcfclk_mhz;
2345+
2346+
if (max_clk_limit->fclk_mhz != 0)
2347+
curr_clk_limit->fclk_mhz = max_clk_limit->fclk_mhz;
2348+
2349+
if (max_clk_limit->memclk_mhz != 0)
2350+
curr_clk_limit->memclk_mhz = max_clk_limit->memclk_mhz;
2351+
2352+
if (max_clk_limit->socclk_mhz != 0)
2353+
curr_clk_limit->socclk_mhz = max_clk_limit->socclk_mhz;
2354+
2355+
if (max_clk_limit->dtbclk_mhz != 0)
2356+
curr_clk_limit->dtbclk_mhz = max_clk_limit->dtbclk_mhz;
2357+
2358+
if (max_clk_limit->dispclk_mhz != 0)
2359+
curr_clk_limit->dispclk_mhz = max_clk_limit->dispclk_mhz;
2360+
2361+
return 0;
2362+
}
2363+
2364+
static int build_synthetic_soc_states(bool disable_dc_mode_overwrite, struct clk_bw_params *bw_params,
23292365
struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries)
23302366
{
23312367
int i, j;
23322368
struct _vcs_dpi_voltage_scaling_st entry = {0};
2333-
2334-
unsigned int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0,
2335-
max_phyclk_mhz = 0, max_dtbclk_mhz = 0, max_fclk_mhz = 0, max_uclk_mhz = 0;
2369+
struct clk_limit_table_entry max_clk_data = {0};
23362370

23372371
unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
23382372

@@ -2343,51 +2377,76 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params,
23432377
unsigned int num_fclk_dpms = 0;
23442378
unsigned int num_dcfclk_dpms = 0;
23452379

2346-
for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
2347-
if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
2348-
max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
2349-
if (bw_params->clk_table.entries[i].fclk_mhz > max_fclk_mhz)
2350-
max_fclk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
2351-
if (bw_params->clk_table.entries[i].memclk_mhz > max_uclk_mhz)
2352-
max_uclk_mhz = bw_params->clk_table.entries[i].memclk_mhz;
2353-
if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
2354-
max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
2355-
if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
2356-
max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
2357-
if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
2358-
max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
2359-
if (bw_params->clk_table.entries[i].dtbclk_mhz > max_dtbclk_mhz)
2360-
max_dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
2380+
unsigned int num_dc_uclk_dpms = 0;
2381+
unsigned int num_dc_fclk_dpms = 0;
2382+
unsigned int num_dc_dcfclk_dpms = 0;
23612383

2362-
if (bw_params->clk_table.entries[i].memclk_mhz > 0)
2384+
for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
2385+
if (bw_params->clk_table.entries[i].dcfclk_mhz > max_clk_data.dcfclk_mhz)
2386+
max_clk_data.dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
2387+
if (bw_params->clk_table.entries[i].fclk_mhz > max_clk_data.fclk_mhz)
2388+
max_clk_data.fclk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
2389+
if (bw_params->clk_table.entries[i].memclk_mhz > max_clk_data.memclk_mhz)
2390+
max_clk_data.memclk_mhz = bw_params->clk_table.entries[i].memclk_mhz;
2391+
if (bw_params->clk_table.entries[i].dispclk_mhz > max_clk_data.dispclk_mhz)
2392+
max_clk_data.dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
2393+
if (bw_params->clk_table.entries[i].dppclk_mhz > max_clk_data.dppclk_mhz)
2394+
max_clk_data.dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
2395+
if (bw_params->clk_table.entries[i].phyclk_mhz > max_clk_data.phyclk_mhz)
2396+
max_clk_data.phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
2397+
if (bw_params->clk_table.entries[i].dtbclk_mhz > max_clk_data.dtbclk_mhz)
2398+
max_clk_data.dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
2399+
2400+
if (bw_params->clk_table.entries[i].memclk_mhz > 0) {
23632401
num_uclk_dpms++;
2364-
if (bw_params->clk_table.entries[i].fclk_mhz > 0)
2402+
if (bw_params->clk_table.entries[i].memclk_mhz <= bw_params->dc_mode_limit.memclk_mhz)
2403+
num_dc_uclk_dpms++;
2404+
}
2405+
if (bw_params->clk_table.entries[i].fclk_mhz > 0) {
23652406
num_fclk_dpms++;
2366-
if (bw_params->clk_table.entries[i].dcfclk_mhz > 0)
2407+
if (bw_params->clk_table.entries[i].fclk_mhz <= bw_params->dc_mode_limit.fclk_mhz)
2408+
num_dc_fclk_dpms++;
2409+
}
2410+
if (bw_params->clk_table.entries[i].dcfclk_mhz > 0) {
23672411
num_dcfclk_dpms++;
2412+
if (bw_params->clk_table.entries[i].dcfclk_mhz <= bw_params->dc_mode_limit.dcfclk_mhz)
2413+
num_dc_dcfclk_dpms++;
2414+
}
2415+
}
2416+
2417+
if (!disable_dc_mode_overwrite) {
2418+
//Overwrite max frequencies with max DC mode frequencies for DC mode systems
2419+
override_max_clk_values(&bw_params->dc_mode_limit, &max_clk_data);
2420+
num_uclk_dpms = num_dc_uclk_dpms;
2421+
num_fclk_dpms = num_dc_fclk_dpms;
2422+
num_dcfclk_dpms = num_dc_dcfclk_dpms;
2423+
bw_params->clk_table.num_entries_per_clk.num_memclk_levels = num_uclk_dpms;
2424+
bw_params->clk_table.num_entries_per_clk.num_fclk_levels = num_fclk_dpms;
23682425
}
23692426

23702427
if (num_dcfclk_dpms > 0 && bw_params->clk_table.entries[0].fclk_mhz > min_fclk_mhz)
23712428
min_fclk_mhz = bw_params->clk_table.entries[0].fclk_mhz;
23722429

2373-
if (!max_dcfclk_mhz || !max_dispclk_mhz || !max_dtbclk_mhz)
2430+
if (!max_clk_data.dcfclk_mhz || !max_clk_data.dispclk_mhz || !max_clk_data.dtbclk_mhz)
23742431
return -1;
23752432

2376-
if (max_dppclk_mhz == 0)
2377-
max_dppclk_mhz = max_dispclk_mhz;
2433+
if (max_clk_data.dppclk_mhz == 0)
2434+
max_clk_data.dppclk_mhz = max_clk_data.dispclk_mhz;
23782435

2379-
if (max_fclk_mhz == 0)
2380-
max_fclk_mhz = max_dcfclk_mhz * dcn3_2_soc.pct_ideal_sdp_bw_after_urgent / dcn3_2_soc.pct_ideal_fabric_bw_after_urgent;
2436+
if (max_clk_data.fclk_mhz == 0)
2437+
max_clk_data.fclk_mhz = max_clk_data.dcfclk_mhz *
2438+
dcn3_2_soc.pct_ideal_sdp_bw_after_urgent /
2439+
dcn3_2_soc.pct_ideal_fabric_bw_after_urgent;
23812440

2382-
if (max_phyclk_mhz == 0)
2383-
max_phyclk_mhz = dcn3_2_soc.clock_limits[0].phyclk_mhz;
2441+
if (max_clk_data.phyclk_mhz == 0)
2442+
max_clk_data.phyclk_mhz = dcn3_2_soc.clock_limits[0].phyclk_mhz;
23842443

23852444
*num_entries = 0;
2386-
entry.dispclk_mhz = max_dispclk_mhz;
2387-
entry.dscclk_mhz = max_dispclk_mhz / 3;
2388-
entry.dppclk_mhz = max_dppclk_mhz;
2389-
entry.dtbclk_mhz = max_dtbclk_mhz;
2390-
entry.phyclk_mhz = max_phyclk_mhz;
2445+
entry.dispclk_mhz = max_clk_data.dispclk_mhz;
2446+
entry.dscclk_mhz = max_clk_data.dispclk_mhz / 3;
2447+
entry.dppclk_mhz = max_clk_data.dppclk_mhz;
2448+
entry.dtbclk_mhz = max_clk_data.dtbclk_mhz;
2449+
entry.phyclk_mhz = max_clk_data.phyclk_mhz;
23912450
entry.phyclk_d18_mhz = dcn3_2_soc.clock_limits[0].phyclk_d18_mhz;
23922451
entry.phyclk_d32_mhz = dcn3_2_soc.clock_limits[0].phyclk_d32_mhz;
23932452

@@ -2401,7 +2460,7 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params,
24012460
}
24022461

24032462
// Insert the max DCFCLK
2404-
entry.dcfclk_mhz = max_dcfclk_mhz;
2463+
entry.dcfclk_mhz = max_clk_data.dcfclk_mhz;
24052464
entry.fabricclk_mhz = 0;
24062465
entry.dram_speed_mts = 0;
24072466

@@ -2429,7 +2488,7 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params,
24292488
// If FCLK fine grained, only insert max
24302489
else {
24312490
entry.dcfclk_mhz = 0;
2432-
entry.fabricclk_mhz = max_fclk_mhz;
2491+
entry.fabricclk_mhz = max_clk_data.fclk_mhz;
24332492
entry.dram_speed_mts = 0;
24342493

24352494
insert_entry_into_table_sorted(table, num_entries, &entry);
@@ -2441,9 +2500,9 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params,
24412500

24422501
// Remove states that require higher clocks than are supported
24432502
for (i = *num_entries - 1; i >= 0 ; i--) {
2444-
if (table[i].dcfclk_mhz > max_dcfclk_mhz ||
2445-
table[i].fabricclk_mhz > max_fclk_mhz ||
2446-
table[i].dram_speed_mts > max_uclk_mhz * 16)
2503+
if (table[i].dcfclk_mhz > max_clk_data.dcfclk_mhz ||
2504+
table[i].fabricclk_mhz > max_clk_data.fclk_mhz ||
2505+
table[i].dram_speed_mts > max_clk_data.memclk_mhz * 16)
24472506
remove_entry_from_table_at_index(table, num_entries, i);
24482507
}
24492508

@@ -2756,7 +2815,8 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa
27562815
dcn3_2_soc.clock_limits[i].phyclk_d32_mhz = dcn3_2_soc.clock_limits[0].phyclk_d32_mhz;
27572816
}
27582817
} else {
2759-
build_synthetic_soc_states(bw_params, dcn3_2_soc.clock_limits, &dcn3_2_soc.num_states);
2818+
build_synthetic_soc_states(dc->debug.disable_dc_mode_overwrite, bw_params,
2819+
dcn3_2_soc.clock_limits, &dcn3_2_soc.num_states);
27602820
}
27612821

27622822
/* Re-init DML with updated bb */

0 commit comments

Comments
 (0)