drm/radeon/kms: avoid possible oops (call gart_fini before gart_disable)
[linux-2.6.git] / drivers / gpu / drm / radeon / r300.c
index 7e9f956..1023eeb 100644 (file)
@@ -30,6 +30,7 @@
 #include "drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_drm.h"
 #include "r100_track.h"
 #include "r300d.h"
@@ -164,9 +165,9 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
 
 void rv370_pcie_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        rv370_pcie_gart_disable(rdev);
        radeon_gart_table_vram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 void r300_fence_ring_emit(struct radeon_device *rdev,
@@ -461,7 +462,8 @@ int r300_gpu_reset(struct radeon_device *rdev)
  */
 void r300_mc_init(struct radeon_device *rdev)
 {
-       uint32_t tmp;
+       u64 base;
+       u32 tmp;
 
        /* DDR for all card after R300 & IGP */
        rdev->mc.vram_is_ddr = true;
@@ -474,8 +476,13 @@ void r300_mc_init(struct radeon_device *rdev)
        default:  rdev->mc.vram_width = 128; break;
        }
        r100_vram_init_sizes(rdev);
+       base = rdev->mc.aper_base;
+       if (rdev->flags & RADEON_IS_IGP)
+               base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
+       radeon_vram_location(rdev, &rdev->mc, base);
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
+       radeon_update_bandwidth_info(rdev);
 }
 
 void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
@@ -549,7 +556,10 @@ int rv370_get_pcie_lanes(struct radeon_device *rdev)
 
        /* FIXME wait for idle */
 
-       link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+       if (rdev->family < CHIP_R600)
+               link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+       else
+               link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
 
        switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) {
        case RADEON_PCIE_LC_LINK_WIDTH_X0:
@@ -697,6 +707,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        tile_flags |= R300_TXO_MACRO_TILE;
                if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
                        tile_flags |= R300_TXO_MICRO_TILE;
+               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                       tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
 
                tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
                tmp |= tile_flags;
@@ -747,6 +759,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        tile_flags |= R300_COLOR_TILE_ENABLE;
                if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
                        tile_flags |= R300_COLOR_MICROTILE_ENABLE;
+               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                       tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
 
                tmp = idx_value & ~(0x7 << 16);
                tmp |= tile_flags;
@@ -818,7 +832,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
                        tile_flags |= R300_DEPTHMACROTILE_ENABLE;
                if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                       tile_flags |= R300_DEPTHMICROTILE_TILED;;
+                       tile_flags |= R300_DEPTHMICROTILE_TILED;
+               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                       tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
 
                tmp = idx_value & ~(0x7 << 16);
                tmp |= tile_flags;
@@ -1320,6 +1336,7 @@ int r300_suspend(struct radeon_device *rdev)
 
 void r300_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);