diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1039-drm-amd-display-Set-requested-plane-state-DCC-params.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1039-drm-amd-display-Set-requested-plane-state-DCC-params.patch | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1039-drm-amd-display-Set-requested-plane-state-DCC-params.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1039-drm-amd-display-Set-requested-plane-state-DCC-params.patch new file mode 100644 index 00000000..c22bf5d1 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1039-drm-amd-display-Set-requested-plane-state-DCC-params.patch @@ -0,0 +1,218 @@ +From b7bc066b031e2d5281d402a308fc239c0353800d Mon Sep 17 00:00:00 2001 +From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Date: Wed, 2 Jan 2019 15:15:41 -0500 +Subject: [PATCH 1039/2940] drm/amd/display: Set requested plane state DCC + params for GFX9 + +[Why] +Hardware support for Delta Color Compression (DCC) decompression is +available in DC for GFX9 but there's no way for userspace to enable +the feature. + +Enabling the feature can provide improved GFX performance and +power savings in many situations. + +[How] +The GFX9 DCC parameters are passed to amdgpu_dm from AMDGPU via the +amdgpu_bo tiling_flags. The plane capability is queried and the +parameters are set accordingly. + +The DCC address is given via a 256 byte aligned offset on the +framebuffer address. The DCC address is updated whenever the buffer +address changes. + +Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +Reviewed-by: Harry Wentland <harry.wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Chaudhary Amit Kumar <Chaudharyamit.Kumar@amd.com> +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 90 ++++++++++++++++++- + include/uapi/drm/amdgpu_drm.h | 7 ++ + 2 files changed, 95 insertions(+), 2 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 abd7b8334955..0f5397059c75 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2297,6 +2297,68 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, + return r; + } + ++static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags) ++{ ++ uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B); ++ ++ return offset ? (address + offset * 256) : 0; ++} ++ ++static bool fill_plane_dcc_attributes(struct amdgpu_device *adev, ++ const struct amdgpu_framebuffer *afb, ++ struct dc_plane_state *plane_state, ++ uint64_t info) ++{ ++ struct dc *dc = adev->dm.dc; ++ struct dc_dcc_surface_param input = {0}; ++ struct dc_surface_dcc_cap output = {0}; ++ uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B); ++ uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0; ++ uint64_t dcc_address; ++ ++ if (!offset) ++ return false; ++ ++ if (!dc->cap_funcs.get_dcc_compression_cap) ++ return false; ++ ++ input.format = plane_state->format; ++ input.surface_size.width = ++ plane_state->plane_size.grph.surface_size.width; ++ input.surface_size.height = ++ plane_state->plane_size.grph.surface_size.height; ++ input.swizzle_mode = plane_state->tiling_info.gfx9.swizzle; ++ ++ if (plane_state->rotation == ROTATION_ANGLE_0 || ++ plane_state->rotation == ROTATION_ANGLE_180) ++ input.scan = SCAN_DIRECTION_HORIZONTAL; ++ else if (plane_state->rotation == ROTATION_ANGLE_90 || ++ plane_state->rotation == ROTATION_ANGLE_270) ++ input.scan = SCAN_DIRECTION_VERTICAL; ++ ++ if (!dc->cap_funcs.get_dcc_compression_cap(dc, &input, &output)) ++ return false; ++ ++ if (!output.capable) ++ return false; ++ ++ if (i64b == 0 && output.grph.rgb.independent_64b_blks != 0) ++ return false; ++ ++ plane_state->dcc.enable = 1; ++ plane_state->dcc.grph.meta_pitch = ++ AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1; ++ plane_state->dcc.grph.independent_64b_blks = i64b; ++ ++ dcc_address = get_dcc_address(afb->address, info); ++ 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); ++ ++ return true; ++} ++ + static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, + struct dc_plane_state *plane_state, + const struct amdgpu_framebuffer *amdgpu_fb) +@@ -2349,6 +2411,10 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, + return -EINVAL; + } + ++ memset(&plane_state->address, 0, sizeof(plane_state->address)); ++ memset(&plane_state->tiling_info, 0, sizeof(plane_state->tiling_info)); ++ memset(&plane_state->dcc, 0, sizeof(plane_state->dcc)); ++ + 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; +@@ -2380,8 +2446,6 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, + plane_state->color_space = COLOR_SPACE_YCBCR709; + } + +- memset(&plane_state->tiling_info, 0, sizeof(plane_state->tiling_info)); +- + /* Fill GFX8 params */ + if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) { + unsigned int bankw, bankh, mtaspect, tile_split, num_banks; +@@ -2431,6 +2495,9 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, + plane_state->tiling_info.gfx9.swizzle = + AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE); + plane_state->tiling_info.gfx9.shaderEnable = 1; ++ ++ fill_plane_dcc_attributes(adev, amdgpu_fb, plane_state, ++ tiling_flags); + } + + plane_state->visible = true; +@@ -3562,6 +3629,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, + 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; + uint32_t domain; + int r; +@@ -3602,6 +3670,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, + DRM_ERROR("%p bind failed\n", rbo); + return r; + } ++ ++ amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); ++ + amdgpu_bo_unreserve(rbo); + + afb->address = amdgpu_bo_gpu_offset(rbo); +@@ -3615,6 +3686,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, + 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; +@@ -4597,6 +4675,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, + struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); + struct dc_stream_status *stream_status; + struct dc_plane_state *surface; ++ uint64_t tiling_flags, dcc_address; + + + /* Prepare wait for target vblank early - before the fence-waits */ +@@ -4619,6 +4698,8 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, + WARN_ON(reservation_object_wait_timeout_rcu(abo->tbo.resv, true, false, + MAX_SCHEDULE_TIMEOUT) < 0); + ++ amdgpu_bo_get_tiling_flags(abo, &tiling_flags); ++ + amdgpu_bo_unreserve(abo); + + /* +@@ -4644,6 +4725,11 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, + + addr.address.grph.addr.low_part = lower_32_bits(afb->address); + addr.address.grph.addr.high_part = upper_32_bits(afb->address); ++ ++ dcc_address = get_dcc_address(afb->address, tiling_flags); ++ addr.address.grph.meta_addr.low_part = lower_32_bits(dcc_address); ++ addr.address.grph.meta_addr.high_part = upper_32_bits(dcc_address); ++ + addr.flip_immediate = async_flip; + + timestamp_ns = ktime_get_ns(); +diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h +index ac71a14540a7..8129a2beffeb 100644 +--- a/include/uapi/drm/amdgpu_drm.h ++++ b/include/uapi/drm/amdgpu_drm.h +@@ -384,6 +384,13 @@ struct drm_amdgpu_gem_dgma { + /* GFX9 and later: */ + #define AMDGPU_TILING_SWIZZLE_MODE_SHIFT 0 + #define AMDGPU_TILING_SWIZZLE_MODE_MASK 0x1f ++#define AMDGPU_TILING_DCC_OFFSET_256B_SHIFT 5 ++#define AMDGPU_TILING_DCC_OFFSET_256B_MASK 0xFFFFFF ++#define AMDGPU_TILING_DCC_PITCH_MAX_SHIFT 29 ++#define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF ++#define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43 ++#define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1 ++ + + /* Set/Get helpers for tiling flags. */ + #define AMDGPU_TILING_SET(field, value) \ +-- +2.17.1 + |