diff options
| author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-07 18:51:13 -0500 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-07 18:51:13 -0500 |
| commit | abaee091a18c19ccd86feb1c8374585d82e96777 (patch) | |
| tree | 01602bae73e1278c3d98dafe1c269049927c58ce /drivers/gpu/drm/amd/amdgpu | |
| parent | a2746fb16e41b7c8f02aa4d2605ecce97abbebbd (diff) | |
| parent | 3f8d6f2a0797e8c650a47e5c1b5c2601a46f4293 (diff) | |
Merge branch 'jejb-scsi' into misc
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
26 files changed, 893 insertions, 453 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 615ce6d464fb..5a5f04d0902d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -389,7 +389,6 @@ struct amdgpu_clock { | |||
| 389 | * Fences. | 389 | * Fences. |
| 390 | */ | 390 | */ |
| 391 | struct amdgpu_fence_driver { | 391 | struct amdgpu_fence_driver { |
| 392 | struct amdgpu_ring *ring; | ||
| 393 | uint64_t gpu_addr; | 392 | uint64_t gpu_addr; |
| 394 | volatile uint32_t *cpu_addr; | 393 | volatile uint32_t *cpu_addr; |
| 395 | /* sync_seq is protected by ring emission lock */ | 394 | /* sync_seq is protected by ring emission lock */ |
| @@ -398,7 +397,7 @@ struct amdgpu_fence_driver { | |||
| 398 | bool initialized; | 397 | bool initialized; |
| 399 | struct amdgpu_irq_src *irq_src; | 398 | struct amdgpu_irq_src *irq_src; |
| 400 | unsigned irq_type; | 399 | unsigned irq_type; |
| 401 | struct delayed_work lockup_work; | 400 | struct timer_list fallback_timer; |
| 402 | wait_queue_head_t fence_queue; | 401 | wait_queue_head_t fence_queue; |
| 403 | }; | 402 | }; |
| 404 | 403 | ||
| @@ -497,6 +496,7 @@ struct amdgpu_bo_va_mapping { | |||
| 497 | 496 | ||
| 498 | /* bo virtual addresses in a specific vm */ | 497 | /* bo virtual addresses in a specific vm */ |
| 499 | struct amdgpu_bo_va { | 498 | struct amdgpu_bo_va { |
| 499 | struct mutex mutex; | ||
| 500 | /* protected by bo being reserved */ | 500 | /* protected by bo being reserved */ |
| 501 | struct list_head bo_list; | 501 | struct list_head bo_list; |
| 502 | struct fence *last_pt_update; | 502 | struct fence *last_pt_update; |
| @@ -539,6 +539,7 @@ struct amdgpu_bo { | |||
| 539 | /* Constant after initialization */ | 539 | /* Constant after initialization */ |
| 540 | struct amdgpu_device *adev; | 540 | struct amdgpu_device *adev; |
| 541 | struct drm_gem_object gem_base; | 541 | struct drm_gem_object gem_base; |
| 542 | struct amdgpu_bo *parent; | ||
| 542 | 543 | ||
| 543 | struct ttm_bo_kmap_obj dma_buf_vmap; | 544 | struct ttm_bo_kmap_obj dma_buf_vmap; |
| 544 | pid_t pid; | 545 | pid_t pid; |
| @@ -917,8 +918,8 @@ struct amdgpu_ring { | |||
| 917 | #define AMDGPU_VM_FAULT_STOP_ALWAYS 2 | 918 | #define AMDGPU_VM_FAULT_STOP_ALWAYS 2 |
| 918 | 919 | ||
| 919 | struct amdgpu_vm_pt { | 920 | struct amdgpu_vm_pt { |
| 920 | struct amdgpu_bo *bo; | 921 | struct amdgpu_bo *bo; |
| 921 | uint64_t addr; | 922 | uint64_t addr; |
| 922 | }; | 923 | }; |
| 923 | 924 | ||
| 924 | struct amdgpu_vm_id { | 925 | struct amdgpu_vm_id { |
| @@ -926,13 +927,9 @@ struct amdgpu_vm_id { | |||
| 926 | uint64_t pd_gpu_addr; | 927 | uint64_t pd_gpu_addr; |
| 927 | /* last flushed PD/PT update */ | 928 | /* last flushed PD/PT update */ |
| 928 | struct fence *flushed_updates; | 929 | struct fence *flushed_updates; |
| 929 | /* last use of vmid */ | ||
| 930 | struct fence *last_id_use; | ||
| 931 | }; | 930 | }; |
| 932 | 931 | ||
| 933 | struct amdgpu_vm { | 932 | struct amdgpu_vm { |
| 934 | struct mutex mutex; | ||
| 935 | |||
| 936 | struct rb_root va; | 933 | struct rb_root va; |
| 937 | 934 | ||
| 938 | /* protecting invalidated */ | 935 | /* protecting invalidated */ |
| @@ -957,24 +954,72 @@ struct amdgpu_vm { | |||
| 957 | 954 | ||
| 958 | /* for id and flush management per ring */ | 955 | /* for id and flush management per ring */ |
| 959 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; | 956 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; |
| 957 | /* for interval tree */ | ||
| 958 | spinlock_t it_lock; | ||
| 959 | /* protecting freed */ | ||
| 960 | spinlock_t freed_lock; | ||
| 960 | }; | 961 | }; |
| 961 | 962 | ||
| 962 | struct amdgpu_vm_manager { | 963 | struct amdgpu_vm_manager { |
| 963 | struct fence *active[AMDGPU_NUM_VM]; | 964 | struct { |
| 964 | uint32_t max_pfn; | 965 | struct fence *active; |
| 966 | atomic_long_t owner; | ||
| 967 | } ids[AMDGPU_NUM_VM]; | ||
| 968 | |||
| 969 | uint32_t max_pfn; | ||
| 965 | /* number of VMIDs */ | 970 | /* number of VMIDs */ |
| 966 | unsigned nvm; | 971 | unsigned nvm; |
| 967 | /* vram base address for page table entry */ | 972 | /* vram base address for page table entry */ |
| 968 | u64 vram_base_offset; | 973 | u64 vram_base_offset; |
| 969 | /* is vm enabled? */ | 974 | /* is vm enabled? */ |
| 970 | bool enabled; | 975 | bool enabled; |
| 971 | /* for hw to save the PD addr on suspend/resume */ | ||
| 972 | uint32_t saved_table_addr[AMDGPU_NUM_VM]; | ||
| 973 | /* vm pte handling */ | 976 | /* vm pte handling */ |
| 974 | const struct amdgpu_vm_pte_funcs *vm_pte_funcs; | 977 | const struct amdgpu_vm_pte_funcs *vm_pte_funcs; |
| 975 | struct amdgpu_ring *vm_pte_funcs_ring; | 978 | struct amdgpu_ring *vm_pte_funcs_ring; |
| 976 | }; | 979 | }; |
| 977 | 980 | ||
| 981 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev); | ||
| 982 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); | ||
| 983 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); | ||
| 984 | struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev, | ||
| 985 | struct amdgpu_vm *vm, | ||
| 986 | struct list_head *head); | ||
| 987 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | ||
| 988 | struct amdgpu_sync *sync); | ||
| 989 | void amdgpu_vm_flush(struct amdgpu_ring *ring, | ||
| 990 | struct amdgpu_vm *vm, | ||
| 991 | struct fence *updates); | ||
| 992 | void amdgpu_vm_fence(struct amdgpu_device *adev, | ||
| 993 | struct amdgpu_vm *vm, | ||
| 994 | struct fence *fence); | ||
| 995 | uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr); | ||
| 996 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | ||
| 997 | struct amdgpu_vm *vm); | ||
| 998 | int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | ||
| 999 | struct amdgpu_vm *vm); | ||
| 1000 | int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, struct amdgpu_vm *vm, | ||
| 1001 | struct amdgpu_sync *sync); | ||
| 1002 | int amdgpu_vm_bo_update(struct amdgpu_device *adev, | ||
| 1003 | struct amdgpu_bo_va *bo_va, | ||
| 1004 | struct ttm_mem_reg *mem); | ||
| 1005 | void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, | ||
| 1006 | struct amdgpu_bo *bo); | ||
| 1007 | struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, | ||
| 1008 | struct amdgpu_bo *bo); | ||
| 1009 | struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, | ||
| 1010 | struct amdgpu_vm *vm, | ||
| 1011 | struct amdgpu_bo *bo); | ||
| 1012 | int amdgpu_vm_bo_map(struct amdgpu_device *adev, | ||
| 1013 | struct amdgpu_bo_va *bo_va, | ||
| 1014 | uint64_t addr, uint64_t offset, | ||
| 1015 | uint64_t size, uint32_t flags); | ||
| 1016 | int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | ||
| 1017 | struct amdgpu_bo_va *bo_va, | ||
| 1018 | uint64_t addr); | ||
| 1019 | void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | ||
| 1020 | struct amdgpu_bo_va *bo_va); | ||
| 1021 | int amdgpu_vm_free_job(struct amdgpu_job *job); | ||
| 1022 | |||
| 978 | /* | 1023 | /* |
| 979 | * context related structures | 1024 | * context related structures |
| 980 | */ | 1025 | */ |
| @@ -1211,6 +1256,7 @@ struct amdgpu_cs_parser { | |||
| 1211 | /* relocations */ | 1256 | /* relocations */ |
| 1212 | struct amdgpu_bo_list_entry *vm_bos; | 1257 | struct amdgpu_bo_list_entry *vm_bos; |
| 1213 | struct list_head validated; | 1258 | struct list_head validated; |
| 1259 | struct fence *fence; | ||
| 1214 | 1260 | ||
| 1215 | struct amdgpu_ib *ibs; | 1261 | struct amdgpu_ib *ibs; |
| 1216 | uint32_t num_ibs; | 1262 | uint32_t num_ibs; |
| @@ -1226,7 +1272,7 @@ struct amdgpu_job { | |||
| 1226 | struct amdgpu_device *adev; | 1272 | struct amdgpu_device *adev; |
| 1227 | struct amdgpu_ib *ibs; | 1273 | struct amdgpu_ib *ibs; |
| 1228 | uint32_t num_ibs; | 1274 | uint32_t num_ibs; |
| 1229 | struct mutex job_lock; | 1275 | void *owner; |
| 1230 | struct amdgpu_user_fence uf; | 1276 | struct amdgpu_user_fence uf; |
| 1231 | int (*free_job)(struct amdgpu_job *job); | 1277 | int (*free_job)(struct amdgpu_job *job); |
| 1232 | }; | 1278 | }; |
| @@ -2257,11 +2303,6 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev); | |||
| 2257 | bool amdgpu_card_posted(struct amdgpu_device *adev); | 2303 | bool amdgpu_card_posted(struct amdgpu_device *adev); |
| 2258 | void amdgpu_update_display_priority(struct amdgpu_device *adev); | 2304 | void amdgpu_update_display_priority(struct amdgpu_device *adev); |
| 2259 | bool amdgpu_boot_test_post_card(struct amdgpu_device *adev); | 2305 | bool amdgpu_boot_test_post_card(struct amdgpu_device *adev); |
| 2260 | struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, | ||
| 2261 | struct drm_file *filp, | ||
| 2262 | struct amdgpu_ctx *ctx, | ||
| 2263 | struct amdgpu_ib *ibs, | ||
| 2264 | uint32_t num_ibs); | ||
| 2265 | 2306 | ||
| 2266 | int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data); | 2307 | int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data); |
| 2267 | int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, | 2308 | int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, |
| @@ -2319,49 +2360,6 @@ long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, | |||
| 2319 | unsigned long arg); | 2360 | unsigned long arg); |
| 2320 | 2361 | ||
| 2321 | /* | 2362 | /* |
| 2322 | * vm | ||
| 2323 | */ | ||
| 2324 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); | ||
| 2325 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); | ||
| 2326 | struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev, | ||
| 2327 | struct amdgpu_vm *vm, | ||
| 2328 | struct list_head *head); | ||
| 2329 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | ||
| 2330 | struct amdgpu_sync *sync); | ||
| 2331 | void amdgpu_vm_flush(struct amdgpu_ring *ring, | ||
| 2332 | struct amdgpu_vm *vm, | ||
| 2333 | struct fence *updates); | ||
| 2334 | void amdgpu_vm_fence(struct amdgpu_device *adev, | ||
| 2335 | struct amdgpu_vm *vm, | ||
| 2336 | struct amdgpu_fence *fence); | ||
| 2337 | uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr); | ||
| 2338 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | ||
| 2339 | struct amdgpu_vm *vm); | ||
| 2340 | int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | ||
| 2341 | struct amdgpu_vm *vm); | ||
| 2342 | int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, | ||
| 2343 | struct amdgpu_vm *vm, struct amdgpu_sync *sync); | ||
| 2344 | int amdgpu_vm_bo_update(struct amdgpu_device *adev, | ||
| 2345 | struct amdgpu_bo_va *bo_va, | ||
| 2346 | struct ttm_mem_reg *mem); | ||
| 2347 | void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, | ||
| 2348 | struct amdgpu_bo *bo); | ||
| 2349 | struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, | ||
| 2350 | struct amdgpu_bo *bo); | ||
| 2351 | struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, | ||
| 2352 | struct amdgpu_vm *vm, | ||
| 2353 | struct amdgpu_bo *bo); | ||
| 2354 | int amdgpu_vm_bo_map(struct amdgpu_device *adev, | ||
| 2355 | struct amdgpu_bo_va *bo_va, | ||
| 2356 | uint64_t addr, uint64_t offset, | ||
| 2357 | uint64_t size, uint32_t flags); | ||
| 2358 | int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | ||
| 2359 | struct amdgpu_bo_va *bo_va, | ||
| 2360 | uint64_t addr); | ||
| 2361 | void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | ||
| 2362 | struct amdgpu_bo_va *bo_va); | ||
| 2363 | int amdgpu_vm_free_job(struct amdgpu_job *job); | ||
| 2364 | /* | ||
| 2365 | * functions used by amdgpu_encoder.c | 2363 | * functions used by amdgpu_encoder.c |
| 2366 | */ | 2364 | */ |
| 2367 | struct amdgpu_afmt_acr { | 2365 | struct amdgpu_afmt_acr { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index dfc4d02c7a38..4f352ec9dec4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
| @@ -127,30 +127,6 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, | |||
| 127 | return 0; | 127 | return 0; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, | ||
| 131 | struct drm_file *filp, | ||
| 132 | struct amdgpu_ctx *ctx, | ||
| 133 | struct amdgpu_ib *ibs, | ||
| 134 | uint32_t num_ibs) | ||
| 135 | { | ||
| 136 | struct amdgpu_cs_parser *parser; | ||
| 137 | int i; | ||
| 138 | |||
| 139 | parser = kzalloc(sizeof(struct amdgpu_cs_parser), GFP_KERNEL); | ||
| 140 | if (!parser) | ||
| 141 | return NULL; | ||
| 142 | |||
| 143 | parser->adev = adev; | ||
| 144 | parser->filp = filp; | ||
| 145 | parser->ctx = ctx; | ||
| 146 | parser->ibs = ibs; | ||
| 147 | parser->num_ibs = num_ibs; | ||
| 148 | for (i = 0; i < num_ibs; i++) | ||
| 149 | ibs[i].ctx = ctx; | ||
| 150 | |||
| 151 | return parser; | ||
| 152 | } | ||
| 153 | |||
| 154 | int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | 130 | int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) |
| 155 | { | 131 | { |
| 156 | union drm_amdgpu_cs *cs = data; | 132 | union drm_amdgpu_cs *cs = data; |
| @@ -246,6 +222,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
| 246 | } | 222 | } |
| 247 | 223 | ||
| 248 | p->uf.bo = gem_to_amdgpu_bo(gobj); | 224 | p->uf.bo = gem_to_amdgpu_bo(gobj); |
| 225 | amdgpu_bo_ref(p->uf.bo); | ||
| 226 | drm_gem_object_unreference_unlocked(gobj); | ||
| 249 | p->uf.offset = fence_data->offset; | 227 | p->uf.offset = fence_data->offset; |
| 250 | } else { | 228 | } else { |
| 251 | ret = -EINVAL; | 229 | ret = -EINVAL; |
| @@ -463,8 +441,18 @@ static int cmp_size_smaller_first(void *priv, struct list_head *a, | |||
| 463 | return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; | 441 | return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; |
| 464 | } | 442 | } |
| 465 | 443 | ||
| 466 | static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int error, bool backoff) | 444 | /** |
| 445 | * cs_parser_fini() - clean parser states | ||
| 446 | * @parser: parser structure holding parsing context. | ||
| 447 | * @error: error number | ||
| 448 | * | ||
| 449 | * If error is set than unvalidate buffer, otherwise just free memory | ||
| 450 | * used by parsing context. | ||
| 451 | **/ | ||
| 452 | static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) | ||
| 467 | { | 453 | { |
| 454 | unsigned i; | ||
| 455 | |||
| 468 | if (!error) { | 456 | if (!error) { |
| 469 | /* Sort the buffer list from the smallest to largest buffer, | 457 | /* Sort the buffer list from the smallest to largest buffer, |
| 470 | * which affects the order of buffers in the LRU list. | 458 | * which affects the order of buffers in the LRU list. |
| @@ -479,17 +467,14 @@ static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int err | |||
| 479 | list_sort(NULL, &parser->validated, cmp_size_smaller_first); | 467 | list_sort(NULL, &parser->validated, cmp_size_smaller_first); |
| 480 | 468 | ||
| 481 | ttm_eu_fence_buffer_objects(&parser->ticket, | 469 | ttm_eu_fence_buffer_objects(&parser->ticket, |
| 482 | &parser->validated, | 470 | &parser->validated, |
| 483 | &parser->ibs[parser->num_ibs-1].fence->base); | 471 | parser->fence); |
| 484 | } else if (backoff) { | 472 | } else if (backoff) { |
| 485 | ttm_eu_backoff_reservation(&parser->ticket, | 473 | ttm_eu_backoff_reservation(&parser->ticket, |
| 486 | &parser->validated); | 474 | &parser->validated); |
| 487 | } | 475 | } |
| 488 | } | 476 | fence_put(parser->fence); |
| 489 | 477 | ||
| 490 | static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) | ||
| 491 | { | ||
| 492 | unsigned i; | ||
| 493 | if (parser->ctx) | 478 | if (parser->ctx) |
| 494 | amdgpu_ctx_put(parser->ctx); | 479 | amdgpu_ctx_put(parser->ctx); |
| 495 | if (parser->bo_list) | 480 | if (parser->bo_list) |
| @@ -499,31 +484,12 @@ static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) | |||
| 499 | for (i = 0; i < parser->nchunks; i++) | 484 | for (i = 0; i < parser->nchunks; i++) |
| 500 | drm_free_large(parser->chunks[i].kdata); | 485 | drm_free_large(parser->chunks[i].kdata); |
| 501 | kfree(parser->chunks); | 486 | kfree(parser->chunks); |
| 502 | if (!amdgpu_enable_scheduler) | 487 | if (parser->ibs) |
| 503 | { | 488 | for (i = 0; i < parser->num_ibs; i++) |
| 504 | if (parser->ibs) | 489 | amdgpu_ib_free(parser->adev, &parser->ibs[i]); |
| 505 | for (i = 0; i < parser->num_ibs; i++) | 490 | kfree(parser->ibs); |
| 506 | amdgpu_ib_free(parser->adev, &parser->ibs[i]); | 491 | if (parser->uf.bo) |
| 507 | kfree(parser->ibs); | 492 | amdgpu_bo_unref(&parser->uf.bo); |
| 508 | if (parser->uf.bo) | ||
| 509 | drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); | ||
| 510 | } | ||
| 511 | |||
| 512 | kfree(parser); | ||
| 513 | } | ||
| 514 | |||
| 515 | /** | ||
| 516 | * cs_parser_fini() - clean parser states | ||
| 517 | * @parser: parser structure holding parsing context. | ||
| 518 | * @error: error number | ||
| 519 | * | ||
| 520 | * If error is set than unvalidate buffer, otherwise just free memory | ||
| 521 | * used by parsing context. | ||
| 522 | **/ | ||
| 523 | static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) | ||
| 524 | { | ||
| 525 | amdgpu_cs_parser_fini_early(parser, error, backoff); | ||
| 526 | amdgpu_cs_parser_fini_late(parser); | ||
| 527 | } | 493 | } |
| 528 | 494 | ||
| 529 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, | 495 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, |
| @@ -610,15 +576,9 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
| 610 | } | 576 | } |
| 611 | 577 | ||
| 612 | r = amdgpu_bo_vm_update_pte(parser, vm); | 578 | r = amdgpu_bo_vm_update_pte(parser, vm); |
| 613 | if (r) { | 579 | if (!r) |
| 614 | goto out; | 580 | amdgpu_cs_sync_rings(parser); |
| 615 | } | ||
| 616 | amdgpu_cs_sync_rings(parser); | ||
| 617 | if (!amdgpu_enable_scheduler) | ||
| 618 | r = amdgpu_ib_schedule(adev, parser->num_ibs, parser->ibs, | ||
| 619 | parser->filp); | ||
| 620 | 581 | ||
| 621 | out: | ||
| 622 | return r; | 582 | return r; |
| 623 | } | 583 | } |
| 624 | 584 | ||
| @@ -818,7 +778,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job) | |||
| 818 | amdgpu_ib_free(job->adev, &job->ibs[i]); | 778 | amdgpu_ib_free(job->adev, &job->ibs[i]); |
| 819 | kfree(job->ibs); | 779 | kfree(job->ibs); |
| 820 | if (job->uf.bo) | 780 | if (job->uf.bo) |
| 821 | drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base); | 781 | amdgpu_bo_unref(&job->uf.bo); |
| 822 | return 0; | 782 | return 0; |
| 823 | } | 783 | } |
| 824 | 784 | ||
| @@ -826,38 +786,35 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 826 | { | 786 | { |
| 827 | struct amdgpu_device *adev = dev->dev_private; | 787 | struct amdgpu_device *adev = dev->dev_private; |
| 828 | union drm_amdgpu_cs *cs = data; | 788 | union drm_amdgpu_cs *cs = data; |
| 829 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | 789 | struct amdgpu_cs_parser parser = {}; |
| 830 | struct amdgpu_vm *vm = &fpriv->vm; | ||
| 831 | struct amdgpu_cs_parser *parser; | ||
| 832 | bool reserved_buffers = false; | 790 | bool reserved_buffers = false; |
| 833 | int i, r; | 791 | int i, r; |
| 834 | 792 | ||
| 835 | if (!adev->accel_working) | 793 | if (!adev->accel_working) |
| 836 | return -EBUSY; | 794 | return -EBUSY; |
| 837 | 795 | ||
| 838 | parser = amdgpu_cs_parser_create(adev, filp, NULL, NULL, 0); | 796 | parser.adev = adev; |
| 839 | if (!parser) | 797 | parser.filp = filp; |
| 840 | return -ENOMEM; | 798 | |
| 841 | r = amdgpu_cs_parser_init(parser, data); | 799 | r = amdgpu_cs_parser_init(&parser, data); |
| 842 | if (r) { | 800 | if (r) { |
| 843 | DRM_ERROR("Failed to initialize parser !\n"); | 801 | DRM_ERROR("Failed to initialize parser !\n"); |
| 844 | amdgpu_cs_parser_fini(parser, r, false); | 802 | amdgpu_cs_parser_fini(&parser, r, false); |
| 845 | r = amdgpu_cs_handle_lockup(adev, r); | 803 | r = amdgpu_cs_handle_lockup(adev, r); |
| 846 | return r; | 804 | return r; |
| 847 | } | 805 | } |
| 848 | mutex_lock(&vm->mutex); | 806 | r = amdgpu_cs_parser_relocs(&parser); |
| 849 | r = amdgpu_cs_parser_relocs(parser); | ||
| 850 | if (r == -ENOMEM) | 807 | if (r == -ENOMEM) |
| 851 | DRM_ERROR("Not enough memory for command submission!\n"); | 808 | DRM_ERROR("Not enough memory for command submission!\n"); |
| 852 | else if (r && r != -ERESTARTSYS) | 809 | else if (r && r != -ERESTARTSYS) |
| 853 | DRM_ERROR("Failed to process the buffer list %d!\n", r); | 810 | DRM_ERROR("Failed to process the buffer list %d!\n", r); |
| 854 | else if (!r) { | 811 | else if (!r) { |
| 855 | reserved_buffers = true; | 812 | reserved_buffers = true; |
| 856 | r = amdgpu_cs_ib_fill(adev, parser); | 813 | r = amdgpu_cs_ib_fill(adev, &parser); |
| 857 | } | 814 | } |
| 858 | 815 | ||
| 859 | if (!r) { | 816 | if (!r) { |
| 860 | r = amdgpu_cs_dependencies(adev, parser); | 817 | r = amdgpu_cs_dependencies(adev, &parser); |
| 861 | if (r) | 818 | if (r) |
| 862 | DRM_ERROR("Failed in the dependencies handling %d!\n", r); | 819 | DRM_ERROR("Failed in the dependencies handling %d!\n", r); |
| 863 | } | 820 | } |
| @@ -865,63 +822,71 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 865 | if (r) | 822 | if (r) |
| 866 | goto out; | 823 | goto out; |
| 867 | 824 | ||
| 868 | for (i = 0; i < parser->num_ibs; i++) | 825 | for (i = 0; i < parser.num_ibs; i++) |
| 869 | trace_amdgpu_cs(parser, i); | 826 | trace_amdgpu_cs(&parser, i); |
| 870 | 827 | ||
| 871 | r = amdgpu_cs_ib_vm_chunk(adev, parser); | 828 | r = amdgpu_cs_ib_vm_chunk(adev, &parser); |
| 872 | if (r) | 829 | if (r) |
| 873 | goto out; | 830 | goto out; |
| 874 | 831 | ||
| 875 | if (amdgpu_enable_scheduler && parser->num_ibs) { | 832 | if (amdgpu_enable_scheduler && parser.num_ibs) { |
| 833 | struct amdgpu_ring * ring = parser.ibs->ring; | ||
| 834 | struct amd_sched_fence *fence; | ||
| 876 | struct amdgpu_job *job; | 835 | struct amdgpu_job *job; |
| 877 | struct amdgpu_ring * ring = parser->ibs->ring; | 836 | |
| 878 | job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); | 837 | job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); |
| 879 | if (!job) { | 838 | if (!job) { |
| 880 | r = -ENOMEM; | 839 | r = -ENOMEM; |
| 881 | goto out; | 840 | goto out; |
| 882 | } | 841 | } |
| 842 | |||
| 883 | job->base.sched = &ring->sched; | 843 | job->base.sched = &ring->sched; |
| 884 | job->base.s_entity = &parser->ctx->rings[ring->idx].entity; | 844 | job->base.s_entity = &parser.ctx->rings[ring->idx].entity; |
| 885 | job->adev = parser->adev; | 845 | job->adev = parser.adev; |
| 886 | job->ibs = parser->ibs; | 846 | job->owner = parser.filp; |
| 887 | job->num_ibs = parser->num_ibs; | 847 | job->free_job = amdgpu_cs_free_job; |
| 888 | job->base.owner = parser->filp; | 848 | |
| 889 | mutex_init(&job->job_lock); | 849 | job->ibs = parser.ibs; |
| 850 | job->num_ibs = parser.num_ibs; | ||
| 851 | parser.ibs = NULL; | ||
| 852 | parser.num_ibs = 0; | ||
| 853 | |||
| 890 | if (job->ibs[job->num_ibs - 1].user) { | 854 | if (job->ibs[job->num_ibs - 1].user) { |
| 891 | memcpy(&job->uf, &parser->uf, | 855 | job->uf = parser.uf; |
| 892 | sizeof(struct amdgpu_user_fence)); | ||
| 893 | job->ibs[job->num_ibs - 1].user = &job->uf; | 856 | job->ibs[job->num_ibs - 1].user = &job->uf; |
| 857 | parser.uf.bo = NULL; | ||
| 894 | } | 858 | } |
| 895 | 859 | ||
| 896 | job->free_job = amdgpu_cs_free_job; | 860 | fence = amd_sched_fence_create(job->base.s_entity, |
| 897 | mutex_lock(&job->job_lock); | 861 | parser.filp); |
| 898 | r = amd_sched_entity_push_job(&job->base); | 862 | if (!fence) { |
| 899 | if (r) { | 863 | r = -ENOMEM; |
| 900 | mutex_unlock(&job->job_lock); | ||
| 901 | amdgpu_cs_free_job(job); | 864 | amdgpu_cs_free_job(job); |
| 902 | kfree(job); | 865 | kfree(job); |
| 903 | goto out; | 866 | goto out; |
| 904 | } | 867 | } |
| 905 | cs->out.handle = | 868 | job->base.s_fence = fence; |
| 906 | amdgpu_ctx_add_fence(parser->ctx, ring, | 869 | parser.fence = fence_get(&fence->base); |
| 907 | &job->base.s_fence->base); | ||
| 908 | parser->ibs[parser->num_ibs - 1].sequence = cs->out.handle; | ||
| 909 | 870 | ||
| 910 | list_sort(NULL, &parser->validated, cmp_size_smaller_first); | 871 | cs->out.handle = amdgpu_ctx_add_fence(parser.ctx, ring, |
| 911 | ttm_eu_fence_buffer_objects(&parser->ticket, | 872 | &fence->base); |
| 912 | &parser->validated, | 873 | job->ibs[job->num_ibs - 1].sequence = cs->out.handle; |
| 913 | &job->base.s_fence->base); | ||
| 914 | 874 | ||
| 915 | mutex_unlock(&job->job_lock); | 875 | trace_amdgpu_cs_ioctl(job); |
| 916 | amdgpu_cs_parser_fini_late(parser); | 876 | amd_sched_entity_push_job(&job->base); |
| 917 | mutex_unlock(&vm->mutex); | 877 | |
| 918 | return 0; | 878 | } else { |
| 879 | struct amdgpu_fence *fence; | ||
| 880 | |||
| 881 | r = amdgpu_ib_schedule(adev, parser.num_ibs, parser.ibs, | ||
| 882 | parser.filp); | ||
| 883 | fence = parser.ibs[parser.num_ibs - 1].fence; | ||
| 884 | parser.fence = fence_get(&fence->base); | ||
| 885 | cs->out.handle = parser.ibs[parser.num_ibs - 1].sequence; | ||
| 919 | } | 886 | } |
| 920 | 887 | ||
| 921 | cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; | ||
| 922 | out: | 888 | out: |
| 923 | amdgpu_cs_parser_fini(parser, r, reserved_buffers); | 889 | amdgpu_cs_parser_fini(&parser, r, reserved_buffers); |
| 924 | mutex_unlock(&vm->mutex); | ||
| 925 | r = amdgpu_cs_handle_lockup(adev, r); | 890 | r = amdgpu_cs_handle_lockup(adev, r); |
| 926 | return r; | 891 | return r; |
| 927 | } | 892 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e173a5a02f0d..5580d3420c3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |||
| @@ -73,6 +73,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work) | |||
| 73 | struct drm_crtc *crtc = &amdgpuCrtc->base; | 73 | struct drm_crtc *crtc = &amdgpuCrtc->base; |
| 74 | unsigned long flags; | 74 | unsigned long flags; |
| 75 | unsigned i; | 75 | unsigned i; |
| 76 | int vpos, hpos, stat, min_udelay; | ||
| 77 | struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; | ||
| 76 | 78 | ||
| 77 | amdgpu_flip_wait_fence(adev, &work->excl); | 79 | amdgpu_flip_wait_fence(adev, &work->excl); |
| 78 | for (i = 0; i < work->shared_count; ++i) | 80 | for (i = 0; i < work->shared_count; ++i) |
| @@ -81,6 +83,41 @@ static void amdgpu_flip_work_func(struct work_struct *__work) | |||
| 81 | /* We borrow the event spin lock for protecting flip_status */ | 83 | /* We borrow the event spin lock for protecting flip_status */ |
| 82 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | 84 | spin_lock_irqsave(&crtc->dev->event_lock, flags); |
| 83 | 85 | ||
| 86 | /* If this happens to execute within the "virtually extended" vblank | ||
| 87 | * interval before the start of the real vblank interval then it needs | ||
| 88 | * to delay programming the mmio flip until the real vblank is entered. | ||
| 89 | * This prevents completing a flip too early due to the way we fudge | ||
| 90 | * our vblank counter and vblank timestamps in order to work around the | ||
| 91 | * problem that the hw fires vblank interrupts before actual start of | ||
| 92 | * vblank (when line buffer refilling is done for a frame). It | ||
| 93 | * complements the fudging logic in amdgpu_get_crtc_scanoutpos() for | ||
| 94 | * timestamping and amdgpu_get_vblank_counter_kms() for vblank counts. | ||
| 95 | * | ||
| 96 | * In practice this won't execute very often unless on very fast | ||
| 97 | * machines because the time window for this to happen is very small. | ||
| 98 | */ | ||
| 99 | for (;;) { | ||
| 100 | /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank | ||
| 101 | * start in hpos, and to the "fudged earlier" vblank start in | ||
| 102 | * vpos. | ||
| 103 | */ | ||
| 104 | stat = amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, | ||
| 105 | GET_DISTANCE_TO_VBLANKSTART, | ||
| 106 | &vpos, &hpos, NULL, NULL, | ||
| 107 | &crtc->hwmode); | ||
| 108 | |||
| 109 | if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != | ||
| 110 | (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) || | ||
| 111 | !(vpos >= 0 && hpos <= 0)) | ||
| 112 | break; | ||
| 113 | |||
| 114 | /* Sleep at least until estimated real start of hw vblank */ | ||
| 115 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
| 116 | min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); | ||
| 117 | usleep_range(min_udelay, 2 * min_udelay); | ||
| 118 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
| 119 | }; | ||
| 120 | |||
| 84 | /* do the flip (mmio) */ | 121 | /* do the flip (mmio) */ |
| 85 | adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); | 122 | adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); |
| 86 | /* set the flip status */ | 123 | /* set the flip status */ |
| @@ -109,7 +146,7 @@ static void amdgpu_unpin_work_func(struct work_struct *__work) | |||
| 109 | } else | 146 | } else |
| 110 | DRM_ERROR("failed to reserve buffer after flip\n"); | 147 | DRM_ERROR("failed to reserve buffer after flip\n"); |
| 111 | 148 | ||
| 112 | drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); | 149 | amdgpu_bo_unref(&work->old_rbo); |
| 113 | kfree(work->shared); | 150 | kfree(work->shared); |
| 114 | kfree(work); | 151 | kfree(work); |
| 115 | } | 152 | } |
| @@ -148,8 +185,8 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, | |||
| 148 | obj = old_amdgpu_fb->obj; | 185 | obj = old_amdgpu_fb->obj; |
| 149 | 186 | ||
| 150 | /* take a reference to the old object */ | 187 | /* take a reference to the old object */ |
| 151 | drm_gem_object_reference(obj); | ||
| 152 | work->old_rbo = gem_to_amdgpu_bo(obj); | 188 | work->old_rbo = gem_to_amdgpu_bo(obj); |
| 189 | amdgpu_bo_ref(work->old_rbo); | ||
| 153 | 190 | ||
| 154 | new_amdgpu_fb = to_amdgpu_framebuffer(fb); | 191 | new_amdgpu_fb = to_amdgpu_framebuffer(fb); |
| 155 | obj = new_amdgpu_fb->obj; | 192 | obj = new_amdgpu_fb->obj; |
| @@ -222,7 +259,7 @@ pflip_cleanup: | |||
| 222 | amdgpu_bo_unreserve(new_rbo); | 259 | amdgpu_bo_unreserve(new_rbo); |
| 223 | 260 | ||
| 224 | cleanup: | 261 | cleanup: |
| 225 | drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); | 262 | amdgpu_bo_unref(&work->old_rbo); |
| 226 | fence_put(work->excl); | 263 | fence_put(work->excl); |
| 227 | for (i = 0; i < work->shared_count; ++i) | 264 | for (i = 0; i < work->shared_count; ++i) |
| 228 | fence_put(work->shared[i]); | 265 | fence_put(work->shared[i]); |
| @@ -712,6 +749,15 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
| 712 | * \param dev Device to query. | 749 | * \param dev Device to query. |
| 713 | * \param pipe Crtc to query. | 750 | * \param pipe Crtc to query. |
| 714 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). | 751 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). |
| 752 | * For driver internal use only also supports these flags: | ||
| 753 | * | ||
| 754 | * USE_REAL_VBLANKSTART to use the real start of vblank instead | ||
| 755 | * of a fudged earlier start of vblank. | ||
| 756 | * | ||
| 757 | * GET_DISTANCE_TO_VBLANKSTART to return distance to the | ||
| 758 | * fudged earlier start of vblank in *vpos and the distance | ||
| 759 | * to true start of vblank in *hpos. | ||
| 760 | * | ||
| 715 | * \param *vpos Location where vertical scanout position should be stored. | 761 | * \param *vpos Location where vertical scanout position should be stored. |
| 716 | * \param *hpos Location where horizontal scanout position should go. | 762 | * \param *hpos Location where horizontal scanout position should go. |
| 717 | * \param *stime Target location for timestamp taken immediately before | 763 | * \param *stime Target location for timestamp taken immediately before |
| @@ -776,10 +822,40 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 776 | vbl_end = 0; | 822 | vbl_end = 0; |
| 777 | } | 823 | } |
| 778 | 824 | ||
| 825 | /* Called from driver internal vblank counter query code? */ | ||
| 826 | if (flags & GET_DISTANCE_TO_VBLANKSTART) { | ||
| 827 | /* Caller wants distance from real vbl_start in *hpos */ | ||
| 828 | *hpos = *vpos - vbl_start; | ||
| 829 | } | ||
| 830 | |||
| 831 | /* Fudge vblank to start a few scanlines earlier to handle the | ||
| 832 | * problem that vblank irqs fire a few scanlines before start | ||
| 833 | * of vblank. Some driver internal callers need the true vblank | ||
| 834 | * start to be used and signal this via the USE_REAL_VBLANKSTART flag. | ||
| 835 | * | ||
| 836 | * The cause of the "early" vblank irq is that the irq is triggered | ||
| 837 | * by the line buffer logic when the line buffer read position enters | ||
| 838 | * the vblank, whereas our crtc scanout position naturally lags the | ||
| 839 | * line buffer read position. | ||
| 840 | */ | ||
| 841 | if (!(flags & USE_REAL_VBLANKSTART)) | ||
| 842 | vbl_start -= adev->mode_info.crtcs[pipe]->lb_vblank_lead_lines; | ||
| 843 | |||
| 779 | /* Test scanout position against vblank region. */ | 844 | /* Test scanout position against vblank region. */ |
| 780 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) | 845 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) |
| 781 | in_vbl = false; | 846 | in_vbl = false; |
| 782 | 847 | ||
| 848 | /* In vblank? */ | ||
| 849 | if (in_vbl) | ||
| 850 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 851 | |||
| 852 | /* Called from driver internal vblank counter query code? */ | ||
| 853 | if (flags & GET_DISTANCE_TO_VBLANKSTART) { | ||
| 854 | /* Caller wants distance from fudged earlier vbl_start */ | ||
| 855 | *vpos -= vbl_start; | ||
| 856 | return ret; | ||
| 857 | } | ||
| 858 | |||
| 783 | /* Check if inside vblank area and apply corrective offsets: | 859 | /* Check if inside vblank area and apply corrective offsets: |
| 784 | * vpos will then be >=0 in video scanout area, but negative | 860 | * vpos will then be >=0 in video scanout area, but negative |
| 785 | * within vblank area, counting down the number of lines until | 861 | * within vblank area, counting down the number of lines until |
| @@ -795,32 +871,6 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 795 | /* Correct for shifted end of vbl at vbl_end. */ | 871 | /* Correct for shifted end of vbl at vbl_end. */ |
| 796 | *vpos = *vpos - vbl_end; | 872 | *vpos = *vpos - vbl_end; |
| 797 | 873 | ||
| 798 | /* In vblank? */ | ||
| 799 | if (in_vbl) | ||
| 800 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 801 | |||
| 802 | /* Is vpos outside nominal vblank area, but less than | ||
| 803 | * 1/100 of a frame height away from start of vblank? | ||
| 804 | * If so, assume this isn't a massively delayed vblank | ||
| 805 | * interrupt, but a vblank interrupt that fired a few | ||
| 806 | * microseconds before true start of vblank. Compensate | ||
| 807 | * by adding a full frame duration to the final timestamp. | ||
| 808 | * Happens, e.g., on ATI R500, R600. | ||
| 809 | * | ||
| 810 | * We only do this if DRM_CALLED_FROM_VBLIRQ. | ||
| 811 | */ | ||
| 812 | if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { | ||
| 813 | vbl_start = mode->crtc_vdisplay; | ||
| 814 | vtotal = mode->crtc_vtotal; | ||
| 815 | |||
| 816 | if (vbl_start - *vpos < vtotal / 100) { | ||
| 817 | *vpos -= vtotal; | ||
| 818 | |||
| 819 | /* Signal this correction as "applied". */ | ||
| 820 | ret |= 0x8; | ||
| 821 | } | ||
| 822 | } | ||
| 823 | |||
| 824 | return ret; | 874 | return ret; |
| 825 | } | 875 | } |
| 826 | 876 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 257d72205bb5..3671f9f220bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | |||
| @@ -47,6 +47,9 @@ | |||
| 47 | * that the the relevant GPU caches have been flushed. | 47 | * that the the relevant GPU caches have been flushed. |
| 48 | */ | 48 | */ |
| 49 | 49 | ||
| 50 | static struct kmem_cache *amdgpu_fence_slab; | ||
| 51 | static atomic_t amdgpu_fence_slab_ref = ATOMIC_INIT(0); | ||
| 52 | |||
| 50 | /** | 53 | /** |
| 51 | * amdgpu_fence_write - write a fence value | 54 | * amdgpu_fence_write - write a fence value |
| 52 | * | 55 | * |
| @@ -85,24 +88,6 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring) | |||
| 85 | } | 88 | } |
| 86 | 89 | ||
| 87 | /** | 90 | /** |
| 88 | * amdgpu_fence_schedule_check - schedule lockup check | ||
| 89 | * | ||
| 90 | * @ring: pointer to struct amdgpu_ring | ||
| 91 | * | ||
| 92 | * Queues a delayed work item to check for lockups. | ||
| 93 | */ | ||
| 94 | static void amdgpu_fence_schedule_check(struct amdgpu_ring *ring) | ||
| 95 | { | ||
| 96 | /* | ||
| 97 | * Do not reset the timer here with mod_delayed_work, | ||
| 98 | * this can livelock in an interaction with TTM delayed destroy. | ||
| 99 | */ | ||
| 100 | queue_delayed_work(system_power_efficient_wq, | ||
| 101 | &ring->fence_drv.lockup_work, | ||
| 102 | AMDGPU_FENCE_JIFFIES_TIMEOUT); | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * amdgpu_fence_emit - emit a fence on the requested ring | 91 | * amdgpu_fence_emit - emit a fence on the requested ring |
| 107 | * | 92 | * |
| 108 | * @ring: ring the fence is associated with | 93 | * @ring: ring the fence is associated with |
| @@ -118,7 +103,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner, | |||
| 118 | struct amdgpu_device *adev = ring->adev; | 103 | struct amdgpu_device *adev = ring->adev; |
| 119 | 104 | ||
| 120 | /* we are protected by the ring emission mutex */ | 105 | /* we are protected by the ring emission mutex */ |
| 121 | *fence = kmalloc(sizeof(struct amdgpu_fence), GFP_KERNEL); | 106 | *fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); |
| 122 | if ((*fence) == NULL) { | 107 | if ((*fence) == NULL) { |
| 123 | return -ENOMEM; | 108 | return -ENOMEM; |
| 124 | } | 109 | } |
| @@ -132,11 +117,23 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner, | |||
| 132 | amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, | 117 | amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, |
| 133 | (*fence)->seq, | 118 | (*fence)->seq, |
| 134 | AMDGPU_FENCE_FLAG_INT); | 119 | AMDGPU_FENCE_FLAG_INT); |
| 135 | trace_amdgpu_fence_emit(ring->adev->ddev, ring->idx, (*fence)->seq); | ||
| 136 | return 0; | 120 | return 0; |
| 137 | } | 121 | } |
| 138 | 122 | ||
| 139 | /** | 123 | /** |
| 124 | * amdgpu_fence_schedule_fallback - schedule fallback check | ||
| 125 | * | ||
| 126 | * @ring: pointer to struct amdgpu_ring | ||
| 127 | * | ||
| 128 | * Start a timer as fallback to our interrupts. | ||
| 129 | */ | ||
| 130 | static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring) | ||
| 131 | { | ||
| 132 | mod_timer(&ring->fence_drv.fallback_timer, | ||
| 133 | jiffies + AMDGPU_FENCE_JIFFIES_TIMEOUT); | ||
| 134 | } | ||
| 135 | |||
| 136 | /** | ||
| 140 | * amdgpu_fence_activity - check for fence activity | 137 | * amdgpu_fence_activity - check for fence activity |
| 141 | * | 138 | * |
| 142 | * @ring: pointer to struct amdgpu_ring | 139 | * @ring: pointer to struct amdgpu_ring |
| @@ -202,45 +199,38 @@ static bool amdgpu_fence_activity(struct amdgpu_ring *ring) | |||
| 202 | } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq); | 199 | } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq); |
| 203 | 200 | ||
| 204 | if (seq < last_emitted) | 201 | if (seq < last_emitted) |
| 205 | amdgpu_fence_schedule_check(ring); | 202 | amdgpu_fence_schedule_fallback(ring); |
| 206 | 203 | ||
| 207 | return wake; | 204 | return wake; |
| 208 | } | 205 | } |
| 209 | 206 | ||
| 210 | /** | 207 | /** |
| 211 | * amdgpu_fence_check_lockup - check for hardware lockup | 208 | * amdgpu_fence_process - process a fence |
| 212 | * | 209 | * |
| 213 | * @work: delayed work item | 210 | * @adev: amdgpu_device pointer |
| 211 | * @ring: ring index the fence is associated with | ||
| 214 | * | 212 | * |
| 215 | * Checks for fence activity and if there is none probe | 213 | * Checks the current fence value and wakes the fence queue |
| 216 | * the hardware if a lockup occured. | 214 | * if the sequence number has increased (all asics). |
| 217 | */ | 215 | */ |
| 218 | static void amdgpu_fence_check_lockup(struct work_struct *work) | 216 | void amdgpu_fence_process(struct amdgpu_ring *ring) |
| 219 | { | 217 | { |
| 220 | struct amdgpu_fence_driver *fence_drv; | ||
| 221 | struct amdgpu_ring *ring; | ||
| 222 | |||
| 223 | fence_drv = container_of(work, struct amdgpu_fence_driver, | ||
| 224 | lockup_work.work); | ||
| 225 | ring = fence_drv->ring; | ||
| 226 | |||
| 227 | if (amdgpu_fence_activity(ring)) | 218 | if (amdgpu_fence_activity(ring)) |
| 228 | wake_up_all(&ring->fence_drv.fence_queue); | 219 | wake_up_all(&ring->fence_drv.fence_queue); |
| 229 | } | 220 | } |
| 230 | 221 | ||
| 231 | /** | 222 | /** |
| 232 | * amdgpu_fence_process - process a fence | 223 | * amdgpu_fence_fallback - fallback for hardware interrupts |
| 233 | * | 224 | * |
| 234 | * @adev: amdgpu_device pointer | 225 | * @work: delayed work item |
| 235 | * @ring: ring index the fence is associated with | ||
| 236 | * | 226 | * |
| 237 | * Checks the current fence value and wakes the fence queue | 227 | * Checks for fence activity. |
| 238 | * if the sequence number has increased (all asics). | ||
| 239 | */ | 228 | */ |
| 240 | void amdgpu_fence_process(struct amdgpu_ring *ring) | 229 | static void amdgpu_fence_fallback(unsigned long arg) |
| 241 | { | 230 | { |
| 242 | if (amdgpu_fence_activity(ring)) | 231 | struct amdgpu_ring *ring = (void *)arg; |
| 243 | wake_up_all(&ring->fence_drv.fence_queue); | 232 | |
| 233 | amdgpu_fence_process(ring); | ||
| 244 | } | 234 | } |
| 245 | 235 | ||
| 246 | /** | 236 | /** |
| @@ -290,7 +280,7 @@ static int amdgpu_fence_ring_wait_seq(struct amdgpu_ring *ring, uint64_t seq) | |||
| 290 | if (atomic64_read(&ring->fence_drv.last_seq) >= seq) | 280 | if (atomic64_read(&ring->fence_drv.last_seq) >= seq) |
| 291 | return 0; | 281 | return 0; |
| 292 | 282 | ||
| 293 | amdgpu_fence_schedule_check(ring); | 283 | amdgpu_fence_schedule_fallback(ring); |
| 294 | wait_event(ring->fence_drv.fence_queue, ( | 284 | wait_event(ring->fence_drv.fence_queue, ( |
| 295 | (signaled = amdgpu_fence_seq_signaled(ring, seq)))); | 285 | (signaled = amdgpu_fence_seq_signaled(ring, seq)))); |
| 296 | 286 | ||
| @@ -491,9 +481,8 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring) | |||
| 491 | atomic64_set(&ring->fence_drv.last_seq, 0); | 481 | atomic64_set(&ring->fence_drv.last_seq, 0); |
| 492 | ring->fence_drv.initialized = false; | 482 | ring->fence_drv.initialized = false; |
| 493 | 483 | ||
| 494 | INIT_DELAYED_WORK(&ring->fence_drv.lockup_work, | 484 | setup_timer(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, |
| 495 | amdgpu_fence_check_lockup); | 485 | (unsigned long)ring); |
| 496 | ring->fence_drv.ring = ring; | ||
| 497 | 486 | ||
| 498 | init_waitqueue_head(&ring->fence_drv.fence_queue); | 487 | init_waitqueue_head(&ring->fence_drv.fence_queue); |
| 499 | 488 | ||
| @@ -536,6 +525,13 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring) | |||
| 536 | */ | 525 | */ |
| 537 | int amdgpu_fence_driver_init(struct amdgpu_device *adev) | 526 | int amdgpu_fence_driver_init(struct amdgpu_device *adev) |
| 538 | { | 527 | { |
| 528 | if (atomic_inc_return(&amdgpu_fence_slab_ref) == 1) { | ||
| 529 | amdgpu_fence_slab = kmem_cache_create( | ||
| 530 | "amdgpu_fence", sizeof(struct amdgpu_fence), 0, | ||
| 531 | SLAB_HWCACHE_ALIGN, NULL); | ||
| 532 | if (!amdgpu_fence_slab) | ||
| 533 | return -ENOMEM; | ||
| 534 | } | ||
| 539 | if (amdgpu_debugfs_fence_init(adev)) | 535 | if (amdgpu_debugfs_fence_init(adev)) |
| 540 | dev_err(adev->dev, "fence debugfs file creation failed\n"); | 536 | dev_err(adev->dev, "fence debugfs file creation failed\n"); |
| 541 | 537 | ||
| @@ -554,9 +550,12 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) | |||
| 554 | { | 550 | { |
| 555 | int i, r; | 551 | int i, r; |
| 556 | 552 | ||
| 553 | if (atomic_dec_and_test(&amdgpu_fence_slab_ref)) | ||
| 554 | kmem_cache_destroy(amdgpu_fence_slab); | ||
| 557 | mutex_lock(&adev->ring_lock); | 555 | mutex_lock(&adev->ring_lock); |
| 558 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | 556 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { |
| 559 | struct amdgpu_ring *ring = adev->rings[i]; | 557 | struct amdgpu_ring *ring = adev->rings[i]; |
| 558 | |||
| 560 | if (!ring || !ring->fence_drv.initialized) | 559 | if (!ring || !ring->fence_drv.initialized) |
| 561 | continue; | 560 | continue; |
| 562 | r = amdgpu_fence_wait_empty(ring); | 561 | r = amdgpu_fence_wait_empty(ring); |
| @@ -568,6 +567,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) | |||
| 568 | amdgpu_irq_put(adev, ring->fence_drv.irq_src, | 567 | amdgpu_irq_put(adev, ring->fence_drv.irq_src, |
| 569 | ring->fence_drv.irq_type); | 568 | ring->fence_drv.irq_type); |
| 570 | amd_sched_fini(&ring->sched); | 569 | amd_sched_fini(&ring->sched); |
| 570 | del_timer_sync(&ring->fence_drv.fallback_timer); | ||
| 571 | ring->fence_drv.initialized = false; | 571 | ring->fence_drv.initialized = false; |
| 572 | } | 572 | } |
| 573 | mutex_unlock(&adev->ring_lock); | 573 | mutex_unlock(&adev->ring_lock); |
| @@ -751,18 +751,25 @@ static bool amdgpu_fence_enable_signaling(struct fence *f) | |||
| 751 | fence->fence_wake.func = amdgpu_fence_check_signaled; | 751 | fence->fence_wake.func = amdgpu_fence_check_signaled; |
| 752 | __add_wait_queue(&ring->fence_drv.fence_queue, &fence->fence_wake); | 752 | __add_wait_queue(&ring->fence_drv.fence_queue, &fence->fence_wake); |
| 753 | fence_get(f); | 753 | fence_get(f); |
| 754 | amdgpu_fence_schedule_check(ring); | 754 | if (!timer_pending(&ring->fence_drv.fallback_timer)) |
| 755 | amdgpu_fence_schedule_fallback(ring); | ||
| 755 | FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx); | 756 | FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx); |
| 756 | return true; | 757 | return true; |
| 757 | } | 758 | } |
| 758 | 759 | ||
| 760 | static void amdgpu_fence_release(struct fence *f) | ||
| 761 | { | ||
| 762 | struct amdgpu_fence *fence = to_amdgpu_fence(f); | ||
| 763 | kmem_cache_free(amdgpu_fence_slab, fence); | ||
| 764 | } | ||
| 765 | |||
| 759 | const struct fence_ops amdgpu_fence_ops = { | 766 | const struct fence_ops amdgpu_fence_ops = { |
| 760 | .get_driver_name = amdgpu_fence_get_driver_name, | 767 | .get_driver_name = amdgpu_fence_get_driver_name, |
| 761 | .get_timeline_name = amdgpu_fence_get_timeline_name, | 768 | .get_timeline_name = amdgpu_fence_get_timeline_name, |
| 762 | .enable_signaling = amdgpu_fence_enable_signaling, | 769 | .enable_signaling = amdgpu_fence_enable_signaling, |
| 763 | .signaled = amdgpu_fence_is_signaled, | 770 | .signaled = amdgpu_fence_is_signaled, |
| 764 | .wait = fence_default_wait, | 771 | .wait = fence_default_wait, |
| 765 | .release = NULL, | 772 | .release = amdgpu_fence_release, |
| 766 | }; | 773 | }; |
| 767 | 774 | ||
| 768 | /* | 775 | /* |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 087332858853..f6ea4b43a60c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |||
| @@ -115,12 +115,9 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri | |||
| 115 | struct amdgpu_vm *vm = &fpriv->vm; | 115 | struct amdgpu_vm *vm = &fpriv->vm; |
| 116 | struct amdgpu_bo_va *bo_va; | 116 | struct amdgpu_bo_va *bo_va; |
| 117 | int r; | 117 | int r; |
| 118 | mutex_lock(&vm->mutex); | ||
| 119 | r = amdgpu_bo_reserve(rbo, false); | 118 | r = amdgpu_bo_reserve(rbo, false); |
| 120 | if (r) { | 119 | if (r) |
| 121 | mutex_unlock(&vm->mutex); | ||
| 122 | return r; | 120 | return r; |
| 123 | } | ||
| 124 | 121 | ||
| 125 | bo_va = amdgpu_vm_bo_find(vm, rbo); | 122 | bo_va = amdgpu_vm_bo_find(vm, rbo); |
| 126 | if (!bo_va) { | 123 | if (!bo_va) { |
| @@ -129,7 +126,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri | |||
| 129 | ++bo_va->ref_count; | 126 | ++bo_va->ref_count; |
| 130 | } | 127 | } |
| 131 | amdgpu_bo_unreserve(rbo); | 128 | amdgpu_bo_unreserve(rbo); |
| 132 | mutex_unlock(&vm->mutex); | ||
| 133 | return 0; | 129 | return 0; |
| 134 | } | 130 | } |
| 135 | 131 | ||
| @@ -142,10 +138,8 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
| 142 | struct amdgpu_vm *vm = &fpriv->vm; | 138 | struct amdgpu_vm *vm = &fpriv->vm; |
| 143 | struct amdgpu_bo_va *bo_va; | 139 | struct amdgpu_bo_va *bo_va; |
| 144 | int r; | 140 | int r; |
| 145 | mutex_lock(&vm->mutex); | ||
| 146 | r = amdgpu_bo_reserve(rbo, true); | 141 | r = amdgpu_bo_reserve(rbo, true); |
| 147 | if (r) { | 142 | if (r) { |
| 148 | mutex_unlock(&vm->mutex); | ||
| 149 | dev_err(adev->dev, "leaking bo va because " | 143 | dev_err(adev->dev, "leaking bo va because " |
| 150 | "we fail to reserve bo (%d)\n", r); | 144 | "we fail to reserve bo (%d)\n", r); |
| 151 | return; | 145 | return; |
| @@ -157,7 +151,6 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
| 157 | } | 151 | } |
| 158 | } | 152 | } |
| 159 | amdgpu_bo_unreserve(rbo); | 153 | amdgpu_bo_unreserve(rbo); |
| 160 | mutex_unlock(&vm->mutex); | ||
| 161 | } | 154 | } |
| 162 | 155 | ||
| 163 | static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) | 156 | static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) |
| @@ -242,8 +235,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, | |||
| 242 | AMDGPU_GEM_USERPTR_REGISTER)) | 235 | AMDGPU_GEM_USERPTR_REGISTER)) |
| 243 | return -EINVAL; | 236 | return -EINVAL; |
| 244 | 237 | ||
| 245 | if (!(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || | 238 | if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && ( |
| 246 | !(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) { | 239 | !(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || |
| 240 | !(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) { | ||
| 247 | 241 | ||
| 248 | /* if we want to write to it we must require anonymous | 242 | /* if we want to write to it we must require anonymous |
| 249 | memory and install a MMU notifier */ | 243 | memory and install a MMU notifier */ |
| @@ -483,6 +477,9 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
| 483 | if (domain == AMDGPU_GEM_DOMAIN_CPU) | 477 | if (domain == AMDGPU_GEM_DOMAIN_CPU) |
| 484 | goto error_unreserve; | 478 | goto error_unreserve; |
| 485 | } | 479 | } |
| 480 | r = amdgpu_vm_update_page_directory(adev, bo_va->vm); | ||
| 481 | if (r) | ||
| 482 | goto error_unreserve; | ||
| 486 | 483 | ||
| 487 | r = amdgpu_vm_clear_freed(adev, bo_va->vm); | 484 | r = amdgpu_vm_clear_freed(adev, bo_va->vm); |
| 488 | if (r) | 485 | if (r) |
| @@ -512,6 +509,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
| 512 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | 509 | struct amdgpu_fpriv *fpriv = filp->driver_priv; |
| 513 | struct amdgpu_bo *rbo; | 510 | struct amdgpu_bo *rbo; |
| 514 | struct amdgpu_bo_va *bo_va; | 511 | struct amdgpu_bo_va *bo_va; |
| 512 | struct ttm_validate_buffer tv, tv_pd; | ||
| 513 | struct ww_acquire_ctx ticket; | ||
| 514 | struct list_head list, duplicates; | ||
| 515 | uint32_t invalid_flags, va_flags = 0; | 515 | uint32_t invalid_flags, va_flags = 0; |
| 516 | int r = 0; | 516 | int r = 0; |
| 517 | 517 | ||
| @@ -547,19 +547,28 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
| 547 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 547 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
| 548 | if (gobj == NULL) | 548 | if (gobj == NULL) |
| 549 | return -ENOENT; | 549 | return -ENOENT; |
| 550 | mutex_lock(&fpriv->vm.mutex); | ||
| 551 | rbo = gem_to_amdgpu_bo(gobj); | 550 | rbo = gem_to_amdgpu_bo(gobj); |
| 552 | r = amdgpu_bo_reserve(rbo, false); | 551 | INIT_LIST_HEAD(&list); |
| 552 | INIT_LIST_HEAD(&duplicates); | ||
| 553 | tv.bo = &rbo->tbo; | ||
| 554 | tv.shared = true; | ||
| 555 | list_add(&tv.head, &list); | ||
| 556 | |||
| 557 | if (args->operation == AMDGPU_VA_OP_MAP) { | ||
| 558 | tv_pd.bo = &fpriv->vm.page_directory->tbo; | ||
| 559 | tv_pd.shared = true; | ||
| 560 | list_add(&tv_pd.head, &list); | ||
| 561 | } | ||
| 562 | r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); | ||
| 553 | if (r) { | 563 | if (r) { |
| 554 | mutex_unlock(&fpriv->vm.mutex); | ||
| 555 | drm_gem_object_unreference_unlocked(gobj); | 564 | drm_gem_object_unreference_unlocked(gobj); |
| 556 | return r; | 565 | return r; |
| 557 | } | 566 | } |
| 558 | 567 | ||
| 559 | bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo); | 568 | bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo); |
| 560 | if (!bo_va) { | 569 | if (!bo_va) { |
| 561 | amdgpu_bo_unreserve(rbo); | 570 | ttm_eu_backoff_reservation(&ticket, &list); |
| 562 | mutex_unlock(&fpriv->vm.mutex); | 571 | drm_gem_object_unreference_unlocked(gobj); |
| 563 | return -ENOENT; | 572 | return -ENOENT; |
| 564 | } | 573 | } |
| 565 | 574 | ||
| @@ -581,10 +590,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
| 581 | default: | 590 | default: |
| 582 | break; | 591 | break; |
| 583 | } | 592 | } |
| 584 | 593 | ttm_eu_backoff_reservation(&ticket, &list); | |
| 585 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) | 594 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) |
| 586 | amdgpu_gem_va_update_vm(adev, bo_va, args->operation); | 595 | amdgpu_gem_va_update_vm(adev, bo_va, args->operation); |
| 587 | mutex_unlock(&fpriv->vm.mutex); | 596 | |
| 588 | drm_gem_object_unreference_unlocked(gobj); | 597 | drm_gem_object_unreference_unlocked(gobj); |
| 589 | return r; | 598 | return r; |
| 590 | } | 599 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index e65987743871..9e25edafa721 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
| @@ -62,7 +62,7 @@ int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, | |||
| 62 | int r; | 62 | int r; |
| 63 | 63 | ||
| 64 | if (size) { | 64 | if (size) { |
| 65 | r = amdgpu_sa_bo_new(adev, &adev->ring_tmp_bo, | 65 | r = amdgpu_sa_bo_new(&adev->ring_tmp_bo, |
| 66 | &ib->sa_bo, size, 256); | 66 | &ib->sa_bo, size, 256); |
| 67 | if (r) { | 67 | if (r) { |
| 68 | dev_err(adev->dev, "failed to get a new IB (%d)\n", r); | 68 | dev_err(adev->dev, "failed to get a new IB (%d)\n", r); |
| @@ -216,7 +216,7 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, | |||
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | if (ib->vm) | 218 | if (ib->vm) |
| 219 | amdgpu_vm_fence(adev, ib->vm, ib->fence); | 219 | amdgpu_vm_fence(adev, ib->vm, &ib->fence->base); |
| 220 | 220 | ||
| 221 | amdgpu_ring_unlock_commit(ring); | 221 | amdgpu_ring_unlock_commit(ring); |
| 222 | return 0; | 222 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1618e2294a16..e23843f4d877 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
| @@ -611,13 +611,59 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev, | |||
| 611 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) | 611 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) |
| 612 | { | 612 | { |
| 613 | struct amdgpu_device *adev = dev->dev_private; | 613 | struct amdgpu_device *adev = dev->dev_private; |
| 614 | int vpos, hpos, stat; | ||
| 615 | u32 count; | ||
| 614 | 616 | ||
| 615 | if (pipe >= adev->mode_info.num_crtc) { | 617 | if (pipe >= adev->mode_info.num_crtc) { |
| 616 | DRM_ERROR("Invalid crtc %u\n", pipe); | 618 | DRM_ERROR("Invalid crtc %u\n", pipe); |
| 617 | return -EINVAL; | 619 | return -EINVAL; |
| 618 | } | 620 | } |
| 619 | 621 | ||
| 620 | return amdgpu_display_vblank_get_counter(adev, pipe); | 622 | /* The hw increments its frame counter at start of vsync, not at start |
| 623 | * of vblank, as is required by DRM core vblank counter handling. | ||
| 624 | * Cook the hw count here to make it appear to the caller as if it | ||
| 625 | * incremented at start of vblank. We measure distance to start of | ||
| 626 | * vblank in vpos. vpos therefore will be >= 0 between start of vblank | ||
| 627 | * and start of vsync, so vpos >= 0 means to bump the hw frame counter | ||
| 628 | * result by 1 to give the proper appearance to caller. | ||
| 629 | */ | ||
| 630 | if (adev->mode_info.crtcs[pipe]) { | ||
| 631 | /* Repeat readout if needed to provide stable result if | ||
| 632 | * we cross start of vsync during the queries. | ||
| 633 | */ | ||
| 634 | do { | ||
| 635 | count = amdgpu_display_vblank_get_counter(adev, pipe); | ||
| 636 | /* Ask amdgpu_get_crtc_scanoutpos to return vpos as | ||
| 637 | * distance to start of vblank, instead of regular | ||
| 638 | * vertical scanout pos. | ||
| 639 | */ | ||
| 640 | stat = amdgpu_get_crtc_scanoutpos( | ||
| 641 | dev, pipe, GET_DISTANCE_TO_VBLANKSTART, | ||
| 642 | &vpos, &hpos, NULL, NULL, | ||
| 643 | &adev->mode_info.crtcs[pipe]->base.hwmode); | ||
| 644 | } while (count != amdgpu_display_vblank_get_counter(adev, pipe)); | ||
| 645 | |||
| 646 | if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != | ||
| 647 | (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) { | ||
| 648 | DRM_DEBUG_VBL("Query failed! stat %d\n", stat); | ||
| 649 | } else { | ||
| 650 | DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n", | ||
| 651 | pipe, vpos); | ||
| 652 | |||
| 653 | /* Bump counter if we are at >= leading edge of vblank, | ||
| 654 | * but before vsync where vpos would turn negative and | ||
| 655 | * the hw counter really increments. | ||
| 656 | */ | ||
| 657 | if (vpos >= 0) | ||
| 658 | count++; | ||
| 659 | } | ||
| 660 | } else { | ||
| 661 | /* Fallback to use value as is. */ | ||
| 662 | count = amdgpu_display_vblank_get_counter(adev, pipe); | ||
| 663 | DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n"); | ||
| 664 | } | ||
| 665 | |||
| 666 | return count; | ||
| 621 | } | 667 | } |
| 622 | 668 | ||
| 623 | /** | 669 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index b62c1710cab6..064ebb347074 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | |||
| @@ -407,6 +407,7 @@ struct amdgpu_crtc { | |||
| 407 | u32 line_time; | 407 | u32 line_time; |
| 408 | u32 wm_low; | 408 | u32 wm_low; |
| 409 | u32 wm_high; | 409 | u32 wm_high; |
| 410 | u32 lb_vblank_lead_lines; | ||
| 410 | struct drm_display_mode hw_mode; | 411 | struct drm_display_mode hw_mode; |
| 411 | }; | 412 | }; |
| 412 | 413 | ||
| @@ -528,6 +529,10 @@ struct amdgpu_framebuffer { | |||
| 528 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ | 529 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ |
| 529 | ((em) == ATOM_ENCODER_MODE_DP_MST)) | 530 | ((em) == ATOM_ENCODER_MODE_DP_MST)) |
| 530 | 531 | ||
| 532 | /* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ | ||
| 533 | #define USE_REAL_VBLANKSTART (1 << 30) | ||
| 534 | #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) | ||
| 535 | |||
| 531 | void amdgpu_link_encoder_connector(struct drm_device *dev); | 536 | void amdgpu_link_encoder_connector(struct drm_device *dev); |
| 532 | 537 | ||
| 533 | struct drm_connector * | 538 | struct drm_connector * |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 0d524384ff79..c3ce103b6a33 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
| @@ -100,6 +100,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) | |||
| 100 | list_del_init(&bo->list); | 100 | list_del_init(&bo->list); |
| 101 | mutex_unlock(&bo->adev->gem.mutex); | 101 | mutex_unlock(&bo->adev->gem.mutex); |
| 102 | drm_gem_object_release(&bo->gem_base); | 102 | drm_gem_object_release(&bo->gem_base); |
| 103 | amdgpu_bo_unref(&bo->parent); | ||
| 103 | kfree(bo->metadata); | 104 | kfree(bo->metadata); |
| 104 | kfree(bo); | 105 | kfree(bo); |
| 105 | } | 106 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 3c2ff4567798..ea756e77b023 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | |||
| @@ -189,10 +189,9 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev, | |||
| 189 | struct amdgpu_sa_manager *sa_manager); | 189 | struct amdgpu_sa_manager *sa_manager); |
| 190 | int amdgpu_sa_bo_manager_suspend(struct amdgpu_device *adev, | 190 | int amdgpu_sa_bo_manager_suspend(struct amdgpu_device *adev, |
| 191 | struct amdgpu_sa_manager *sa_manager); | 191 | struct amdgpu_sa_manager *sa_manager); |
| 192 | int amdgpu_sa_bo_new(struct amdgpu_device *adev, | 192 | int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, |
| 193 | struct amdgpu_sa_manager *sa_manager, | 193 | struct amdgpu_sa_bo **sa_bo, |
| 194 | struct amdgpu_sa_bo **sa_bo, | 194 | unsigned size, unsigned align); |
| 195 | unsigned size, unsigned align); | ||
| 196 | void amdgpu_sa_bo_free(struct amdgpu_device *adev, | 195 | void amdgpu_sa_bo_free(struct amdgpu_device *adev, |
| 197 | struct amdgpu_sa_bo **sa_bo, | 196 | struct amdgpu_sa_bo **sa_bo, |
| 198 | struct fence *fence); | 197 | struct fence *fence); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 0212b31dc194..8b88edb0434b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | |||
| @@ -311,8 +311,7 @@ static bool amdgpu_sa_bo_next_hole(struct amdgpu_sa_manager *sa_manager, | |||
| 311 | return false; | 311 | return false; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | int amdgpu_sa_bo_new(struct amdgpu_device *adev, | 314 | int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, |
| 315 | struct amdgpu_sa_manager *sa_manager, | ||
| 316 | struct amdgpu_sa_bo **sa_bo, | 315 | struct amdgpu_sa_bo **sa_bo, |
| 317 | unsigned size, unsigned align) | 316 | unsigned size, unsigned align) |
| 318 | { | 317 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index dcf4a8aca680..438c05254695 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
| 27 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
| 28 | #include "amdgpu.h" | 28 | #include "amdgpu.h" |
| 29 | #include "amdgpu_trace.h" | ||
| 29 | 30 | ||
| 30 | static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) | 31 | static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) |
| 31 | { | 32 | { |
| @@ -44,11 +45,8 @@ static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) | |||
| 44 | return NULL; | 45 | return NULL; |
| 45 | } | 46 | } |
| 46 | job = to_amdgpu_job(sched_job); | 47 | job = to_amdgpu_job(sched_job); |
| 47 | mutex_lock(&job->job_lock); | 48 | trace_amdgpu_sched_run_job(job); |
| 48 | r = amdgpu_ib_schedule(job->adev, | 49 | r = amdgpu_ib_schedule(job->adev, job->num_ibs, job->ibs, job->owner); |
| 49 | job->num_ibs, | ||
| 50 | job->ibs, | ||
| 51 | job->base.owner); | ||
| 52 | if (r) { | 50 | if (r) { |
| 53 | DRM_ERROR("Error scheduling IBs (%d)\n", r); | 51 | DRM_ERROR("Error scheduling IBs (%d)\n", r); |
| 54 | goto err; | 52 | goto err; |
| @@ -61,8 +59,6 @@ err: | |||
| 61 | if (job->free_job) | 59 | if (job->free_job) |
| 62 | job->free_job(job); | 60 | job->free_job(job); |
| 63 | 61 | ||
| 64 | mutex_unlock(&job->job_lock); | ||
| 65 | fence_put(&job->base.s_fence->base); | ||
| 66 | kfree(job); | 62 | kfree(job); |
| 67 | return fence ? &fence->base : NULL; | 63 | return fence ? &fence->base : NULL; |
| 68 | } | 64 | } |
| @@ -88,21 +84,19 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, | |||
| 88 | return -ENOMEM; | 84 | return -ENOMEM; |
| 89 | job->base.sched = &ring->sched; | 85 | job->base.sched = &ring->sched; |
| 90 | job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; | 86 | job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; |
| 87 | job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); | ||
| 88 | if (!job->base.s_fence) { | ||
| 89 | kfree(job); | ||
| 90 | return -ENOMEM; | ||
| 91 | } | ||
| 92 | *f = fence_get(&job->base.s_fence->base); | ||
| 93 | |||
| 91 | job->adev = adev; | 94 | job->adev = adev; |
| 92 | job->ibs = ibs; | 95 | job->ibs = ibs; |
| 93 | job->num_ibs = num_ibs; | 96 | job->num_ibs = num_ibs; |
| 94 | job->base.owner = owner; | 97 | job->owner = owner; |
| 95 | mutex_init(&job->job_lock); | ||
| 96 | job->free_job = free_job; | 98 | job->free_job = free_job; |
| 97 | mutex_lock(&job->job_lock); | 99 | amd_sched_entity_push_job(&job->base); |
| 98 | r = amd_sched_entity_push_job(&job->base); | ||
| 99 | if (r) { | ||
| 100 | mutex_unlock(&job->job_lock); | ||
| 101 | kfree(job); | ||
| 102 | return r; | ||
| 103 | } | ||
| 104 | *f = fence_get(&job->base.s_fence->base); | ||
| 105 | mutex_unlock(&job->job_lock); | ||
| 106 | } else { | 100 | } else { |
| 107 | r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner); | 101 | r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner); |
| 108 | if (r) | 102 | if (r) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c index ff3ca52ec6fe..1caaf201b708 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c | |||
| @@ -40,7 +40,7 @@ int amdgpu_semaphore_create(struct amdgpu_device *adev, | |||
| 40 | if (*semaphore == NULL) { | 40 | if (*semaphore == NULL) { |
| 41 | return -ENOMEM; | 41 | return -ENOMEM; |
| 42 | } | 42 | } |
| 43 | r = amdgpu_sa_bo_new(adev, &adev->ring_tmp_bo, | 43 | r = amdgpu_sa_bo_new(&adev->ring_tmp_bo, |
| 44 | &(*semaphore)->sa_bo, 8, 8); | 44 | &(*semaphore)->sa_bo, 8, 8); |
| 45 | if (r) { | 45 | if (r) { |
| 46 | kfree(*semaphore); | 46 | kfree(*semaphore); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index a6697fd05217..dd005c336c97 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | |||
| @@ -302,8 +302,14 @@ int amdgpu_sync_rings(struct amdgpu_sync *sync, | |||
| 302 | return -EINVAL; | 302 | return -EINVAL; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores || | 305 | if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores) { |
| 306 | (count >= AMDGPU_NUM_SYNCS)) { | 306 | r = fence_wait(&fence->base, true); |
| 307 | if (r) | ||
| 308 | return r; | ||
| 309 | continue; | ||
| 310 | } | ||
| 311 | |||
| 312 | if (count >= AMDGPU_NUM_SYNCS) { | ||
| 307 | /* not enough room, wait manually */ | 313 | /* not enough room, wait manually */ |
| 308 | r = fence_wait(&fence->base, false); | 314 | r = fence_wait(&fence->base, false); |
| 309 | if (r) | 315 | if (r) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index 76ecbaf72a2e..8f9834ab1bd5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | |||
| @@ -48,6 +48,57 @@ TRACE_EVENT(amdgpu_cs, | |||
| 48 | __entry->fences) | 48 | __entry->fences) |
| 49 | ); | 49 | ); |
| 50 | 50 | ||
| 51 | TRACE_EVENT(amdgpu_cs_ioctl, | ||
| 52 | TP_PROTO(struct amdgpu_job *job), | ||
| 53 | TP_ARGS(job), | ||
| 54 | TP_STRUCT__entry( | ||
| 55 | __field(struct amdgpu_device *, adev) | ||
| 56 | __field(struct amd_sched_job *, sched_job) | ||
| 57 | __field(struct amdgpu_ib *, ib) | ||
| 58 | __field(struct fence *, fence) | ||
| 59 | __field(char *, ring_name) | ||
| 60 | __field(u32, num_ibs) | ||
| 61 | ), | ||
| 62 | |||
| 63 | TP_fast_assign( | ||
| 64 | __entry->adev = job->adev; | ||
| 65 | __entry->sched_job = &job->base; | ||
| 66 | __entry->ib = job->ibs; | ||
| 67 | __entry->fence = &job->base.s_fence->base; | ||
| 68 | __entry->ring_name = job->ibs[0].ring->name; | ||
| 69 | __entry->num_ibs = job->num_ibs; | ||
| 70 | ), | ||
| 71 | TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", | ||
| 72 | __entry->adev, __entry->sched_job, __entry->ib, | ||
| 73 | __entry->fence, __entry->ring_name, __entry->num_ibs) | ||
| 74 | ); | ||
| 75 | |||
| 76 | TRACE_EVENT(amdgpu_sched_run_job, | ||
| 77 | TP_PROTO(struct amdgpu_job *job), | ||
| 78 | TP_ARGS(job), | ||
| 79 | TP_STRUCT__entry( | ||
| 80 | __field(struct amdgpu_device *, adev) | ||
| 81 | __field(struct amd_sched_job *, sched_job) | ||
| 82 | __field(struct amdgpu_ib *, ib) | ||
| 83 | __field(struct fence *, fence) | ||
| 84 | __field(char *, ring_name) | ||
| 85 | __field(u32, num_ibs) | ||
| 86 | ), | ||
| 87 | |||
| 88 | TP_fast_assign( | ||
| 89 | __entry->adev = job->adev; | ||
| 90 | __entry->sched_job = &job->base; | ||
| 91 | __entry->ib = job->ibs; | ||
| 92 | __entry->fence = &job->base.s_fence->base; | ||
| 93 | __entry->ring_name = job->ibs[0].ring->name; | ||
| 94 | __entry->num_ibs = job->num_ibs; | ||
| 95 | ), | ||
| 96 | TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", | ||
| 97 | __entry->adev, __entry->sched_job, __entry->ib, | ||
| 98 | __entry->fence, __entry->ring_name, __entry->num_ibs) | ||
| 99 | ); | ||
| 100 | |||
| 101 | |||
| 51 | TRACE_EVENT(amdgpu_vm_grab_id, | 102 | TRACE_EVENT(amdgpu_vm_grab_id, |
| 52 | TP_PROTO(unsigned vmid, int ring), | 103 | TP_PROTO(unsigned vmid, int ring), |
| 53 | TP_ARGS(vmid, ring), | 104 | TP_ARGS(vmid, ring), |
| @@ -196,49 +247,6 @@ TRACE_EVENT(amdgpu_bo_list_set, | |||
| 196 | TP_printk("list=%p, bo=%p", __entry->list, __entry->bo) | 247 | TP_printk("list=%p, bo=%p", __entry->list, __entry->bo) |
| 197 | ); | 248 | ); |
| 198 | 249 | ||
| 199 | DECLARE_EVENT_CLASS(amdgpu_fence_request, | ||
| 200 | |||
| 201 | TP_PROTO(struct drm_device *dev, int ring, u32 seqno), | ||
| 202 | |||
| 203 | TP_ARGS(dev, ring, seqno), | ||
| 204 | |||
| 205 | TP_STRUCT__entry( | ||
| 206 | __field(u32, dev) | ||
| 207 | __field(int, ring) | ||
| 208 | __field(u32, seqno) | ||
| 209 | ), | ||
| 210 | |||
| 211 | TP_fast_assign( | ||
| 212 | __entry->dev = dev->primary->index; | ||
| 213 | __entry->ring = ring; | ||
| 214 | __entry->seqno = seqno; | ||
| 215 | ), | ||
| 216 | |||
| 217 | TP_printk("dev=%u, ring=%d, seqno=%u", | ||
| 218 | __entry->dev, __entry->ring, __entry->seqno) | ||
| 219 | ); | ||
| 220 | |||
| 221 | DEFINE_EVENT(amdgpu_fence_request, amdgpu_fence_emit, | ||
| 222 | |||
| 223 | TP_PROTO(struct drm_device *dev, int ring, u32 seqno), | ||
| 224 | |||
| 225 | TP_ARGS(dev, ring, seqno) | ||
| 226 | ); | ||
| 227 | |||
| 228 | DEFINE_EVENT(amdgpu_fence_request, amdgpu_fence_wait_begin, | ||
| 229 | |||
| 230 | TP_PROTO(struct drm_device *dev, int ring, u32 seqno), | ||
| 231 | |||
| 232 | TP_ARGS(dev, ring, seqno) | ||
| 233 | ); | ||
| 234 | |||
| 235 | DEFINE_EVENT(amdgpu_fence_request, amdgpu_fence_wait_end, | ||
| 236 | |||
| 237 | TP_PROTO(struct drm_device *dev, int ring, u32 seqno), | ||
| 238 | |||
| 239 | TP_ARGS(dev, ring, seqno) | ||
| 240 | ); | ||
| 241 | |||
| 242 | DECLARE_EVENT_CLASS(amdgpu_semaphore_request, | 250 | DECLARE_EVENT_CLASS(amdgpu_semaphore_request, |
| 243 | 251 | ||
| 244 | TP_PROTO(int ring, struct amdgpu_semaphore *sem), | 252 | TP_PROTO(int ring, struct amdgpu_semaphore *sem), |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 81bb8e9fc26d..8a1752ff3d8e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
| @@ -587,9 +587,13 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, | |||
| 587 | uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem); | 587 | uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem); |
| 588 | int r; | 588 | int r; |
| 589 | 589 | ||
| 590 | if (gtt->userptr) | 590 | if (gtt->userptr) { |
| 591 | amdgpu_ttm_tt_pin_userptr(ttm); | 591 | r = amdgpu_ttm_tt_pin_userptr(ttm); |
| 592 | 592 | if (r) { | |
| 593 | DRM_ERROR("failed to pin userptr\n"); | ||
| 594 | return r; | ||
| 595 | } | ||
| 596 | } | ||
| 593 | gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); | 597 | gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); |
| 594 | if (!ttm->num_pages) { | 598 | if (!ttm->num_pages) { |
| 595 | WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", | 599 | WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", |
| @@ -797,11 +801,12 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | |||
| 797 | if (mem && mem->mem_type != TTM_PL_SYSTEM) | 801 | if (mem && mem->mem_type != TTM_PL_SYSTEM) |
| 798 | flags |= AMDGPU_PTE_VALID; | 802 | flags |= AMDGPU_PTE_VALID; |
| 799 | 803 | ||
| 800 | if (mem && mem->mem_type == TTM_PL_TT) | 804 | if (mem && mem->mem_type == TTM_PL_TT) { |
| 801 | flags |= AMDGPU_PTE_SYSTEM; | 805 | flags |= AMDGPU_PTE_SYSTEM; |
| 802 | 806 | ||
| 803 | if (!ttm || ttm->caching_state == tt_cached) | 807 | if (ttm->caching_state == tt_cached) |
| 804 | flags |= AMDGPU_PTE_SNOOPED; | 808 | flags |= AMDGPU_PTE_SNOOPED; |
| 809 | } | ||
| 805 | 810 | ||
| 806 | if (adev->asic_type >= CHIP_TOPAZ) | 811 | if (adev->asic_type >= CHIP_TOPAZ) |
| 807 | flags |= AMDGPU_PTE_EXECUTABLE; | 812 | flags |= AMDGPU_PTE_EXECUTABLE; |
| @@ -1073,10 +1078,10 @@ static int amdgpu_mm_dump_table(struct seq_file *m, void *data) | |||
| 1073 | ret = drm_mm_dump_table(m, mm); | 1078 | ret = drm_mm_dump_table(m, mm); |
| 1074 | spin_unlock(&glob->lru_lock); | 1079 | spin_unlock(&glob->lru_lock); |
| 1075 | if (ttm_pl == TTM_PL_VRAM) | 1080 | if (ttm_pl == TTM_PL_VRAM) |
| 1076 | seq_printf(m, "man size:%llu pages, ram usage:%luMB, vis usage:%luMB\n", | 1081 | seq_printf(m, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n", |
| 1077 | adev->mman.bdev.man[ttm_pl].size, | 1082 | adev->mman.bdev.man[ttm_pl].size, |
| 1078 | atomic64_read(&adev->vram_usage) >> 20, | 1083 | (u64)atomic64_read(&adev->vram_usage) >> 20, |
| 1079 | atomic64_read(&adev->vram_vis_usage) >> 20); | 1084 | (u64)atomic64_read(&adev->vram_vis_usage) >> 20); |
| 1080 | return ret; | 1085 | return ret; |
| 1081 | } | 1086 | } |
| 1082 | 1087 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 03f0c3bae516..a745eeeb5d82 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
| @@ -392,7 +392,10 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
| 392 | ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */ | 392 | ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */ |
| 393 | ib->ptr[ib->length_dw++] = handle; | 393 | ib->ptr[ib->length_dw++] = handle; |
| 394 | 394 | ||
| 395 | ib->ptr[ib->length_dw++] = 0x00000030; /* len */ | 395 | if ((ring->adev->vce.fw_version >> 24) >= 52) |
| 396 | ib->ptr[ib->length_dw++] = 0x00000040; /* len */ | ||
| 397 | else | ||
| 398 | ib->ptr[ib->length_dw++] = 0x00000030; /* len */ | ||
| 396 | ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */ | 399 | ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */ |
| 397 | ib->ptr[ib->length_dw++] = 0x00000000; | 400 | ib->ptr[ib->length_dw++] = 0x00000000; |
| 398 | ib->ptr[ib->length_dw++] = 0x00000042; | 401 | ib->ptr[ib->length_dw++] = 0x00000042; |
| @@ -404,6 +407,12 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
| 404 | ib->ptr[ib->length_dw++] = 0x00000100; | 407 | ib->ptr[ib->length_dw++] = 0x00000100; |
| 405 | ib->ptr[ib->length_dw++] = 0x0000000c; | 408 | ib->ptr[ib->length_dw++] = 0x0000000c; |
| 406 | ib->ptr[ib->length_dw++] = 0x00000000; | 409 | ib->ptr[ib->length_dw++] = 0x00000000; |
| 410 | if ((ring->adev->vce.fw_version >> 24) >= 52) { | ||
| 411 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
| 412 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
| 413 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
| 414 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
| 415 | } | ||
| 407 | 416 | ||
| 408 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ | 417 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ |
| 409 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ | 418 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 633a32a48560..b53d273eb7a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
| @@ -143,10 +143,15 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
| 143 | unsigned i; | 143 | unsigned i; |
| 144 | 144 | ||
| 145 | /* check if the id is still valid */ | 145 | /* check if the id is still valid */ |
| 146 | if (vm_id->id && vm_id->last_id_use && | 146 | if (vm_id->id) { |
| 147 | vm_id->last_id_use == adev->vm_manager.active[vm_id->id]) { | 147 | unsigned id = vm_id->id; |
| 148 | trace_amdgpu_vm_grab_id(vm_id->id, ring->idx); | 148 | long owner; |
| 149 | return 0; | 149 | |
| 150 | owner = atomic_long_read(&adev->vm_manager.ids[id].owner); | ||
| 151 | if (owner == (long)vm) { | ||
| 152 | trace_amdgpu_vm_grab_id(vm_id->id, ring->idx); | ||
| 153 | return 0; | ||
| 154 | } | ||
| 150 | } | 155 | } |
| 151 | 156 | ||
| 152 | /* we definately need to flush */ | 157 | /* we definately need to flush */ |
| @@ -154,7 +159,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
| 154 | 159 | ||
| 155 | /* skip over VMID 0, since it is the system VM */ | 160 | /* skip over VMID 0, since it is the system VM */ |
| 156 | for (i = 1; i < adev->vm_manager.nvm; ++i) { | 161 | for (i = 1; i < adev->vm_manager.nvm; ++i) { |
| 157 | struct fence *fence = adev->vm_manager.active[i]; | 162 | struct fence *fence = adev->vm_manager.ids[i].active; |
| 158 | struct amdgpu_ring *fring; | 163 | struct amdgpu_ring *fring; |
| 159 | 164 | ||
| 160 | if (fence == NULL) { | 165 | if (fence == NULL) { |
| @@ -176,7 +181,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
| 176 | if (choices[i]) { | 181 | if (choices[i]) { |
| 177 | struct fence *fence; | 182 | struct fence *fence; |
| 178 | 183 | ||
| 179 | fence = adev->vm_manager.active[choices[i]]; | 184 | fence = adev->vm_manager.ids[choices[i]].active; |
| 180 | vm_id->id = choices[i]; | 185 | vm_id->id = choices[i]; |
| 181 | 186 | ||
| 182 | trace_amdgpu_vm_grab_id(choices[i], ring->idx); | 187 | trace_amdgpu_vm_grab_id(choices[i], ring->idx); |
| @@ -207,24 +212,21 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
| 207 | uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); | 212 | uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); |
| 208 | struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; | 213 | struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; |
| 209 | struct fence *flushed_updates = vm_id->flushed_updates; | 214 | struct fence *flushed_updates = vm_id->flushed_updates; |
| 210 | bool is_earlier = false; | 215 | bool is_later; |
| 211 | 216 | ||
| 212 | if (flushed_updates && updates) { | 217 | if (!flushed_updates) |
| 213 | BUG_ON(flushed_updates->context != updates->context); | 218 | is_later = true; |
| 214 | is_earlier = (updates->seqno - flushed_updates->seqno <= | 219 | else if (!updates) |
| 215 | INT_MAX) ? true : false; | 220 | is_later = false; |
| 216 | } | 221 | else |
| 217 | 222 | is_later = fence_is_later(updates, flushed_updates); | |
| 218 | if (pd_addr != vm_id->pd_gpu_addr || !flushed_updates || | ||
| 219 | is_earlier) { | ||
| 220 | 223 | ||
| 224 | if (pd_addr != vm_id->pd_gpu_addr || is_later) { | ||
| 221 | trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id->id); | 225 | trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id->id); |
| 222 | if (is_earlier) { | 226 | if (is_later) { |
| 223 | vm_id->flushed_updates = fence_get(updates); | 227 | vm_id->flushed_updates = fence_get(updates); |
| 224 | fence_put(flushed_updates); | 228 | fence_put(flushed_updates); |
| 225 | } | 229 | } |
| 226 | if (!flushed_updates) | ||
| 227 | vm_id->flushed_updates = fence_get(updates); | ||
| 228 | vm_id->pd_gpu_addr = pd_addr; | 230 | vm_id->pd_gpu_addr = pd_addr; |
| 229 | amdgpu_ring_emit_vm_flush(ring, vm_id->id, vm_id->pd_gpu_addr); | 231 | amdgpu_ring_emit_vm_flush(ring, vm_id->id, vm_id->pd_gpu_addr); |
| 230 | } | 232 | } |
| @@ -244,16 +246,14 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
| 244 | */ | 246 | */ |
| 245 | void amdgpu_vm_fence(struct amdgpu_device *adev, | 247 | void amdgpu_vm_fence(struct amdgpu_device *adev, |
| 246 | struct amdgpu_vm *vm, | 248 | struct amdgpu_vm *vm, |
| 247 | struct amdgpu_fence *fence) | 249 | struct fence *fence) |
| 248 | { | 250 | { |
| 249 | unsigned ridx = fence->ring->idx; | 251 | struct amdgpu_ring *ring = amdgpu_ring_from_fence(fence); |
| 250 | unsigned vm_id = vm->ids[ridx].id; | 252 | unsigned vm_id = vm->ids[ring->idx].id; |
| 251 | |||
| 252 | fence_put(adev->vm_manager.active[vm_id]); | ||
| 253 | adev->vm_manager.active[vm_id] = fence_get(&fence->base); | ||
| 254 | 253 | ||
| 255 | fence_put(vm->ids[ridx].last_id_use); | 254 | fence_put(adev->vm_manager.ids[vm_id].active); |
| 256 | vm->ids[ridx].last_id_use = fence_get(&fence->base); | 255 | adev->vm_manager.ids[vm_id].active = fence_get(fence); |
| 256 | atomic_long_set(&adev->vm_manager.ids[vm_id].owner, (long)vm); | ||
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | /** | 259 | /** |
| @@ -332,6 +332,8 @@ int amdgpu_vm_free_job(struct amdgpu_job *job) | |||
| 332 | * | 332 | * |
| 333 | * @adev: amdgpu_device pointer | 333 | * @adev: amdgpu_device pointer |
| 334 | * @bo: bo to clear | 334 | * @bo: bo to clear |
| 335 | * | ||
| 336 | * need to reserve bo first before calling it. | ||
| 335 | */ | 337 | */ |
| 336 | static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | 338 | static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, |
| 337 | struct amdgpu_bo *bo) | 339 | struct amdgpu_bo *bo) |
| @@ -343,24 +345,20 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | |||
| 343 | uint64_t addr; | 345 | uint64_t addr; |
| 344 | int r; | 346 | int r; |
| 345 | 347 | ||
| 346 | r = amdgpu_bo_reserve(bo, false); | ||
| 347 | if (r) | ||
| 348 | return r; | ||
| 349 | |||
| 350 | r = reservation_object_reserve_shared(bo->tbo.resv); | 348 | r = reservation_object_reserve_shared(bo->tbo.resv); |
| 351 | if (r) | 349 | if (r) |
| 352 | return r; | 350 | return r; |
| 353 | 351 | ||
| 354 | r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); | 352 | r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); |
| 355 | if (r) | 353 | if (r) |
| 356 | goto error_unreserve; | 354 | goto error; |
| 357 | 355 | ||
| 358 | addr = amdgpu_bo_gpu_offset(bo); | 356 | addr = amdgpu_bo_gpu_offset(bo); |
| 359 | entries = amdgpu_bo_size(bo) / 8; | 357 | entries = amdgpu_bo_size(bo) / 8; |
| 360 | 358 | ||
| 361 | ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); | 359 | ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); |
| 362 | if (!ib) | 360 | if (!ib) |
| 363 | goto error_unreserve; | 361 | goto error; |
| 364 | 362 | ||
| 365 | r = amdgpu_ib_get(ring, NULL, entries * 2 + 64, ib); | 363 | r = amdgpu_ib_get(ring, NULL, entries * 2 + 64, ib); |
| 366 | if (r) | 364 | if (r) |
| @@ -378,16 +376,14 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | |||
| 378 | if (!r) | 376 | if (!r) |
| 379 | amdgpu_bo_fence(bo, fence, true); | 377 | amdgpu_bo_fence(bo, fence, true); |
| 380 | fence_put(fence); | 378 | fence_put(fence); |
| 381 | if (amdgpu_enable_scheduler) { | 379 | if (amdgpu_enable_scheduler) |
| 382 | amdgpu_bo_unreserve(bo); | ||
| 383 | return 0; | 380 | return 0; |
| 384 | } | 381 | |
| 385 | error_free: | 382 | error_free: |
| 386 | amdgpu_ib_free(adev, ib); | 383 | amdgpu_ib_free(adev, ib); |
| 387 | kfree(ib); | 384 | kfree(ib); |
| 388 | 385 | ||
| 389 | error_unreserve: | 386 | error: |
| 390 | amdgpu_bo_unreserve(bo); | ||
| 391 | return r; | 387 | return r; |
| 392 | } | 388 | } |
| 393 | 389 | ||
| @@ -889,17 +885,21 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | |||
| 889 | struct amdgpu_bo_va_mapping *mapping; | 885 | struct amdgpu_bo_va_mapping *mapping; |
| 890 | int r; | 886 | int r; |
| 891 | 887 | ||
| 888 | spin_lock(&vm->freed_lock); | ||
| 892 | while (!list_empty(&vm->freed)) { | 889 | while (!list_empty(&vm->freed)) { |
| 893 | mapping = list_first_entry(&vm->freed, | 890 | mapping = list_first_entry(&vm->freed, |
| 894 | struct amdgpu_bo_va_mapping, list); | 891 | struct amdgpu_bo_va_mapping, list); |
| 895 | list_del(&mapping->list); | 892 | list_del(&mapping->list); |
| 896 | 893 | spin_unlock(&vm->freed_lock); | |
| 897 | r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); | 894 | r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); |
| 898 | kfree(mapping); | 895 | kfree(mapping); |
| 899 | if (r) | 896 | if (r) |
| 900 | return r; | 897 | return r; |
| 901 | 898 | ||
| 899 | spin_lock(&vm->freed_lock); | ||
| 902 | } | 900 | } |
| 901 | spin_unlock(&vm->freed_lock); | ||
| 902 | |||
| 903 | return 0; | 903 | return 0; |
| 904 | 904 | ||
| 905 | } | 905 | } |
| @@ -926,8 +926,9 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, | |||
| 926 | bo_va = list_first_entry(&vm->invalidated, | 926 | bo_va = list_first_entry(&vm->invalidated, |
| 927 | struct amdgpu_bo_va, vm_status); | 927 | struct amdgpu_bo_va, vm_status); |
| 928 | spin_unlock(&vm->status_lock); | 928 | spin_unlock(&vm->status_lock); |
| 929 | 929 | mutex_lock(&bo_va->mutex); | |
| 930 | r = amdgpu_vm_bo_update(adev, bo_va, NULL); | 930 | r = amdgpu_vm_bo_update(adev, bo_va, NULL); |
| 931 | mutex_unlock(&bo_va->mutex); | ||
| 931 | if (r) | 932 | if (r) |
| 932 | return r; | 933 | return r; |
| 933 | 934 | ||
| @@ -971,7 +972,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, | |||
| 971 | INIT_LIST_HEAD(&bo_va->valids); | 972 | INIT_LIST_HEAD(&bo_va->valids); |
| 972 | INIT_LIST_HEAD(&bo_va->invalids); | 973 | INIT_LIST_HEAD(&bo_va->invalids); |
| 973 | INIT_LIST_HEAD(&bo_va->vm_status); | 974 | INIT_LIST_HEAD(&bo_va->vm_status); |
| 974 | 975 | mutex_init(&bo_va->mutex); | |
| 975 | list_add_tail(&bo_va->bo_list, &bo->va); | 976 | list_add_tail(&bo_va->bo_list, &bo->va); |
| 976 | 977 | ||
| 977 | return bo_va; | 978 | return bo_va; |
| @@ -989,7 +990,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, | |||
| 989 | * Add a mapping of the BO at the specefied addr into the VM. | 990 | * Add a mapping of the BO at the specefied addr into the VM. |
| 990 | * Returns 0 for success, error for failure. | 991 | * Returns 0 for success, error for failure. |
| 991 | * | 992 | * |
| 992 | * Object has to be reserved and gets unreserved by this function! | 993 | * Object has to be reserved and unreserved outside! |
| 993 | */ | 994 | */ |
| 994 | int amdgpu_vm_bo_map(struct amdgpu_device *adev, | 995 | int amdgpu_vm_bo_map(struct amdgpu_device *adev, |
| 995 | struct amdgpu_bo_va *bo_va, | 996 | struct amdgpu_bo_va *bo_va, |
| @@ -1005,30 +1006,27 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
| 1005 | 1006 | ||
| 1006 | /* validate the parameters */ | 1007 | /* validate the parameters */ |
| 1007 | if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || | 1008 | if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || |
| 1008 | size == 0 || size & AMDGPU_GPU_PAGE_MASK) { | 1009 | size == 0 || size & AMDGPU_GPU_PAGE_MASK) |
| 1009 | amdgpu_bo_unreserve(bo_va->bo); | ||
| 1010 | return -EINVAL; | 1010 | return -EINVAL; |
| 1011 | } | ||
| 1012 | 1011 | ||
| 1013 | /* make sure object fit at this offset */ | 1012 | /* make sure object fit at this offset */ |
| 1014 | eaddr = saddr + size; | 1013 | eaddr = saddr + size; |
| 1015 | if ((saddr >= eaddr) || (offset + size > amdgpu_bo_size(bo_va->bo))) { | 1014 | if ((saddr >= eaddr) || (offset + size > amdgpu_bo_size(bo_va->bo))) |
| 1016 | amdgpu_bo_unreserve(bo_va->bo); | ||
| 1017 | return -EINVAL; | 1015 | return -EINVAL; |
| 1018 | } | ||
| 1019 | 1016 | ||
| 1020 | last_pfn = eaddr / AMDGPU_GPU_PAGE_SIZE; | 1017 | last_pfn = eaddr / AMDGPU_GPU_PAGE_SIZE; |
| 1021 | if (last_pfn > adev->vm_manager.max_pfn) { | 1018 | if (last_pfn > adev->vm_manager.max_pfn) { |
| 1022 | dev_err(adev->dev, "va above limit (0x%08X > 0x%08X)\n", | 1019 | dev_err(adev->dev, "va above limit (0x%08X > 0x%08X)\n", |
| 1023 | last_pfn, adev->vm_manager.max_pfn); | 1020 | last_pfn, adev->vm_manager.max_pfn); |
| 1024 | amdgpu_bo_unreserve(bo_va->bo); | ||
| 1025 | return -EINVAL; | 1021 | return -EINVAL; |
| 1026 | } | 1022 | } |
| 1027 | 1023 | ||
| 1028 | saddr /= AMDGPU_GPU_PAGE_SIZE; | 1024 | saddr /= AMDGPU_GPU_PAGE_SIZE; |
| 1029 | eaddr /= AMDGPU_GPU_PAGE_SIZE; | 1025 | eaddr /= AMDGPU_GPU_PAGE_SIZE; |
| 1030 | 1026 | ||
| 1027 | spin_lock(&vm->it_lock); | ||
| 1031 | it = interval_tree_iter_first(&vm->va, saddr, eaddr - 1); | 1028 | it = interval_tree_iter_first(&vm->va, saddr, eaddr - 1); |
| 1029 | spin_unlock(&vm->it_lock); | ||
| 1032 | if (it) { | 1030 | if (it) { |
| 1033 | struct amdgpu_bo_va_mapping *tmp; | 1031 | struct amdgpu_bo_va_mapping *tmp; |
| 1034 | tmp = container_of(it, struct amdgpu_bo_va_mapping, it); | 1032 | tmp = container_of(it, struct amdgpu_bo_va_mapping, it); |
| @@ -1036,14 +1034,12 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
| 1036 | dev_err(adev->dev, "bo %p va 0x%010Lx-0x%010Lx conflict with " | 1034 | dev_err(adev->dev, "bo %p va 0x%010Lx-0x%010Lx conflict with " |
| 1037 | "0x%010lx-0x%010lx\n", bo_va->bo, saddr, eaddr, | 1035 | "0x%010lx-0x%010lx\n", bo_va->bo, saddr, eaddr, |
| 1038 | tmp->it.start, tmp->it.last + 1); | 1036 | tmp->it.start, tmp->it.last + 1); |
| 1039 | amdgpu_bo_unreserve(bo_va->bo); | ||
| 1040 | r = -EINVAL; | 1037 | r = -EINVAL; |
| 1041 | goto error; | 1038 | goto error; |
| 1042 | } | 1039 | } |
| 1043 | 1040 | ||
| 1044 | mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); | 1041 | mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); |
| 1045 | if (!mapping) { | 1042 | if (!mapping) { |
| 1046 | amdgpu_bo_unreserve(bo_va->bo); | ||
| 1047 | r = -ENOMEM; | 1043 | r = -ENOMEM; |
| 1048 | goto error; | 1044 | goto error; |
| 1049 | } | 1045 | } |
| @@ -1054,8 +1050,12 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
| 1054 | mapping->offset = offset; | 1050 | mapping->offset = offset; |
| 1055 | mapping->flags = flags; | 1051 | mapping->flags = flags; |
| 1056 | 1052 | ||
| 1053 | mutex_lock(&bo_va->mutex); | ||
| 1057 | list_add(&mapping->list, &bo_va->invalids); | 1054 | list_add(&mapping->list, &bo_va->invalids); |
| 1055 | mutex_unlock(&bo_va->mutex); | ||
| 1056 | spin_lock(&vm->it_lock); | ||
| 1058 | interval_tree_insert(&mapping->it, &vm->va); | 1057 | interval_tree_insert(&mapping->it, &vm->va); |
| 1058 | spin_unlock(&vm->it_lock); | ||
| 1059 | trace_amdgpu_vm_bo_map(bo_va, mapping); | 1059 | trace_amdgpu_vm_bo_map(bo_va, mapping); |
| 1060 | 1060 | ||
| 1061 | /* Make sure the page tables are allocated */ | 1061 | /* Make sure the page tables are allocated */ |
| @@ -1067,8 +1067,6 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
| 1067 | if (eaddr > vm->max_pde_used) | 1067 | if (eaddr > vm->max_pde_used) |
| 1068 | vm->max_pde_used = eaddr; | 1068 | vm->max_pde_used = eaddr; |
| 1069 | 1069 | ||
| 1070 | amdgpu_bo_unreserve(bo_va->bo); | ||
| 1071 | |||
| 1072 | /* walk over the address space and allocate the page tables */ | 1070 | /* walk over the address space and allocate the page tables */ |
| 1073 | for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) { | 1071 | for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) { |
| 1074 | struct reservation_object *resv = vm->page_directory->tbo.resv; | 1072 | struct reservation_object *resv = vm->page_directory->tbo.resv; |
| @@ -1077,16 +1075,19 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
| 1077 | if (vm->page_tables[pt_idx].bo) | 1075 | if (vm->page_tables[pt_idx].bo) |
| 1078 | continue; | 1076 | continue; |
| 1079 | 1077 | ||
| 1080 | ww_mutex_lock(&resv->lock, NULL); | ||
| 1081 | r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8, | 1078 | r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8, |
| 1082 | AMDGPU_GPU_PAGE_SIZE, true, | 1079 | AMDGPU_GPU_PAGE_SIZE, true, |
| 1083 | AMDGPU_GEM_DOMAIN_VRAM, | 1080 | AMDGPU_GEM_DOMAIN_VRAM, |
| 1084 | AMDGPU_GEM_CREATE_NO_CPU_ACCESS, | 1081 | AMDGPU_GEM_CREATE_NO_CPU_ACCESS, |
| 1085 | NULL, resv, &pt); | 1082 | NULL, resv, &pt); |
| 1086 | ww_mutex_unlock(&resv->lock); | ||
| 1087 | if (r) | 1083 | if (r) |
| 1088 | goto error_free; | 1084 | goto error_free; |
| 1089 | 1085 | ||
| 1086 | /* Keep a reference to the page table to avoid freeing | ||
| 1087 | * them up in the wrong order. | ||
| 1088 | */ | ||
| 1089 | pt->parent = amdgpu_bo_ref(vm->page_directory); | ||
| 1090 | |||
| 1090 | r = amdgpu_vm_clear_bo(adev, pt); | 1091 | r = amdgpu_vm_clear_bo(adev, pt); |
| 1091 | if (r) { | 1092 | if (r) { |
| 1092 | amdgpu_bo_unref(&pt); | 1093 | amdgpu_bo_unref(&pt); |
| @@ -1101,7 +1102,9 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
| 1101 | 1102 | ||
| 1102 | error_free: | 1103 | error_free: |
| 1103 | list_del(&mapping->list); | 1104 | list_del(&mapping->list); |
| 1105 | spin_lock(&vm->it_lock); | ||
| 1104 | interval_tree_remove(&mapping->it, &vm->va); | 1106 | interval_tree_remove(&mapping->it, &vm->va); |
| 1107 | spin_unlock(&vm->it_lock); | ||
| 1105 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1108 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
| 1106 | kfree(mapping); | 1109 | kfree(mapping); |
| 1107 | 1110 | ||
| @@ -1119,7 +1122,7 @@ error: | |||
| 1119 | * Remove a mapping of the BO at the specefied addr from the VM. | 1122 | * Remove a mapping of the BO at the specefied addr from the VM. |
| 1120 | * Returns 0 for success, error for failure. | 1123 | * Returns 0 for success, error for failure. |
| 1121 | * | 1124 | * |
| 1122 | * Object has to be reserved and gets unreserved by this function! | 1125 | * Object has to be reserved and unreserved outside! |
| 1123 | */ | 1126 | */ |
| 1124 | int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | 1127 | int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, |
| 1125 | struct amdgpu_bo_va *bo_va, | 1128 | struct amdgpu_bo_va *bo_va, |
| @@ -1130,7 +1133,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
| 1130 | bool valid = true; | 1133 | bool valid = true; |
| 1131 | 1134 | ||
| 1132 | saddr /= AMDGPU_GPU_PAGE_SIZE; | 1135 | saddr /= AMDGPU_GPU_PAGE_SIZE; |
| 1133 | 1136 | mutex_lock(&bo_va->mutex); | |
| 1134 | list_for_each_entry(mapping, &bo_va->valids, list) { | 1137 | list_for_each_entry(mapping, &bo_va->valids, list) { |
| 1135 | if (mapping->it.start == saddr) | 1138 | if (mapping->it.start == saddr) |
| 1136 | break; | 1139 | break; |
| @@ -1145,20 +1148,24 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
| 1145 | } | 1148 | } |
| 1146 | 1149 | ||
| 1147 | if (&mapping->list == &bo_va->invalids) { | 1150 | if (&mapping->list == &bo_va->invalids) { |
| 1148 | amdgpu_bo_unreserve(bo_va->bo); | 1151 | mutex_unlock(&bo_va->mutex); |
| 1149 | return -ENOENT; | 1152 | return -ENOENT; |
| 1150 | } | 1153 | } |
| 1151 | } | 1154 | } |
| 1152 | 1155 | mutex_unlock(&bo_va->mutex); | |
| 1153 | list_del(&mapping->list); | 1156 | list_del(&mapping->list); |
| 1157 | spin_lock(&vm->it_lock); | ||
| 1154 | interval_tree_remove(&mapping->it, &vm->va); | 1158 | interval_tree_remove(&mapping->it, &vm->va); |
| 1159 | spin_unlock(&vm->it_lock); | ||
| 1155 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1160 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
| 1156 | 1161 | ||
| 1157 | if (valid) | 1162 | if (valid) { |
| 1163 | spin_lock(&vm->freed_lock); | ||
| 1158 | list_add(&mapping->list, &vm->freed); | 1164 | list_add(&mapping->list, &vm->freed); |
| 1159 | else | 1165 | spin_unlock(&vm->freed_lock); |
| 1166 | } else { | ||
| 1160 | kfree(mapping); | 1167 | kfree(mapping); |
| 1161 | amdgpu_bo_unreserve(bo_va->bo); | 1168 | } |
| 1162 | 1169 | ||
| 1163 | return 0; | 1170 | return 0; |
| 1164 | } | 1171 | } |
| @@ -1187,17 +1194,23 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
| 1187 | 1194 | ||
| 1188 | list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { | 1195 | list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { |
| 1189 | list_del(&mapping->list); | 1196 | list_del(&mapping->list); |
| 1197 | spin_lock(&vm->it_lock); | ||
| 1190 | interval_tree_remove(&mapping->it, &vm->va); | 1198 | interval_tree_remove(&mapping->it, &vm->va); |
| 1199 | spin_unlock(&vm->it_lock); | ||
| 1191 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1200 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
| 1201 | spin_lock(&vm->freed_lock); | ||
| 1192 | list_add(&mapping->list, &vm->freed); | 1202 | list_add(&mapping->list, &vm->freed); |
| 1203 | spin_unlock(&vm->freed_lock); | ||
| 1193 | } | 1204 | } |
| 1194 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { | 1205 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { |
| 1195 | list_del(&mapping->list); | 1206 | list_del(&mapping->list); |
| 1207 | spin_lock(&vm->it_lock); | ||
| 1196 | interval_tree_remove(&mapping->it, &vm->va); | 1208 | interval_tree_remove(&mapping->it, &vm->va); |
| 1209 | spin_unlock(&vm->it_lock); | ||
| 1197 | kfree(mapping); | 1210 | kfree(mapping); |
| 1198 | } | 1211 | } |
| 1199 | |||
| 1200 | fence_put(bo_va->last_pt_update); | 1212 | fence_put(bo_va->last_pt_update); |
| 1213 | mutex_destroy(&bo_va->mutex); | ||
| 1201 | kfree(bo_va); | 1214 | kfree(bo_va); |
| 1202 | } | 1215 | } |
| 1203 | 1216 | ||
| @@ -1241,15 +1254,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
| 1241 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1254 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 1242 | vm->ids[i].id = 0; | 1255 | vm->ids[i].id = 0; |
| 1243 | vm->ids[i].flushed_updates = NULL; | 1256 | vm->ids[i].flushed_updates = NULL; |
| 1244 | vm->ids[i].last_id_use = NULL; | ||
| 1245 | } | 1257 | } |
| 1246 | mutex_init(&vm->mutex); | ||
| 1247 | vm->va = RB_ROOT; | 1258 | vm->va = RB_ROOT; |
| 1248 | spin_lock_init(&vm->status_lock); | 1259 | spin_lock_init(&vm->status_lock); |
| 1249 | INIT_LIST_HEAD(&vm->invalidated); | 1260 | INIT_LIST_HEAD(&vm->invalidated); |
| 1250 | INIT_LIST_HEAD(&vm->cleared); | 1261 | INIT_LIST_HEAD(&vm->cleared); |
| 1251 | INIT_LIST_HEAD(&vm->freed); | 1262 | INIT_LIST_HEAD(&vm->freed); |
| 1252 | 1263 | spin_lock_init(&vm->it_lock); | |
| 1264 | spin_lock_init(&vm->freed_lock); | ||
| 1253 | pd_size = amdgpu_vm_directory_size(adev); | 1265 | pd_size = amdgpu_vm_directory_size(adev); |
| 1254 | pd_entries = amdgpu_vm_num_pdes(adev); | 1266 | pd_entries = amdgpu_vm_num_pdes(adev); |
| 1255 | 1267 | ||
| @@ -1269,8 +1281,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
| 1269 | NULL, NULL, &vm->page_directory); | 1281 | NULL, NULL, &vm->page_directory); |
| 1270 | if (r) | 1282 | if (r) |
| 1271 | return r; | 1283 | return r; |
| 1272 | 1284 | r = amdgpu_bo_reserve(vm->page_directory, false); | |
| 1285 | if (r) { | ||
| 1286 | amdgpu_bo_unref(&vm->page_directory); | ||
| 1287 | vm->page_directory = NULL; | ||
| 1288 | return r; | ||
| 1289 | } | ||
| 1273 | r = amdgpu_vm_clear_bo(adev, vm->page_directory); | 1290 | r = amdgpu_vm_clear_bo(adev, vm->page_directory); |
| 1291 | amdgpu_bo_unreserve(vm->page_directory); | ||
| 1274 | if (r) { | 1292 | if (r) { |
| 1275 | amdgpu_bo_unref(&vm->page_directory); | 1293 | amdgpu_bo_unref(&vm->page_directory); |
| 1276 | vm->page_directory = NULL; | 1294 | vm->page_directory = NULL; |
| @@ -1313,11 +1331,27 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
| 1313 | 1331 | ||
| 1314 | amdgpu_bo_unref(&vm->page_directory); | 1332 | amdgpu_bo_unref(&vm->page_directory); |
| 1315 | fence_put(vm->page_directory_fence); | 1333 | fence_put(vm->page_directory_fence); |
| 1316 | |||
| 1317 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1334 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
| 1335 | unsigned id = vm->ids[i].id; | ||
| 1336 | |||
| 1337 | atomic_long_cmpxchg(&adev->vm_manager.ids[id].owner, | ||
| 1338 | (long)vm, 0); | ||
| 1318 | fence_put(vm->ids[i].flushed_updates); | 1339 | fence_put(vm->ids[i].flushed_updates); |
| 1319 | fence_put(vm->ids[i].last_id_use); | ||
| 1320 | } | 1340 | } |
| 1321 | 1341 | ||
| 1322 | mutex_destroy(&vm->mutex); | 1342 | } |
| 1343 | |||
| 1344 | /** | ||
| 1345 | * amdgpu_vm_manager_fini - cleanup VM manager | ||
| 1346 | * | ||
| 1347 | * @adev: amdgpu_device pointer | ||
| 1348 | * | ||
| 1349 | * Cleanup the VM manager and free resources. | ||
| 1350 | */ | ||
| 1351 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev) | ||
| 1352 | { | ||
| 1353 | unsigned i; | ||
| 1354 | |||
| 1355 | for (i = 0; i < AMDGPU_NUM_VM; ++i) | ||
| 1356 | fence_put(adev->vm_manager.ids[i].active); | ||
| 1323 | } | 1357 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index a1a35a5df8e7..57a2e347f04d 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
| @@ -6569,12 +6569,12 @@ static int ci_dpm_set_interrupt_state(struct amdgpu_device *adev, | |||
| 6569 | switch (state) { | 6569 | switch (state) { |
| 6570 | case AMDGPU_IRQ_STATE_DISABLE: | 6570 | case AMDGPU_IRQ_STATE_DISABLE: |
| 6571 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); | 6571 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); |
| 6572 | cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; | 6572 | cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; |
| 6573 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); | 6573 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); |
| 6574 | break; | 6574 | break; |
| 6575 | case AMDGPU_IRQ_STATE_ENABLE: | 6575 | case AMDGPU_IRQ_STATE_ENABLE: |
| 6576 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); | 6576 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); |
| 6577 | cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; | 6577 | cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; |
| 6578 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); | 6578 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); |
| 6579 | break; | 6579 | break; |
| 6580 | default: | 6580 | default: |
| @@ -6586,12 +6586,12 @@ static int ci_dpm_set_interrupt_state(struct amdgpu_device *adev, | |||
| 6586 | switch (state) { | 6586 | switch (state) { |
| 6587 | case AMDGPU_IRQ_STATE_DISABLE: | 6587 | case AMDGPU_IRQ_STATE_DISABLE: |
| 6588 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); | 6588 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); |
| 6589 | cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; | 6589 | cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; |
| 6590 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); | 6590 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); |
| 6591 | break; | 6591 | break; |
| 6592 | case AMDGPU_IRQ_STATE_ENABLE: | 6592 | case AMDGPU_IRQ_STATE_ENABLE: |
| 6593 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); | 6593 | cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); |
| 6594 | cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; | 6594 | cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; |
| 6595 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); | 6595 | WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); |
| 6596 | break; | 6596 | break; |
| 6597 | default: | 6597 | default: |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index cb0f7747e3dc..4dcc8fba5792 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | |||
| @@ -1250,7 +1250,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1250 | u32 pixel_period; | 1250 | u32 pixel_period; |
| 1251 | u32 line_time = 0; | 1251 | u32 line_time = 0; |
| 1252 | u32 latency_watermark_a = 0, latency_watermark_b = 0; | 1252 | u32 latency_watermark_a = 0, latency_watermark_b = 0; |
| 1253 | u32 tmp, wm_mask; | 1253 | u32 tmp, wm_mask, lb_vblank_lead_lines = 0; |
| 1254 | 1254 | ||
| 1255 | if (amdgpu_crtc->base.enabled && num_heads && mode) { | 1255 | if (amdgpu_crtc->base.enabled && num_heads && mode) { |
| 1256 | pixel_period = 1000000 / (u32)mode->clock; | 1256 | pixel_period = 1000000 / (u32)mode->clock; |
| @@ -1333,6 +1333,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1333 | (adev->mode_info.disp_priority == 2)) { | 1333 | (adev->mode_info.disp_priority == 2)) { |
| 1334 | DRM_DEBUG_KMS("force priority to high\n"); | 1334 | DRM_DEBUG_KMS("force priority to high\n"); |
| 1335 | } | 1335 | } |
| 1336 | lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
| 1336 | } | 1337 | } |
| 1337 | 1338 | ||
| 1338 | /* select wm A */ | 1339 | /* select wm A */ |
| @@ -1357,6 +1358,8 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1357 | amdgpu_crtc->line_time = line_time; | 1358 | amdgpu_crtc->line_time = line_time; |
| 1358 | amdgpu_crtc->wm_high = latency_watermark_a; | 1359 | amdgpu_crtc->wm_high = latency_watermark_a; |
| 1359 | amdgpu_crtc->wm_low = latency_watermark_b; | 1360 | amdgpu_crtc->wm_low = latency_watermark_b; |
| 1361 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 1362 | amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; | ||
| 1360 | } | 1363 | } |
| 1361 | 1364 | ||
| 1362 | /** | 1365 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 5af3721851d6..8f1e51128b33 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | |||
| @@ -1238,7 +1238,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1238 | u32 pixel_period; | 1238 | u32 pixel_period; |
| 1239 | u32 line_time = 0; | 1239 | u32 line_time = 0; |
| 1240 | u32 latency_watermark_a = 0, latency_watermark_b = 0; | 1240 | u32 latency_watermark_a = 0, latency_watermark_b = 0; |
| 1241 | u32 tmp, wm_mask; | 1241 | u32 tmp, wm_mask, lb_vblank_lead_lines = 0; |
| 1242 | 1242 | ||
| 1243 | if (amdgpu_crtc->base.enabled && num_heads && mode) { | 1243 | if (amdgpu_crtc->base.enabled && num_heads && mode) { |
| 1244 | pixel_period = 1000000 / (u32)mode->clock; | 1244 | pixel_period = 1000000 / (u32)mode->clock; |
| @@ -1321,6 +1321,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1321 | (adev->mode_info.disp_priority == 2)) { | 1321 | (adev->mode_info.disp_priority == 2)) { |
| 1322 | DRM_DEBUG_KMS("force priority to high\n"); | 1322 | DRM_DEBUG_KMS("force priority to high\n"); |
| 1323 | } | 1323 | } |
| 1324 | lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
| 1324 | } | 1325 | } |
| 1325 | 1326 | ||
| 1326 | /* select wm A */ | 1327 | /* select wm A */ |
| @@ -1345,6 +1346,8 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1345 | amdgpu_crtc->line_time = line_time; | 1346 | amdgpu_crtc->line_time = line_time; |
| 1346 | amdgpu_crtc->wm_high = latency_watermark_a; | 1347 | amdgpu_crtc->wm_high = latency_watermark_a; |
| 1347 | amdgpu_crtc->wm_low = latency_watermark_b; | 1348 | amdgpu_crtc->wm_low = latency_watermark_b; |
| 1349 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 1350 | amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; | ||
| 1348 | } | 1351 | } |
| 1349 | 1352 | ||
| 1350 | /** | 1353 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 4f7b49a6dc50..42d954dc436d 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | |||
| @@ -1193,7 +1193,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1193 | u32 pixel_period; | 1193 | u32 pixel_period; |
| 1194 | u32 line_time = 0; | 1194 | u32 line_time = 0; |
| 1195 | u32 latency_watermark_a = 0, latency_watermark_b = 0; | 1195 | u32 latency_watermark_a = 0, latency_watermark_b = 0; |
| 1196 | u32 tmp, wm_mask; | 1196 | u32 tmp, wm_mask, lb_vblank_lead_lines = 0; |
| 1197 | 1197 | ||
| 1198 | if (amdgpu_crtc->base.enabled && num_heads && mode) { | 1198 | if (amdgpu_crtc->base.enabled && num_heads && mode) { |
| 1199 | pixel_period = 1000000 / (u32)mode->clock; | 1199 | pixel_period = 1000000 / (u32)mode->clock; |
| @@ -1276,6 +1276,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1276 | (adev->mode_info.disp_priority == 2)) { | 1276 | (adev->mode_info.disp_priority == 2)) { |
| 1277 | DRM_DEBUG_KMS("force priority to high\n"); | 1277 | DRM_DEBUG_KMS("force priority to high\n"); |
| 1278 | } | 1278 | } |
| 1279 | lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
| 1279 | } | 1280 | } |
| 1280 | 1281 | ||
| 1281 | /* select wm A */ | 1282 | /* select wm A */ |
| @@ -1302,6 +1303,8 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, | |||
| 1302 | amdgpu_crtc->line_time = line_time; | 1303 | amdgpu_crtc->line_time = line_time; |
| 1303 | amdgpu_crtc->wm_high = latency_watermark_a; | 1304 | amdgpu_crtc->wm_high = latency_watermark_a; |
| 1304 | amdgpu_crtc->wm_low = latency_watermark_b; | 1305 | amdgpu_crtc->wm_low = latency_watermark_b; |
| 1306 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 1307 | amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; | ||
| 1305 | } | 1308 | } |
| 1306 | 1309 | ||
| 1307 | /** | 1310 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 6776cf756d40..e1dcab98e249 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
| @@ -268,7 +268,6 @@ static const u32 fiji_mgcg_cgcg_init[] = | |||
| 268 | mmCGTT_CP_CLK_CTRL, 0xffffffff, 0x00000100, | 268 | mmCGTT_CP_CLK_CTRL, 0xffffffff, 0x00000100, |
| 269 | mmCGTT_CPC_CLK_CTRL, 0xffffffff, 0x00000100, | 269 | mmCGTT_CPC_CLK_CTRL, 0xffffffff, 0x00000100, |
| 270 | mmCGTT_CPF_CLK_CTRL, 0xffffffff, 0x40000100, | 270 | mmCGTT_CPF_CLK_CTRL, 0xffffffff, 0x40000100, |
| 271 | mmCGTT_DRM_CLK_CTRL0, 0xffffffff, 0x00600100, | ||
| 272 | mmCGTT_GDS_CLK_CTRL, 0xffffffff, 0x00000100, | 271 | mmCGTT_GDS_CLK_CTRL, 0xffffffff, 0x00000100, |
| 273 | mmCGTT_IA_CLK_CTRL, 0xffffffff, 0x06000100, | 272 | mmCGTT_IA_CLK_CTRL, 0xffffffff, 0x06000100, |
| 274 | mmCGTT_PA_CLK_CTRL, 0xffffffff, 0x00000100, | 273 | mmCGTT_PA_CLK_CTRL, 0xffffffff, 0x00000100, |
| @@ -296,10 +295,6 @@ static const u32 fiji_mgcg_cgcg_init[] = | |||
| 296 | mmCGTS_SM_CTRL_REG, 0xffffffff, 0x96e00200, | 295 | mmCGTS_SM_CTRL_REG, 0xffffffff, 0x96e00200, |
| 297 | mmCP_RB_WPTR_POLL_CNTL, 0xffffffff, 0x00900100, | 296 | mmCP_RB_WPTR_POLL_CNTL, 0xffffffff, 0x00900100, |
| 298 | mmRLC_CGCG_CGLS_CTRL, 0xffffffff, 0x0020003c, | 297 | mmRLC_CGCG_CGLS_CTRL, 0xffffffff, 0x0020003c, |
| 299 | mmPCIE_INDEX, 0xffffffff, 0x0140001c, | ||
| 300 | mmPCIE_DATA, 0x000f0000, 0x00000000, | ||
| 301 | mmCGTT_DRM_CLK_CTRL0, 0xff000fff, 0x00000100, | ||
| 302 | mmHDP_XDP_CGTT_BLK_CTRL, 0xc0000fff, 0x00000104, | ||
| 303 | mmCP_MEM_SLP_CNTL, 0x00000001, 0x00000001, | 298 | mmCP_MEM_SLP_CNTL, 0x00000001, 0x00000001, |
| 304 | }; | 299 | }; |
| 305 | 300 | ||
| @@ -1000,7 +995,7 @@ static void gfx_v8_0_gpu_early_init(struct amdgpu_device *adev) | |||
| 1000 | adev->gfx.config.max_cu_per_sh = 16; | 995 | adev->gfx.config.max_cu_per_sh = 16; |
| 1001 | adev->gfx.config.max_sh_per_se = 1; | 996 | adev->gfx.config.max_sh_per_se = 1; |
| 1002 | adev->gfx.config.max_backends_per_se = 4; | 997 | adev->gfx.config.max_backends_per_se = 4; |
| 1003 | adev->gfx.config.max_texture_channel_caches = 8; | 998 | adev->gfx.config.max_texture_channel_caches = 16; |
| 1004 | adev->gfx.config.max_gprs = 256; | 999 | adev->gfx.config.max_gprs = 256; |
| 1005 | adev->gfx.config.max_gs_threads = 32; | 1000 | adev->gfx.config.max_gs_threads = 32; |
| 1006 | adev->gfx.config.max_hw_contexts = 8; | 1001 | adev->gfx.config.max_hw_contexts = 8; |
| @@ -1613,6 +1608,296 @@ static void gfx_v8_0_tiling_mode_table_init(struct amdgpu_device *adev) | |||
| 1613 | WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); | 1608 | WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); |
| 1614 | } | 1609 | } |
| 1615 | case CHIP_FIJI: | 1610 | case CHIP_FIJI: |
| 1611 | for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { | ||
| 1612 | switch (reg_offset) { | ||
| 1613 | case 0: | ||
| 1614 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1615 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1616 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | | ||
| 1617 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1618 | break; | ||
| 1619 | case 1: | ||
| 1620 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1621 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1622 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | | ||
| 1623 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1624 | break; | ||
| 1625 | case 2: | ||
| 1626 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1627 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1628 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | ||
| 1629 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1630 | break; | ||
| 1631 | case 3: | ||
| 1632 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1633 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1634 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | | ||
| 1635 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1636 | break; | ||
| 1637 | case 4: | ||
| 1638 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1639 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1640 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | | ||
| 1641 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1642 | break; | ||
| 1643 | case 5: | ||
| 1644 | gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | | ||
| 1645 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1646 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | | ||
| 1647 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1648 | break; | ||
| 1649 | case 6: | ||
| 1650 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1651 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1652 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | | ||
| 1653 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1654 | break; | ||
| 1655 | case 7: | ||
| 1656 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1657 | PIPE_CONFIG(ADDR_SURF_P4_16x16) | | ||
| 1658 | TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | | ||
| 1659 | MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); | ||
| 1660 | break; | ||
| 1661 | case 8: | ||
| 1662 | gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | | ||
| 1663 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16)); | ||
| 1664 | break; | ||
| 1665 | case 9: | ||
| 1666 | gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | | ||
| 1667 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1668 | MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | | ||
| 1669 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); | ||
| 1670 | break; | ||
| 1671 | case 10: | ||
| 1672 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1673 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1674 | MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | | ||
| 1675 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); | ||
| 1676 | break; | ||
| 1677 | case 11: | ||
| 1678 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1679 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1680 | MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | | ||
| 1681 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); | ||
| 1682 | break; | ||
| 1683 | case 12: | ||
| 1684 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1685 | PIPE_CONFIG(ADDR_SURF_P4_16x16) | | ||
| 1686 | MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | | ||
| 1687 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); | ||
| 1688 | break; | ||
| 1689 | case 13: | ||
| 1690 | gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | | ||
| 1691 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1692 | MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | | ||
| 1693 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); | ||
| 1694 | break; | ||
| 1695 | case 14: | ||
| 1696 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1697 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1698 | MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | | ||
| 1699 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); | ||
| 1700 | break; | ||
| 1701 | case 15: | ||
| 1702 | gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | | ||
| 1703 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1704 | MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | | ||
| 1705 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); | ||
| 1706 | break; | ||
| 1707 | case 16: | ||
| 1708 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1709 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1710 | MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | | ||
| 1711 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); | ||
| 1712 | break; | ||
| 1713 | case 17: | ||
| 1714 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1715 | PIPE_CONFIG(ADDR_SURF_P4_16x16) | | ||
| 1716 | MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | | ||
| 1717 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); | ||
| 1718 | break; | ||
| 1719 | case 18: | ||
| 1720 | gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | | ||
| 1721 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1722 | MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | | ||
| 1723 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1724 | break; | ||
| 1725 | case 19: | ||
| 1726 | gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | | ||
| 1727 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1728 | MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | | ||
| 1729 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1730 | break; | ||
| 1731 | case 20: | ||
| 1732 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | | ||
| 1733 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1734 | MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | | ||
| 1735 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1736 | break; | ||
| 1737 | case 21: | ||
| 1738 | gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | | ||
| 1739 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1740 | MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | | ||
| 1741 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1742 | break; | ||
| 1743 | case 22: | ||
| 1744 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | | ||
| 1745 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1746 | MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | | ||
| 1747 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1748 | break; | ||
| 1749 | case 23: | ||
| 1750 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | | ||
| 1751 | PIPE_CONFIG(ADDR_SURF_P4_16x16) | | ||
| 1752 | MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | | ||
| 1753 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1754 | break; | ||
| 1755 | case 24: | ||
| 1756 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | | ||
| 1757 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1758 | MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | | ||
| 1759 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1760 | break; | ||
| 1761 | case 25: | ||
| 1762 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | | ||
| 1763 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1764 | MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | | ||
| 1765 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1766 | break; | ||
| 1767 | case 26: | ||
| 1768 | gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | | ||
| 1769 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1770 | MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | | ||
| 1771 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); | ||
| 1772 | break; | ||
| 1773 | case 27: | ||
| 1774 | gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | | ||
| 1775 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1776 | MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | | ||
| 1777 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); | ||
| 1778 | break; | ||
| 1779 | case 28: | ||
| 1780 | gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | ||
| 1781 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1782 | MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | | ||
| 1783 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); | ||
| 1784 | break; | ||
| 1785 | case 29: | ||
| 1786 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1787 | PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | | ||
| 1788 | MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | | ||
| 1789 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); | ||
| 1790 | break; | ||
| 1791 | case 30: | ||
| 1792 | gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | | ||
| 1793 | PIPE_CONFIG(ADDR_SURF_P4_16x16) | | ||
| 1794 | MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | | ||
| 1795 | SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); | ||
| 1796 | break; | ||
| 1797 | default: | ||
| 1798 | gb_tile_moden = 0; | ||
| 1799 | break; | ||
| 1800 | } | ||
| 1801 | adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; | ||
| 1802 | WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); | ||
| 1803 | } | ||
| 1804 | for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { | ||
| 1805 | switch (reg_offset) { | ||
| 1806 | case 0: | ||
| 1807 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1808 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | ||
| 1809 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1810 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1811 | break; | ||
| 1812 | case 1: | ||
| 1813 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1814 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | ||
| 1815 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1816 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1817 | break; | ||
| 1818 | case 2: | ||
| 1819 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1820 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | ||
| 1821 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1822 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1823 | break; | ||
| 1824 | case 3: | ||
| 1825 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1826 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | ||
| 1827 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1828 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1829 | break; | ||
| 1830 | case 4: | ||
| 1831 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1832 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | ||
| 1833 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | | ||
| 1834 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1835 | break; | ||
| 1836 | case 5: | ||
| 1837 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1838 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | ||
| 1839 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | | ||
| 1840 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1841 | break; | ||
| 1842 | case 6: | ||
| 1843 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1844 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | ||
| 1845 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | | ||
| 1846 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1847 | break; | ||
| 1848 | case 8: | ||
| 1849 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1850 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | | ||
| 1851 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1852 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1853 | break; | ||
| 1854 | case 9: | ||
| 1855 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1856 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | ||
| 1857 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1858 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1859 | break; | ||
| 1860 | case 10: | ||
| 1861 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1862 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | ||
| 1863 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | | ||
| 1864 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1865 | break; | ||
| 1866 | case 11: | ||
| 1867 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1868 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | ||
| 1869 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | | ||
| 1870 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1871 | break; | ||
| 1872 | case 12: | ||
| 1873 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1874 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | ||
| 1875 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1876 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1877 | break; | ||
| 1878 | case 13: | ||
| 1879 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1880 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | ||
| 1881 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | | ||
| 1882 | NUM_BANKS(ADDR_SURF_8_BANK)); | ||
| 1883 | break; | ||
| 1884 | case 14: | ||
| 1885 | gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | ||
| 1886 | BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | ||
| 1887 | MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | | ||
| 1888 | NUM_BANKS(ADDR_SURF_4_BANK)); | ||
| 1889 | break; | ||
| 1890 | case 7: | ||
| 1891 | /* unused idx */ | ||
| 1892 | continue; | ||
| 1893 | default: | ||
| 1894 | gb_tile_moden = 0; | ||
| 1895 | break; | ||
| 1896 | } | ||
| 1897 | adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; | ||
| 1898 | WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); | ||
| 1899 | } | ||
| 1900 | break; | ||
| 1616 | case CHIP_TONGA: | 1901 | case CHIP_TONGA: |
| 1617 | for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { | 1902 | for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { |
| 1618 | switch (reg_offset) { | 1903 | switch (reg_offset) { |
| @@ -2971,10 +3256,13 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) | |||
| 2971 | amdgpu_ring_write(ring, mmPA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); | 3256 | amdgpu_ring_write(ring, mmPA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); |
| 2972 | switch (adev->asic_type) { | 3257 | switch (adev->asic_type) { |
| 2973 | case CHIP_TONGA: | 3258 | case CHIP_TONGA: |
| 2974 | case CHIP_FIJI: | ||
| 2975 | amdgpu_ring_write(ring, 0x16000012); | 3259 | amdgpu_ring_write(ring, 0x16000012); |
| 2976 | amdgpu_ring_write(ring, 0x0000002A); | 3260 | amdgpu_ring_write(ring, 0x0000002A); |
| 2977 | break; | 3261 | break; |
| 3262 | case CHIP_FIJI: | ||
| 3263 | amdgpu_ring_write(ring, 0x3a00161a); | ||
| 3264 | amdgpu_ring_write(ring, 0x0000002e); | ||
| 3265 | break; | ||
| 2978 | case CHIP_TOPAZ: | 3266 | case CHIP_TOPAZ: |
| 2979 | case CHIP_CARRIZO: | 3267 | case CHIP_CARRIZO: |
| 2980 | amdgpu_ring_write(ring, 0x00000002); | 3268 | amdgpu_ring_write(ring, 0x00000002); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 85bbcdc73fff..ed8abb58a785 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev); | 40 | static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev); |
| 41 | static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); | 41 | static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); |
| 42 | 42 | ||
| 43 | MODULE_FIRMWARE("radeon/boniare_mc.bin"); | 43 | MODULE_FIRMWARE("radeon/bonaire_mc.bin"); |
| 44 | MODULE_FIRMWARE("radeon/hawaii_mc.bin"); | 44 | MODULE_FIRMWARE("radeon/hawaii_mc.bin"); |
| 45 | 45 | ||
| 46 | /** | 46 | /** |
| @@ -501,6 +501,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) | |||
| 501 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE, 1); | 501 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE, 1); |
| 502 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, EFFECTIVE_L2_QUEUE_SIZE, 7); | 502 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, EFFECTIVE_L2_QUEUE_SIZE, 7); |
| 503 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); | 503 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); |
| 504 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1); | ||
| 504 | WREG32(mmVM_L2_CNTL, tmp); | 505 | WREG32(mmVM_L2_CNTL, tmp); |
| 505 | tmp = REG_SET_FIELD(0, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); | 506 | tmp = REG_SET_FIELD(0, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); |
| 506 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1); | 507 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1); |
| @@ -512,7 +513,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) | |||
| 512 | WREG32(mmVM_L2_CNTL3, tmp); | 513 | WREG32(mmVM_L2_CNTL3, tmp); |
| 513 | /* setup context0 */ | 514 | /* setup context0 */ |
| 514 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); | 515 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); |
| 515 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1); | 516 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12); |
| 516 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); | 517 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); |
| 517 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | 518 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
| 518 | (u32)(adev->dummy_page.addr >> 12)); | 519 | (u32)(adev->dummy_page.addr >> 12)); |
| @@ -960,12 +961,10 @@ static int gmc_v7_0_sw_init(void *handle) | |||
| 960 | 961 | ||
| 961 | static int gmc_v7_0_sw_fini(void *handle) | 962 | static int gmc_v7_0_sw_fini(void *handle) |
| 962 | { | 963 | { |
| 963 | int i; | ||
| 964 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 964 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 965 | 965 | ||
| 966 | if (adev->vm_manager.enabled) { | 966 | if (adev->vm_manager.enabled) { |
| 967 | for (i = 0; i < AMDGPU_NUM_VM; ++i) | 967 | amdgpu_vm_manager_fini(adev); |
| 968 | fence_put(adev->vm_manager.active[i]); | ||
| 969 | gmc_v7_0_vm_fini(adev); | 968 | gmc_v7_0_vm_fini(adev); |
| 970 | adev->vm_manager.enabled = false; | 969 | adev->vm_manager.enabled = false; |
| 971 | } | 970 | } |
| @@ -1010,12 +1009,10 @@ static int gmc_v7_0_hw_fini(void *handle) | |||
| 1010 | 1009 | ||
| 1011 | static int gmc_v7_0_suspend(void *handle) | 1010 | static int gmc_v7_0_suspend(void *handle) |
| 1012 | { | 1011 | { |
| 1013 | int i; | ||
| 1014 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1012 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1015 | 1013 | ||
| 1016 | if (adev->vm_manager.enabled) { | 1014 | if (adev->vm_manager.enabled) { |
| 1017 | for (i = 0; i < AMDGPU_NUM_VM; ++i) | 1015 | amdgpu_vm_manager_fini(adev); |
| 1018 | fence_put(adev->vm_manager.active[i]); | ||
| 1019 | gmc_v7_0_vm_fini(adev); | 1016 | gmc_v7_0_vm_fini(adev); |
| 1020 | adev->vm_manager.enabled = false; | 1017 | adev->vm_manager.enabled = false; |
| 1021 | } | 1018 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 1bcc4e74e3b4..d39028440814 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
| @@ -629,6 +629,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) | |||
| 629 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE, 1); | 629 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE, 1); |
| 630 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, EFFECTIVE_L2_QUEUE_SIZE, 7); | 630 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, EFFECTIVE_L2_QUEUE_SIZE, 7); |
| 631 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); | 631 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); |
| 632 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1); | ||
| 632 | WREG32(mmVM_L2_CNTL, tmp); | 633 | WREG32(mmVM_L2_CNTL, tmp); |
| 633 | tmp = RREG32(mmVM_L2_CNTL2); | 634 | tmp = RREG32(mmVM_L2_CNTL2); |
| 634 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); | 635 | tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); |
| @@ -656,7 +657,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) | |||
| 656 | WREG32(mmVM_L2_CNTL4, tmp); | 657 | WREG32(mmVM_L2_CNTL4, tmp); |
| 657 | /* setup context0 */ | 658 | /* setup context0 */ |
| 658 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); | 659 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); |
| 659 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1); | 660 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12); |
| 660 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); | 661 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); |
| 661 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | 662 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
| 662 | (u32)(adev->dummy_page.addr >> 12)); | 663 | (u32)(adev->dummy_page.addr >> 12)); |
| @@ -979,12 +980,10 @@ static int gmc_v8_0_sw_init(void *handle) | |||
| 979 | 980 | ||
| 980 | static int gmc_v8_0_sw_fini(void *handle) | 981 | static int gmc_v8_0_sw_fini(void *handle) |
| 981 | { | 982 | { |
| 982 | int i; | ||
| 983 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 983 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 984 | 984 | ||
| 985 | if (adev->vm_manager.enabled) { | 985 | if (adev->vm_manager.enabled) { |
| 986 | for (i = 0; i < AMDGPU_NUM_VM; ++i) | 986 | amdgpu_vm_manager_fini(adev); |
| 987 | fence_put(adev->vm_manager.active[i]); | ||
| 988 | gmc_v8_0_vm_fini(adev); | 987 | gmc_v8_0_vm_fini(adev); |
| 989 | adev->vm_manager.enabled = false; | 988 | adev->vm_manager.enabled = false; |
| 990 | } | 989 | } |
| @@ -1031,12 +1030,10 @@ static int gmc_v8_0_hw_fini(void *handle) | |||
| 1031 | 1030 | ||
| 1032 | static int gmc_v8_0_suspend(void *handle) | 1031 | static int gmc_v8_0_suspend(void *handle) |
| 1033 | { | 1032 | { |
| 1034 | int i; | ||
| 1035 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1033 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1036 | 1034 | ||
| 1037 | if (adev->vm_manager.enabled) { | 1035 | if (adev->vm_manager.enabled) { |
| 1038 | for (i = 0; i < AMDGPU_NUM_VM; ++i) | 1036 | amdgpu_vm_manager_fini(adev); |
| 1039 | fence_put(adev->vm_manager.active[i]); | ||
| 1040 | gmc_v8_0_vm_fini(adev); | 1037 | gmc_v8_0_vm_fini(adev); |
| 1041 | adev->vm_manager.enabled = false; | 1038 | adev->vm_manager.enabled = false; |
| 1042 | } | 1039 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 6a52db6ad8d7..370c6c9d81c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | |||
| @@ -40,6 +40,9 @@ | |||
| 40 | 40 | ||
| 41 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 | 41 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 |
| 42 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 | 42 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 |
| 43 | #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0 0x8616 | ||
| 44 | #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1 0x8617 | ||
| 45 | #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2 0x8618 | ||
| 43 | 46 | ||
| 44 | #define VCE_V3_0_FW_SIZE (384 * 1024) | 47 | #define VCE_V3_0_FW_SIZE (384 * 1024) |
| 45 | #define VCE_V3_0_STACK_SIZE (64 * 1024) | 48 | #define VCE_V3_0_STACK_SIZE (64 * 1024) |
| @@ -130,9 +133,11 @@ static int vce_v3_0_start(struct amdgpu_device *adev) | |||
| 130 | 133 | ||
| 131 | /* set BUSY flag */ | 134 | /* set BUSY flag */ |
| 132 | WREG32_P(mmVCE_STATUS, 1, ~1); | 135 | WREG32_P(mmVCE_STATUS, 1, ~1); |
| 133 | 136 | if (adev->asic_type >= CHIP_STONEY) | |
| 134 | WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, | 137 | WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001); |
| 135 | ~VCE_VCPU_CNTL__CLK_EN_MASK); | 138 | else |
| 139 | WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, | ||
| 140 | ~VCE_VCPU_CNTL__CLK_EN_MASK); | ||
| 136 | 141 | ||
| 137 | WREG32_P(mmVCE_SOFT_RESET, | 142 | WREG32_P(mmVCE_SOFT_RESET, |
| 138 | VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, | 143 | VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, |
| @@ -391,8 +396,12 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx) | |||
| 391 | WREG32(mmVCE_LMI_SWAP_CNTL, 0); | 396 | WREG32(mmVCE_LMI_SWAP_CNTL, 0); |
| 392 | WREG32(mmVCE_LMI_SWAP_CNTL1, 0); | 397 | WREG32(mmVCE_LMI_SWAP_CNTL1, 0); |
| 393 | WREG32(mmVCE_LMI_VM_CTRL, 0); | 398 | WREG32(mmVCE_LMI_VM_CTRL, 0); |
| 394 | 399 | if (adev->asic_type >= CHIP_STONEY) { | |
| 395 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); | 400 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8)); |
| 401 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8)); | ||
| 402 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8)); | ||
| 403 | } else | ||
| 404 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); | ||
| 396 | offset = AMDGPU_VCE_FIRMWARE_OFFSET; | 405 | offset = AMDGPU_VCE_FIRMWARE_OFFSET; |
| 397 | size = VCE_V3_0_FW_SIZE; | 406 | size = VCE_V3_0_FW_SIZE; |
| 398 | WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); | 407 | WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); |
| @@ -576,6 +585,11 @@ static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, | |||
| 576 | struct amdgpu_iv_entry *entry) | 585 | struct amdgpu_iv_entry *entry) |
| 577 | { | 586 | { |
| 578 | DRM_DEBUG("IH: VCE\n"); | 587 | DRM_DEBUG("IH: VCE\n"); |
| 588 | |||
| 589 | WREG32_P(mmVCE_SYS_INT_STATUS, | ||
| 590 | VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK, | ||
| 591 | ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK); | ||
| 592 | |||
| 579 | switch (entry->src_data) { | 593 | switch (entry->src_data) { |
| 580 | case 0: | 594 | case 0: |
| 581 | amdgpu_fence_process(&adev->vce.ring[0]); | 595 | amdgpu_fence_process(&adev->vce.ring[0]); |
