aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Cox <Philip.Cox@amd.com>2017-11-01 19:22:00 -0400
committerOded Gabbay <oded.gabbay@gmail.com>2017-11-01 19:22:00 -0400
commit9807c3668500b0964e8ee59d68083675971bc224 (patch)
treef35a7543dcf261c758f98b05bff8be781e399b49
parentfd0f0762dc590736a6692707860af3ce793f5028 (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.c87
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vid.h2
-rw-r--r--drivers/gpu/drm/amd/include/vi_structs.h2
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
48struct cik_sdma_rlc_registers; 48struct 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
272static inline uint32_t get_sdma_base_addr(struct cik_sdma_rlc_registers *m) 272static 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
277static inline struct vi_mqd *get_mqd(void *mqd) 283static 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
282static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd) 288static 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
287static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, 293static 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,
362static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, 368static 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,
390static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) 453static 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
158struct vi_mqd { 160struct vi_mqd {