mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-06 00:47:56 -04:00
drm/amd/display: correct dcn351 dpm clk table based on pmfw_drv_if
[why] driver got wrong clock table due to miss match dtm_table headers. correct the dtn_clock table based on pmfw header. Reviewed-by: Alvin Lee <alvin.lee2@amd.com> Reviewed-by: Sung joon Kim <sungjoon.kim@amd.com> Signed-off-by: Charlene Liu <Charlene.Liu@amd.com> Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
0f5ac8c8e2
commit
cb49aefb19
@@ -632,6 +632,7 @@ static struct wm_table lpddr5_wm_table = {
|
||||
};
|
||||
|
||||
static DpmClocks_t_dcn35 dummy_clocks;
|
||||
static DpmClocks_t_dcn351 dummy_clocks_dcn351;
|
||||
|
||||
static struct dcn35_watermarks dummy_wms = { 0 };
|
||||
|
||||
@@ -755,6 +756,22 @@ static void dcn35_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
|
||||
dcn35_smu_transfer_dpm_table_smu_2_dram(clk_mgr);
|
||||
}
|
||||
|
||||
static void dcn351_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
|
||||
struct dcn351_smu_dpm_clks *smu_dpm_clks)
|
||||
{
|
||||
DpmClocks_t_dcn351 *table = smu_dpm_clks->dpm_clks;
|
||||
|
||||
if (!clk_mgr->smu_ver)
|
||||
return;
|
||||
if (!table || smu_dpm_clks->mc_address.quad_part == 0)
|
||||
return;
|
||||
memset(table, 0, sizeof(*table));
|
||||
dcn35_smu_set_dram_addr_high(clk_mgr,
|
||||
smu_dpm_clks->mc_address.high_part);
|
||||
dcn35_smu_set_dram_addr_low(clk_mgr,
|
||||
smu_dpm_clks->mc_address.low_part);
|
||||
dcn35_smu_transfer_dpm_table_smu_2_dram(clk_mgr);
|
||||
}
|
||||
static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
|
||||
{
|
||||
uint32_t max = 0;
|
||||
@@ -1093,6 +1110,57 @@ struct clk_mgr_funcs dcn35_fpga_funcs = {
|
||||
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
|
||||
};
|
||||
|
||||
static void translate_to_DpmClocks_t_dcn35(struct dcn351_smu_dpm_clks *smu_dpm_clks_a,
|
||||
struct dcn35_smu_dpm_clks *smu_dpm_clks_b)
|
||||
{
|
||||
/*translate two structures and only take need clock tables*/
|
||||
uint8_t i;
|
||||
|
||||
if (smu_dpm_clks_a == NULL || smu_dpm_clks_b == NULL ||
|
||||
smu_dpm_clks_a->dpm_clks == NULL || smu_dpm_clks_b->dpm_clks == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++)
|
||||
smu_dpm_clks_b->dpm_clks->DcfClocks[i] = smu_dpm_clks_a->dpm_clks->DcfClocks[i];
|
||||
|
||||
for (i = 0; i < NUM_DISPCLK_DPM_LEVELS; i++)
|
||||
smu_dpm_clks_b->dpm_clks->DispClocks[i] = smu_dpm_clks_a->dpm_clks->DispClocks[i];
|
||||
|
||||
for (i = 0; i < NUM_DPPCLK_DPM_LEVELS; i++)
|
||||
smu_dpm_clks_b->dpm_clks->DppClocks[i] = smu_dpm_clks_a->dpm_clks->DppClocks[i];
|
||||
|
||||
for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) {
|
||||
smu_dpm_clks_b->dpm_clks->FclkClocks_Freq[i] = smu_dpm_clks_a->dpm_clks->FclkClocks_Freq[i];
|
||||
smu_dpm_clks_b->dpm_clks->FclkClocks_Voltage[i] = smu_dpm_clks_a->dpm_clks->FclkClocks_Voltage[i];
|
||||
}
|
||||
for (i = 0; i < NUM_MEM_PSTATE_LEVELS; i++) {
|
||||
smu_dpm_clks_b->dpm_clks->MemPstateTable[i].MemClk =
|
||||
smu_dpm_clks_a->dpm_clks->MemPstateTable[i].MemClk;
|
||||
smu_dpm_clks_b->dpm_clks->MemPstateTable[i].UClk =
|
||||
smu_dpm_clks_a->dpm_clks->MemPstateTable[i].UClk;
|
||||
smu_dpm_clks_b->dpm_clks->MemPstateTable[i].Voltage =
|
||||
smu_dpm_clks_a->dpm_clks->MemPstateTable[i].Voltage;
|
||||
smu_dpm_clks_b->dpm_clks->MemPstateTable[i].WckRatio =
|
||||
smu_dpm_clks_a->dpm_clks->MemPstateTable[i].WckRatio;
|
||||
}
|
||||
smu_dpm_clks_b->dpm_clks->MaxGfxClk = smu_dpm_clks_a->dpm_clks->MaxGfxClk;
|
||||
smu_dpm_clks_b->dpm_clks->MinGfxClk = smu_dpm_clks_a->dpm_clks->MinGfxClk;
|
||||
smu_dpm_clks_b->dpm_clks->NumDcfClkLevelsEnabled =
|
||||
smu_dpm_clks_a->dpm_clks->NumDcfClkLevelsEnabled;
|
||||
smu_dpm_clks_b->dpm_clks->NumDispClkLevelsEnabled =
|
||||
smu_dpm_clks_a->dpm_clks->NumDispClkLevelsEnabled;
|
||||
smu_dpm_clks_b->dpm_clks->NumFclkLevelsEnabled =
|
||||
smu_dpm_clks_a->dpm_clks->NumFclkLevelsEnabled;
|
||||
smu_dpm_clks_b->dpm_clks->NumMemPstatesEnabled =
|
||||
smu_dpm_clks_a->dpm_clks->NumMemPstatesEnabled;
|
||||
smu_dpm_clks_b->dpm_clks->NumSocClkLevelsEnabled =
|
||||
smu_dpm_clks_a->dpm_clks->NumSocClkLevelsEnabled;
|
||||
|
||||
for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) {
|
||||
smu_dpm_clks_b->dpm_clks->SocClocks[i] = smu_dpm_clks_a->dpm_clks->SocClocks[i];
|
||||
smu_dpm_clks_b->dpm_clks->SocVoltage[i] = smu_dpm_clks_a->dpm_clks->SocVoltage[i];
|
||||
}
|
||||
}
|
||||
void dcn35_clk_mgr_construct(
|
||||
struct dc_context *ctx,
|
||||
struct clk_mgr_dcn35 *clk_mgr,
|
||||
@@ -1100,6 +1168,7 @@ void dcn35_clk_mgr_construct(
|
||||
struct dccg *dccg)
|
||||
{
|
||||
struct dcn35_smu_dpm_clks smu_dpm_clks = { 0 };
|
||||
struct dcn351_smu_dpm_clks smu_dpm_clks_dcn351 = { 0 };
|
||||
clk_mgr->base.base.ctx = ctx;
|
||||
clk_mgr->base.base.funcs = &dcn35_funcs;
|
||||
|
||||
@@ -1130,14 +1199,24 @@ void dcn35_clk_mgr_construct(
|
||||
DC_MEM_ALLOC_TYPE_GART,
|
||||
sizeof(DpmClocks_t_dcn35),
|
||||
&smu_dpm_clks.mc_address.quad_part);
|
||||
|
||||
if (smu_dpm_clks.dpm_clks == NULL) {
|
||||
smu_dpm_clks.dpm_clks = &dummy_clocks;
|
||||
smu_dpm_clks.mc_address.quad_part = 0;
|
||||
}
|
||||
|
||||
ASSERT(smu_dpm_clks.dpm_clks);
|
||||
|
||||
if (ctx->dce_version == DCN_VERSION_3_51) {
|
||||
smu_dpm_clks_dcn351.dpm_clks = (DpmClocks_t_dcn351 *)dm_helpers_allocate_gpu_mem(
|
||||
clk_mgr->base.base.ctx,
|
||||
DC_MEM_ALLOC_TYPE_GART,
|
||||
sizeof(DpmClocks_t_dcn351),
|
||||
&smu_dpm_clks_dcn351.mc_address.quad_part);
|
||||
if (smu_dpm_clks_dcn351.dpm_clks == NULL) {
|
||||
smu_dpm_clks_dcn351.dpm_clks = &dummy_clocks_dcn351;
|
||||
smu_dpm_clks_dcn351.mc_address.quad_part = 0;
|
||||
}
|
||||
}
|
||||
|
||||
clk_mgr->base.smu_ver = dcn35_smu_get_smu_version(&clk_mgr->base);
|
||||
|
||||
if (clk_mgr->base.smu_ver)
|
||||
@@ -1166,7 +1245,11 @@ void dcn35_clk_mgr_construct(
|
||||
|
||||
if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
|
||||
int i;
|
||||
dcn35_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
|
||||
if (ctx->dce_version == DCN_VERSION_3_51) {
|
||||
dcn351_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks_dcn351);
|
||||
translate_to_DpmClocks_t_dcn35(&smu_dpm_clks_dcn351, &smu_dpm_clks);
|
||||
} else
|
||||
dcn35_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
|
||||
DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
|
||||
"NumDispClkLevelsEnabled: %d\n"
|
||||
"NumSocClkLevelsEnabled: %d\n"
|
||||
@@ -1227,6 +1310,10 @@ void dcn35_clk_mgr_construct(
|
||||
dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_GART,
|
||||
smu_dpm_clks.dpm_clks);
|
||||
|
||||
if (smu_dpm_clks_dcn351.dpm_clks && smu_dpm_clks_dcn351.mc_address.quad_part != 0)
|
||||
dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_GART,
|
||||
smu_dpm_clks_dcn351.dpm_clks);
|
||||
|
||||
if (ctx->dc->config.disable_ips != DMUB_IPS_DISABLE_ALL) {
|
||||
bool ips_support = false;
|
||||
|
||||
|
||||
@@ -126,18 +126,31 @@ typedef struct {
|
||||
uint32_t MaxGfxClk;
|
||||
} DpmClocks_t_dcn35;
|
||||
|
||||
|
||||
// Throttler Status Bitmask
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
|
||||
uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
|
||||
uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
|
||||
uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
|
||||
uint32_t VClocks0[NUM_VCN_DPM_LEVELS];
|
||||
uint32_t VClocks1[NUM_VCN_DPM_LEVELS];
|
||||
uint32_t DClocks0[NUM_VCN_DPM_LEVELS];
|
||||
uint32_t DClocks1[NUM_VCN_DPM_LEVELS];
|
||||
uint32_t VPEClocks[NUM_VPE_DPM_LEVELS];
|
||||
uint32_t FclkClocks_Freq[NUM_FCLK_DPM_LEVELS];
|
||||
uint32_t FclkClocks_Voltage[NUM_FCLK_DPM_LEVELS];
|
||||
uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
|
||||
MemPstateTable_t MemPstateTable[NUM_MEM_PSTATE_LEVELS];
|
||||
uint8_t NumDcfClkLevelsEnabled;
|
||||
uint8_t NumDispClkLevelsEnabled; // Applies to both Dispclk and Dppclk
|
||||
uint8_t NumSocClkLevelsEnabled;
|
||||
uint8_t Vcn0ClkLevelsEnabled; // Applies to both Vclk0 and Dclk0
|
||||
uint8_t Vcn1ClkLevelsEnabled; // Applies to both Vclk1 and Dclk1
|
||||
uint8_t VpeClkLevelsEnabled;
|
||||
uint8_t NumMemPstatesEnabled;
|
||||
uint8_t NumFclkLevelsEnabled;
|
||||
uint32_t MinGfxClk;
|
||||
uint32_t MaxGfxClk;
|
||||
} DpmClocks_t_dcn351;
|
||||
|
||||
#define TABLE_BIOS_IF 0 // Called by BIOS
|
||||
#define TABLE_WATERMARKS 1 // Called by DAL through VBIOS
|
||||
@@ -163,6 +176,10 @@ struct dcn35_smu_dpm_clks {
|
||||
union large_integer mc_address;
|
||||
};
|
||||
|
||||
struct dcn351_smu_dpm_clks {
|
||||
DpmClocks_t_dcn351 *dpm_clks;
|
||||
union large_integer mc_address;
|
||||
};
|
||||
/* TODO: taken from vgh, may not be correct */
|
||||
struct display_idle_optimization {
|
||||
unsigned int df_request_disabled : 1;
|
||||
|
||||
Reference in New Issue
Block a user