aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/2245-drm-amdgpu-partially-revert-1cfd8e237f0318e330190ac2.patch
blob: ec26fb128480a230b7db9181e30cd83b07327693 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
From 18b0d4e821efc5dbe66e4ef8ab7686cefa611453 Mon Sep 17 00:00:00 2001
From: Monk Liu <Monk.Liu@amd.com>
Date: Tue, 21 Nov 2017 13:29:14 +0800
Subject: [PATCH 2245/4131] drm/amdgpu:partially revert
 1cfd8e237f0318e330190ac21d63c58ae6a1f66c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

found RING0 test fail after S3 resume regression, which is
introduced by 1cfd8e237f0318e330190ac21d63c58ae6a1f66c

Because after suspend VRAM will be cleared, so driver must
unpin the GART table(resident in VRAM) during suspend so it
can be evicted to system ram and must correspondingly pin it
during resume so the GART table could be restored to VRAM.

Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 79 +++++++++++++++++++++++++++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h |  2 +
 drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c    |  7 ++-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c    |  7 ++-
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c    |  7 ++-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c    |  4 ++
 6 files changed, 94 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index 707f858..1f51897 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -68,9 +68,75 @@
  */
 int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
 {
-	return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE,
-					AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.robj,
-					&adev->gart.table_addr, &adev->gart.ptr);
+	int r;
+
+	if (adev->gart.robj == NULL) {
+		r = amdgpu_bo_create(adev, adev->gart.table_size,
+				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
+				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+				     AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
+				     NULL, NULL, 0, &adev->gart.robj);
+		if (r) {
+			return r;
+		}
+	}
+	return 0;
+}
+
+/**
+ * amdgpu_gart_table_vram_pin - pin gart page table in vram
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Pin the GART page table in vram so it will not be moved
+ * by the memory manager (pcie r4xx, r5xx+).  These asics require the
+ * gart table to be in video memory.
+ * Returns 0 for success, error for failure.
+ */
+int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev)
+{
+	uint64_t gpu_addr;
+	int r;
+
+	r = amdgpu_bo_reserve(adev->gart.robj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = amdgpu_bo_pin(adev->gart.robj,
+				AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr);
+	if (r) {
+		amdgpu_bo_unreserve(adev->gart.robj);
+		return r;
+	}
+	r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr);
+	if (r)
+		amdgpu_bo_unpin(adev->gart.robj);
+	amdgpu_bo_unreserve(adev->gart.robj);
+	adev->gart.table_addr = gpu_addr;
+	return r;
+}
+
+/**
+ * amdgpu_gart_table_vram_unpin - unpin gart page table in vram
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Unpin the GART page table in vram (pcie r4xx, r5xx+).
+ * These asics require the gart table to be in video memory.
+ */
+void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev)
+{
+	int r;
+
+	if (adev->gart.robj == NULL) {
+		return;
+	}
+	r = amdgpu_bo_reserve(adev->gart.robj, true);
+	if (likely(r == 0)) {
+		amdgpu_bo_kunmap(adev->gart.robj);
+		amdgpu_bo_unpin(adev->gart.robj);
+		amdgpu_bo_unreserve(adev->gart.robj);
+		adev->gart.ptr = NULL;
+	}
 }
 
 /**
@@ -84,9 +150,10 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
  */
 void amdgpu_gart_table_vram_free(struct amdgpu_device *adev)
 {
-	amdgpu_bo_free_kernel(&adev->gart.robj,
-				&adev->gart.table_addr,
-				&adev->gart.ptr);
+	if (adev->gart.robj == NULL) {
+		return;
+	}
+	amdgpu_bo_unref(&adev->gart.robj);
 }
 
 /*
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
index 5eb1a680..d4a4330 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
@@ -58,6 +58,8 @@ struct amdgpu_gart {
 
 int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
 void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
+int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
+void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
 int amdgpu_gart_init(struct amdgpu_device *adev);
 void amdgpu_gart_fini(struct amdgpu_device *adev);
 int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
index b87b30d..3d4adc4 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
@@ -472,14 +472,16 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
 
 static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
 {
-	int i;
+	int r, i;
 	u32 field;
 
 	if (adev->gart.robj == NULL) {
 		dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
 		return -EINVAL;
 	}
-
+	r = amdgpu_gart_table_vram_pin(adev);
+	if (r)
+		return r;
 	/* Setup TLB control */
 	WREG32(mmMC_VM_MX_L1_TLB_CNTL,
 	       (0xA << 7) |
@@ -606,6 +608,7 @@ static void gmc_v6_0_gart_disable(struct amdgpu_device *adev)
 	WREG32(mmVM_L2_CNTL3,
 	       VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK |
 	       (0UL << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT));
+	amdgpu_gart_table_vram_unpin(adev);
 }
 
 static void gmc_v6_0_gart_fini(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 23d7c12..0b6f387 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -576,14 +576,16 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
  */
 static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
 {
-	int i;
+	int r, i;
 	u32 tmp, field;
 
 	if (adev->gart.robj == NULL) {
 		dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
 		return -EINVAL;
 	}
-
+	r = amdgpu_gart_table_vram_pin(adev);
+	if (r)
+		return r;
 	/* Setup TLB control */
 	tmp = RREG32(mmMC_VM_MX_L1_TLB_CNTL);
 	tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
@@ -716,6 +718,7 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev)
 	tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
 	WREG32(mmVM_L2_CNTL, tmp);
 	WREG32(mmVM_L2_CNTL2, 0);
+	amdgpu_gart_table_vram_unpin(adev);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index b77778f..21e81aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -779,14 +779,16 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
  */
 static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
 {
-	int i;
+	int r, i;
 	u32 tmp, field;
 
 	if (adev->gart.robj == NULL) {
 		dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
 		return -EINVAL;
 	}
-
+	r = amdgpu_gart_table_vram_pin(adev);
+	if (r)
+		return r;
 	/* Setup TLB control */
 	tmp = RREG32(mmMC_VM_MX_L1_TLB_CNTL);
 	tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
@@ -936,6 +938,7 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev)
 	tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
 	WREG32(mmVM_L2_CNTL, tmp);
 	WREG32(mmVM_L2_CNTL2, 0);
+	amdgpu_gart_table_vram_unpin(adev);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index fd2d793..085288f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -930,6 +930,9 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
 		dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
 		return -EINVAL;
 	}
+	r = amdgpu_gart_table_vram_pin(adev);
+	if (r)
+		return r;
 
 	switch (adev->asic_type) {
 	case CHIP_RAVEN:
@@ -1007,6 +1010,7 @@ static void gmc_v9_0_gart_disable(struct amdgpu_device *adev)
 {
 	gfxhub_v1_0_gart_disable(adev);
 	mmhub_v1_0_gart_disable(adev);
+	amdgpu_gart_table_vram_unpin(adev);
 }
 
 static int gmc_v9_0_hw_fini(void *handle)
-- 
2.7.4