drm/amd/display: Force enable pstate on driver unload
authorJoshua Aberback <joshua.aberback@amd.com>
Wed, 29 Apr 2020 23:01:14 +0000 (19:01 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 5 Oct 2020 19:16:30 +0000 (15:16 -0400)
[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@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Eryk Brol <eryk.brol@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index 014d757..8d96ef1 100644 (file)
@@ -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
index 3ea4be4..d893211 100644 (file)
@@ -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);
index 256185a..86a0d46 100644 (file)
@@ -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
index 204773f..2ace138 100644 (file)
@@ -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);
+}
index a4989f5..0ae0472 100644 (file)
@@ -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__ */
index 7c90c22..ae7a789 100644 (file)
@@ -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 = {
index f48ee24..55c6429 100644 (file)
@@ -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);