diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1780-drm-amd-display-Recalculate-pitch-when-buffers-chang.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1780-drm-amd-display-Recalculate-pitch-when-buffers-chang.patch | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1780-drm-amd-display-Recalculate-pitch-when-buffers-chang.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1780-drm-amd-display-Recalculate-pitch-when-buffers-chang.patch new file mode 100644 index 00000000..489a3dd5 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1780-drm-amd-display-Recalculate-pitch-when-buffers-chang.patch @@ -0,0 +1,160 @@ +From 8442dac5e3f501022e75eb813cc111f1d49318c9 Mon Sep 17 00:00:00 2001 +From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Date: Thu, 28 Mar 2019 09:46:23 -0400 +Subject: [PATCH 1780/2940] drm/amd/display: Recalculate pitch when buffers + change + +[Why] +Pitch was only calculated based on format whenever the plane state +was recreated. This could result in surface corruption due to the +incorrect pitch being programmed when the surface pitch changed during +commits where state->allow_modeset = false. + +[How] +Recalculate pitch at the same time we update the buffer address and +other buffer attributes. This function was previously called +fill_plane_tiling_attributes but I've also renamed it to +fill_plane_buffer_attributes to clarify the actual intent of the +function now that it's handling most buffer related attributes. + +Change-Id: I2f7a65165a30339a9115c18fa06397260e74c252 +Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Reviewed-by: David Francis <David.Francis@amd.com> +Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha@amd.com> +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 75 +++++++++---------- + 1 file changed, 35 insertions(+), 40 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 7db79f623ca7..8a1e7085c3b1 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2616,28 +2616,53 @@ static int fill_plane_dcc_attributes(struct amdgpu_device *adev, + } + + static int +-fill_plane_tiling_attributes(struct amdgpu_device *adev, ++fill_plane_buffer_attributes(struct amdgpu_device *adev, + const struct amdgpu_framebuffer *afb, + const struct dc_plane_state *plane_state, + union dc_tiling_info *tiling_info, ++ union plane_size *plane_size, + struct dc_plane_dcc_param *dcc, + struct dc_plane_address *address, + uint64_t tiling_flags) + { ++ const struct drm_framebuffer *fb = &afb->base; + int ret; + + memset(tiling_info, 0, sizeof(*tiling_info)); ++ memset(plane_size, 0, sizeof(*plane_size)); + memset(dcc, 0, sizeof(*dcc)); + memset(address, 0, sizeof(*address)); + + if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { ++ plane_size->grph.surface_size.x = 0; ++ plane_size->grph.surface_size.y = 0; ++ plane_size->grph.surface_size.width = fb->width; ++ plane_size->grph.surface_size.height = fb->height; ++ plane_size->grph.surface_pitch = ++ fb->pitches[0] / fb->format->cpp[0]; ++ + 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 chroma_addr = afb->address + fb->offsets[1]; + ++ plane_size->video.luma_size.x = 0; ++ plane_size->video.luma_size.y = 0; ++ plane_size->video.luma_size.width = fb->width; ++ plane_size->video.luma_size.height = fb->height; ++ plane_size->video.luma_pitch = ++ fb->pitches[0] / fb->format->cpp[0]; ++ ++ plane_size->video.chroma_size.x = 0; ++ plane_size->video.chroma_size.y = 0; ++ /* TODO: set these based on surface format */ ++ plane_size->video.chroma_size.width = fb->width / 2; ++ plane_size->video.chroma_size.height = fb->height / 2; ++ ++ plane_size->video.chroma_pitch = ++ fb->pitches[1] / fb->format->cpp[1]; ++ + address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; + address->video_progressive.luma_addr.low_part = + lower_32_bits(afb->address); +@@ -2758,42 +2783,10 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, + return -EINVAL; + } + +- memset(&plane_state->address, 0, sizeof(plane_state->address)); +- +- if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { +- 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; +- plane_state->plane_size.grph.surface_size.height = fb->height; +- plane_state->plane_size.grph.surface_pitch = +- fb->pitches[0] / fb->format->cpp[0]; +- /* TODO: unhardcode */ +- plane_state->color_space = COLOR_SPACE_SRGB; +- +- } else { +- 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 = fb->width; +- plane_state->plane_size.video.luma_size.height = fb->height; +- plane_state->plane_size.video.luma_pitch = +- fb->pitches[0] / fb->format->cpp[0]; +- +- plane_state->plane_size.video.chroma_size.x = 0; +- plane_state->plane_size.video.chroma_size.y = 0; +- /* TODO: set these based on surface format */ +- plane_state->plane_size.video.chroma_size.width = fb->width / 2; +- plane_state->plane_size.video.chroma_size.height = fb->height / 2; +- +- plane_state->plane_size.video.chroma_pitch = +- fb->pitches[1] / fb->format->cpp[1]; +- +- /* TODO: unhardcode */ +- plane_state->color_space = COLOR_SPACE_YCBCR709; +- } +- +- fill_plane_tiling_attributes(adev, amdgpu_fb, plane_state, ++ fill_plane_buffer_attributes(adev, amdgpu_fb, plane_state, + &plane_state->tiling_info, +- &plane_state->dcc, ++ &plane_state->plane_size, ++ &plane_state->dcc, + &plane_state->address, + tiling_flags); + +@@ -4115,9 +4108,10 @@ 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; + +- fill_plane_tiling_attributes( ++ fill_plane_buffer_attributes( + adev, afb, plane_state, &plane_state->tiling_info, +- &plane_state->dcc, &plane_state->address, tiling_flags); ++ &plane_state->plane_size, &plane_state->dcc, ++ &plane_state->address, tiling_flags); + } + + return 0; +@@ -5292,8 +5286,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + + amdgpu_bo_unreserve(abo); + +- fill_plane_tiling_attributes(dm->adev, afb, dc_plane, ++ fill_plane_buffer_attributes(dm->adev, afb, dc_plane, + &bundle->plane_infos[planes_count].tiling_info, ++ &bundle->plane_infos[planes_count].plane_size, + &bundle->plane_infos[planes_count].dcc, + &bundle->flip_addrs[planes_count].address, + tiling_flags); +-- +2.17.1 + |