aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
diff options
context:
space:
mode:
authorFelix Kuehling <Felix.Kuehling@amd.com>2017-07-03 14:18:27 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-07-25 16:29:18 -0400
commite342610c9a9b36459c5be107cb0b7c338404fcc3 (patch)
treeac3ac00d5fc7fa7de1bd8d325e0ff5eb00f99d7c /drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
parent09ac4fcb3f255e9225967c75f5893325c116cdbe (diff)
drm/amdgpu: Implement ttm_bo_driver.access_memory callback v2
Allows gdb to access contents of user mode mapped VRAM BOs. v2: return error for non-VRAM pools Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index da8b0e15a30c..e6f9a54c959d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1115,6 +1115,67 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
1115 return ttm_bo_eviction_valuable(bo, place); 1115 return ttm_bo_eviction_valuable(bo, place);
1116} 1116}
1117 1117
1118static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
1119 unsigned long offset,
1120 void *buf, int len, int write)
1121{
1122 struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo);
1123 struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
1124 struct drm_mm_node *nodes = abo->tbo.mem.mm_node;
1125 uint32_t value = 0;
1126 int ret = 0;
1127 uint64_t pos;
1128 unsigned long flags;
1129
1130 if (bo->mem.mem_type != TTM_PL_VRAM)
1131 return -EIO;
1132
1133 while (offset >= (nodes->size << PAGE_SHIFT)) {
1134 offset -= nodes->size << PAGE_SHIFT;
1135 ++nodes;
1136 }
1137 pos = (nodes->start << PAGE_SHIFT) + offset;
1138
1139 while (len && pos < adev->mc.mc_vram_size) {
1140 uint64_t aligned_pos = pos & ~(uint64_t)3;
1141 uint32_t bytes = 4 - (pos & 3);
1142 uint32_t shift = (pos & 3) * 8;
1143 uint32_t mask = 0xffffffff << shift;
1144
1145 if (len < bytes) {
1146 mask &= 0xffffffff >> (bytes - len) * 8;
1147 bytes = len;
1148 }
1149
1150 spin_lock_irqsave(&adev->mmio_idx_lock, flags);
1151 WREG32(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000);
1152 WREG32(mmMM_INDEX_HI, aligned_pos >> 31);
1153 if (!write || mask != 0xffffffff)
1154 value = RREG32(mmMM_DATA);
1155 if (write) {
1156 value &= ~mask;
1157 value |= (*(uint32_t *)buf << shift) & mask;
1158 WREG32(mmMM_DATA, value);
1159 }
1160 spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
1161 if (!write) {
1162 value = (value & mask) >> shift;
1163 memcpy(buf, &value, bytes);
1164 }
1165
1166 ret += bytes;
1167 buf = (uint8_t *)buf + bytes;
1168 pos += bytes;
1169 len -= bytes;
1170 if (pos >= (nodes->start + nodes->size) << PAGE_SHIFT) {
1171 ++nodes;
1172 pos = (nodes->start << PAGE_SHIFT);
1173 }
1174 }
1175
1176 return ret;
1177}
1178
1118static struct ttm_bo_driver amdgpu_bo_driver = { 1179static struct ttm_bo_driver amdgpu_bo_driver = {
1119 .ttm_tt_create = &amdgpu_ttm_tt_create, 1180 .ttm_tt_create = &amdgpu_ttm_tt_create,
1120 .ttm_tt_populate = &amdgpu_ttm_tt_populate, 1181 .ttm_tt_populate = &amdgpu_ttm_tt_populate,
@@ -1130,6 +1191,7 @@ static struct ttm_bo_driver amdgpu_bo_driver = {
1130 .io_mem_reserve = &amdgpu_ttm_io_mem_reserve, 1191 .io_mem_reserve = &amdgpu_ttm_io_mem_reserve,
1131 .io_mem_free = &amdgpu_ttm_io_mem_free, 1192 .io_mem_free = &amdgpu_ttm_io_mem_free,
1132 .io_mem_pfn = amdgpu_ttm_io_mem_pfn, 1193 .io_mem_pfn = amdgpu_ttm_io_mem_pfn,
1194 .access_memory = &amdgpu_ttm_access_memory
1133}; 1195};
1134 1196
1135int amdgpu_ttm_init(struct amdgpu_device *adev) 1197int amdgpu_ttm_init(struct amdgpu_device *adev)