drm/amd/display: PSR eDP p-state warning occurs intermittently after unplug DP

[Why]
with eDP + DP, each display use one pipe. after DP unplugged, eDP switch
from one pipe to two pipes -- pipe split.  dpp1_cm_set_regamma_pwl will
be executed too. The duration from switch single pipe to dual pipes is a
little long which could let eDP enter PSR mode. upon two pipes for eDP
are setup, eDP PHY is disabled. front pipe is not really running to
fetch data from frame buffer. i.e., dchubp is not in normal working
status. execution of hubbub1_wm_change_req_wa may cause p-state warning.

[How]
disable eDP PSR before dc_commit_state. psr is disabled when execute
hubbub1_wm_change_req_wa.

Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
Reviewed-by: Roman Li <Roman.Li@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
hersen wu 2020-07-08 22:14:41 -04:00 committed by Alex Deucher
parent 9804ecbba8
commit 6ee90e88b9
3 changed files with 48 additions and 6 deletions

View File

@ -171,7 +171,7 @@ static void amdgpu_dm_set_psr_caps(struct dc_link *link);
static bool amdgpu_dm_psr_enable(struct dc_stream_state *stream); static bool amdgpu_dm_psr_enable(struct dc_stream_state *stream);
static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream); static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream);
static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream); static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm);
/* /*
* dm_vblank_get_counter * dm_vblank_get_counter
@ -7445,6 +7445,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
struct drm_connector_state *old_con_state, *new_con_state; struct drm_connector_state *old_con_state, *new_con_state;
struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
int crtc_disable_count = 0; int crtc_disable_count = 0;
bool mode_set_reset_required = false;
drm_atomic_helper_update_legacy_modeset_state(dev, state); drm_atomic_helper_update_legacy_modeset_state(dev, state);
@ -7521,19 +7522,21 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
acrtc->enabled = true; acrtc->enabled = true;
acrtc->hw_mode = new_crtc_state->mode; acrtc->hw_mode = new_crtc_state->mode;
crtc->hwmode = new_crtc_state->mode; crtc->hwmode = new_crtc_state->mode;
mode_set_reset_required = true;
} else if (modereset_required(new_crtc_state)) { } else if (modereset_required(new_crtc_state)) {
DRM_DEBUG_DRIVER("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc); DRM_DEBUG_DRIVER("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc);
/* i.e. reset mode */ /* i.e. reset mode */
if (dm_old_crtc_state->stream) { if (dm_old_crtc_state->stream)
if (dm_old_crtc_state->stream->link->psr_settings.psr_allow_active)
amdgpu_dm_psr_disable(dm_old_crtc_state->stream);
remove_stream(adev, acrtc, dm_old_crtc_state->stream); remove_stream(adev, acrtc, dm_old_crtc_state->stream);
} mode_set_reset_required = true;
} }
} /* for_each_crtc_in_state() */ } /* for_each_crtc_in_state() */
if (dc_state) { if (dc_state) {
/* if there mode set or reset, disable eDP PSR */
if (mode_set_reset_required)
amdgpu_dm_psr_disable_all(dm);
dm_enable_per_frame_crtc_master_sync(dc_state); dm_enable_per_frame_crtc_master_sync(dc_state);
mutex_lock(&dm->dc_lock); mutex_lock(&dm->dc_lock);
WARN_ON(!dc_commit_state(dm->dc, dc_state)); WARN_ON(!dc_commit_state(dm->dc, dc_state));
@ -9054,6 +9057,18 @@ static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
return dc_link_set_psr_allow_active(stream->link, false, true); return dc_link_set_psr_allow_active(stream->link, false, true);
} }
/*
* amdgpu_dm_psr_disable() - disable psr f/w
* if psr is enabled on any stream
*
* Return: true if success
*/
static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm)
{
DRM_DEBUG_DRIVER("Disabling psr if psr is enabled on any stream\n");
return dc_set_psr_allow_active(dm->dc, false);
}
void amdgpu_dm_trigger_timing_sync(struct drm_device *dev) void amdgpu_dm_trigger_timing_sync(struct drm_device *dev)
{ {
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;

View File

@ -2948,6 +2948,30 @@ void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_
dc->hwss.get_clock(dc, clock_type, clock_cfg); dc->hwss.get_clock(dc, clock_type, clock_cfg);
} }
/* enable/disable eDP PSR without specify stream for eDP */
bool dc_set_psr_allow_active(struct dc *dc, bool enable)
{
int i;
for (i = 0; i < dc->current_state->stream_count ; i++) {
struct dc_link *link;
struct dc_stream_state *stream = dc->current_state->streams[i];
link = stream->link;
if (!link)
continue;
if (link->psr_settings.psr_feature_enabled) {
if (enable && !link->psr_settings.psr_allow_active)
return dc_link_set_psr_allow_active(link, true, false);
else if (!enable && link->psr_settings.psr_allow_active)
return dc_link_set_psr_allow_active(link, false, false);
}
}
return true;
}
#if defined(CONFIG_DRM_AMD_DC_DCN3_0) #if defined(CONFIG_DRM_AMD_DC_DCN3_0)
void dc_allow_idle_optimizations(struct dc *dc, bool allow) void dc_allow_idle_optimizations(struct dc *dc, bool allow)

View File

@ -1265,6 +1265,9 @@ void dc_unlock_memory_clock_frequency(struct dc *dc);
void dc_lock_memory_clock_frequency(struct dc *dc); void dc_lock_memory_clock_frequency(struct dc *dc);
#endif #endif
bool dc_set_psr_allow_active(struct dc *dc, bool enable);
/******************************************************************************* /*******************************************************************************
* DSC Interfaces * DSC Interfaces
******************************************************************************/ ******************************************************************************/