Merge branch 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[pandora-kernel.git] / drivers / gpu / drm / radeon / radeon_ttm.c
index 15c3531..765bd18 100644 (file)
 #include <ttm/ttm_module.h>
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
+#include <linux/seq_file.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 
 #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
 
+static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
+
 static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
 {
        struct radeon_mman *mman;
@@ -77,9 +80,25 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
        global_ref->release = &radeon_ttm_mem_global_release;
        r = ttm_global_item_ref(global_ref);
        if (r != 0) {
-               DRM_ERROR("Failed referencing a global TTM memory object.\n");
+               DRM_ERROR("Failed setting up TTM memory accounting "
+                         "subsystem.\n");
+               return r;
+       }
+
+       rdev->mman.bo_global_ref.mem_glob =
+               rdev->mman.mem_global_ref.object;
+       global_ref = &rdev->mman.bo_global_ref.ref;
+       global_ref->global_type = TTM_GLOBAL_TTM_BO;
+       global_ref->size = sizeof(struct ttm_bo_global);
+       global_ref->init = &ttm_bo_global_init;
+       global_ref->release = &ttm_bo_global_release;
+       r = ttm_global_item_ref(global_ref);
+       if (r != 0) {
+               DRM_ERROR("Failed setting up TTM BO subsystem.\n");
+               ttm_global_item_unref(&rdev->mman.mem_global_ref);
                return r;
        }
+
        rdev->mman.mem_global_referenced = true;
        return 0;
 }
@@ -87,6 +106,7 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
 static void radeon_ttm_global_fini(struct radeon_device *rdev)
 {
        if (rdev->mman.mem_global_referenced) {
+               ttm_global_item_unref(&rdev->mman.bo_global_ref.ref);
                ttm_global_item_unref(&rdev->mman.mem_global_ref);
                rdev->mman.mem_global_referenced = false;
        }
@@ -286,9 +306,11 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
        r = ttm_bo_move_ttm(bo, true, no_wait, new_mem);
 out_cleanup:
        if (tmp_mem.mm_node) {
-               spin_lock(&rdev->mman.bdev.lru_lock);
+               struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+
+               spin_lock(&glob->lru_lock);
                drm_mm_put_block(tmp_mem.mm_node);
-               spin_unlock(&rdev->mman.bdev.lru_lock);
+               spin_unlock(&glob->lru_lock);
                return r;
        }
        return r;
@@ -323,9 +345,11 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo,
        }
 out_cleanup:
        if (tmp_mem.mm_node) {
-               spin_lock(&rdev->mman.bdev.lru_lock);
+               struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+
+               spin_lock(&glob->lru_lock);
                drm_mm_put_block(tmp_mem.mm_node);
-               spin_unlock(&rdev->mman.bdev.lru_lock);
+               spin_unlock(&glob->lru_lock);
                return r;
        }
        return r;
@@ -352,9 +376,8 @@ static int radeon_bo_move(struct ttm_buffer_object *bo,
                radeon_move_null(bo, new_mem);
                return 0;
        }
-       if (!rdev->cp.ready) {
+       if (!rdev->cp.ready || rdev->asic->copy == NULL) {
                /* use memcpy */
-               DRM_ERROR("CP is not ready use memcpy.\n");
                goto memcpy;
        }
 
@@ -446,7 +469,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
        }
        /* No others user of address space so set it to 0 */
        r = ttm_bo_device_init(&rdev->mman.bdev,
-                              rdev->mman.mem_global_ref.object,
+                              rdev->mman.bo_global_ref.ref.object,
                               &radeon_bo_driver, DRM_FILE_PAGE_OFFSET,
                               rdev->need_dma32);
        if (r) {
@@ -471,7 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
                return r;
        }
        DRM_INFO("radeon: %uM of VRAM memory ready\n",
-                rdev->mc.real_vram_size / (1024 * 1024));
+                (unsigned)rdev->mc.real_vram_size / (1024 * 1024));
        r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0,
                           ((rdev->mc.gtt_size) >> PAGE_SHIFT));
        if (r) {
@@ -479,10 +502,16 @@ int radeon_ttm_init(struct radeon_device *rdev)
                return r;
        }
        DRM_INFO("radeon: %uM of GTT memory ready.\n",
-                rdev->mc.gtt_size / (1024 * 1024));
+                (unsigned)(rdev->mc.gtt_size / (1024 * 1024)));
        if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
                rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
        }
+
+       r = radeon_ttm_debugfs_init(rdev);
+       if (r) {
+               DRM_ERROR("Failed to init debugfs\n");
+               return r;
+       }
        return 0;
 }
 
@@ -501,7 +530,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)
 }
 
 static struct vm_operations_struct radeon_ttm_vm_ops;
-static struct vm_operations_struct *ttm_vm_ops = NULL;
+static const struct vm_operations_struct *ttm_vm_ops = NULL;
 
 static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
@@ -657,3 +686,49 @@ struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev)
        gtt->bound = false;
        return &gtt->backend;
 }
+
+#define RADEON_DEBUGFS_MEM_TYPES 2
+
+#if defined(CONFIG_DEBUG_FS)
+static int radeon_mm_dump_table(struct seq_file *m, void *data)
+{
+       struct drm_info_node *node = (struct drm_info_node *)m->private;
+       struct drm_mm *mm = (struct drm_mm *)node->info_ent->data;
+       struct drm_device *dev = node->minor->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       int ret;
+       struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+
+       spin_lock(&glob->lru_lock);
+       ret = drm_mm_dump_table(m, mm);
+       spin_unlock(&glob->lru_lock);
+       return ret;
+}
+#endif
+
+static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+       static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES];
+       static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32];
+       unsigned i;
+
+       for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) {
+               if (i == 0)
+                       sprintf(radeon_mem_types_names[i], "radeon_vram_mm");
+               else
+                       sprintf(radeon_mem_types_names[i], "radeon_gtt_mm");
+               radeon_mem_types_list[i].name = radeon_mem_types_names[i];
+               radeon_mem_types_list[i].show = &radeon_mm_dump_table;
+               radeon_mem_types_list[i].driver_features = 0;
+               if (i == 0)
+                       radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].manager;
+               else
+                       radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].manager;
+
+       }
+       return radeon_debugfs_add_files(rdev, radeon_mem_types_list, RADEON_DEBUGFS_MEM_TYPES);
+
+#endif
+       return 0;
+}