aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1307-drm-amd-display-Make-stream-commits-call-into-DC-onl.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1307-drm-amd-display-Make-stream-commits-call-into-DC-onl.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1307-drm-amd-display-Make-stream-commits-call-into-DC-onl.patch273
1 files changed, 273 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1307-drm-amd-display-Make-stream-commits-call-into-DC-onl.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1307-drm-amd-display-Make-stream-commits-call-into-DC-onl.patch
new file mode 100644
index 00000000..e6cb85c6
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1307-drm-amd-display-Make-stream-commits-call-into-DC-onl.patch
@@ -0,0 +1,273 @@
+From b3d57bb8aa9475e670ea539fb5cccf53b62f4772 Mon Sep 17 00:00:00 2001
+From: David Francis <David.Francis@amd.com>
+Date: Wed, 6 Feb 2019 13:44:33 -0500
+Subject: [PATCH 1307/2940] drm/amd/display: Make stream commits call into DC
+ only once
+
+[Why]
+dc_commit_updates_for_stream is called twice per stream: once
+with the flip data and once will all other data. This causes
+problems when these DC calls have different numbers of planes
+
+For example, a commit with a pageflip on plane A and a
+non-pageflip change on plane B will first call
+into DC with just plane A, causing plane B to be
+disabled. Then it will call into DC with both planes,
+re-enabling plane B
+
+[How]
+Merge flip and full into a single bundle
+
+Apart from the single DC call, the logic should not be
+changed by this patch
+
+Signed-off-by: David Francis <David.Francis@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 | 129 ++++++++----------
+ 1 file changed, 54 insertions(+), 75 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 1b56da5a32d4..ab4bae386772 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -4758,30 +4758,25 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state);
+ struct dm_crtc_state *dm_old_crtc_state =
+ to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc));
+- int flip_count = 0, planes_count = 0, vpos, hpos;
++ int planes_count = 0, vpos, hpos;
+ unsigned long flags;
+ struct amdgpu_bo *abo;
+ uint64_t tiling_flags, dcc_address;
+ uint32_t target, target_vblank;
+-
+- struct {
+- struct dc_surface_update surface_updates[MAX_SURFACES];
+- struct dc_flip_addrs flip_addrs[MAX_SURFACES];
+- struct dc_stream_update stream_update;
+- } *flip;
++ bool pflip_present = false;
+
+ struct {
+ struct dc_surface_update surface_updates[MAX_SURFACES];
+ struct dc_plane_info plane_infos[MAX_SURFACES];
+ struct dc_scaling_info scaling_infos[MAX_SURFACES];
++ struct dc_flip_addrs flip_addrs[MAX_SURFACES];
+ struct dc_stream_update stream_update;
+- } *full;
++ } *bundle;
+
+- flip = kzalloc(sizeof(*flip), GFP_KERNEL);
+- full = kzalloc(sizeof(*full), GFP_KERNEL);
++ bundle = kzalloc(sizeof(*bundle), GFP_KERNEL);
+
+- if (!flip || !full) {
+- dm_error("Failed to allocate update bundles\n");
++ if (!bundle) {
++ dm_error("Failed to allocate update bundle\n");
+ goto cleanup;
+ }
+
+@@ -4791,7 +4786,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ struct drm_crtc_state *new_crtc_state;
+ struct drm_framebuffer *fb = new_plane_state->fb;
+ struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(fb);
+- bool pflip_needed;
++ bool framebuffer_changed;
+ struct dc_plane_state *dc_plane;
+ struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state);
+
+@@ -4806,12 +4801,14 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ if (!new_crtc_state->active)
+ continue;
+
+- pflip_needed = old_plane_state->fb &&
++ dc_plane = dm_new_plane_state->dc_state;
++
++ framebuffer_changed = old_plane_state->fb &&
+ old_plane_state->fb != new_plane_state->fb;
+
+- dc_plane = dm_new_plane_state->dc_state;
++ pflip_present = pflip_present || framebuffer_changed;
+
+- if (pflip_needed) {
++ if (framebuffer_changed) {
+ /*
+ * TODO This might fail and hence better not used, wait
+ * explicitly on fences instead
+@@ -4840,22 +4837,22 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+
+ amdgpu_bo_unreserve(abo);
+
+- flip->flip_addrs[flip_count].address.grph.addr.low_part = lower_32_bits(afb->address);
+- flip->flip_addrs[flip_count].address.grph.addr.high_part = upper_32_bits(afb->address);
++ bundle->flip_addrs[planes_count].address.grph.addr.low_part = lower_32_bits(afb->address);
++ bundle->flip_addrs[planes_count].address.grph.addr.high_part = upper_32_bits(afb->address);
+
+ dcc_address = get_dcc_address(afb->address, tiling_flags);
+- flip->flip_addrs[flip_count].address.grph.meta_addr.low_part = lower_32_bits(dcc_address);
+- flip->flip_addrs[flip_count].address.grph.meta_addr.high_part = upper_32_bits(dcc_address);
++ bundle->flip_addrs[planes_count].address.grph.meta_addr.low_part = lower_32_bits(dcc_address);
++ bundle->flip_addrs[planes_count].address.grph.meta_addr.high_part = upper_32_bits(dcc_address);
+
+- flip->flip_addrs[flip_count].flip_immediate =
++ bundle->flip_addrs[planes_count].flip_immediate =
+ (crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0;
+
+ timestamp_ns = ktime_get_ns();
+- flip->flip_addrs[flip_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000);
+- flip->surface_updates[flip_count].flip_addr = &flip->flip_addrs[flip_count];
+- flip->surface_updates[flip_count].surface = dc_plane;
++ bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000);
++ bundle->surface_updates[planes_count].flip_addr = &bundle->flip_addrs[planes_count];
++ bundle->surface_updates[planes_count].surface = dc_plane;
+
+- if (!flip->surface_updates[flip_count].surface) {
++ if (!bundle->surface_updates[planes_count].surface) {
+ DRM_ERROR("No surface for CRTC: id=%d\n",
+ acrtc_attach->crtc_id);
+ continue;
+@@ -4867,53 +4864,45 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ acrtc_state,
+ acrtc_state->stream,
+ dc_plane,
+- flip->flip_addrs[flip_count].flip_timestamp_in_us);
++ bundle->flip_addrs[planes_count].flip_timestamp_in_us);
+
+ DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x\n",
+ __func__,
+- flip->flip_addrs[flip_count].address.grph.addr.high_part,
+- flip->flip_addrs[flip_count].address.grph.addr.low_part);
+-
+- flip_count += 1;
++ bundle->flip_addrs[planes_count].address.grph.addr.high_part,
++ bundle->flip_addrs[planes_count].address.grph.addr.low_part);
+ }
+
+- full->surface_updates[planes_count].surface = dc_plane;
++ bundle->surface_updates[planes_count].surface = dc_plane;
+ if (new_pcrtc_state->color_mgmt_changed) {
+- full->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
+- full->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
++ bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
++ bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
+ }
+
+
+- full->scaling_infos[planes_count].scaling_quality = dc_plane->scaling_quality;
+- full->scaling_infos[planes_count].src_rect = dc_plane->src_rect;
+- full->scaling_infos[planes_count].dst_rect = dc_plane->dst_rect;
+- full->scaling_infos[planes_count].clip_rect = dc_plane->clip_rect;
+- full->surface_updates[planes_count].scaling_info = &full->scaling_infos[planes_count];
++ bundle->scaling_infos[planes_count].scaling_quality = dc_plane->scaling_quality;
++ bundle->scaling_infos[planes_count].src_rect = dc_plane->src_rect;
++ bundle->scaling_infos[planes_count].dst_rect = dc_plane->dst_rect;
++ bundle->scaling_infos[planes_count].clip_rect = dc_plane->clip_rect;
++ bundle->surface_updates[planes_count].scaling_info = &bundle->scaling_infos[planes_count];
+
+
+- full->plane_infos[planes_count].color_space = dc_plane->color_space;
+- full->plane_infos[planes_count].format = dc_plane->format;
+- full->plane_infos[planes_count].plane_size = dc_plane->plane_size;
+- full->plane_infos[planes_count].rotation = dc_plane->rotation;
+- full->plane_infos[planes_count].horizontal_mirror = dc_plane->horizontal_mirror;
+- full->plane_infos[planes_count].stereo_format = dc_plane->stereo_format;
+- full->plane_infos[planes_count].tiling_info = dc_plane->tiling_info;
+- full->plane_infos[planes_count].visible = dc_plane->visible;
+- full->plane_infos[planes_count].per_pixel_alpha = dc_plane->per_pixel_alpha;
+- full->plane_infos[planes_count].dcc = dc_plane->dcc;
+- full->surface_updates[planes_count].plane_info = &full->plane_infos[planes_count];
++ bundle->plane_infos[planes_count].color_space = dc_plane->color_space;
++ bundle->plane_infos[planes_count].format = dc_plane->format;
++ bundle->plane_infos[planes_count].plane_size = dc_plane->plane_size;
++ bundle->plane_infos[planes_count].rotation = dc_plane->rotation;
++ bundle->plane_infos[planes_count].horizontal_mirror = dc_plane->horizontal_mirror;
++ bundle->plane_infos[planes_count].stereo_format = dc_plane->stereo_format;
++ bundle->plane_infos[planes_count].tiling_info = dc_plane->tiling_info;
++ bundle->plane_infos[planes_count].visible = dc_plane->visible;
++ bundle->plane_infos[planes_count].per_pixel_alpha = dc_plane->per_pixel_alpha;
++ bundle->plane_infos[planes_count].dcc = dc_plane->dcc;
++ bundle->surface_updates[planes_count].plane_info = &bundle->plane_infos[planes_count];
+
+ planes_count += 1;
+
+ }
+
+- /*
+- * TODO: For proper atomic behaviour, we should be calling into DC once with
+- * all the changes. However, DC refuses to do pageflips and non-pageflip
+- * changes in the same call. Change DC to respect atomic behaviour,
+- * hopefully eliminating dc_*_update structs in their entirety.
+- */
+- if (flip_count) {
++ if (pflip_present) {
+ target = (uint32_t)drm_crtc_vblank_count(pcrtc) + wait_for_vblank;
+ /* Prepare wait for target vblank early - before the fence-waits */
+ target_vblank = target - (uint32_t)drm_crtc_vblank_count(pcrtc) +
+@@ -4948,43 +4937,34 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ if (acrtc_state->stream) {
+
+ if (acrtc_state->freesync_timing_changed)
+- flip->stream_update.adjust =
++ bundle->stream_update.adjust =
+ &acrtc_state->stream->adjust;
+
+ if (acrtc_state->freesync_vrr_info_changed)
+- flip->stream_update.vrr_infopacket =
++ bundle->stream_update.vrr_infopacket =
+ &acrtc_state->stream->vrr_infopacket;
+ }
+-
+- mutex_lock(&dm->dc_lock);
+- dc_commit_updates_for_stream(dm->dc,
+- flip->surface_updates,
+- flip_count,
+- acrtc_state->stream,
+- &flip->stream_update,
+- dc_state);
+- mutex_unlock(&dm->dc_lock);
+ }
+
+ if (planes_count) {
+ if (new_pcrtc_state->mode_changed) {
+- full->stream_update.src = acrtc_state->stream->src;
+- full->stream_update.dst = acrtc_state->stream->dst;
++ bundle->stream_update.src = acrtc_state->stream->src;
++ bundle->stream_update.dst = acrtc_state->stream->dst;
+ }
+
+ if (new_pcrtc_state->color_mgmt_changed)
+- full->stream_update.out_transfer_func = acrtc_state->stream->out_transfer_func;
++ bundle->stream_update.out_transfer_func = acrtc_state->stream->out_transfer_func;
+
+ acrtc_state->stream->abm_level = acrtc_state->abm_level;
+ if (acrtc_state->abm_level != dm_old_crtc_state->abm_level)
+- full->stream_update.abm_level = &acrtc_state->abm_level;
++ bundle->stream_update.abm_level = &acrtc_state->abm_level;
+
+ mutex_lock(&dm->dc_lock);
+ dc_commit_updates_for_stream(dm->dc,
+- full->surface_updates,
++ bundle->surface_updates,
+ planes_count,
+ acrtc_state->stream,
+- &full->stream_update,
++ &bundle->stream_update,
+ dc_state);
+ mutex_unlock(&dm->dc_lock);
+ }
+@@ -4994,8 +4974,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ handle_cursor_update(plane, old_plane_state);
+
+ cleanup:
+- kfree(flip);
+- kfree(full);
++ kfree(bundle);
+ }
+
+ /*
+--
+2.17.1
+