From 7c22adcacb849e0713a7747362e9d38273546270 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexdeucher@gmail.com>
Date: Wed, 17 Nov 2010 17:37:25 -0500
Subject: [PATCH 1/4] radeon/kms: allow tiled front buffer on 6xx/7xx

Use UTS/DFS to tile/untile as appropriate for sw access.
Also enables pageflipping with tiling enabled.
---
 src/drmmode_display.c |   10 ++++++----
 src/evergreen_exa.c   |   21 ++++++++++++++-------
 src/r600_exa.c        |   21 ++++++++++++++-------
 src/radeon_exa.c      |   11 +++++++++++
 src/radeon_kms.c      |    9 ++++++---
 5 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 3332472..5b228fa 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -266,9 +266,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	uint32_t tiling_flags = 0;
 	int height;
 
-	/* no tiled scanout on r6xx+ yet */
 	if (info->allowColorTiling) {
-		if (info->ChipFamily < CHIP_FAMILY_R600)
+		if (info->ChipFamily >= CHIP_FAMILY_R600)
+			tiling_flags |= RADEON_TILING_MICRO;
+		else
 			tiling_flags |= RADEON_TILING_MACRO;
 	}
 
@@ -1161,9 +1162,10 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 	if (front_bo)
 		radeon_bo_wait(front_bo);
 
-	/* no tiled scanout on r6xx+ yet */
 	if (info->allowColorTiling) {
-		if (info->ChipFamily < CHIP_FAMILY_R600)
+		if (info->ChipFamily >= CHIP_FAMILY_R600)
+			tiling_flags |= RADEON_TILING_MICRO;
+		else
 			tiling_flags |= RADEON_TILING_MACRO;
 	}
 
diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c
index 72e3a5d..b832045 100644
--- a/src/evergreen_exa.c
+++ b/src/evergreen_exa.c
@@ -1647,22 +1647,29 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w,
     Bool flush = FALSE;
     Bool r;
     struct r600_accel_object src_obj, dst_obj;
+    uint32_t tiling_flags = 0, pitch = 0;
 
     if (bpp < 8)
 	return FALSE;
 
     driver_priv = exaGetPixmapDriverPrivate(pSrc);
 
+    ret = radeon_bo_get_tiling(driver_priv->bo, &tiling_flags, &pitch);
+    if (ret)
+	ErrorF("radeon_bo_get_tiling failed\n");
+
     /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */
     copy_src = driver_priv->bo;
     copy_pitch = pSrc->devKind;
-    if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
-	src_domain = radeon_bo_get_src_domain(driver_priv->bo);
-	if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
-	    (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
-	    src_domain = 0;
-	else /* A write may be scheduled */
-	    flush = TRUE;
+    if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
+	if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
+	    src_domain = radeon_bo_get_src_domain(driver_priv->bo);
+	    if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
+		(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
+		src_domain = 0;
+	    else /* A write may be scheduled */
+		flush = TRUE;
+	}
     }
 
     if (!src_domain)
diff --git a/src/r600_exa.c b/src/r600_exa.c
index a04d66a..955d8f1 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -1895,22 +1895,29 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
     Bool flush = FALSE;
     Bool r;
     struct r600_accel_object src_obj, dst_obj;
+    uint32_t tiling_flags = 0, pitch = 0;
 
     if (bpp < 8)
 	return FALSE;
 
     driver_priv = exaGetPixmapDriverPrivate(pSrc);
 
+    ret = radeon_bo_get_tiling(driver_priv->bo, &tiling_flags, &pitch);
+    if (ret)
+	ErrorF("radeon_bo_get_tiling failed\n");
+
     /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */
     copy_src = driver_priv->bo;
     copy_pitch = pSrc->devKind;
-    if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
-	src_domain = radeon_bo_get_src_domain(driver_priv->bo);
-	if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
-	    (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
-	    src_domain = 0;
-	else /* A write may be scheduled */
-	    flush = TRUE;
+    if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
+	if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
+	    src_domain = radeon_bo_get_src_domain(driver_priv->bo);
+	    if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
+		(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
+		src_domain = 0;
+	    else /* A write may be scheduled */
+		flush = TRUE;
+	}
     }
 
     if (!src_domain)
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 503d569..1c512d4 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -306,6 +306,17 @@ Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index)
     if (!driver_priv)
       return FALSE;
 
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	uint32_t tiling_flags = 0, pitch = 0;
+
+	ret = radeon_bo_get_tiling(driver_priv->bo, &tiling_flags, &pitch);
+	if (ret)
+	    return FALSE;
+	/* untile in DFS/UTS */
+	if (tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))
+	    return FALSE;
+    }
+
     /* if we have more refs than just the BO then flush */
     if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
 	flush = TRUE;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 0cd419f..10eeb90 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -681,7 +681,9 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 
     /* no tiled scanout on r6xx+ yet */
     if (info->allowColorTiling) {
-	if (info->ChipFamily < CHIP_FAMILY_R600)
+	if (info->ChipFamily >= CHIP_FAMILY_R600)
+	    tiling |= RADEON_TILING_MICRO;
+	else
 	    tiling |= RADEON_TILING_MACRO;
     }
     cpp = pScrn->bitsPerPixel / 8;
@@ -1118,9 +1120,10 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
 	    return FALSE;
     }
 
-    /* no tiled scanout on r6xx+ yet */
     if (info->allowColorTiling) {
-	if (info->ChipFamily < CHIP_FAMILY_R600)
+	if (info->ChipFamily >= CHIP_FAMILY_R600)
+	    tiling_flags |= RADEON_TILING_MICRO;
+	else
 	    tiling_flags |= RADEON_TILING_MACRO;
     }
     pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp;
-- 
1.7.1.1

