aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/1453-drm-amdgpu-Fix-SDMA-RLC-queues-on-Hawaii.patch
blob: 75107ae530fb4fc04dd0c59c686d2c38a87dc964 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
From 140eca45c531ecd0787eca20a45dc5259633423e Mon Sep 17 00:00:00 2001
From: Felix Kuehling <Felix.Kuehling@amd.com>
Date: Wed, 15 Jun 2016 16:33:15 -0400
Subject: [PATCH 1453/4131] drm/amdgpu: Fix SDMA RLC queues on Hawaii

Enable SDMA context switching on CIK (copied from sdma_v3_0.c).
Fix programming sequence for queueing and dequeueing RLC queues
(copied from gfx_v8).

Change-Id: I97d0298ad91144ad7a683cd1c57470d359893dac
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>

 Conflicts:
	drivers/gpu/drm/amd/amdgpu/cik_sdma.c
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 37 ++++++++++++++++++++---
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index d48a859..b643f1d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -447,16 +447,44 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd)
 	struct cik_sdma_rlc_registers *m;
 	unsigned long end_jiffies;
 	uint32_t sdma_base_addr;
+        uint32_t temp, timeout = 2000;
+        uint32_t data;
 
 	m = get_sdma_mqd(mqd);
 	sdma_base_addr = get_sdma_base_addr(m);
 
+        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
+                m->sdma_rlc_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK));
+
+        while (true) {
+                temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
+                if (temp & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
+                        break;
+                if (timeout == 0)
+                        return -ETIME;
+               msleep(10);
+                timeout -= 10;
+        }
+        if (m->sdma_engine_id) {
+                data = RREG32(mmSDMA1_GFX_CONTEXT_CNTL);
+                data = REG_SET_FIELD(data, SDMA1_GFX_CONTEXT_CNTL,
+                                RESUME_CTX, 0);
+                WREG32(mmSDMA1_GFX_CONTEXT_CNTL, data);
+        } else {
+                data = RREG32(mmSDMA0_GFX_CONTEXT_CNTL);
+                data = REG_SET_FIELD(data, SDMA0_GFX_CONTEXT_CNTL,
+                                RESUME_CTX, 0);
+                WREG32(mmSDMA0_GFX_CONTEXT_CNTL, data);
+        }
+ 
+        WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, m->sdma_rlc_doorbell);
+        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
+        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
         WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR, m->sdma_rlc_virtual_addr);
         WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdma_rlc_rb_base);
         WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI, m->sdma_rlc_rb_base_hi);
         WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO, m->sdma_rlc_rb_rptr_addr_lo);
         WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI, m->sdma_rlc_rb_rptr_addr_hi);
-        WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, m->sdma_rlc_doorbell);
         WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, m->sdma_rlc_rb_cntl);
 
         return 0;
@@ -598,10 +626,9 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
 	}
 
 	WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0);
-        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
-        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
-        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, 0);
-
+        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
+                RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) |
+                SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK);
 	return 0;
 }
 
-- 
2.7.4