diff options
author | Philip Cox <Philip.Cox@amd.com> | 2017-11-01 19:22:00 -0400 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@gmail.com> | 2017-11-01 19:22:00 -0400 |
commit | 9807c3668500b0964e8ee59d68083675971bc224 (patch) | |
tree | f35a7543dcf261c758f98b05bff8be781e399b49 | |
parent | fd0f0762dc590736a6692707860af3ce793f5028 (diff) |
drm/amdgpu: Implement amdgpu SDMA functions for VI
Signed-off-by: Philip Cox <Philip.Cox@amd.com>
Signed-off-by: shaoyun liu <shaoyun.liu@amd.com>
Signed-off-by: Yong Zhao <yong.zhao@amd.com>
Signed-off-by: Jay Cornwall <Jay.Cornwall@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 87 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vid.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/include/vi_structs.h | 2 |
3 files changed, 80 insertions, 11 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index c0c8cc3b23b0..1d989e4915b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | |||
@@ -45,7 +45,7 @@ enum hqd_dequeue_request_type { | |||
45 | RESET_WAVES | 45 | RESET_WAVES |
46 | }; | 46 | }; |
47 | 47 | ||
48 | struct cik_sdma_rlc_registers; | 48 | struct vi_sdma_mqd; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Register access functions | 51 | * Register access functions |
@@ -269,9 +269,15 @@ static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) | |||
269 | return 0; | 269 | return 0; |
270 | } | 270 | } |
271 | 271 | ||
272 | static inline uint32_t get_sdma_base_addr(struct cik_sdma_rlc_registers *m) | 272 | static inline uint32_t get_sdma_base_addr(struct vi_sdma_mqd *m) |
273 | { | 273 | { |
274 | return 0; | 274 | uint32_t retval; |
275 | |||
276 | retval = m->sdma_engine_id * SDMA1_REGISTER_OFFSET + | ||
277 | m->sdma_queue_id * KFD_VI_SDMA_QUEUE_OFFSET; | ||
278 | pr_debug("kfd: sdma base address: 0x%x\n", retval); | ||
279 | |||
280 | return retval; | ||
275 | } | 281 | } |
276 | 282 | ||
277 | static inline struct vi_mqd *get_mqd(void *mqd) | 283 | static inline struct vi_mqd *get_mqd(void *mqd) |
@@ -279,9 +285,9 @@ static inline struct vi_mqd *get_mqd(void *mqd) | |||
279 | return (struct vi_mqd *)mqd; | 285 | return (struct vi_mqd *)mqd; |
280 | } | 286 | } |
281 | 287 | ||
282 | static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd) | 288 | static inline struct vi_sdma_mqd *get_sdma_mqd(void *mqd) |
283 | { | 289 | { |
284 | return (struct cik_sdma_rlc_registers *)mqd; | 290 | return (struct vi_sdma_mqd *)mqd; |
285 | } | 291 | } |
286 | 292 | ||
287 | static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | 293 | static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, |
@@ -362,6 +368,63 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | |||
362 | static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, | 368 | static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, |
363 | uint32_t __user *wptr, struct mm_struct *mm) | 369 | uint32_t __user *wptr, struct mm_struct *mm) |
364 | { | 370 | { |
371 | struct amdgpu_device *adev = get_amdgpu_device(kgd); | ||
372 | struct vi_sdma_mqd *m; | ||
373 | unsigned long end_jiffies; | ||
374 | uint32_t sdma_base_addr; | ||
375 | uint32_t data; | ||
376 | |||
377 | m = get_sdma_mqd(mqd); | ||
378 | sdma_base_addr = get_sdma_base_addr(m); | ||
379 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, | ||
380 | m->sdmax_rlcx_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK)); | ||
381 | |||
382 | end_jiffies = msecs_to_jiffies(2000) + jiffies; | ||
383 | while (true) { | ||
384 | data = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS); | ||
385 | if (data & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK) | ||
386 | break; | ||
387 | if (time_after(jiffies, end_jiffies)) | ||
388 | return -ETIME; | ||
389 | usleep_range(500, 1000); | ||
390 | } | ||
391 | if (m->sdma_engine_id) { | ||
392 | data = RREG32(mmSDMA1_GFX_CONTEXT_CNTL); | ||
393 | data = REG_SET_FIELD(data, SDMA1_GFX_CONTEXT_CNTL, | ||
394 | RESUME_CTX, 0); | ||
395 | WREG32(mmSDMA1_GFX_CONTEXT_CNTL, data); | ||
396 | } else { | ||
397 | data = RREG32(mmSDMA0_GFX_CONTEXT_CNTL); | ||
398 | data = REG_SET_FIELD(data, SDMA0_GFX_CONTEXT_CNTL, | ||
399 | RESUME_CTX, 0); | ||
400 | WREG32(mmSDMA0_GFX_CONTEXT_CNTL, data); | ||
401 | } | ||
402 | |||
403 | data = REG_SET_FIELD(m->sdmax_rlcx_doorbell, SDMA0_RLC0_DOORBELL, | ||
404 | ENABLE, 1); | ||
405 | WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, data); | ||
406 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, m->sdmax_rlcx_rb_rptr); | ||
407 | |||
408 | if (read_user_wptr(mm, wptr, data)) | ||
409 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, data); | ||
410 | else | ||
411 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, | ||
412 | m->sdmax_rlcx_rb_rptr); | ||
413 | |||
414 | WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR, | ||
415 | m->sdmax_rlcx_virtual_addr); | ||
416 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdmax_rlcx_rb_base); | ||
417 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI, | ||
418 | m->sdmax_rlcx_rb_base_hi); | ||
419 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO, | ||
420 | m->sdmax_rlcx_rb_rptr_addr_lo); | ||
421 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI, | ||
422 | m->sdmax_rlcx_rb_rptr_addr_hi); | ||
423 | |||
424 | data = REG_SET_FIELD(m->sdmax_rlcx_rb_cntl, SDMA0_RLC0_RB_CNTL, | ||
425 | RB_ENABLE, 1); | ||
426 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, data); | ||
427 | |||
365 | return 0; | 428 | return 0; |
366 | } | 429 | } |
367 | 430 | ||
@@ -390,7 +453,7 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, | |||
390 | static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) | 453 | static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) |
391 | { | 454 | { |
392 | struct amdgpu_device *adev = get_amdgpu_device(kgd); | 455 | struct amdgpu_device *adev = get_amdgpu_device(kgd); |
393 | struct cik_sdma_rlc_registers *m; | 456 | struct vi_sdma_mqd *m; |
394 | uint32_t sdma_base_addr; | 457 | uint32_t sdma_base_addr; |
395 | uint32_t sdma_rlc_rb_cntl; | 458 | uint32_t sdma_rlc_rb_cntl; |
396 | 459 | ||
@@ -511,7 +574,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, | |||
511 | unsigned int utimeout) | 574 | unsigned int utimeout) |
512 | { | 575 | { |
513 | struct amdgpu_device *adev = get_amdgpu_device(kgd); | 576 | struct amdgpu_device *adev = get_amdgpu_device(kgd); |
514 | struct cik_sdma_rlc_registers *m; | 577 | struct vi_sdma_mqd *m; |
515 | uint32_t sdma_base_addr; | 578 | uint32_t sdma_base_addr; |
516 | uint32_t temp; | 579 | uint32_t temp; |
517 | unsigned long end_jiffies = (utimeout * HZ / 1000) + jiffies; | 580 | unsigned long end_jiffies = (utimeout * HZ / 1000) + jiffies; |
@@ -525,7 +588,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, | |||
525 | 588 | ||
526 | while (true) { | 589 | while (true) { |
527 | temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS); | 590 | temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS); |
528 | if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT) | 591 | if (temp & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK) |
529 | break; | 592 | break; |
530 | if (time_after(jiffies, end_jiffies)) | 593 | if (time_after(jiffies, end_jiffies)) |
531 | return -ETIME; | 594 | return -ETIME; |
@@ -533,9 +596,11 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, | |||
533 | } | 596 | } |
534 | 597 | ||
535 | WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0); | 598 | WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0); |
536 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0); | 599 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, |
537 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0); | 600 | RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) | |
538 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, 0); | 601 | SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK); |
602 | |||
603 | m->sdmax_rlcx_rb_rptr = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR); | ||
539 | 604 | ||
540 | return 0; | 605 | return 0; |
541 | } | 606 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/vid.h b/drivers/gpu/drm/amd/amdgpu/vid.h index dbf3703cbd1b..19ddd2312e00 100644 --- a/drivers/gpu/drm/amd/amdgpu/vid.h +++ b/drivers/gpu/drm/amd/amdgpu/vid.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #define SDMA1_REGISTER_OFFSET 0x200 /* not a register */ | 27 | #define SDMA1_REGISTER_OFFSET 0x200 /* not a register */ |
28 | #define SDMA_MAX_INSTANCE 2 | 28 | #define SDMA_MAX_INSTANCE 2 |
29 | 29 | ||
30 | #define KFD_VI_SDMA_QUEUE_OFFSET 0x80 /* not a register */ | ||
31 | |||
30 | /* crtc instance offsets */ | 32 | /* crtc instance offsets */ |
31 | #define CRTC0_REGISTER_OFFSET (0x1b9c - 0x1b9c) | 33 | #define CRTC0_REGISTER_OFFSET (0x1b9c - 0x1b9c) |
32 | #define CRTC1_REGISTER_OFFSET (0x1d9c - 0x1b9c) | 34 | #define CRTC1_REGISTER_OFFSET (0x1d9c - 0x1b9c) |
diff --git a/drivers/gpu/drm/amd/include/vi_structs.h b/drivers/gpu/drm/amd/include/vi_structs.h index 20234820194b..717fbae1d362 100644 --- a/drivers/gpu/drm/amd/include/vi_structs.h +++ b/drivers/gpu/drm/amd/include/vi_structs.h | |||
@@ -153,6 +153,8 @@ struct vi_sdma_mqd { | |||
153 | uint32_t reserved_125; | 153 | uint32_t reserved_125; |
154 | uint32_t reserved_126; | 154 | uint32_t reserved_126; |
155 | uint32_t reserved_127; | 155 | uint32_t reserved_127; |
156 | uint32_t sdma_engine_id; | ||
157 | uint32_t sdma_queue_id; | ||
156 | }; | 158 | }; |
157 | 159 | ||
158 | struct vi_mqd { | 160 | struct vi_mqd { |