Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Dmytro Laktyushkin and committed by
Alex Deucher
60f6fe66 d1826081

+67 -40
+67 -40
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
··· 436 436 struct integrated_info *bios_info, 437 437 const DpmClocks_315_t *clock_table) 438 438 { 439 - int i, j; 439 + int i; 440 440 struct clk_bw_params *bw_params = clk_mgr->base.bw_params; 441 - uint32_t max_dispclk = 0, max_dppclk = 0; 441 + uint32_t max_dispclk, max_dppclk, max_pstate, max_socclk, max_fclk = 0, min_pstate = 0; 442 + struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1]; 442 443 443 - j = -1; 444 + max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled); 445 + max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled); 446 + max_socclk = find_max_clk_value(clock_table->SocClocks, clock_table->NumSocClkLevelsEnabled); 444 447 445 - ASSERT(NUM_DF_PSTATE_LEVELS <= MAX_NUM_DPM_LVL); 446 - 447 - /* Find lowest DPM, FCLK is filled in reverse order*/ 448 - 449 - for (i = NUM_DF_PSTATE_LEVELS - 1; i >= 0; i--) { 450 - if (clock_table->DfPstateTable[i].FClk != 0) { 451 - j = i; 452 - break; 448 + /* Find highest fclk pstate */ 449 + for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) { 450 + if (clock_table->DfPstateTable[i].FClk > max_fclk) { 451 + max_fclk = clock_table->DfPstateTable[i].FClk; 452 + max_pstate = i; 453 453 } 454 454 } 455 455 456 - if (j == -1) { 457 - /* clock table is all 0s, just use our own hardcode */ 458 - ASSERT(0); 459 - return; 460 - } 456 + /* For 315 we want to base clock table on dcfclk, need at least one entry regardless of pmfw table */ 457 + for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) { 458 + int j; 459 + uint32_t min_fclk = clock_table->DfPstateTable[0].FClk; 461 460 462 - bw_params->clk_table.num_entries = j + 1; 461 + for (j = 1; j < clock_table->NumDfPstatesEnabled; j++) { 462 + if (clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i] 463 + && clock_table->DfPstateTable[j].FClk < min_fclk) { 464 + min_fclk = clock_table->DfPstateTable[j].FClk; 465 + min_pstate = j; 466 + } 467 + } 463 468 464 - /* dispclk and dppclk can be max at any voltage, same number of levels for both */ 465 - if (clock_table->NumDispClkLevelsEnabled <= NUM_DISPCLK_DPM_LEVELS && 466 - clock_table->NumDispClkLevelsEnabled <= NUM_DPPCLK_DPM_LEVELS) { 467 - max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled); 468 - max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled); 469 - } else { 470 - ASSERT(0); 471 - } 472 - 473 - for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { 474 - int temp; 475 - 476 - bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].FClk; 477 - bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].MemClk; 478 - bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].Voltage; 479 - bw_params->clk_table.entries[i].wck_ratio = 1; 480 - temp = find_clk_for_voltage(clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[j].Voltage); 481 - if (temp) 482 - bw_params->clk_table.entries[i].dcfclk_mhz = temp; 483 - temp = find_clk_for_voltage(clock_table, clock_table->SocClocks, clock_table->DfPstateTable[j].Voltage); 484 - if (temp) 485 - bw_params->clk_table.entries[i].socclk_mhz = temp; 469 + bw_params->clk_table.entries[i].fclk_mhz = min_fclk; 470 + bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk; 471 + bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_pstate].Voltage; 472 + bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i]; 473 + bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i]; 486 474 bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; 487 475 bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; 488 - } 476 + bw_params->clk_table.entries[i].wck_ratio = 1; 477 + }; 489 478 479 + /* Make sure to include at least one entry and highest pstate */ 480 + if (max_pstate != min_pstate) { 481 + bw_params->clk_table.entries[i].fclk_mhz = max_fclk; 482 + bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_pstate].MemClk; 483 + bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_pstate].Voltage; 484 + bw_params->clk_table.entries[i].dcfclk_mhz = find_clk_for_voltage( 485 + clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[max_pstate].Voltage); 486 + bw_params->clk_table.entries[i].socclk_mhz = find_clk_for_voltage( 487 + clock_table, clock_table->SocClocks, clock_table->DfPstateTable[max_pstate].Voltage); 488 + bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; 489 + bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; 490 + bw_params->clk_table.entries[i].wck_ratio = 1; 491 + i++; 492 + } 493 + bw_params->clk_table.num_entries = i; 494 + 495 + /* Include highest socclk */ 496 + if (bw_params->clk_table.entries[i-1].socclk_mhz < max_socclk) 497 + bw_params->clk_table.entries[i-1].socclk_mhz = max_socclk; 498 + 499 + /* Set any 0 clocks to max default setting. Not an issue for 500 + * power since we aren't doing switching in such case anyway 501 + */ 502 + for (i = 0; i < bw_params->clk_table.num_entries; i++) { 503 + if (!bw_params->clk_table.entries[i].fclk_mhz) { 504 + bw_params->clk_table.entries[i].fclk_mhz = def_max.fclk_mhz; 505 + bw_params->clk_table.entries[i].memclk_mhz = def_max.memclk_mhz; 506 + bw_params->clk_table.entries[i].voltage = def_max.voltage; 507 + } 508 + if (!bw_params->clk_table.entries[i].dcfclk_mhz) 509 + bw_params->clk_table.entries[i].dcfclk_mhz = def_max.dcfclk_mhz; 510 + if (!bw_params->clk_table.entries[i].socclk_mhz) 511 + bw_params->clk_table.entries[i].socclk_mhz = def_max.socclk_mhz; 512 + if (!bw_params->clk_table.entries[i].dispclk_mhz) 513 + bw_params->clk_table.entries[i].dispclk_mhz = def_max.dispclk_mhz; 514 + if (!bw_params->clk_table.entries[i].dppclk_mhz) 515 + bw_params->clk_table.entries[i].dppclk_mhz = def_max.dppclk_mhz; 516 + } 490 517 bw_params->vram_type = bios_info->memory_type; 491 518 bw_params->num_channels = bios_info->ma_channel_number; 492 519