提交 28c25238 编写于 作者: D Dmytro Laktyushkin 提交者: Alex Deucher

drm/amd/display: update dcn315 clock table read

[Why & How]
Make dcn315 base its clock table off dcfclk rather than fclk.

This change also adds some sanity checking to make sure an
empty pmfw table does not result in invalid dal clocks.
Reviewed-by: NCharlene Liu <Charlene.Liu@amd.com>
Acked-by: NQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: NDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 879791ad
...@@ -436,57 +436,84 @@ static void dcn315_clk_mgr_helper_populate_bw_params( ...@@ -436,57 +436,84 @@ static void dcn315_clk_mgr_helper_populate_bw_params(
struct integrated_info *bios_info, struct integrated_info *bios_info,
const DpmClocks_315_t *clock_table) const DpmClocks_315_t *clock_table)
{ {
int i, j; int i;
struct clk_bw_params *bw_params = clk_mgr->base.bw_params; struct clk_bw_params *bw_params = clk_mgr->base.bw_params;
uint32_t max_dispclk = 0, max_dppclk = 0; uint32_t max_dispclk, max_dppclk, max_pstate, max_socclk, max_fclk = 0, min_pstate = 0;
struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1];
j = -1;
max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled);
ASSERT(NUM_DF_PSTATE_LEVELS <= MAX_NUM_DPM_LVL); max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled);
max_socclk = find_max_clk_value(clock_table->SocClocks, clock_table->NumSocClkLevelsEnabled);
/* Find lowest DPM, FCLK is filled in reverse order*/
/* Find highest fclk pstate */
for (i = NUM_DF_PSTATE_LEVELS - 1; i >= 0; i--) { for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) {
if (clock_table->DfPstateTable[i].FClk != 0) { if (clock_table->DfPstateTable[i].FClk > max_fclk) {
j = i; max_fclk = clock_table->DfPstateTable[i].FClk;
break; max_pstate = i;
} }
} }
if (j == -1) { /* For 315 we want to base clock table on dcfclk, need at least one entry regardless of pmfw table */
/* clock table is all 0s, just use our own hardcode */ for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) {
ASSERT(0); int j;
return; uint32_t min_fclk = clock_table->DfPstateTable[0].FClk;
}
bw_params->clk_table.num_entries = j + 1;
/* dispclk and dppclk can be max at any voltage, same number of levels for both */
if (clock_table->NumDispClkLevelsEnabled <= NUM_DISPCLK_DPM_LEVELS &&
clock_table->NumDispClkLevelsEnabled <= NUM_DPPCLK_DPM_LEVELS) {
max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled);
max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled);
} else {
ASSERT(0);
}
for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { for (j = 1; j < clock_table->NumDfPstatesEnabled; j++) {
int temp; if (clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i]
&& clock_table->DfPstateTable[j].FClk < min_fclk) {
min_fclk = clock_table->DfPstateTable[j].FClk;
min_pstate = j;
}
}
bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].FClk; bw_params->clk_table.entries[i].fclk_mhz = min_fclk;
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].MemClk; bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk;
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].Voltage; bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_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 = 1; bw_params->clk_table.entries[i].wck_ratio = 1;
temp = find_clk_for_voltage(clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[j].Voltage); };
if (temp)
bw_params->clk_table.entries[i].dcfclk_mhz = temp; /* Make sure to include at least one entry and highest pstate */
temp = find_clk_for_voltage(clock_table, clock_table->SocClocks, clock_table->DfPstateTable[j].Voltage); if (max_pstate != min_pstate) {
if (temp) bw_params->clk_table.entries[i].fclk_mhz = max_fclk;
bw_params->clk_table.entries[i].socclk_mhz = temp; bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_pstate].MemClk;
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_pstate].Voltage;
bw_params->clk_table.entries[i].dcfclk_mhz = find_clk_for_voltage(
clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[max_pstate].Voltage);
bw_params->clk_table.entries[i].socclk_mhz = find_clk_for_voltage(
clock_table, clock_table->SocClocks, clock_table->DfPstateTable[max_pstate].Voltage);
bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; 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].dppclk_mhz = max_dppclk;
bw_params->clk_table.entries[i].wck_ratio = 1;
i++;
} }
bw_params->clk_table.num_entries = i;
/* Include highest socclk */
if (bw_params->clk_table.entries[i-1].socclk_mhz < max_socclk)
bw_params->clk_table.entries[i-1].socclk_mhz = max_socclk;
/* Set any 0 clocks to max default setting. Not an issue for
* power since we aren't doing switching in such case anyway
*/
for (i = 0; i < bw_params->clk_table.num_entries; i++) {
if (!bw_params->clk_table.entries[i].fclk_mhz) {
bw_params->clk_table.entries[i].fclk_mhz = def_max.fclk_mhz;
bw_params->clk_table.entries[i].memclk_mhz = def_max.memclk_mhz;
bw_params->clk_table.entries[i].voltage = def_max.voltage;
}
if (!bw_params->clk_table.entries[i].dcfclk_mhz)
bw_params->clk_table.entries[i].dcfclk_mhz = def_max.dcfclk_mhz;
if (!bw_params->clk_table.entries[i].socclk_mhz)
bw_params->clk_table.entries[i].socclk_mhz = def_max.socclk_mhz;
if (!bw_params->clk_table.entries[i].dispclk_mhz)
bw_params->clk_table.entries[i].dispclk_mhz = def_max.dispclk_mhz;
if (!bw_params->clk_table.entries[i].dppclk_mhz)
bw_params->clk_table.entries[i].dppclk_mhz = def_max.dppclk_mhz;
}
bw_params->vram_type = bios_info->memory_type; bw_params->vram_type = bios_info->memory_type;
bw_params->num_channels = bios_info->ma_channel_number; bw_params->num_channels = bios_info->ma_channel_number;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册