Update drm/radeon to Linux 4.7.10 as much as possible...
authorDavid Shao <davshao@gmail.com>
Sat, 1 Apr 2017 23:32:06 +0000 (16:32 -0700)
committerFran├žois Tigeot <ftigeot@wolfpond.org>
Fri, 5 May 2017 11:56:43 +0000 (13:56 +0200)
...before other kernel changes.

104 files changed:
sys/conf/files
sys/dev/drm/radeon/Makefile
sys/dev/drm/radeon/atom.c
sys/dev/drm/radeon/atombios.h
sys/dev/drm/radeon/atombios_crtc.c
sys/dev/drm/radeon/atombios_dp.c
sys/dev/drm/radeon/atombios_encoders.c
sys/dev/drm/radeon/atombios_i2c.c
sys/dev/drm/radeon/btc_dpm.c
sys/dev/drm/radeon/cayman_blit_shaders.c
sys/dev/drm/radeon/ci_dpm.c
sys/dev/drm/radeon/ci_dpm.h
sys/dev/drm/radeon/ci_smc.c
sys/dev/drm/radeon/cik.c
sys/dev/drm/radeon/cik_sdma.c
sys/dev/drm/radeon/cikd.h
sys/dev/drm/radeon/dce3_1_afmt.c
sys/dev/drm/radeon/dce6_afmt.c
sys/dev/drm/radeon/evergreen.c
sys/dev/drm/radeon/evergreen_blit_shaders.c
sys/dev/drm/radeon/evergreen_cs.c
sys/dev/drm/radeon/evergreen_hdmi.c
sys/dev/drm/radeon/evergreen_reg.h
sys/dev/drm/radeon/evergreend.h
sys/dev/drm/radeon/kv_dpm.c
sys/dev/drm/radeon/ni.c
sys/dev/drm/radeon/ni_dma.c
sys/dev/drm/radeon/ni_dpm.c
sys/dev/drm/radeon/nid.h
sys/dev/drm/radeon/ppsmc.h
sys/dev/drm/radeon/pptable.h
sys/dev/drm/radeon/r100.c
sys/dev/drm/radeon/r200.c
sys/dev/drm/radeon/r300.c
sys/dev/drm/radeon/r420.c
sys/dev/drm/radeon/r600.c
sys/dev/drm/radeon/r600_blit_shaders.c
sys/dev/drm/radeon/r600_cs.c
sys/dev/drm/radeon/r600_dma.c
sys/dev/drm/radeon/r600_dpm.c
sys/dev/drm/radeon/r600_dpm.h
sys/dev/drm/radeon/r600_hdmi.c
sys/dev/drm/radeon/radeon.h
sys/dev/drm/radeon/radeon_agp.c
sys/dev/drm/radeon/radeon_asic.c
sys/dev/drm/radeon/radeon_asic.h
sys/dev/drm/radeon/radeon_atombios.c
sys/dev/drm/radeon/radeon_audio.c [new file with mode: 0644]
sys/dev/drm/radeon/radeon_audio.h [new file with mode: 0644]
sys/dev/drm/radeon/radeon_bios.c
sys/dev/drm/radeon/radeon_combios.c
sys/dev/drm/radeon/radeon_connectors.c
sys/dev/drm/radeon/radeon_cs.c
sys/dev/drm/radeon/radeon_cursor.c
sys/dev/drm/radeon/radeon_device.c
sys/dev/drm/radeon/radeon_display.c
sys/dev/drm/radeon/radeon_dp_auxch.c [new file with mode: 0644]
sys/dev/drm/radeon/radeon_drv.c
sys/dev/drm/radeon/radeon_encoders.c
sys/dev/drm/radeon/radeon_fb.c
sys/dev/drm/radeon/radeon_fence.c
sys/dev/drm/radeon/radeon_gart.c
sys/dev/drm/radeon/radeon_gem.c
sys/dev/drm/radeon/radeon_i2c.c
sys/dev/drm/radeon/radeon_irq_kms.c
sys/dev/drm/radeon/radeon_kms.c
sys/dev/drm/radeon/radeon_legacy_crtc.c
sys/dev/drm/radeon/radeon_legacy_encoders.c
sys/dev/drm/radeon/radeon_mode.h
sys/dev/drm/radeon/radeon_object.c
sys/dev/drm/radeon/radeon_object.h
sys/dev/drm/radeon/radeon_pm.c
sys/dev/drm/radeon/radeon_ring.c
sys/dev/drm/radeon/radeon_sa.c
sys/dev/drm/radeon/radeon_ttm.c
sys/dev/drm/radeon/radeon_uvd.c
sys/dev/drm/radeon/radeon_vce.c
sys/dev/drm/radeon/radeon_vm.c
sys/dev/drm/radeon/rs400.c
sys/dev/drm/radeon/rs600.c
sys/dev/drm/radeon/rs690.c
sys/dev/drm/radeon/rs780_dpm.c
sys/dev/drm/radeon/rv515.c
sys/dev/drm/radeon/rv6xx_dpm.c
sys/dev/drm/radeon/rv730_dpm.c
sys/dev/drm/radeon/rv770.c
sys/dev/drm/radeon/rv770_dpm.c
sys/dev/drm/radeon/rv770_smc.c
sys/dev/drm/radeon/rv770d.h
sys/dev/drm/radeon/si.c
sys/dev/drm/radeon/si_dma.c
sys/dev/drm/radeon/si_dpm.c
sys/dev/drm/radeon/si_dpm.h
sys/dev/drm/radeon/si_smc.c
sys/dev/drm/radeon/sid.h
sys/dev/drm/radeon/sislands_smc.h
sys/dev/drm/radeon/smu7_discrete.h
sys/dev/drm/radeon/sumo_dpm.c
sys/dev/drm/radeon/trinity_dpm.c
sys/dev/drm/radeon/uvd_v1_0.c
sys/dev/drm/radeon/uvd_v2_2.c
sys/dev/drm/radeon/uvd_v4_2.c
sys/dev/drm/radeon/vce_v1_0.c
sys/dev/drm/radeon/vce_v2_0.c

index 43c9d8d..0a13e90 100644 (file)
@@ -2172,6 +2172,7 @@ dev/drm/radeon/radeon_acpi.c              optional radeon drm
 dev/drm/radeon/radeon_agp.c            optional radeon drm
 dev/drm/radeon/radeon_asic.c           optional radeon drm
 dev/drm/radeon/radeon_atombios.c       optional radeon drm
+dev/drm/radeon/radeon_audio.c          optional radeon drm
 dev/drm/radeon/radeon_benchmark.c      optional radeon drm
 dev/drm/radeon/radeon_bios.c           optional radeon drm
 dev/drm/radeon/radeon_clocks.c         optional radeon drm
@@ -2181,6 +2182,7 @@ dev/drm/radeon/radeon_cs.c                optional radeon drm
 dev/drm/radeon/radeon_cursor.c         optional radeon drm
 dev/drm/radeon/radeon_device.c         optional radeon drm
 dev/drm/radeon/radeon_display.c                optional radeon drm
+dev/drm/radeon/radeon_dp_auxch.c       optional radeon drm
 dev/drm/radeon/radeon_drv.c            optional radeon drm
 dev/drm/radeon/radeon_encoders.c       optional radeon drm
 dev/drm/radeon/radeon_fb.c             optional radeon drm
index 592368a..4505b54 100644 (file)
@@ -22,6 +22,7 @@ SRCS  +=                                                              \
        radeon_agp.c                                                    \
        radeon_asic.c                                                   \
        radeon_atombios.c                                               \
+       radeon_audio.c                                          \
        radeon_benchmark.c                                              \
        radeon_bios.c                                                   \
        radeon_clocks.c                                                 \
@@ -31,6 +32,7 @@ SRCS  +=                                                              \
        radeon_cursor.c                                                 \
        radeon_device.c                                                 \
        radeon_display.c                                                \
+       radeon_dp_auxch.c                                               \
        radeon_drv.c                                                    \
        radeon_encoders.c                                               \
        radeon_fb.c                                                     \
index 73da113..521e189 100644 (file)
@@ -65,9 +65,10 @@ typedef struct {
 int atom_debug = 0;
 static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
 
-static uint32_t atom_arg_mask[8] =
-    { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
-0xFF000000 };
+static uint32_t atom_arg_mask[8] = {
+       0xFFFFFFFF, 0x0000FFFF, 0x00FFFF00, 0xFFFF0000,
+       0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
+};
 static int atom_arg_shift[8] = { 0, 0, 8, 16, 0, 8, 16, 24 };
 
 static int atom_dst_to_src[8][4] = {
@@ -91,13 +92,23 @@ static void debug_print_spaces(int n)
                kprintf("   ");
 }
 
-#define ATOM_DEBUG_PRINT(...) do if (atom_debug) { kprintf(__FILE__ __VA_ARGS__); } while (0)
-#define ATOM_SDEBUG_PRINT(...) do if (atom_debug) { kprintf(__FILE__); debug_print_spaces(debug_depth); kprintf(__VA_ARGS__); } while (0)
-#else
-#define ATOM_DEBUG_PRINT(...) do { } while (0)
-#define ATOM_SDEBUG_PRINT(...) do { } while (0)
+#ifdef DEBUG
+#undef DEBUG
+#endif
+#ifdef SDEBUG
+#undef SDEBUG
 #endif
 
+#define DEBUG(...) do if (atom_debug) { kprintf(__FILE__ __VA_ARGS__); } while (0)
+#define SDEBUG(...) do if (atom_debug) { kprintf(__FILE__); debug_print_spaces(debug_depth); kprintf(__VA_ARGS__); } while (0)
+
+#else /* !ATOM_DEBUG */
+
+#define DEBUG(...) do { } while (0)
+#define SDEBUG(...) do { } while (0)
+
+#endif /* ATOM_DEBUG */
+
 static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
                                 uint32_t index, uint32_t data)
 {
@@ -189,7 +200,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                idx = U16(*ptr);
                (*ptr) += 2;
                if (print)
-                       ATOM_DEBUG_PRINT("REG[0x%04X]", idx);
+                       DEBUG("REG[0x%04X]", idx);
                idx += gctx->reg_block;
                switch (gctx->io_mode) {
                case ATOM_IO_MM:
@@ -227,13 +238,13 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                 * tables, noticed on a DEC Alpha. */
                val = get_unaligned_le32((u32 *)&ctx->ps[idx]);
                if (print)
-                       ATOM_DEBUG_PRINT("PS[0x%02X,0x%04X]", idx, val);
+                       DEBUG("PS[0x%02X,0x%04X]", idx, val);
                break;
        case ATOM_ARG_WS:
                idx = U8(*ptr);
                (*ptr)++;
                if (print)
-                       ATOM_DEBUG_PRINT("WS[0x%02X]", idx);
+                       DEBUG("WS[0x%02X]", idx);
                switch (idx) {
                case ATOM_WS_QUOTIENT:
                        val = gctx->divmul[0];
@@ -271,9 +282,9 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                (*ptr) += 2;
                if (print) {
                        if (gctx->data_block)
-                               ATOM_DEBUG_PRINT("ID[0x%04X+%04X]", idx, gctx->data_block);
+                               DEBUG("ID[0x%04X+%04X]", idx, gctx->data_block);
                        else
-                               ATOM_DEBUG_PRINT("ID[0x%04X]", idx);
+                               DEBUG("ID[0x%04X]", idx);
                }
                val = U32(idx + gctx->data_block);
                break;
@@ -287,7 +298,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                } else
                        val = gctx->scratch[(gctx->fb_base / 4) + idx];
                if (print)
-                       ATOM_DEBUG_PRINT("FB[0x%02X]", idx);
+                       DEBUG("FB[0x%02X]", idx);
                break;
        case ATOM_ARG_IMM:
                switch (align) {
@@ -295,7 +306,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                        val = U32(*ptr);
                        (*ptr) += 4;
                        if (print)
-                               ATOM_DEBUG_PRINT("IMM 0x%08X\n", val);
+                               DEBUG("IMM 0x%08X\n", val);
                        return val;
                case ATOM_SRC_WORD0:
                case ATOM_SRC_WORD8:
@@ -303,7 +314,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                        val = U16(*ptr);
                        (*ptr) += 2;
                        if (print)
-                               ATOM_DEBUG_PRINT("IMM 0x%04X\n", val);
+                               DEBUG("IMM 0x%04X\n", val);
                        return val;
                case ATOM_SRC_BYTE0:
                case ATOM_SRC_BYTE8:
@@ -312,7 +323,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                        val = U8(*ptr);
                        (*ptr)++;
                        if (print)
-                               ATOM_DEBUG_PRINT("IMM 0x%02X\n", val);
+                               DEBUG("IMM 0x%02X\n", val);
                        return val;
                }
                return 0;
@@ -320,14 +331,14 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
                idx = U8(*ptr);
                (*ptr)++;
                if (print)
-                       ATOM_DEBUG_PRINT("PLL[0x%02X]", idx);
+                       DEBUG("PLL[0x%02X]", idx);
                val = gctx->card->pll_read(gctx->card, idx);
                break;
        case ATOM_ARG_MC:
                idx = U8(*ptr);
                (*ptr)++;
                if (print)
-                       ATOM_DEBUG_PRINT("MC[0x%02X]", idx);
+                       DEBUG("MC[0x%02X]", idx);
                val = gctx->card->mc_read(gctx->card, idx);
                break;
        }
@@ -338,28 +349,28 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
        if (print)
                switch (align) {
                case ATOM_SRC_DWORD:
-                       ATOM_DEBUG_PRINT(".[31:0] -> 0x%08X\n", val);
+                       DEBUG(".[31:0] -> 0x%08X\n", val);
                        break;
                case ATOM_SRC_WORD0:
-                       ATOM_DEBUG_PRINT(".[15:0] -> 0x%04X\n", val);
+                       DEBUG(".[15:0] -> 0x%04X\n", val);
                        break;
                case ATOM_SRC_WORD8:
-                       ATOM_DEBUG_PRINT(".[23:8] -> 0x%04X\n", val);
+                       DEBUG(".[23:8] -> 0x%04X\n", val);
                        break;
                case ATOM_SRC_WORD16:
-                       ATOM_DEBUG_PRINT(".[31:16] -> 0x%04X\n", val);
+                       DEBUG(".[31:16] -> 0x%04X\n", val);
                        break;
                case ATOM_SRC_BYTE0:
-                       ATOM_DEBUG_PRINT(".[7:0] -> 0x%02X\n", val);
+                       DEBUG(".[7:0] -> 0x%02X\n", val);
                        break;
                case ATOM_SRC_BYTE8:
-                       ATOM_DEBUG_PRINT(".[15:8] -> 0x%02X\n", val);
+                       DEBUG(".[15:8] -> 0x%02X\n", val);
                        break;
                case ATOM_SRC_BYTE16:
-                       ATOM_DEBUG_PRINT(".[23:16] -> 0x%02X\n", val);
+                       DEBUG(".[23:16] -> 0x%02X\n", val);
                        break;
                case ATOM_SRC_BYTE24:
-                       ATOM_DEBUG_PRINT(".[31:24] -> 0x%02X\n", val);
+                       DEBUG(".[31:24] -> 0x%02X\n", val);
                        break;
                }
        return val;
@@ -464,7 +475,7 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,
        case ATOM_ARG_REG:
                idx = U16(*ptr);
                (*ptr) += 2;
-               ATOM_DEBUG_PRINT("REG[0x%04X]", idx);
+               DEBUG("REG[0x%04X]", idx);
                idx += gctx->reg_block;
                switch (gctx->io_mode) {
                case ATOM_IO_MM:
@@ -500,13 +511,13 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,
        case ATOM_ARG_PS:
                idx = U8(*ptr);
                (*ptr)++;
-               ATOM_DEBUG_PRINT("PS[0x%02X]", idx);
+               DEBUG("PS[0x%02X]", idx);
                ctx->ps[idx] = cpu_to_le32(val);
                break;
        case ATOM_ARG_WS:
                idx = U8(*ptr);
                (*ptr)++;
-               ATOM_DEBUG_PRINT("WS[0x%02X]", idx);
+               DEBUG("WS[0x%02X]", idx);
                switch (idx) {
                case ATOM_WS_QUOTIENT:
                        gctx->divmul[0] = val;
@@ -544,45 +555,45 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,
                                  gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
                } else
                        gctx->scratch[(gctx->fb_base / 4) + idx] = val;
-               ATOM_DEBUG_PRINT("FB[0x%02X]", idx);
+               DEBUG("FB[0x%02X]", idx);
                break;
        case ATOM_ARG_PLL:
                idx = U8(*ptr);
                (*ptr)++;
-               ATOM_DEBUG_PRINT("PLL[0x%02X]", idx);
+               DEBUG("PLL[0x%02X]", idx);
                gctx->card->pll_write(gctx->card, idx, val);
                break;
        case ATOM_ARG_MC:
                idx = U8(*ptr);
                (*ptr)++;
-               ATOM_DEBUG_PRINT("MC[0x%02X]", idx);
+               DEBUG("MC[0x%02X]", idx);
                gctx->card->mc_write(gctx->card, idx, val);
                return;
        }
        switch (align) {
        case ATOM_SRC_DWORD:
-               ATOM_DEBUG_PRINT(".[31:0] <- 0x%08X\n", old_val);
+               DEBUG(".[31:0] <- 0x%08X\n", old_val);
                break;
        case ATOM_SRC_WORD0:
-               ATOM_DEBUG_PRINT(".[15:0] <- 0x%04X\n", old_val);
+               DEBUG(".[15:0] <- 0x%04X\n", old_val);
                break;
        case ATOM_SRC_WORD8:
-               ATOM_DEBUG_PRINT(".[23:8] <- 0x%04X\n", old_val);
+               DEBUG(".[23:8] <- 0x%04X\n", old_val);
                break;
        case ATOM_SRC_WORD16:
-               ATOM_DEBUG_PRINT(".[31:16] <- 0x%04X\n", old_val);
+               DEBUG(".[31:16] <- 0x%04X\n", old_val);
                break;
        case ATOM_SRC_BYTE0:
-               ATOM_DEBUG_PRINT(".[7:0] <- 0x%02X\n", old_val);
+               DEBUG(".[7:0] <- 0x%02X\n", old_val);
                break;
        case ATOM_SRC_BYTE8:
-               ATOM_DEBUG_PRINT(".[15:8] <- 0x%02X\n", old_val);
+               DEBUG(".[15:8] <- 0x%02X\n", old_val);
                break;
        case ATOM_SRC_BYTE16:
-               ATOM_DEBUG_PRINT(".[23:16] <- 0x%02X\n", old_val);
+               DEBUG(".[23:16] <- 0x%02X\n", old_val);
                break;
        case ATOM_SRC_BYTE24:
-               ATOM_DEBUG_PRINT(".[31:24] <- 0x%02X\n", old_val);
+               DEBUG(".[31:24] <- 0x%02X\n", old_val);
                break;
        }
 }
@@ -592,12 +603,12 @@ static void atom_op_add(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src, saved;
        int dptr = *ptr;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       ATOM_SDEBUG_PRINT("   src: ");
+       SDEBUG("   src: ");
        src = atom_get_src(ctx, attr, ptr);
        dst += src;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -606,12 +617,12 @@ static void atom_op_and(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src, saved;
        int dptr = *ptr;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       ATOM_SDEBUG_PRINT("   src: ");
+       SDEBUG("   src: ");
        src = atom_get_src(ctx, attr, ptr);
        dst &= src;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -626,9 +637,9 @@ static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
        int r = 0;
 
        if (idx < ATOM_TABLE_NAMES_CNT)
-               ATOM_SDEBUG_PRINT("   table: %d (%s)\n", idx, atom_table_names[idx]);
+               SDEBUG("   table: %d (%s)\n", idx, atom_table_names[idx]);
        else
-               ATOM_SDEBUG_PRINT("   table: %d\n", idx);
+               SDEBUG("   table: %d\n", idx);
        if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
                r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
        if (r) {
@@ -644,7 +655,7 @@ static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
        attr &= 0x38;
        attr |= atom_def_dst[attr >> 3] << 6;
        atom_get_dst(ctx, arg, attr, ptr, &saved, 0);
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, 0, saved);
 }
 
@@ -652,20 +663,20 @@ static void atom_op_compare(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src;
-       ATOM_SDEBUG_PRINT("   src1: ");
+       SDEBUG("   src1: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
-       ATOM_SDEBUG_PRINT("   src2: ");
+       SDEBUG("   src2: ");
        src = atom_get_src(ctx, attr, ptr);
        ctx->ctx->cs_equal = (dst == src);
        ctx->ctx->cs_above = (dst > src);
-       ATOM_SDEBUG_PRINT("   result: %s %s\n", ctx->ctx->cs_equal ? "EQ" : "NE",
+       SDEBUG("   result: %s %s\n", ctx->ctx->cs_equal ? "EQ" : "NE",
               ctx->ctx->cs_above ? "GT" : "LE");
 }
 
 static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
 {
        unsigned count = U8((*ptr)++);
-       ATOM_SDEBUG_PRINT("   count: %d\n", count);
+       SDEBUG("   count: %d\n", count);
        if (arg == ATOM_UNIT_MICROSEC)
                udelay(count);
        else if (!drm_can_sleep())
@@ -678,9 +689,9 @@ static void atom_op_div(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src;
-       ATOM_SDEBUG_PRINT("   src1: ");
+       SDEBUG("   src1: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
-       ATOM_SDEBUG_PRINT("   src2: ");
+       SDEBUG("   src2: ");
        src = atom_get_src(ctx, attr, ptr);
        if (src != 0) {
                ctx->ctx->divmul[0] = dst / src;
@@ -726,8 +737,8 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
                break;
        }
        if (arg != ATOM_COND_ALWAYS)
-               ATOM_SDEBUG_PRINT("   taken: %s\n", execute ? "yes" : "no");
-       ATOM_SDEBUG_PRINT("   target: 0x%04X\n", target);
+               SDEBUG("   taken: %s\n", execute ? "yes" : "no");
+       SDEBUG("   target: 0x%04X\n", target);
        if (execute) {
                if (ctx->last_jump == (ctx->start + target)) {
                        cjiffies = jiffies;
@@ -754,15 +765,15 @@ static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, mask, src, saved;
        int dptr = *ptr;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
        mask = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr);
-       ATOM_SDEBUG_PRINT("   mask: 0x%08x", mask);
-       ATOM_SDEBUG_PRINT("   src: ");
+       SDEBUG("   mask: 0x%08x", mask);
+       SDEBUG("   src: ");
        src = atom_get_src(ctx, attr, ptr);
        dst &= mask;
        dst |= src;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -777,9 +788,9 @@ static void atom_op_move(atom_exec_context *ctx, int *ptr, int arg)
                atom_skip_dst(ctx, arg, attr, ptr);
                saved = 0xCDCDCDCD;
        }
-       ATOM_SDEBUG_PRINT("   src: ");
+       SDEBUG("   src: ");
        src = atom_get_src(ctx, attr, ptr);
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, src, saved);
 }
 
@@ -787,9 +798,9 @@ static void atom_op_mul(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src;
-       ATOM_SDEBUG_PRINT("   src1: ");
+       SDEBUG("   src1: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
-       ATOM_SDEBUG_PRINT("   src2: ");
+       SDEBUG("   src2: ");
        src = atom_get_src(ctx, attr, ptr);
        ctx->ctx->divmul[0] = dst * src;
 }
@@ -804,19 +815,19 @@ static void atom_op_or(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src, saved;
        int dptr = *ptr;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       ATOM_SDEBUG_PRINT("   src: ");
+       SDEBUG("   src: ");
        src = atom_get_src(ctx, attr, ptr);
        dst |= src;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
 static void atom_op_postcard(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8_t val = U8((*ptr)++);
-       ATOM_SDEBUG_PRINT("POST card output: 0x%02X\n", val);
+       SDEBUG("POST card output: 0x%02X\n", val);
 }
 
 static void atom_op_repeat(atom_exec_context *ctx, int *ptr, int arg)
@@ -838,20 +849,20 @@ static void atom_op_setdatablock(atom_exec_context *ctx, int *ptr, int arg)
 {
        int idx = U8(*ptr);
        (*ptr)++;
-       ATOM_SDEBUG_PRINT("   block: %d\n", idx);
+       SDEBUG("   block: %d\n", idx);
        if (!idx)
                ctx->ctx->data_block = 0;
        else if (idx == 255)
                ctx->ctx->data_block = ctx->start;
        else
                ctx->ctx->data_block = U16(ctx->ctx->data_table + 4 + 2 * idx);
-       ATOM_SDEBUG_PRINT("   base: 0x%04X\n", ctx->ctx->data_block);
+       SDEBUG("   base: 0x%04X\n", ctx->ctx->data_block);
 }
 
 static void atom_op_setfbbase(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8_t attr = U8((*ptr)++);
-       ATOM_SDEBUG_PRINT("   fb_base: ");
+       SDEBUG("   fb_base: ");
        ctx->ctx->fb_base = atom_get_src(ctx, attr, ptr);
 }
 
@@ -862,9 +873,9 @@ static void atom_op_setport(atom_exec_context *ctx, int *ptr, int arg)
        case ATOM_PORT_ATI:
                port = U16(*ptr);
                if (port < ATOM_IO_NAMES_CNT)
-                       ATOM_SDEBUG_PRINT("   port: %d (%s)\n", port, atom_io_names[port]);
+                       SDEBUG("   port: %d (%s)\n", port, atom_io_names[port]);
                else
-                       ATOM_SDEBUG_PRINT("   port: %d\n", port);
+                       SDEBUG("   port: %d\n", port);
                if (!port)
                        ctx->ctx->io_mode = ATOM_IO_MM;
                else
@@ -886,7 +897,7 @@ static void atom_op_setregblock(atom_exec_context *ctx, int *ptr, int arg)
 {
        ctx->ctx->reg_block = U16(*ptr);
        (*ptr) += 2;
-       ATOM_SDEBUG_PRINT("   base: 0x%04X\n", ctx->ctx->reg_block);
+       SDEBUG("   base: 0x%04X\n", ctx->ctx->reg_block);
 }
 
 static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg)
@@ -896,12 +907,12 @@ static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg)
        int dptr = *ptr;
        attr &= 0x38;
        attr |= atom_def_dst[attr >> 3] << 6;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
        shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr);
-       ATOM_SDEBUG_PRINT("   shift: %d\n", shift);
+       SDEBUG("   shift: %d\n", shift);
        dst <<= shift;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -912,12 +923,12 @@ static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg)
        int dptr = *ptr;
        attr &= 0x38;
        attr |= atom_def_dst[attr >> 3] << 6;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
        shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr);
-       ATOM_SDEBUG_PRINT("   shift: %d\n", shift);
+       SDEBUG("   shift: %d\n", shift);
        dst >>= shift;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -927,16 +938,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
        uint32_t saved, dst;
        int dptr = *ptr;
        uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
        /* op needs to full dst value */
        dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
-       ATOM_SDEBUG_PRINT("   shift: %d\n", shift);
+       SDEBUG("   shift: %d\n", shift);
        dst <<= shift;
        dst &= atom_arg_mask[dst_align];
        dst >>= atom_arg_shift[dst_align];
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -946,16 +957,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
        uint32_t saved, dst;
        int dptr = *ptr;
        uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
        /* op needs to full dst value */
        dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
-       ATOM_SDEBUG_PRINT("   shift: %d\n", shift);
+       SDEBUG("   shift: %d\n", shift);
        dst >>= shift;
        dst &= atom_arg_mask[dst_align];
        dst >>= atom_arg_shift[dst_align];
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -964,12 +975,12 @@ static void atom_op_sub(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src, saved;
        int dptr = *ptr;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       ATOM_SDEBUG_PRINT("   src: ");
+       SDEBUG("   src: ");
        src = atom_get_src(ctx, attr, ptr);
        dst -= src;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -977,18 +988,18 @@ static void atom_op_switch(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8_t attr = U8((*ptr)++);
        uint32_t src, val, target;
-       ATOM_SDEBUG_PRINT("   switch: ");
+       SDEBUG("   switch: ");
        src = atom_get_src(ctx, attr, ptr);
        while (U16(*ptr) != ATOM_CASE_END)
                if (U8(*ptr) == ATOM_CASE_MAGIC) {
                        (*ptr)++;
-                       ATOM_SDEBUG_PRINT("   case: ");
+                       SDEBUG("   case: ");
                        val =
                            atom_get_src(ctx, (attr & 0x38) | ATOM_ARG_IMM,
                                         ptr);
                        target = U16(*ptr);
                        if (val == src) {
-                               ATOM_SDEBUG_PRINT("   target: %04X\n", target);
+                               SDEBUG("   target: %04X\n", target);
                                *ptr = ctx->start + target;
                                return;
                        }
@@ -1004,12 +1015,12 @@ static void atom_op_test(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src;
-       ATOM_SDEBUG_PRINT("   src1: ");
+       SDEBUG("   src1: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
-       ATOM_SDEBUG_PRINT("   src2: ");
+       SDEBUG("   src2: ");
        src = atom_get_src(ctx, attr, ptr);
        ctx->ctx->cs_equal = ((dst & src) == 0);
-       ATOM_SDEBUG_PRINT("   result: %s\n", ctx->ctx->cs_equal ? "EQ" : "NE");
+       SDEBUG("   result: %s\n", ctx->ctx->cs_equal ? "EQ" : "NE");
 }
 
 static void atom_op_xor(atom_exec_context *ctx, int *ptr, int arg)
@@ -1017,12 +1028,12 @@ static void atom_op_xor(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++);
        uint32_t dst, src, saved;
        int dptr = *ptr;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       ATOM_SDEBUG_PRINT("   src: ");
+       SDEBUG("   src: ");
        src = atom_get_src(ctx, attr, ptr);
        dst ^= src;
-       ATOM_SDEBUG_PRINT("   dst: ");
+       SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -1175,7 +1186,7 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32
        ps = CU8(base + ATOM_CT_PS_PTR) & ATOM_CT_PS_MASK;
        ptr = base + ATOM_CT_CODE_PTR;
 
-       ATOM_SDEBUG_PRINT(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps);
+       SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps);
 
        ectx.ctx = ctx;
        ectx.ps_shift = ps / 4;
@@ -1192,9 +1203,9 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32
        while (1) {
                op = CU8(ptr++);
                if (op < ATOM_OP_NAMES_CNT)
-                       ATOM_SDEBUG_PRINT("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);
+                       SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);
                else
-                       ATOM_SDEBUG_PRINT("[%d] @ 0x%04X\n", op, ptr - 1);
+                       SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1);
                if (ectx.abort) {
                        DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n",
                                base, len, ws, ps, ptr - 1);
@@ -1212,7 +1223,7 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32
                        break;
        }
        debug_depth--;
-       ATOM_SDEBUG_PRINT("<<\n");
+       SDEBUG("<<\n");
 
 free:
        if (ws)
@@ -1224,7 +1235,7 @@ int atom_execute_table_scratch_unlocked(struct atom_context *ctx, int index, uin
 {
        int r;
 
-       lockmgr(&ctx->mutex, LK_EXCLUSIVE);
+       mutex_lock(&ctx->mutex);
        /* reset data block */
        ctx->data_block = 0;
        /* reset reg block */
@@ -1237,16 +1248,16 @@ int atom_execute_table_scratch_unlocked(struct atom_context *ctx, int index, uin
        ctx->divmul[0] = 0;
        ctx->divmul[1] = 0;
        r = atom_execute_table_locked(ctx, index, params);
-       lockmgr(&ctx->mutex, LK_RELEASE);
+       mutex_unlock(&ctx->mutex);
        return r;
 }
 
 int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
 {
        int r;
-       lockmgr(&ctx->scratch_mutex, LK_EXCLUSIVE);
+       mutex_lock(&ctx->scratch_mutex);
        r = atom_execute_table_scratch_unlocked(ctx, index, params);
-       lockmgr(&ctx->scratch_mutex, LK_RELEASE);
+       mutex_unlock(&ctx->scratch_mutex);
        return r;
 }
 
index 47d7123..cd57f37 100644 (file)
@@ -7944,8 +7944,8 @@ typedef struct {
 typedef struct {
   AMD_ACPI_DESCRIPTION_HEADER SHeader;
   UCHAR TableUUID[16];    //0x24
-  ULONG VBIOSImageOffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the stucture.
-  ULONG Lib1ImageOffset;  //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the stucture.
+  ULONG VBIOSImageOffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the structure.
+  ULONG Lib1ImageOffset;  //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the structure.
   ULONG Reserved[4];      //0x3C
 }UEFI_ACPI_VFCT;
 
index 103c2ba..d65baf5 100644 (file)
@@ -275,13 +275,15 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
                        atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
                atombios_blank_crtc(crtc, ATOM_DISABLE);
-               drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_on(dev, radeon_crtc->crtc_id);
                radeon_crtc_load_lut(crtc);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_off(dev, radeon_crtc->crtc_id);
                if (radeon_crtc->enabled)
                        atombios_blank_crtc(crtc, ATOM_ENABLE);
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
@@ -331,8 +333,10 @@ atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
                misc |= ATOM_COMPOSITESYNC;
        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
                misc |= ATOM_INTERLACE;
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               misc |= ATOM_DOUBLE_CLOCK_MODE;
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               misc |= ATOM_DOUBLE_CLOCK_MODE;
+               misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
 
        args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
        args.ucCRTC = radeon_crtc->crtc_id;
@@ -375,8 +379,10 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
                misc |= ATOM_COMPOSITESYNC;
        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
                misc |= ATOM_INTERLACE;
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               misc |= ATOM_DOUBLE_CLOCK_MODE;
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               misc |= ATOM_DOUBLE_CLOCK_MODE;
+               misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
 
        args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
        args.ucCRTC = radeon_crtc->crtc_id;
@@ -583,7 +589,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                /* use frac fb div on RS780/RS880 */
-               if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
+               if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
+                   && !radeon_crtc->ss_enabled)
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
@@ -613,7 +620,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                        if (radeon_crtc->ss.refdiv) {
                                radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
                                radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
-                               if (ASIC_IS_AVIVO(rdev))
+                               if (ASIC_IS_AVIVO(rdev) &&
+                                   rdev->family != CHIP_RS780 &&
+                                   rdev->family != CHIP_RS880)
                                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                        }
                }
@@ -1360,6 +1369,11 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
                break;
        }
 
+       /* Make sure surface address is updated at vertical blank rather than
+        * horizontal blank
+        */
+       WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
+
        WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
               upper_32_bits(fb_location));
        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
@@ -1406,15 +1420,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
               (x << 16) | y);
        viewport_w = crtc->mode.hdisplay;
        viewport_h = (crtc->mode.vdisplay + 1) & ~1;
+       if ((rdev->family >= CHIP_BONAIRE) &&
+           (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE))
+               viewport_h *= 2;
        WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
               (viewport_w << 16) | viewport_h);
 
-       /* pageflip setup */
-       /* make sure flip is at vb rather than hb */
-       tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
-       tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN;
-       WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
-
        /* set pageflip to happen only at start of vblank interval (front porch) */
        WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
 
@@ -1448,7 +1459,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        uint64_t fb_location;
        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
        u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
-       u32 tmp, viewport_w, viewport_h;
+       u32 viewport_w, viewport_h;
        int r;
        bool bypass_lut = false;
 
@@ -1563,6 +1574,11 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        else
                WREG32(AVIVO_D2VGA_CONTROL, 0);
 
+       /* Make sure surface address is update at vertical blank rather than
+        * horizontal blank
+        */
+       WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
+
        if (rdev->family >= CHIP_RV770) {
                if (radeon_crtc->crtc_id) {
                        WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
@@ -1609,12 +1625,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
               (viewport_w << 16) | viewport_h);
 
-       /* pageflip setup */
-       /* make sure flip is at vb rather than hb */
-       tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
-       tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
-       WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
-
        /* set pageflip to happen only at start of vblank interval (front porch) */
        WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
 
@@ -1724,6 +1734,7 @@ static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
 static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct drm_crtc *test_crtc;
        struct radeon_crtc *test_radeon_crtc;
 
@@ -1733,6 +1744,10 @@ static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
                test_radeon_crtc = to_radeon_crtc(test_crtc);
                if (test_radeon_crtc->encoder &&
                    ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+                       /* PPLL2 is exclusive to UNIPHYA on DCE61 */
+                       if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
+                           test_radeon_crtc->pll_id == ATOM_PPLL2)
+                               continue;
                        /* for DP use the same PLL for all */
                        if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
                                return test_radeon_crtc->pll_id;
@@ -1754,6 +1769,7 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct drm_crtc *test_crtc;
        struct radeon_crtc *test_radeon_crtc;
        u32 adjusted_clock, test_adjusted_clock;
@@ -1769,6 +1785,10 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
                test_radeon_crtc = to_radeon_crtc(test_crtc);
                if (test_radeon_crtc->encoder &&
                    !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+                       /* PPLL2 is exclusive to UNIPHYA on DCE61 */
+                       if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
+                           test_radeon_crtc->pll_id == ATOM_PPLL2)
+                               continue;
                        /* check if we are already driving this connector with another crtc */
                        if (test_radeon_crtc->connector == radeon_crtc->connector) {
                                /* if we are, return that pll */
@@ -1852,10 +1872,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
                                return pll;
                }
                /* otherwise, pick one of the plls */
-               if ((rdev->family == CHIP_KAVERI) ||
-                   (rdev->family == CHIP_KABINI) ||
-                   (rdev->family == CHIP_MULLINS)) {
-                       /* KB/KV/ML has PPLL1 and PPLL2 */
+               if ((rdev->family == CHIP_KABINI) ||
+                   (rdev->family == CHIP_MULLINS)) {
+                       /* KB/ML has PPLL1 and PPLL2 */
                        pll_in_use = radeon_get_pll_use_mask(crtc);
                        if (!(pll_in_use & (1 << ATOM_PPLL2)))
                                return ATOM_PPLL2;
@@ -1864,7 +1883,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
                        DRM_ERROR("unable to allocate a PPLL\n");
                        return ATOM_PPLL_INVALID;
                } else {
-                       /* CI has PPLL0, PPLL1, and PPLL2 */
+                       /* CI/KV has PPLL0, PPLL1, and PPLL2 */
                        pll_in_use = radeon_get_pll_use_mask(crtc);
                        if (!(pll_in_use & (1 << ATOM_PPLL2)))
                                return ATOM_PPLL2;
@@ -2040,6 +2059,7 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
        atombios_crtc_set_base(crtc, x, y, old_fb);
        atombios_overscan_setup(crtc, mode, adjusted_mode);
        atombios_scaler_setup(crtc);
+       radeon_cursor_reset(crtc);
        /* update the hw version fpr dpm */
        radeon_crtc->hw_mode = *adjusted_mode;
 
@@ -2067,6 +2087,12 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
                radeon_crtc->connector = NULL;
                return false;
        }
+       if (radeon_crtc->encoder) {
+               struct radeon_encoder *radeon_encoder =
+                       to_radeon_encoder(radeon_crtc->encoder);
+
+               radeon_crtc->output_csc = radeon_encoder->output_csc;
+       }
        if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
                return false;
        if (!atombios_crtc_prepare_pll(crtc, adjusted_mode))
@@ -2155,6 +2181,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
        case ATOM_PPLL0:
                /* disable the ppll */
                if ((rdev->family == CHIP_ARUBA) ||
+                   (rdev->family == CHIP_KAVERI) ||
                    (rdev->family == CHIP_BONAIRE) ||
                    (rdev->family == CHIP_HAWAII))
                        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
index eb026f8..b4ecf2e 100644 (file)
@@ -99,8 +99,8 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
 
        memset(&args, 0, sizeof(args));
 
-       lockmgr(&chan->mutex, LK_EXCLUSIVE);
-       lockmgr(&rdev->mode_info.atom_context->scratch_mutex, LK_EXCLUSIVE);
+       mutex_lock(&chan->mutex);
+       mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
 
        base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
 
@@ -148,8 +148,8 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
 
        r = recv_bytes;
 done:
-       lockmgr(&rdev->mode_info.atom_context->scratch_mutex, LK_RELEASE);
-       lockmgr(&chan->mutex, LK_RELEASE);
+       mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
+       mutex_unlock(&chan->mutex);
 
        return r;
 }
@@ -158,7 +158,7 @@ done:
 #define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
 
 static ssize_t
-radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
+radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 {
        struct radeon_i2c_chan *chan =
                container_of(aux, struct radeon_i2c_chan, aux);
@@ -171,13 +171,22 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
                return -E2BIG;
 
        tx_buf[0] = msg->address & 0xff;
-       tx_buf[1] = msg->address >> 8;
-       tx_buf[2] = msg->request << 4;
+       tx_buf[1] = (msg->address >> 8) & 0xff;
+       tx_buf[2] = (msg->request << 4) |
+               ((msg->address >> 16) & 0xf);
        tx_buf[3] = msg->size ? (msg->size - 1) : 0;
 
        switch (msg->request & ~DP_AUX_I2C_MOT) {
        case DP_AUX_NATIVE_WRITE:
        case DP_AUX_I2C_WRITE:
+       case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+               /* The atom implementation only supports writes with a max payload of
+                * 12 bytes since it uses 4 bits for the total count (header + payload)
+                * in the parameter space.  The atom interface supports 16 byte
+                * payloads for reads. The hw itself supports up to 16 bytes of payload.
+                */
+               if (WARN_ON_ONCE(msg->size > 12))
+                       return -E2BIG;
                /* tx_size needs to be 4 even for bare address packets since the atom
                 * table needs the info in tx_buf[3].
                 */
@@ -219,98 +228,26 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 
 void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
 {
-       struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
-
-       dig_connector->dp_i2c_bus->rec.hpd = radeon_connector->hpd.hpd; /* XXX check*/
-       dig_connector->dp_i2c_bus->aux.dev = radeon_connector->base.kdev;
-       dig_connector->dp_i2c_bus->aux.transfer = radeon_dp_aux_transfer;
-}
-
-int radeon_dp_i2c_aux_ch(device_t dev, int mode, u8 write_byte, u8 *read_byte)
-{
-       struct i2c_algo_dp_aux_data *algo_data = device_get_softc(dev);
-       struct radeon_i2c_chan *auxch = algo_data->priv;
-       u16 address = algo_data->address;
-       u8 msg[5];
-       u8 reply[2];
-       unsigned retry;
-       int msg_bytes;
-       int reply_bytes = 1;
-       int ret;
-       u8 ack;
-
-       /* Set up the address */
-       msg[0] = address;
-       msg[1] = address >> 8;
-
-       /* Set up the command byte */
-       if (mode & MODE_I2C_READ) {
-               msg[2] = DP_AUX_I2C_READ << 4;
-               msg_bytes = 4;
-               msg[3] = msg_bytes << 4;
+       struct drm_device *dev = radeon_connector->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
+       int ret;
+       radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
+       radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
+       if (ASIC_IS_DCE5(rdev)) {
+               if (radeon_auxch)
+                       radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_native;
+               else
+                       radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom;
        } else {
-               msg[2] = DP_AUX_I2C_WRITE << 4;
-               msg_bytes = 5;
-               msg[3] = msg_bytes << 4;
-               msg[4] = write_byte;
+               radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom;
        }
 
-       /* special handling for start/stop */
-       if (mode & (MODE_I2C_START | MODE_I2C_STOP))
-               msg[3] = 3 << 4;
-
-       /* Set MOT bit for all but stop */
-       if ((mode & MODE_I2C_STOP) == 0)
-               msg[2] |= DP_AUX_I2C_MOT << 4;
-
-       for (retry = 0; retry < 7; retry++) {
-               ret = radeon_process_aux_ch(auxch,
-                                           msg, msg_bytes, reply, reply_bytes, 0, &ack);
-               if (ret == -EBUSY)
-                       continue;
-               else if (ret < 0) {
-                       DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
-                       return ret;
-               }
-
-               switch ((ack >> 4) & DP_AUX_NATIVE_REPLY_MASK) {
-               case DP_AUX_NATIVE_REPLY_ACK:
-                       /* I2C-over-AUX Reply field is only valid
-                        * when paired with AUX ACK.
-                        */
-                       break;
-               case DP_AUX_NATIVE_REPLY_NACK:
-                       DRM_DEBUG_KMS("aux_ch native nack\n");
-                       return -EREMOTEIO;
-               case DP_AUX_NATIVE_REPLY_DEFER:
-                       DRM_DEBUG_KMS("aux_ch native defer\n");
-                       usleep_range(500, 600);
-                       continue;
-               default:
-                       DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack);
-                       return -EREMOTEIO;
-               }
-
-               switch ((ack >> 4) & DP_AUX_I2C_REPLY_MASK) {
-               case DP_AUX_I2C_REPLY_ACK:
-                       if (mode == MODE_I2C_READ)
-                               *read_byte = reply[0];
-                       return (0);             /* XXX: why 0 and not msg size? */
-               case DP_AUX_I2C_REPLY_NACK:
-                       DRM_DEBUG_KMS("aux_i2c nack\n");
-                       return -EREMOTEIO;
-               case DP_AUX_I2C_REPLY_DEFER:
-                       DRM_DEBUG_KMS("aux_i2c defer\n");
-                       usleep_range(400, 500);
-                       break;
-               default:
-                       DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack);
-                       return -EREMOTEIO;
-               }
-       }
+       ret = drm_dp_aux_register(&radeon_connector->ddc_bus->aux);
+       if (!ret)
+               radeon_connector->ddc_bus->has_aux = true;
 
-       DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
-       return -EREMOTEIO;
+       WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret);
 }
 
 /***** general DP utility functions *****/
@@ -318,7 +255,7 @@ int radeon_dp_i2c_aux_ch(device_t dev, int mode, u8 write_byte, u8 *read_byte)
 #define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_LEVEL_3
 #define DP_PRE_EMPHASIS_MAX    DP_TRAIN_PRE_EMPH_LEVEL_3
 
-static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
+static void dp_get_adjust_train(const u8 link_status[DP_LINK_STATUS_SIZE],
                                int lane_count,
                                u8 train_set[4])
 {
@@ -365,77 +302,43 @@ static int convert_bpc_to_bpp(int bpc)
                return bpc * 3;
 }
 
-/* get the max pix clock supported by the link rate and lane num */
-static int dp_get_max_dp_pix_clock(int link_rate,
-                                  int lane_num,
-                                  int bpp)
-{
-       return (link_rate * lane_num * 8) / bpp;
-}
-
 /***** radeon specific DP functions *****/
 
-static int radeon_dp_get_max_link_rate(struct drm_connector *connector,
-                                      u8 dpcd[DP_DPCD_SIZE])
-{
-       int max_link_rate;
-
-       if (radeon_connector_is_dp12_capable(connector))
-               max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000);
-       else
-               max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000);
-
-       return max_link_rate;
-}
-
-/* First get the min lane# when low rate is used according to pixel clock
- * (prefer low rate), second check max lane# supported by DP panel,
- * if the max lane# < low rate lane# then use max lane# instead.
- */
-static int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
-                                       u8 dpcd[DP_DPCD_SIZE],
-                                       int pix_clock)
+int radeon_dp_get_dp_link_config(struct drm_connector *connector,
+                                const u8 dpcd[DP_DPCD_SIZE],
+                                unsigned pix_clock,
+                                unsigned *dp_lanes, unsigned *dp_rate)
 {
        int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
-       int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd);
-       int max_lane_num = drm_dp_max_lane_count(dpcd);
-       int lane_num;
-       int max_dp_pix_clock;
-
-       for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
-               max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp);
-               if (pix_clock <= max_dp_pix_clock)
-                       break;
-       }
-
-       return lane_num;
-}
-
-static int radeon_dp_get_dp_link_clock(struct drm_connector *connector,
-                                      u8 dpcd[DP_DPCD_SIZE],
-                                      int pix_clock)
-{
-       int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
-       int lane_num, max_pix_clock;
+       static const unsigned link_rates[3] = { 162000, 270000, 540000 };
+       unsigned max_link_rate = drm_dp_max_link_rate(dpcd);
+       unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
+       unsigned lane_num, i, max_pix_clock;
 
        if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
-           ENCODER_OBJECT_ID_NUTMEG)
-               return 270000;
-
-       lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock);
-       max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp);
-       if (pix_clock <= max_pix_clock)
-               return 162000;
-       max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp);
-       if (pix_clock <= max_pix_clock)
-               return 270000;
-       if (radeon_connector_is_dp12_capable(connector)) {
-               max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp);
-               if (pix_clock <= max_pix_clock)
-                       return 540000;
-       }
+           ENCODER_OBJECT_ID_NUTMEG) {
+               for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
+                       max_pix_clock = (lane_num * 270000 * 8) / bpp;
+                       if (max_pix_clock >= pix_clock) {
+                               *dp_lanes = lane_num;
+                               *dp_rate = 270000;
+                               return 0;
+                       }
+               }
+       } else {
+               for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
+                       for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
+                               max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
+                               if (max_pix_clock >= pix_clock) {
+                                       *dp_lanes = lane_num;
+                                       *dp_rate = link_rates[i];
+                                       return 0;
+                               }
+                       }
+               }
+       }
 
-       return radeon_dp_get_max_link_rate(connector, dpcd);
+       return -EINVAL;
 }
 
 static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
@@ -458,12 +361,11 @@ static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
 
 u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
 {
-       struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
        struct drm_device *dev = radeon_connector->base.dev;
        struct radeon_device *rdev = dev->dev_private;
 
        return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
-                                        dig_connector->dp_i2c_bus->rec.i2c_id, 0);
+                                        radeon_connector->ddc_bus->rec.i2c_id, 0);
 }
 
 static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
@@ -474,11 +376,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
        if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
                return;
 
-       if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_SINK_OUI, buf, 3) == 3)
+       if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3)
                DRM_DEBUG_KMS("Sink OUI: %02hhx%02hhx%02hhx\n",
                              buf[0], buf[1], buf[2]);
 
-       if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
+       if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
                DRM_DEBUG_KMS("Branch OUI: %02hhx%02hhx%02hhx\n",
                              buf[0], buf[1], buf[2]);
 }
@@ -487,21 +389,23 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
 {
        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
        u8 msg[DP_DPCD_SIZE];
-       int ret;
+       int ret, i;
 
        char dpcd_hex_dump[DP_DPCD_SIZE * 3];
 
-       ret = drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_DPCD_REV, msg,
-                              DP_DPCD_SIZE);
-       if (ret > 0) {
-               memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
-               DRM_DEBUG_KMS("DPCD: %s\n", hexncpy(dig_connector->dpcd,
-                             sizeof(dig_connector->dpcd),
-                             dpcd_hex_dump, sizeof(dpcd_hex_dump), " "));
+       for (i = 0; i < 7; i++) {
+               ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
+                                      DP_DPCD_SIZE);
+               if (ret == DP_DPCD_SIZE) {
+                       memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
+                       DRM_DEBUG_KMS("DPCD: %s\n", hexncpy(dig_connector->dpcd,
+                                     sizeof(dig_connector->dpcd),
+                                     dpcd_hex_dump, sizeof(dpcd_hex_dump), " "));
 
-               radeon_dp_probe_oui(radeon_connector);
+                       radeon_dp_probe_oui(radeon_connector);
 
-               return true;
+                       return true;
+               }
        }
        dig_connector->dpcd[0] = 0;
        return false;
@@ -528,7 +432,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
 
        if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
                /* DP bridge chips */
-               if (drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+               if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
                                      DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
                        if (tmp & 1)
                                panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
@@ -540,7 +444,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
                }
        } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
                /* eDP */
-               if (drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+               if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
                                      DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
                        if (tmp & 1)
                                panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
@@ -555,6 +459,7 @@ void radeon_dp_set_link_config(struct drm_connector *connector,
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        struct radeon_connector_atom_dig *dig_connector;
+       int ret;
 
        if (!radeon_connector->con_priv)
                return;
@@ -562,10 +467,14 @@ void radeon_dp_set_link_config(struct drm_connector *connector,
 
        if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
            (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
-               dig_connector->dp_clock =
-                       radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
-               dig_connector->dp_lane_count =
-                       radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock);
+               ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
+                                                  mode->clock,
+                                                  &dig_connector->dp_lane_count,
+                                                  &dig_connector->dp_clock);
+               if (ret) {
+                       dig_connector->dp_clock = 0;
+                       dig_connector->dp_lane_count = 0;
+               }
        }
 }
 
@@ -574,7 +483,8 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector,
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        struct radeon_connector_atom_dig *dig_connector;
-       int dp_clock;
+       unsigned dp_clock, dp_lanes;
+       int ret;
 
        if ((mode->clock > 340000) &&
            (!radeon_connector_is_dp12_capable(connector)))
@@ -584,8 +494,12 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector,
                return MODE_CLOCK_HIGH;
        dig_connector = radeon_connector->con_priv;
 
-       dp_clock =
-               radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
+       ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
+                                          mode->clock,
+                                          &dp_lanes,
+                                          &dp_clock);
+       if (ret)
+               return MODE_CLOCK_HIGH;
 
        if ((dp_clock == 540000) &&
            (!radeon_connector_is_dp12_capable(connector)))
@@ -599,7 +513,8 @@ bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
        u8 link_status[DP_LINK_STATUS_SIZE];
        struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
 
-       if (drm_dp_dpcd_read_link_status(&dig->dp_i2c_bus->aux, link_status) <= 0)
+       if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status)
+           <= 0)
                return false;
        if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
                return false;
@@ -619,7 +534,7 @@ void radeon_dp_set_rx_power_state(struct drm_connector *connector,
 
        /* power up/down the sink */
        if (dig_connector->dpcd[0] >= 0x11) {
-               drm_dp_dpcd_writeb(&dig_connector->dp_i2c_bus->aux,
+               drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux,
                                   DP_SET_POWER, power_state);
                usleep_range(1000, 2000);
        }
@@ -706,10 +621,8 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
                drm_dp_dpcd_writeb(dp_info->aux,
                                   DP_DOWNSPREAD_CTRL, 0);
 
-       if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
-           (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
-               drm_dp_dpcd_writeb(dp_info->aux, DP_EDP_CONFIGURATION_SET, 1);
-       }
+       if (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)
+               drm_dp_dpcd_writeb(dp_info->aux, DP_EDP_CONFIGURATION_SET, 1);
 
        /* set the lane count on the sink */
        tmp = dp_info->dp_lane_count;
@@ -923,7 +836,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
        else
                dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
 
-       if (drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, DP_MAX_LANE_COUNT, &tmp)
+       if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp)
            == 1) {
                if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
                        dp_info.tp3_supported = true;
@@ -939,7 +852,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
        dp_info.connector = connector;
        dp_info.dp_lane_count = dig_connector->dp_lane_count;
        dp_info.dp_clock = dig_connector->dp_clock;
-       dp_info.aux = &dig_connector->dp_i2c_bus->aux;
+       dp_info.aux = &radeon_connector->ddc_bus->aux;
 
        if (radeon_dp_link_train_init(&dp_info))
                goto done;
index ce2cae3..81adc91 100644 (file)
@@ -27,6 +27,7 @@
 #include <drm/drm_crtc_helper.h>
 #include <uapi_drm/radeon_drm.h>
 #include "radeon.h"
+#include "radeon_audio.h"
 #include "radeon_asic.h"
 #include "atom.h"
 
@@ -117,6 +118,7 @@ atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level)
                case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
                        if (dig->backlight_level == 0)
                                atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
                        else {
@@ -235,6 +237,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
        backlight_update_status(bd);
 
        DRM_INFO("radeon atom DIG backlight initialized\n");
+       rdev->mode_info.bl_encoder = radeon_encoder;
 
        return;
 
@@ -335,6 +338,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
        dig->backlight_level = radeon_atom_get_backlight_level_from_reg(rdev);
 
        DRM_INFO("radeon atom DIG backlight initialized\n");
+       rdev->mode_info.bl_encoder = radeon_encoder;
 
        SYSCTL_ADD_PROC(&drm_connector->dev->sysctl->ctx, &sysctl__hw_children,
                        OID_AUTO, "backlight_max",
@@ -375,6 +379,10 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
            && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
                adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
+       /* vertical FP must be at least 1 */
+       if (mode->crtc_vsync_start == mode->crtc_vdisplay)
+               adjusted_mode->crtc_vsync_start++;
+
        /* get the native mode for scaling */
        if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
                radeon_panel_mode_fixup(encoder, adjusted_mode);
@@ -731,6 +739,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
 int
 atombios_get_encoder_mode(struct drm_encoder *encoder)
 {
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_connector *connector;
        struct radeon_connector *radeon_connector;
@@ -795,6 +805,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
                dig_connector = radeon_connector->con_priv;
                if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
                    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
+                       if (radeon_audio != 0 &&
+                           drm_detect_monitor_audio(radeon_connector_edid(connector)) &&
+                           ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))
+                               return ATOM_ENCODER_MODE_DP_AUDIO;
                        return ATOM_ENCODER_MODE_DP;
                } else if (radeon_audio != 0) {
                        if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
@@ -809,6 +823,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
                }
                break;
        case DRM_MODE_CONNECTOR_eDP:
+               if (radeon_audio != 0 &&
+                   drm_detect_monitor_audio(radeon_connector_edid(connector)) &&
+                   ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))
+                       return ATOM_ENCODER_MODE_DP_AUDIO;
                return ATOM_ENCODER_MODE_DP;
        case DRM_MODE_CONNECTOR_DVIA:
        case DRM_MODE_CONNECTOR_VGA:
@@ -879,7 +897,7 @@ union dig_encoder_control {
 };
 
 void
-atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode)
+atombios_dig_encoder_setup2(struct drm_encoder *encoder, int action, int panel_mode, int enc_override)
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
@@ -939,8 +957,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
                        else
                                args.v1.ucLaneNum = 4;
 
-                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
-                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
                        switch (radeon_encoder->encoder_id) {
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                                args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
@@ -957,6 +973,10 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
                                args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
                        else
                                args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+
+                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
+                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+
                        break;
                case 2:
                case 3:
@@ -976,7 +996,10 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
 
                        if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode) && (dp_clock == 270000))
                                args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
-                       args.v3.acConfig.ucDigSel = dig->dig_encoder;
+                       if (enc_override != -1)
+                               args.v3.acConfig.ucDigSel = enc_override;
+                       else
+                               args.v3.acConfig.ucDigSel = dig->dig_encoder;
                        args.v3.ucBitPerColor = radeon_atom_get_bpc(encoder);
                        break;
                case 4:
@@ -1004,7 +1027,11 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
                                else
                                        args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ;
                        }
-                       args.v4.acConfig.ucDigSel = dig->dig_encoder;
+
+                       if (enc_override != -1)
+                               args.v4.acConfig.ucDigSel = enc_override;
+                       else
+                               args.v4.acConfig.ucDigSel = dig->dig_encoder;
                        args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder);
                        if (hpd_id == RADEON_HPD_NONE)
                                args.v4.ucHPD_ID = 0;
@@ -1025,6 +1052,12 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
 
 }
 
+void
+atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode)
+{
+       atombios_dig_encoder_setup2(encoder, action, panel_mode, -1);
+}
+
 union dig_transmitter_control {
        DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
        DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
@@ -1034,7 +1067,7 @@ union dig_transmitter_control {
 };
 
 void
-atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
+atombios_dig_transmitter_setup2(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set, int fe)
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
@@ -1384,7 +1417,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                                args.v5.asConfig.ucHPDSel = 0;
                        else
                                args.v5.asConfig.ucHPDSel = hpd_id + 1;
-                       args.v5.ucDigEncoderSel = 1 << dig_encoder;
+                       args.v5.ucDigEncoderSel = (fe != -1) ? (1 << fe) : (1 << dig_encoder);
                        args.v5.ucDPLaneSet = lane_set;
                        break;
                default:
@@ -1400,6 +1433,12 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+void
+atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
+{
+       atombios_dig_transmitter_setup2(encoder, action, lane_num, lane_set, -1);
+}
+
 bool
 atombios_set_edp_panel_power(struct drm_connector *connector, int action)
 {
@@ -1653,8 +1692,14 @@ radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode)
                } else
                        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
                if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                       args.ucAction = ATOM_LCD_BLON;
-                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       if (rdev->mode_info.bl_encoder) {
+                               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+                               atombios_set_backlight_level(radeon_encoder, dig->backlight_level);
+                       } else {
+                               args.ucAction = ATOM_LCD_BLON;
+                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       }
                }
                break;
        case DRM_MODE_DPMS_STANDBY:
@@ -1734,9 +1779,13 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
                        if (ASIC_IS_DCE4(rdev))
                                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
                }
-               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                       atombios_dig_transmitter_setup(encoder,
-                                                      ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                       if (rdev->mode_info.bl_encoder)
+                               atombios_set_backlight_level(radeon_encoder, dig->backlight_level);
+                       else
+                               atombios_dig_transmitter_setup(encoder,
+                                                              ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
+               }
                if (ext_encoder)
                        atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
                break;
@@ -1785,10 +1834,17 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       int encoder_mode = atombios_get_encoder_mode(encoder);
 
        DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
                  radeon_encoder->encoder_id, mode, radeon_encoder->devices,
                  radeon_encoder->active_device);
+
+       if ((radeon_audio != 0) &&
+           ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||
+            ENCODER_MODE_IS_DP(encoder_mode)))
+               radeon_audio_dpms(encoder, mode);
+
        switch (radeon_encoder->encoder_id) {
        case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -2050,7 +2106,14 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
        }
 }
 
-static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
+void radeon_atom_release_dig_encoder(struct radeon_device *rdev, int enc_idx)
+{
+       if (enc_idx < 0)
+               return;
+       rdev->mode_info.active_encoders &= ~(1 << enc_idx);
+}
+
+int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder, int fe_idx)
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
@@ -2059,71 +2122,79 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
        struct drm_encoder *test_encoder;
        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        uint32_t dig_enc_in_use = 0;
-
+       int enc_idx = -1;
+       if (fe_idx >= 0) {
+               enc_idx = fe_idx;
+               goto assigned;
+       }
        if (ASIC_IS_DCE6(rdev)) {
                /* DCE6 */
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                        if (dig->linkb)
-                               return 1;
+                               enc_idx = 1;
                        else
-                               return 0;
+                               enc_idx = 0;
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                        if (dig->linkb)
-                               return 3;
+                               enc_idx = 3;
                        else
-                               return 2;
+                               enc_idx = 2;
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
                        if (dig->linkb)
-                               return 5;
+                               enc_idx = 5;
                        else
-                               return 4;
+                               enc_idx = 4;
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
-                       return 6;
+                       enc_idx = 6;
                        break;
                }
+               goto assigned;
        } else if (ASIC_IS_DCE4(rdev)) {
                /* DCE4/5 */
                if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) {
                        /* ontario follows DCE4 */
                        if (rdev->family == CHIP_PALM) {
                                if (dig->linkb)
-                                       return 1;
+                                       enc_idx = 1;
                                else
-                                       return 0;
+                                       enc_idx = 0;
                        } else
                                /* llano follows DCE3.2 */
-                               return radeon_crtc->crtc_id;
+                               enc_idx = radeon_crtc->crtc_id;
                } else {
                        switch (radeon_encoder->encoder_id) {
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                                if (dig->linkb)
-                                       return 1;
+                                       enc_idx = 1;
                                else
-                                       return 0;
+                                       enc_idx = 0;
                                break;
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                                if (dig->linkb)
-                                       return 3;
+                                       enc_idx = 3;
                                else
-                                       return 2;
+                                       enc_idx = 2;
                                break;
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
                                if (dig->linkb)
-                                       return 5;
+                                       enc_idx = 5;
                                else
-                                       return 4;
+                                       enc_idx = 4;
                                break;
                        }
                }
+               goto assigned;
        }
 
        /* on DCE32 and encoder can driver any block so just crtc id */
        if (ASIC_IS_DCE32(rdev)) {
-               return radeon_crtc->crtc_id;
+               enc_idx = radeon_crtc->crtc_id;
+               goto assigned;
        }
 
        /* on DCE3 - LVTMA can only be driven by DIGB */
@@ -2151,6 +2222,17 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
        if (!(dig_enc_in_use & 1))
                return 0;
        return 1;
+
+assigned:
+       if (enc_idx == -1) {
+               DRM_ERROR("Got encoder index incorrect - returning 0\n");
+               return 0;
+       }
+       if (rdev->mode_info.active_encoders & (1 << enc_idx)) {
+               DRM_ERROR("chosen encoder in use %d\n", enc_idx);
+       }
+       rdev->mode_info.active_encoders |= (1 << enc_idx);
+       return enc_idx;
 }
 
 /* This only needs to be called once at startup */
@@ -2190,6 +2272,8 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+       int encoder_mode;
 
        radeon_encoder->pixel_clock = adjusted_mode->clock;
 
@@ -2238,12 +2322,11 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 
        atombios_apply_encoder_quirks(encoder, adjusted_mode);
 
-       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
-               if (rdev->asic->display.hdmi_enable)
-                       radeon_hdmi_enable(rdev, encoder, true);
-               if (rdev->asic->display.hdmi_setmode)
-                       radeon_hdmi_setmode(rdev, encoder, adjusted_mode);
-       }
+       encoder_mode = atombios_get_encoder_mode(encoder);
+       if (connector && (radeon_audio != 0) &&
+           ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||
+            ENCODER_MODE_IS_DP(encoder_mode)))
+               radeon_audio_mode_set(encoder, adjusted_mode);
 }
 
 static bool
@@ -2407,7 +2490,9 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
             ENCODER_OBJECT_ID_NONE)) {
                struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
                if (dig) {
-                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
+                       if (dig->dig_encoder >= 0)
+                               radeon_atom_release_dig_encoder(rdev, dig->dig_encoder);
+                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder, -1);
                        if (radeon_encoder->active_device & ATOM_DEVICE_DFP_SUPPORT) {
                                if (rdev->family >= CHIP_R600)
                                        dig->afmt = rdev->mode_info.afmt[dig->dig_encoder];
@@ -2508,15 +2593,19 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
        }
 
 disable_done:
-       if (radeon_encoder_is_digital(encoder)) {
+       if (radeon_encoder_is_digital(encoder)) {
                if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
                        if (rdev->asic->display.hdmi_enable)
                                radeon_hdmi_enable(rdev, encoder, false);
                }
-               dig = radeon_encoder->enc_priv;
-               dig->dig_encoder = -1;
-       }
-       radeon_encoder->active_device = 0;
+               if (atombios_get_encoder_mode(encoder) != ATOM_ENCODER_MODE_DP_MST) {
+                       dig = radeon_encoder->enc_priv;
+                       radeon_atom_release_dig_encoder(rdev, dig->dig_encoder);
+                       dig->dig_encoder = -1;
+                       radeon_encoder->active_device = 0;
+               }
+       } else
+               radeon_encoder->active_device = 0;
 }
 
 /* these are handled by the primary encoders */
index 9a0e945..dda824a 100644 (file)
@@ -40,6 +40,8 @@
 #define ATOM_MAX_HW_I2C_WRITE 3
 #define ATOM_MAX_HW_I2C_READ  255
 
+int radeon_atom_hw_i2c_xfer(device_t dev, struct iic_msg *msgs, u_int num);
+
 static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
                                 u8 slave_addr, u8 flags,
                                 u8 *buf, u8 num)
@@ -54,8 +56,8 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
 
        memset(&args, 0, sizeof(args));
 
-       lockmgr(&chan->mutex, LK_EXCLUSIVE);
-       lockmgr(&rdev->mode_info.atom_context->scratch_mutex, LK_EXCLUSIVE);
+       mutex_lock(&chan->mutex);
+       mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
 
        base = (unsigned char *)rdev->mode_info.atom_context->scratch;
 
@@ -103,14 +105,13 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
                radeon_atom_copy_swap(buf, base, num, false);
 
 done:
-       lockmgr(&rdev->mode_info.atom_context->scratch_mutex, LK_RELEASE);
-       lockmgr(&chan->mutex, LK_RELEASE);
+       mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
+       mutex_unlock(&chan->mutex);
 
        return r;
 }
 
-static int
-radeon_atom_hw_i2c_xfer(device_t dev, struct iic_msg *msgs, u_int num)
+int radeon_atom_hw_i2c_xfer(device_t dev, struct iic_msg *msgs, u_int num)
 {
        struct radeon_i2c_chan *i2c = device_get_softc(dev);
        struct iic_msg *p;
index 9f4a805..81c2802 100644 (file)
@@ -30,6 +30,7 @@
 #include "cypress_dpm.h"
 #include "btc_dpm.h"
 #include "atom.h"
+#include <linux/seq_file.h>
 
 #define MC_CG_ARB_FREQ_F0           0x0a
 #define MC_CG_ARB_FREQ_F1           0x0b
@@ -1160,8 +1161,7 @@ u32 btc_valid_sclk[40] =
        155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
 };
 
-static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
-{
+static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = {
         { 10000, 30000, RADEON_SCLK_UP },
         { 15000, 30000, RADEON_SCLK_UP },
         { 20000, 30000, RADEON_SCLK_UP },
@@ -2748,13 +2748,54 @@ void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
                else /* current_index == 2 */
                        pl = &ps->high;
                seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
-               if (rdev->family >= CHIP_CEDAR) {
-                       seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
-                                  current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
-               } else {
-                       seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u\n",
-                                  current_index, pl->sclk, pl->mclk, pl->vddc);
-               }
+               seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
+                          current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+       }
+}
+
+u32 btc_dpm_get_current_sclk(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct radeon_ps *rps = &eg_pi->current_rps;
+       struct rv7xx_ps *ps = rv770_get_ps(rps);
+       struct rv7xx_pl *pl;
+       u32 current_index =
+               (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
+               CURRENT_PROFILE_INDEX_SHIFT;
+
+       if (current_index > 2) {
+               return 0;
+       } else {
+               if (current_index == 0)
+                       pl = &ps->low;
+               else if (current_index == 1)
+                       pl = &ps->medium;
+               else /* current_index == 2 */
+                       pl = &ps->high;
+               return pl->sclk;
+       }
+}
+
+u32 btc_dpm_get_current_mclk(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct radeon_ps *rps = &eg_pi->current_rps;
+       struct rv7xx_ps *ps = rv770_get_ps(rps);
+       struct rv7xx_pl *pl;
+       u32 current_index =
+               (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
+               CURRENT_PROFILE_INDEX_SHIFT;
+
+       if (current_index > 2) {
+               return 0;
+       } else {
+               if (current_index == 0)
+                       pl = &ps->low;
+               else if (current_index == 1)
+                       pl = &ps->medium;
+               else /* current_index == 2 */
+                       pl = &ps->high;
+               return pl->mclk;
        }
 }
 
index 98d009e..9fec4d0 100644 (file)
@@ -32,7 +32,7 @@
  * evergreen cards need to use the 3D engine to blit data which requires
  * quite a bit of hw state setup.  Rather than pull the whole 3D driver
  * (which normally generates the 3D state) into the DRM, we opt to use
- * statically generated state tables.  The regsiter state and shaders
+ * statically generated state tables.  The register state and shaders
  * were hand generated to support blitting functionality.  See the 3D
  * driver or documentation for descriptions of the registers and
  * shader instructions.
index c799335..7d7b34e 100644 (file)
 static const struct ci_pt_defaults defaults_hawaii_xt =
 {
        1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0xB0000,
-       { 0x84,  0x0,   0x0,   0x7F,  0x0,   0x0,   0x5A,  0x60,  0x51,  0x8E,  0x79,  0x6B,  0x5F,  0x90,  0x79  },
-       { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC }
+       { 0x2E,  0x00,  0x00,  0x88,  0x00,  0x00,  0x72,  0x60,  0x51,  0xA7,  0x79,  0x6B,  0x90,  0xBD,  0x79  },
+       { 0x217, 0x217, 0x217, 0x242, 0x242, 0x242, 0x269, 0x269, 0x269, 0x2A1, 0x2A1, 0x2A1, 0x2C9, 0x2C9, 0x2C9 }
 };
 
 static const struct ci_pt_defaults defaults_hawaii_pro =
 {
        1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0x65062,
-       { 0x93,  0x0,   0x0,   0x97,  0x0,   0x0,   0x6B,  0x60,  0x51,  0x95,  0x79,  0x6B,  0x5F,  0x90,  0x79  },
-       { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC }
+       { 0x2E,  0x00,  0x00,  0x88,  0x00,  0x00,  0x72,  0x60,  0x51,  0xA7,  0x79,  0x6B,  0x90,  0xBD,  0x79  },
+       { 0x217, 0x217, 0x217, 0x242, 0x242, 0x242, 0x269, 0x269, 0x269, 0x2A1, 0x2A1, 0x2A1, 0x2C9, 0x2C9, 0x2C9 }
 };
 
 static const struct ci_pt_defaults defaults_bonaire_xt =
@@ -171,6 +171,12 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev,
                                       u32 target_tdp);
 static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate);
 
+static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
+                                                     PPSMC_Msg msg, u32 parameter);
+
+static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev);
+static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev);
+
 static struct ci_power_info *ci_get_pi(struct radeon_device *rdev)
 {
         struct ci_power_info *pi = rdev->pm.dpm.priv;
@@ -236,7 +242,10 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev)
 
        if (pi->caps_power_containment) {
                pi->caps_cac = true;
-               pi->enable_bapm_feature = true;
+               if (rdev->family == CHIP_HAWAII)
+                       pi->enable_bapm_feature = false;
+               else
+                       pi->enable_bapm_feature = true;
                pi->enable_tdc_limit_feature = true;
                pi->enable_pkg_pwr_tracking_feature = true;
        }
@@ -339,6 +348,21 @@ static int ci_populate_dw8(struct radeon_device *rdev)
        return 0;
 }
 
+static int ci_populate_fuzzy_fan(struct radeon_device *rdev)
+{
+       struct ci_power_info *pi = ci_get_pi(rdev);
+
+       if ((rdev->pm.dpm.fan.fan_output_sensitivity & (1 << 15)) ||
+           (rdev->pm.dpm.fan.fan_output_sensitivity == 0))
+               rdev->pm.dpm.fan.fan_output_sensitivity =
+                       rdev->pm.dpm.fan.default_fan_output_sensitivity;
+
+       pi->smc_powertune_table.FuzzyFan_PwmSetDelta =
+               cpu_to_be16(rdev->pm.dpm.fan.fan_output_sensitivity);
+
+       return 0;
+}
+
 static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct radeon_device *rdev)
 {
        struct ci_power_info *pi = ci_get_pi(rdev);
@@ -462,6 +486,9 @@ static int ci_populate_pm_base(struct radeon_device *rdev)
                if (ret)
                        return ret;
                ret = ci_populate_dw8(rdev);
+               if (ret)
+                       return ret;
+               ret = ci_populate_fuzzy_fan(rdev);
                if (ret)
                        return ret;
                ret = ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(rdev);
@@ -677,6 +704,25 @@ static int ci_enable_smc_cac(struct radeon_device *rdev, bool enable)
        return ret;
 }
 
+static int ci_enable_thermal_based_sclk_dpm(struct radeon_device *rdev,
+                                           bool enable)
+{
+       struct ci_power_info *pi = ci_get_pi(rdev);
+       PPSMC_Result smc_result = PPSMC_Result_OK;
+
+       if (pi->thermal_sclk_dpm_enabled) {
+               if (enable)
+                       smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_ENABLE_THERMAL_DPM);
+               else
+                       smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_DISABLE_THERMAL_DPM);
+       }
+
+       if (smc_result == PPSMC_Result_OK)
+               return 0;
+       else
+               return -EINVAL;
+}
+
 static int ci_power_control_set_level(struct radeon_device *rdev)
 {
        struct ci_power_info *pi = ci_get_pi(rdev);
@@ -687,13 +733,11 @@ static int ci_power_control_set_level(struct radeon_device *rdev)
        int ret = 0;
        bool adjust_polarity = false; /* ??? */
 
-       if (pi->caps_power_containment &&
-           (pi->power_containment_features & POWERCONTAINMENT_FEATURE_BAPM)) {
+       if (pi->caps_power_containment) {
                adjust_percent = adjust_polarity ?
                        rdev->pm.dpm.tdp_adjustment : (-1 * rdev->pm.dpm.tdp_adjustment);
                target_tdp = ((100 + adjust_percent) *
                              (s32)cac_tdp_table->configurable_tdp) / 100;
-               target_tdp *= 256;
 
                ret = ci_set_overdrive_target_tdp(rdev, (u32)target_tdp);
        }
@@ -801,7 +845,7 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev,
        }
 }
 
-static int ci_set_thermal_temperature_range(struct radeon_device *rdev,
+static int ci_thermal_set_temperature_range(struct radeon_device *rdev,
                                            int min_temp, int max_temp)
 {
        int low_temp = 0 * 1000;
@@ -837,6 +881,380 @@ static int ci_set_thermal_temperature_range(struct radeon_device *rdev,
        return 0;
 }
 
+static int ci_thermal_enable_alert(struct radeon_device *rdev,
+                                  bool enable)
+{
+       u32 thermal_int = RREG32_SMC(CG_THERMAL_INT);
+       PPSMC_Result result;
+
+       if (enable) {
+               thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+               WREG32_SMC(CG_THERMAL_INT, thermal_int);
+               rdev->irq.dpm_thermal = false;
+               result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable);
+               if (result != PPSMC_Result_OK) {
+                       DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
+                       return -EINVAL;
+               }
+       } else {
+               thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
+               WREG32_SMC(CG_THERMAL_INT, thermal_int);
+               rdev->irq.dpm_thermal = true;
+               result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable);
+               if (result != PPSMC_Result_OK) {
+                       DRM_DEBUG_KMS("Could not disable thermal interrupts.\n");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static void ci_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode)
+{
+       struct ci_power_info *pi = ci_get_pi(rdev);
+       u32 tmp;
+
+       if (pi->fan_ctrl_is_in_default_mode) {
+               tmp = (RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT;
+               pi->fan_ctrl_default_mode = tmp;
+               tmp = (RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT;
+               pi->t_min = tmp;
+               pi->fan_ctrl_is_in_default_mode = false;
+       }
+
+       tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TMIN_MASK;
+       tmp |= TMIN(0);
+       WREG32_SMC(CG_FDO_CTRL2, tmp);
+
+       tmp = RREG32_SMC(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
+       tmp |= FDO_PWM_MODE(mode);
+       WREG32_SMC(CG_FDO_CTRL2, tmp);
+}
+
+static int ci_thermal_setup_fan_table(struct radeon_device *rdev)
+{
+       struct ci_power_info *pi = ci_get_pi(rdev);
+       SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
+       u32 duty100;
+       u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2;
+       u16 fdo_min, slope1, slope2;
+       u32 reference_clock, tmp;
+       int ret;
+       u64 tmp64;
+
+       if (!pi->fan_table_start) {
+               rdev->pm.dpm.fan.ucode_fan_control = false;
+               return 0;
+       }
+
+       duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
+
+       if (duty100 == 0) {
+               rdev->pm.dpm.fan.ucode_fan_control = false;
+               return 0;
+       }
+
+       tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100;
+       do_div(tmp64, 10000);
+       fdo_min = (u16)tmp64;
+
+       t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min;
+       t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med;
+
+       pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min;
+       pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med;
+
+       slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
+       slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
+
+       fan_table.TempMin = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100);
+       fan_table.TempMed = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100);
+       fan_table.TempMax = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100);
+
+       fan_table.Slope1 = cpu_to_be16(slope1);
+       fan_table.Slope2 = cpu_to_be16(slope2);
+
+       fan_table.FdoMin = cpu_to_be16(fdo_min);
+
+       fan_table.HystDown = cpu_to_be16(rdev->pm.dpm.fan.t_hyst);
+
+       fan_table.HystUp = cpu_to_be16(1);
+
+       fan_table.HystSlope = cpu_to_be16(1);
+
+       fan_table.TempRespLim = cpu_to_be16(5);
+
+       reference_clock = radeon_get_xclk(rdev);
+
+       fan_table.RefreshPeriod = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay *
+                                              reference_clock) / 1600);
+
+       fan_table.FdoMax = cpu_to_be16((u16)duty100);
+
+       tmp = (RREG32_SMC(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT;
+       fan_table.TempSrc = (uint8_t)tmp;
+
+       ret = ci_copy_bytes_to_smc(rdev,
+                                  pi->fan_table_start,
+                                  (u8 *)(&fan_table),
+                                  sizeof(fan_table),
+                                  pi->sram_end);
+
+       if (ret) {
+               DRM_ERROR("Failed to load fan table to the SMC.");
+               rdev->pm.dpm.fan.ucode_fan_control = false;
+       }
+
+       return 0;
+}
+
+static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev)
+{
+       struct ci_power_info *pi = ci_get_pi(rdev);
+       PPSMC_Result ret;
+
+       if (pi->caps_od_fuzzy_fan_control_support) {
+               ret = ci_send_msg_to_smc_with_parameter(rdev,
+                                                       PPSMC_StartFanControl,
+                                                       FAN_CONTROL_FUZZY);
+               if (ret != PPSMC_Result_OK)
+                       return -EINVAL;
+               ret = ci_send_msg_to_smc_with_parameter(rdev,
+                                                       PPSMC_MSG_SetFanPwmMax,
+                                                       rdev->pm.dpm.fan.default_max_fan_pwm);
+               if (ret != PPSMC_Result_OK)
+                       return -EINVAL;
+       } else {
+               ret = ci_send_msg_to_smc_with_parameter(rdev,
+                                                       PPSMC_StartFanControl,
+                                                       FAN_CONTROL_TABLE);
+               if (ret != PPSMC_Result_OK)
+                       return -EINVAL;
+       }
+
+       pi->fan_is_controlled_by_smc = true; 
+       return 0;
+}
+
+static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev)
+{
+       PPSMC_Result ret;
+       struct ci_power_info *pi = ci_get_pi(rdev);
+
+       ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl);
+       if (ret == PPSMC_Result_OK) {
+               pi->fan_is_controlled_by_smc = false;
+               return 0;
+       } else
+               return -EINVAL;
+}
+
+int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
+                                            u32 *speed)
+{
+       u32 duty, duty100;
+       u64 tmp64;
+
+       if (rdev->pm.no_fan)
+               return -ENOENT;
+
+       duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
+       duty = (RREG32_SMC(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT;
+
+       if (duty100 == 0)
+               return -EINVAL;
+
+       tmp64 = (u64)duty * 100;
+       do_div(tmp64, duty100);
+       *speed = (u32)tmp64;
+
+       if (*speed > 100)
+               *speed = 100;
+
+       return 0;
+}
+
+int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
+                                            u32 speed)
+{
+       u32 tmp;
+       u32 duty, duty100;
+       u64 tmp64;
+       struct ci_power_info *pi = ci_get_pi(rdev);
+
+       if (rdev->pm.no_fan)
+               return -ENOENT;
+
+       if (pi->fan_is_controlled_by_smc)
+               return -EINVAL;
+
+       if (speed > 100)
+               return -EINVAL;
+
+       duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
+
+       if (duty100 == 0)
+               return -EINVAL;
+
+       tmp64 = (u64)speed * duty100;
+       do_div(tmp64, 100);
+       duty = (u32)tmp64;
+
+       tmp = RREG32_SMC(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK;
+       tmp |= FDO_STATIC_DUTY(duty);
+       WREG32_SMC(CG_FDO_CTRL0, tmp);
+
+       return 0;
+}
+
+void ci_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode)
+{
+       if (mode) {
+               /* stop auto-manage */
+               if (rdev->pm.dpm.fan.ucode_fan_control)
+                       ci_fan_ctrl_stop_smc_fan_control(rdev);
+               ci_fan_ctrl_set_static_mode(rdev, mode);
+       } else {
+               /* restart auto-manage */
+               if (rdev->pm.dpm.fan.ucode_fan_control)
+                       ci_thermal_start_smc_fan_control(rdev);
+               else
+                       ci_fan_ctrl_set_default_mode(rdev);
+       }
+}
+
+u32 ci_fan_ctrl_get_mode(struct radeon_device *rdev)
+{
+       struct ci_power_info *pi = ci_get_pi(rdev);
+       u32 tmp;
+
+       if (pi->fan_is_controlled_by_smc)
+               return 0;
+
+       tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK;
+       return (tmp >> FDO_PWM_MODE_SHIFT);
+}
+
+#if 0
+static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev,
+                                        u32 *speed)
+{
+       u32 tach_period;
+       u32 xclk = radeon_get_xclk(rdev);
+
+       if (rdev->pm.no_fan)
+               return -ENOENT;
+
+       if (rdev->pm.fan_pulses_per_revolution == 0)
+               return -ENOENT;
+
+       tach_period = (RREG32_SMC(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT;
+       if (tach_period == 0)
+               return -ENOENT;
+
+       *speed = 60 * xclk * 10000 / tach_period;
+
+       return 0;
+}
+
+static int ci_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev,
+                                        u32 speed)
+{
+       u32 tach_period, tmp;
+       u32 xclk = radeon_get_xclk(rdev);
+
+       if (rdev->pm.no_fan)
+               return -ENOENT;
+
+       if (rdev->pm.fan_pulses_per_revolution == 0)
+               return -ENOENT;
+
+       if ((speed < rdev->pm.fan_min_rpm) ||
+           (speed > rdev->pm.fan_max_rpm))
+               return -EINVAL;
+
+       if (rdev->pm.dpm.fan.ucode_fan_control)
+               ci_fan_ctrl_stop_smc_fan_control(rdev);
+
+       tach_period = 60 * xclk * 10000 / (8 * speed);
+       tmp = RREG32_SMC(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK;
+       tmp |= TARGET_PERIOD(tach_period);
+       WREG32_SMC(CG_TACH_CTRL, tmp);
+
+       ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC_RPM);
+
+       return 0;
+}
+#endif
+
+static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev)
+{
+       struct ci_power_info *pi = ci_get_pi(rdev);
+       u32 tmp;
+
+       if (!pi->fan_ctrl_is_in_default_mode) {
+               tmp = RREG32_SMC(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
+               tmp |= FDO_PWM_MODE(pi->fan_ctrl_default_mode);
+               WREG32_SMC(CG_FDO_CTRL2, tmp);
+
+               tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TMIN_MASK;
+               tmp |= TMIN(pi->t_min);
+               WREG32_SMC(CG_FDO_CTRL2, tmp);
+               pi->fan_ctrl_is_in_default_mode = true;
+       }
+}
+
+static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev)
+{
+       if (rdev->pm.dpm.fan.ucode_fan_control) {
+               ci_fan_ctrl_start_smc_fan_control(rdev);
+               ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
+       }
+}
+
+static void ci_thermal_initialize(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       if (rdev->pm.fan_pulses_per_revolution) {
+               tmp = RREG32_SMC(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK;
+               tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1);
+               WREG32_SMC(CG_TACH_CTRL, tmp);
+       }
+
+       tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK;
+       tmp |= TACH_PWM_RESP_RATE(0x28);
+       WREG32_SMC(CG_FDO_CTRL2, tmp);
+}
+
+static int ci_thermal_start_thermal_controller(struct radeon_device *rdev)
+{
+       int ret;
+
+       ci_thermal_initialize(rdev);
+       ret = ci_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+       if (ret)
+               return ret;
+       ret = ci_thermal_enable_alert(rdev, true);
+       if (ret)
+               return ret;
+       if (rdev->pm.dpm.fan.ucode_fan_control) {
+               ret = ci_thermal_setup_fan_table(rdev);
+               if (ret)
+                       return ret;
+               ci_thermal_start_smc_fan_control(rdev);
+       }
+
+       return 0;
+}
+
+static void ci_thermal_stop_thermal_controller(struct radeon_device *rdev)
+{
+       if (!rdev->pm.no_fan)
+               ci_fan_ctrl_set_default_mode(rdev);
+}
+
 #if 0
 static int ci_read_smc_soft_register(struct radeon_device *rdev,
                                     u16 reg_offset, u32 *value)
@@ -1240,7 +1658,7 @@ static int ci_dpm_force_state_sclk(struct radeon_device *rdev, u32 n)
 
        if (!pi->sclk_dpm_key_disabled) {
                PPSMC_Result smc_result =
-                       ci_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, n);
+                       ci_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SCLKDPM_SetEnabledMask, 1 << n);
                if (smc_result != PPSMC_Result_OK)
                        return -EINVAL;
        }
@@ -1254,7 +1672,7 @@ static int ci_dpm_force_state_mclk(struct radeon_device *rdev, u32 n)
 
        if (!pi->mclk_dpm_key_disabled) {
                PPSMC_Result smc_result =
-                       ci_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_MCLKDPM_ForceState, n);
+                       ci_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_MCLKDPM_SetEnabledMask, 1 << n);
                if (smc_result != PPSMC_Result_OK)
                        return -EINVAL;
        }
@@ -2031,6 +2449,33 @@ static int ci_force_switch_to_arb_f0(struct radeon_device *rdev)
        return ni_copy_and_switch_arb_sets(rdev, tmp, MC_CG_ARB_FREQ_F0);
 }
 
+static void ci_register_patching_mc_arb(struct radeon_device *rdev,
+                                       const u32 engine_clock,
+                                       const u32 memory_clock,
+                                       u32 *dram_timimg2)
+{
+       bool patch;
+       u32 tmp, tmp2;
+
+       tmp = RREG32(MC_SEQ_MISC0);
+       patch = ((tmp & 0x0000f00) == 0x300) ? true : false;
+
+       if (patch &&
+           ((rdev->pdev->device == 0x67B0) ||
+            (rdev->pdev->device == 0x67B1))) {
+               if ((memory_clock > 100000) && (memory_clock <= 125000)) {
+                       tmp2 = (((0x31 * engine_clock) / 125000) - 1) & 0xff;
+                       *dram_timimg2 &= ~0x00ff0000;
+                       *dram_timimg2 |= tmp2 << 16;
+               } else if ((memory_clock > 125000) && (memory_clock <= 137500)) {
+                       tmp2 = (((0x36 * engine_clock) / 137500) - 1) & 0xff;
+                       *dram_timimg2 &= ~0x00ff0000;
+                       *dram_timimg2 |= tmp2 << 16;
+               }
+       }
+}
+
+
 static int ci_populate_memory_timing_parameters(struct radeon_device *rdev,
                                                u32 sclk,
                                                u32 mclk,
@@ -2046,6 +2491,8 @@ static int ci_populate_memory_timing_parameters(struct radeon_device *rdev,
        dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
        burst_time = RREG32(MC_ARB_BURST_TIME) & STATE0_MASK;
 
+       ci_register_patching_mc_arb(rdev, sclk, mclk, &dram_timing2);
+
        arb_regs->McArbDramTiming  = cpu_to_be32(dram_timing);
        arb_regs->McArbDramTiming2 = cpu_to_be32(dram_timing2);
        arb_regs->McArbBurstTime = (u8)burst_time;
@@ -2340,10 +2787,10 @@ static int ci_calculate_mclk_params(struct radeon_device *rdev,
                u32 tmp;
                u32 reference_clock = rdev->clock.mpll.reference_freq;
 
-               if (pi->mem_gddr5)
-                       freq_nom = memory_clock * 4;
+               if (mpll_param.qdr == 1)
+                       freq_nom = memory_clock * 4 * (1 << mpll_param.post_div);
                else
-                       freq_nom = memory_clock * 2;
+                       freq_nom = memory_clock * 2 * (1 << mpll_param.post_div);
 
                tmp = (freq_nom / reference_clock);
                tmp = tmp * tmp;
@@ -2423,7 +2870,6 @@ static int ci_populate_single_memory_level(struct radeon_device *rdev,
                                                      &memory_level->MinVddcPhases);
 
        memory_level->EnabledForThrottle = 1;
-       memory_level->EnabledForActivity = 1;
        memory_level->UpH = 0;
        memory_level->DownH = 100;
        memory_level->VoltageDownH = 0;
@@ -2756,7 +3202,6 @@ static int ci_populate_single_graphic_level(struct radeon_device *rdev,
 
        graphic_level->CcPwrDynRm = 0;
        graphic_level->CcPwrDynRm1 = 0;
-       graphic_level->EnabledForActivity = 1;
        graphic_level->EnabledForThrottle = 1;
        graphic_level->UpH = 0;
        graphic_level->DownH = 0;
@@ -2805,10 +3250,13 @@ static int ci_populate_all_graphic_levels(struct radeon_device *rdev)
                                                       &pi->smc_state_table.GraphicsLevel[i]);
                if (ret)
                        return ret;
+               if (i > 1)
+                       pi->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0;
                if (i == (dpm_table->sclk_table.count - 1))
                        pi->smc_state_table.GraphicsLevel[i].DisplayWatermark =
                                PPSMC_DISPLAY_WATERMARK_HIGH;
        }
+       pi->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1;
 
        pi->smc_state_table.GraphicsDpmLevelCount = (u8)dpm_table->sclk_table.count;
        pi->dpm_level_enable_mask.sclk_dpm_enable_mask =
@@ -2852,6 +3300,16 @@ static int ci_populate_all_memory_levels(struct radeon_device *rdev)
                        return ret;
        }
 
+       pi->smc_state_table.MemoryLevel[0].EnabledForActivity = 1;
+
+       if ((dpm_table->mclk_table.count >= 2) &&
+           ((rdev->pdev->device == 0x67B0) || (rdev->pdev->device == 0x67B1))) {
+               pi->smc_state_table.MemoryLevel[1].MinVddc =
+                       pi->smc_state_table.MemoryLevel[0].MinVddc;
+               pi->smc_state_table.MemoryLevel[1].MinVddcPhases =
+                       pi->smc_state_table.MemoryLevel[0].MinVddcPhases;
+       }
+
        pi->smc_state_table.MemoryLevel[0].ActivityLevel = cpu_to_be16(0x1F);
 
        pi->smc_state_table.MemoryDpmLevelCount = (u8)dpm_table->mclk_table.count;
@@ -2908,9 +3366,14 @@ static int ci_setup_default_pcie_tables(struct radeon_device *rdev)
                                  &pi->dpm_table.pcie_speed_table,
                                  SMU7_MAX_LEVELS_LINK);
 
-       ci_setup_pcie_table_entry(&pi->dpm_table.pcie_speed_table, 0,
-                                 pi->pcie_gen_powersaving.min,
-                                 pi->pcie_lane_powersaving.min);
+       if (rdev->family == CHIP_BONAIRE)
+               ci_setup_pcie_table_entry(&pi->dpm_table.pcie_speed_table, 0,
+                                         pi->pcie_gen_powersaving.min,
+                                         pi->pcie_lane_powersaving.max);
+       else
+               ci_setup_pcie_table_entry(&pi->dpm_table.pcie_speed_table, 0,
+                                         pi->pcie_gen_powersaving.min,
+                                         pi->pcie_lane_powersaving.min);
        ci_setup_pcie_table_entry(&pi->dpm_table.pcie_speed_table, 1,
                                  pi->pcie_gen_performance.min,
                                  pi->pcie_lane_performance.min);
@@ -2977,19 +3440,21 @@ static int ci_setup_default_dpm_tables(struct radeon_device *rdev)
                     allowed_sclk_vddc_table->entries[i].clk)) {
                        pi->dpm_table.sclk_table.dpm_levels[pi->dpm_table.sclk_table.count].value =
                                allowed_sclk_vddc_table->entries[i].clk;
-                       pi->dpm_table.sclk_table.dpm_levels[pi->dpm_table.sclk_table.count].enabled = true;
+                       pi->dpm_table.sclk_table.dpm_levels[pi->dpm_table.sclk_table.count].enabled =
+                               (i == 0) ? true : false;
                        pi->dpm_table.sclk_table.count++;
                }
        }
 
        pi->dpm_table.mclk_table.count = 0;
        for (i = 0; i < allowed_mclk_table->count; i++) {
-               if ((i==0) ||
+               if ((i == 0) ||
                    (pi->dpm_table.mclk_table.dpm_levels[pi->dpm_table.mclk_table.count-1].value !=
                     allowed_mclk_table->entries[i].clk)) {
                        pi->dpm_table.mclk_table.dpm_levels[pi->dpm_table.mclk_table.count].value =
                                allowed_mclk_table->entries[i].clk;
-                       pi->dpm_table.mclk_table.dpm_levels[pi->dpm_table.mclk_table.count].enabled = true;
+                       pi->dpm_table.mclk_table.dpm_levels[pi->dpm_table.mclk_table.count].enabled =
+                               (i == 0) ? true : false;
                        pi->dpm_table.mclk_table.count++;
                }
        }
@@ -3155,7 +3620,7 @@ static int ci_init_smc_table(struct radeon_device *rdev)
        table->VddcVddciDelta = 4000;
        table->PhaseResponseTime = 0;
        table->MemoryThermThrottleEnable = 1;
-       table->PCIeBootLinkLevel = 0;
+       table->PCIeBootLinkLevel = pi->dpm_table.pcie_speed_table.count - 1;
        table->PCIeGenInterval = 1;
        if (pi->voltage_control == CISLANDS_VOLTAGE_CONTROL_BY_SVID2)
                table->SVI2Enable  = 1;
@@ -3309,6 +3774,8 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev)
        struct ci_power_info *pi = ci_get_pi(rdev);
        PPSMC_Result result;
 
+       ci_apply_disp_minimum_voltage_request(rdev);
+
        if (!pi->sclk_dpm_key_disabled) {
                if (pi->dpm_level_enable_mask.sclk_dpm_enable_mask) {
                        result = ci_send_msg_to_smc_with_parameter(rdev,
@@ -3328,7 +3795,7 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev)
                                return -EINVAL;
                }
        }
-
+#if 0
        if (!pi->pcie_dpm_key_disabled) {
                if (pi->dpm_level_enable_mask.pcie_dpm_enable_mask) {
                        result = ci_send_msg_to_smc_with_parameter(rdev,
@@ -3338,9 +3805,7 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev)
                                return -EINVAL;
                }
        }
-
-       ci_apply_disp_minimum_voltage_request(rdev);
-
+#endif
        return 0;
 }
 
@@ -3366,7 +3831,7 @@ static void ci_find_dpm_states_clocks_in_dpm_table(struct radeon_device *rdev,
                pi->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
        } else {
                /* XXX check display min clock requirements */
-               if (0 != CISLAND_MINIMUM_ENGINE_CLOCK)
+               if (CISLAND_MINIMUM_ENGINE_CLOCK != CISLAND_MINIMUM_ENGINE_CLOCK)
                        pi->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK;
        }
 
@@ -3696,62 +4161,61 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev,
                                   enum radeon_dpm_forced_level level)
 {
        struct ci_power_info *pi = ci_get_pi(rdev);
-       PPSMC_Result smc_result;
        u32 tmp, levels, i;
        int ret;
 
        if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
-               if ((!pi->sclk_dpm_key_disabled) &&
-                   pi->dpm_level_enable_mask.sclk_dpm_enable_mask) {
+               if ((!pi->pcie_dpm_key_disabled) &&
+                   pi->dpm_level_enable_mask.pcie_dpm_enable_mask) {
                        levels = 0;
-                       tmp = pi->dpm_level_enable_mask.sclk_dpm_enable_mask;
+                       tmp = pi->dpm_level_enable_mask.pcie_dpm_enable_mask;
                        while (tmp >>= 1)
                                levels++;
                        if (levels) {
-                               ret = ci_dpm_force_state_sclk(rdev, levels);
+                               ret = ci_dpm_force_state_pcie(rdev, level);
                                if (ret)
                                        return ret;
                                for (i = 0; i < rdev->usec_timeout; i++) {
-                                       tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) &
-                                              CURR_SCLK_INDEX_MASK) >> CURR_SCLK_INDEX_SHIFT;
+                                       tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX_1) &
+                                              CURR_PCIE_INDEX_MASK) >> CURR_PCIE_INDEX_SHIFT;
                                        if (tmp == levels)
                                                break;
                                        udelay(1);
                                }
                        }
                }
-               if ((!pi->mclk_dpm_key_disabled) &&
-                   pi->dpm_level_enable_mask.mclk_dpm_enable_mask) {
+               if ((!pi->sclk_dpm_key_disabled) &&
+                   pi->dpm_level_enable_mask.sclk_dpm_enable_mask) {
                        levels = 0;
-                       tmp = pi->dpm_level_enable_mask.mclk_dpm_enable_mask;
+                       tmp = pi->dpm_level_enable_mask.sclk_dpm_enable_mask;
                        while (tmp >>= 1)
                                levels++;
                        if (levels) {
-                               ret = ci_dpm_force_state_mclk(rdev, levels);
+                               ret = ci_dpm_force_state_sclk(rdev, levels);
                                if (ret)
                                        return ret;
                                for (i = 0; i < rdev->usec_timeout; i++) {
                                        tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) &
-                                              CURR_MCLK_INDEX_MASK) >> CURR_MCLK_INDEX_SHIFT;
+                                              CURR_SCLK_INDEX_MASK) >> CURR_SCLK_INDEX_SHIFT;
                                        if (tmp == levels)
                                                break;
                                        udelay(1);
                                }
                        }
                }
-               if ((!pi->pcie_dpm_key_disabled) &&
-                   pi->dpm_level_enable_mask.pcie_dpm_enable_mask) {
+               if ((!pi->mclk_dpm_key_disabled) &&
+                   pi->dpm_level_enable_mask.mclk_dpm_enable_mask) {
                        levels = 0;
-                       tmp = pi->dpm_level_enable_mask.pcie_dpm_enable_mask;
+                       tmp = pi->dpm_level_enable_mask.mclk_dpm_enable_mask;
                        while (tmp >>= 1)
                                levels++;
                        if (levels) {
-                               ret = ci_dpm_force_state_pcie(rdev, level);
+                               ret = ci_dpm_force_state_mclk(rdev, levels);
                                if (ret)
                                        return ret;
                                for (i = 0; i < rdev->usec_timeout; i++) {
-                                       tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX_1) &
-                                              CURR_PCIE_INDEX_MASK) >> CURR_PCIE_INDEX_SHIFT;
+                                       tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) &
+                                              CURR_MCLK_INDEX_MASK) >> CURR_MCLK_INDEX_SHIFT;
                                        if (tmp == levels)
                                                break;
                                        udelay(1);
@@ -3805,21 +4269,17 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev,
                        }
                }
        } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
-               if (!pi->sclk_dpm_key_disabled) {
-                       smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel);
-                       if (smc_result != PPSMC_Result_OK)
-                               return -EINVAL;
-               }
-               if (!pi->mclk_dpm_key_disabled) {
-                       smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_MCLKDPM_NoForcedLevel);
-                       if (smc_result != PPSMC_Result_OK)
-                               return -EINVAL;
-               }
                if (!pi->pcie_dpm_key_disabled) {
-                       smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_PCIeDPM_UnForceLevel);
+                       PPSMC_Result smc_result;
+
+                       smc_result = ci_send_msg_to_smc(rdev,
+                                                       PPSMC_MSG_PCIeDPM_UnForceLevel);
                        if (smc_result != PPSMC_Result_OK)
                                return -EINVAL;
                }
+               ret = ci_upload_dpm_level_enable_mask(rdev);
+               if (ret)
+                       return ret;
        }
 
        rdev->pm.dpm.forced_level = level;
@@ -4025,6 +4485,96 @@ static int ci_copy_vbios_mc_reg_table(const struct atom_mc_reg_table *table,
        return 0;
 }
 
+static int ci_register_patching_mc_seq(struct radeon_device *rdev,
+                                      struct ci_mc_reg_table *table)
+{
+       u8 i, k;
+       u32 tmp;
+       bool patch;
+
+       tmp = RREG32(MC_SEQ_MISC0);
+       patch = ((tmp & 0x0000f00) == 0x300) ? true : false;
+
+       if (patch &&
+           ((rdev->pdev->device == 0x67B0) ||
+            (rdev->pdev->device == 0x67B1))) {
+               for (i = 0; i < table->last; i++) {
+                       if (table->last >= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
+                               return -EINVAL;
+                       switch(table->mc_reg_address[i].s1 >> 2) {
+                       case MC_SEQ_MISC1:
+                               for (k = 0; k < table->num_entries; k++) {
+                                       if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
+                                           (table->mc_reg_table_entry[k].mclk_max == 137500))
+                                               table->mc_reg_table_entry[k].mc_data[i] =
+                                                       (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFFFFF8) |
+                                                       0x00000007;
+                               }
+                               break;
+                       case MC_SEQ_WR_CTL_D0:
+                               for (k = 0; k < table->num_entries; k++) {
+                                       if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
+                                           (table->mc_reg_table_entry[k].mclk_max == 137500))
+                                               table->mc_reg_table_entry[k].mc_data[i] =
+                                                       (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFF0F00) |
+                                                       0x0000D0DD;
+                               }
+                               break;
+                       case MC_SEQ_WR_CTL_D1:
+                               for (k = 0; k < table->num_entries; k++) {
+                                       if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
+                                           (table->mc_reg_table_entry[k].mclk_max == 137500))
+                                               table->mc_reg_table_entry[k].mc_data[i] =
+                                                       (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFF0F00) |
+                                                       0x0000D0DD;
+                               }
+                               break;
+                       case MC_SEQ_WR_CTL_2:
+                               for (k = 0; k < table->num_entries; k++) {
+                                       if ((table->mc_reg_table_entry[k].mclk_max == 125000) ||
+                                           (table->mc_reg_table_entry[k].mclk_max == 137500))
+                                               table->mc_reg_table_entry[k].mc_data[i] = 0;
+                               }
+                               break;
+                       case MC_SEQ_CAS_TIMING:
+                               for (k = 0; k < table->num_entries; k++) {
+                                       if (table->mc_reg_table_entry[k].mclk_max == 125000)
+                                               table->mc_reg_table_entry[k].mc_data[i] =
+                                                       (table->mc_reg_table_entry[k].mc_data[i] & 0xFFE0FE0F) |
+                                                       0x000C0140;
+                                       else if (table->mc_reg_table_entry[k].mclk_max == 137500)
+                                               table->mc_reg_table_entry[k].mc_data[i] =
+                                                       (table->mc_reg_table_entry[k].mc_data[i] & 0xFFE0FE0F) |
+                                                       0x000C0150;
+                               }
+                               break;
+                       case MC_SEQ_MISC_TIMING:
+                               for (k = 0; k < table->num_entries; k++) {
+                                       if (table->mc_reg_table_entry[k].mclk_max == 125000)
+                                               table->mc_reg_table_entry[k].mc_data[i] =
+                                                       (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFFFFE0) |
+                                                       0x00000030;
+                                       else if (table->mc_reg_table_entry[k].mclk_max == 137500)
+                                               table->mc_reg_table_entry[k].mc_data[i] =
+                                                       (table->mc_reg_table_entry[k].mc_data[i] & 0xFFFFFFE0) |
+                                                       0x00000035;
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
+               WREG32(MC_SEQ_IO_DEBUG_INDEX, 3);
+               tmp = RREG32(MC_SEQ_IO_DEBUG_DATA);
+               tmp = (tmp & 0xFFF8FFFF) | (1 << 16);
+               WREG32(MC_SEQ_IO_DEBUG_INDEX, 3);
+               WREG32(MC_SEQ_IO_DEBUG_DATA, tmp);
+       }
+
+       return 0;
+}
+
 static int ci_initialize_mc_reg_table(struct radeon_device *rdev)
 {
        struct ci_power_info *pi = ci_get_pi(rdev);
@@ -4068,6 +4618,10 @@ static int ci_initialize_mc_reg_table(struct radeon_device *rdev)
 
        ci_set_s0_mc_reg_index(ci_table);
 
+       ret = ci_register_patching_mc_seq(rdev, ci_table);
+       if (ret)
+               goto init_mc_done;
+
        ret = ci_set_mc_special_registers(rdev, ci_table);
        if (ret)
                goto init_mc_done;
@@ -4672,34 +5226,43 @@ int ci_dpm_enable(struct radeon_device *rdev)
 
        ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 
+       ret = ci_enable_thermal_based_sclk_dpm(rdev, true);
+       if (ret) {
+               DRM_ERROR("ci_enable_thermal_based_sclk_dpm failed\n");
+               return ret;
+       }
+
+       ci_thermal_start_thermal_controller(rdev);
+
        ci_update_current_ps(rdev, boot_ps);
 
        return 0;
 }
 
-int ci_dpm_late_enable(struct radeon_device *rdev)
+static int ci_set_temperature_range(struct radeon_device *rdev)
 {
        int ret;
 
-       if (rdev->irq.installed &&
-           r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
-#if 0
-               PPSMC_Result result;
-#endif
-               ret = ci_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
-               if (ret) {
-                       DRM_ERROR("ci_set_thermal_temperature_range failed\n");
-                       return ret;
-               }
-               rdev->irq.dpm_thermal = true;
-               radeon_irq_set(rdev);
-#if 0
-               result = ci_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+       ret = ci_thermal_enable_alert(rdev, false);
+       if (ret)
+               return ret;
+       ret = ci_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+       if (ret)
+               return ret;
+       ret = ci_thermal_enable_alert(rdev, true);
+       if (ret)
+               return ret;
 
-               if (result != PPSMC_Result_OK)
-                       DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
-#endif
-       }
+       return ret;
+}
+
+int ci_dpm_late_enable(struct radeon_device *rdev)
+{
+       int ret;
+
+       ret = ci_set_temperature_range(rdev);
+       if (ret)
+               return ret;
 
        ci_dpm_powergate_uvd(rdev, true);
 
@@ -4716,6 +5279,8 @@ void ci_dpm_disable(struct radeon_device *rdev)
        if (!ci_is_smc_running(rdev))
                return;
 
+       ci_thermal_stop_thermal_controller(rdev);
+
        if (pi->thermal_protection)
                ci_enable_thermal_protection(rdev, false);
        ci_enable_power_containment(rdev, false);
@@ -4724,12 +5289,13 @@ void ci_dpm_disable(struct radeon_device *rdev)
        ci_enable_spread_spectrum(rdev, false);
        ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, false);
        ci_stop_dpm(rdev);
-       ci_enable_ds_master_switch(rdev, true);
+       ci_enable_ds_master_switch(rdev, false);
        ci_enable_ulv(rdev, false);
        ci_clear_vc(rdev);
        ci_reset_to_default(rdev);
        ci_dpm_stop_smc(rdev);
        ci_force_switch_to_arb_f0(rdev);
+       ci_enable_thermal_based_sclk_dpm(rdev, false);
 
        ci_update_current_ps(rdev, boot_ps);
 }
@@ -5060,6 +5626,8 @@ void ci_dpm_fini(struct radeon_device *rdev)
 int ci_dpm_init(struct radeon_device *rdev)
 {
        int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
+       SMU7_Discrete_DpmTable  *dpm_table;
+       struct radeon_gpio_rec gpio;
        u16 data_offset, size;
        u8 frev, crev;
        struct ci_power_info *pi;
@@ -5129,6 +5697,7 @@ int ci_dpm_init(struct radeon_device *rdev)
        pi->sclk_dpm_key_disabled = 0;
        pi->mclk_dpm_key_disabled = 0;
        pi->pcie_dpm_key_disabled = 0;
+       pi->thermal_sclk_dpm_enabled = 0;
 
        /* mclk dpm is unstable on some R7 260X cards with the old mc ucode */
        if ((rdev->pdev->device == 0x6658) &&
@@ -5193,6 +5762,55 @@ int ci_dpm_init(struct radeon_device *rdev)
 
        pi->uvd_enabled = false;
 
+       dpm_table = &pi->smc_state_table;
+
+       gpio = radeon_atombios_lookup_gpio(rdev, VDDC_VRHOT_GPIO_PINID);
+       if (gpio.valid) {
+               dpm_table->VRHotGpio = gpio.shift;
+               rdev->pm.dpm.platform_caps |= ATOM_PP_PLATFORM_CAP_REGULATOR_HOT;
+       } else {
+               dpm_table->VRHotGpio = CISLANDS_UNUSED_GPIO_PIN;
+               rdev->pm.dpm.platform_caps &= ~ATOM_PP_PLATFORM_CAP_REGULATOR_HOT;
+       }
+
+       gpio = radeon_atombios_lookup_gpio(rdev, PP_AC_DC_SWITCH_GPIO_PINID);
+       if (gpio.valid) {
+               dpm_table->AcDcGpio = gpio.shift;
+               rdev->pm.dpm.platform_caps |= ATOM_PP_PLATFORM_CAP_HARDWAREDC;
+       } else {
+               dpm_table->AcDcGpio = CISLANDS_UNUSED_GPIO_PIN;
+               rdev->pm.dpm.platform_caps &= ~ATOM_PP_PLATFORM_CAP_HARDWAREDC;
+       }
+
+       gpio = radeon_atombios_lookup_gpio(rdev, VDDC_PCC_GPIO_PINID);
+       if (gpio.valid) {
+               u32 tmp = RREG32_SMC(CNB_PWRMGT_CNTL);
+
+               switch (gpio.shift) {
+               case 0:
+                       tmp &= ~GNB_SLOW_MODE_MASK;
+                       tmp |= GNB_SLOW_MODE(1);
+                       break;
+               case 1:
+                       tmp &= ~GNB_SLOW_MODE_MASK;
+                       tmp |= GNB_SLOW_MODE(2);
+                       break;
+               case 2:
+                       tmp |= GNB_SLOW;
+                       break;
+               case 3:
+                       tmp |= FORCE_NB_PS1;
+                       break;
+               case 4:
+                       tmp |= DPM_ENABLED;
+                       break;
+               default:
+                       DRM_DEBUG("Invalid PCC GPIO: %u!\n", gpio.shift);
+                       break;
+               }
+               WREG32_SMC(CNB_PWRMGT_CNTL, tmp);
+       }
+
        pi->voltage_control = CISLANDS_VOLTAGE_CONTROL_NONE;
        pi->vddci_control = CISLANDS_VOLTAGE_CONTROL_NONE;
        pi->mvdd_control = CISLANDS_VOLTAGE_CONTROL_NONE;
@@ -5254,6 +5872,8 @@ int ci_dpm_init(struct radeon_device *rdev)
                rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
                        rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
 
+       pi->fan_ctrl_is_in_default_mode = true;
+
        return 0;
 }
 
@@ -5289,6 +5909,20 @@ void ci_dpm_print_power_state(struct radeon_device *rdev,
        r600_dpm_print_ps_status(rdev, rps);
 }
 
+u32 ci_dpm_get_current_sclk(struct radeon_device *rdev)
+{
+       u32 sclk = ci_get_average_sclk_freq(rdev);
+
+       return sclk;
+}
+
+u32 ci_dpm_get_current_mclk(struct radeon_device *rdev)
+{
+       u32 mclk = ci_get_average_mclk_freq(rdev);
+
+       return mclk;
+}
+
 u32 ci_dpm_get_sclk(struct radeon_device *rdev, bool low)
 {
        struct ci_power_info *pi = ci_get_pi(rdev);
index 596d17e..8b4fd92 100644 (file)
@@ -33,6 +33,8 @@
 
 #define CISLANDS_MAX_HARDWARE_POWERLEVELS 2
 
+#define CISLANDS_UNUSED_GPIO_PIN 0x7F
+
 struct ci_pl {
        u32 mclk;
        u32 sclk;
@@ -237,6 +239,7 @@ struct ci_power_info {
        u32 sclk_dpm_key_disabled;
        u32 mclk_dpm_key_disabled;
        u32 pcie_dpm_key_disabled;
+       u32 thermal_sclk_dpm_enabled;
        struct ci_pcie_perf_range pcie_gen_performance;
        struct ci_pcie_perf_range pcie_lane_performance;
        struct ci_pcie_perf_range pcie_gen_powersaving;
@@ -264,6 +267,7 @@ struct ci_power_info {
        bool caps_automatic_dc_transition;
        bool caps_sclk_throttle_low_notification;
        bool caps_dynamic_ac_timing;
+       bool caps_od_fuzzy_fan_control_support;
        /* flags */
        bool thermal_protection;
        bool pcie_performance_request;
@@ -285,6 +289,11 @@ struct ci_power_info {
        struct ci_ps current_ps;
        struct radeon_ps requested_rps;
        struct ci_ps requested_ps;
+       /* fan control */
+       bool fan_ctrl_is_in_default_mode;
+       bool fan_is_controlled_by_smc;
+       u32 t_min;
+       u32 fan_ctrl_default_mode;
 };
 
 #define CISLANDS_VOLTAGE_CONTROL_NONE                   0x0
index 42efe8b..82c1403 100644 (file)
@@ -48,6 +48,7 @@ int ci_copy_bytes_to_smc(struct radeon_device *rdev,
                         u32 smc_start_address,
                         const u8 *src, u32 byte_count, u32 limit)
 {
+       unsigned long flags;
        u32 data, original_data;
        u32 addr;
        u32 extra_shift;
@@ -60,7 +61,7 @@ int ci_copy_bytes_to_smc(struct radeon_device *rdev,
 
        addr = smc_start_address;
 
-       spin_lock(&rdev->smc_idx_lock);
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        while (byte_count >= 4) {
                /* SMC address space is BE */
                data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
@@ -105,7 +106,7 @@ int ci_copy_bytes_to_smc(struct radeon_device *rdev,
        }
 
 done:
-       spin_unlock(&rdev->smc_idx_lock);
+       spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 
        return ret;
 }
@@ -128,7 +129,7 @@ void ci_reset_smc(struct radeon_device *rdev)
 
 int ci_program_jump_on_start(struct radeon_device *rdev)
 {
-       static u8 data[] = { 0xE0, 0x00, 0x80, 0x40 };
+       static const u8 data[] = { 0xE0, 0x00, 0x80, 0x40 };
 
        return ci_copy_bytes_to_smc(rdev, 0x0, data, 4, sizeof(data)+1);
 }
@@ -205,6 +206,7 @@ PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev)
 
 int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
 {
+       unsigned long flags;
        u32 ucode_start_address;
        u32 ucode_size;
        const u8 *src;
@@ -244,7 +246,7 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
        if (ucode_size & 3)
                return -EINVAL;
 
-       spin_lock(&rdev->smc_idx_lock);
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        WREG32(SMC_IND_INDEX_0, ucode_start_address);
        WREG32_P(SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, ~AUTO_INCREMENT_IND_0);
        while (ucode_size >= 4) {
@@ -257,7 +259,7 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
                ucode_size -= 4;
        }
        WREG32_P(SMC_IND_ACCESS_CNTL, 0, ~AUTO_INCREMENT_IND_0);
-       spin_unlock(&rdev->smc_idx_lock);
+       spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 
        return 0;
 }
@@ -265,13 +267,14 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
 int ci_read_smc_sram_dword(struct radeon_device *rdev,
                           u32 smc_address, u32 *value, u32 limit)
 {
+       unsigned long flags;
        int ret;
 
-       spin_lock(&rdev->smc_idx_lock);
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        ret = ci_set_smc_sram_address(rdev, smc_address, limit);
        if (ret == 0)
                *value = RREG32(SMC_IND_DATA_0);
-       spin_unlock(&rdev->smc_idx_lock);
+       spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 
        return ret;
 }
@@ -279,13 +282,14 @@ int ci_read_smc_sram_dword(struct radeon_device *rdev,
 int ci_write_smc_sram_dword(struct radeon_device *rdev,
                            u32 smc_address, u32 value, u32 limit)
 {
+       unsigned long flags;
        int ret;
 
-       spin_lock(&rdev->smc_idx_lock);
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        ret = ci_set_smc_sram_address(rdev, smc_address, limit);
        if (ret == 0)
                WREG32(SMC_IND_DATA_0, value);
-       spin_unlock(&rdev->smc_idx_lock);
+       spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 
        return ret;
 }
index 73df88e..d129ed0 100644 (file)
@@ -26,6 +26,7 @@
 #include <drm/drmP.h>
 #include "radeon.h"
 #include "radeon_asic.h"
+#include "radeon_audio.h"
 #include "cikd.h"
 #include "atom.h"
 #include "cik_blit_shaders.h"
@@ -123,6 +124,63 @@ static void cik_fini_pg(struct radeon_device *rdev);
 static void cik_fini_cg(struct radeon_device *rdev);
 static void cik_enable_gui_idle_interrupt(struct radeon_device *rdev,
                                          bool enable);
+/**
+ * cik_get_allowed_info_register - fetch the register for the info ioctl
+ *
+ * @rdev: radeon_device pointer
+ * @reg: register offset in bytes
+ * @val: register value
+ *
+ * Returns 0 for success or -EINVAL for an invalid register
+ *
+ */
+int cik_get_allowed_info_register(struct radeon_device *rdev,
+                                 u32 reg, u32 *val)
+{
+       switch (reg) {
+       case GRBM_STATUS:
+       case GRBM_STATUS2:
+       case GRBM_STATUS_SE0:
+       case GRBM_STATUS_SE1:
+       case GRBM_STATUS_SE2:
+       case GRBM_STATUS_SE3:
+       case SRBM_STATUS:
+       case SRBM_STATUS2:
+       case (SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET):
+       case (SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET):
+       case UVD_STATUS:
+       /* TODO VCE */
+               *val = RREG32(reg);
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+/*
+ * Indirect registers accessor
+ */
+u32 cik_didt_rreg(struct radeon_device *rdev, u32 reg)
+{
+       unsigned long flags;
+       u32 r;
+
+       spin_lock_irqsave(&rdev->didt_idx_lock, flags);
+       WREG32(CIK_DIDT_IND_INDEX, (reg));
+       r = RREG32(CIK_DIDT_IND_DATA);
+       spin_unlock_irqrestore(&rdev->didt_idx_lock, flags);
+       return r;
+}
+
+void cik_didt_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&rdev->didt_idx_lock, flags);
+       WREG32(CIK_DIDT_IND_INDEX, (reg));
+       WREG32(CIK_DIDT_IND_DATA, (v));
+       spin_unlock_irqrestore(&rdev->didt_idx_lock, flags);
+}
 
 /* get temperature in millidegrees */
 int ci_get_temp(struct radeon_device *rdev)
@@ -166,24 +224,27 @@ int kv_get_temp(struct radeon_device *rdev)
  */
 u32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg)
 {
+       unsigned long flags;
        u32 r;
 
-       spin_lock(&rdev->pciep_idx_lock);
+       spin_lock_irqsave(&rdev->pciep_idx_lock, flags);
        WREG32(PCIE_INDEX, reg);
        (void)RREG32(PCIE_INDEX);
        r = RREG32(PCIE_DATA);
-       spin_unlock(&rdev->pciep_idx_lock);
+       spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags);
        return r;
 }
 
 void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
 {
-       spin_lock(&rdev->pciep_idx_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&rdev->pciep_idx_lock, flags);
        WREG32(PCIE_INDEX, reg);
        (void)RREG32(PCIE_INDEX);
        WREG32(PCIE_DATA, v);
        (void)RREG32(PCIE_DATA);
-       spin_unlock(&rdev->pciep_idx_lock);
+       spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags);
 }
 
 static const u32 spectre_rlc_save_restore_register_list[] =
@@ -1545,6 +1606,8 @@ static const u32 godavari_golden_registers[] =
 
 static void cik_init_golden_registers(struct radeon_device *rdev)
 {
+       /* Some of the registers might be dependent on GRBM_GFX_INDEX */
+       mutex_lock(&rdev->grbm_idx_mutex);
        switch (rdev->family) {
        case CHIP_BONAIRE:
                radeon_program_register_sequence(rdev,
@@ -1619,6 +1682,7 @@ static void cik_init_golden_registers(struct radeon_device *rdev)
        default:
                break;
        }
+       mutex_unlock(&rdev->grbm_idx_mutex);
 }
 
 /**
@@ -1788,7 +1852,7 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
 {
        const __be32 *fw_data = NULL;
        const __le32 *new_fw_data = NULL;
-       u32 running, blackout = 0;
+       u32 running, blackout = 0, tmp;
        u32 *io_mc_regs = NULL;
        const __le32 *new_io_mc_regs = NULL;
        int i, regs_size, ucode_size;
@@ -1848,6 +1912,15 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
                                WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
                        }
                }
+
+               tmp = RREG32(MC_SEQ_MISC0);
+               if ((rdev->pdev->device == 0x6649) && ((tmp & 0xff00) == 0x5600)) {
+                       WREG32(MC_SEQ_IO_DEBUG_INDEX, 5);
+                       WREG32(MC_SEQ_IO_DEBUG_DATA, 0x00000023);
+                       WREG32(MC_SEQ_IO_DEBUG_INDEX, 9);
+                       WREG32(MC_SEQ_IO_DEBUG_DATA, 0x000001f0);
+               }
+
                /* load the MC ucode */
                for (i = 0; i < ucode_size; i++) {
                        if (rdev->new_fw)
@@ -2283,9 +2356,13 @@ static void cik_fini_microcode(struct radeon_device *rdev)
  */
 static void cik_tiling_mode_table_init(struct radeon_device *rdev)
 {
-       const u32 num_tile_mode_states = 32;
-       const u32 num_secondary_tile_mode_states = 16;
-       u32 reg_offset, gb_tile_moden, split_equal_to_row_size;
+       u32 *tile = rdev->config.cik.tile_mode_array;
+       u32 *macrotile = rdev->config.cik.macrotile_mode_array;
+       const u32 num_tile_mode_states =
+                       ARRAY_SIZE(rdev->config.cik.tile_mode_array);
+       const u32 num_secondary_tile_mode_states =
+                       ARRAY_SIZE(rdev->config.cik.macrotile_mode_array);
+       u32 reg_offset, split_equal_to_row_size;
        u32 num_pipe_configs;
        u32 num_rbs = rdev->config.cik.max_backends_per_se *
                rdev->config.cik.max_shader_engines;
@@ -2307,1032 +2384,669 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev)
        if (num_pipe_configs > 8)
                num_pipe_configs = 16;
 
-       if (num_pipe_configs == 16) {
-               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_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
-                               break;
-                       case 1:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
-                               break;
-                       case 2:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                               break;
-                       case 3:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
-                               break;
-                       case 4:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                TILE_SPLIT(split_equal_to_row_size));
-                               break;
-                       case 5:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
-                               break;
-                       case 6:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                               break;
-                       case 7:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                TILE_SPLIT(split_equal_to_row_size));
-                               break;
-                       case 8:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16));
-                               break;
-                       case 9:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
-                               break;
-                       case 10:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 11:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 12:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 13:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
-                               break;
-                       case 14:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 16:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 17:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 27:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
-                               break;
-                       case 28:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 29:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 30:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       default:
-                               gb_tile_moden = 0;
-                               break;
-                       }
-                       rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
-                       WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-               }
-               for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
-                       switch (reg_offset) {
-                       case 0:
-                               gb_tile_moden = (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 1:
-                               gb_tile_moden = (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 2:
-                               gb_tile_moden = (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));
-                               break;
-                       case 3:
-                               gb_tile_moden = (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));
-                               break;
-                       case 4:
-                               gb_tile_moden = (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 5:
-                               gb_tile_moden = (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_4_BANK));
-                               break;
-                       case 6:
-                               gb_tile_moden = (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_2_BANK));
-                               break;
-                       case 8:
-                               gb_tile_moden = (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 9:
-                               gb_tile_moden = (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 10:
-                               gb_tile_moden = (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));
-                               break;
-                       case 11:
-                               gb_tile_moden = (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 12:
-                               gb_tile_moden = (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_4_BANK));
-                               break;
-                       case 13:
-                               gb_tile_moden = (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_2_BANK));
-                               break;
-                       case 14:
-                               gb_tile_moden = (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_2_BANK));
-                               break;
-                       default:
-                               gb_tile_moden = 0;
-                               break;
-                       }
-                       rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
-                       WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-               }
-       } else if (num_pipe_configs == 8) {
-               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_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
-                               break;
-                       case 1:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
-                               break;
-                       case 2:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                               break;
-                       case 3:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
-                               break;
-                       case 4:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                TILE_SPLIT(split_equal_to_row_size));
-                               break;
-                       case 5:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
-                               break;
-                       case 6:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                               break;
-                       case 7:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                TILE_SPLIT(split_equal_to_row_size));
-                               break;
-                       case 8:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16));
-                               break;
-                       case 9:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
-                               break;
-                       case 10:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 11:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 12:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 13:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
-                               break;
-                       case 14:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 16:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 17:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 27:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
-                               break;
-                       case 28:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 29:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 30:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       default:
-                               gb_tile_moden = 0;
-                               break;
-                       }
-                       rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
-                       WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-               }
-               for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
-                       switch (reg_offset) {
-                       case 0:
-                               gb_tile_moden = (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 = (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 2:
-                               gb_tile_moden = (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 3:
-                               gb_tile_moden = (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 4:
-                               gb_tile_moden = (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 5:
-                               gb_tile_moden = (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_4_BANK));
-                               break;
-                       case 6:
-                               gb_tile_moden = (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_2_BANK));
-                               break;
-                       case 8:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 9:
-                               gb_tile_moden = (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 10:
-                               gb_tile_moden = (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 11:
-                               gb_tile_moden = (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 12:
-                               gb_tile_moden = (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 13:
-                               gb_tile_moden = (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_4_BANK));
-                               break;
-                       case 14:
-                               gb_tile_moden = (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_2_BANK));
-                               break;
-                       default:
-                               gb_tile_moden = 0;
-                               break;
-                       }
-                       rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
-                       WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-               }
-       } else if (num_pipe_configs == 4) {
+       for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
+               tile[reg_offset] = 0;
+       for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
+               macrotile[reg_offset] = 0;
+
+       switch(num_pipe_configs) {
+       case 16:
+               tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+               tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+               tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+               tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+               tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16));
+               tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+               tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+               tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+               tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+
+               macrotile[0] = (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));
+               macrotile[1] = (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));
+               macrotile[2] = (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));
+               macrotile[3] = (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));
+               macrotile[4] = (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));
+               macrotile[5] = (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_4_BANK));
+               macrotile[6] = (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_2_BANK));
+               macrotile[8] = (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));
+               macrotile[9] = (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));
+               macrotile[10] = (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));
+               macrotile[11] = (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));
+               macrotile[12] = (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_4_BANK));
+               macrotile[13] = (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_2_BANK));
+               macrotile[14] = (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_2_BANK));
+
+               for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
+                       WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
+               for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
+                       WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]);
+               break;
+
+       case 8:
+               tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+               tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+               tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+               tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+               tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16));
+               tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+               tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+               tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+               tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+
+               macrotile[0] = (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));
+               macrotile[1] = (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));
+               macrotile[2] = (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));
+               macrotile[3] = (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));
+               macrotile[4] = (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));
+               macrotile[5] = (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_4_BANK));
+               macrotile[6] = (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_2_BANK));
+               macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                               BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+                               MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+                               NUM_BANKS(ADDR_SURF_16_BANK));
+               macrotile[9] = (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));
+               macrotile[10] = (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));
+               macrotile[11] = (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));
+               macrotile[12] = (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));
+               macrotile[13] = (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_4_BANK));
+               macrotile[14] = (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_2_BANK));
+
+               for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
+                       WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
+               for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
+                       WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]);
+               break;
+
+       case 4:
                if (num_rbs == 4) {
-                       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_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
-                                       break;
-                               case 1:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
-                                       break;
-                               case 2:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                                       break;
-                               case 3:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
-                                       break;
-                               case 4:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        TILE_SPLIT(split_equal_to_row_size));
-                                       break;
-                               case 5:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
-                                       break;
-                               case 6:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                                       break;
-                               case 7:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        TILE_SPLIT(split_equal_to_row_size));
-                                       break;
-                               case 8:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16));
-                                       break;
-                               case 9:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
-                                       break;
-                               case 10:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 11:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 12:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 13:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
-                                       break;
-                               case 14:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 16:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 17:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 27:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
-                                       break;
-                               case 28:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 29:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 30:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               default:
-                                       gb_tile_moden = 0;
-                                       break;
-                               }
-                               rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
-                               WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-                       }
+               tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+               tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+               tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+               tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+               tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16));
+               tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+               tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+               tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+               tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+
                } else if (num_rbs < 4) {
-                       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_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
-                                       break;
-                               case 1:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
-                                       break;
-                               case 2:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                                       break;
-                               case 3:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
-                                       break;
-                               case 4:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        TILE_SPLIT(split_equal_to_row_size));
-                                       break;
-                               case 5:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
-                                       break;
-                               case 6:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                                       break;
-                               case 7:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        TILE_SPLIT(split_equal_to_row_size));
-                                       break;
-                               case 8:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
-                                                PIPE_CONFIG(ADDR_SURF_P4_8x16));
-                                       break;
-                               case 9:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
-                                       break;
-                               case 10:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 11:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 12:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 13:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
-                                       break;
-                               case 14:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 16:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 17:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 27:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
-                                       break;
-                               case 28:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 29:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               case 30:
-                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
-                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                                       break;
-                               default:
-                                       gb_tile_moden = 0;
-                                       break;
-                               }
-                               rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
-                               WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-                       }
-               }
-               for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
-                       switch (reg_offset) {
-                       case 0:
-                               gb_tile_moden = (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 = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 2:
-                               gb_tile_moden = (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 3:
-                               gb_tile_moden = (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 4:
-                               gb_tile_moden = (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 5:
-                               gb_tile_moden = (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_8_BANK));
-                               break;
-                       case 6:
-                               gb_tile_moden = (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_4_BANK));
-                               break;
-                       case 8:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 9:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 10:
-                               gb_tile_moden = (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 = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 12:
-                               gb_tile_moden = (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 = (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_8_BANK));
-                               break;
-                       case 14:
-                               gb_tile_moden = (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_4_BANK));
-                               break;
-                       default:
-                               gb_tile_moden = 0;
-                               break;
-                       }
-                       rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
-                       WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-               }
-       } else if (num_pipe_configs == 2) {
-               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_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
-                               break;
-                       case 1:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
-                               break;
-                       case 2:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                               break;
-                       case 3:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
-                               break;
-                       case 4:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                TILE_SPLIT(split_equal_to_row_size));
-                               break;
-                       case 5:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
-                               break;
-                       case 6:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
-                               break;
-                       case 7:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                TILE_SPLIT(split_equal_to_row_size));
-                               break;
-                       case 8:
-                               gb_tile_moden = ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
-                                               PIPE_CONFIG(ADDR_SURF_P2);
-                               break;
-                       case 9:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2));
-                               break;
-                       case 10:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 11:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 12:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 13:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
-                               break;
-                       case 14:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 16:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 17:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 27:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2));
-                               break;
-                       case 28:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 29:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       case 30:
-                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
-                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
-                                                PIPE_CONFIG(ADDR_SURF_P2) |
-                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
-                               break;
-                       default:
-                               gb_tile_moden = 0;
-                               break;
-                       }
-                       rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
-                       WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+               tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+               tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+               tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+               tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+               tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+               tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          TILE_SPLIT(split_equal_to_row_size));
+               tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16));
+               tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                          PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                          MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+               tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+               tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+               tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+               tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                           MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                           PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                           SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
                }
-               for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
-                       switch (reg_offset) {
-                       case 0:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
-                                                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 = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 2:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 3:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 4:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 5:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 6:
-                               gb_tile_moden = (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_8_BANK));
-                               break;
-                       case 8:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 9:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 10:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
-                                                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 = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 12:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 13:
-                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
-                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
-                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
-                                                NUM_BANKS(ADDR_SURF_16_BANK));
-                               break;
-                       case 14:
-                               gb_tile_moden = (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_8_BANK));
-                               break;
-                       default:
-                               gb_tile_moden = 0;
-                               break;
-                       }
-                       rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
-                       WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
-               }
-       } else
+
+               macrotile[0] = (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));
+               macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                               BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+                               MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+                               NUM_BANKS(ADDR_SURF_16_BANK));
+               macrotile[2] = (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));
+               macrotile[3] = (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));
+               macrotile[4] = (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));
+               macrotile[5] = (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_8_BANK));
+               macrotile[6] = (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_4_BANK));
+               macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+                               BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+                               MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+                               NUM_BANKS(ADDR_SURF_16_BANK));
+               macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+                               BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+                               MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+                               NUM_BANKS(ADDR_SURF_16_BANK));
+               macrotile[10] = (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));
+          &n