summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_ttm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_ttm.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c96
1 files changed, 86 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 15c3531377ed..acd889c94549 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -35,11 +35,14 @@
#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;
}
@@ -657,3 +686,50 @@ struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev)
gtt->bound = false;
return &gtt->backend;
}
+
+#define RADEON_DEBUGFS_MEM_TYPES 2
+
+static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES];
+static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32];
+
+#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)
+{
+ unsigned i;
+
+#if defined(CONFIG_DEBUG_FS)
+ 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;
+}