aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Aberback <[email protected]>2020-04-29 19:01:14 -0400
committerAlex Deucher <[email protected]>2020-10-05 15:16:30 -0400
commit3e19095534caec6be8f8c1a7d8fd4879e23637ed (patch)
treee586f46680328f59140ead02872b3f8d9a75fce8
parentfe984cb3dd325c4c5c7c360e43d93608d4d8870a (diff)
drm/amd/display: Force enable pstate on driver unload
[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 <[email protected]> Reviewed-by: Jun Lei <[email protected]> Acked-by: Eryk Brol <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h3
7 files changed, 29 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_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_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);