]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/gpu/drm/msm/adreno/adreno_gpu.c
drm/msm: Support multiple ringbuffers
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / msm / adreno / adreno_gpu.c
CommitLineData
7198e6b0
RC
1/*
2 * Copyright (C) 2013 Red Hat
3 * Author: Rob Clark <robdclark@gmail.com>
4 *
91b74e97
AG
5 * Copyright (c) 2014 The Linux Foundation. All rights reserved.
6 *
7198e6b0
RC
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "adreno_gpu.h"
21#include "msm_gem.h"
871d812a 22#include "msm_mmu.h"
7198e6b0 23
b5f103ab 24#define RB_BLKSIZE 32
7198e6b0
RC
25
26int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
27{
28 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
29
30 switch (param) {
31 case MSM_PARAM_GPU_ID:
32 *value = adreno_gpu->info->revn;
33 return 0;
34 case MSM_PARAM_GMEM_SIZE:
55459968 35 *value = adreno_gpu->gmem;
7198e6b0 36 return 0;
e3689e47
JC
37 case MSM_PARAM_GMEM_BASE:
38 *value = 0x100000;
39 return 0;
4e1cbaa3
RC
40 case MSM_PARAM_CHIP_ID:
41 *value = adreno_gpu->rev.patchid |
42 (adreno_gpu->rev.minor << 8) |
43 (adreno_gpu->rev.major << 16) |
44 (adreno_gpu->rev.core << 24);
45 return 0;
4102a9e5
RC
46 case MSM_PARAM_MAX_FREQ:
47 *value = adreno_gpu->base.fast_rate;
48 return 0;
6c77d1ab 49 case MSM_PARAM_TIMESTAMP:
541de4c9
AT
50 if (adreno_gpu->funcs->get_timestamp) {
51 int ret;
52
53 pm_runtime_get_sync(&gpu->pdev->dev);
54 ret = adreno_gpu->funcs->get_timestamp(gpu, value);
55 pm_runtime_put_autosuspend(&gpu->pdev->dev);
56
57 return ret;
58 }
6c77d1ab 59 return -EINVAL;
7198e6b0
RC
60 default:
61 DBG("%s: invalid param: %u", gpu->name, param);
62 return -EINVAL;
63 }
64}
65
e8f3de96
RC
66const struct firmware *
67adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
eec874ce
RC
68{
69 struct drm_device *drm = adreno_gpu->base.dev;
e8f3de96 70 const struct firmware *fw = NULL;
2c41ef1b 71 char newname[strlen("qcom/") + strlen(fwname) + 1];
eec874ce
RC
72 int ret;
73
2c41ef1b
RC
74 sprintf(newname, "qcom/%s", fwname);
75
76 /*
77 * Try first to load from qcom/$fwfile using a direct load (to avoid
78 * a potential timeout waiting for usermode helper)
79 */
80 if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
81 (adreno_gpu->fwloc == FW_LOCATION_NEW)) {
82
83 ret = request_firmware_direct(&fw, newname, drm->dev);
84 if (!ret) {
85 dev_info(drm->dev, "loaded %s from new location\n",
86 newname);
87 adreno_gpu->fwloc = FW_LOCATION_NEW;
88 return fw;
89 } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
90 dev_err(drm->dev, "failed to load %s: %d\n",
91 newname, ret);
92 return ERR_PTR(ret);
93 }
94 }
95
96 /*
97 * Then try the legacy location without qcom/ prefix
98 */
99 if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
100 (adreno_gpu->fwloc == FW_LOCATION_LEGACY)) {
101
102 ret = request_firmware_direct(&fw, fwname, drm->dev);
103 if (!ret) {
104 dev_info(drm->dev, "loaded %s from legacy location\n",
105 newname);
106 adreno_gpu->fwloc = FW_LOCATION_LEGACY;
107 return fw;
108 } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
109 dev_err(drm->dev, "failed to load %s: %d\n",
110 fwname, ret);
111 return ERR_PTR(ret);
112 }
113 }
114
115 /*
116 * Finally fall back to request_firmware() for cases where the
117 * usermode helper is needed (I think mainly android)
118 */
119 if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
120 (adreno_gpu->fwloc == FW_LOCATION_HELPER)) {
121
122 ret = request_firmware(&fw, newname, drm->dev);
123 if (!ret) {
124 dev_info(drm->dev, "loaded %s with helper\n",
125 newname);
126 adreno_gpu->fwloc = FW_LOCATION_HELPER;
127 return fw;
128 } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
129 dev_err(drm->dev, "failed to load %s: %d\n",
130 newname, ret);
131 return ERR_PTR(ret);
132 }
e8f3de96
RC
133 }
134
2c41ef1b
RC
135 dev_err(drm->dev, "failed to load %s\n", fwname);
136 return ERR_PTR(-ENOENT);
e8f3de96
RC
137}
138
139static int adreno_load_fw(struct adreno_gpu *adreno_gpu)
140{
141 const struct firmware *fw;
142
eec874ce
RC
143 if (adreno_gpu->pm4)
144 return 0;
145
e8f3de96
RC
146 fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw);
147 if (IS_ERR(fw))
148 return PTR_ERR(fw);
149 adreno_gpu->pm4 = fw;
eec874ce 150
e8f3de96
RC
151 fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw);
152 if (IS_ERR(fw)) {
eec874ce
RC
153 release_firmware(adreno_gpu->pm4);
154 adreno_gpu->pm4 = NULL;
e8f3de96 155 return PTR_ERR(fw);
eec874ce 156 }
e8f3de96 157 adreno_gpu->pfp = fw;
eec874ce
RC
158
159 return 0;
160}
161
7198e6b0
RC
162int adreno_hw_init(struct msm_gpu *gpu)
163{
164 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
f97decac 165 int ret, i;
7198e6b0
RC
166
167 DBG("%s", gpu->name);
168
eec874ce
RC
169 ret = adreno_load_fw(adreno_gpu);
170 if (ret)
171 return ret;
172
f97decac
JC
173 for (i = 0; i < gpu->nr_rings; i++) {
174 struct msm_ringbuffer *ring = gpu->rb[i];
944fc36c 175
f97decac
JC
176 if (!ring)
177 continue;
de098e5f 178
f97decac
JC
179 ret = msm_gem_get_iova(ring->bo, gpu->aspace, &ring->iova);
180 if (ret) {
181 ring->iova = 0;
182 dev_err(gpu->dev->dev,
183 "could not map ringbuffer %d: %d\n", i, ret);
184 return ret;
185 }
186
187 ring->cur = ring->start;
188
189 /* reset completed fence seqno: */
190 ring->memptrs->fence = ring->seqno;
191 ring->memptrs->rptr = 0;
192 }
de098e5f 193
7198e6b0 194 /* Setup REG_CP_RB_CNTL: */
91b74e97 195 adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL,
f97decac
JC
196 /* size is log2(quad-words): */
197 AXXX_CP_RB_CNTL_BUFSZ(ilog2(MSM_GPU_RINGBUFFER_SZ / 8)) |
198 AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8)) |
199 (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0));
7198e6b0 200
f97decac 201 /* Setup ringbuffer address - use ringbuffer[0] for GPU init */
fb039981 202 adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_BASE,
f97decac 203 REG_ADRENO_CP_RB_BASE_HI, gpu->rb[0]->iova);
7198e6b0 204
fb039981
JC
205 if (!adreno_is_a430(adreno_gpu)) {
206 adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR,
f97decac
JC
207 REG_ADRENO_CP_RB_RPTR_ADDR_HI,
208 rbmemptr(gpu->rb[0], rptr));
fb039981 209 }
7198e6b0
RC
210
211 return 0;
212}
213
214static uint32_t get_wptr(struct msm_ringbuffer *ring)
215{
216 return ring->cur - ring->start;
217}
218
7d0c5ee9 219/* Use this helper to read rptr, since a430 doesn't update rptr in memory */
f97decac
JC
220static uint32_t get_rptr(struct adreno_gpu *adreno_gpu,
221 struct msm_ringbuffer *ring)
7d0c5ee9
CS
222{
223 if (adreno_is_a430(adreno_gpu))
f97decac 224 return ring->memptrs->rptr = adreno_gpu_read(
7d0c5ee9
CS
225 adreno_gpu, REG_ADRENO_CP_RB_RPTR);
226 else
f97decac
JC
227 return ring->memptrs->rptr;
228}
229
230struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu)
231{
232 return gpu->rb[0];
7198e6b0
RC
233}
234
bd6f82d8
RC
235void adreno_recover(struct msm_gpu *gpu)
236{
bd6f82d8
RC
237 struct drm_device *dev = gpu->dev;
238 int ret;
239
eeb75474
RC
240 // XXX pm-runtime?? we *need* the device to be off after this
241 // so maybe continuing to call ->pm_suspend/resume() is better?
242
bd6f82d8 243 gpu->funcs->pm_suspend(gpu);
bd6f82d8 244 gpu->funcs->pm_resume(gpu);
4ac277cd 245
eeb75474 246 ret = msm_gpu_hw_init(gpu);
bd6f82d8
RC
247 if (ret) {
248 dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
249 /* hmm, oh well? */
250 }
251}
252
1193c3bc 253void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
7198e6b0
RC
254 struct msm_file_private *ctx)
255{
256 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
257 struct msm_drm_private *priv = gpu->dev->dev_private;
f97decac 258 struct msm_ringbuffer *ring = submit->ring;
6b597ce2 259 unsigned i;
7198e6b0 260
7198e6b0
RC
261 for (i = 0; i < submit->nr_cmds; i++) {
262 switch (submit->cmd[i].type) {
263 case MSM_SUBMIT_CMD_IB_TARGET_BUF:
264 /* ignore IB-targets */
265 break;
266 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
267 /* ignore if there has not been a ctx switch: */
268 if (priv->lastctx == ctx)
269 break;
270 case MSM_SUBMIT_CMD_BUF:
357ff00b
CS
271 OUT_PKT3(ring, adreno_is_a430(adreno_gpu) ?
272 CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2);
7198e6b0
RC
273 OUT_RING(ring, submit->cmd[i].iova);
274 OUT_RING(ring, submit->cmd[i].size);
6b597ce2 275 OUT_PKT2(ring);
7198e6b0
RC
276 break;
277 }
278 }
279
7198e6b0 280 OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1);
f97decac 281 OUT_RING(ring, submit->seqno);
7198e6b0 282
23bd62fd 283 if (adreno_is_a3xx(adreno_gpu) || adreno_is_a4xx(adreno_gpu)) {
7198e6b0
RC
284 /* Flush HLSQ lazy updates to make sure there is nothing
285 * pending for indirect loads after the timestamp has
286 * passed:
287 */
288 OUT_PKT3(ring, CP_EVENT_WRITE, 1);
289 OUT_RING(ring, HLSQ_FLUSH);
290
291 OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
292 OUT_RING(ring, 0x00000000);
293 }
294
295 OUT_PKT3(ring, CP_EVENT_WRITE, 3);
296 OUT_RING(ring, CACHE_FLUSH_TS);
f97decac
JC
297 OUT_RING(ring, rbmemptr(ring, fence));
298 OUT_RING(ring, submit->seqno);
7198e6b0
RC
299
300 /* we could maybe be clever and only CP_COND_EXEC the interrupt: */
301 OUT_PKT3(ring, CP_INTERRUPT, 1);
302 OUT_RING(ring, 0x80000000);
303
d735fdc3
RC
304 /* Workaround for missing irq issue on 8x16/a306. Unsure if the
305 * root cause is a platform issue or some a306 quirk, but this
306 * keeps things humming along:
307 */
308 if (adreno_is_a306(adreno_gpu)) {
309 OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
310 OUT_RING(ring, 0x00000000);
311 OUT_PKT3(ring, CP_INTERRUPT, 1);
312 OUT_RING(ring, 0x80000000);
313 }
314
7198e6b0
RC
315#if 0
316 if (adreno_is_a3xx(adreno_gpu)) {
317 /* Dummy set-constant to trigger context rollover */
318 OUT_PKT3(ring, CP_SET_CONSTANT, 2);
319 OUT_RING(ring, CP_REG(REG_A3XX_HLSQ_CL_KERNEL_GROUP_X_REG));
320 OUT_RING(ring, 0x00000000);
321 }
322#endif
323
f97decac 324 gpu->funcs->flush(gpu, ring);
7198e6b0
RC
325}
326
f97decac 327void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
7198e6b0 328{
91b74e97 329 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
88b333b0
JC
330 uint32_t wptr;
331
332 /*
333 * Mask wptr value that we calculate to fit in the HW range. This is
334 * to account for the possibility that the last command fit exactly into
335 * the ringbuffer and rb->next hasn't wrapped to zero yet
336 */
f97decac 337 wptr = get_wptr(ring) % (MSM_GPU_RINGBUFFER_SZ >> 2);
7198e6b0
RC
338
339 /* ensure writes to ringbuffer have hit system memory: */
340 mb();
341
91b74e97 342 adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_WPTR, wptr);
7198e6b0
RC
343}
344
f97decac 345bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
7198e6b0
RC
346{
347 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
f97decac 348 uint32_t wptr = get_wptr(ring);
7198e6b0 349
0963756f 350 /* wait for CP to drain ringbuffer: */
f97decac 351 if (!spin_until(get_rptr(adreno_gpu, ring) == wptr))
c4a8d475 352 return true;
7198e6b0
RC
353
354 /* TODO maybe we need to reset GPU here to recover from hang? */
f97decac
JC
355 DRM_ERROR("%s: timeout waiting to drain ringbuffer %d!\n", gpu->name,
356 ring->id);
c4a8d475 357 return false;
7198e6b0
RC
358}
359
360#ifdef CONFIG_DEBUG_FS
361void adreno_show(struct msm_gpu *gpu, struct seq_file *m)
362{
363 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
3bcefb04 364 int i;
7198e6b0
RC
365
366 seq_printf(m, "revision: %d (%d.%d.%d.%d)\n",
367 adreno_gpu->info->revn, adreno_gpu->rev.core,
368 adreno_gpu->rev.major, adreno_gpu->rev.minor,
369 adreno_gpu->rev.patchid);
370
f97decac
JC
371 for (i = 0; i < gpu->nr_rings; i++) {
372 struct msm_ringbuffer *ring = gpu->rb[i];
373
374 seq_printf(m, "rb %d: fence: %d/%d\n", i,
375 ring->memptrs->fence, ring->seqno);
376
377 seq_printf(m, " rptr: %d\n",
378 get_rptr(adreno_gpu, ring));
379 seq_printf(m, "rb wptr: %d\n", get_wptr(ring));
380 }
3bcefb04 381
3bcefb04
RC
382 /* dump these out in a form that can be parsed by demsm: */
383 seq_printf(m, "IO:region %s 00000000 00020000\n", gpu->name);
384 for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
385 uint32_t start = adreno_gpu->registers[i];
386 uint32_t end = adreno_gpu->registers[i+1];
387 uint32_t addr;
388
389 for (addr = start; addr <= end; addr++) {
390 uint32_t val = gpu_read(gpu, addr);
391 seq_printf(m, "IO:R %08x %08x\n", addr<<2, val);
392 }
393 }
7198e6b0
RC
394}
395#endif
396
26716185
RC
397/* Dump common gpu status and scratch registers on any hang, to make
398 * the hangcheck logs more useful. The scratch registers seem always
399 * safe to read when GPU has hung (unlike some other regs, depending
400 * on how the GPU hung), and they are useful to match up to cmdstream
401 * dumps when debugging hangs:
402 */
403void adreno_dump_info(struct msm_gpu *gpu)
5b6ef08e
RC
404{
405 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
f97decac 406 int i;
5b6ef08e
RC
407
408 printk("revision: %d (%d.%d.%d.%d)\n",
409 adreno_gpu->info->revn, adreno_gpu->rev.core,
410 adreno_gpu->rev.major, adreno_gpu->rev.minor,
411 adreno_gpu->rev.patchid);
412
f97decac
JC
413 for (i = 0; i < gpu->nr_rings; i++) {
414 struct msm_ringbuffer *ring = gpu->rb[i];
415
416 printk("rb %d: fence: %d/%d\n", i,
417 ring->memptrs->fence,
418 ring->seqno);
419
420 printk("rptr: %d\n", get_rptr(adreno_gpu, ring));
421 printk("rb wptr: %d\n", get_wptr(ring));
422 }
26716185
RC
423}
424
425/* would be nice to not have to duplicate the _show() stuff with printk(): */
426void adreno_dump(struct msm_gpu *gpu)
427{
428 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
429 int i;
430
3bcefb04
RC
431 /* dump these out in a form that can be parsed by demsm: */
432 printk("IO:region %s 00000000 00020000\n", gpu->name);
433 for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
434 uint32_t start = adreno_gpu->registers[i];
435 uint32_t end = adreno_gpu->registers[i+1];
436 uint32_t addr;
437
438 for (addr = start; addr <= end; addr++) {
439 uint32_t val = gpu_read(gpu, addr);
440 printk("IO:R %08x %08x\n", addr<<2, val);
441 }
442 }
5b6ef08e
RC
443}
444
f97decac 445static uint32_t ring_freewords(struct msm_ringbuffer *ring)
7198e6b0 446{
f97decac
JC
447 struct adreno_gpu *adreno_gpu = to_adreno_gpu(ring->gpu);
448 uint32_t size = MSM_GPU_RINGBUFFER_SZ >> 2;
449 uint32_t wptr = get_wptr(ring);
450 uint32_t rptr = get_rptr(adreno_gpu, ring);
0963756f
RC
451 return (rptr + (size - 1) - wptr) % size;
452}
453
f97decac 454void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords)
0963756f 455{
f97decac
JC
456 if (spin_until(ring_freewords(ring) >= ndwords))
457 DRM_DEV_ERROR(ring->gpu->dev->dev,
458 "timeout waiting for space in ringubffer %d\n",
459 ring->id);
7198e6b0
RC
460}
461
7198e6b0 462int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
f97decac
JC
463 struct adreno_gpu *adreno_gpu,
464 const struct adreno_gpu_funcs *funcs, int nr_rings)
7198e6b0 465{
3526e9fb 466 struct adreno_platform_config *config = pdev->dev.platform_data;
5770fc7a 467 struct msm_gpu_config adreno_gpu_config = { 0 };
3526e9fb 468 struct msm_gpu *gpu = &adreno_gpu->base;
7198e6b0 469
3526e9fb
RC
470 adreno_gpu->funcs = funcs;
471 adreno_gpu->info = adreno_info(config->rev);
472 adreno_gpu->gmem = adreno_gpu->info->gmem;
473 adreno_gpu->revn = adreno_gpu->info->revn;
474 adreno_gpu->rev = config->rev;
475
476 gpu->fast_rate = config->fast_rate;
3526e9fb 477 gpu->bus_freq = config->bus_freq;
6490ad47 478#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
3526e9fb
RC
479 gpu->bus_scale_table = config->bus_scale_table;
480#endif
481
bf5af4ae
JC
482 DBG("fast_rate=%u, slow_rate=27000000, bus_freq=%u",
483 gpu->fast_rate, gpu->bus_freq);
7198e6b0 484
5770fc7a
JC
485 adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
486 adreno_gpu_config.irqname = "kgsl_3d0_irq";
487
488 adreno_gpu_config.va_start = SZ_16M;
489 adreno_gpu_config.va_end = 0xffffffff;
490
f97decac 491 adreno_gpu_config.nr_rings = nr_rings;
5770fc7a 492
1267a4df
JC
493 pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD);
494 pm_runtime_use_autosuspend(&pdev->dev);
495 pm_runtime_enable(&pdev->dev);
496
cd414f3d 497 return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
5770fc7a 498 adreno_gpu->info->name, &adreno_gpu_config);
7198e6b0
RC
499}
500
9873ef07 501void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
7198e6b0 502{
9873ef07
JC
503 release_firmware(adreno_gpu->pm4);
504 release_firmware(adreno_gpu->pfp);
18f23049 505
cd414f3d 506 msm_gpu_cleanup(&adreno_gpu->base);
7198e6b0 507}