summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c23
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_psr.c7
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_replay.c7
7 files changed, 60 insertions, 16 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index cc029af0cef2..683b5fb1945d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1994,6 +1994,7 @@ struct dc_scratch_space {
// BW ALLOCATON USB4 ONLY
struct dc_dpia_bw_alloc dpia_bw_alloc_config;
bool skip_implict_edp_power_control;
+ bool forced_psr_active;
enum backlight_control_type backlight_control_type;
};
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 5fcf30b448a5..80180cb00aba 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -1286,6 +1286,8 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
return;
if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+ if (link->forced_psr_active)
+ return;
if (!link->skip_implict_edp_power_control && hws)
hws->funcs.edp_backlight_control(link, false);
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
@@ -1811,7 +1813,9 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
dc->link_srv->set_dsc_enable(pipe_ctx, true);
}
- if (!stream->dpms_off)
+ if (!stream->dpms_off &&
+ !(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active))
dc->link_srv->set_dpms_on(context, pipe_ctx);
/* DCN3.1 FPGA Workaround
@@ -1830,7 +1834,9 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
* is constructed with the same sink). Make sure not to override
* and link programming on the main.
*/
- if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) {
+ if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM &&
+ !(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false;
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
index b6f3c0480ab6..823ef06c64f5 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
@@ -537,10 +537,12 @@ static void dcn31_reset_back_end_for_pipe(
}
ASSERT(!pipe_ctx->top_pipe);
- dc->hwss.set_abm_immediate_disable(pipe_ctx);
-
link = pipe_ctx->stream->link;
+ if (!(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active))
+ dc->hwss.set_abm_immediate_disable(pipe_ctx);
+
if (dc->hwseq)
dc->hwseq->wa_state.skip_blank_stream = false;
@@ -555,9 +557,11 @@ static void dcn31_reset_back_end_for_pipe(
pipe_ctx->stream_res.tg,
OPTC_DSC_DISABLED, 0, 0);
- pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
-
- pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ if (!(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
+ pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ }
if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
@@ -586,7 +590,12 @@ static void dcn31_reset_back_end_for_pipe(
* screen only, the dpms_off would be true but
* VBIOS lit up eDP, so check link status too.
*/
- if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+ if (link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active) {
+ /* forced psr is active for seamless switch; skip dpms-off. */
+ if (pipe_ctx->stream_res.audio)
+ dc->hwss.disable_audio_stream(pipe_ctx);
+ } else if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
dc->link_srv->set_dpms_off(pipe_ctx);
else if (pipe_ctx->stream_res.audio)
dc->hwss.disable_audio_stream(pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index 08f1f307657c..6e1079377f48 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -1819,8 +1819,11 @@ void dcn35_disable_link_output(struct dc_link *link,
disable_link_output_symclk_on_tx_off(link, DP_UNKNOWN_ENCODING);
link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
} else {
- link_hwss->disable_link_output(link, link_res, signal);
- link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ if (!(signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ link_hwss->disable_link_output(link, link_res, signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ }
}
/*
* Add the logic to extract BOTH power up and power down sequences
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index b89010a88b44..904780e02f70 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -1113,8 +1113,11 @@ void dcn401_disable_link_output(struct dc_link *link,
disable_link_output_symclk_on_tx_off(link, DP_UNKNOWN_ENCODING);
link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
} else {
- link_hwss->disable_link_output(link, link_res, signal);
- link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ if (!(signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
+ link_hwss->disable_link_output(link, link_res, signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ }
}
if (signal == SIGNAL_TYPE_EDP &&
@@ -2162,7 +2165,12 @@ void dcn401_reset_back_end_for_pipe(
* screen only, the dpms_off would be true but
* VBIOS lit up eDP, so check link status too.
*/
- if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+ if (link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active) {
+ /* Forced psr is active for seamless switch; skip dpms-off. */
+ if (pipe_ctx->stream_res.audio)
+ dc->hwss.disable_audio_stream(pipe_ctx);
+ } else if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
dc->link_srv->set_dpms_off(pipe_ctx);
else if (pipe_ctx->stream_res.audio)
dc->hwss.disable_audio_stream(pipe_ctx);
@@ -2187,12 +2195,15 @@ void dcn401_reset_back_end_for_pipe(
* parent pipe.
*/
if (pipe_ctx->top_pipe == NULL) {
+ if (!(link->connector_signal == SIGNAL_TYPE_EDP &&
+ link->forced_psr_active)) {
- dc->hwss.set_abm_immediate_disable(pipe_ctx);
+ dc->hwss.set_abm_immediate_disable(pipe_ctx);
- pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
+ pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
- pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
+ }
if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_psr.c b/drivers/gpu/drm/amd/display/modules/power/power_psr.c
index 5ecb570c204e..96bb77fff05b 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_psr.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_psr.c
@@ -58,6 +58,13 @@ bool mod_power_psr_notify_mode_change(struct mod_power *mod_power,
// stream_index is passed as validated parameter
active_psr_events = core_power->map[stream_index].psr_events;
+ /* forced psr is active for seamless switch.
+ * Re-running edp_setup_psr would disturb the freeze,
+ * so skip the PSR re-setup until forced psr releases the override.
+ */
+ if (active_psr_events & psr_event_os_override_hold)
+ return false;
+
/* Calculate PSR configurations */
mod_power_calc_psr_configs(&psr_config, link, stream);
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_replay.c b/drivers/gpu/drm/amd/display/modules/power/power_replay.c
index e782501442c4..31d9cb3a12ba 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_replay.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_replay.c
@@ -805,6 +805,13 @@ void mod_power_replay_notify_mode_change(struct mod_power *mod_power,
core_power = MOD_POWER_TO_CORE(mod_power);
active_replay_events = core_power->map[stream_index].replay_events;
+ /* forced psr is active for seamless switch.
+ * Re-running edp_setup_psr would disturb the freeze,
+ * so skip the PSR re-setup until forced psr releases the override.
+ */
+ if (active_replay_events & replay_event_os_override_hold)
+ return;
+
link->replay_settings.replay_smu_opt_enable =
(link->replay_settings.config.replay_smu_opt_supported &&
mod_power_only_edp(dc->current_state, stream));