diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_ttm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ttm.c | 122 |
1 files changed, 76 insertions, 46 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 1381e06d6af3..d031b6863082 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <drm/drmP.h> | 36 | #include <drm/drmP.h> |
37 | #include <drm/radeon_drm.h> | 37 | #include <drm/radeon_drm.h> |
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/slab.h> | ||
39 | #include "radeon_reg.h" | 40 | #include "radeon_reg.h" |
40 | #include "radeon.h" | 41 | #include "radeon.h" |
41 | 42 | ||
@@ -150,7 +151,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
150 | man->default_caching = TTM_PL_FLAG_CACHED; | 151 | man->default_caching = TTM_PL_FLAG_CACHED; |
151 | break; | 152 | break; |
152 | case TTM_PL_TT: | 153 | case TTM_PL_TT: |
153 | man->gpu_offset = 0; | 154 | man->gpu_offset = rdev->mc.gtt_start; |
154 | man->available_caching = TTM_PL_MASK_CACHING; | 155 | man->available_caching = TTM_PL_MASK_CACHING; |
155 | man->default_caching = TTM_PL_FLAG_CACHED; | 156 | man->default_caching = TTM_PL_FLAG_CACHED; |
156 | man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; | 157 | man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; |
@@ -180,7 +181,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
180 | break; | 181 | break; |
181 | case TTM_PL_VRAM: | 182 | case TTM_PL_VRAM: |
182 | /* "On-card" video ram */ | 183 | /* "On-card" video ram */ |
183 | man->gpu_offset = 0; | 184 | man->gpu_offset = rdev->mc.vram_start; |
184 | man->flags = TTM_MEMTYPE_FLAG_FIXED | | 185 | man->flags = TTM_MEMTYPE_FLAG_FIXED | |
185 | TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | | 186 | TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | |
186 | TTM_MEMTYPE_FLAG_MAPPABLE; | 187 | TTM_MEMTYPE_FLAG_MAPPABLE; |
@@ -197,16 +198,34 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
197 | return 0; | 198 | return 0; |
198 | } | 199 | } |
199 | 200 | ||
200 | static uint32_t radeon_evict_flags(struct ttm_buffer_object *bo) | 201 | static void radeon_evict_flags(struct ttm_buffer_object *bo, |
202 | struct ttm_placement *placement) | ||
201 | { | 203 | { |
202 | uint32_t cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEMTYPE; | 204 | struct radeon_bo *rbo; |
205 | static u32 placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; | ||
203 | 206 | ||
207 | if (!radeon_ttm_bo_is_radeon_bo(bo)) { | ||
208 | placement->fpfn = 0; | ||
209 | placement->lpfn = 0; | ||
210 | placement->placement = &placements; | ||
211 | placement->busy_placement = &placements; | ||
212 | placement->num_placement = 1; | ||
213 | placement->num_busy_placement = 1; | ||
214 | return; | ||
215 | } | ||
216 | rbo = container_of(bo, struct radeon_bo, tbo); | ||
204 | switch (bo->mem.mem_type) { | 217 | switch (bo->mem.mem_type) { |
218 | case TTM_PL_VRAM: | ||
219 | if (rbo->rdev->cp.ready == false) | ||
220 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); | ||
221 | else | ||
222 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); | ||
223 | break; | ||
224 | case TTM_PL_TT: | ||
205 | default: | 225 | default: |
206 | return (cur_placement & ~TTM_PL_MASK_CACHING) | | 226 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); |
207 | TTM_PL_FLAG_SYSTEM | | ||
208 | TTM_PL_FLAG_CACHED; | ||
209 | } | 227 | } |
228 | *placement = rbo->placement; | ||
210 | } | 229 | } |
211 | 230 | ||
212 | static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) | 231 | static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) |
@@ -244,10 +263,10 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
244 | 263 | ||
245 | switch (old_mem->mem_type) { | 264 | switch (old_mem->mem_type) { |
246 | case TTM_PL_VRAM: | 265 | case TTM_PL_VRAM: |
247 | old_start += rdev->mc.vram_location; | 266 | old_start += rdev->mc.vram_start; |
248 | break; | 267 | break; |
249 | case TTM_PL_TT: | 268 | case TTM_PL_TT: |
250 | old_start += rdev->mc.gtt_location; | 269 | old_start += rdev->mc.gtt_start; |
251 | break; | 270 | break; |
252 | default: | 271 | default: |
253 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); | 272 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); |
@@ -255,10 +274,10 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
255 | } | 274 | } |
256 | switch (new_mem->mem_type) { | 275 | switch (new_mem->mem_type) { |
257 | case TTM_PL_VRAM: | 276 | case TTM_PL_VRAM: |
258 | new_start += rdev->mc.vram_location; | 277 | new_start += rdev->mc.vram_start; |
259 | break; | 278 | break; |
260 | case TTM_PL_TT: | 279 | case TTM_PL_TT: |
261 | new_start += rdev->mc.gtt_location; | 280 | new_start += rdev->mc.gtt_start; |
262 | break; | 281 | break; |
263 | default: | 282 | default: |
264 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); | 283 | DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); |
@@ -283,14 +302,21 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, | |||
283 | struct radeon_device *rdev; | 302 | struct radeon_device *rdev; |
284 | struct ttm_mem_reg *old_mem = &bo->mem; | 303 | struct ttm_mem_reg *old_mem = &bo->mem; |
285 | struct ttm_mem_reg tmp_mem; | 304 | struct ttm_mem_reg tmp_mem; |
286 | uint32_t proposed_placement; | 305 | u32 placements; |
306 | struct ttm_placement placement; | ||
287 | int r; | 307 | int r; |
288 | 308 | ||
289 | rdev = radeon_get_rdev(bo->bdev); | 309 | rdev = radeon_get_rdev(bo->bdev); |
290 | tmp_mem = *new_mem; | 310 | tmp_mem = *new_mem; |
291 | tmp_mem.mm_node = NULL; | 311 | tmp_mem.mm_node = NULL; |
292 | proposed_placement = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | 312 | placement.fpfn = 0; |
293 | r = ttm_bo_mem_space(bo, proposed_placement, &tmp_mem, | 313 | placement.lpfn = 0; |
314 | placement.num_placement = 1; | ||
315 | placement.placement = &placements; | ||
316 | placement.num_busy_placement = 1; | ||
317 | placement.busy_placement = &placements; | ||
318 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; | ||
319 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, | ||
294 | interruptible, no_wait); | 320 | interruptible, no_wait); |
295 | if (unlikely(r)) { | 321 | if (unlikely(r)) { |
296 | return r; | 322 | return r; |
@@ -329,15 +355,21 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, | |||
329 | struct radeon_device *rdev; | 355 | struct radeon_device *rdev; |
330 | struct ttm_mem_reg *old_mem = &bo->mem; | 356 | struct ttm_mem_reg *old_mem = &bo->mem; |
331 | struct ttm_mem_reg tmp_mem; | 357 | struct ttm_mem_reg tmp_mem; |
332 | uint32_t proposed_flags; | 358 | struct ttm_placement placement; |
359 | u32 placements; | ||
333 | int r; | 360 | int r; |
334 | 361 | ||
335 | rdev = radeon_get_rdev(bo->bdev); | 362 | rdev = radeon_get_rdev(bo->bdev); |
336 | tmp_mem = *new_mem; | 363 | tmp_mem = *new_mem; |
337 | tmp_mem.mm_node = NULL; | 364 | tmp_mem.mm_node = NULL; |
338 | proposed_flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | 365 | placement.fpfn = 0; |
339 | r = ttm_bo_mem_space(bo, proposed_flags, &tmp_mem, | 366 | placement.lpfn = 0; |
340 | interruptible, no_wait); | 367 | placement.num_placement = 1; |
368 | placement.placement = &placements; | ||
369 | placement.num_busy_placement = 1; | ||
370 | placement.busy_placement = &placements; | ||
371 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; | ||
372 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait); | ||
341 | if (unlikely(r)) { | 373 | if (unlikely(r)) { |
342 | return r; | 374 | return r; |
343 | } | 375 | } |
@@ -378,7 +410,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, | |||
378 | new_mem->mem_type == TTM_PL_SYSTEM) || | 410 | new_mem->mem_type == TTM_PL_SYSTEM) || |
379 | (old_mem->mem_type == TTM_PL_SYSTEM && | 411 | (old_mem->mem_type == TTM_PL_SYSTEM && |
380 | new_mem->mem_type == TTM_PL_TT)) { | 412 | new_mem->mem_type == TTM_PL_TT)) { |
381 | /* bind is enought */ | 413 | /* bind is enough */ |
382 | radeon_move_null(bo, new_mem); | 414 | radeon_move_null(bo, new_mem); |
383 | return 0; | 415 | return 0; |
384 | } | 416 | } |
@@ -407,18 +439,6 @@ memcpy: | |||
407 | return r; | 439 | return r; |
408 | } | 440 | } |
409 | 441 | ||
410 | const uint32_t radeon_mem_prios[] = { | ||
411 | TTM_PL_VRAM, | ||
412 | TTM_PL_TT, | ||
413 | TTM_PL_SYSTEM, | ||
414 | }; | ||
415 | |||
416 | const uint32_t radeon_busy_prios[] = { | ||
417 | TTM_PL_TT, | ||
418 | TTM_PL_VRAM, | ||
419 | TTM_PL_SYSTEM, | ||
420 | }; | ||
421 | |||
422 | static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg, | 442 | static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg, |
423 | bool lazy, bool interruptible) | 443 | bool lazy, bool interruptible) |
424 | { | 444 | { |
@@ -446,10 +466,6 @@ static bool radeon_sync_obj_signaled(void *sync_obj, void *sync_arg) | |||
446 | } | 466 | } |
447 | 467 | ||
448 | static struct ttm_bo_driver radeon_bo_driver = { | 468 | static struct ttm_bo_driver radeon_bo_driver = { |
449 | .mem_type_prio = radeon_mem_prios, | ||
450 | .mem_busy_prio = radeon_busy_prios, | ||
451 | .num_mem_type_prio = ARRAY_SIZE(radeon_mem_prios), | ||
452 | .num_mem_busy_prio = ARRAY_SIZE(radeon_busy_prios), | ||
453 | .create_ttm_backend_entry = &radeon_create_ttm_backend_entry, | 469 | .create_ttm_backend_entry = &radeon_create_ttm_backend_entry, |
454 | .invalidate_caches = &radeon_invalidate_caches, | 470 | .invalidate_caches = &radeon_invalidate_caches, |
455 | .init_mem_type = &radeon_init_mem_type, | 471 | .init_mem_type = &radeon_init_mem_type, |
@@ -482,27 +498,32 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
482 | DRM_ERROR("failed initializing buffer object driver(%d).\n", r); | 498 | DRM_ERROR("failed initializing buffer object driver(%d).\n", r); |
483 | return r; | 499 | return r; |
484 | } | 500 | } |
485 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, 0, | 501 | rdev->mman.initialized = true; |
486 | ((rdev->mc.real_vram_size) >> PAGE_SHIFT)); | 502 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, |
503 | rdev->mc.real_vram_size >> PAGE_SHIFT); | ||
487 | if (r) { | 504 | if (r) { |
488 | DRM_ERROR("Failed initializing VRAM heap.\n"); | 505 | DRM_ERROR("Failed initializing VRAM heap.\n"); |
489 | return r; | 506 | return r; |
490 | } | 507 | } |
491 | r = radeon_object_create(rdev, NULL, 256 * 1024, true, | 508 | r = radeon_bo_create(rdev, NULL, 256 * 1024, true, |
492 | RADEON_GEM_DOMAIN_VRAM, false, | 509 | RADEON_GEM_DOMAIN_VRAM, |
493 | &rdev->stollen_vga_memory); | 510 | &rdev->stollen_vga_memory); |
494 | if (r) { | 511 | if (r) { |
495 | return r; | 512 | return r; |
496 | } | 513 | } |
497 | r = radeon_object_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL); | 514 | r = radeon_bo_reserve(rdev->stollen_vga_memory, false); |
515 | if (r) | ||
516 | return r; | ||
517 | r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL); | ||
518 | radeon_bo_unreserve(rdev->stollen_vga_memory); | ||
498 | if (r) { | 519 | if (r) { |
499 | radeon_object_unref(&rdev->stollen_vga_memory); | 520 | radeon_bo_unref(&rdev->stollen_vga_memory); |
500 | return r; | 521 | return r; |
501 | } | 522 | } |
502 | DRM_INFO("radeon: %uM of VRAM memory ready\n", | 523 | DRM_INFO("radeon: %uM of VRAM memory ready\n", |
503 | (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); | 524 | (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); |
504 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0, | 525 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, |
505 | ((rdev->mc.gtt_size) >> PAGE_SHIFT)); | 526 | rdev->mc.gtt_size >> PAGE_SHIFT); |
506 | if (r) { | 527 | if (r) { |
507 | DRM_ERROR("Failed initializing GTT heap.\n"); | 528 | DRM_ERROR("Failed initializing GTT heap.\n"); |
508 | return r; | 529 | return r; |
@@ -523,15 +544,24 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
523 | 544 | ||
524 | void radeon_ttm_fini(struct radeon_device *rdev) | 545 | void radeon_ttm_fini(struct radeon_device *rdev) |
525 | { | 546 | { |
547 | int r; | ||
548 | |||
549 | if (!rdev->mman.initialized) | ||
550 | return; | ||
526 | if (rdev->stollen_vga_memory) { | 551 | if (rdev->stollen_vga_memory) { |
527 | radeon_object_unpin(rdev->stollen_vga_memory); | 552 | r = radeon_bo_reserve(rdev->stollen_vga_memory, false); |
528 | radeon_object_unref(&rdev->stollen_vga_memory); | 553 | if (r == 0) { |
554 | radeon_bo_unpin(rdev->stollen_vga_memory); | ||
555 | radeon_bo_unreserve(rdev->stollen_vga_memory); | ||
556 | } | ||
557 | radeon_bo_unref(&rdev->stollen_vga_memory); | ||
529 | } | 558 | } |
530 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM); | 559 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM); |
531 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT); | 560 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT); |
532 | ttm_bo_device_release(&rdev->mman.bdev); | 561 | ttm_bo_device_release(&rdev->mman.bdev); |
533 | radeon_gart_fini(rdev); | 562 | radeon_gart_fini(rdev); |
534 | radeon_ttm_global_fini(rdev); | 563 | radeon_ttm_global_fini(rdev); |
564 | rdev->mman.initialized = false; | ||
535 | DRM_INFO("radeon: ttm finalized\n"); | 565 | DRM_INFO("radeon: ttm finalized\n"); |
536 | } | 566 | } |
537 | 567 | ||