summaryrefslogtreecommitdiff
path: root/lib/igt_amd.c
diff options
context:
space:
mode:
authorSung Joon Kim <sungkim@amd.com>2021-02-03 15:56:03 -0500
committerNicholas Kazlauskas <nicholas.kazlauskas@amd.com>2021-02-22 11:58:34 -0500
commit232db375fcd86bef00badb1e3913630a2a5649d6 (patch)
treef0df64d3b4b950f1fdff949fc45e9b74525f19c9 /lib/igt_amd.c
parenta43bcf438e84283dd04d382fbebc4a727137bcc2 (diff)
tests/kms_rotation_crc: Add HW Rotation test case for amdgpu with tiling
Allow amdgpu to run HW rotation IGT test case Added conditions to bypass all the requirements needed for intel when testing amdgpu. Additionally, freed unused frame buffers. Added swizzle 64kb tiling method for amdgpu-specific. Updated drm header for amdgpu tiling modifiers. v2: drm_fourcc.h copied from kernel header commit:8ba16d5993749c3f31fd2b49e16f0dc1e1770b9c from drm-next. removed igt_pipe_crc_collect_crc for intel gpu. Only on AMDGPU. v3: moved drm_fourcc.h to another patch. Removed creating redundant fb in prepare_crtc for amdgpu. Guarded display commit for amdgpu. Blocked cursor plane rotation for amdgpu. Added back tiling when creating reference fb. Signed-off-by: Sung Joon Kim <sungkim@amd.com> Reviewed by: Nikola Cornij <nikola.cornij@amd.com> Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Diffstat (limited to 'lib/igt_amd.c')
-rw-r--r--lib/igt_amd.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/lib/igt_amd.c b/lib/igt_amd.c
index abd3ad96..a4e1cb59 100644
--- a/lib/igt_amd.c
+++ b/lib/igt_amd.c
@@ -24,6 +24,29 @@
#include "igt.h"
#include <amdgpu_drm.h>
+#define X0 1
+#define X1 2
+#define X2 4
+#define X3 8
+#define X4 16
+#define X5 32
+#define X6 64
+#define X7 128
+#define Y0 1
+#define Y1 2
+#define Y2 4
+#define Y3 8
+#define Y4 16
+#define Y5 32
+#define Y6 64
+#define Y7 128
+
+struct dim2d
+{
+ int w;
+ int h;
+};
+
uint32_t igt_amd_create_bo(int fd, uint64_t size)
{
union drm_amdgpu_gem_create create;
@@ -54,3 +77,172 @@ void *igt_amd_mmap_bo(int fd, uint32_t handle, uint64_t size, int prot)
ptr = mmap(0, size, prot, MAP_SHARED, fd, map.out.addr_ptr);
return ptr == MAP_FAILED ? NULL : ptr;
}
+
+unsigned int igt_amd_compute_offset(unsigned int* swizzle_pattern,
+ unsigned int x, unsigned int y)
+{
+ unsigned int offset = 0, index = 0;
+ unsigned int blk_size_table_index = 0, interleave = 0;
+ unsigned int channel[16] =
+ {0, 0, 1, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1};
+ unsigned int i, v;
+
+ for (i = 0; i < 16; i++)
+ {
+ v = 0;
+ if (channel[i] == 1)
+ {
+ blk_size_table_index = 0;
+ interleave = swizzle_pattern[i];
+
+ while (interleave > 1) {
+ blk_size_table_index++;
+ interleave = (interleave + 1) >> 1;
+ }
+
+ index = blk_size_table_index + 2;
+ v ^= (x >> index) & 1;
+ }
+ else if (channel[i] == 2)
+ {
+ blk_size_table_index = 0;
+ interleave = swizzle_pattern[i];
+
+ while (interleave > 1) {
+ blk_size_table_index++;
+ interleave = (interleave + 1) >> 1;
+ }
+
+ index = blk_size_table_index;
+ v ^= (y >> index) & 1;
+ }
+
+ offset |= (v << i);
+ }
+
+ return offset;
+}
+
+unsigned int igt_amd_fb_get_blk_size_table_idx(unsigned int bpp)
+{
+ unsigned int element_bytes;
+ unsigned int blk_size_table_index = 0;
+
+ element_bytes = bpp >> 3;
+
+ while (element_bytes > 1) {
+ blk_size_table_index++;
+ element_bytes = (element_bytes + 1) >> 1;
+ }
+
+ return blk_size_table_index;
+}
+
+void igt_amd_fb_calculate_tile_dimension(unsigned int bpp,
+ unsigned int *width, unsigned int *height)
+{
+ unsigned int blk_size_table_index;
+ unsigned int blk_size_log2, blk_size_log2_256B;
+ unsigned int width_amp, height_amp;
+
+ // swizzle 64kb tile block
+ unsigned int block256_2d[][2] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
+ blk_size_log2 = 16;
+
+ blk_size_table_index = igt_amd_fb_get_blk_size_table_idx(bpp);
+
+ blk_size_log2_256B = blk_size_log2 - 8;
+
+ width_amp = blk_size_log2_256B / 2;
+ height_amp = blk_size_log2_256B - width_amp;
+
+ *width = (block256_2d[blk_size_table_index][0] << width_amp);
+ *height = (block256_2d[blk_size_table_index][1] << height_amp);
+}
+
+uint32_t igt_amd_fb_tiled_offset(unsigned int bpp, unsigned int x_input,
+ unsigned int y_input, unsigned int width_input)
+{
+ unsigned int width, height, pitch;
+ unsigned int pb, yb, xb, blk_idx, blk_offset, addr;
+ unsigned int blk_size_table_index, blk_size_log2;
+ unsigned int* swizzle_pattern;
+
+ // swizzle 64kb tile block
+ unsigned int sw_64k_s[][16]=
+ {
+ {X0, X1, X2, X3, Y0, Y1, Y2, Y3, Y4, X4, Y5, X5, Y6, X6, Y7, X7},
+ {0, X0, X1, X2, Y0, Y1, Y2, X3, Y3, X4, Y4, X5, Y5, X6, Y6, X7},
+ {0, 0, X0, X1, Y0, Y1, Y2, X2, Y3, X3, Y4, X4, Y5, X5, Y6, X6},
+ {0, 0, 0, X0, Y0, Y1, X1, X2, Y2, X3, Y3, X4, Y4, X5, Y5, X6},
+ {0, 0, 0, 0, Y0, Y1, X0, X1, Y2, X2, Y3, X3, Y4, X4, Y5, X5},
+ };
+ igt_amd_fb_calculate_tile_dimension(bpp, &width, &height);
+ blk_size_table_index = igt_amd_fb_get_blk_size_table_idx(bpp);
+ blk_size_log2 = 16;
+
+ pitch = (width_input + (width - 1)) & (~(width - 1));
+
+ swizzle_pattern = sw_64k_s[blk_size_table_index];
+
+ pb = pitch / width;
+ yb = y_input / height;
+ xb = x_input / width;
+ blk_idx = yb * pb + xb;
+ blk_offset = igt_amd_compute_offset(swizzle_pattern,
+ x_input << blk_size_table_index, y_input);
+ addr = (blk_idx << blk_size_log2) + blk_offset;
+
+ return (uint32_t)addr;
+}
+
+void igt_amd_fb_to_tiled(struct igt_fb *dst, void *dst_buf, struct igt_fb *src,
+ void *src_buf, unsigned int plane)
+{
+ uint32_t src_offset, dst_offset;
+ unsigned int bpp = src->plane_bpp[plane];
+ unsigned int width = dst->plane_width[plane];
+ unsigned int height = dst->plane_height[plane];
+ unsigned int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ src_offset = src->offsets[plane];
+ dst_offset = dst->offsets[plane];
+
+ src_offset += src->strides[plane] * y + x * bpp / 8;
+ dst_offset += igt_amd_fb_tiled_offset(bpp, x, y, width);
+
+ switch (bpp) {
+ case 16:
+ *(uint16_t *)(dst_buf + dst_offset) =
+ *(uint16_t *)(src_buf + src_offset);
+ break;
+ case 32:
+ *(uint32_t *)(dst_buf + dst_offset) =
+ *(uint32_t *)(src_buf + src_offset);
+ break;
+ }
+ }
+ }
+}
+
+void igt_amd_fb_convert_plane_to_tiled(struct igt_fb *dst, void *dst_buf,
+ struct igt_fb *src, void *src_buf)
+{
+ unsigned int plane;
+
+ for (plane = 0; plane < src->num_planes; plane++) {
+ igt_require(AMD_FMT_MOD_GET(TILE, dst->modifier) ==
+ AMD_FMT_MOD_TILE_GFX9_64K_S);
+ igt_amd_fb_to_tiled(dst, dst_buf, src, src_buf, plane);
+ }
+}
+
+bool igt_amd_is_tiled(uint64_t modifier)
+{
+ if (IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(TILE, modifier))
+ return true;
+ else
+ return false;
+}