[PATCH] drm/amd/display: Fix plane address updates for video surface formats
Li, Sun peng (Leo)
Sunpeng.Li at amd.com
Mon Mar 11 13:52:31 UTC 2019
On 2019-03-11 9:38 a.m., Nicholas Kazlauskas wrote:
> [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.
>
> Cc: Leo Li <sunpeng.li at amd.com>
Reviewed-by: Leo Li <sunpeng.li at amd.com>
> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas at 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 59a8045c9e2a..e0c0621f40d4 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -2457,6 +2457,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) {
> @@ -2571,7 +2592,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;
> @@ -2583,7 +2603,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;
> @@ -3738,10 +3758,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;
>
> @@ -3794,29 +3812,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;
> @@ -4878,9 +4876,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,
>
More information about the amd-gfx
mailing list