From 9df95ba119842740baa6f7509cafda595dfa22a7 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexander.deucher@amd.com>
Date: Wed, 3 Aug 2011 10:38:45 -0400
Subject: [PATCH] drm/radeon/kms: add htile support to the cs checker

For 6xx+.  Required for mesa to use htile support
for HiZ/HiS.

Based on a patch from Pierre-Eric Pelloux-Prayer.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/radeon/evergreen_cs.c     |   15 ++++++++++
 drivers/gpu/drm/radeon/evergreend.h       |    2 +
 drivers/gpu/drm/radeon/r600_cs.c          |   44 +++++++++++++++++++++++++++-
 drivers/gpu/drm/radeon/r600d.h            |    1 +
 drivers/gpu/drm/radeon/radeon_drv.c       |    2 +-
 drivers/gpu/drm/radeon/reg_srcs/cayman    |    1 -
 drivers/gpu/drm/radeon/reg_srcs/evergreen |    1 -
 drivers/gpu/drm/radeon/reg_srcs/r600      |    1 -
 8 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 189e865..eb9b357 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -75,6 +75,8 @@ struct evergreen_cs_track {
 	u32			db_s_write_offset;
 	struct radeon_bo	*db_s_read_bo;
 	struct radeon_bo	*db_s_write_bo;
+	u32			htile_offset;
+	struct radeon_bo	*htile_bo;
 };
 
 static void evergreen_cs_track_init(struct evergreen_cs_track *track)
@@ -849,6 +851,19 @@ static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u3
 	case CB_IMMED10_BASE:
 	case CB_IMMED11_BASE:
 	case DB_HTILE_DATA_BASE:
+		r = evergreen_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		track->htile_offset = radeon_get_ib_value(p, idx);
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		track->htile_bo = reloc->robj;
+		break;
+	case DB_HTILE_SURFACE:
+		/* 8x8 only */
+		break;
 	case SQ_PGM_START_FS:
 	case SQ_PGM_START_ES:
 	case SQ_PGM_START_VS:
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 7363d9d..bd37834 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -922,6 +922,8 @@
 
 #define GDS_ADDR_BASE					0x28720
 
+#define DB_HTILE_SURFACE				0x28abc
+
 #define	CB_IMMED0_BASE					0x28b9c
 #define	CB_IMMED1_BASE					0x28ba0
 #define	CB_IMMED2_BASE					0x28ba4
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index db8ef19..855bdca 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -69,6 +69,11 @@ struct r600_cs_track {
 	u32			db_offset;
 	struct radeon_bo	*db_bo;
 	u64			db_bo_mc;
+	u32			htile_offset;
+	struct radeon_bo	*htile_bo;
+	u64			htile_bo_mc;
+	int                     htile_w;
+	int                     htile_h;
 };
 
 #define FMT_8_BIT(fmt, vc)   [fmt] = { 1, 1, 1, vc, CHIP_R600 }
@@ -323,6 +328,10 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 	track->cb_shader_mask = 0xFFFFFFFF;
 	track->db_bo = NULL;
 	track->db_bo_mc = 0xFFFFFFFF;
+	track->htile_bo = NULL;
+	track->htile_bo_mc = 0xFFFFFFFF;
+	track->htile_w = 4;
+	track->htile_h = 4;
 	/* assume the biggest format and that htile is enabled */
 	track->db_depth_info = 7 | (1 << 25);
 	track->db_depth_view = 0xFFFFC000;
@@ -485,8 +494,9 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
 			dev_warn(p->dev, "z/stencil with no depth buffer\n");
 			return -EINVAL;
 		}
-		if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
-			dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n");
+		if ((track->htile_bo == NULL) &&
+		    G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
+			dev_warn(p->dev, "z/stencil htile enabled with no htile surface\n");
 			return -EINVAL;
 		}
 		switch (G_028010_FORMAT(track->db_depth_info)) {
@@ -585,6 +595,18 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
 					 radeon_bo_size(track->db_bo));
 				return -EINVAL;
 			}
+			/* check htile buffer */
+			if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
+				tmp = (pitch / track->htile_w) * (height / track->htile_h) * 4;
+				if ((tmp + track->htile_offset) > radeon_bo_size(track->htile_bo)) {
+					dev_warn(p->dev, "htile buffer too small (%dx%d (%dx%d) -> %u have %lu)\n",
+						 pitch, height,
+						 track->htile_w, track->htile_h,
+						 tmp + track->htile_offset,
+						 radeon_bo_size(track->htile_bo));
+					return -EINVAL;
+				}
+			}
 		}
 	}
 	return 0;
@@ -1139,6 +1161,24 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
 		track->db_bo_mc = reloc->lobj.gpu_offset;
 		break;
 	case DB_HTILE_DATA_BASE:
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		track->htile_offset = radeon_get_ib_value(p, idx) << 8;
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		track->htile_bo = reloc->robj;
+		track->htile_bo_mc = reloc->lobj.gpu_offset;
+		break;
+	case DB_HTILE_SURFACE:
+		tmp = radeon_get_ib_value(p, idx);
+		if (tmp & 1)
+			track->htile_w = 8;
+		if (tmp & 2)
+			track->htile_h = 8;
+		break;
 	case SQ_PGM_START_FS:
 	case SQ_PGM_START_ES:
 	case SQ_PGM_START_VS:
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index a1f3904..0270ac7 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -176,6 +176,7 @@
 #define		PREZ_MUST_WAIT_FOR_POSTZ_DONE			(1 << 31)
 #define	DB_DEPTH_BASE					0x2800C
 #define	DB_HTILE_DATA_BASE				0x28014
+#define	DB_HTILE_SURFACE				0x28D24
 #define	DB_WATERMARKS					0x9838
 #define		DEPTH_FREE(x)					((x) << 0)
 #define		DEPTH_FLUSH(x)					((x) << 5)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index e71d2ed..1220bc8 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -51,7 +51,7 @@
  *   2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query
  *   2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query
  *   2.10.0 - fusion 2D tiling
- *   2.11.0 - backend map, initial compute support for the CS checker
+ *   2.11.0 - backend map, initial compute support for the CS checker, cs htile support
  */
 #define KMS_DRIVER_MAJOR	2
 #define KMS_DRIVER_MINOR	11
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman
index 2316977..f34e8c1 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/cayman
+++ b/drivers/gpu/drm/radeon/reg_srcs/cayman
@@ -508,7 +508,6 @@ cayman 0x9400
 0x00028AA8 IA_MULTI_VGT_PARAM
 0x00028AB4 VGT_REUSE_OFF
 0x00028AB8 VGT_VTX_CNT_EN
-0x00028ABC DB_HTILE_SURFACE
 0x00028AC0 DB_SRESULTS_COMPARE_STATE0
 0x00028AC4 DB_SRESULTS_COMPARE_STATE1
 0x00028AC8 DB_PRELOAD_CONTROL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
index 161737a..44f0fe4 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/evergreen
+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen
@@ -518,7 +518,6 @@ evergreen 0x9400
 0x00028AA4 VGT_INSTANCE_STEP_RATE_1
 0x00028AB4 VGT_REUSE_OFF
 0x00028AB8 VGT_VTX_CNT_EN
-0x00028ABC DB_HTILE_SURFACE
 0x00028AC0 DB_SRESULTS_COMPARE_STATE0
 0x00028AC4 DB_SRESULTS_COMPARE_STATE1
 0x00028AC8 DB_PRELOAD_CONTROL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600
index 0380c5c..6eae8f2 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r600
+++ b/drivers/gpu/drm/radeon/reg_srcs/r600
@@ -703,7 +703,6 @@ r600 0x9400
 0x0000A710 TD_VS_SAMPLER17_BORDER_RED
 0x00009508 TA_CNTL_AUX
 0x0002802C DB_DEPTH_CLEAR
-0x00028D24 DB_HTILE_SURFACE
 0x00028D34 DB_PREFETCH_LIMIT
 0x00028D30 DB_PRELOAD_CONTROL
 0x00028D0C DB_RENDER_CONTROL
-- 
1.7.1.1

