aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4236-drm-amd-display-Enable-PSR.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4236-drm-amd-display-Enable-PSR.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4236-drm-amd-display-Enable-PSR.patch229
1 files changed, 229 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4236-drm-amd-display-Enable-PSR.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4236-drm-amd-display-Enable-PSR.patch
new file mode 100644
index 00000000..7983bd1a
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4236-drm-amd-display-Enable-PSR.patch
@@ -0,0 +1,229 @@
+From a8ee241de4c89b32b586e89e150b1471714b6ffa Mon Sep 17 00:00:00 2001
+From: Roman Li <Roman.Li@amd.com>
+Date: Fri, 20 Sep 2019 19:03:17 -0400
+Subject: [PATCH 4236/4736] drm/amd/display: Enable PSR
+
+[Why]
+PSR (Panel Self-Refresh) is a power-saving feature for eDP panels.
+The feature has support in DMCU (Display MicroController Unit).
+DMCU/driver communication is implemented in DC.
+DM can use existing DC PSR interface to use PSR feature.
+
+[How]
+- Read psr caps via dpcd
+- Send vsc infoframe if panel supports psr
+- Disable psr before h/w programming (FULL_UPDATE)
+- Enable psr after h/w programming
+- Disable psr for fb console
+
+Change-Id: Ic52045fc6c68d66d744b1bdd99f14274f69322c6
+Signed-off-by: Roman Li <Roman.Li@amd.com>
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 133 +++++++++++++++++-
+ 1 file changed, 130 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index b55dd3680581..8139cffd5b88 100755
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -146,6 +146,12 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc);
+ static void handle_cursor_update(struct drm_plane *plane,
+ struct drm_plane_state *old_plane_state);
+
++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_link_setup_psr(struct dc_stream_state *stream);
++static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
++
++
+ /*
+ * dm_vblank_get_counter
+ *
+@@ -2400,6 +2406,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
+ } else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
+ amdgpu_dm_update_connector_after_detect(aconnector);
+ register_backlight_device(dm, link);
++ amdgpu_dm_set_psr_caps(link);
+ }
+
+
+@@ -3799,7 +3806,16 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+
+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
+ mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false);
++ if (stream->link->psr_feature_enabled) {
++ struct dc *core_dc = stream->link->ctx->dc;
+
++ if (dc_is_dmcu_initialized(core_dc)) {
++ struct dmcu *dmcu = core_dc->res_pool->dmcu;
++
++ stream->psr_version = dmcu->dmcu_version.psr_version;
++ mod_build_vsc_infopacket(stream, &stream->vsc_infopacket);
++ }
++ }
+ finish:
+ dc_sink_release(sink);
+
+@@ -5782,6 +5798,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ uint32_t target_vblank, last_flip_vblank;
+ bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
+ bool pflip_present = false;
++ bool swizzle = true;
+ struct {
+ struct dc_surface_update surface_updates[MAX_SURFACES];
+ struct dc_plane_info plane_infos[MAX_SURFACES];
+@@ -5827,6 +5844,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+
+ dc_plane = dm_new_plane_state->dc_state;
+
++ if (dc_plane && !dc_plane->tiling_info.gfx9.swizzle)
++ swizzle = false;
++
+ bundle->surface_updates[planes_count].surface = dc_plane;
+ if (new_pcrtc_state->color_mgmt_changed) {
+ bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
+@@ -6017,14 +6037,29 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ &acrtc_state->vrr_params.adjust);
+ spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
+ }
+-
+ mutex_lock(&dm->dc_lock);
++ if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
++ acrtc_state->stream->link->psr_allow_active)
++ amdgpu_dm_psr_disable(acrtc_state->stream);
++
+ dc_commit_updates_for_stream(dm->dc,
+ bundle->surface_updates,
+ planes_count,
+ acrtc_state->stream,
+ &bundle->stream_update,
+ dc_state);
++
++ if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
++ acrtc_state->stream->psr_version &&
++ !acrtc_state->stream->link->psr_feature_enabled)
++ amdgpu_dm_link_setup_psr(acrtc_state->stream);
++ else if ((acrtc_state->update_type == UPDATE_TYPE_FAST) &&
++ acrtc_state->stream->link->psr_feature_enabled &&
++ !acrtc_state->stream->link->psr_allow_active &&
++ swizzle) {
++ amdgpu_dm_psr_enable(acrtc_state->stream);
++ }
++
+ mutex_unlock(&dm->dc_lock);
+ }
+
+@@ -6329,10 +6364,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ crtc->hwmode = new_crtc_state->mode;
+ } else if (modereset_required(new_crtc_state)) {
+ DRM_DEBUG_DRIVER("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc);
+-
+ /* i.e. reset mode */
+- if (dm_old_crtc_state->stream)
++ if (dm_old_crtc_state->stream) {
++ if (dm_old_crtc_state->stream->link->psr_allow_active)
++ amdgpu_dm_psr_disable(dm_old_crtc_state->stream);
++
+ remove_stream(adev, acrtc, dm_old_crtc_state->stream);
++ }
+ }
+ } /* for_each_crtc_in_state() */
+
+@@ -7688,3 +7726,92 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
+ freesync_capable);
+ }
+
++static void amdgpu_dm_set_psr_caps(struct dc_link *link)
++{
++ uint8_t dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE];
++
++ if (!(link->connector_signal & SIGNAL_TYPE_EDP))
++ return;
++ if (link->type == dc_connection_none)
++ return;
++ if (dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT,
++ dpcd_data, sizeof(dpcd_data))) {
++ link->psr_feature_enabled = dpcd_data[0] ? true:false;
++ DRM_INFO("PSR support:%d\n", link->psr_feature_enabled);
++ }
++}
++
++/*
++ * amdgpu_dm_link_setup_psr() - configure psr link
++ * @stream: stream state
++ *
++ * Return: true if success
++ */
++static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream)
++{
++ struct dc_link *link = NULL;
++ struct psr_config psr_config = {0};
++ struct psr_context psr_context = {0};
++ struct dc *dc = NULL;
++ bool ret = false;
++
++ if (stream == NULL)
++ return false;
++
++ link = stream->link;
++ dc = link->ctx->dc;
++
++ psr_config.psr_version = dc->res_pool->dmcu->dmcu_version.psr_version;
++
++ if (psr_config.psr_version > 0) {
++ psr_config.psr_exit_link_training_required = 0x1;
++ psr_config.psr_frame_capture_indication_req = 0;
++ psr_config.psr_rfb_setup_time = 0x37;
++ psr_config.psr_sdp_transmit_line_num_deadline = 0x20;
++ psr_config.allow_smu_optimizations = 0x0;
++
++ ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context);
++
++ }
++ DRM_DEBUG_DRIVER("PSR link: %d\n", link->psr_feature_enabled);
++
++ return ret;
++}
++
++/*
++ * amdgpu_dm_psr_enable() - enable psr f/w
++ * @stream: stream state
++ *
++ * Return: true if success
++ */
++bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
++{
++ struct dc_link *link = stream->link;
++ struct dc_static_screen_events triggers = {0};
++
++ DRM_DEBUG_DRIVER("Enabling psr...\n");
++
++ triggers.cursor_update = true;
++ triggers.overlay_update = true;
++ triggers.surface_update = true;
++
++ dc_stream_set_static_screen_events(link->ctx->dc,
++ &stream, 1,
++ &triggers);
++
++ return dc_link_set_psr_allow_active(link, true, false);
++}
++
++/*
++ * amdgpu_dm_psr_disable() - disable psr f/w
++ * @stream: stream state
++ *
++ * Return: true if success
++ */
++static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
++{
++
++ DRM_DEBUG_DRIVER("Disabling psr...\n");
++
++ return dc_link_set_psr_allow_active(stream->link, false, true);
++}
+--
+2.17.1
+