From: Daniel Miess Date: Tue, 17 Jan 2023 20:23:06 +0000 (-0500) Subject: drm/amd/display: Correct bw_params population X-Git-Tag: v6.6.7~3356^2~10^2~27 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f5df7725e38853b5b07b7ab41017916f1e5b4e57;p=platform%2Fkernel%2Flinux-starfive.git drm/amd/display: Correct bw_params population [Why] Underflow observed during P010 video playback on dcn314 due to incorrectly populated bw_params [How] Populate fclk, memclk and voltage in bw_params with values from max pstate rather than min pstate Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Daniel Miess Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c index 89df7244b272..f5276bacfa4e 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c @@ -572,10 +572,11 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl { struct clk_bw_params *bw_params = clk_mgr->base.bw_params; struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1]; - uint32_t max_pstate = 0, max_fclk = 0, min_pstate = 0, max_dispclk = 0, max_dppclk = 0; + uint32_t max_pstate = 0, max_fclk = 0, max_dispclk = 0, max_dppclk = 0; + uint32_t min_pstate = 0, min_fclk = clock_table->DfPstateTable[0].FClk; int i; - /* Find highest valid fclk pstate */ + /* Find highest and lowest valid fclk pstate */ for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) { if (is_valid_clock_value(clock_table->DfPstateTable[i].FClk) && clock_table->DfPstateTable[i].FClk > max_fclk) { @@ -584,6 +585,14 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl } } + for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) { + if (is_valid_clock_value(clock_table->DfPstateTable[i].FClk) && + clock_table->DfPstateTable[i].FClk < min_fclk) { + min_fclk = clock_table->DfPstateTable[i].FClk; + min_pstate = i; + } + } + /* We expect the table to contain at least one valid fclk entry. */ ASSERT(is_valid_clock_value(max_fclk)); @@ -599,15 +608,17 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl /* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */ for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) { - uint32_t min_fclk = clock_table->DfPstateTable[0].FClk; + uint32_t max_level_fclk = clock_table->DfPstateTable[0].FClk; + uint32_t max_level_pstate = 0; int j; + /* Look for the maximum supported FCLK for the current voltage. */ for (j = 1; j < clock_table->NumDfPstatesEnabled; j++) { if (is_valid_clock_value(clock_table->DfPstateTable[j].FClk) && - clock_table->DfPstateTable[j].FClk < min_fclk && + clock_table->DfPstateTable[j].FClk > max_level_fclk && clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i]) { - min_fclk = clock_table->DfPstateTable[j].FClk; - min_pstate = j; + max_level_fclk = clock_table->DfPstateTable[j].FClk; + max_level_pstate = j; } } @@ -621,15 +632,15 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl bw_params->clk_table.entries[i].dtbclk_mhz = bw_params->clk_table.entries[j].dtbclk_mhz; /* Now update clocks we do read */ - bw_params->clk_table.entries[i].fclk_mhz = min_fclk; - bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk; - bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_pstate].Voltage; + bw_params->clk_table.entries[i].fclk_mhz = max_level_fclk; + bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_level_pstate].MemClk; + bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_level_pstate].Voltage; bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i]; bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i]; bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio( - clock_table->DfPstateTable[min_pstate].WckRatio); + clock_table->DfPstateTable[max_level_pstate].WckRatio); } /* Make sure to include at least one entry at highest pstate */