Commit 8803bfff authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher

drm/amd/display: Add optional optimization for IPS handshake

[Why]
It's possible to skip parts of the eval and exit sequencing if we know
whether DCN is in IPS2 already or if it's committed to going to idle
and not in IPS2.

[How]
Skip IPS2 entry/exit if DMCUB is idle but the IPS2 commit is not set.

Skip the eval delay if DMCUB is already in IPS2 since we know we need
to exit.

These are turned off by default.
Reviewed-by: default avatarDuncan Ma <duncan.ma@amd.com>
Acked-by: default avatarWayne Lin <wayne.lin@amd.com>
Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 93ddf00f
...@@ -988,6 +988,7 @@ struct dc_debug_options { ...@@ -988,6 +988,7 @@ struct dc_debug_options {
bool psp_disabled_wa; bool psp_disabled_wa;
unsigned int ips2_eval_delay_us; unsigned int ips2_eval_delay_us;
unsigned int ips2_entry_delay_us; unsigned int ips2_entry_delay_us;
bool optimize_ips_handshake;
bool disable_dmub_reallow_idle; bool disable_dmub_reallow_idle;
bool disable_timeout; bool disable_timeout;
bool disable_extblankadj; bool disable_extblankadj;
......
...@@ -1318,13 +1318,16 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc) ...@@ -1318,13 +1318,16 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
*/ */
dc_dmub_srv->needs_idle_wake = false; dc_dmub_srv->needs_idle_wake = false;
if (prev_driver_signals.bits.allow_ips2) { if (prev_driver_signals.bits.allow_ips2 &&
(!dc->debug.optimize_ips_handshake ||
ips_fw->signals.bits.ips2_commit || !ips_fw->signals.bits.in_idle)) {
DC_LOG_IPS( DC_LOG_IPS(
"wait IPS2 eval (ips1_commit=%d ips2_commit=%d)", "wait IPS2 eval (ips1_commit=%d ips2_commit=%d)",
ips_fw->signals.bits.ips1_commit, ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit); ips_fw->signals.bits.ips2_commit);
udelay(dc->debug.ips2_eval_delay_us); if (!dc->debug.optimize_ips_handshake || !ips_fw->signals.bits.ips2_commit)
udelay(dc->debug.ips2_eval_delay_us);
if (ips_fw->signals.bits.ips2_commit) { if (ips_fw->signals.bits.ips2_commit) {
DC_LOG_IPS( DC_LOG_IPS(
......
...@@ -700,7 +700,8 @@ union dmub_shared_state_ips_fw_signals { ...@@ -700,7 +700,8 @@ union dmub_shared_state_ips_fw_signals {
struct { struct {
uint32_t ips1_commit : 1; /**< 1 if in IPS1 */ uint32_t ips1_commit : 1; /**< 1 if in IPS1 */
uint32_t ips2_commit : 1; /**< 1 if in IPS2 */ uint32_t ips2_commit : 1; /**< 1 if in IPS2 */
uint32_t reserved_bits : 30; /**< Reversed */ uint32_t in_idle : 1; /**< 1 if DMCUB is in idle */
uint32_t reserved_bits : 29; /**< Reversed */
} bits; } bits;
uint32_t all; uint32_t all;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment