Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
[pandora-kernel.git] / drivers / gpu / drm / radeon / ni.c
index 8c79ca9..0e57998 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "drmP.h"
 #include "radeon.h"
 #include "radeon_asic.h"
@@ -40,6 +41,7 @@ extern void evergreen_mc_program(struct radeon_device *rdev);
 extern void evergreen_irq_suspend(struct radeon_device *rdev);
 extern int evergreen_mc_init(struct radeon_device *rdev);
 extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
+extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
 
 #define EVERGREEN_PFP_UCODE_SIZE 1120
 #define EVERGREEN_PM4_UCODE_SIZE 1376
@@ -260,8 +262,11 @@ int ni_mc_load_microcode(struct radeon_device *rdev)
                WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
 
                /* wait for training to complete */
-               while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD))
-                       udelay(10);
+               for (i = 0; i < rdev->usec_timeout; i++) {
+                       if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
+                               break;
+                       udelay(1);
+               }
 
                if (running)
                        WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
@@ -931,7 +936,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
@@ -967,14 +972,15 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(VM_CONTEXT1_CNTL, 0);
 
        cayman_pcie_gart_tlb_flush(rdev);
+       DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
+                (unsigned)(rdev->mc.gtt_size >> 20),
+                (unsigned long long)rdev->gart.table_addr);
        rdev->gart.ready = true;
        return 0;
 }
 
 void cayman_pcie_gart_disable(struct radeon_device *rdev)
 {
-       int r;
-
        /* Disable all tables */
        WREG32(VM_CONTEXT0_CNTL, 0);
        WREG32(VM_CONTEXT1_CNTL, 0);
@@ -990,14 +996,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev)
        WREG32(VM_L2_CNTL2, 0);
        WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
               L2_CACHE_BIGK_FRAGMENT_SIZE(6));
-       if (rdev->gart.table.vram.robj) {
-               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
-               if (likely(r == 0)) {
-                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
-                       radeon_bo_unpin(rdev->gart.table.vram.robj);
-                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
-               }
-       }
+       radeon_gart_table_vram_unpin(rdev);
 }
 
 void cayman_pcie_gart_fini(struct radeon_device *rdev)
@@ -1341,6 +1340,9 @@ static int cayman_startup(struct radeon_device *rdev)
 {
        int r;
 
+       /* enable pcie gen2 link */
+       evergreen_pcie_gen2_enable(rdev);
+
        if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
                r = ni_init_microcode(rdev);
                if (r) {
@@ -1354,6 +1356,10 @@ static int cayman_startup(struct radeon_device *rdev)
                return r;
        }
 
+       r = r600_vram_scratch_init(rdev);
+       if (r)
+               return r;
+
        evergreen_mc_program(rdev);
        r = cayman_pcie_gart_enable(rdev);
        if (r)
@@ -1362,7 +1368,7 @@ static int cayman_startup(struct radeon_device *rdev)
 
        r = evergreen_blit_init(rdev);
        if (r) {
-               evergreen_blit_fini(rdev);
+               r600_blit_fini(rdev);
                rdev->asic->copy = NULL;
                dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
        }
@@ -1423,21 +1429,13 @@ int cayman_resume(struct radeon_device *rdev)
 
 int cayman_suspend(struct radeon_device *rdev)
 {
-       int r;
-
        /* FIXME: we should wait for ring to be empty */
        cayman_cp_enable(rdev, false);
        rdev->cp.ready = false;
        evergreen_irq_suspend(rdev);
        radeon_wb_disable(rdev);
        cayman_pcie_gart_disable(rdev);
-
-       /* unpin shaders bo */
-       r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
-       if (likely(r == 0)) {
-               radeon_bo_unpin(rdev->r600_blit.shader_obj);
-               radeon_bo_unreserve(rdev->r600_blit.shader_obj);
-       }
+       r600_blit_suspend(rdev);
 
        return 0;
 }
@@ -1550,13 +1548,14 @@ int cayman_init(struct radeon_device *rdev)
 
 void cayman_fini(struct radeon_device *rdev)
 {
-       evergreen_blit_fini(rdev);
+       r600_blit_fini(rdev);
        cayman_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        cayman_pcie_gart_fini(rdev);
+       r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
        radeon_bo_fini(rdev);