From: Joshua Aberback <joshua.aberback@xxxxxxx> [Why] During driver unload, it is expected that p-state switching is supported. If it's not supported, PMFW will hang due to a forced p-state switch. Even if the current timing does not support p-state normally, we still want to force allow because the worst that can happen is underflow. This will match Navi10 behaviour. [How] - new hubbub func to control the force pstate register - force allow when releasing display ownership - registers are inaccessible after due to m_cgs.hwNotAvailable - explicitly disable force signal during hw_init - if driver is disabled and re-enabled, register not cleared otherwise Also, remove DCN3 part of dcn10_init_hw, we will not be going back to it. Signed-off-by: Joshua Aberback <joshua.aberback@xxxxxxx> Reviewed-by: Jun Lei <Jun.Lei@xxxxxxx> Acked-by: Eryk Brol <eryk.brol@xxxxxxx> --- drivers/gpu/drm/amd/display/dc/core/dc.c | 7 +++++++ drivers/gpu/drm/amd/display/dc/dc.h | 3 +++ .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 6 ------ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c | 11 +++++++++++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.h | 3 +++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 13 +++++++++++++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h | 2 ++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c | 1 + drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 4 ++++ drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 +++ 10 files changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 014d7571474e..8d96ef157987 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3097,4 +3097,11 @@ bool dc_is_plane_eligible_for_idle_optimizaitons(struct dc *dc, { return false; } + +/* cleanup on driver unload */ +void dc_hardware_release(struct dc *dc) +{ + if (dc->hwss.hardware_release) + dc->hwss.hardware_release(dc); +} #endif diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3ea4be40050d..d893211977ff 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1267,6 +1267,9 @@ void dc_unlock_memory_clock_frequency(struct dc *dc); */ void dc_lock_memory_clock_frequency(struct dc *dc); +/* cleanup on driver unload */ +void dc_hardware_release(struct dc *dc); + #endif bool dc_set_psr_allow_active(struct dc *dc, bool enable); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 256185a22800..86a0d46ff2e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1434,12 +1434,6 @@ void dcn10_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); - -#ifdef CONFIG_DRM_AMD_DC_DCN3_0 - if (dc->clk_mgr->funcs->set_hard_max_memclk) - dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); -#endif - } /* In headless boot cases, DIG may be turned diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c index 982732dec133..2c68a246fa83 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c @@ -384,6 +384,16 @@ void hubbub3_force_wm_propagate_to_pipes(struct hubbub *hubbub) DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value); } +void hubbub3_force_pstate_change_control(struct hubbub *hubbub, + bool force, bool allow) +{ + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); + + REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, allow, + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, force); +} + static const struct hubbub_funcs hubbub30_funcs = { .update_dchub = hubbub2_update_dchub, .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx, @@ -397,6 +407,7 @@ static const struct hubbub_funcs hubbub30_funcs = { .allow_self_refresh_control = hubbub1_allow_self_refresh_control, .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, .force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes, + .force_pstate_change_control = hubbub3_force_pstate_change_control, }; void hubbub3_construct(struct dcn20_hubbub *hubbub3, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.h index 790baa00672b..38f1d2fd939b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.h @@ -116,4 +116,7 @@ bool hubbub3_program_watermarks( unsigned int refclk_mhz, bool safe_to_lower); +void hubbub3_force_pstate_change_control(struct hubbub *hubbub, + bool force, bool allow); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 204773ffc376..2ace13878aaf 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -622,6 +622,10 @@ void dcn30_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->set_hard_max_memclk) dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); + + if (dc->res_pool->hubbub->funcs->force_pstate_change_control) + dc->res_pool->hubbub->funcs->force_pstate_change_control( + dc->res_pool->hubbub, false, false); } void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) @@ -711,3 +715,12 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) return true; } + +void dcn30_hardware_release(struct dc *dc) +{ + /* if pstate unsupported, force it supported */ + if (!dc->clk_mgr->clks.p_state_change_support && + dc->res_pool->hubbub->funcs->force_pstate_change_control) + dc->res_pool->hubbub->funcs->force_pstate_change_control( + dc->res_pool->hubbub, true, true); +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h index a4989f5ac4e9..0ae047221afe 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h @@ -67,4 +67,6 @@ void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx); bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable); +void dcn30_hardware_release(struct dc *dc); + #endif /* __DC_HWSS_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c index 7c90c2222506..ae7a789bf6e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c @@ -93,6 +93,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations, .set_backlight_level = dcn21_set_backlight_level, .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, + .hardware_release = dcn30_hardware_release, }; static const struct hwseq_private_funcs dcn30_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h index 65f182c8bf14..371da657c8a4 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -152,6 +152,10 @@ struct hubbub_funcs { void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub); void (*force_wm_propagate_to_pipes)(struct hubbub *hubbub); +#if defined(CONFIG_DRM_AMD_DC_DCN3_0) + + void (*force_pstate_change_control)(struct hubbub *hubbub, bool force, bool allow); +#endif }; struct hubbub { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index f48ee24d42f9..55c642950e91 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -50,6 +50,9 @@ struct dpp; struct dce_hwseq; struct hw_sequencer_funcs { +#ifdef CONFIG_DRM_AMD_DC_DCN3_0 + void (*hardware_release)(struct dc *dc); +#endif /* Embedded Display Related */ void (*edp_power_control)(struct dc_link *link, bool enable); void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); -- 2.25.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx