Blob Blame History Raw
From d5c869fe0fda3edc4c83d046f5d015be1cbd4213 Mon Sep 17 00:00:00 2001
From: Aurabindo Pillai <aurabindo.pillai@amd.com>
Date: Tue, 28 Jun 2022 16:25:28 -0400
Subject: drm/amd/display: expose additional modifier for DCN32/321
Git-commit: ff15cea338d2c78e0086d55c8a9dd637a5dd3ccc
Patch-mainline: v6.0-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225 jsc#PED-2849

[Why&How]
Some userspace expect a backwards compatible modifier on DCN32/321. For
hardware with num_pipes more than 16, we expose the most efficient
modifier first. As a fall back method, we need to expose slightly inefficient
modifier AMD_FMT_MOD_TILE_GFX9_64K_R_X after the best option.

Also set the number of packers to fixed value as required per hardware
documentation. This value is cached during hardware initialization and
can be read through the base driver.

Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  3 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 66 ++++++++++---------
 2 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index a2e62d9405e7..c20922a5af9f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -744,8 +744,7 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
 			switch (version) {
 			case AMD_FMT_MOD_TILE_VER_GFX11:
 				pipe_xor_bits = min(block_size_bits - 8, pipes);
-				packers = min(block_size_bits - 8 - pipe_xor_bits,
-						ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
+				packers = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
 				break;
 			case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
 				pipe_xor_bits = min(block_size_bits - 8, pipes);
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 10a375df2f9f..c3178f63c976 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5276,6 +5276,7 @@ add_gfx11_modifiers(struct amdgpu_device *adev,
 	int num_pkrs = 0;
 	int pkrs = 0;
 	u32 gb_addr_config;
+	u8 i = 0;
 	unsigned swizzle_r_x;
 	uint64_t modifier_r_x;
 	uint64_t modifier_dcc_best;
@@ -5291,37 +5292,40 @@ add_gfx11_modifiers(struct amdgpu_device *adev,
 	num_pipes = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PIPES);
 	pipe_xor_bits = ilog2(num_pipes);
 
-	/* R_X swizzle modes are the best for rendering and DCC requires them. */
-	swizzle_r_x = num_pipes > 16 ? AMD_FMT_MOD_TILE_GFX11_256K_R_X :
-                                              AMD_FMT_MOD_TILE_GFX9_64K_R_X;
-
-	modifier_r_x = AMD_FMT_MOD |
-		AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
-		AMD_FMT_MOD_SET(TILE, swizzle_r_x) |
-		AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
-		AMD_FMT_MOD_SET(PACKERS, pkrs);
-
-	/* DCC_CONSTANT_ENCODE is not set because it can't vary with gfx11 (it's implied to be 1). */
-	modifier_dcc_best = modifier_r_x |
-		AMD_FMT_MOD_SET(DCC, 1) |
-		AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 0) |
-		AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
-		AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B);
-
-	/* DCC settings for 4K and greater resolutions. (required by display hw) */
-	modifier_dcc_4k = modifier_r_x |
-			AMD_FMT_MOD_SET(DCC, 1) |
-			AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
-			AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
-			AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B);
-
-	add_modifier(mods, size, capacity, modifier_dcc_best);
-	add_modifier(mods, size, capacity, modifier_dcc_4k);
-
-	add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1));
-	add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1));
-
-	add_modifier(mods, size, capacity, modifier_r_x);
+	for (i = 0; i < 2; i++) {
+		/* Insert the best one first. */
+		/* R_X swizzle modes are the best for rendering and DCC requires them. */
+		if (num_pipes > 16)
+			swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX11_256K_R_X : AMD_FMT_MOD_TILE_GFX9_64K_R_X;
+		else
+			swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX9_64K_R_X : AMD_FMT_MOD_TILE_GFX11_256K_R_X;
+
+		modifier_r_x = AMD_FMT_MOD |
+			       AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
+			       AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+			       AMD_FMT_MOD_SET(TILE, swizzle_r_x) |
+			       AMD_FMT_MOD_SET(PACKERS, pkrs);
+
+		/* DCC_CONSTANT_ENCODE is not set because it can't vary with gfx11 (it's implied to be 1). */
+		modifier_dcc_best = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) |
+				    AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 0) |
+				    AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+				    AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B);
+
+		/* DCC settings for 4K and greater resolutions. (required by display hw) */
+		modifier_dcc_4k = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) |
+				  AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+				  AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+				  AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B);
+
+		add_modifier(mods, size, capacity, modifier_dcc_best);
+		add_modifier(mods, size, capacity, modifier_dcc_4k);
+
+		add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1));
+		add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1));
+
+		add_modifier(mods, size, capacity, modifier_r_x);
+	}
 
 	add_modifier(mods, size, capacity, AMD_FMT_MOD |
              AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
-- 
2.38.1