Commit 2eb7d4b9 authored by Dillon Varone's avatar Dillon Varone Committed by Alex Deucher

drm/amd/display: Refactor dcn401_update_clocks

[WHY & HOW]
Refactor complex code into manageable functions. This also cleans up
some updating logics.
Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Acked-by: default avatarAlex Hung <alex.hung@amd.com>
Signed-off-by: default avatarDillon Varone <dillon.varone@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 61f88003
......@@ -36,7 +36,13 @@
#define DALSMC_MSG_SetFclkSwitchAllow 0x11
#define DALSMC_MSG_SetCabForUclkPstate 0x12
#define DALSMC_MSG_SetWorstCaseUclkLatency 0x13
#define DALSMC_Message_Count 0x14
#define DALSMC_MSG_DcnExitReset 0x14
#define DALSMC_MSG_ReturnHardMinStatus 0x15
#define DALSMC_MSG_SetAlwaysWaitDmcubResp 0x16
#define DALSMC_MSG_IndicateDrrStatus 0x17 // PMFW 15811
#define DALSMC_MSG_ActiveUclkFclk 0x18
#define DALSMC_MSG_IdleUclkFclk 0x19
#define DALSMC_Message_Count 0x1A
typedef enum {
FCLK_SWITCH_DISALLOW,
......
......@@ -5,8 +5,102 @@
#ifndef __DCN401_CLK_MGR_H_
#define __DCN401_CLK_MGR_H_
#define DCN401_CLK_MGR_MAX_SEQUENCE_SIZE 30
union dcn401_clk_mgr_block_sequence_params {
struct {
/* inputs */
uint32_t num_displays;
} update_num_displays_params;
struct {
/* inputs */
uint32_t ppclk;
uint16_t freq_mhz;
/* outputs */
uint32_t *response;
} update_hardmin_params;
struct {
/* inputs */
uint32_t ppclk;
int freq_khz;
/* outputs */
uint32_t *response;
} update_hardmin_optimized_params;
struct {
/* inputs */
uint16_t uclk_mhz;
uint16_t fclk_mhz;
} update_idle_hardmin_params;
struct {
/* inputs */
uint16_t freq_mhz;
} update_deep_sleep_dcfclk_params;
struct {
/* inputs */
bool support;
} update_fclk_pstate_support_params;
struct {
/* inputs */
unsigned int num_ways;
} update_cab_for_uclk_params;
struct {
/* inputs */
bool enable;
} update_wait_for_dmub_ack_params;
struct {
/* inputs */
bool mod_drr_for_pstate;
} indicate_drr_status_params;
struct {
/* inputs */
struct dc_state *context;
int dppclk_khz;
bool safe_to_lower;
} update_dppclk_dto_params;
struct {
/* inputs */
struct dc_state *context;
int ref_dtbclk_khz;
} update_dtbclk_dto_params;
struct {
/* inputs */
struct dc_state *context;
int ref_dtbclk_khz;
} update_dentist_params;
struct {
/* inputs */
struct dmcu *dmcu;
unsigned int wait;
} update_psr_wait_loop_params;
};
enum dcn401_clk_mgr_block_sequence_func {
CLK_MGR401_READ_CLOCKS_FROM_DENTIST,
CLK_MGR401_UPDATE_NUM_DISPLAYS,
CLK_MGR401_UPDATE_HARDMIN_PPCLK,
CLK_MGR401_UPDATE_HARDMIN_PPCLK_OPTIMIZED,
CLK_MGR401_UPDATE_ACTIVE_HARDMINS,
CLK_MGR401_UPDATE_IDLE_HARDMINS,
CLK_MGR401_UPDATE_DEEP_SLEEP_DCFCLK,
CLK_MGR401_UPDATE_FCLK_PSTATE_SUPPORT,
CLK_MGR401_UPDATE_CAB_FOR_UCLK,
CLK_MGR401_UPDATE_WAIT_FOR_DMUB_ACK,
CLK_MGR401_INDICATE_DRR_STATUS,
CLK_MGR401_UPDATE_DPPCLK_DTO,
CLK_MGR401_UPDATE_DTBCLK_DTO,
CLK_MGR401_UPDATE_DENTIST,
CLK_MGR401_UPDATE_PSR_WAIT_LOOP,
};
struct dcn401_clk_mgr_block_sequence {
union dcn401_clk_mgr_block_sequence_params params;
enum dcn401_clk_mgr_block_sequence_func func;
};
struct dcn401_clk_mgr {
struct clk_mgr_internal base;
struct dcn401_clk_mgr_block_sequence block_sequence[DCN401_CLK_MGR_MAX_SEQUENCE_SIZE];
};
void dcn401_init_clocks(struct clk_mgr *clk_mgr_base);
......
......@@ -105,6 +105,7 @@ void dcn401_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr)
unsigned int dcn401_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint16_t freq_mhz)
{
uint32_t response = 0;
bool hard_min_done = false;
/* bits 23:16 for clock type, lower 16 bits for frequency in MHz */
uint32_t param = (clk << 16) | freq_mhz;
......@@ -114,7 +115,84 @@ unsigned int dcn401_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, u
dcn401_smu_send_msg_with_param(clk_mgr,
DALSMC_MSG_SetHardMinByFreq, param, &response);
smu_print("SMU Frequency set = %d KHz\n", response);
/* wait until hardmin acknowledged */
//hard_min_done = dcn401_smu_wait_get_hard_min_status(clk_mgr, clk);
smu_print("SMU Frequency set = %d KHz hard_min_done %d\n", response, hard_min_done);
return response;
}
void dcn401_smu_wait_for_dmub_ack_mclk(struct clk_mgr_internal *clk_mgr, bool enable)
{
smu_print("SMU to wait for DMCUB ack for MCLK : %d\n", enable);
dcn401_smu_send_msg_with_param(clk_mgr, DALSMC_MSG_SetAlwaysWaitDmcubResp, enable ? 1 : 0, NULL);
}
void dcn401_smu_indicate_drr_status(struct clk_mgr_internal *clk_mgr, bool mod_drr_for_pstate)
{
smu_print("SMU Set indicate drr status = %d\n", mod_drr_for_pstate);
dcn401_smu_send_msg_with_param(clk_mgr,
DALSMC_MSG_IndicateDrrStatus, mod_drr_for_pstate ? 1 : 0, NULL);
}
bool dcn401_smu_set_idle_uclk_fclk_hardmin(struct clk_mgr_internal *clk_mgr,
uint16_t uclk_freq_mhz,
uint16_t fclk_freq_mhz)
{
uint32_t response = 0;
bool success;
/* 15:0 for uclk, 32:16 for fclk */
uint32_t param = (fclk_freq_mhz << 16) | uclk_freq_mhz;
smu_print("SMU Set idle hardmin by freq: uclk_freq_mhz = %d MHz, fclk_freq_mhz = %d MHz\n", uclk_freq_mhz, fclk_freq_mhz);
success = dcn401_smu_send_msg_with_param(clk_mgr,
DALSMC_MSG_IdleUclkFclk, param, &response);
/* wait until hardmin acknowledged */
//success &= dcn401_smu_wait_get_hard_min_status(clk_mgr, PPCLK_UCLK);
smu_print("SMU hard_min_done %d\n", success);
return success;
}
bool dcn401_smu_set_active_uclk_fclk_hardmin(struct clk_mgr_internal *clk_mgr,
uint16_t uclk_freq_mhz,
uint16_t fclk_freq_mhz)
{
uint32_t response = 0;
bool success;
/* 15:0 for uclk, 32:16 for fclk */
uint32_t param = (fclk_freq_mhz << 16) | uclk_freq_mhz;
smu_print("SMU Set active hardmin by freq: uclk_freq_mhz = %d MHz, fclk_freq_mhz = %d MHz\n", uclk_freq_mhz, fclk_freq_mhz);
success = dcn401_smu_send_msg_with_param(clk_mgr,
DALSMC_MSG_ActiveUclkFclk, param, &response);
/* wait until hardmin acknowledged */
//success &= dcn401_smu_wait_get_hard_min_status(clk_mgr, PPCLK_UCLK);
smu_print("SMU hard_min_done %d\n", success);
return success;
}
void dcn401_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz)
{
smu_print("SMU Set min deep sleep dcef clk: freq_mhz = %d MHz\n", freq_mhz);
dcn401_smu_send_msg_with_param(clk_mgr,
DALSMC_MSG_SetMinDeepSleepDcfclk, freq_mhz, NULL);
}
void dcn401_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t num_displays)
{
smu_print("SMU Set num of displays: num_displays = %d\n", num_displays);
dcn401_smu_send_msg_with_param(clk_mgr,
DALSMC_MSG_NumOfDisplays, num_displays, NULL);
}
......@@ -17,5 +17,15 @@ void dcn401_smu_send_cab_for_uclk_message(struct clk_mgr_internal *clk_mgr, unsi
void dcn401_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr);
void dcn401_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr);
unsigned int dcn401_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint16_t freq_mhz);
void dcn401_smu_wait_for_dmub_ack_mclk(struct clk_mgr_internal *clk_mgr, bool enable);
void dcn401_smu_indicate_drr_status(struct clk_mgr_internal *clk_mgr, bool mod_drr_for_pstate);
bool dcn401_smu_set_idle_uclk_fclk_hardmin(struct clk_mgr_internal *clk_mgr,
uint16_t uclk_freq_mhz,
uint16_t fclk_freq_mhz);
bool dcn401_smu_set_active_uclk_fclk_hardmin(struct clk_mgr_internal *clk_mgr,
uint16_t uclk_freq_mhz,
uint16_t fclk_freq_mhz);
void dcn401_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz);
void dcn401_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t num_displays);
#endif /* __DCN401_CLK_MGR_SMU_MSG_H_ */
......@@ -204,7 +204,8 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
dc_version = DCN_VERSION_3_51;
break;
case AMDGPU_FAMILY_GC_12_0_0:
if (ASICREV_IS_DCN401(asic_id.hw_internal_rev))
if (ASICREV_IS_GC_12_0_1_A0(asic_id.hw_internal_rev) ||
ASICREV_IS_GC_12_0_0_A0(asic_id.hw_internal_rev))
dc_version = DCN_VERSION_4_01;
break;
default:
......
......@@ -610,6 +610,8 @@ struct dc_clocks {
int max_supported_dispclk_khz;
int bw_dppclk_khz; /*a copy of dppclk_khz*/
int bw_dispclk_khz;
int idle_dramclk_khz;
int idle_fclk_khz;
};
struct dc_bw_validation_profile {
......@@ -1035,6 +1037,7 @@ struct dc_debug_options {
uint32_t dml21_force_pstate_method_value;
uint32_t dml21_disable_pstate_method_mask;
union dmub_fams2_global_feature_config fams2_config;
bool enable_legacy_clock_update;
unsigned int force_cositing;
};
......
......@@ -266,6 +266,9 @@ enum {
GC_12_UNKNOWN = 0xFF,
};
#define ASICREV_IS_GC_12_0_1_A0(eChipRev) (eChipRev >= GC_12_0_1_A0 && eChipRev < GC_12_0_0_A0)
#define ASICREV_IS_GC_12_0_0_A0(eChipRev) (eChipRev >= GC_12_0_0_A0 && eChipRev < 0xFF)
#define ASICREV_IS_DCN4(eChipRev) (eChipRev >= GC_12_0_1_A0 && eChipRev < GC_12_0_0_A0)
#define ASICREV_IS_DCN401(eChipRev) (eChipRev >= GC_12_0_0_A0 && eChipRev < GC_12_UNKNOWN)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment