mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
drm/amd/display: Ensure dtbclk is enabled
[why] ensure dtbclk is enabled before hdmistreamclk_en pmfw could stop dtbclk on idle. driver needs to ensure dtbclk enabled is enabled before hdmistreamclk_en also disable debounce timer on dcn42. Reviewed-by: Chris Park <chris.park@amd.com> Reviewed-by: Leo Chen <leo.chen@amd.com> Signed-off-by: Charlene Liu <Charlene.Liu@amd.com> Signed-off-by: Roman Li <roman.li@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
7cc88c0d56
commit
807d6345bc
|
|
@ -220,6 +220,7 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
bool update_dispclk = false;
|
||||
bool dpp_clock_lowered = false;
|
||||
bool has_active_display;
|
||||
int actual_dtbclk = 0;
|
||||
|
||||
if (dc->work_arounds.skip_clock_update)
|
||||
return;
|
||||
|
|
@ -260,8 +261,9 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
* For dcn42b (no dtbclk hardware), init_clk_states sets dtbclk_en=false and
|
||||
* new_clocks->dtbclk_en should always be false, so this block never executes.
|
||||
*/
|
||||
if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) {
|
||||
int actual_dtbclk = 0;
|
||||
actual_dtbclk = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dtbclk);
|
||||
|
||||
if (new_clocks->dtbclk_en && actual_dtbclk < 590000) {
|
||||
|
||||
dcn42_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz);
|
||||
dcn42_smu_set_dtbclk(clk_mgr, true);
|
||||
|
|
@ -343,7 +345,6 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
dcn42_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz);
|
||||
clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz;
|
||||
}
|
||||
|
||||
if (dpp_clock_lowered) {
|
||||
// increase per DPP DTO before lowering global dppclk
|
||||
dcn42_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
|
||||
|
|
@ -1051,7 +1052,27 @@ void dcn42_get_smu_clocks(struct clk_mgr_internal *clk_mgr_int)
|
|||
dm_helpers_free_gpu_mem(clk_mgr_base->ctx, DC_MEM_ALLOC_TYPE_GART,
|
||||
smu_dpm_clks.dpm_clks);
|
||||
}
|
||||
void dcn42_request_dtbclk(struct clk_mgr *clk_mgr_base, bool enable)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
|
||||
/*pmfw might turn off dtblck based on allow_dtbstop*/
|
||||
clk_mgr_base->clks.dtbclk_en = false;
|
||||
|
||||
if (enable) {
|
||||
int actual_dtbclk = 0;
|
||||
|
||||
dcn42_smu_set_dtbclk(clk_mgr, true);
|
||||
actual_dtbclk = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dtbclk);
|
||||
if (actual_dtbclk > 590000) {
|
||||
clk_mgr_base->clks.ref_dtbclk_khz = actual_dtbclk;
|
||||
clk_mgr_base->clks.dtbclk_en = true;
|
||||
}
|
||||
} else {
|
||||
clk_mgr_base->clks.dtbclk_en = false;
|
||||
dcn42_smu_set_dtbclk(clk_mgr, false);
|
||||
}
|
||||
}
|
||||
static struct clk_mgr_funcs dcn42_funcs = {
|
||||
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
|
||||
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
|
||||
|
|
@ -1065,6 +1086,7 @@ static struct clk_mgr_funcs dcn42_funcs = {
|
|||
.get_max_clock_khz = dcn42_get_max_clock_khz,
|
||||
.get_dispclk_from_dentist = dcn42_get_dispclk_from_dentist,
|
||||
.is_smu_present = dcn42_is_smu_present,
|
||||
.request_dtbclk = dcn42_request_dtbclk,
|
||||
.notify_cstate_disable = dcn42_notify_cstate_disable,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -84,4 +84,5 @@ void dcn42_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, struct dcn42
|
|||
void dcn42_get_smu_clocks(struct clk_mgr_internal *clk_mgr_int);
|
||||
void dcn42_update_clocks_fpga(struct clk_mgr *clk_mgr, struct dc_state *context, bool safe_to_lower);
|
||||
int dcn42_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base);
|
||||
void dcn42_request_dtbclk(struct clk_mgr *clk_mgr_base, bool enable);
|
||||
#endif //__DCN42_CLK_MGR_H__
|
||||
|
|
|
|||
|
|
@ -1117,6 +1117,10 @@ static bool dcn401_program_pix_clk(
|
|||
if (clock_source->ctx->dc->caps.is_apu &&
|
||||
pix_clk_params->requested_pix_clk_100hz &&
|
||||
dc_is_hdmi_frl_signal(pix_clk_params->signal_type)) {
|
||||
//make sure dtbclk is enabled
|
||||
if (clock_source->ctx->dc->clk_mgr->funcs->request_dtbclk)
|
||||
clock_source->ctx->dc->clk_mgr->funcs->request_dtbclk(
|
||||
clock_source->ctx->dc->clk_mgr, true);
|
||||
/*need hdmistreamclk before vpg block register access*/
|
||||
clock_source->ctx->dc->res_pool->dccg->funcs->set_hdmistreamclk(
|
||||
clock_source->ctx->dc->res_pool->dccg,
|
||||
|
|
|
|||
|
|
@ -427,6 +427,7 @@ struct clk_mgr_funcs {
|
|||
struct block_sequence_state *seq_state);
|
||||
|
||||
void (*execute_clk_mgr_block_sequence)(struct clk_mgr *clk_mgr);
|
||||
void (*request_dtbclk)(struct clk_mgr *clk_mgr_base, bool enable);
|
||||
};
|
||||
|
||||
struct clk_mgr {
|
||||
|
|
|
|||
|
|
@ -415,6 +415,18 @@ void hdmi_frl_LTS_clear_Link_Setting(struct ddc_service *ddc_service)
|
|||
|
||||
}
|
||||
|
||||
static uint8_t hdmi_frl_get_max_ffe_level(struct dc_link *link,
|
||||
struct dc_hdmi_frl_link_settings *link_settings)
|
||||
{
|
||||
uint8_t max_ffe_level =
|
||||
(link_settings->frl_link_rate > HDMI_FRL_LINK_RATE_12GBPS) ? 7 : 3;
|
||||
|
||||
if ((uint8_t)link->dc->debug.limit_ffe < max_ffe_level)
|
||||
max_ffe_level = (uint8_t)link->dc->debug.limit_ffe;
|
||||
|
||||
return max_ffe_level;
|
||||
}
|
||||
|
||||
static enum link_result hdmi_frl_perform_link_training(struct ddc_service *ddc_service,
|
||||
struct dc_hdmi_frl_link_settings *link_settings)
|
||||
{
|
||||
|
|
@ -436,7 +448,7 @@ static enum link_result hdmi_frl_perform_link_training(struct ddc_service *ddc_s
|
|||
struct hpo_frl_link_encoder *hpo_frl_link_enc = ddc_service->link->hpo_frl_link_enc;
|
||||
struct link_encoder *dio_link_enc = ddc_service->link->link_enc;
|
||||
uint8_t sink_version = 0;
|
||||
uint8_t FFE_Levels = (uint8_t)ddc_service->link->dc->debug.limit_ffe;
|
||||
uint8_t FFE_Levels = hdmi_frl_get_max_ffe_level(ddc_service->link, link_settings);
|
||||
uint8_t current_FFE = 0;
|
||||
bool override_FFE = false;
|
||||
bool flt_no_timeout = false;
|
||||
|
|
@ -616,7 +628,7 @@ static enum link_result hdmi_frl_perform_link_training(struct ddc_service *ddc_s
|
|||
}
|
||||
current_FFE++;
|
||||
override_FFE = true;
|
||||
if (current_FFE > 3)
|
||||
if (current_FFE > FFE_Levels)
|
||||
current_FFE = 0;
|
||||
if (flt_no_timeout)
|
||||
current_FFE = 0;
|
||||
|
|
@ -642,7 +654,7 @@ static enum link_result hdmi_frl_perform_link_training(struct ddc_service *ddc_s
|
|||
}
|
||||
current_FFE++;
|
||||
override_FFE = true;
|
||||
if (current_FFE > 3)
|
||||
if (current_FFE > FFE_Levels)
|
||||
current_FFE = 0;
|
||||
if (flt_no_timeout)
|
||||
current_FFE = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user