diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index e564442b6393f82520aad6e2f47f99e23f7c68bc..b4e4ec630e8cfd5d38d55b61199f3cc60269e0c2 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1944,9 +1944,7 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc,
 
 	dce_v6_0_lock_cursor(crtc, true);
 
-	if (width != amdgpu_crtc->cursor_width ||
-	    height != amdgpu_crtc->cursor_height ||
-	    hot_x != amdgpu_crtc->cursor_hot_x ||
+	if (hot_x != amdgpu_crtc->cursor_hot_x ||
 	    hot_y != amdgpu_crtc->cursor_hot_y) {
 		int x, y;
 
@@ -1955,8 +1953,6 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc,
 
 		dce_v6_0_cursor_move_locked(crtc, x, y);
 
-		amdgpu_crtc->cursor_width = width;
-		amdgpu_crtc->cursor_height = height;
 		amdgpu_crtc->cursor_hot_x = hot_x;
 		amdgpu_crtc->cursor_hot_y = hot_y;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 6ce7fb42dbef68232a8325d720d54bf99b3c8783..584abe834a3ce4658de0e54f6aae416729ad868f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -2438,8 +2438,6 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,
 
 		dce_v8_0_cursor_move_locked(crtc, x, y);
 
-		amdgpu_crtc->cursor_width = width;
-		amdgpu_crtc->cursor_height = height;
 		amdgpu_crtc->cursor_hot_x = hot_x;
 		amdgpu_crtc->cursor_hot_y = hot_y;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
index 558640aee15a178f9e79ba786bd67bfc12c7d197..b323f5ef64d217813683722ec4cd25282e9185ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -411,244 +411,587 @@ static void gfx_v6_0_tiling_mode_table_init(struct amdgpu_device *adev)
 		break;
 	}
 
-	if (adev->asic_type == CHIP_VERDE ||
-	    adev->asic_type == CHIP_OLAND ||
-	    adev->asic_type == CHIP_HAINAN) {
+	if (adev->asic_type == CHIP_VERDE) {
 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
 			switch (reg_offset) {
 			case 0:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 1:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 2:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 3:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
 				break;
 			case 4:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16));
 				break;
 			case 5:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
 				break;
 			case 6:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
 				break;
 			case 7:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
 			case 8:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED));
 				break;
 			case 9:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16));
 				break;
 			case 10:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 11:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 12:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 13:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16));
 				break;
 			case 14:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 15:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 16:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
 			case 17:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 18:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THICK) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16));
+				break;
+			case 19:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_XTHICK) |
 						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
 						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 20:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THICK) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
 				break;
 			case 21:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
 				break;
 			case 22:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 23:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 24:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 25:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 26:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 27:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 28:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 29:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 30:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			default:
+				continue;
+			}
+			adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden;
+			WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden);
+		}
+	} else if (adev->asic_type == CHIP_OLAND ||
+	    adev->asic_type == CHIP_HAINAN) {
+		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+			switch (reg_offset) {
+			case 0:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 1:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 2:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 3:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 4:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2));
+				break;
+			case 5:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 6:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 7:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 8:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED));
+				break;
+			case 9:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2));
+				break;
+			case 10:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 11:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 12:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 13:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2));
+				break;
+			case 14:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 15:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 16:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 17:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
 						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 18:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THICK) |
+						 PIPE_CONFIG(ADDR_SURF_P2));
+				break;
+			case 19:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_XTHICK) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 20:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THICK) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 21:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 22:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
 				break;
 			case 23:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
 				break;
 			case 24:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
 				break;
 			case 25:
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
-						 NUM_BANKS(ADDR_SURF_8_BANK) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 26:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 27:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 28:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 29:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 30:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
 				break;
 			default:
-				gb_tile_moden = 0;
-				break;
+				continue;
 			}
 			adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden;
 			WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden);
@@ -656,239 +999,291 @@ static void gfx_v6_0_tiling_mode_table_init(struct amdgpu_device *adev)
 	} else if ((adev->asic_type == CHIP_TAHITI) || (adev->asic_type == CHIP_PITCAIRN)) {
 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
 			switch (reg_offset) {
-			case 0:  /* non-AA compressed depth or any compressed stencil */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+			case 0:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 1:  /* 2xAA/4xAA compressed depth only */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+			case 1:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 2:  /* 8xAA compressed depth only */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+			case 2:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 3:  /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+			case 3:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
 				break;
-			case 4:  /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+			case 4:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16));
 				break;
-			case 5:  /* Uncompressed 16bpp depth - and stencil buffer allocated with it */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+			case 5:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
-			case 6:  /* Uncompressed 32bpp depth - and stencil buffer allocated with it */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+			case 6:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
-			case 7:  /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
+			case 7:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
-			case 8:  /* 1D and 1D Array Surfaces */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+			case 8:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED));
 				break;
-			case 9:  /* Displayable maps. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+			case 9:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16));
 				break;
-			case 10:  /* Display 8bpp. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+			case 10:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 11:  /* Display 16bpp. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+			case 11:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 12:  /* Display 32bpp. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+			case 12:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 13:  /* Thin. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+			case 13:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16));
 				break;
-			case 14:  /* Thin 8 bpp. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 14:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 15:  /* Thin 16 bpp. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 15:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 16:  /* Thin 32 bpp. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 16:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
 				break;
-			case 17:  /* Thin 64 bpp. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 17:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(split_equal_to_row_size) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
 						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 18:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_1D_TILED_THICK) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16));
+				break;
+			case 19:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_XTHICK) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_16_BANK) |
+						 TILE_SPLIT(split_equal_to_row_size));
 				break;
-			case 21:  /* 8 bpp PRT. */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 20:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THICK) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
 						 NUM_BANKS(ADDR_SURF_16_BANK) |
-						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 TILE_SPLIT(split_equal_to_row_size));
 				break;
-			case 22:  /* 16 bpp PRT */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 21:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 22:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
 						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
 				break;
-			case 23:  /* 32 bpp PRT */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 23:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
-			case 24:  /* 64 bpp PRT */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+			case 24:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
 						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
-						 NUM_BANKS(ADDR_SURF_16_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
-			case 25:  /* 128 bpp PRT */
-				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
-						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+			case 25:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
 						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
-						 NUM_BANKS(ADDR_SURF_8_BANK) |
 						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
-			default:
-				gb_tile_moden = 0;
+			case 26:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 27:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 28:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
 				break;
+			case 29:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 30:
+				gb_tile_moden = (MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
+						 ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) |
+						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			default:
+				continue;
 			}
 			adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden;
 			WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index 6324f67bdb1fac705d79e80c4d85ce097ec7358f..d0ec00986f3826c32957ab432c677c53c24091c2 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -3949,8 +3949,12 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev)
 	temp = mmRLC_SRM_INDEX_CNTL_ADDR_0;
 	data = mmRLC_SRM_INDEX_CNTL_DATA_0;
 	for (i = 0; i < sizeof(unique_indices) / sizeof(int); i++) {
-		amdgpu_mm_wreg(adev, temp + i, unique_indices[i] & 0x3FFFF, false);
-		amdgpu_mm_wreg(adev, data + i, unique_indices[i] >> 20, false);
+		if (unique_indices[i] != 0) {
+			amdgpu_mm_wreg(adev, temp + i,
+					unique_indices[i] & 0x3FFFF, false);
+			amdgpu_mm_wreg(adev, data + i,
+					unique_indices[i] >> 20, false);
+		}
 	}
 	kfree(register_list_format);
 
@@ -3966,20 +3970,17 @@ static void gfx_v8_0_init_power_gating(struct amdgpu_device *adev)
 {
 	uint32_t data;
 
-	if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
-			      AMD_PG_SUPPORT_GFX_SMG |
-			      AMD_PG_SUPPORT_GFX_DMG)) {
-		WREG32_FIELD(CP_RB_WPTR_POLL_CNTL, IDLE_POLL_COUNT, 0x60);
+	WREG32_FIELD(CP_RB_WPTR_POLL_CNTL, IDLE_POLL_COUNT, 0x60);
 
-		data = REG_SET_FIELD(0, RLC_PG_DELAY, POWER_UP_DELAY, 0x10);
-		data = REG_SET_FIELD(data, RLC_PG_DELAY, POWER_DOWN_DELAY, 0x10);
-		data = REG_SET_FIELD(data, RLC_PG_DELAY, CMD_PROPAGATE_DELAY, 0x10);
-		data = REG_SET_FIELD(data, RLC_PG_DELAY, MEM_SLEEP_DELAY, 0x10);
-		WREG32(mmRLC_PG_DELAY, data);
+	data = REG_SET_FIELD(0, RLC_PG_DELAY, POWER_UP_DELAY, 0x10);
+	data = REG_SET_FIELD(data, RLC_PG_DELAY, POWER_DOWN_DELAY, 0x10);
+	data = REG_SET_FIELD(data, RLC_PG_DELAY, CMD_PROPAGATE_DELAY, 0x10);
+	data = REG_SET_FIELD(data, RLC_PG_DELAY, MEM_SLEEP_DELAY, 0x10);
+	WREG32(mmRLC_PG_DELAY, data);
+
+	WREG32_FIELD(RLC_PG_DELAY_2, SERDES_CMD_DELAY, 0x3);
+	WREG32_FIELD(RLC_AUTO_PG_CTRL, GRBM_REG_SAVE_GFX_IDLE_THRESHOLD, 0x55f0);
 
-		WREG32_FIELD(RLC_PG_DELAY_2, SERDES_CMD_DELAY, 0x3);
-		WREG32_FIELD(RLC_AUTO_PG_CTRL, GRBM_REG_SAVE_GFX_IDLE_THRESHOLD, 0x55f0);
-	}
 }
 
 static void cz_enable_sck_slow_down_on_power_up(struct amdgpu_device *adev,
@@ -3996,41 +3997,37 @@ static void cz_enable_sck_slow_down_on_power_down(struct amdgpu_device *adev,
 
 static void cz_enable_cp_power_gating(struct amdgpu_device *adev, bool enable)
 {
-	WREG32_FIELD(RLC_PG_CNTL, CP_PG_DISABLE, enable ? 1 : 0);
+	WREG32_FIELD(RLC_PG_CNTL, CP_PG_DISABLE, enable ? 0 : 1);
 }
 
 static void gfx_v8_0_init_pg(struct amdgpu_device *adev)
 {
-	if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
-			      AMD_PG_SUPPORT_GFX_SMG |
-			      AMD_PG_SUPPORT_GFX_DMG |
-			      AMD_PG_SUPPORT_CP |
-			      AMD_PG_SUPPORT_GDS |
-			      AMD_PG_SUPPORT_RLC_SMU_HS)) {
+	if ((adev->asic_type == CHIP_CARRIZO) ||
+	    (adev->asic_type == CHIP_STONEY)) {
 		gfx_v8_0_init_csb(adev);
 		gfx_v8_0_init_save_restore_list(adev);
 		gfx_v8_0_enable_save_restore_machine(adev);
-
-		if ((adev->asic_type == CHIP_CARRIZO) ||
-		    (adev->asic_type == CHIP_STONEY)) {
-			WREG32(mmRLC_JUMP_TABLE_RESTORE, adev->gfx.rlc.cp_table_gpu_addr >> 8);
-			gfx_v8_0_init_power_gating(adev);
-			WREG32(mmRLC_PG_ALWAYS_ON_CU_MASK, adev->gfx.cu_info.ao_cu_mask);
-			if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) {
-				cz_enable_sck_slow_down_on_power_up(adev, true);
-				cz_enable_sck_slow_down_on_power_down(adev, true);
-			} else {
-				cz_enable_sck_slow_down_on_power_up(adev, false);
-				cz_enable_sck_slow_down_on_power_down(adev, false);
-			}
-			if (adev->pg_flags & AMD_PG_SUPPORT_CP)
-				cz_enable_cp_power_gating(adev, true);
-			else
-				cz_enable_cp_power_gating(adev, false);
-		} else if (adev->asic_type == CHIP_POLARIS11) {
-			gfx_v8_0_init_power_gating(adev);
+		WREG32(mmRLC_JUMP_TABLE_RESTORE, adev->gfx.rlc.cp_table_gpu_addr >> 8);
+		gfx_v8_0_init_power_gating(adev);
+		WREG32(mmRLC_PG_ALWAYS_ON_CU_MASK, adev->gfx.cu_info.ao_cu_mask);
+		if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) {
+			cz_enable_sck_slow_down_on_power_up(adev, true);
+			cz_enable_sck_slow_down_on_power_down(adev, true);
+		} else {
+			cz_enable_sck_slow_down_on_power_up(adev, false);
+			cz_enable_sck_slow_down_on_power_down(adev, false);
 		}
+		if (adev->pg_flags & AMD_PG_SUPPORT_CP)
+			cz_enable_cp_power_gating(adev, true);
+		else
+			cz_enable_cp_power_gating(adev, false);
+	} else if (adev->asic_type == CHIP_POLARIS11) {
+		gfx_v8_0_init_csb(adev);
+		gfx_v8_0_init_save_restore_list(adev);
+		gfx_v8_0_enable_save_restore_machine(adev);
+		gfx_v8_0_init_power_gating(adev);
 	}
+
 }
 
 static void gfx_v8_0_rlc_stop(struct amdgpu_device *adev)
@@ -5339,14 +5336,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 	bool enable = (state == AMD_PG_STATE_GATE) ? true : false;
 
-	if (!(adev->pg_flags & AMD_PG_SUPPORT_GFX_PG))
-		return 0;
-
 	switch (adev->asic_type) {
 	case CHIP_CARRIZO:
 	case CHIP_STONEY:
-		if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)
-			cz_update_gfx_cg_power_gating(adev, enable);
+
+		cz_update_gfx_cg_power_gating(adev, enable);
 
 		if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable)
 			gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true);
@@ -5791,25 +5785,49 @@ static int gfx_v8_0_update_gfx_clock_gating(struct amdgpu_device *adev,
 static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev,
 					  enum amd_clockgating_state state)
 {
-	uint32_t msg_id, pp_state;
+	uint32_t msg_id, pp_state = 0;
+	uint32_t pp_support_state = 0;
 	void *pp_handle = adev->powerplay.pp_handle;
 
-	if (state == AMD_CG_STATE_UNGATE)
-		pp_state = 0;
-	else
-		pp_state = PP_STATE_CG | PP_STATE_LS;
+	if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) {
+			pp_support_state = PP_STATE_SUPPORT_LS;
+			pp_state = PP_STATE_LS;
+		}
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG) {
+			pp_support_state |= PP_STATE_SUPPORT_CG;
+			pp_state |= PP_STATE_CG;
+		}
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+				PP_BLOCK_GFX_CG,
+				pp_support_state,
+				pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
 
-	msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
-			PP_BLOCK_GFX_CG,
-			PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-			pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+	if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGLS) {
+			pp_support_state = PP_STATE_SUPPORT_LS;
+			pp_state = PP_STATE_LS;
+		}
 
-	msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
-			PP_BLOCK_GFX_MG,
-			PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-			pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG) {
+			pp_support_state |= PP_STATE_SUPPORT_CG;
+			pp_state |= PP_STATE_CG;
+		}
+
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+				PP_BLOCK_GFX_MG,
+				pp_support_state,
+				pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
 
 	return 0;
 }
@@ -5817,43 +5835,98 @@ static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev,
 static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev,
 					  enum amd_clockgating_state state)
 {
-	uint32_t msg_id, pp_state;
+
+	uint32_t msg_id, pp_state = 0;
+	uint32_t pp_support_state = 0;
 	void *pp_handle = adev->powerplay.pp_handle;
 
-	if (state == AMD_CG_STATE_UNGATE)
-		pp_state = 0;
-	else
-		pp_state = PP_STATE_CG | PP_STATE_LS;
+	if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) {
+			pp_support_state = PP_STATE_SUPPORT_LS;
+			pp_state = PP_STATE_LS;
+		}
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG) {
+			pp_support_state |= PP_STATE_SUPPORT_CG;
+			pp_state |= PP_STATE_CG;
+		}
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+				PP_BLOCK_GFX_CG,
+				pp_support_state,
+				pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
 
-	msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
-			PP_BLOCK_GFX_CG,
-			PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-			pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+	if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGLS) {
+			pp_support_state = PP_STATE_SUPPORT_LS;
+			pp_state = PP_STATE_LS;
+		}
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGCG) {
+			pp_support_state |= PP_STATE_SUPPORT_CG;
+			pp_state |= PP_STATE_CG;
+		}
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+				PP_BLOCK_GFX_3D,
+				pp_support_state,
+				pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
 
-	msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
-			PP_BLOCK_GFX_3D,
-			PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-			pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+	if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGLS) {
+			pp_support_state = PP_STATE_SUPPORT_LS;
+			pp_state = PP_STATE_LS;
+		}
 
-	msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
-			PP_BLOCK_GFX_MG,
-			PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-			pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG) {
+			pp_support_state |= PP_STATE_SUPPORT_CG;
+			pp_state |= PP_STATE_CG;
+		}
 
-	msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
-			PP_BLOCK_GFX_RLC,
-			PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-			pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+				PP_BLOCK_GFX_MG,
+				pp_support_state,
+				pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
+
+	if (adev->cg_flags & AMD_CG_SUPPORT_GFX_RLC_LS) {
+		pp_support_state = PP_STATE_SUPPORT_LS;
 
-	msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		else
+			pp_state = PP_STATE_LS;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+				PP_BLOCK_GFX_RLC,
+				pp_support_state,
+				pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
+
+	if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CP_LS) {
+		pp_support_state = PP_STATE_SUPPORT_LS;
+
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		else
+			pp_state = PP_STATE_LS;
+		msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
 			PP_BLOCK_GFX_CP,
-			PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+			pp_support_state,
 			pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 3ed8ad8725b9cf09c965876a482b0699e5704058..c46b0159007d976406d64557316f45e045d82191 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -43,13 +43,14 @@
 
 static const u32 tahiti_golden_registers[] =
 {
+	0x17bc, 0x00000030, 0x00000011,
 	0x2684, 0x00010000, 0x00018208,
 	0x260c, 0xffffffff, 0x00000000,
 	0x260d, 0xf00fffff, 0x00000400,
 	0x260e, 0x0002021c, 0x00020200,
 	0x031e, 0x00000080, 0x00000000,
-	0x340c, 0x000300c0, 0x00800040,
-	0x360c, 0x000300c0, 0x00800040,
+	0x340c, 0x000000c0, 0x00800040,
+	0x360c, 0x000000c0, 0x00800040,
 	0x16ec, 0x000000f0, 0x00000070,
 	0x16f0, 0x00200000, 0x50100000,
 	0x1c0c, 0x31000311, 0x00000011,
@@ -60,7 +61,7 @@ static const u32 tahiti_golden_registers[] =
 	0x22c4, 0x0000ff0f, 0x00000000,
 	0xa293, 0x07ffffff, 0x4e000000,
 	0xa0d4, 0x3f3f3fff, 0x2a00126a,
-	0x000c, 0x000000ff, 0x0040,
+	0x000c, 0xffffffff, 0x0040,
 	0x000d, 0x00000040, 0x00004040,
 	0x2440, 0x07ffffff, 0x03000000,
 	0x23a2, 0x01ff1f3f, 0x00000000,
@@ -73,7 +74,11 @@ static const u32 tahiti_golden_registers[] =
 	0x2234, 0xffffffff, 0x000fff40,
 	0x2235, 0x0000001f, 0x00000010,
 	0x0504, 0x20000000, 0x20fffed8,
-	0x0570, 0x000c0fc0, 0x000c0400
+	0x0570, 0x000c0fc0, 0x000c0400,
+	0x052c, 0x0fffffff, 0xffffffff,
+	0x052d, 0x0fffffff, 0x0fffffff,
+	0x052e, 0x0fffffff, 0x0fffffff,
+	0x052f, 0x0fffffff, 0x0fffffff
 };
 
 static const u32 tahiti_golden_registers2[] =
@@ -83,16 +88,18 @@ static const u32 tahiti_golden_registers2[] =
 
 static const u32 tahiti_golden_rlc_registers[] =
 {
+	0x263e, 0xffffffff, 0x12011003,
 	0x3109, 0xffffffff, 0x00601005,
 	0x311f, 0xffffffff, 0x10104040,
 	0x3122, 0xffffffff, 0x0100000a,
 	0x30c5, 0xffffffff, 0x00000800,
 	0x30c3, 0xffffffff, 0x800000f4,
-	0x3d2a, 0xffffffff, 0x00000000
+	0x3d2a, 0x00000008, 0x00000000
 };
 
 static const u32 pitcairn_golden_registers[] =
 {
+	0x17bc, 0x00000030, 0x00000011,
 	0x2684, 0x00010000, 0x00018208,
 	0x260c, 0xffffffff, 0x00000000,
 	0x260d, 0xf00fffff, 0x00000400,
@@ -110,7 +117,7 @@ static const u32 pitcairn_golden_registers[] =
 	0x22c4, 0x0000ff0f, 0x00000000,
 	0xa293, 0x07ffffff, 0x4e000000,
 	0xa0d4, 0x3f3f3fff, 0x2a00126a,
-	0x000c, 0x000000ff, 0x0040,
+	0x000c, 0xffffffff, 0x0040,
 	0x000d, 0x00000040, 0x00004040,
 	0x2440, 0x07ffffff, 0x03000000,
 	0x2418, 0x0000007f, 0x00000020,
@@ -119,11 +126,16 @@ static const u32 pitcairn_golden_registers[] =
 	0x2b04, 0xffffffff, 0x00000000,
 	0x2b03, 0xffffffff, 0x32761054,
 	0x2235, 0x0000001f, 0x00000010,
-	0x0570, 0x000c0fc0, 0x000c0400
+	0x0570, 0x000c0fc0, 0x000c0400,
+	0x052c, 0x0fffffff, 0xffffffff,
+	0x052d, 0x0fffffff, 0x0fffffff,
+	0x052e, 0x0fffffff, 0x0fffffff,
+	0x052f, 0x0fffffff, 0x0fffffff
 };
 
 static const u32 pitcairn_golden_rlc_registers[] =
 {
+	0x263e, 0xffffffff, 0x12011003,
 	0x3109, 0xffffffff, 0x00601004,
 	0x311f, 0xffffffff, 0x10102020,
 	0x3122, 0xffffffff, 0x01000020,
@@ -133,133 +145,134 @@ static const u32 pitcairn_golden_rlc_registers[] =
 
 static const u32 verde_pg_init[] =
 {
-	0xd4f, 0xffffffff, 0x40000,
-	0xd4e, 0xffffffff, 0x200010ff,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x7007,
-	0xd4e, 0xffffffff, 0x300010ff,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x400000,
-	0xd4e, 0xffffffff, 0x100010ff,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x120200,
-	0xd4e, 0xffffffff, 0x500010ff,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x1e1e16,
-	0xd4e, 0xffffffff, 0x600010ff,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x171f1e,
-	0xd4e, 0xffffffff, 0x700010ff,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4f, 0xffffffff, 0x0,
-	0xd4e, 0xffffffff, 0x9ff,
-	0xd40, 0xffffffff, 0x0,
-	0xd41, 0xffffffff, 0x10000800,
-	0xd41, 0xffffffff, 0xf,
-	0xd41, 0xffffffff, 0xf,
-	0xd40, 0xffffffff, 0x4,
-	0xd41, 0xffffffff, 0x1000051e,
-	0xd41, 0xffffffff, 0xffff,
-	0xd41, 0xffffffff, 0xffff,
-	0xd40, 0xffffffff, 0x8,
-	0xd41, 0xffffffff, 0x80500,
-	0xd40, 0xffffffff, 0x12,
-	0xd41, 0xffffffff, 0x9050c,
-	0xd40, 0xffffffff, 0x1d,
-	0xd41, 0xffffffff, 0xb052c,
-	0xd40, 0xffffffff, 0x2a,
-	0xd41, 0xffffffff, 0x1053e,
-	0xd40, 0xffffffff, 0x2d,
-	0xd41, 0xffffffff, 0x10546,
-	0xd40, 0xffffffff, 0x30,
-	0xd41, 0xffffffff, 0xa054e,
-	0xd40, 0xffffffff, 0x3c,
-	0xd41, 0xffffffff, 0x1055f,
-	0xd40, 0xffffffff, 0x3f,
-	0xd41, 0xffffffff, 0x10567,
-	0xd40, 0xffffffff, 0x42,
-	0xd41, 0xffffffff, 0x1056f,
-	0xd40, 0xffffffff, 0x45,
-	0xd41, 0xffffffff, 0x10572,
-	0xd40, 0xffffffff, 0x48,
-	0xd41, 0xffffffff, 0x20575,
-	0xd40, 0xffffffff, 0x4c,
-	0xd41, 0xffffffff, 0x190801,
-	0xd40, 0xffffffff, 0x67,
-	0xd41, 0xffffffff, 0x1082a,
-	0xd40, 0xffffffff, 0x6a,
-	0xd41, 0xffffffff, 0x1b082d,
-	0xd40, 0xffffffff, 0x87,
-	0xd41, 0xffffffff, 0x310851,
-	0xd40, 0xffffffff, 0xba,
-	0xd41, 0xffffffff, 0x891,
-	0xd40, 0xffffffff, 0xbc,
-	0xd41, 0xffffffff, 0x893,
-	0xd40, 0xffffffff, 0xbe,
-	0xd41, 0xffffffff, 0x20895,
-	0xd40, 0xffffffff, 0xc2,
-	0xd41, 0xffffffff, 0x20899,
-	0xd40, 0xffffffff, 0xc6,
-	0xd41, 0xffffffff, 0x2089d,
-	0xd40, 0xffffffff, 0xca,
-	0xd41, 0xffffffff, 0x8a1,
-	0xd40, 0xffffffff, 0xcc,
-	0xd41, 0xffffffff, 0x8a3,
-	0xd40, 0xffffffff, 0xce,
-	0xd41, 0xffffffff, 0x308a5,
-	0xd40, 0xffffffff, 0xd3,
-	0xd41, 0xffffffff, 0x6d08cd,
-	0xd40, 0xffffffff, 0x142,
-	0xd41, 0xffffffff, 0x2000095a,
-	0xd41, 0xffffffff, 0x1,
-	0xd40, 0xffffffff, 0x144,
-	0xd41, 0xffffffff, 0x301f095b,
-	0xd40, 0xffffffff, 0x165,
-	0xd41, 0xffffffff, 0xc094d,
-	0xd40, 0xffffffff, 0x173,
-	0xd41, 0xffffffff, 0xf096d,
-	0xd40, 0xffffffff, 0x184,
-	0xd41, 0xffffffff, 0x15097f,
-	0xd40, 0xffffffff, 0x19b,
-	0xd41, 0xffffffff, 0xc0998,
-	0xd40, 0xffffffff, 0x1a9,
-	0xd41, 0xffffffff, 0x409a7,
-	0xd40, 0xffffffff, 0x1af,
-	0xd41, 0xffffffff, 0xcdc,
-	0xd40, 0xffffffff, 0x1b1,
-	0xd41, 0xffffffff, 0x800,
-	0xd42, 0xffffffff, 0x6c9b2000,
-	0xd44, 0xfc00, 0x2000,
-	0xd51, 0xffffffff, 0xfc0,
-	0xa35, 0x00000100, 0x100
+	0x0d4f, 0xffffffff, 0x40000,
+	0x0d4e, 0xffffffff, 0x200010ff,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x7007,
+	0x0d4e, 0xffffffff, 0x300010ff,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x400000,
+	0x0d4e, 0xffffffff, 0x100010ff,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x120200,
+	0x0d4e, 0xffffffff, 0x500010ff,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x1e1e16,
+	0x0d4e, 0xffffffff, 0x600010ff,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x171f1e,
+	0x0d4e, 0xffffffff, 0x700010ff,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4f, 0xffffffff, 0x0,
+	0x0d4e, 0xffffffff, 0x9ff,
+	0x0d40, 0xffffffff, 0x0,
+	0x0d41, 0xffffffff, 0x10000800,
+	0x0d41, 0xffffffff, 0xf,
+	0x0d41, 0xffffffff, 0xf,
+	0x0d40, 0xffffffff, 0x4,
+	0x0d41, 0xffffffff, 0x1000051e,
+	0x0d41, 0xffffffff, 0xffff,
+	0x0d41, 0xffffffff, 0xffff,
+	0x0d40, 0xffffffff, 0x8,
+	0x0d41, 0xffffffff, 0x80500,
+	0x0d40, 0xffffffff, 0x12,
+	0x0d41, 0xffffffff, 0x9050c,
+	0x0d40, 0xffffffff, 0x1d,
+	0x0d41, 0xffffffff, 0xb052c,
+	0x0d40, 0xffffffff, 0x2a,
+	0x0d41, 0xffffffff, 0x1053e,
+	0x0d40, 0xffffffff, 0x2d,
+	0x0d41, 0xffffffff, 0x10546,
+	0x0d40, 0xffffffff, 0x30,
+	0x0d41, 0xffffffff, 0xa054e,
+	0x0d40, 0xffffffff, 0x3c,
+	0x0d41, 0xffffffff, 0x1055f,
+	0x0d40, 0xffffffff, 0x3f,
+	0x0d41, 0xffffffff, 0x10567,
+	0x0d40, 0xffffffff, 0x42,
+	0x0d41, 0xffffffff, 0x1056f,
+	0x0d40, 0xffffffff, 0x45,
+	0x0d41, 0xffffffff, 0x10572,
+	0x0d40, 0xffffffff, 0x48,
+	0x0d41, 0xffffffff, 0x20575,
+	0x0d40, 0xffffffff, 0x4c,
+	0x0d41, 0xffffffff, 0x190801,
+	0x0d40, 0xffffffff, 0x67,
+	0x0d41, 0xffffffff, 0x1082a,
+	0x0d40, 0xffffffff, 0x6a,
+	0x0d41, 0xffffffff, 0x1b082d,
+	0x0d40, 0xffffffff, 0x87,
+	0x0d41, 0xffffffff, 0x310851,
+	0x0d40, 0xffffffff, 0xba,
+	0x0d41, 0xffffffff, 0x891,
+	0x0d40, 0xffffffff, 0xbc,
+	0x0d41, 0xffffffff, 0x893,
+	0x0d40, 0xffffffff, 0xbe,
+	0x0d41, 0xffffffff, 0x20895,
+	0x0d40, 0xffffffff, 0xc2,
+	0x0d41, 0xffffffff, 0x20899,
+	0x0d40, 0xffffffff, 0xc6,
+	0x0d41, 0xffffffff, 0x2089d,
+	0x0d40, 0xffffffff, 0xca,
+	0x0d41, 0xffffffff, 0x8a1,
+	0x0d40, 0xffffffff, 0xcc,
+	0x0d41, 0xffffffff, 0x8a3,
+	0x0d40, 0xffffffff, 0xce,
+	0x0d41, 0xffffffff, 0x308a5,
+	0x0d40, 0xffffffff, 0xd3,
+	0x0d41, 0xffffffff, 0x6d08cd,
+	0x0d40, 0xffffffff, 0x142,
+	0x0d41, 0xffffffff, 0x2000095a,
+	0x0d41, 0xffffffff, 0x1,
+	0x0d40, 0xffffffff, 0x144,
+	0x0d41, 0xffffffff, 0x301f095b,
+	0x0d40, 0xffffffff, 0x165,
+	0x0d41, 0xffffffff, 0xc094d,
+	0x0d40, 0xffffffff, 0x173,
+	0x0d41, 0xffffffff, 0xf096d,
+	0x0d40, 0xffffffff, 0x184,
+	0x0d41, 0xffffffff, 0x15097f,
+	0x0d40, 0xffffffff, 0x19b,
+	0x0d41, 0xffffffff, 0xc0998,
+	0x0d40, 0xffffffff, 0x1a9,
+	0x0d41, 0xffffffff, 0x409a7,
+	0x0d40, 0xffffffff, 0x1af,
+	0x0d41, 0xffffffff, 0xcdc,
+	0x0d40, 0xffffffff, 0x1b1,
+	0x0d41, 0xffffffff, 0x800,
+	0x0d42, 0xffffffff, 0x6c9b2000,
+	0x0d44, 0xfc00, 0x2000,
+	0x0d51, 0xffffffff, 0xfc0,
+	0x0a35, 0x00000100, 0x100
 };
 
 static const u32 verde_golden_rlc_registers[] =
 {
+	0x263e, 0xffffffff, 0x02010002,
 	0x3109, 0xffffffff, 0x033f1005,
 	0x311f, 0xffffffff, 0x10808020,
 	0x3122, 0xffffffff, 0x00800008,
@@ -269,65 +282,45 @@ static const u32 verde_golden_rlc_registers[] =
 
 static const u32 verde_golden_registers[] =
 {
+	0x17bc, 0x00000030, 0x00000011,
 	0x2684, 0x00010000, 0x00018208,
 	0x260c, 0xffffffff, 0x00000000,
 	0x260d, 0xf00fffff, 0x00000400,
 	0x260e, 0x0002021c, 0x00020200,
 	0x031e, 0x00000080, 0x00000000,
 	0x340c, 0x000300c0, 0x00800040,
-	0x340c, 0x000300c0, 0x00800040,
-	0x360c, 0x000300c0, 0x00800040,
 	0x360c, 0x000300c0, 0x00800040,
 	0x16ec, 0x000000f0, 0x00000070,
 	0x16f0, 0x00200000, 0x50100000,
-
 	0x1c0c, 0x31000311, 0x00000011,
 	0x0ab9, 0x00073ffe, 0x000022a2,
-	0x0ab9, 0x00073ffe, 0x000022a2,
-	0x0ab9, 0x00073ffe, 0x000022a2,
-	0x0903, 0x000007ff, 0x00000000,
-	0x0903, 0x000007ff, 0x00000000,
 	0x0903, 0x000007ff, 0x00000000,
 	0x2285, 0xf000001f, 0x00000007,
-	0x2285, 0xf000001f, 0x00000007,
-	0x2285, 0xf000001f, 0x00000007,
-	0x2285, 0xffffffff, 0x00ffffff,
+	0x22c9, 0xffffffff, 0x00ffffff,
 	0x22c4, 0x0000ff0f, 0x00000000,
-
 	0xa293, 0x07ffffff, 0x4e000000,
 	0xa0d4, 0x3f3f3fff, 0x0000124a,
-	0xa0d4, 0x3f3f3fff, 0x0000124a,
-	0xa0d4, 0x3f3f3fff, 0x0000124a,
-	0x000c, 0x000000ff, 0x0040,
+	0x000c, 0xffffffff, 0x0040,
 	0x000d, 0x00000040, 0x00004040,
 	0x2440, 0x07ffffff, 0x03000000,
-	0x2440, 0x07ffffff, 0x03000000,
-	0x23a2, 0x01ff1f3f, 0x00000000,
-	0x23a3, 0x01ff1f3f, 0x00000000,
 	0x23a2, 0x01ff1f3f, 0x00000000,
-	0x23a1, 0x01ff1f3f, 0x00000000,
-	0x23a1, 0x01ff1f3f, 0x00000000,
-
 	0x23a1, 0x01ff1f3f, 0x00000000,
 	0x2418, 0x0000007f, 0x00000020,
 	0x2542, 0x00010000, 0x00010000,
-	0x2b01, 0x000003ff, 0x00000003,
-	0x2b05, 0x000003ff, 0x00000003,
 	0x2b05, 0x000003ff, 0x00000003,
 	0x2b04, 0xffffffff, 0x00000000,
-	0x2b04, 0xffffffff, 0x00000000,
-	0x2b04, 0xffffffff, 0x00000000,
-	0x2b03, 0xffffffff, 0x00001032,
-	0x2b03, 0xffffffff, 0x00001032,
 	0x2b03, 0xffffffff, 0x00001032,
 	0x2235, 0x0000001f, 0x00000010,
-	0x2235, 0x0000001f, 0x00000010,
-	0x2235, 0x0000001f, 0x00000010,
-	0x0570, 0x000c0fc0, 0x000c0400
+	0x0570, 0x000c0fc0, 0x000c0400,
+	0x052c, 0x0fffffff, 0xffffffff,
+	0x052d, 0x0fffffff, 0x0fffffff,
+	0x052e, 0x0fffffff, 0x0fffffff,
+	0x052f, 0x0fffffff, 0x0fffffff
 };
 
 static const u32 oland_golden_registers[] =
 {
+	0x17bc, 0x00000030, 0x00000011,
 	0x2684, 0x00010000, 0x00018208,
 	0x260c, 0xffffffff, 0x00000000,
 	0x260d, 0xf00fffff, 0x00000400,
@@ -336,7 +329,7 @@ static const u32 oland_golden_registers[] =
 	0x340c, 0x000300c0, 0x00800040,
 	0x360c, 0x000300c0, 0x00800040,
 	0x16ec, 0x000000f0, 0x00000070,
-	0x16f9, 0x00200000, 0x50100000,
+	0x16f0, 0x00200000, 0x50100000,
 	0x1c0c, 0x31000311, 0x00000011,
 	0x0ab9, 0x00073ffe, 0x000022a2,
 	0x0903, 0x000007ff, 0x00000000,
@@ -345,7 +338,7 @@ static const u32 oland_golden_registers[] =
 	0x22c4, 0x0000ff0f, 0x00000000,
 	0xa293, 0x07ffffff, 0x4e000000,
 	0xa0d4, 0x3f3f3fff, 0x00000082,
-	0x000c, 0x000000ff, 0x0040,
+	0x000c, 0xffffffff, 0x0040,
 	0x000d, 0x00000040, 0x00004040,
 	0x2440, 0x07ffffff, 0x03000000,
 	0x2418, 0x0000007f, 0x00000020,
@@ -354,11 +347,16 @@ static const u32 oland_golden_registers[] =
 	0x2b04, 0xffffffff, 0x00000000,
 	0x2b03, 0xffffffff, 0x00003210,
 	0x2235, 0x0000001f, 0x00000010,
-	0x0570, 0x000c0fc0, 0x000c0400
+	0x0570, 0x000c0fc0, 0x000c0400,
+	0x052c, 0x0fffffff, 0xffffffff,
+	0x052d, 0x0fffffff, 0x0fffffff,
+	0x052e, 0x0fffffff, 0x0fffffff,
+	0x052f, 0x0fffffff, 0x0fffffff
 };
 
 static const u32 oland_golden_rlc_registers[] =
 {
+	0x263e, 0xffffffff, 0x02010002,
 	0x3109, 0xffffffff, 0x00601005,
 	0x311f, 0xffffffff, 0x10104040,
 	0x3122, 0xffffffff, 0x0100000a,
@@ -368,22 +366,27 @@ static const u32 oland_golden_rlc_registers[] =
 
 static const u32 hainan_golden_registers[] =
 {
+	0x17bc, 0x00000030, 0x00000011,
 	0x2684, 0x00010000, 0x00018208,
 	0x260c, 0xffffffff, 0x00000000,
 	0x260d, 0xf00fffff, 0x00000400,
 	0x260e, 0x0002021c, 0x00020200,
-	0x4595, 0xff000fff, 0x00000100,
+	0x031e, 0x00000080, 0x00000000,
+	0x3430, 0xff000fff, 0x00000100,
 	0x340c, 0x000300c0, 0x00800040,
 	0x3630, 0xff000fff, 0x00000100,
 	0x360c, 0x000300c0, 0x00800040,
+	0x16ec, 0x000000f0, 0x00000070,
+	0x16f0, 0x00200000, 0x50100000,
+	0x1c0c, 0x31000311, 0x00000011,
 	0x0ab9, 0x00073ffe, 0x000022a2,
 	0x0903, 0x000007ff, 0x00000000,
 	0x2285, 0xf000001f, 0x00000007,
 	0x22c9, 0xffffffff, 0x00ffffff,
 	0x22c4, 0x0000ff0f, 0x00000000,
-	0xa393, 0x07ffffff, 0x4e000000,
+	0xa293, 0x07ffffff, 0x4e000000,
 	0xa0d4, 0x3f3f3fff, 0x00000000,
-	0x000c, 0x000000ff, 0x0040,
+	0x000c, 0xffffffff, 0x0040,
 	0x000d, 0x00000040, 0x00004040,
 	0x2440, 0x03e00000, 0x03600000,
 	0x2418, 0x0000007f, 0x00000020,
@@ -392,12 +395,16 @@ static const u32 hainan_golden_registers[] =
 	0x2b04, 0xffffffff, 0x00000000,
 	0x2b03, 0xffffffff, 0x00003210,
 	0x2235, 0x0000001f, 0x00000010,
-	0x0570, 0x000c0fc0, 0x000c0400
+	0x0570, 0x000c0fc0, 0x000c0400,
+	0x052c, 0x0fffffff, 0xffffffff,
+	0x052d, 0x0fffffff, 0x0fffffff,
+	0x052e, 0x0fffffff, 0x0fffffff,
+	0x052f, 0x0fffffff, 0x0fffffff
 };
 
 static const u32 hainan_golden_registers2[] =
 {
-	0x263e, 0xffffffff, 0x02010001
+	0x263e, 0xffffffff, 0x2011003
 };
 
 static const u32 tahiti_mgcg_cgcg_init[] =
@@ -513,18 +520,18 @@ static const u32 tahiti_mgcg_cgcg_init[] =
 	0x21c2, 0xffffffff, 0x00900100,
 	0x311e, 0xffffffff, 0x00000080,
 	0x3101, 0xffffffff, 0x0020003f,
-	0xc, 0xffffffff, 0x0000001c,
-	0xd, 0x000f0000, 0x000f0000,
-	0x583, 0xffffffff, 0x00000100,
-	0x409, 0xffffffff, 0x00000100,
-	0x40b, 0x00000101, 0x00000000,
-	0x82a, 0xffffffff, 0x00000104,
-	0x993, 0x000c0000, 0x000c0000,
-	0x992, 0x000c0000, 0x000c0000,
+	0x000c, 0xffffffff, 0x0000001c,
+	0x000d, 0x000f0000, 0x000f0000,
+	0x0583, 0xffffffff, 0x00000100,
+	0x0409, 0xffffffff, 0x00000100,
+	0x040b, 0x00000101, 0x00000000,
+	0x082a, 0xffffffff, 0x00000104,
+	0x0993, 0x000c0000, 0x000c0000,
+	0x0992, 0x000c0000, 0x000c0000,
 	0x1579, 0xff000fff, 0x00000100,
 	0x157a, 0x00000001, 0x00000001,
-	0xbd4, 0x00000001, 0x00000001,
-	0xc33, 0xc0000fff, 0x00000104,
+	0x0bd4, 0x00000001, 0x00000001,
+	0x0c33, 0xc0000fff, 0x00000104,
 	0x3079, 0x00000001, 0x00000001,
 	0x3430, 0xfffffff0, 0x00000100,
 	0x3630, 0xfffffff0, 0x00000100
@@ -612,16 +619,16 @@ static const u32 pitcairn_mgcg_cgcg_init[] =
 	0x21c2, 0xffffffff, 0x00900100,
 	0x311e, 0xffffffff, 0x00000080,
 	0x3101, 0xffffffff, 0x0020003f,
-	0xc, 0xffffffff, 0x0000001c,
-	0xd, 0x000f0000, 0x000f0000,
-	0x583, 0xffffffff, 0x00000100,
-	0x409, 0xffffffff, 0x00000100,
-	0x40b, 0x00000101, 0x00000000,
-	0x82a, 0xffffffff, 0x00000104,
+	0x000c, 0xffffffff, 0x0000001c,
+	0x000d, 0x000f0000, 0x000f0000,
+	0x0583, 0xffffffff, 0x00000100,
+	0x0409, 0xffffffff, 0x00000100,
+	0x040b, 0x00000101, 0x00000000,
+	0x082a, 0xffffffff, 0x00000104,
 	0x1579, 0xff000fff, 0x00000100,
 	0x157a, 0x00000001, 0x00000001,
-	0xbd4, 0x00000001, 0x00000001,
-	0xc33, 0xc0000fff, 0x00000104,
+	0x0bd4, 0x00000001, 0x00000001,
+	0x0c33, 0xc0000fff, 0x00000104,
 	0x3079, 0x00000001, 0x00000001,
 	0x3430, 0xfffffff0, 0x00000100,
 	0x3630, 0xfffffff0, 0x00000100
@@ -709,18 +716,18 @@ static const u32 verde_mgcg_cgcg_init[] =
 	0x21c2, 0xffffffff, 0x00900100,
 	0x311e, 0xffffffff, 0x00000080,
 	0x3101, 0xffffffff, 0x0020003f,
-	0xc, 0xffffffff, 0x0000001c,
-	0xd, 0x000f0000, 0x000f0000,
-	0x583, 0xffffffff, 0x00000100,
-	0x409, 0xffffffff, 0x00000100,
-	0x40b, 0x00000101, 0x00000000,
-	0x82a, 0xffffffff, 0x00000104,
-	0x993, 0x000c0000, 0x000c0000,
-	0x992, 0x000c0000, 0x000c0000,
+	0x000c, 0xffffffff, 0x0000001c,
+	0x000d, 0x000f0000, 0x000f0000,
+	0x0583, 0xffffffff, 0x00000100,
+	0x0409, 0xffffffff, 0x00000100,
+	0x040b, 0x00000101, 0x00000000,
+	0x082a, 0xffffffff, 0x00000104,
+	0x0993, 0x000c0000, 0x000c0000,
+	0x0992, 0x000c0000, 0x000c0000,
 	0x1579, 0xff000fff, 0x00000100,
 	0x157a, 0x00000001, 0x00000001,
-	0xbd4, 0x00000001, 0x00000001,
-	0xc33, 0xc0000fff, 0x00000104,
+	0x0bd4, 0x00000001, 0x00000001,
+	0x0c33, 0xc0000fff, 0x00000104,
 	0x3079, 0x00000001, 0x00000001,
 	0x3430, 0xfffffff0, 0x00000100,
 	0x3630, 0xfffffff0, 0x00000100
@@ -788,18 +795,18 @@ static const u32 oland_mgcg_cgcg_init[] =
 	0x21c2, 0xffffffff, 0x00900100,
 	0x311e, 0xffffffff, 0x00000080,
 	0x3101, 0xffffffff, 0x0020003f,
-	0xc, 0xffffffff, 0x0000001c,
-	0xd, 0x000f0000, 0x000f0000,
-	0x583, 0xffffffff, 0x00000100,
-	0x409, 0xffffffff, 0x00000100,
-	0x40b, 0x00000101, 0x00000000,
-	0x82a, 0xffffffff, 0x00000104,
-	0x993, 0x000c0000, 0x000c0000,
-	0x992, 0x000c0000, 0x000c0000,
+	0x000c, 0xffffffff, 0x0000001c,
+	0x000d, 0x000f0000, 0x000f0000,
+	0x0583, 0xffffffff, 0x00000100,
+	0x0409, 0xffffffff, 0x00000100,
+	0x040b, 0x00000101, 0x00000000,
+	0x082a, 0xffffffff, 0x00000104,
+	0x0993, 0x000c0000, 0x000c0000,
+	0x0992, 0x000c0000, 0x000c0000,
 	0x1579, 0xff000fff, 0x00000100,
 	0x157a, 0x00000001, 0x00000001,
-	0xbd4, 0x00000001, 0x00000001,
-	0xc33, 0xc0000fff, 0x00000104,
+	0x0bd4, 0x00000001, 0x00000001,
+	0x0c33, 0xc0000fff, 0x00000104,
 	0x3079, 0x00000001, 0x00000001,
 	0x3430, 0xfffffff0, 0x00000100,
 	0x3630, 0xfffffff0, 0x00000100
@@ -867,15 +874,15 @@ static const u32 hainan_mgcg_cgcg_init[] =
 	0x21c2, 0xffffffff, 0x00900100,
 	0x311e, 0xffffffff, 0x00000080,
 	0x3101, 0xffffffff, 0x0020003f,
-	0xc, 0xffffffff, 0x0000001c,
-	0xd, 0x000f0000, 0x000f0000,
-	0x583, 0xffffffff, 0x00000100,
-	0x409, 0xffffffff, 0x00000100,
-	0x82a, 0xffffffff, 0x00000104,
-	0x993, 0x000c0000, 0x000c0000,
-	0x992, 0x000c0000, 0x000c0000,
-	0xbd4, 0x00000001, 0x00000001,
-	0xc33, 0xc0000fff, 0x00000104,
+	0x000c, 0xffffffff, 0x0000001c,
+	0x000d, 0x000f0000, 0x000f0000,
+	0x0583, 0xffffffff, 0x00000100,
+	0x0409, 0xffffffff, 0x00000100,
+	0x082a, 0xffffffff, 0x00000104,
+	0x0993, 0x000c0000, 0x000c0000,
+	0x0992, 0x000c0000, 0x000c0000,
+	0x0bd4, 0x00000001, 0x00000001,
+	0x0c33, 0xc0000fff, 0x00000104,
 	0x3079, 0x00000001, 0x00000001,
 	0x3430, 0xfffffff0, 0x00000100,
 	0x3630, 0xfffffff0, 0x00000100
@@ -1179,6 +1186,8 @@ static int si_common_early_init(void *handle)
 			AMD_CG_SUPPORT_HDP_LS |
 			AMD_CG_SUPPORT_HDP_MGCG;
 			adev->pg_flags = 0;
+		adev->external_rev_id = (adev->rev_id == 0) ? 1 :
+					(adev->rev_id == 1) ? 5 : 6;
 		break;
 	case CHIP_PITCAIRN:
 		adev->cg_flags =
@@ -1198,6 +1207,7 @@ static int si_common_early_init(void *handle)
 			AMD_CG_SUPPORT_HDP_LS |
 			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags = 0;
+		adev->external_rev_id = adev->rev_id + 20;
 		break;
 
 	case CHIP_VERDE:
@@ -1219,7 +1229,7 @@ static int si_common_early_init(void *handle)
 			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags = 0;
 		//???
-		adev->external_rev_id = adev->rev_id + 0x14;
+		adev->external_rev_id = adev->rev_id + 40;
 		break;
 	case CHIP_OLAND:
 		adev->cg_flags =
@@ -1238,6 +1248,7 @@ static int si_common_early_init(void *handle)
 			AMD_CG_SUPPORT_HDP_LS |
 			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags = 0;
+		adev->external_rev_id = 60;
 		break;
 	case CHIP_HAINAN:
 		adev->cg_flags =
@@ -1255,6 +1266,7 @@ static int si_common_early_init(void *handle)
 			AMD_CG_SUPPORT_HDP_LS |
 			AMD_CG_SUPPORT_HDP_MGCG;
 		adev->pg_flags = 0;
+		adev->external_rev_id = 70;
 		break;
 
 	default:
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 9f771f4ffcb71bf1267ff3aae9c5853fb944e149..bf088d6d9bf1f96430d7afda1ec3fbeae6e82768 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -932,18 +932,64 @@ static int vi_common_early_init(void *handle)
 		adev->external_rev_id = adev->rev_id + 0x3c;
 		break;
 	case CHIP_TONGA:
-		adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG;
-		adev->pg_flags = AMD_PG_SUPPORT_UVD;
+		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
+			AMD_CG_SUPPORT_GFX_CGCG |
+			AMD_CG_SUPPORT_GFX_CGLS |
+			AMD_CG_SUPPORT_SDMA_MGCG |
+			AMD_CG_SUPPORT_SDMA_LS |
+			AMD_CG_SUPPORT_BIF_LS |
+			AMD_CG_SUPPORT_HDP_MGCG |
+			AMD_CG_SUPPORT_HDP_LS |
+			AMD_CG_SUPPORT_ROM_MGCG |
+			AMD_CG_SUPPORT_MC_MGCG |
+			AMD_CG_SUPPORT_MC_LS |
+			AMD_CG_SUPPORT_DRM_LS |
+			AMD_CG_SUPPORT_UVD_MGCG;
+		adev->pg_flags = 0;
 		adev->external_rev_id = adev->rev_id + 0x14;
 		break;
 	case CHIP_POLARIS11:
-		adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG |
+		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
+			AMD_CG_SUPPORT_GFX_RLC_LS |
+			AMD_CG_SUPPORT_GFX_CP_LS |
+			AMD_CG_SUPPORT_GFX_CGCG |
+			AMD_CG_SUPPORT_GFX_CGLS |
+			AMD_CG_SUPPORT_GFX_3D_CGCG |
+			AMD_CG_SUPPORT_GFX_3D_CGLS |
+			AMD_CG_SUPPORT_SDMA_MGCG |
+			AMD_CG_SUPPORT_SDMA_LS |
+			AMD_CG_SUPPORT_BIF_MGCG |
+			AMD_CG_SUPPORT_BIF_LS |
+			AMD_CG_SUPPORT_HDP_MGCG |
+			AMD_CG_SUPPORT_HDP_LS |
+			AMD_CG_SUPPORT_ROM_MGCG |
+			AMD_CG_SUPPORT_MC_MGCG |
+			AMD_CG_SUPPORT_MC_LS |
+			AMD_CG_SUPPORT_DRM_LS |
+			AMD_CG_SUPPORT_UVD_MGCG |
 			AMD_CG_SUPPORT_VCE_MGCG;
 		adev->pg_flags = 0;
 		adev->external_rev_id = adev->rev_id + 0x5A;
 		break;
 	case CHIP_POLARIS10:
-		adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG |
+		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
+			AMD_CG_SUPPORT_GFX_RLC_LS |
+			AMD_CG_SUPPORT_GFX_CP_LS |
+			AMD_CG_SUPPORT_GFX_CGCG |
+			AMD_CG_SUPPORT_GFX_CGLS |
+			AMD_CG_SUPPORT_GFX_3D_CGCG |
+			AMD_CG_SUPPORT_GFX_3D_CGLS |
+			AMD_CG_SUPPORT_SDMA_MGCG |
+			AMD_CG_SUPPORT_SDMA_LS |
+			AMD_CG_SUPPORT_BIF_MGCG |
+			AMD_CG_SUPPORT_BIF_LS |
+			AMD_CG_SUPPORT_HDP_MGCG |
+			AMD_CG_SUPPORT_HDP_LS |
+			AMD_CG_SUPPORT_ROM_MGCG |
+			AMD_CG_SUPPORT_MC_MGCG |
+			AMD_CG_SUPPORT_MC_LS |
+			AMD_CG_SUPPORT_DRM_LS |
+			AMD_CG_SUPPORT_UVD_MGCG |
 			AMD_CG_SUPPORT_VCE_MGCG;
 		adev->pg_flags = 0;
 		adev->external_rev_id = adev->rev_id + 0x50;
@@ -971,6 +1017,7 @@ static int vi_common_early_init(void *handle)
 			adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
 				AMD_PG_SUPPORT_GFX_SMG |
 				AMD_PG_SUPPORT_GFX_PIPELINE |
+				AMD_PG_SUPPORT_CP |
 				AMD_PG_SUPPORT_UVD |
 				AMD_PG_SUPPORT_VCE;
 		}
@@ -996,6 +1043,7 @@ static int vi_common_early_init(void *handle)
 		adev->pg_flags = AMD_PG_SUPPORT_GFX_PG |
 			AMD_PG_SUPPORT_GFX_SMG |
 			AMD_PG_SUPPORT_GFX_PIPELINE |
+			AMD_PG_SUPPORT_CP |
 			AMD_PG_SUPPORT_UVD |
 			AMD_PG_SUPPORT_VCE;
 		adev->external_rev_id = adev->rev_id + 0x61;
@@ -1155,57 +1203,118 @@ static void vi_update_rom_medium_grain_clock_gating(struct amdgpu_device *adev,
 static int vi_common_set_clockgating_state_by_smu(void *handle,
 					   enum amd_clockgating_state state)
 {
-	uint32_t msg_id, pp_state;
+	uint32_t msg_id, pp_state = 0;
+	uint32_t pp_support_state = 0;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 	void *pp_handle = adev->powerplay.pp_handle;
 
-	if (state == AMD_CG_STATE_UNGATE)
-		pp_state = 0;
-	else
-		pp_state = PP_STATE_CG | PP_STATE_LS;
-
-	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
-		       PP_BLOCK_SYS_MC,
-		       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-		       pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
-
-	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
-		       PP_BLOCK_SYS_SDMA,
-		       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-		       pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
-
-	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
-		       PP_BLOCK_SYS_HDP,
-		       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
-		       pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
-
-	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
-		       PP_BLOCK_SYS_BIF,
-		       PP_STATE_SUPPORT_LS,
-		       pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
-
-	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
-		       PP_BLOCK_SYS_BIF,
-		       PP_STATE_SUPPORT_CG,
-		       pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
-
-	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
-		       PP_BLOCK_SYS_DRM,
-		       PP_STATE_SUPPORT_LS,
-		       pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
-
-	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
-		       PP_BLOCK_SYS_ROM,
-		       PP_STATE_SUPPORT_CG,
-		       pp_state);
-	amd_set_clockgating_by_smu(pp_handle, msg_id);
+	if (adev->cg_flags & (AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_MC_MGCG)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_MC_LS) {
+			pp_support_state = AMD_CG_SUPPORT_MC_LS;
+			pp_state = PP_STATE_LS;
+		}
+		if (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG) {
+			pp_support_state |= AMD_CG_SUPPORT_MC_MGCG;
+			pp_state |= PP_STATE_CG;
+		}
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+			       PP_BLOCK_SYS_MC,
+			       pp_support_state,
+			       pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
+
+	if (adev->cg_flags & (AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_SDMA_MGCG)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_SDMA_LS) {
+			pp_support_state = AMD_CG_SUPPORT_SDMA_LS;
+			pp_state = PP_STATE_LS;
+		}
+		if (adev->cg_flags & AMD_CG_SUPPORT_SDMA_MGCG) {
+			pp_support_state |= AMD_CG_SUPPORT_SDMA_MGCG;
+			pp_state |= PP_STATE_CG;
+		}
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+			       PP_BLOCK_SYS_SDMA,
+			       pp_support_state,
+			       pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
+
+	if (adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_HDP_MGCG)) {
+		if (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS) {
+			pp_support_state = AMD_CG_SUPPORT_HDP_LS;
+			pp_state = PP_STATE_LS;
+		}
+		if (adev->cg_flags & AMD_CG_SUPPORT_HDP_MGCG) {
+			pp_support_state |= AMD_CG_SUPPORT_HDP_MGCG;
+			pp_state |= PP_STATE_CG;
+		}
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+			       PP_BLOCK_SYS_HDP,
+			       pp_support_state,
+			       pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
 
+
+	if (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS) {
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		else
+			pp_state = PP_STATE_LS;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+			       PP_BLOCK_SYS_BIF,
+			       PP_STATE_SUPPORT_LS,
+			        pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
+	if (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG) {
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		else
+			pp_state = PP_STATE_CG;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+			       PP_BLOCK_SYS_BIF,
+			       PP_STATE_SUPPORT_CG,
+			       pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
+
+	if (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS) {
+
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		else
+			pp_state = PP_STATE_LS;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+			       PP_BLOCK_SYS_DRM,
+			       PP_STATE_SUPPORT_LS,
+			       pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
+
+	if (adev->cg_flags & AMD_CG_SUPPORT_ROM_MGCG) {
+
+		if (state == AMD_CG_STATE_UNGATE)
+			pp_state = 0;
+		else
+			pp_state = PP_STATE_CG;
+
+		msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+			       PP_BLOCK_SYS_ROM,
+			       PP_STATE_SUPPORT_CG,
+			       pp_state);
+		amd_set_clockgating_by_smu(pp_handle, msg_id);
+	}
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h
index d1986276dbbd71cc144a48ec52bb14b908095509..c02469ada9f131f417e2a4fdb1d0c6b1fac4eafa 100644
--- a/drivers/gpu/drm/amd/include/amd_shared.h
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
@@ -126,6 +126,10 @@ enum amd_vce_level {
 #define AMD_CG_SUPPORT_HDP_LS			(1 << 15)
 #define AMD_CG_SUPPORT_HDP_MGCG			(1 << 16)
 #define AMD_CG_SUPPORT_ROM_MGCG			(1 << 17)
+#define AMD_CG_SUPPORT_DRM_LS			(1 << 18)
+#define AMD_CG_SUPPORT_BIF_MGCG			(1 << 19)
+#define AMD_CG_SUPPORT_GFX_3D_CGCG		(1 << 20)
+#define AMD_CG_SUPPORT_GFX_3D_CGLS		(1 << 21)
 
 /* PG flags */
 #define AMD_PG_SUPPORT_GFX_PG			(1 << 0)
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 904beaa932d03f0b5ce7d89a13d16729582052e0..f75c6421db6239c9435ed39dc7d6244d13894920 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -223,7 +223,8 @@ static int ast_get_dram_info(struct drm_device *dev)
 	ast_write32(ast, 0x10000, 0xfc600309);
 
 	do {
-		;
+		if (pci_channel_offline(dev->pdev))
+			return -EIO;
 	} while (ast_read32(ast, 0x10000) != 0x01);
 	data = ast_read32(ast, 0x10004);
 
@@ -428,7 +429,9 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
 	ast_detect_chip(dev, &need_post);
 
 	if (ast->chip != AST1180) {
-		ast_get_dram_info(dev);
+		ret = ast_get_dram_info(dev);
+		if (ret)
+			goto out_free;
 		ast->vram_size = ast_get_vram_info(dev);
 		DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size);
 	}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 56002a52936dcfc4a7dd5539973ce316353d0b1c..243224aeabf82f111ab14c4d6995ce868c0d36c1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3509,6 +3509,8 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
 int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
+int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
+		      u32 reply_mask, u32 reply, int timeout_base_ms);
 
 /* intel_sideband.c */
 u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 412f3513f269b4a96217f814aa0d882a27a3e1e5..4a31b7a891ecaf3e2732c9f2d6ce62fa633419f6 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -174,21 +174,35 @@ static struct sg_table *
 i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 {
 	struct address_space *mapping = obj->base.filp->f_mapping;
-	char *vaddr = obj->phys_handle->vaddr;
+	drm_dma_handle_t *phys;
 	struct sg_table *st;
 	struct scatterlist *sg;
+	char *vaddr;
 	int i;
 
 	if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj)))
 		return ERR_PTR(-EINVAL);
 
+	/* Always aligning to the object size, allows a single allocation
+	 * to handle all possible callers, and given typical object sizes,
+	 * the alignment of the buddy allocation will naturally match.
+	 */
+	phys = drm_pci_alloc(obj->base.dev,
+			     obj->base.size,
+			     roundup_pow_of_two(obj->base.size));
+	if (!phys)
+		return ERR_PTR(-ENOMEM);
+
+	vaddr = phys->vaddr;
 	for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
 		struct page *page;
 		char *src;
 
 		page = shmem_read_mapping_page(mapping, i);
-		if (IS_ERR(page))
-			return ERR_CAST(page);
+		if (IS_ERR(page)) {
+			st = ERR_CAST(page);
+			goto err_phys;
+		}
 
 		src = kmap_atomic(page);
 		memcpy(vaddr, src, PAGE_SIZE);
@@ -202,21 +216,29 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 	i915_gem_chipset_flush(to_i915(obj->base.dev));
 
 	st = kmalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL)
-		return ERR_PTR(-ENOMEM);
+	if (!st) {
+		st = ERR_PTR(-ENOMEM);
+		goto err_phys;
+	}
 
 	if (sg_alloc_table(st, 1, GFP_KERNEL)) {
 		kfree(st);
-		return ERR_PTR(-ENOMEM);
+		st = ERR_PTR(-ENOMEM);
+		goto err_phys;
 	}
 
 	sg = st->sgl;
 	sg->offset = 0;
 	sg->length = obj->base.size;
 
-	sg_dma_address(sg) = obj->phys_handle->busaddr;
+	sg_dma_address(sg) = phys->busaddr;
 	sg_dma_len(sg) = obj->base.size;
 
+	obj->phys_handle = phys;
+	return st;
+
+err_phys:
+	drm_pci_free(obj->base.dev, phys);
 	return st;
 }
 
@@ -272,12 +294,13 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
 
 	sg_free_table(pages);
 	kfree(pages);
+
+	drm_pci_free(obj->base.dev, obj->phys_handle);
 }
 
 static void
 i915_gem_object_release_phys(struct drm_i915_gem_object *obj)
 {
-	drm_pci_free(obj->base.dev, obj->phys_handle);
 	i915_gem_object_unpin_pages(obj);
 }
 
@@ -538,15 +561,13 @@ int
 i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
 			    int align)
 {
-	drm_dma_handle_t *phys;
 	int ret;
 
-	if (obj->phys_handle) {
-		if ((unsigned long)obj->phys_handle->vaddr & (align -1))
-			return -EBUSY;
+	if (align > obj->base.size)
+		return -EINVAL;
 
+	if (obj->ops == &i915_gem_phys_ops)
 		return 0;
-	}
 
 	if (obj->mm.madv != I915_MADV_WILLNEED)
 		return -EFAULT;
@@ -562,12 +583,6 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
 	if (obj->mm.pages)
 		return -EBUSY;
 
-	/* create a new object */
-	phys = drm_pci_alloc(obj->base.dev, obj->base.size, align);
-	if (!phys)
-		return -ENOMEM;
-
-	obj->phys_handle = phys;
 	obj->ops = &i915_gem_phys_ops;
 
 	return i915_gem_object_pin_pages(obj);
@@ -2326,7 +2341,8 @@ static struct sg_table *
 i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
-	int page_count, i;
+	const unsigned long page_count = obj->base.size / PAGE_SIZE;
+	unsigned long i;
 	struct address_space *mapping;
 	struct sg_table *st;
 	struct scatterlist *sg;
@@ -2352,7 +2368,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	if (st == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	page_count = obj->base.size / PAGE_SIZE;
+rebuild_st:
 	if (sg_alloc_table(st, page_count, GFP_KERNEL)) {
 		kfree(st);
 		return ERR_PTR(-ENOMEM);
@@ -2411,8 +2427,25 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	i915_sg_trim(st);
 
 	ret = i915_gem_gtt_prepare_pages(obj, st);
-	if (ret)
-		goto err_pages;
+	if (ret) {
+		/* DMA remapping failed? One possible cause is that
+		 * it could not reserve enough large entries, asking
+		 * for PAGE_SIZE chunks instead may be helpful.
+		 */
+		if (max_segment > PAGE_SIZE) {
+			for_each_sgt_page(page, sgt_iter, st)
+				put_page(page);
+			sg_free_table(st);
+
+			max_segment = PAGE_SIZE;
+			goto rebuild_st;
+		} else {
+			dev_warn(&dev_priv->drm.pdev->dev,
+				 "Failed to DMA remap %lu pages\n",
+				 page_count);
+			goto err_pages;
+		}
+	}
 
 	if (i915_gem_object_needs_bit17_swizzle(obj))
 		i915_gem_object_do_bit_17_swizzle(obj, st);
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index ebaa941c83afd7843a56287f2b857d8f8fd3a9fa..abc78bbfc1dcd0fbc6373222c3801929d1dfd2d4 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -55,10 +55,9 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
 		return -ENODEV;
 
 	/* See the comment at the drm_mm_init() call for more about this check.
-	 * WaSkipStolenMemoryFirstPage:bdw,chv,kbl (incomplete)
+	 * WaSkipStolenMemoryFirstPage:bdw+ (incomplete)
 	 */
-	if (start < 4096 && (IS_GEN8(dev_priv) ||
-			     IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0)))
+	if (start < 4096 && INTEL_GEN(dev_priv) >= 8)
 		start = 4096;
 
 	mutex_lock(&dev_priv->mm.stolen_lock);
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 47590ab08d7ea65e7cc94594853117f78e04946b..3df8d3dd31cd0fdb8972b5f3d2ddb5aa1c61d556 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -460,7 +460,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
 
 static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
 static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
-static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
+static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO | S_IWUSR, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
 static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
 static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
 
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 8405b5a367d7164a15df16ea5c453b472e965916..7e3545f65257c415fa7fab7a65e27a6858e80a09 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -46,14 +46,20 @@ struct edp_power_seq {
 	u16 t11_t12;
 } __packed;
 
-/* MIPI Sequence Block definitions */
+/*
+ * MIPI Sequence Block definitions
+ *
+ * Note the VBT spec has AssertReset / DeassertReset swapped from their
+ * usual naming, we use the proper names here to avoid confusion when
+ * reading the code.
+ */
 enum mipi_seq {
 	MIPI_SEQ_END = 0,
-	MIPI_SEQ_ASSERT_RESET,
+	MIPI_SEQ_DEASSERT_RESET,	/* Spec says MipiAssertResetPin */
 	MIPI_SEQ_INIT_OTP,
 	MIPI_SEQ_DISPLAY_ON,
 	MIPI_SEQ_DISPLAY_OFF,
-	MIPI_SEQ_DEASSERT_RESET,
+	MIPI_SEQ_ASSERT_RESET,		/* Spec says MipiDeassertResetPin */
 	MIPI_SEQ_BACKLIGHT_ON,		/* sequence block v2+ */
 	MIPI_SEQ_BACKLIGHT_OFF,		/* sequence block v2+ */
 	MIPI_SEQ_TEAR_ON,		/* sequence block v2+ */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cf5cff7b03b8528ce10590a1dd973bbfa2b87776..6daad86137606d700b6101ee0ffde7a7ee35a1cd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6244,35 +6244,24 @@ skl_dpll0_disable(struct drm_i915_private *dev_priv)
 	dev_priv->cdclk_pll.vco = 0;
 }
 
-static bool skl_cdclk_pcu_ready(struct drm_i915_private *dev_priv)
-{
-	int ret;
-	u32 val;
-
-	/* inform PCU we want to change CDCLK */
-	val = SKL_CDCLK_PREPARE_FOR_CHANGE;
-	mutex_lock(&dev_priv->rps.hw_lock);
-	ret = sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &val);
-	mutex_unlock(&dev_priv->rps.hw_lock);
-
-	return ret == 0 && (val & SKL_CDCLK_READY_FOR_CHANGE);
-}
-
-static bool skl_cdclk_wait_for_pcu_ready(struct drm_i915_private *dev_priv)
-{
-	return _wait_for(skl_cdclk_pcu_ready(dev_priv), 3000, 10) == 0;
-}
-
 static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco)
 {
 	u32 freq_select, pcu_ack;
+	int ret;
 
 	WARN_ON((cdclk == 24000) != (vco == 0));
 
 	DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
 
-	if (!skl_cdclk_wait_for_pcu_ready(dev_priv)) {
-		DRM_ERROR("failed to inform PCU about cdclk change\n");
+	mutex_lock(&dev_priv->rps.hw_lock);
+	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
+				SKL_CDCLK_PREPARE_FOR_CHANGE,
+				SKL_CDCLK_READY_FOR_CHANGE,
+				SKL_CDCLK_READY_FOR_CHANGE, 3);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+	if (ret) {
+		DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
+			  ret);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 90283edcafba6786f79c509df64aa194e490bc3c..d9bc19be855e76b9bab0f1cee082bc170bccff26 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4014,8 +4014,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
 		return;
 
 	/* FIXME: we need to synchronize this sort of stuff with hardware
-	 * readout */
-	if (WARN_ON_ONCE(!intel_dp->lane_count))
+	 * readout. Currently fast link training doesn't work on boot-up. */
+	if (!intel_dp->lane_count)
 		return;
 
 	/* if link training is requested we should perform it always */
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 0d8ff0034b88567369861dc9ee5aa8de6651b05b..47cd1b20fb3e958fc89c83981e29496ecdfbff49 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -300,7 +300,8 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
 	mutex_lock(&dev_priv->sb_lock);
 	vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
 	vlv_iosf_sb_write(dev_priv, port, cfg0,
-			  CHV_GPIO_GPIOCFG_GPO | CHV_GPIO_GPIOTXSTATE(value));
+			  CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
+			  CHV_GPIO_GPIOTXSTATE(value));
 	mutex_unlock(&dev_priv->sb_lock);
 }
 
@@ -376,11 +377,11 @@ static const fn_mipi_elem_exec exec_elem[] = {
  */
 
 static const char * const seq_name[] = {
-	[MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
+	[MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
 	[MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
 	[MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
 	[MIPI_SEQ_DISPLAY_OFF]  = "MIPI_SEQ_DISPLAY_OFF",
-	[MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
+	[MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
 	[MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
 	[MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
 	[MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 0a09024d6ca3ebc502f0b99cef07ed91f0b4cd64..d4961fa20c73d0e2d390673889ae5fa82f04dd07 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1968,12 +1968,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
 			  ret);
 	}
 
-	ret = logical_ring_init(engine);
-	if (ret) {
-		lrc_destroy_wa_ctx_obj(engine);
-	}
-
-	return ret;
+	return logical_ring_init(engine);
 }
 
 int logical_xcs_ring_init(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d67974eb127a0f19caa005c1f5a69687ec88ae84..ae2c0bb4b2e8b384c6fc8858490143064ec4dec3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2964,24 +2964,10 @@ intel_enable_sagv(struct drm_i915_private *dev_priv)
 	return 0;
 }
 
-static int
-intel_do_sagv_disable(struct drm_i915_private *dev_priv)
-{
-	int ret;
-	uint32_t temp = GEN9_SAGV_DISABLE;
-
-	ret = sandybridge_pcode_read(dev_priv, GEN9_PCODE_SAGV_CONTROL,
-				     &temp);
-	if (ret)
-		return ret;
-	else
-		return temp & GEN9_SAGV_IS_DISABLED;
-}
-
 int
 intel_disable_sagv(struct drm_i915_private *dev_priv)
 {
-	int ret, result;
+	int ret;
 
 	if (!intel_has_sagv(dev_priv))
 		return 0;
@@ -2993,25 +2979,23 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 	mutex_lock(&dev_priv->rps.hw_lock);
 
 	/* bspec says to keep retrying for at least 1 ms */
-	ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1);
+	ret = skl_pcode_request(dev_priv, GEN9_PCODE_SAGV_CONTROL,
+				GEN9_SAGV_DISABLE,
+				GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED,
+				1);
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
-	if (ret == -ETIMEDOUT) {
-		DRM_ERROR("Request to disable SAGV timed out\n");
-		return -ETIMEDOUT;
-	}
-
 	/*
 	 * Some skl systems, pre-release machines in particular,
 	 * don't actually have an SAGV.
 	 */
-	if (IS_SKYLAKE(dev_priv) && result == -ENXIO) {
+	if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) {
 		DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
 		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
 		return 0;
-	} else if (result < 0) {
-		DRM_ERROR("Failed to disable the SAGV\n");
-		return result;
+	} else if (ret < 0) {
+		DRM_ERROR("Failed to disable the SAGV (%d)\n", ret);
+		return ret;
 	}
 
 	dev_priv->sagv_status = I915_SAGV_DISABLED;
@@ -7890,6 +7874,81 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
+static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
+				  u32 request, u32 reply_mask, u32 reply,
+				  u32 *status)
+{
+	u32 val = request;
+
+	*status = sandybridge_pcode_read(dev_priv, mbox, &val);
+
+	return *status || ((val & reply_mask) == reply);
+}
+
+/**
+ * skl_pcode_request - send PCODE request until acknowledgment
+ * @dev_priv: device private
+ * @mbox: PCODE mailbox ID the request is targeted for
+ * @request: request ID
+ * @reply_mask: mask used to check for request acknowledgment
+ * @reply: value used to check for request acknowledgment
+ * @timeout_base_ms: timeout for polling with preemption enabled
+ *
+ * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE
+ * reports an error or an overall timeout of @timeout_base_ms+10 ms expires.
+ * The request is acknowledged once the PCODE reply dword equals @reply after
+ * applying @reply_mask. Polling is first attempted with preemption enabled
+ * for @timeout_base_ms and if this times out for another 10 ms with
+ * preemption disabled.
+ *
+ * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some
+ * other error as reported by PCODE.
+ */
+int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
+		      u32 reply_mask, u32 reply, int timeout_base_ms)
+{
+	u32 status;
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+#define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
+				   &status)
+
+	/*
+	 * Prime the PCODE by doing a request first. Normally it guarantees
+	 * that a subsequent request, at most @timeout_base_ms later, succeeds.
+	 * _wait_for() doesn't guarantee when its passed condition is evaluated
+	 * first, so send the first request explicitly.
+	 */
+	if (COND) {
+		ret = 0;
+		goto out;
+	}
+	ret = _wait_for(COND, timeout_base_ms * 1000, 10);
+	if (!ret)
+		goto out;
+
+	/*
+	 * The above can time out if the number of requests was low (2 in the
+	 * worst case) _and_ PCODE was busy for some reason even after a
+	 * (queued) request and @timeout_base_ms delay. As a workaround retry
+	 * the poll with preemption disabled to maximize the number of
+	 * requests. Increase the timeout from @timeout_base_ms to 10ms to
+	 * account for interrupts that could reduce the number of these
+	 * requests.
+	 */
+	DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n");
+	WARN_ON_ONCE(timeout_base_ms > 3);
+	preempt_disable();
+	ret = wait_for_atomic(COND, 10);
+	preempt_enable();
+
+out:
+	return ret ? ret : status;
+#undef COND
+}
+
 static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
 	/*
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 7b488e2793d98457c2ae09dd988d49707288acf5..c6be70686b4af869a41db55d01b6f562a9355ce1 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -825,13 +825,9 @@ void intel_psr_init(struct drm_device *dev)
 	dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ?
 		HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE;
 
-	/* Per platform default */
-	if (i915.enable_psr == -1) {
-		if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-			i915.enable_psr = 1;
-		else
-			i915.enable_psr = 0;
-	}
+	/* Per platform default: all disabled. */
+	if (i915.enable_psr == -1)
+		i915.enable_psr = 0;
 
 	/* Set link_standby x link_off defaults */
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 356c662ad45325f6185a7eb6518e33641479d4c3..87b4af092d5487d219024c858585b5448dd3ea1c 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1039,7 +1039,18 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
 
 static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
 {
-	I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
+	u32 val;
+
+	/*
+	 * On driver load, a pipe may be active and driving a DSI display.
+	 * Preserve DPOUNIT_CLOCK_GATE_DISABLE to avoid the pipe getting stuck
+	 * (and never recovering) in this case. intel_dsi_post_disable() will
+	 * clear it when we turn off the display.
+	 */
+	val = I915_READ(DSPCLK_GATE_D);
+	val &= DPOUNIT_CLOCK_GATE_DISABLE;
+	val |= VRHUNIT_CLOCK_GATE_DISABLE;
+	I915_WRITE(DSPCLK_GATE_D, val);
 
 	/*
 	 * Disable trickle feed and enable pnd deadline calculation