]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/gpu/drm/radeon/rv770.c
drm/radeon/kms: avoid corner case issue with unmappable vram V2
[net-next-2.6.git] / drivers / gpu / drm / radeon / rv770.c
index f1c796810117fdb9dfb0b66aa5a89eee5e1da1e9..9490da700749487c00fe9c57671ec89727653136 100644 (file)
@@ -267,6 +267,7 @@ static void rv770_mc_program(struct radeon_device *rdev)
  */
 void r700_cp_stop(struct radeon_device *rdev)
 {
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
 }
 
@@ -905,6 +906,54 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
 }
 
+static int rv770_vram_scratch_init(struct radeon_device *rdev)
+{
+       int r;
+       u64 gpu_addr;
+
+       if (rdev->vram_scratch.robj == NULL) {
+               r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
+                                       true, RADEON_GEM_DOMAIN_VRAM,
+                                       &rdev->vram_scratch.robj);
+               if (r) {
+                       return r;
+               }
+       }
+
+       r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+       if (unlikely(r != 0))
+               return r;
+       r = radeon_bo_pin(rdev->vram_scratch.robj,
+                         RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
+       if (r) {
+               radeon_bo_unreserve(rdev->vram_scratch.robj);
+               return r;
+       }
+       r = radeon_bo_kmap(rdev->vram_scratch.robj,
+                               (void **)&rdev->vram_scratch.ptr);
+       if (r)
+               radeon_bo_unpin(rdev->vram_scratch.robj);
+       radeon_bo_unreserve(rdev->vram_scratch.robj);
+
+       return r;
+}
+
+static void rv770_vram_scratch_fini(struct radeon_device *rdev)
+{
+       int r;
+
+       if (rdev->vram_scratch.robj == NULL) {
+               return;
+       }
+       r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+       if (likely(r == 0)) {
+               radeon_bo_kunmap(rdev->vram_scratch.robj);
+               radeon_bo_unpin(rdev->vram_scratch.robj);
+               radeon_bo_unreserve(rdev->vram_scratch.robj);
+       }
+       radeon_bo_unref(&rdev->vram_scratch.robj);
+}
+
 int rv770_mc_init(struct radeon_device *rdev)
 {
        u32 tmp;
@@ -944,6 +993,7 @@ int rv770_mc_init(struct radeon_device *rdev)
        rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        r600_vram_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
 
@@ -970,6 +1020,9 @@ static int rv770_startup(struct radeon_device *rdev)
                if (r)
                        return r;
        }
+       r = rv770_vram_scratch_init(rdev);
+       if (r)
+               return r;
        rv770_gpu_init(rdev);
        r = r600_blit_init(rdev);
        if (r) {
@@ -1023,11 +1076,6 @@ int rv770_resume(struct radeon_device *rdev)
         */
        /* post card */
        atom_asic_init(rdev->mode_info.atom_context);
-       /* Initialize clocks */
-       r = radeon_clocks_init(rdev);
-       if (r) {
-               return r;
-       }
 
        r = rv770_startup(rdev);
        if (r) {
@@ -1118,9 +1166,6 @@ int rv770_init(struct radeon_device *rdev)
        radeon_surface_init(rdev);
        /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
-       r = radeon_clocks_init(rdev);
-       if (r)
-               return r;
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)
@@ -1195,9 +1240,9 @@ void rv770_fini(struct radeon_device *rdev)
        r600_irq_fini(rdev);
        radeon_irq_kms_fini(rdev);
        rv770_pcie_gart_fini(rdev);
+       rv770_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
-       radeon_clocks_fini(rdev);
        radeon_agp_fini(rdev);
        radeon_bo_fini(rdev);
        radeon_atombios_fini(rdev);