diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 820c121..8c82e43 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -170,6 +170,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	struct r600_cs_track *track = p->track;
 	u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align;
 	volatile u32 *ib = p->ib->ptr;
+	unsigned array_mode;
 
 	if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
 		dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
@@ -185,12 +186,12 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	/* pitch is the number of 8x8 tiles per row */
 	pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1;
 	slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
-	height = size / (pitch * 8 * bpe);
+	slice_tile_max *= 64;
+	height = slice_tile_max / (pitch * 8);
 	if (height > 8192)
 		height = 8192;
-	if (height > 7)
-		height &= ~0x7;
-	switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) {
+	array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]);
+	switch (array_mode) {
 	case V_0280A0_ARRAY_LINEAR_GENERAL:
 		/* technically height & 0x7 */
 		break;
@@ -222,7 +223,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 		break;
 	case V_0280A0_ARRAY_2D_TILED_THIN1:
 		pitch_align = max((u32)track->nbanks,
-				  (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks));
+				  (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8;
 		if (!IS_ALIGNED(pitch, pitch_align)) {
 			dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
 				__func__, __LINE__, pitch);
@@ -243,8 +244,18 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	/* check offset */
 	tmp = height * pitch * 8 * bpe;
 	if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
-		dev_warn(p->dev, "%s offset[%d] %d too big\n", __func__, i, track->cb_color_bo_offset[i]);
-		return -EINVAL;
+		if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
+			/* the initial DDX does bad things with the CB size occasionally */
+			/* it rounds up height too far for slice tile max but the BO is smaller */
+			tmp = (height - 7) * 8 * bpe;
+			if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
+				dev_warn(p->dev, "%s offset[%d] %d %d %d too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
+				return -EINVAL;
+			}
+		} else {
+			dev_warn(p->dev, "%s offset[%d] %d %d %d too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
+			return -EINVAL;
+		}
 	}
 	if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) {
 		dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]);
@@ -361,7 +372,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
 				break;
 			case V_028010_ARRAY_2D_TILED_THIN1:
 				pitch_align = max((u32)track->nbanks,
-						  (u32)(((track->group_size / 8) / bpe) * track->nbanks));
+						  (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
 				if (!IS_ALIGNED(pitch, pitch_align)) {
 					dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
 						 __func__, __LINE__, pitch);
@@ -1139,7 +1150,7 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
 		break;
 	case V_038000_ARRAY_2D_TILED_THIN1:
 		pitch_align = max((u32)track->nbanks,
-				  (u32)(((track->group_size / 8) / bpe) * track->nbanks));
+				  (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
 		if (!IS_ALIGNED(pitch, pitch_align)) {
 			dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
 				__func__, __LINE__, pitch);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index f29a269..f9e2286 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -47,9 +47,10 @@
  * - 2.4.0 - add crtc id query
  * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen
  * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500)
+ *   2.7.0 - fixups for r600 2D tiling support. (no external ABI change)
  */
 #define KMS_DRIVER_MAJOR	2
-#define KMS_DRIVER_MINOR	6
+#define KMS_DRIVER_MINOR	7
 #define KMS_DRIVER_PATCHLEVEL	0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
