diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1607-drm-amd-display-Fix-plane-address-updates-for-video-.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1607-drm-amd-display-Fix-plane-address-updates-for-video-.patch | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1607-drm-amd-display-Fix-plane-address-updates-for-video-.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1607-drm-amd-display-Fix-plane-address-updates-for-video-.patch new file mode 100644 index 00000000..ac50dffe --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1607-drm-amd-display-Fix-plane-address-updates-for-video-.patch @@ -0,0 +1,142 @@ +From 7672bc8c3f6320597af8462b18c9c6e530bb3590 Mon Sep 17 00:00:00 2001 +From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Date: Mon, 11 Mar 2019 09:38:35 -0400 +Subject: [PATCH 1607/2940] drm/amd/display: Fix plane address updates for + video surface formats + +[Why] +For new DC planes the correct plane address fields are filled based +on whether the plane had a graphics or video format. + +However, when we perform stream and plane updates using DC we only ever +fill in the graphics format fields. This causing corruption and hangs +when using video surface formats like NV12 for planes. + +[How] +Use the same logic everywhere we update dc_plane_address - always +fill in the correct fields based on the surface format type. + +There are 3 places this is done: + +- Atomic check, during DC plane creation +- Atomic commit, during plane prepare_fb +- Atomic commit tail, during amdgpu_dm_commit_planes + +We use the fill_plane_tiling_attributes in all 3 locations and it +already needs the address to update DCC attributes, so the surface +address update logic can be moved into this helper. + +Change-Id: I757b0110997d02ba24b8e77bf6286f0bd9f707de +Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Reviewed-by: Leo Li <sunpeng.li@amd.com> +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 57 +++++++++---------- + 1 file changed, 26 insertions(+), 31 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 fc04cbc719a5..5922eedc7a98 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2476,6 +2476,27 @@ fill_plane_tiling_attributes(struct amdgpu_device *adev, + + memset(tiling_info, 0, sizeof(*tiling_info)); + memset(dcc, 0, sizeof(*dcc)); ++ memset(address, 0, sizeof(*address)); ++ ++ if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { ++ address->type = PLN_ADDR_TYPE_GRAPHICS; ++ address->grph.addr.low_part = lower_32_bits(afb->address); ++ address->grph.addr.high_part = upper_32_bits(afb->address); ++ } else { ++ const struct drm_framebuffer *fb = &afb->base; ++ uint64_t awidth = ALIGN(fb->width, 64); ++ uint64_t chroma_addr = afb->address + awidth * fb->height; ++ ++ address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; ++ address->video_progressive.luma_addr.low_part = ++ lower_32_bits(afb->address); ++ address->video_progressive.luma_addr.high_part = ++ upper_32_bits(afb->address); ++ address->video_progressive.chroma_addr.low_part = ++ lower_32_bits(chroma_addr); ++ address->video_progressive.chroma_addr.high_part = ++ upper_32_bits(chroma_addr); ++ } + + /* Fill GFX8 params */ + if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) { +@@ -2590,7 +2611,6 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, + memset(&plane_state->address, 0, sizeof(plane_state->address)); + + if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { +- plane_state->address.type = PLN_ADDR_TYPE_GRAPHICS; + plane_state->plane_size.grph.surface_size.x = 0; + plane_state->plane_size.grph.surface_size.y = 0; + plane_state->plane_size.grph.surface_size.width = fb->width; +@@ -2602,7 +2622,7 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, + + } else { + awidth = ALIGN(fb->width, 64); +- plane_state->address.type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; ++ + plane_state->plane_size.video.luma_size.x = 0; + plane_state->plane_size.video.luma_size.y = 0; + plane_state->plane_size.video.luma_size.width = awidth; +@@ -3812,10 +3832,8 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, + struct drm_gem_object *obj; + struct amdgpu_device *adev; + struct amdgpu_bo *rbo; +- uint64_t chroma_addr = 0; + struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old; +- uint64_t tiling_flags, dcc_address; +- unsigned int awidth; ++ uint64_t tiling_flags; + uint32_t domain; + int r; + +@@ -3868,29 +3886,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, + dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { + struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; + +- if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { +- plane_state->address.grph.addr.low_part = lower_32_bits(afb->address); +- plane_state->address.grph.addr.high_part = upper_32_bits(afb->address); +- +- dcc_address = +- get_dcc_address(afb->address, tiling_flags); +- plane_state->address.grph.meta_addr.low_part = +- lower_32_bits(dcc_address); +- plane_state->address.grph.meta_addr.high_part = +- upper_32_bits(dcc_address); +- } else { +- awidth = ALIGN(new_state->fb->width, 64); +- plane_state->address.type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; +- plane_state->address.video_progressive.luma_addr.low_part +- = lower_32_bits(afb->address); +- plane_state->address.video_progressive.luma_addr.high_part +- = upper_32_bits(afb->address); +- chroma_addr = afb->address + (u64)awidth * new_state->fb->height; +- plane_state->address.video_progressive.chroma_addr.low_part +- = lower_32_bits(chroma_addr); +- plane_state->address.video_progressive.chroma_addr.high_part +- = upper_32_bits(chroma_addr); +- } ++ fill_plane_tiling_attributes( ++ adev, afb, plane_state, &plane_state->tiling_info, ++ &plane_state->dcc, &plane_state->address, tiling_flags); + } + + return 0; +@@ -4962,9 +4960,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + + amdgpu_bo_unreserve(abo); + +- 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); +- + fill_plane_tiling_attributes(dm->adev, afb, dc_plane, + &bundle->plane_infos[planes_count].tiling_info, + &bundle->plane_infos[planes_count].dcc, +-- +2.17.1 + |