Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6.git] / drivers / gpu / drm / radeon / rv770.c
index 3ecd138..9f37d2e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/platform_device.h>
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_drm.h"
 #include "rv770d.h"
 #include "atom.h"
@@ -56,6 +57,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
        r = radeon_gart_table_vram_pin(rdev);
        if (r)
                return r;
+       radeon_gart_restore(rdev);
        /* Setup L2 cache */
        WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
                                ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
@@ -124,9 +126,9 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
 
 void rv770_pcie_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        rv770_pcie_gart_disable(rdev);
        radeon_gart_table_vram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 
@@ -273,9 +275,10 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev)
 /*
  * Core functions
  */
-static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
-                                               u32 num_backends,
-                                               u32 backend_disable_mask)
+static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
+                                            u32 num_tile_pipes,
+                                            u32 num_backends,
+                                            u32 backend_disable_mask)
 {
        u32 backend_map = 0;
        u32 enabled_backends_mask;
@@ -284,6 +287,7 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
        u32 swizzle_pipe[R7XX_MAX_PIPES];
        u32 cur_backend;
        u32 i;
+       bool force_no_swizzle;
 
        if (num_tile_pipes > R7XX_MAX_PIPES)
                num_tile_pipes = R7XX_MAX_PIPES;
@@ -313,6 +317,18 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
        if (enabled_backends_count != num_backends)
                num_backends = enabled_backends_count;
 
+       switch (rdev->family) {
+       case CHIP_RV770:
+       case CHIP_RV730:
+               force_no_swizzle = false;
+               break;
+       case CHIP_RV710:
+       case CHIP_RV740:
+       default:
+               force_no_swizzle = true;
+               break;
+       }
+
        memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
        switch (num_tile_pipes) {
        case 1:
@@ -323,49 +339,100 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
                swizzle_pipe[1] = 1;
                break;
        case 3:
-               swizzle_pipe[0] = 0;
-               swizzle_pipe[1] = 2;
-               swizzle_pipe[2] = 1;
+               if (force_no_swizzle) {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 1;
+                       swizzle_pipe[2] = 2;
+               } else {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 2;
+                       swizzle_pipe[2] = 1;
+               }
                break;
        case 4:
-               swizzle_pipe[0] = 0;
-               swizzle_pipe[1] = 2;
-               swizzle_pipe[2] = 3;
-               swizzle_pipe[3] = 1;
+               if (force_no_swizzle) {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 1;
+                       swizzle_pipe[2] = 2;
+                       swizzle_pipe[3] = 3;
+               } else {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 2;
+                       swizzle_pipe[2] = 3;
+                       swizzle_pipe[3] = 1;
+               }
                break;
        case 5:
-               swizzle_pipe[0] = 0;
-               swizzle_pipe[1] = 2;
-               swizzle_pipe[2] = 4;
-               swizzle_pipe[3] = 1;
-               swizzle_pipe[4] = 3;
+               if (force_no_swizzle) {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 1;
+                       swizzle_pipe[2] = 2;
+                       swizzle_pipe[3] = 3;
+                       swizzle_pipe[4] = 4;
+               } else {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 2;
+                       swizzle_pipe[2] = 4;
+                       swizzle_pipe[3] = 1;
+                       swizzle_pipe[4] = 3;
+               }
                break;
        case 6:
-               swizzle_pipe[0] = 0;
-               swizzle_pipe[1] = 2;
-               swizzle_pipe[2] = 4;
-               swizzle_pipe[3] = 5;
-               swizzle_pipe[4] = 3;
-               swizzle_pipe[5] = 1;
+               if (force_no_swizzle) {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 1;
+                       swizzle_pipe[2] = 2;
+                       swizzle_pipe[3] = 3;
+                       swizzle_pipe[4] = 4;
+                       swizzle_pipe[5] = 5;
+               } else {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 2;
+                       swizzle_pipe[2] = 4;
+                       swizzle_pipe[3] = 5;
+                       swizzle_pipe[4] = 3;
+                       swizzle_pipe[5] = 1;
+               }
                break;
        case 7:
-               swizzle_pipe[0] = 0;
-               swizzle_pipe[1] = 2;
-               swizzle_pipe[2] = 4;
-               swizzle_pipe[3] = 6;
-               swizzle_pipe[4] = 3;
-               swizzle_pipe[5] = 1;
-               swizzle_pipe[6] = 5;
+               if (force_no_swizzle) {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 1;
+                       swizzle_pipe[2] = 2;
+                       swizzle_pipe[3] = 3;
+                       swizzle_pipe[4] = 4;
+                       swizzle_pipe[5] = 5;
+                       swizzle_pipe[6] = 6;
+               } else {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 2;
+                       swizzle_pipe[2] = 4;
+                       swizzle_pipe[3] = 6;
+                       swizzle_pipe[4] = 3;
+                       swizzle_pipe[5] = 1;
+                       swizzle_pipe[6] = 5;
+               }
                break;
        case 8:
-               swizzle_pipe[0] = 0;
-               swizzle_pipe[1] = 2;
-               swizzle_pipe[2] = 4;
-               swizzle_pipe[3] = 6;
-               swizzle_pipe[4] = 3;
-               swizzle_pipe[5] = 1;
-               swizzle_pipe[6] = 7;
-               swizzle_pipe[7] = 5;
+               if (force_no_swizzle) {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 1;
+                       swizzle_pipe[2] = 2;
+                       swizzle_pipe[3] = 3;
+                       swizzle_pipe[4] = 4;
+                       swizzle_pipe[5] = 5;
+                       swizzle_pipe[6] = 6;
+                       swizzle_pipe[7] = 7;
+               } else {
+                       swizzle_pipe[0] = 0;
+                       swizzle_pipe[1] = 2;
+                       swizzle_pipe[2] = 4;
+                       swizzle_pipe[3] = 6;
+                       swizzle_pipe[4] = 3;
+                       swizzle_pipe[5] = 1;
+                       swizzle_pipe[6] = 7;
+                       swizzle_pipe[7] = 5;
+               }
                break;
        }
 
@@ -385,8 +452,10 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
 static void rv770_gpu_init(struct radeon_device *rdev)
 {
        int i, j, num_qd_pipes;
+       u32 ta_aux_cntl;
        u32 sx_debug_1;
        u32 smx_dc_ctl0;
+       u32 db_debug3;
        u32 num_gs_verts_per_thread;
        u32 vgt_gs_per_es;
        u32 gs_prim_buffer_depth = 0;
@@ -515,24 +584,20 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
        switch (rdev->config.rv770.max_tile_pipes) {
        case 1:
+       default:
                gb_tiling_config |= PIPE_TILING(0);
-               rdev->config.rv770.tiling_npipes = 1;
                break;
        case 2:
                gb_tiling_config |= PIPE_TILING(1);
-               rdev->config.rv770.tiling_npipes = 2;
                break;
        case 4:
                gb_tiling_config |= PIPE_TILING(2);
-               rdev->config.rv770.tiling_npipes = 4;
                break;
        case 8:
                gb_tiling_config |= PIPE_TILING(3);
-               rdev->config.rv770.tiling_npipes = 8;
-               break;
-       default:
                break;
        }
+       rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes;
 
        if (rdev->family == CHIP_RV770)
                gb_tiling_config |= BANK_TILING(1);
@@ -555,18 +620,27 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
        gb_tiling_config |= BANK_SWAPS(1);
 
-       backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes,
-                                                       rdev->config.rv770.max_backends,
-                                                       (0xff << rdev->config.rv770.max_backends) & 0xff);
-       gb_tiling_config |= BACKEND_MAP(backend_map);
+       cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000;
+       cc_rb_backend_disable |=
+               BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK);
 
-       cc_gc_shader_pipe_config =
+       cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
+       cc_gc_shader_pipe_config |=
                INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK);
        cc_gc_shader_pipe_config |=
                INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK);
 
-       cc_rb_backend_disable =
-               BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK);
+       if (rdev->family == CHIP_RV740)
+               backend_map = 0x28;
+       else
+               backend_map = r700_get_tile_pipe_to_backend_map(rdev,
+                                                               rdev->config.rv770.max_tile_pipes,
+                                                               (R7XX_MAX_BACKENDS -
+                                                                r600_count_pipe_bits((cc_rb_backend_disable &
+                                                                                      R7XX_MAX_BACKENDS_MASK) >> 16)),
+                                                               (cc_rb_backend_disable >> 16));
+       gb_tiling_config |= BACKEND_MAP(backend_map);
+
 
        WREG32(GB_TILING_CONFIG, gb_tiling_config);
        WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
@@ -575,15 +649,15 @@ static void rv770_gpu_init(struct radeon_device *rdev)
        WREG32(CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
        WREG32(CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
        WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+       WREG32(CC_SYS_RB_BACKEND_DISABLE,  cc_rb_backend_disable);
 
-       WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
        WREG32(CGTS_SYS_TCC_DISABLE, 0);
        WREG32(CGTS_TCC_DISABLE, 0);
        WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
        WREG32(CGTS_USER_TCC_DISABLE, 0);
 
        num_qd_pipes =
-               R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK);
+               R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
        WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK);
        WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK);
 
@@ -593,10 +667,8 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
        WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
 
-       WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
-                            SYNC_GRADIENT |
-                            SYNC_WALKER |
-                            SYNC_ALIGNER));
+       ta_aux_cntl = RREG32(TA_CNTL_AUX);
+       WREG32(TA_CNTL_AUX, ta_aux_cntl | DISABLE_CUBE_ANISO);
 
        sx_debug_1 = RREG32(SX_DEBUG_1);
        sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
@@ -607,14 +679,28 @@ static void rv770_gpu_init(struct radeon_device *rdev)
        smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1);
        WREG32(SMX_DC_CTL0, smx_dc_ctl0);
 
-       WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
-                              GS_FLUSH_CTL(4) |
-                              ACK_FLUSH_CTL(3) |
-                              SYNC_FLUSH_CTL));
+       if (rdev->family != CHIP_RV740)
+               WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
+                                      GS_FLUSH_CTL(4) |
+                                      ACK_FLUSH_CTL(3) |
+                                      SYNC_FLUSH_CTL));
 
-       if (rdev->family == CHIP_RV770)
-               WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f));
-       else {
+       db_debug3 = RREG32(DB_DEBUG3);
+       db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f);
+       switch (rdev->family) {
+       case CHIP_RV770:
+       case CHIP_RV740:
+               db_debug3 |= DB_CLK_OFF_DELAY(0x1f);
+               break;
+       case CHIP_RV710:
+       case CHIP_RV730:
+       default:
+               db_debug3 |= DB_CLK_OFF_DELAY(2);
+               break;
+       }
+       WREG32(DB_DEBUG3, db_debug3);
+
+       if (rdev->family != CHIP_RV770) {
                db_debug4 = RREG32(DB_DEBUG4);
                db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER;
                WREG32(DB_DEBUG4, db_debug4);
@@ -643,10 +729,10 @@ static void rv770_gpu_init(struct radeon_device *rdev)
                            ALU_UPDATE_FIFO_HIWATER(0x8));
        switch (rdev->family) {
        case CHIP_RV770:
-               sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
-               break;
        case CHIP_RV730:
        case CHIP_RV710:
+               sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
+               break;
        case CHIP_RV740:
        default:
                sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4);
@@ -782,7 +868,6 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
 int rv770_mc_init(struct radeon_device *rdev)
 {
-       fixed20_12 a;
        u32 tmp;
        int chansize, numchan;
 
@@ -819,53 +904,18 @@ int rv770_mc_init(struct radeon_device *rdev)
        /* Setup GPU memory space */
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
-
-       if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+       rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       /* FIXME remove this once we support unmappable VRAM */
+       if (rdev->mc.mc_vram_size > rdev->mc.aper_size) {
                rdev->mc.mc_vram_size = rdev->mc.aper_size;
-
-       if (rdev->mc.real_vram_size > rdev->mc.aper_size)
                rdev->mc.real_vram_size = rdev->mc.aper_size;
-
-       if (rdev->flags & RADEON_IS_AGP) {
-               /* gtt_size is setup by radeon_agp_init */
-               rdev->mc.gtt_location = rdev->mc.agp_base;
-               tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
-               /* Try to put vram before or after AGP because we
-                * we want SYSTEM_APERTURE to cover both VRAM and
-                * AGP so that GPU can catch out of VRAM/AGP access
-                */
-               if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-                       /* Enought place before */
-                       rdev->mc.vram_location = rdev->mc.gtt_location -
-                                                       rdev->mc.mc_vram_size;
-               } else if (tmp > rdev->mc.mc_vram_size) {
-                       /* Enought place after */
-                       rdev->mc.vram_location = rdev->mc.gtt_location +
-                                                       rdev->mc.gtt_size;
-               } else {
-                       /* Try to setup VRAM then AGP might not
-                        * not work on some card
-                        */
-                       rdev->mc.vram_location = 0x00000000UL;
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               }
-       } else {
-               rdev->mc.vram_location = 0x00000000UL;
-               rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
        }
-       rdev->mc.vram_start = rdev->mc.vram_location;
-       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-       rdev->mc.gtt_start = rdev->mc.gtt_location;
-       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-       /* FIXME: we should enforce default clock in case GPU is not in
-        * default setup
-        */
-       a.full = rfixed_const(100);
-       rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-       rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+       r600_vram_gtt_location(rdev, &rdev->mc);
+       radeon_update_bandwidth_info(rdev);
+
        return 0;
 }
+
 int rv770_gpu_reset(struct radeon_device *rdev)
 {
        /* FIXME: implement any rv770 specific bits */
@@ -962,6 +1012,13 @@ int rv770_resume(struct radeon_device *rdev)
                DRM_ERROR("radeon: failled testing IB (%d).\n", r);
                return r;
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "radeon: audio init failed\n");
+               return r;
+       }
+
        return r;
 
 }
@@ -970,6 +1027,7 @@ int rv770_suspend(struct radeon_device *rdev)
 {
        int r;
 
+       r600_audio_fini(rdev);
        /* FIXME: we should wait for ring to be empty */
        r700_cp_stop(rdev);
        rdev->cp.ready = false;
@@ -1041,6 +1099,7 @@ int rv770_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
+       /* initialize AGP */
        if (rdev->flags & RADEON_IS_AGP) {
                r = radeon_agp_init(rdev);
                if (r)
@@ -1092,11 +1151,19 @@ int rv770_init(struct radeon_device *rdev)
                        }
                }
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "radeon: audio init failed\n");
+               return r;
+       }
+
        return 0;
 }
 
 void rv770_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r600_blit_fini(rdev);
        r600_cp_fini(rdev);
        r600_wb_fini(rdev);