]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/msm/adreno/adreno_gpu.c
drm/msm/adreno: split out helper to load fw
[linux.git] / drivers / gpu / drm / msm / adreno / adreno_gpu.c
1 /*
2  * Copyright (C) 2013 Red Hat
3  * Author: Rob Clark <robdclark@gmail.com>
4  *
5  * Copyright (c) 2014 The Linux Foundation. All rights reserved.
6  *
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"
22 #include "msm_mmu.h"
23
24 #define RB_SIZE    SZ_32K
25 #define RB_BLKSIZE 32
26
27 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
28 {
29         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
30
31         switch (param) {
32         case MSM_PARAM_GPU_ID:
33                 *value = adreno_gpu->info->revn;
34                 return 0;
35         case MSM_PARAM_GMEM_SIZE:
36                 *value = adreno_gpu->gmem;
37                 return 0;
38         case MSM_PARAM_GMEM_BASE:
39                 *value = 0x100000;
40                 return 0;
41         case MSM_PARAM_CHIP_ID:
42                 *value = adreno_gpu->rev.patchid |
43                                 (adreno_gpu->rev.minor << 8) |
44                                 (adreno_gpu->rev.major << 16) |
45                                 (adreno_gpu->rev.core << 24);
46                 return 0;
47         case MSM_PARAM_MAX_FREQ:
48                 *value = adreno_gpu->base.fast_rate;
49                 return 0;
50         case MSM_PARAM_TIMESTAMP:
51                 if (adreno_gpu->funcs->get_timestamp) {
52                         int ret;
53
54                         pm_runtime_get_sync(&gpu->pdev->dev);
55                         ret = adreno_gpu->funcs->get_timestamp(gpu, value);
56                         pm_runtime_put_autosuspend(&gpu->pdev->dev);
57
58                         return ret;
59                 }
60                 return -EINVAL;
61         default:
62                 DBG("%s: invalid param: %u", gpu->name, param);
63                 return -EINVAL;
64         }
65 }
66
67 const struct firmware *
68 adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
69 {
70         struct drm_device *drm = adreno_gpu->base.dev;
71         const struct firmware *fw = NULL;
72         int ret;
73
74         ret = request_firmware(&fw, fwname, drm->dev);
75         if (ret) {
76                 dev_err(drm->dev, "failed to load %s: %d\n", fwname, ret);
77                 return ERR_PTR(ret);
78         }
79
80         return fw;
81 }
82
83 static int adreno_load_fw(struct adreno_gpu *adreno_gpu)
84 {
85         const struct firmware *fw;
86
87         if (adreno_gpu->pm4)
88                 return 0;
89
90         fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw);
91         if (IS_ERR(fw))
92                 return PTR_ERR(fw);
93         adreno_gpu->pm4 = fw;
94
95         fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw);
96         if (IS_ERR(fw)) {
97                 release_firmware(adreno_gpu->pm4);
98                 adreno_gpu->pm4 = NULL;
99                 return PTR_ERR(fw);
100         }
101         adreno_gpu->pfp = fw;
102
103         return 0;
104 }
105
106 int adreno_hw_init(struct msm_gpu *gpu)
107 {
108         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
109         int ret;
110
111         DBG("%s", gpu->name);
112
113         ret = adreno_load_fw(adreno_gpu);
114         if (ret)
115                 return ret;
116
117         ret = msm_gem_get_iova(gpu->rb->bo, gpu->aspace, &gpu->rb_iova);
118         if (ret) {
119                 gpu->rb_iova = 0;
120                 dev_err(gpu->dev->dev, "could not map ringbuffer: %d\n", ret);
121                 return ret;
122         }
123
124         /* reset ringbuffer: */
125         gpu->rb->cur = gpu->rb->start;
126
127         /* reset completed fence seqno: */
128         adreno_gpu->memptrs->fence = gpu->fctx->completed_fence;
129         adreno_gpu->memptrs->rptr  = 0;
130
131         /* Setup REG_CP_RB_CNTL: */
132         adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL,
133                         /* size is log2(quad-words): */
134                         AXXX_CP_RB_CNTL_BUFSZ(ilog2(gpu->rb->size / 8)) |
135                         AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8)) |
136                         (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0));
137
138         /* Setup ringbuffer address: */
139         adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_BASE,
140                 REG_ADRENO_CP_RB_BASE_HI, gpu->rb_iova);
141
142         if (!adreno_is_a430(adreno_gpu)) {
143                 adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR,
144                         REG_ADRENO_CP_RB_RPTR_ADDR_HI,
145                         rbmemptr(adreno_gpu, rptr));
146         }
147
148         return 0;
149 }
150
151 static uint32_t get_wptr(struct msm_ringbuffer *ring)
152 {
153         return ring->cur - ring->start;
154 }
155
156 /* Use this helper to read rptr, since a430 doesn't update rptr in memory */
157 static uint32_t get_rptr(struct adreno_gpu *adreno_gpu)
158 {
159         if (adreno_is_a430(adreno_gpu))
160                 return adreno_gpu->memptrs->rptr = adreno_gpu_read(
161                         adreno_gpu, REG_ADRENO_CP_RB_RPTR);
162         else
163                 return adreno_gpu->memptrs->rptr;
164 }
165
166 uint32_t adreno_last_fence(struct msm_gpu *gpu)
167 {
168         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
169         return adreno_gpu->memptrs->fence;
170 }
171
172 void adreno_recover(struct msm_gpu *gpu)
173 {
174         struct drm_device *dev = gpu->dev;
175         int ret;
176
177         // XXX pm-runtime??  we *need* the device to be off after this
178         // so maybe continuing to call ->pm_suspend/resume() is better?
179
180         gpu->funcs->pm_suspend(gpu);
181         gpu->funcs->pm_resume(gpu);
182
183         ret = msm_gpu_hw_init(gpu);
184         if (ret) {
185                 dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
186                 /* hmm, oh well? */
187         }
188 }
189
190 void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
191                 struct msm_file_private *ctx)
192 {
193         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
194         struct msm_drm_private *priv = gpu->dev->dev_private;
195         struct msm_ringbuffer *ring = gpu->rb;
196         unsigned i;
197
198         for (i = 0; i < submit->nr_cmds; i++) {
199                 switch (submit->cmd[i].type) {
200                 case MSM_SUBMIT_CMD_IB_TARGET_BUF:
201                         /* ignore IB-targets */
202                         break;
203                 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
204                         /* ignore if there has not been a ctx switch: */
205                         if (priv->lastctx == ctx)
206                                 break;
207                 case MSM_SUBMIT_CMD_BUF:
208                         OUT_PKT3(ring, adreno_is_a430(adreno_gpu) ?
209                                 CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2);
210                         OUT_RING(ring, submit->cmd[i].iova);
211                         OUT_RING(ring, submit->cmd[i].size);
212                         OUT_PKT2(ring);
213                         break;
214                 }
215         }
216
217         OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1);
218         OUT_RING(ring, submit->fence->seqno);
219
220         if (adreno_is_a3xx(adreno_gpu) || adreno_is_a4xx(adreno_gpu)) {
221                 /* Flush HLSQ lazy updates to make sure there is nothing
222                  * pending for indirect loads after the timestamp has
223                  * passed:
224                  */
225                 OUT_PKT3(ring, CP_EVENT_WRITE, 1);
226                 OUT_RING(ring, HLSQ_FLUSH);
227
228                 OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
229                 OUT_RING(ring, 0x00000000);
230         }
231
232         OUT_PKT3(ring, CP_EVENT_WRITE, 3);
233         OUT_RING(ring, CACHE_FLUSH_TS);
234         OUT_RING(ring, rbmemptr(adreno_gpu, fence));
235         OUT_RING(ring, submit->fence->seqno);
236
237         /* we could maybe be clever and only CP_COND_EXEC the interrupt: */
238         OUT_PKT3(ring, CP_INTERRUPT, 1);
239         OUT_RING(ring, 0x80000000);
240
241         /* Workaround for missing irq issue on 8x16/a306.  Unsure if the
242          * root cause is a platform issue or some a306 quirk, but this
243          * keeps things humming along:
244          */
245         if (adreno_is_a306(adreno_gpu)) {
246                 OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
247                 OUT_RING(ring, 0x00000000);
248                 OUT_PKT3(ring, CP_INTERRUPT, 1);
249                 OUT_RING(ring, 0x80000000);
250         }
251
252 #if 0
253         if (adreno_is_a3xx(adreno_gpu)) {
254                 /* Dummy set-constant to trigger context rollover */
255                 OUT_PKT3(ring, CP_SET_CONSTANT, 2);
256                 OUT_RING(ring, CP_REG(REG_A3XX_HLSQ_CL_KERNEL_GROUP_X_REG));
257                 OUT_RING(ring, 0x00000000);
258         }
259 #endif
260
261         gpu->funcs->flush(gpu);
262 }
263
264 void adreno_flush(struct msm_gpu *gpu)
265 {
266         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
267         uint32_t wptr;
268
269         /*
270          * Mask wptr value that we calculate to fit in the HW range. This is
271          * to account for the possibility that the last command fit exactly into
272          * the ringbuffer and rb->next hasn't wrapped to zero yet
273          */
274         wptr = get_wptr(gpu->rb) & ((gpu->rb->size / 4) - 1);
275
276         /* ensure writes to ringbuffer have hit system memory: */
277         mb();
278
279         adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_WPTR, wptr);
280 }
281
282 bool adreno_idle(struct msm_gpu *gpu)
283 {
284         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
285         uint32_t wptr = get_wptr(gpu->rb);
286
287         /* wait for CP to drain ringbuffer: */
288         if (!spin_until(get_rptr(adreno_gpu) == wptr))
289                 return true;
290
291         /* TODO maybe we need to reset GPU here to recover from hang? */
292         DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
293         return false;
294 }
295
296 #ifdef CONFIG_DEBUG_FS
297 void adreno_show(struct msm_gpu *gpu, struct seq_file *m)
298 {
299         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
300         int i;
301
302         seq_printf(m, "revision: %d (%d.%d.%d.%d)\n",
303                         adreno_gpu->info->revn, adreno_gpu->rev.core,
304                         adreno_gpu->rev.major, adreno_gpu->rev.minor,
305                         adreno_gpu->rev.patchid);
306
307         seq_printf(m, "fence:    %d/%d\n", adreno_gpu->memptrs->fence,
308                         gpu->fctx->last_fence);
309         seq_printf(m, "rptr:     %d\n", get_rptr(adreno_gpu));
310         seq_printf(m, "rb wptr:  %d\n", get_wptr(gpu->rb));
311
312         /* dump these out in a form that can be parsed by demsm: */
313         seq_printf(m, "IO:region %s 00000000 00020000\n", gpu->name);
314         for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
315                 uint32_t start = adreno_gpu->registers[i];
316                 uint32_t end   = adreno_gpu->registers[i+1];
317                 uint32_t addr;
318
319                 for (addr = start; addr <= end; addr++) {
320                         uint32_t val = gpu_read(gpu, addr);
321                         seq_printf(m, "IO:R %08x %08x\n", addr<<2, val);
322                 }
323         }
324 }
325 #endif
326
327 /* Dump common gpu status and scratch registers on any hang, to make
328  * the hangcheck logs more useful.  The scratch registers seem always
329  * safe to read when GPU has hung (unlike some other regs, depending
330  * on how the GPU hung), and they are useful to match up to cmdstream
331  * dumps when debugging hangs:
332  */
333 void adreno_dump_info(struct msm_gpu *gpu)
334 {
335         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
336
337         printk("revision: %d (%d.%d.%d.%d)\n",
338                         adreno_gpu->info->revn, adreno_gpu->rev.core,
339                         adreno_gpu->rev.major, adreno_gpu->rev.minor,
340                         adreno_gpu->rev.patchid);
341
342         printk("fence:    %d/%d\n", adreno_gpu->memptrs->fence,
343                         gpu->fctx->last_fence);
344         printk("rptr:     %d\n", get_rptr(adreno_gpu));
345         printk("rb wptr:  %d\n", get_wptr(gpu->rb));
346 }
347
348 /* would be nice to not have to duplicate the _show() stuff with printk(): */
349 void adreno_dump(struct msm_gpu *gpu)
350 {
351         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
352         int i;
353
354         /* dump these out in a form that can be parsed by demsm: */
355         printk("IO:region %s 00000000 00020000\n", gpu->name);
356         for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
357                 uint32_t start = adreno_gpu->registers[i];
358                 uint32_t end   = adreno_gpu->registers[i+1];
359                 uint32_t addr;
360
361                 for (addr = start; addr <= end; addr++) {
362                         uint32_t val = gpu_read(gpu, addr);
363                         printk("IO:R %08x %08x\n", addr<<2, val);
364                 }
365         }
366 }
367
368 static uint32_t ring_freewords(struct msm_gpu *gpu)
369 {
370         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
371         uint32_t size = gpu->rb->size / 4;
372         uint32_t wptr = get_wptr(gpu->rb);
373         uint32_t rptr = get_rptr(adreno_gpu);
374         return (rptr + (size - 1) - wptr) % size;
375 }
376
377 void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
378 {
379         if (spin_until(ring_freewords(gpu) >= ndwords))
380                 DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
381 }
382
383 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
384                 struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs)
385 {
386         struct adreno_platform_config *config = pdev->dev.platform_data;
387         struct msm_gpu_config adreno_gpu_config  = { 0 };
388         struct msm_gpu *gpu = &adreno_gpu->base;
389         int ret;
390
391         adreno_gpu->funcs = funcs;
392         adreno_gpu->info = adreno_info(config->rev);
393         adreno_gpu->gmem = adreno_gpu->info->gmem;
394         adreno_gpu->revn = adreno_gpu->info->revn;
395         adreno_gpu->rev = config->rev;
396
397         gpu->fast_rate = config->fast_rate;
398         gpu->bus_freq  = config->bus_freq;
399 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
400         gpu->bus_scale_table = config->bus_scale_table;
401 #endif
402
403         DBG("fast_rate=%u, slow_rate=27000000, bus_freq=%u",
404                         gpu->fast_rate, gpu->bus_freq);
405
406         adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
407         adreno_gpu_config.irqname = "kgsl_3d0_irq";
408
409         adreno_gpu_config.va_start = SZ_16M;
410         adreno_gpu_config.va_end = 0xffffffff;
411
412         adreno_gpu_config.ringsz = RB_SIZE;
413
414         pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD);
415         pm_runtime_use_autosuspend(&pdev->dev);
416         pm_runtime_enable(&pdev->dev);
417
418         ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
419                         adreno_gpu->info->name, &adreno_gpu_config);
420         if (ret)
421                 return ret;
422
423         adreno_gpu->memptrs = msm_gem_kernel_new(drm,
424                 sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED, gpu->aspace,
425                 &adreno_gpu->memptrs_bo, &adreno_gpu->memptrs_iova);
426
427         if (IS_ERR(adreno_gpu->memptrs)) {
428                 ret = PTR_ERR(adreno_gpu->memptrs);
429                 adreno_gpu->memptrs = NULL;
430                 dev_err(drm->dev, "could not allocate memptrs: %d\n", ret);
431         }
432
433         return ret;
434 }
435
436 void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
437 {
438         struct msm_gpu *gpu = &adreno_gpu->base;
439
440         if (adreno_gpu->memptrs_bo) {
441                 if (adreno_gpu->memptrs)
442                         msm_gem_put_vaddr(adreno_gpu->memptrs_bo);
443
444                 if (adreno_gpu->memptrs_iova)
445                         msm_gem_put_iova(adreno_gpu->memptrs_bo, gpu->aspace);
446
447                 drm_gem_object_unreference_unlocked(adreno_gpu->memptrs_bo);
448         }
449         release_firmware(adreno_gpu->pm4);
450         release_firmware(adreno_gpu->pfp);
451
452         msm_gpu_cleanup(gpu);
453 }