From 2b84bcf5b24cc26aec3d6a6c75d478795a30d0c6 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexander.deucher@amd.com>
Date: Wed, 23 Nov 2011 12:38:00 -0500
Subject: [PATCH] drm/radeon/kms: properly set up backend map for Barts LE (v2)

May fix:
https://bugs.freedesktop.org/show_bug.cgi?id=39282

v2: add additional cases.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@kernel.org
---
 drivers/gpu/drm/radeon/evergreen.c |   66 ++++++++++++++++++++++++++++++++++--
 1 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 7a98c66..dd5b5bb 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1825,8 +1825,14 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 		rdev->config.evergreen.num_ses = 2;
 		rdev->config.evergreen.max_pipes = 4;
 		rdev->config.evergreen.max_tile_pipes = 8;
-		rdev->config.evergreen.max_simds = 7;
-		rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
+		if (rdev->pdev->device == 0x673e) {
+			/* BARTS LE */
+			rdev->config.evergreen.max_simds = 5;
+			rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
+		} else {
+			rdev->config.evergreen.max_simds = 7;
+			rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
+		}
 		rdev->config.evergreen.max_gprs = 256;
 		rdev->config.evergreen.max_threads = 248;
 		rdev->config.evergreen.max_gs_threads = 32;
@@ -1908,7 +1914,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 		INACTIVE_SIMDS((EVERGREEN_MAX_SIMDS_MASK << rdev->config.evergreen.max_simds)
 			       & EVERGREEN_MAX_SIMDS_MASK);
 
-	cc_rb_backend_disable =
+	cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE);
+	cc_rb_backend_disable |=
 		BACKEND_DISABLE((EVERGREEN_MAX_BACKENDS_MASK << rdev->config.evergreen.max_backends)
 				& EVERGREEN_MAX_BACKENDS_MASK);
 
@@ -2026,6 +2033,58 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 									EVERGREEN_MAX_BACKENDS_MASK));
 			break;
 		}
+	} else if (rdev->pdev->device == 0x673e) {
+		switch ((RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16) {
+		case 0x00:
+			gb_backend_map = 0x76543210;
+			break;
+		case 0x05:
+			gb_backend_map = 0x76543311;
+			break;
+		case 0x06:
+			gb_backend_map = 0x76543300;
+			break;
+		case 0x09:
+			gb_backend_map = 0x76542211;
+			break;
+		case 0x0a:
+			gb_backend_map = 0x76542200;
+			break;
+		case 0x55:
+			gb_backend_map = 0x77553311;
+			break;
+		case 0x56:
+			gb_backend_map = 0x77553300;
+			break;
+		case 0x59:
+			gb_backend_map = 0x77552211;
+			break;
+		case 0x66:
+			gb_backend_map = 0x77443300;
+			break;
+		case 0x99:
+			gb_backend_map = 0x66552211;
+			break;
+		case 0x5a:
+			gb_backend_map = 0x77552200;
+			break;
+		case 0xaa:
+			gb_backend_map = 0x66442200;
+			break;
+		case 0x95:
+			gb_backend_map = 0x66553311;
+			break;
+		default:
+			DRM_ERROR("bad backend map, using default\n");
+			gb_backend_map =
+				evergreen_get_tile_pipe_to_backend_map(rdev,
+								       rdev->config.evergreen.max_tile_pipes,
+								       rdev->config.evergreen.max_backends,
+								       ((EVERGREEN_MAX_BACKENDS_MASK <<
+								   rdev->config.evergreen.max_backends) &
+									EVERGREEN_MAX_BACKENDS_MASK));
+			break;
+		}
 	} else {
 		switch (rdev->family) {
 		case CHIP_CYPRESS:
@@ -2044,6 +2103,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 								       ((EVERGREEN_MAX_BACKENDS_MASK <<
 									 rdev->config.evergreen.max_backends) &
 									EVERGREEN_MAX_BACKENDS_MASK));
+			break;
 		}
 	}
 
-- 
1.7.3.4