forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
....@@ -1,14 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* Copyright (c) 2017 The Linux Foundation. All rights reserved.
2
- *
3
- * This program is free software; you can redistribute it and/or modify
4
- * it under the terms of the GNU General Public License version 2 and
5
- * only version 2 as published by the Free Software Foundation.
6
- *
7
- * This program is distributed in the hope that it will be useful,
8
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- * GNU General Public License for more details.
11
- *
123 */
134
145 #include "msm_gem.h"
....@@ -92,7 +83,7 @@
9283 if (!try_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED, PREEMPT_FAULTED))
9384 return;
9485
95
- dev_err(dev->dev, "%s: preemption timed out\n", gpu->name);
86
+ DRM_DEV_ERROR(dev->dev, "%s: preemption timed out\n", gpu->name);
9687 queue_work(priv->wq, &gpu->recover_work);
9788 }
9889
....@@ -188,7 +179,7 @@
188179 status = gpu_read(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL);
189180 if (unlikely(status)) {
190181 set_preempt_state(a5xx_gpu, PREEMPT_FAULTED);
191
- dev_err(dev->dev, "%s: Preemption failed to complete\n",
182
+ DRM_DEV_ERROR(dev->dev, "%s: Preemption failed to complete\n",
192183 gpu->name);
193184 queue_work(priv->wq, &gpu->recover_work);
194185 return;
....@@ -208,6 +199,13 @@
208199 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
209200 int i;
210201
202
+ /* Always come up on rb 0 */
203
+ a5xx_gpu->cur_ring = gpu->rb[0];
204
+
205
+ /* No preemption if we only have one ring */
206
+ if (gpu->nr_rings == 1)
207
+ return;
208
+
211209 for (i = 0; i < gpu->nr_rings; i++) {
212210 a5xx_gpu->preempt[i]->wptr = 0;
213211 a5xx_gpu->preempt[i]->rptr = 0;
....@@ -220,9 +218,6 @@
220218
221219 /* Reset the preemption state */
222220 set_preempt_state(a5xx_gpu, PREEMPT_NONE);
223
-
224
- /* Always come up on rb 0 */
225
- a5xx_gpu->cur_ring = gpu->rb[0];
226221 }
227222
228223 static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,
....@@ -231,17 +226,31 @@
231226 struct adreno_gpu *adreno_gpu = &a5xx_gpu->base;
232227 struct msm_gpu *gpu = &adreno_gpu->base;
233228 struct a5xx_preempt_record *ptr;
234
- struct drm_gem_object *bo = NULL;
235
- u64 iova = 0;
229
+ void *counters;
230
+ struct drm_gem_object *bo = NULL, *counters_bo = NULL;
231
+ u64 iova = 0, counters_iova = 0;
236232
237233 ptr = msm_gem_kernel_new(gpu->dev,
238234 A5XX_PREEMPT_RECORD_SIZE + A5XX_PREEMPT_COUNTER_SIZE,
239
- MSM_BO_UNCACHED, gpu->aspace, &bo, &iova);
235
+ MSM_BO_UNCACHED | MSM_BO_MAP_PRIV, gpu->aspace, &bo, &iova);
240236
241237 if (IS_ERR(ptr))
242238 return PTR_ERR(ptr);
243239
240
+ /* The buffer to store counters needs to be unprivileged */
241
+ counters = msm_gem_kernel_new(gpu->dev,
242
+ A5XX_PREEMPT_COUNTER_SIZE,
243
+ MSM_BO_UNCACHED, gpu->aspace, &counters_bo, &counters_iova);
244
+ if (IS_ERR(counters)) {
245
+ msm_gem_kernel_put(bo, gpu->aspace, true);
246
+ return PTR_ERR(counters);
247
+ }
248
+
249
+ msm_gem_object_set_name(bo, "preempt");
250
+ msm_gem_object_set_name(counters_bo, "preempt_counters");
251
+
244252 a5xx_gpu->preempt_bo[ring->id] = bo;
253
+ a5xx_gpu->preempt_counters_bo[ring->id] = counters_bo;
245254 a5xx_gpu->preempt_iova[ring->id] = iova;
246255 a5xx_gpu->preempt[ring->id] = ptr;
247256
....@@ -250,9 +259,10 @@
250259 ptr->magic = A5XX_PREEMPT_RECORD_MAGIC;
251260 ptr->info = 0;
252261 ptr->data = 0;
253
- ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT;
254
- ptr->rptr_addr = rbmemptr(ring, rptr);
255
- ptr->counter = iova + A5XX_PREEMPT_RECORD_SIZE;
262
+ ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE;
263
+
264
+ ptr->rptr_addr = shadowptr(a5xx_gpu, ring);
265
+ ptr->counter = counters_iova;
256266
257267 return 0;
258268 }
....@@ -264,16 +274,9 @@
264274 int i;
265275
266276 for (i = 0; i < gpu->nr_rings; i++) {
267
- if (!a5xx_gpu->preempt_bo[i])
268
- continue;
269
-
270
- msm_gem_put_vaddr(a5xx_gpu->preempt_bo[i]);
271
-
272
- if (a5xx_gpu->preempt_iova[i])
273
- msm_gem_put_iova(a5xx_gpu->preempt_bo[i], gpu->aspace);
274
-
275
- drm_gem_object_unreference(a5xx_gpu->preempt_bo[i]);
276
- a5xx_gpu->preempt_bo[i] = NULL;
277
+ msm_gem_kernel_put(a5xx_gpu->preempt_bo[i], gpu->aspace, true);
278
+ msm_gem_kernel_put(a5xx_gpu->preempt_counters_bo[i],
279
+ gpu->aspace, true);
277280 }
278281 }
279282