blob: c2266d4da56ea077b2516aa916e796fb287d013e [file] [log] [blame]
Sunil Khatri82eb1ec2018-01-09 15:28:14 +05301/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
Shrenuj Bansala419c792016-10-20 14:05:11 -07002 *
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 *
12 */
13#include <linux/types.h>
14#include <linux/delay.h>
15#include <linux/device.h>
16#include <linux/spinlock.h>
17#include <linux/genalloc.h>
18#include <linux/slab.h>
19#include <linux/iommu.h>
20#include <linux/msm_kgsl.h>
21#include <linux/ratelimit.h>
22#include <linux/of_platform.h>
23#include <soc/qcom/scm.h>
24#include <soc/qcom/secure_buffer.h>
Shrenuj Bansala419c792016-10-20 14:05:11 -070025#include <linux/compat.h>
26
27#include "kgsl.h"
28#include "kgsl_device.h"
29#include "kgsl_mmu.h"
30#include "kgsl_sharedmem.h"
31#include "kgsl_iommu.h"
32#include "adreno_pm4types.h"
33#include "adreno.h"
34#include "kgsl_trace.h"
35#include "kgsl_pwrctrl.h"
36
Shrenuj Bansal9a0563b2017-06-15 14:45:15 -070037#define CP_APERTURE_REG 0
Sunil Khatri82eb1ec2018-01-09 15:28:14 +053038#define CP_SMMU_APERTURE_ID 0x1B
Shrenuj Bansal9a0563b2017-06-15 14:45:15 -070039
Shrenuj Bansala419c792016-10-20 14:05:11 -070040#define _IOMMU_PRIV(_mmu) (&((_mmu)->priv.iommu))
41
Deepak Kumar756d6a92017-11-28 16:58:29 +053042#define ADDR_IN_GLOBAL(_mmu, _a) \
43 (((_a) >= KGSL_IOMMU_GLOBAL_MEM_BASE(_mmu)) && \
44 ((_a) < (KGSL_IOMMU_GLOBAL_MEM_BASE(_mmu) + \
45 KGSL_IOMMU_GLOBAL_MEM_SIZE)))
Shrenuj Bansala419c792016-10-20 14:05:11 -070046
Sushmita Susheelendra7f66cf72016-09-12 11:04:43 -060047/*
48 * Flag to set SMMU memory attributes required to
49 * enable system cache for GPU transactions.
50 */
51#ifndef IOMMU_USE_UPSTREAM_HINT
52#define IOMMU_USE_UPSTREAM_HINT 0
53#endif
54
Shrenuj Bansala419c792016-10-20 14:05:11 -070055static struct kgsl_mmu_pt_ops iommu_pt_ops;
56static bool need_iommu_sync;
57
58const unsigned int kgsl_iommu_reg_list[KGSL_IOMMU_REG_MAX] = {
59 0x0,/* SCTLR */
60 0x20,/* TTBR0 */
61 0x34,/* CONTEXTIDR */
62 0x58,/* FSR */
63 0x60,/* FAR_0 */
64 0x618,/* TLBIALL */
65 0x008,/* RESUME */
66 0x68,/* FSYNR0 */
67 0x6C,/* FSYNR1 */
68 0x7F0,/* TLBSYNC */
69 0x7F4,/* TLBSTATUS */
70};
71
72/*
73 * struct kgsl_iommu_addr_entry - entry in the kgsl_iommu_pt rbtree.
74 * @base: starting virtual address of the entry
75 * @size: size of the entry
76 * @node: the rbtree node
77 *
78 */
79struct kgsl_iommu_addr_entry {
80 uint64_t base;
81 uint64_t size;
82 struct rb_node node;
83};
84
85static struct kmem_cache *addr_entry_cache;
86
87/*
88 * There are certain memory allocations (ringbuffer, memstore, etc) that need to
89 * be present at the same address in every pagetable. We call these "global"
90 * pagetable entries. There are relatively few of these and they are mostly
91 * stable (defined at init time) but the actual number of globals can differ
92 * slight depending on the target and implementation.
93 *
94 * Here we define an array and a simple allocator to keep track of the currently
95 * active global entries. Each entry is assigned a unique address inside of a
96 * MMU implementation specific "global" region. The addresses are assigned
97 * sequentially and never re-used to avoid having to go back and reprogram
98 * existing pagetables. The entire list of active entries are mapped and
99 * unmapped into every new pagetable as it is created and destroyed.
100 *
101 * Because there are relatively few entries and they are defined at boot time we
102 * don't need to go over the top to define a dynamic allocation scheme. It will
103 * be less wasteful to pick a static number with a little bit of growth
104 * potential.
105 */
106
107#define GLOBAL_PT_ENTRIES 32
108
109struct global_pt_entry {
110 struct kgsl_memdesc *memdesc;
111 char name[32];
112};
113
114static struct global_pt_entry global_pt_entries[GLOBAL_PT_ENTRIES];
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600115static int secure_global_size;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700116static int global_pt_count;
117uint64_t global_pt_alloc;
118static struct kgsl_memdesc gpu_qdss_desc;
Jonathan Wicks4892d8d2017-02-24 16:21:26 -0700119static struct kgsl_memdesc gpu_qtimer_desc;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700120
121void kgsl_print_global_pt_entries(struct seq_file *s)
122{
123 int i;
124
125 for (i = 0; i < global_pt_count; i++) {
126 struct kgsl_memdesc *memdesc = global_pt_entries[i].memdesc;
127
128 if (memdesc == NULL)
129 continue;
130
Hareesh Gundu1fbd9062017-11-01 18:47:45 +0530131 seq_printf(s, "0x%pK-0x%pK %16llu %s\n",
132 (uint64_t *)(uintptr_t) memdesc->gpuaddr,
133 (uint64_t *)(uintptr_t) (memdesc->gpuaddr +
134 memdesc->size - 1), memdesc->size,
135 global_pt_entries[i].name);
Shrenuj Bansala419c792016-10-20 14:05:11 -0700136 }
137}
138
139static void kgsl_iommu_unmap_globals(struct kgsl_pagetable *pagetable)
140{
141 unsigned int i;
142
143 for (i = 0; i < global_pt_count; i++) {
144 if (global_pt_entries[i].memdesc != NULL)
145 kgsl_mmu_unmap(pagetable,
146 global_pt_entries[i].memdesc);
147 }
148}
149
150static int kgsl_iommu_map_globals(struct kgsl_pagetable *pagetable)
151{
152 unsigned int i;
153
154 for (i = 0; i < global_pt_count; i++) {
155 if (global_pt_entries[i].memdesc != NULL) {
156 int ret = kgsl_mmu_map(pagetable,
157 global_pt_entries[i].memdesc);
158
159 if (ret)
160 return ret;
161 }
162 }
163
164 return 0;
165}
166
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600167void kgsl_iommu_unmap_global_secure_pt_entry(struct kgsl_device *device,
Harshdeep Dhattae25cb62018-01-29 10:19:59 -0700168 struct kgsl_memdesc *memdesc)
Shrenuj Bansala419c792016-10-20 14:05:11 -0700169{
Harshdeep Dhattae25cb62018-01-29 10:19:59 -0700170 if (!kgsl_mmu_is_secured(&device->mmu) || memdesc == NULL)
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600171 return;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700172
Harshdeep Dhattae25cb62018-01-29 10:19:59 -0700173 /* Check if an empty memdesc got passed in */
174 if ((memdesc->gpuaddr == 0) || (memdesc->size == 0))
175 return;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700176
Harshdeep Dhattae25cb62018-01-29 10:19:59 -0700177 if (memdesc->pagetable) {
178 if (memdesc->pagetable->name == KGSL_MMU_SECURE_PT)
179 kgsl_mmu_unmap(memdesc->pagetable, memdesc);
180 }
Shrenuj Bansala419c792016-10-20 14:05:11 -0700181}
182
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600183int kgsl_iommu_map_global_secure_pt_entry(struct kgsl_device *device,
184 struct kgsl_memdesc *entry)
Shrenuj Bansala419c792016-10-20 14:05:11 -0700185{
186 int ret = 0;
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600187
188 if (!kgsl_mmu_is_secured(&device->mmu))
189 return -ENOTSUPP;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700190
191 if (entry != NULL) {
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600192 struct kgsl_pagetable *pagetable = device->mmu.securepagetable;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700193 entry->pagetable = pagetable;
Deepak Kumar756d6a92017-11-28 16:58:29 +0530194 entry->gpuaddr = KGSL_IOMMU_SECURE_BASE(&device->mmu) +
195 secure_global_size;
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600196
Shrenuj Bansala419c792016-10-20 14:05:11 -0700197 ret = kgsl_mmu_map(pagetable, entry);
Harshdeep Dhatt1f408332017-03-27 11:35:13 -0600198 if (ret == 0)
199 secure_global_size += entry->size;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700200 }
201 return ret;
202}
203
204static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu,
205 struct kgsl_memdesc *memdesc)
206{
207 int i;
208
209 if (memdesc->gpuaddr == 0 || !(memdesc->priv & KGSL_MEMDESC_GLOBAL))
210 return;
211
212 for (i = 0; i < global_pt_count; i++) {
213 if (global_pt_entries[i].memdesc == memdesc) {
214 memdesc->gpuaddr = 0;
215 memdesc->priv &= ~KGSL_MEMDESC_GLOBAL;
216 global_pt_entries[i].memdesc = NULL;
217 return;
218 }
219 }
220}
221
222static void kgsl_iommu_add_global(struct kgsl_mmu *mmu,
223 struct kgsl_memdesc *memdesc, const char *name)
224{
225 if (memdesc->gpuaddr != 0)
226 return;
227
228 /*Check that we can fit the global allocations */
229 if (WARN_ON(global_pt_count >= GLOBAL_PT_ENTRIES) ||
230 WARN_ON((global_pt_alloc + memdesc->size) >=
231 KGSL_IOMMU_GLOBAL_MEM_SIZE))
232 return;
233
Deepak Kumar756d6a92017-11-28 16:58:29 +0530234 memdesc->gpuaddr = KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + global_pt_alloc;
235
Shrenuj Bansala419c792016-10-20 14:05:11 -0700236 memdesc->priv |= KGSL_MEMDESC_GLOBAL;
237 global_pt_alloc += memdesc->size;
238
239 global_pt_entries[global_pt_count].memdesc = memdesc;
240 strlcpy(global_pt_entries[global_pt_count].name, name,
241 sizeof(global_pt_entries[global_pt_count].name));
242 global_pt_count++;
243}
244
Shrenuj Bansala419c792016-10-20 14:05:11 -0700245struct kgsl_memdesc *kgsl_iommu_get_qdss_global_entry(void)
246{
247 return &gpu_qdss_desc;
248}
249
250static void kgsl_setup_qdss_desc(struct kgsl_device *device)
251{
252 int result = 0;
253 uint32_t gpu_qdss_entry[2];
254
255 if (!of_find_property(device->pdev->dev.of_node,
256 "qcom,gpu-qdss-stm", NULL))
257 return;
258
259 if (of_property_read_u32_array(device->pdev->dev.of_node,
260 "qcom,gpu-qdss-stm", gpu_qdss_entry, 2)) {
261 KGSL_CORE_ERR("Failed to read gpu qdss dts entry\n");
262 return;
263 }
264
Lynus Vaz90d98b52018-04-09 14:45:36 +0530265 kgsl_memdesc_init(device, &gpu_qdss_desc, 0);
Shrenuj Bansala419c792016-10-20 14:05:11 -0700266 gpu_qdss_desc.priv = 0;
267 gpu_qdss_desc.physaddr = gpu_qdss_entry[0];
268 gpu_qdss_desc.size = gpu_qdss_entry[1];
269 gpu_qdss_desc.pagetable = NULL;
270 gpu_qdss_desc.ops = NULL;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700271 gpu_qdss_desc.hostptr = NULL;
272
273 result = memdesc_sg_dma(&gpu_qdss_desc, gpu_qdss_desc.physaddr,
274 gpu_qdss_desc.size);
275 if (result) {
276 KGSL_CORE_ERR("memdesc_sg_dma failed: %d\n", result);
277 return;
278 }
279
280 kgsl_mmu_add_global(device, &gpu_qdss_desc, "gpu-qdss");
281}
282
283static inline void kgsl_cleanup_qdss_desc(struct kgsl_mmu *mmu)
284{
285 kgsl_iommu_remove_global(mmu, &gpu_qdss_desc);
286 kgsl_sharedmem_free(&gpu_qdss_desc);
287}
288
Jonathan Wicks4892d8d2017-02-24 16:21:26 -0700289struct kgsl_memdesc *kgsl_iommu_get_qtimer_global_entry(void)
290{
291 return &gpu_qtimer_desc;
292}
293
294static void kgsl_setup_qtimer_desc(struct kgsl_device *device)
295{
296 int result = 0;
297 uint32_t gpu_qtimer_entry[2];
298
299 if (!of_find_property(device->pdev->dev.of_node,
300 "qcom,gpu-qtimer", NULL))
301 return;
302
303 if (of_property_read_u32_array(device->pdev->dev.of_node,
304 "qcom,gpu-qtimer", gpu_qtimer_entry, 2)) {
305 KGSL_CORE_ERR("Failed to read gpu qtimer dts entry\n");
306 return;
307 }
308
Lynus Vaz90d98b52018-04-09 14:45:36 +0530309 kgsl_memdesc_init(device, &gpu_qtimer_desc, 0);
Jonathan Wicks4892d8d2017-02-24 16:21:26 -0700310 gpu_qtimer_desc.priv = 0;
311 gpu_qtimer_desc.physaddr = gpu_qtimer_entry[0];
312 gpu_qtimer_desc.size = gpu_qtimer_entry[1];
313 gpu_qtimer_desc.pagetable = NULL;
314 gpu_qtimer_desc.ops = NULL;
Jonathan Wicks4892d8d2017-02-24 16:21:26 -0700315 gpu_qtimer_desc.hostptr = NULL;
316
317 result = memdesc_sg_dma(&gpu_qtimer_desc, gpu_qtimer_desc.physaddr,
318 gpu_qtimer_desc.size);
319 if (result) {
320 KGSL_CORE_ERR("memdesc_sg_dma failed: %d\n", result);
321 return;
322 }
323
324 kgsl_mmu_add_global(device, &gpu_qtimer_desc, "gpu-qtimer");
325}
326
327static inline void kgsl_cleanup_qtimer_desc(struct kgsl_mmu *mmu)
328{
329 kgsl_iommu_remove_global(mmu, &gpu_qtimer_desc);
330 kgsl_sharedmem_free(&gpu_qtimer_desc);
331}
Shrenuj Bansala419c792016-10-20 14:05:11 -0700332
333static inline void _iommu_sync_mmu_pc(bool lock)
334{
335 if (need_iommu_sync == false)
336 return;
337
338 if (lock)
339 mutex_lock(&kgsl_mmu_sync);
340 else
341 mutex_unlock(&kgsl_mmu_sync);
342}
343
344static void _detach_pt(struct kgsl_iommu_pt *iommu_pt,
345 struct kgsl_iommu_context *ctx)
346{
347 if (iommu_pt->attached) {
348 _iommu_sync_mmu_pc(true);
349 iommu_detach_device(iommu_pt->domain, ctx->dev);
350 _iommu_sync_mmu_pc(false);
351 iommu_pt->attached = false;
352 }
353}
354
355static int _attach_pt(struct kgsl_iommu_pt *iommu_pt,
356 struct kgsl_iommu_context *ctx)
357{
358 int ret;
359
360 if (iommu_pt->attached)
361 return 0;
362
363 _iommu_sync_mmu_pc(true);
364 ret = iommu_attach_device(iommu_pt->domain, ctx->dev);
365 _iommu_sync_mmu_pc(false);
366
367 if (ret == 0)
368 iommu_pt->attached = true;
369
370 return ret;
371}
372
Shrenuj Bansala419c792016-10-20 14:05:11 -0700373static int _iommu_map_sync_pc(struct kgsl_pagetable *pt,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700374 uint64_t gpuaddr, phys_addr_t physaddr,
375 uint64_t size, unsigned int flags)
376{
377 struct kgsl_iommu_pt *iommu_pt = pt->priv;
378 int ret;
379
Shrenuj Bansala419c792016-10-20 14:05:11 -0700380 _iommu_sync_mmu_pc(true);
381
382 ret = iommu_map(iommu_pt->domain, gpuaddr, physaddr, size, flags);
383
384 _iommu_sync_mmu_pc(false);
385
Shrenuj Bansala419c792016-10-20 14:05:11 -0700386 if (ret) {
387 KGSL_CORE_ERR("map err: 0x%016llX, 0x%llx, 0x%x, %d\n",
388 gpuaddr, size, flags, ret);
389 return -ENODEV;
390 }
391
392 return 0;
393}
394
395static int _iommu_unmap_sync_pc(struct kgsl_pagetable *pt,
Carter Coopera1c7cce2017-12-15 13:29:29 -0700396 uint64_t addr, uint64_t size)
Shrenuj Bansala419c792016-10-20 14:05:11 -0700397{
398 struct kgsl_iommu_pt *iommu_pt = pt->priv;
399 size_t unmapped = 0;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700400
401 _iommu_sync_mmu_pc(true);
402
403 unmapped = iommu_unmap(iommu_pt->domain, addr, size);
404
405 _iommu_sync_mmu_pc(false);
406
Shrenuj Bansala419c792016-10-20 14:05:11 -0700407 if (unmapped != size) {
408 KGSL_CORE_ERR("unmap err: 0x%016llx, 0x%llx, %zd\n",
409 addr, size, unmapped);
410 return -ENODEV;
411 }
412
413 return 0;
414}
415
416static int _iommu_map_sg_offset_sync_pc(struct kgsl_pagetable *pt,
Carter Coopera1c7cce2017-12-15 13:29:29 -0700417 uint64_t addr, struct scatterlist *sg, int nents,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700418 uint64_t offset, uint64_t size, unsigned int flags)
419{
420 struct kgsl_iommu_pt *iommu_pt = pt->priv;
421 uint64_t offset_tmp = offset;
422 uint64_t size_tmp = size;
423 size_t mapped = 0;
424 unsigned int i;
425 struct scatterlist *s;
426 phys_addr_t physaddr;
427 int ret;
428
Shrenuj Bansala419c792016-10-20 14:05:11 -0700429 _iommu_sync_mmu_pc(true);
430
431 for_each_sg(sg, s, nents, i) {
432 /* Iterate until we find the offset */
433 if (offset_tmp >= s->length) {
434 offset_tmp -= s->length;
435 continue;
436 }
437
438 /* How much mapping is needed in this sg? */
439 if (size < s->length - offset_tmp)
440 size_tmp = size;
441 else
442 size_tmp = s->length - offset_tmp;
443
444 /* Get the phys addr for the offset page */
445 if (offset_tmp != 0) {
446 physaddr = page_to_phys(nth_page(sg_page(s),
447 offset_tmp >> PAGE_SHIFT));
448 /* Reset offset_tmp */
449 offset_tmp = 0;
450 } else
451 physaddr = page_to_phys(sg_page(s));
452
453 /* Do the map for this sg */
454 ret = iommu_map(iommu_pt->domain, addr + mapped,
455 physaddr, size_tmp, flags);
456 if (ret)
457 break;
458
459 mapped += size_tmp;
460 size -= size_tmp;
461
462 if (size == 0)
463 break;
464 }
465
466 _iommu_sync_mmu_pc(false);
467
Shrenuj Bansala419c792016-10-20 14:05:11 -0700468 if (size != 0) {
469 /* Cleanup on error */
Carter Coopera1c7cce2017-12-15 13:29:29 -0700470 _iommu_unmap_sync_pc(pt, addr, mapped);
Shrenuj Bansala419c792016-10-20 14:05:11 -0700471 KGSL_CORE_ERR(
472 "map sg offset err: 0x%016llX, %d, %x, %zd\n",
473 addr, nents, flags, mapped);
474 return -ENODEV;
475 }
476
477 return 0;
478}
479
480static int _iommu_map_sg_sync_pc(struct kgsl_pagetable *pt,
Carter Coopera1c7cce2017-12-15 13:29:29 -0700481 uint64_t addr, struct scatterlist *sg, int nents,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700482 unsigned int flags)
483{
484 struct kgsl_iommu_pt *iommu_pt = pt->priv;
485 size_t mapped;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700486
487 _iommu_sync_mmu_pc(true);
488
489 mapped = iommu_map_sg(iommu_pt->domain, addr, sg, nents, flags);
490
491 _iommu_sync_mmu_pc(false);
492
Shrenuj Bansala419c792016-10-20 14:05:11 -0700493 if (mapped == 0) {
494 KGSL_CORE_ERR("map sg err: 0x%016llX, %d, %x, %zd\n",
495 addr, nents, flags, mapped);
496 return -ENODEV;
497 }
498
499 return 0;
500}
501
502/*
503 * One page allocation for a guard region to protect against over-zealous
504 * GPU pre-fetch
505 */
506
507static struct page *kgsl_guard_page;
508static struct kgsl_memdesc kgsl_secure_guard_page_memdesc;
509
510/*
511 * The dummy page is a placeholder/extra page to be used for sparse mappings.
512 * This page will be mapped to all virtual sparse bindings that are not
513 * physically backed.
514 */
515static struct page *kgsl_dummy_page;
516
517/* These functions help find the nearest allocated memory entries on either side
518 * of a faulting address. If we know the nearby allocations memory we can
519 * get a better determination of what we think should have been located in the
520 * faulting region
521 */
522
523/*
524 * A local structure to make it easy to store the interesting bits for the
525 * memory entries on either side of the faulting address
526 */
527
528struct _mem_entry {
529 uint64_t gpuaddr;
530 uint64_t size;
531 uint64_t flags;
532 unsigned int priv;
533 int pending_free;
534 pid_t pid;
535 char name[32];
536};
537
538static void _get_global_entries(uint64_t faultaddr,
539 struct _mem_entry *prev,
540 struct _mem_entry *next)
541{
542 int i;
543 uint64_t prevaddr = 0;
544 struct global_pt_entry *p = NULL;
545
546 uint64_t nextaddr = (uint64_t) -1;
547 struct global_pt_entry *n = NULL;
548
549 for (i = 0; i < global_pt_count; i++) {
550 uint64_t addr;
551
552 if (global_pt_entries[i].memdesc == NULL)
553 continue;
554
555 addr = global_pt_entries[i].memdesc->gpuaddr;
556 if ((addr < faultaddr) && (addr > prevaddr)) {
557 prevaddr = addr;
558 p = &global_pt_entries[i];
559 }
560
561 if ((addr > faultaddr) && (addr < nextaddr)) {
562 nextaddr = addr;
563 n = &global_pt_entries[i];
564 }
565 }
566
567 if (p != NULL) {
568 prev->gpuaddr = p->memdesc->gpuaddr;
569 prev->size = p->memdesc->size;
570 prev->flags = p->memdesc->flags;
571 prev->priv = p->memdesc->priv;
572 prev->pid = 0;
573 strlcpy(prev->name, p->name, sizeof(prev->name));
574 }
575
576 if (n != NULL) {
577 next->gpuaddr = n->memdesc->gpuaddr;
578 next->size = n->memdesc->size;
579 next->flags = n->memdesc->flags;
580 next->priv = n->memdesc->priv;
581 next->pid = 0;
582 strlcpy(next->name, n->name, sizeof(next->name));
583 }
584}
585
586void __kgsl_get_memory_usage(struct _mem_entry *entry)
587{
588 kgsl_get_memory_usage(entry->name, sizeof(entry->name), entry->flags);
589}
590
591static void _get_entries(struct kgsl_process_private *private,
592 uint64_t faultaddr, struct _mem_entry *prev,
593 struct _mem_entry *next)
594{
595 int id;
596 struct kgsl_mem_entry *entry;
597
598 uint64_t prevaddr = 0;
599 struct kgsl_mem_entry *p = NULL;
600
601 uint64_t nextaddr = (uint64_t) -1;
602 struct kgsl_mem_entry *n = NULL;
603
604 idr_for_each_entry(&private->mem_idr, entry, id) {
605 uint64_t addr = entry->memdesc.gpuaddr;
606
607 if ((addr < faultaddr) && (addr > prevaddr)) {
608 prevaddr = addr;
609 p = entry;
610 }
611
612 if ((addr > faultaddr) && (addr < nextaddr)) {
613 nextaddr = addr;
614 n = entry;
615 }
616 }
617
618 if (p != NULL) {
619 prev->gpuaddr = p->memdesc.gpuaddr;
620 prev->size = p->memdesc.size;
621 prev->flags = p->memdesc.flags;
622 prev->priv = p->memdesc.priv;
623 prev->pending_free = p->pending_free;
624 prev->pid = private->pid;
625 __kgsl_get_memory_usage(prev);
626 }
627
628 if (n != NULL) {
629 next->gpuaddr = n->memdesc.gpuaddr;
630 next->size = n->memdesc.size;
631 next->flags = n->memdesc.flags;
632 next->priv = n->memdesc.priv;
633 next->pending_free = n->pending_free;
634 next->pid = private->pid;
635 __kgsl_get_memory_usage(next);
636 }
637}
638
639static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
640 struct _mem_entry *preventry, struct _mem_entry *nextentry,
641 struct kgsl_context *context)
642{
643 struct kgsl_process_private *private;
644
645 memset(preventry, 0, sizeof(*preventry));
646 memset(nextentry, 0, sizeof(*nextentry));
647
648 /* Set the maximum possible size as an initial value */
649 nextentry->gpuaddr = (uint64_t) -1;
650
Deepak Kumar756d6a92017-11-28 16:58:29 +0530651 if (ADDR_IN_GLOBAL(mmu, faultaddr)) {
Shrenuj Bansala419c792016-10-20 14:05:11 -0700652 _get_global_entries(faultaddr, preventry, nextentry);
653 } else if (context) {
654 private = context->proc_priv;
655 spin_lock(&private->mem_lock);
656 _get_entries(private, faultaddr, preventry, nextentry);
657 spin_unlock(&private->mem_lock);
658 }
659}
660
661static void _print_entry(struct kgsl_device *device, struct _mem_entry *entry)
662{
663 KGSL_LOG_DUMP(device,
664 "[%016llX - %016llX] %s %s (pid = %d) (%s)\n",
665 entry->gpuaddr,
666 entry->gpuaddr + entry->size,
667 entry->priv & KGSL_MEMDESC_GUARD_PAGE ? "(+guard)" : "",
668 entry->pending_free ? "(pending free)" : "",
669 entry->pid, entry->name);
670}
671
672static void _check_if_freed(struct kgsl_iommu_context *ctx,
673 uint64_t addr, pid_t ptname)
674{
675 uint64_t gpuaddr = addr;
676 uint64_t size = 0;
677 uint64_t flags = 0;
678 pid_t pid;
679
680 char name[32];
681
682 memset(name, 0, sizeof(name));
683
684 if (kgsl_memfree_find_entry(ptname, &gpuaddr, &size, &flags, &pid)) {
685 kgsl_get_memory_usage(name, sizeof(name) - 1, flags);
686 KGSL_LOG_DUMP(ctx->kgsldev, "---- premature free ----\n");
687 KGSL_LOG_DUMP(ctx->kgsldev,
688 "[%8.8llX-%8.8llX] (%s) was already freed by pid %d\n",
689 gpuaddr, gpuaddr + size, name, pid);
690 }
691}
692
693static bool
694kgsl_iommu_uche_overfetch(struct kgsl_process_private *private,
695 uint64_t faultaddr)
696{
697 int id;
698 struct kgsl_mem_entry *entry = NULL;
699
700 spin_lock(&private->mem_lock);
701 idr_for_each_entry(&private->mem_idr, entry, id) {
702 struct kgsl_memdesc *m = &entry->memdesc;
703
704 if ((faultaddr >= (m->gpuaddr + m->size))
705 && (faultaddr < (m->gpuaddr + m->size + 64))) {
706 spin_unlock(&private->mem_lock);
707 return true;
708 }
709 }
710 spin_unlock(&private->mem_lock);
711 return false;
712}
713
714/*
715 * Read pagefaults where the faulting address lies within the first 64 bytes
716 * of a page (UCHE line size is 64 bytes) and the fault page is preceded by a
717 * valid allocation are considered likely due to UCHE overfetch and suppressed.
718 */
719
720static bool kgsl_iommu_suppress_pagefault(uint64_t faultaddr, int write,
721 struct kgsl_context *context)
722{
723 /*
724 * If there is no context associated with the pagefault then this
725 * could be a fault on a global buffer. We do not suppress faults
726 * on global buffers as they are mainly accessed by the CP bypassing
727 * the UCHE. Also, write pagefaults are never suppressed.
728 */
729 if (!context || write)
730 return false;
731
732 return kgsl_iommu_uche_overfetch(context->proc_priv, faultaddr);
733}
734
735static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
736 struct device *dev, unsigned long addr, int flags, void *token)
737{
738 int ret = 0;
739 struct kgsl_pagetable *pt = token;
740 struct kgsl_mmu *mmu = pt->mmu;
741 struct kgsl_iommu *iommu;
742 struct kgsl_iommu_context *ctx;
743 u64 ptbase;
744 u32 contextidr;
Lynus Vaze0a01312017-11-08 19:39:31 +0530745 pid_t pid = 0;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700746 pid_t ptname;
747 struct _mem_entry prev, next;
748 int write;
749 struct kgsl_device *device;
750 struct adreno_device *adreno_dev;
Lynus Vaz1fde74d2017-03-20 18:02:47 +0530751 struct adreno_gpudev *gpudev;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700752 unsigned int no_page_fault_log = 0;
753 unsigned int curr_context_id = 0;
754 struct kgsl_context *context;
755 char *fault_type = "unknown";
756
757 static DEFINE_RATELIMIT_STATE(_rs,
758 DEFAULT_RATELIMIT_INTERVAL,
759 DEFAULT_RATELIMIT_BURST);
760
761 if (mmu == NULL)
762 return ret;
763
764 iommu = _IOMMU_PRIV(mmu);
765 ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
766 device = KGSL_MMU_DEVICE(mmu);
767 adreno_dev = ADRENO_DEVICE(device);
Lynus Vaz1fde74d2017-03-20 18:02:47 +0530768 gpudev = ADRENO_GPU_DEVICE(adreno_dev);
Shrenuj Bansala419c792016-10-20 14:05:11 -0700769
770 if (pt->name == KGSL_MMU_SECURE_PT)
771 ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE];
772
773 /*
774 * set the fault bits and stuff before any printks so that if fault
775 * handler runs then it will know it's dealing with a pagefault.
776 * Read the global current timestamp because we could be in middle of
777 * RB switch and hence the cur RB may not be reliable but global
778 * one will always be reliable
779 */
780 kgsl_sharedmem_readl(&device->memstore, &curr_context_id,
781 KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));
782
783 context = kgsl_context_get(device, curr_context_id);
784
785 write = (flags & IOMMU_FAULT_WRITE) ? 1 : 0;
786 if (flags & IOMMU_FAULT_TRANSLATION)
787 fault_type = "translation";
788 else if (flags & IOMMU_FAULT_PERMISSION)
789 fault_type = "permission";
790
791 if (kgsl_iommu_suppress_pagefault(addr, write, context)) {
792 iommu->pagefault_suppression_count++;
793 kgsl_context_put(context);
794 return ret;
795 }
796
797 if (context != NULL) {
798 /* save pagefault timestamp for GFT */
799 set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);
Lynus Vaze0a01312017-11-08 19:39:31 +0530800 pid = context->proc_priv->pid;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700801 }
802
803 ctx->fault = 1;
804
805 if (test_bit(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE,
806 &adreno_dev->ft_pf_policy) &&
807 (flags & IOMMU_FAULT_TRANSACTION_STALLED)) {
808 /*
809 * Turn off GPU IRQ so we don't get faults from it too.
810 * The device mutex must be held to change power state
811 */
812 mutex_lock(&device->mutex);
813 kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
814 mutex_unlock(&device->mutex);
815 }
816
817 ptbase = KGSL_IOMMU_GET_CTX_REG_Q(ctx, TTBR0);
818 contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, CONTEXTIDR);
819
820 ptname = MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE) ?
Lynus Vaze0a01312017-11-08 19:39:31 +0530821 KGSL_MMU_GLOBAL_PT : pid;
Sunil Khatri86e95682017-01-23 17:10:32 +0530822 /*
823 * Trace needs to be logged before searching the faulting
824 * address in free list as it takes quite long time in
825 * search and delays the trace unnecessarily.
826 */
827 trace_kgsl_mmu_pagefault(ctx->kgsldev, addr,
828 ptname, write ? "write" : "read");
Shrenuj Bansala419c792016-10-20 14:05:11 -0700829
830 if (test_bit(KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE,
831 &adreno_dev->ft_pf_policy))
832 no_page_fault_log = kgsl_mmu_log_fault_addr(mmu, ptbase, addr);
833
834 if (!no_page_fault_log && __ratelimit(&_rs)) {
835 KGSL_MEM_CRIT(ctx->kgsldev,
836 "GPU PAGE FAULT: addr = %lX pid= %d\n", addr, ptname);
837 KGSL_MEM_CRIT(ctx->kgsldev,
838 "context=%s TTBR0=0x%llx CIDR=0x%x (%s %s fault)\n",
839 ctx->name, ptbase, contextidr,
840 write ? "write" : "read", fault_type);
841
Lynus Vaz1fde74d2017-03-20 18:02:47 +0530842 if (gpudev->iommu_fault_block) {
843 unsigned int fsynr1;
844
845 fsynr1 = KGSL_IOMMU_GET_CTX_REG(ctx, FSYNR1);
846 KGSL_MEM_CRIT(ctx->kgsldev,
847 "FAULTING BLOCK: %s\n",
848 gpudev->iommu_fault_block(adreno_dev,
849 fsynr1));
850 }
851
Shrenuj Bansala419c792016-10-20 14:05:11 -0700852 /* Don't print the debug if this is a permissions fault */
853 if (!(flags & IOMMU_FAULT_PERMISSION)) {
854 _check_if_freed(ctx, addr, ptname);
855
856 KGSL_LOG_DUMP(ctx->kgsldev,
857 "---- nearby memory ----\n");
858
859 _find_mem_entries(mmu, addr, &prev, &next, context);
860 if (prev.gpuaddr)
861 _print_entry(ctx->kgsldev, &prev);
862 else
863 KGSL_LOG_DUMP(ctx->kgsldev, "*EMPTY*\n");
864
865 KGSL_LOG_DUMP(ctx->kgsldev, " <- fault @ %8.8lX\n",
866 addr);
867
868 if (next.gpuaddr != (uint64_t) -1)
869 _print_entry(ctx->kgsldev, &next);
870 else
871 KGSL_LOG_DUMP(ctx->kgsldev, "*EMPTY*\n");
872 }
873 }
874
Shrenuj Bansala419c792016-10-20 14:05:11 -0700875
876 /*
877 * We do not want the h/w to resume fetching data from an iommu
878 * that has faulted, this is better for debugging as it will stall
879 * the GPU and trigger a snapshot. Return EBUSY error.
880 */
881 if (test_bit(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE,
882 &adreno_dev->ft_pf_policy) &&
883 (flags & IOMMU_FAULT_TRANSACTION_STALLED)) {
884 uint32_t sctlr_val;
885
886 ret = -EBUSY;
887 /*
888 * Disable context fault interrupts
889 * as we do not clear FSR in the ISR.
890 * Will be re-enabled after FSR is cleared.
891 */
892 sctlr_val = KGSL_IOMMU_GET_CTX_REG(ctx, SCTLR);
893 sctlr_val &= ~(0x1 << KGSL_IOMMU_SCTLR_CFIE_SHIFT);
894 KGSL_IOMMU_SET_CTX_REG(ctx, SCTLR, sctlr_val);
895
896 adreno_set_gpu_fault(adreno_dev, ADRENO_IOMMU_PAGE_FAULT);
897 /* Go ahead with recovery*/
898 adreno_dispatcher_schedule(device);
899 }
900
901 kgsl_context_put(context);
902 return ret;
903}
904
905/*
906 * kgsl_iommu_disable_clk() - Disable iommu clocks
907 * Disable IOMMU clocks
908 */
909static void kgsl_iommu_disable_clk(struct kgsl_mmu *mmu)
910{
911 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
912 int j;
913
914 atomic_dec(&iommu->clk_enable_count);
915
916 /*
917 * Make sure the clk refcounts are good. An unbalance may
918 * cause the clocks to be off when we need them on.
919 */
920 WARN_ON(atomic_read(&iommu->clk_enable_count) < 0);
921
922 for (j = (KGSL_IOMMU_MAX_CLKS - 1); j >= 0; j--)
923 if (iommu->clks[j])
924 clk_disable_unprepare(iommu->clks[j]);
925}
926
927/*
928 * kgsl_iommu_enable_clk_prepare_enable - Enable the specified IOMMU clock
929 * Try 4 times to enable it and then BUG() for debug
930 */
931static void kgsl_iommu_clk_prepare_enable(struct clk *clk)
932{
933 int num_retries = 4;
934
935 while (num_retries--) {
936 if (!clk_prepare_enable(clk))
937 return;
938 }
939
940 /* Failure is fatal so BUG() to facilitate debug */
941 KGSL_CORE_ERR("IOMMU clock enable failed\n");
942 BUG();
943}
944
945/*
946 * kgsl_iommu_enable_clk - Enable iommu clocks
947 * Enable all the IOMMU clocks
948 */
949static void kgsl_iommu_enable_clk(struct kgsl_mmu *mmu)
950{
951 int j;
952 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
953
954 for (j = 0; j < KGSL_IOMMU_MAX_CLKS; j++) {
955 if (iommu->clks[j])
956 kgsl_iommu_clk_prepare_enable(iommu->clks[j]);
957 }
958 atomic_inc(&iommu->clk_enable_count);
959}
960
961/* kgsl_iommu_get_ttbr0 - Get TTBR0 setting for a pagetable */
962static u64 kgsl_iommu_get_ttbr0(struct kgsl_pagetable *pt)
963{
964 struct kgsl_iommu_pt *iommu_pt = pt ? pt->priv : NULL;
965
966 BUG_ON(iommu_pt == NULL);
967
968 return iommu_pt->ttbr0;
969}
970
971static bool kgsl_iommu_pt_equal(struct kgsl_mmu *mmu,
972 struct kgsl_pagetable *pt,
973 u64 ttbr0)
974{
975 struct kgsl_iommu_pt *iommu_pt = pt ? pt->priv : NULL;
976 u64 domain_ttbr0;
977
978 if (iommu_pt == NULL)
979 return 0;
980
981 domain_ttbr0 = kgsl_iommu_get_ttbr0(pt);
982
983 return (domain_ttbr0 == ttbr0);
984}
985
986/* kgsl_iommu_get_contextidr - query CONTEXTIDR setting for a pagetable */
987static u32 kgsl_iommu_get_contextidr(struct kgsl_pagetable *pt)
988{
989 struct kgsl_iommu_pt *iommu_pt = pt ? pt->priv : NULL;
990
991 BUG_ON(iommu_pt == NULL);
992
993 return iommu_pt->contextidr;
994}
995
996/*
997 * kgsl_iommu_destroy_pagetable - Free up reaources help by a pagetable
998 * @mmu_specific_pt - Pointer to pagetable which is to be freed
999 *
1000 * Return - void
1001 */
1002static void kgsl_iommu_destroy_pagetable(struct kgsl_pagetable *pt)
1003{
1004 struct kgsl_iommu_pt *iommu_pt = pt->priv;
1005 struct kgsl_mmu *mmu = pt->mmu;
1006 struct kgsl_iommu *iommu;
1007 struct kgsl_iommu_context *ctx;
1008
1009 /*
1010 * Make sure all allocations are unmapped before destroying
1011 * the pagetable
1012 */
1013 WARN_ON(!list_empty(&pt->list));
1014
1015 iommu = _IOMMU_PRIV(mmu);
1016
1017 if (pt->name == KGSL_MMU_SECURE_PT) {
1018 ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE];
Shrenuj Bansala419c792016-10-20 14:05:11 -07001019 } else {
1020 ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
1021 kgsl_iommu_unmap_globals(pt);
1022 }
1023
1024 if (iommu_pt->domain) {
1025 trace_kgsl_pagetable_destroy(iommu_pt->ttbr0, pt->name);
1026
1027 _detach_pt(iommu_pt, ctx);
1028
1029 iommu_domain_free(iommu_pt->domain);
1030 }
1031
1032 kfree(iommu_pt);
1033}
1034
1035static void setup_64bit_pagetable(struct kgsl_mmu *mmu,
1036 struct kgsl_pagetable *pagetable,
1037 struct kgsl_iommu_pt *pt)
1038{
Shrenuj Bansala419c792016-10-20 14:05:11 -07001039 if (mmu->secured && pagetable->name == KGSL_MMU_SECURE_PT) {
Deepak Kumar756d6a92017-11-28 16:58:29 +05301040 pt->compat_va_start = KGSL_IOMMU_SECURE_BASE(mmu);
1041 pt->compat_va_end = KGSL_IOMMU_SECURE_END(mmu);
1042 pt->va_start = KGSL_IOMMU_SECURE_BASE(mmu);
1043 pt->va_end = KGSL_IOMMU_SECURE_END(mmu);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001044 } else {
1045 pt->compat_va_start = KGSL_IOMMU_SVM_BASE32;
Deepak Kumar756d6a92017-11-28 16:58:29 +05301046 pt->compat_va_end = KGSL_IOMMU_SECURE_BASE(mmu);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001047 pt->va_start = KGSL_IOMMU_VA_BASE64;
1048 pt->va_end = KGSL_IOMMU_VA_END64;
1049 }
1050
1051 if (pagetable->name != KGSL_MMU_GLOBAL_PT &&
1052 pagetable->name != KGSL_MMU_SECURE_PT) {
Deepak Kumarcf056d12018-04-17 15:59:42 +05301053 if (kgsl_is_compat_task()) {
Shrenuj Bansala419c792016-10-20 14:05:11 -07001054 pt->svm_start = KGSL_IOMMU_SVM_BASE32;
Deepak Kumar756d6a92017-11-28 16:58:29 +05301055 pt->svm_end = KGSL_IOMMU_SECURE_BASE(mmu);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001056 } else {
1057 pt->svm_start = KGSL_IOMMU_SVM_BASE64;
1058 pt->svm_end = KGSL_IOMMU_SVM_END64;
1059 }
1060 }
1061}
1062
1063static void setup_32bit_pagetable(struct kgsl_mmu *mmu,
1064 struct kgsl_pagetable *pagetable,
1065 struct kgsl_iommu_pt *pt)
1066{
Shrenuj Bansala419c792016-10-20 14:05:11 -07001067 if (mmu->secured) {
1068 if (pagetable->name == KGSL_MMU_SECURE_PT) {
Deepak Kumar756d6a92017-11-28 16:58:29 +05301069 pt->compat_va_start = KGSL_IOMMU_SECURE_BASE(mmu);
1070 pt->compat_va_end = KGSL_IOMMU_SECURE_END(mmu);
1071 pt->va_start = KGSL_IOMMU_SECURE_BASE(mmu);
1072 pt->va_end = KGSL_IOMMU_SECURE_END(mmu);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001073 } else {
1074 pt->va_start = KGSL_IOMMU_SVM_BASE32;
Deepak Kumar756d6a92017-11-28 16:58:29 +05301075 pt->va_end = KGSL_IOMMU_SECURE_BASE(mmu);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001076 pt->compat_va_start = pt->va_start;
1077 pt->compat_va_end = pt->va_end;
1078 }
1079 } else {
1080 pt->va_start = KGSL_IOMMU_SVM_BASE32;
Deepak Kumar756d6a92017-11-28 16:58:29 +05301081 pt->va_end = KGSL_IOMMU_GLOBAL_MEM_BASE(mmu);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001082 pt->compat_va_start = pt->va_start;
1083 pt->compat_va_end = pt->va_end;
1084 }
1085
1086 if (pagetable->name != KGSL_MMU_GLOBAL_PT &&
1087 pagetable->name != KGSL_MMU_SECURE_PT) {
1088 pt->svm_start = KGSL_IOMMU_SVM_BASE32;
1089 pt->svm_end = KGSL_IOMMU_SVM_END32;
1090 }
1091}
1092
1093
1094static struct kgsl_iommu_pt *
1095_alloc_pt(struct device *dev, struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
1096{
1097 struct kgsl_iommu_pt *iommu_pt;
1098 struct bus_type *bus = kgsl_mmu_get_bus(dev);
1099
1100 if (bus == NULL)
1101 return ERR_PTR(-ENODEV);
1102
1103 iommu_pt = kzalloc(sizeof(struct kgsl_iommu_pt), GFP_KERNEL);
1104 if (iommu_pt == NULL)
1105 return ERR_PTR(-ENOMEM);
1106
1107 iommu_pt->domain = iommu_domain_alloc(bus);
1108 if (iommu_pt->domain == NULL) {
1109 kfree(iommu_pt);
1110 return ERR_PTR(-ENODEV);
1111 }
1112
1113 pt->pt_ops = &iommu_pt_ops;
1114 pt->priv = iommu_pt;
1115 pt->fault_addr = ~0ULL;
1116 iommu_pt->rbtree = RB_ROOT;
1117
1118 if (MMU_FEATURE(mmu, KGSL_MMU_64BIT))
1119 setup_64bit_pagetable(mmu, pt, iommu_pt);
1120 else
1121 setup_32bit_pagetable(mmu, pt, iommu_pt);
1122
1123
1124 return iommu_pt;
1125}
1126
1127static void _free_pt(struct kgsl_iommu_context *ctx, struct kgsl_pagetable *pt)
1128{
1129 struct kgsl_iommu_pt *iommu_pt = pt->priv;
1130
1131 pt->pt_ops = NULL;
1132 pt->priv = NULL;
1133
1134 if (iommu_pt == NULL)
1135 return;
1136
1137 _detach_pt(iommu_pt, ctx);
1138
1139 if (iommu_pt->domain != NULL)
1140 iommu_domain_free(iommu_pt->domain);
1141 kfree(iommu_pt);
1142}
1143
Sushmita Susheelendra906564d2017-01-10 15:53:55 -07001144void _enable_gpuhtw_llc(struct kgsl_mmu *mmu, struct kgsl_iommu_pt *iommu_pt)
1145{
1146 struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
1147 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1148 int gpuhtw_llc_enable = 1;
1149 int ret;
1150
1151 /* GPU pagetable walk LLC slice not enabled */
1152 if (!adreno_dev->gpuhtw_llc_slice)
1153 return;
1154
1155 /* Domain attribute to enable system cache for GPU pagetable walks */
1156 ret = iommu_domain_set_attr(iommu_pt->domain,
1157 DOMAIN_ATTR_USE_UPSTREAM_HINT, &gpuhtw_llc_enable);
1158 /*
1159 * Warn that the system cache will not be used for GPU
1160 * pagetable walks. This is not a fatal error.
1161 */
1162 WARN_ONCE(ret,
1163 "System cache not enabled for GPU pagetable walks: %d\n", ret);
1164}
1165
Shrenuj Bansal9a0563b2017-06-15 14:45:15 -07001166static int program_smmu_aperture(unsigned int cb, unsigned int aperture_reg)
1167{
1168 struct scm_desc desc = {0};
1169
1170 desc.args[0] = 0xFFFF0000 | ((aperture_reg & 0xff) << 8) | (cb & 0xff);
1171 desc.args[1] = 0xFFFFFFFF;
1172 desc.args[2] = 0xFFFFFFFF;
1173 desc.args[3] = 0xFFFFFFFF;
1174 desc.arginfo = SCM_ARGS(4);
1175
Sunil Khatri82eb1ec2018-01-09 15:28:14 +05301176 return scm_call2(SCM_SIP_FNID(SCM_SVC_MP, CP_SMMU_APERTURE_ID), &desc);
Shrenuj Bansal9a0563b2017-06-15 14:45:15 -07001177}
1178
Shrenuj Bansala419c792016-10-20 14:05:11 -07001179static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
1180{
1181 int ret = 0;
1182 struct kgsl_iommu_pt *iommu_pt = NULL;
1183 unsigned int cb_num;
1184 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1185 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
1186
1187 iommu_pt = _alloc_pt(ctx->dev, mmu, pt);
1188
1189 if (IS_ERR(iommu_pt))
1190 return PTR_ERR(iommu_pt);
1191
1192 if (kgsl_mmu_is_perprocess(mmu)) {
1193 ret = iommu_domain_set_attr(iommu_pt->domain,
1194 DOMAIN_ATTR_PROCID, &pt->name);
1195 if (ret) {
1196 KGSL_CORE_ERR("set DOMAIN_ATTR_PROCID failed: %d\n",
1197 ret);
1198 goto done;
1199 }
1200 }
1201
Sushmita Susheelendra906564d2017-01-10 15:53:55 -07001202 _enable_gpuhtw_llc(mmu, iommu_pt);
1203
Shrenuj Bansala419c792016-10-20 14:05:11 -07001204 ret = _attach_pt(iommu_pt, ctx);
1205 if (ret)
1206 goto done;
1207
1208 iommu_set_fault_handler(iommu_pt->domain,
1209 kgsl_iommu_fault_handler, pt);
1210
1211 ret = iommu_domain_get_attr(iommu_pt->domain,
1212 DOMAIN_ATTR_CONTEXT_BANK, &cb_num);
1213 if (ret) {
Shrenuj Bansalc3b15ce2017-06-15 14:48:05 -07001214 KGSL_CORE_ERR("get DOMAIN_ATTR_CONTEXT_BANK failed: %d\n",
Shrenuj Bansala419c792016-10-20 14:05:11 -07001215 ret);
1216 goto done;
1217 }
1218
Sunil Khatri82eb1ec2018-01-09 15:28:14 +05301219 if (!MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE) &&
1220 scm_is_call_available(SCM_SVC_MP, CP_SMMU_APERTURE_ID)) {
Shrenuj Bansal9a0563b2017-06-15 14:45:15 -07001221 ret = program_smmu_aperture(cb_num, CP_APERTURE_REG);
1222 if (ret) {
1223 pr_err("SMMU aperture programming call failed with error %d\n",
1224 ret);
1225 return ret;
1226 }
1227 }
1228
Shrenuj Bansala419c792016-10-20 14:05:11 -07001229 ctx->cb_num = cb_num;
1230 ctx->regbase = iommu->regbase + KGSL_IOMMU_CB0_OFFSET
1231 + (cb_num << KGSL_IOMMU_CB_SHIFT);
1232
1233 ret = iommu_domain_get_attr(iommu_pt->domain,
1234 DOMAIN_ATTR_TTBR0, &iommu_pt->ttbr0);
1235 if (ret) {
1236 KGSL_CORE_ERR("get DOMAIN_ATTR_TTBR0 failed: %d\n",
1237 ret);
1238 goto done;
1239 }
1240 ret = iommu_domain_get_attr(iommu_pt->domain,
1241 DOMAIN_ATTR_CONTEXTIDR, &iommu_pt->contextidr);
1242 if (ret) {
1243 KGSL_CORE_ERR("get DOMAIN_ATTR_CONTEXTIDR failed: %d\n",
1244 ret);
1245 goto done;
1246 }
1247
1248 ret = kgsl_iommu_map_globals(pt);
1249
1250done:
1251 if (ret)
1252 _free_pt(ctx, pt);
1253
1254 return ret;
1255}
1256
1257static int _init_secure_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
1258{
1259 int ret = 0;
1260 struct kgsl_iommu_pt *iommu_pt = NULL;
1261 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1262 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE];
1263 int secure_vmid = VMID_CP_PIXEL;
1264 unsigned int cb_num;
1265
1266 if (!mmu->secured)
1267 return -EPERM;
1268
1269 if (!MMU_FEATURE(mmu, KGSL_MMU_HYP_SECURE_ALLOC)) {
1270 if (!kgsl_mmu_bus_secured(ctx->dev))
1271 return -EPERM;
1272 }
1273
1274 iommu_pt = _alloc_pt(ctx->dev, mmu, pt);
1275
1276 if (IS_ERR(iommu_pt))
1277 return PTR_ERR(iommu_pt);
1278
1279 ret = iommu_domain_set_attr(iommu_pt->domain,
1280 DOMAIN_ATTR_SECURE_VMID, &secure_vmid);
1281 if (ret) {
1282 KGSL_CORE_ERR("set DOMAIN_ATTR_SECURE_VMID failed: %d\n", ret);
1283 goto done;
1284 }
1285
Sushmita Susheelendra906564d2017-01-10 15:53:55 -07001286 _enable_gpuhtw_llc(mmu, iommu_pt);
1287
Shrenuj Bansala419c792016-10-20 14:05:11 -07001288 ret = _attach_pt(iommu_pt, ctx);
1289
1290 if (MMU_FEATURE(mmu, KGSL_MMU_HYP_SECURE_ALLOC))
1291 iommu_set_fault_handler(iommu_pt->domain,
1292 kgsl_iommu_fault_handler, pt);
1293
1294 ret = iommu_domain_get_attr(iommu_pt->domain,
1295 DOMAIN_ATTR_CONTEXT_BANK, &cb_num);
1296 if (ret) {
1297 KGSL_CORE_ERR("get DOMAIN_ATTR_PROCID failed: %d\n",
1298 ret);
1299 goto done;
1300 }
1301
1302 ctx->cb_num = cb_num;
1303 ctx->regbase = iommu->regbase + KGSL_IOMMU_CB0_OFFSET
1304 + (cb_num << KGSL_IOMMU_CB_SHIFT);
1305
Shrenuj Bansala419c792016-10-20 14:05:11 -07001306done:
1307 if (ret)
1308 _free_pt(ctx, pt);
1309 return ret;
1310}
1311
1312static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
1313{
1314 int ret = 0;
1315 struct kgsl_iommu_pt *iommu_pt = NULL;
1316 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1317 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
1318 int dynamic = 1;
1319 unsigned int cb_num = ctx->cb_num;
1320
1321 iommu_pt = _alloc_pt(ctx->dev, mmu, pt);
1322
1323 if (IS_ERR(iommu_pt))
1324 return PTR_ERR(iommu_pt);
1325
1326 ret = iommu_domain_set_attr(iommu_pt->domain,
1327 DOMAIN_ATTR_DYNAMIC, &dynamic);
1328 if (ret) {
1329 KGSL_CORE_ERR("set DOMAIN_ATTR_DYNAMIC failed: %d\n", ret);
1330 goto done;
1331 }
1332 ret = iommu_domain_set_attr(iommu_pt->domain,
1333 DOMAIN_ATTR_CONTEXT_BANK, &cb_num);
1334 if (ret) {
1335 KGSL_CORE_ERR("set DOMAIN_ATTR_CONTEXT_BANK failed: %d\n", ret);
1336 goto done;
1337 }
1338
1339 ret = iommu_domain_set_attr(iommu_pt->domain,
1340 DOMAIN_ATTR_PROCID, &pt->name);
1341 if (ret) {
1342 KGSL_CORE_ERR("set DOMAIN_ATTR_PROCID failed: %d\n", ret);
1343 goto done;
1344 }
1345
Sushmita Susheelendra906564d2017-01-10 15:53:55 -07001346 _enable_gpuhtw_llc(mmu, iommu_pt);
1347
Shrenuj Bansala419c792016-10-20 14:05:11 -07001348 ret = _attach_pt(iommu_pt, ctx);
1349 if (ret)
1350 goto done;
1351
1352 /* now read back the attributes needed for self programming */
1353 ret = iommu_domain_get_attr(iommu_pt->domain,
1354 DOMAIN_ATTR_TTBR0, &iommu_pt->ttbr0);
1355 if (ret) {
1356 KGSL_CORE_ERR("get DOMAIN_ATTR_TTBR0 failed: %d\n", ret);
1357 goto done;
1358 }
1359
1360 ret = iommu_domain_get_attr(iommu_pt->domain,
1361 DOMAIN_ATTR_CONTEXTIDR, &iommu_pt->contextidr);
1362 if (ret) {
1363 KGSL_CORE_ERR("get DOMAIN_ATTR_CONTEXTIDR failed: %d\n", ret);
1364 goto done;
1365 }
1366
1367 ret = kgsl_iommu_map_globals(pt);
1368
1369done:
1370 if (ret)
1371 _free_pt(ctx, pt);
1372
1373 return ret;
1374}
1375
1376/* kgsl_iommu_init_pt - Set up an IOMMU pagetable */
1377static int kgsl_iommu_init_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
1378{
1379 if (pt == NULL)
1380 return -EINVAL;
1381
1382 switch (pt->name) {
1383 case KGSL_MMU_GLOBAL_PT:
1384 return _init_global_pt(mmu, pt);
1385
1386 case KGSL_MMU_SECURE_PT:
1387 return _init_secure_pt(mmu, pt);
1388
1389 default:
1390 return _init_per_process_pt(mmu, pt);
1391 }
1392}
1393
1394static struct kgsl_pagetable *kgsl_iommu_getpagetable(struct kgsl_mmu *mmu,
1395 unsigned long name)
1396{
1397 struct kgsl_pagetable *pt;
1398
1399 if (!kgsl_mmu_is_perprocess(mmu) && (name != KGSL_MMU_SECURE_PT)) {
1400 name = KGSL_MMU_GLOBAL_PT;
1401 if (mmu->defaultpagetable != NULL)
1402 return mmu->defaultpagetable;
1403 }
1404
1405 pt = kgsl_get_pagetable(name);
1406 if (pt == NULL)
1407 pt = kgsl_mmu_createpagetableobject(mmu, name);
1408
1409 return pt;
1410}
1411
1412/*
1413 * kgsl_iommu_get_reg_ahbaddr - Returns the ahb address of the register
1414 * @mmu - Pointer to mmu structure
1415 * @id - The context ID of the IOMMU ctx
1416 * @reg - The register for which address is required
1417 *
1418 * Return - The address of register which can be used in type0 packet
1419 */
1420static unsigned int kgsl_iommu_get_reg_ahbaddr(struct kgsl_mmu *mmu,
1421 int id, unsigned int reg)
1422{
1423 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1424 struct kgsl_iommu_context *ctx = &iommu->ctx[id];
1425
1426 return ctx->gpu_offset + kgsl_iommu_reg_list[reg];
1427}
1428
1429static void _detach_context(struct kgsl_iommu_context *ctx)
1430{
1431 struct kgsl_iommu_pt *iommu_pt;
1432
1433 if (ctx->default_pt == NULL)
1434 return;
1435
1436 iommu_pt = ctx->default_pt->priv;
1437
1438 _detach_pt(iommu_pt, ctx);
1439
1440 ctx->default_pt = NULL;
1441}
1442
1443static void kgsl_iommu_close(struct kgsl_mmu *mmu)
1444{
1445 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1446 int i;
1447
1448 for (i = 0; i < KGSL_IOMMU_CONTEXT_MAX; i++)
1449 _detach_context(&iommu->ctx[i]);
1450
1451 kgsl_mmu_putpagetable(mmu->defaultpagetable);
1452 mmu->defaultpagetable = NULL;
1453
1454 kgsl_mmu_putpagetable(mmu->securepagetable);
1455 mmu->securepagetable = NULL;
1456
1457 if (iommu->regbase != NULL)
1458 iounmap(iommu->regbase);
1459
1460 kgsl_sharedmem_free(&kgsl_secure_guard_page_memdesc);
1461
1462 if (kgsl_guard_page != NULL) {
1463 __free_page(kgsl_guard_page);
1464 kgsl_guard_page = NULL;
1465 }
1466
1467 if (kgsl_dummy_page != NULL) {
1468 __free_page(kgsl_dummy_page);
1469 kgsl_dummy_page = NULL;
1470 }
1471
1472 kgsl_iommu_remove_global(mmu, &iommu->setstate);
1473 kgsl_sharedmem_free(&iommu->setstate);
1474 kgsl_cleanup_qdss_desc(mmu);
Jonathan Wicks4892d8d2017-02-24 16:21:26 -07001475 kgsl_cleanup_qtimer_desc(mmu);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001476}
1477
1478static int _setstate_alloc(struct kgsl_device *device,
1479 struct kgsl_iommu *iommu)
1480{
1481 int ret;
1482
Lynus Vaz90d98b52018-04-09 14:45:36 +05301483 kgsl_memdesc_init(device, &iommu->setstate, 0);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001484 ret = kgsl_sharedmem_alloc_contig(device, &iommu->setstate, PAGE_SIZE);
1485
1486 if (!ret) {
1487 /* Mark the setstate memory as read only */
1488 iommu->setstate.flags |= KGSL_MEMFLAGS_GPUREADONLY;
1489
1490 kgsl_sharedmem_set(device, &iommu->setstate, 0, 0, PAGE_SIZE);
1491 }
1492
1493 return ret;
1494}
1495
1496static int kgsl_iommu_init(struct kgsl_mmu *mmu)
1497{
1498 struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
1499 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1500 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
1501 int status;
1502
1503 mmu->features |= KGSL_MMU_PAGED;
1504
1505 if (ctx->name == NULL) {
1506 KGSL_CORE_ERR("dt: gfx3d0_user context bank not found\n");
1507 return -EINVAL;
1508 }
1509
1510 status = _setstate_alloc(device, iommu);
1511 if (status)
1512 return status;
1513
1514 /* check requirements for per process pagetables */
1515 if (ctx->gpu_offset == UINT_MAX) {
1516 KGSL_CORE_ERR("missing qcom,gpu-offset forces global pt\n");
1517 mmu->features |= KGSL_MMU_GLOBAL_PAGETABLE;
1518 }
1519
1520 if (iommu->version == 1 && iommu->micro_mmu_ctrl == UINT_MAX) {
1521 KGSL_CORE_ERR(
1522 "missing qcom,micro-mmu-control forces global pt\n");
1523 mmu->features |= KGSL_MMU_GLOBAL_PAGETABLE;
1524 }
1525
1526 /* Check to see if we need to do the IOMMU sync dance */
1527 need_iommu_sync = of_property_read_bool(device->pdev->dev.of_node,
1528 "qcom,gpu-quirk-iommu-sync");
1529
1530 iommu->regbase = ioremap(iommu->regstart, iommu->regsize);
1531 if (iommu->regbase == NULL) {
1532 KGSL_CORE_ERR("Could not map IOMMU registers 0x%lx:0x%x\n",
1533 iommu->regstart, iommu->regsize);
1534 status = -ENOMEM;
1535 goto done;
1536 }
1537
1538 if (addr_entry_cache == NULL) {
1539 addr_entry_cache = KMEM_CACHE(kgsl_iommu_addr_entry, 0);
1540 if (addr_entry_cache == NULL) {
1541 status = -ENOMEM;
1542 goto done;
1543 }
1544 }
1545
1546 kgsl_iommu_add_global(mmu, &iommu->setstate, "setstate");
1547 kgsl_setup_qdss_desc(device);
Jonathan Wicks4892d8d2017-02-24 16:21:26 -07001548 kgsl_setup_qtimer_desc(device);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001549
Harshdeep Dhatt1f408332017-03-27 11:35:13 -06001550 if (!mmu->secured)
1551 goto done;
1552
1553 mmu->securepagetable = kgsl_mmu_getpagetable(mmu,
1554 KGSL_MMU_SECURE_PT);
1555 if (IS_ERR(mmu->securepagetable)) {
1556 status = PTR_ERR(mmu->securepagetable);
1557 mmu->securepagetable = NULL;
1558 } else if (mmu->securepagetable == NULL) {
1559 status = -ENOMEM;
1560 }
1561
Shrenuj Bansala419c792016-10-20 14:05:11 -07001562done:
1563 if (status)
1564 kgsl_iommu_close(mmu);
1565
1566 return status;
1567}
1568
1569static int _setup_user_context(struct kgsl_mmu *mmu)
1570{
1571 int ret = 0;
1572 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1573 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
1574 struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
1575 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1576 struct kgsl_iommu_pt *iommu_pt = NULL;
1577 unsigned int sctlr_val;
1578
1579 if (mmu->defaultpagetable == NULL) {
1580 mmu->defaultpagetable = kgsl_mmu_getpagetable(mmu,
1581 KGSL_MMU_GLOBAL_PT);
1582 /* if we don't have a default pagetable, nothing will work */
1583 if (IS_ERR(mmu->defaultpagetable)) {
1584 ret = PTR_ERR(mmu->defaultpagetable);
1585 mmu->defaultpagetable = NULL;
1586 return ret;
Lynus Vaza2e31112017-04-17 18:29:58 +05301587 } else if (mmu->defaultpagetable == NULL) {
1588 return -ENOMEM;
Shrenuj Bansala419c792016-10-20 14:05:11 -07001589 }
1590 }
1591
1592 iommu_pt = mmu->defaultpagetable->priv;
1593 if (iommu_pt == NULL)
1594 return -ENODEV;
1595
1596 ret = _attach_pt(iommu_pt, ctx);
1597 if (ret)
1598 return ret;
1599
1600 ctx->default_pt = mmu->defaultpagetable;
1601
1602 kgsl_iommu_enable_clk(mmu);
1603
1604 sctlr_val = KGSL_IOMMU_GET_CTX_REG(ctx, SCTLR);
1605
1606 /*
1607 * If pagefault policy is GPUHALT_ENABLE,
1608 * 1) Program CFCFG to 1 to enable STALL mode
1609 * 2) Program HUPCF to 0 (Stall or terminate subsequent
1610 * transactions in the presence of an outstanding fault)
1611 * else
1612 * 1) Program CFCFG to 0 to disable STALL mode (0=Terminate)
1613 * 2) Program HUPCF to 1 (Process subsequent transactions
1614 * independently of any outstanding fault)
1615 */
1616
1617 if (test_bit(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE,
1618 &adreno_dev->ft_pf_policy)) {
1619 sctlr_val |= (0x1 << KGSL_IOMMU_SCTLR_CFCFG_SHIFT);
1620 sctlr_val &= ~(0x1 << KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
1621 } else {
1622 sctlr_val &= ~(0x1 << KGSL_IOMMU_SCTLR_CFCFG_SHIFT);
1623 sctlr_val |= (0x1 << KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
1624 }
1625 KGSL_IOMMU_SET_CTX_REG(ctx, SCTLR, sctlr_val);
1626 kgsl_iommu_disable_clk(mmu);
1627
1628 return 0;
1629}
1630
1631static int _setup_secure_context(struct kgsl_mmu *mmu)
1632{
1633 int ret;
1634 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1635 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE];
1636 unsigned int cb_num;
1637
1638 struct kgsl_iommu_pt *iommu_pt;
1639
1640 if (ctx->dev == NULL || !mmu->secured)
1641 return 0;
1642
Harshdeep Dhatt1f408332017-03-27 11:35:13 -06001643 if (mmu->securepagetable == NULL)
1644 return -ENOMEM;
1645
Shrenuj Bansala419c792016-10-20 14:05:11 -07001646 iommu_pt = mmu->securepagetable->priv;
1647
1648 ret = _attach_pt(iommu_pt, ctx);
1649 if (ret)
1650 goto done;
1651
1652 ctx->default_pt = mmu->securepagetable;
1653
1654 ret = iommu_domain_get_attr(iommu_pt->domain, DOMAIN_ATTR_CONTEXT_BANK,
1655 &cb_num);
1656 if (ret) {
1657 KGSL_CORE_ERR("get CONTEXT_BANK attr, err %d\n", ret);
1658 goto done;
1659 }
1660 ctx->cb_num = cb_num;
1661done:
1662 if (ret)
1663 _detach_context(ctx);
1664 return ret;
1665}
1666
1667static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt);
1668
1669static int kgsl_iommu_start(struct kgsl_mmu *mmu)
1670{
1671 int status;
1672 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1673
1674 status = _setup_user_context(mmu);
1675 if (status)
1676 return status;
1677
1678 status = _setup_secure_context(mmu);
1679 if (status) {
1680 _detach_context(&iommu->ctx[KGSL_IOMMU_CONTEXT_USER]);
1681 return status;
1682 }
1683
1684 /* Make sure the hardware is programmed to the default pagetable */
1685 return kgsl_iommu_set_pt(mmu, mmu->defaultpagetable);
1686}
1687
1688static int
1689kgsl_iommu_unmap_offset(struct kgsl_pagetable *pt,
1690 struct kgsl_memdesc *memdesc, uint64_t addr,
1691 uint64_t offset, uint64_t size)
1692{
1693 if (size == 0 || (size + offset) > kgsl_memdesc_footprint(memdesc))
1694 return -EINVAL;
1695 /*
1696 * All GPU addresses as assigned are page aligned, but some
1697 * functions perturb the gpuaddr with an offset, so apply the
1698 * mask here to make sure we have the right address.
1699 */
1700
1701 addr = PAGE_ALIGN(addr);
1702 if (addr == 0)
1703 return -EINVAL;
1704
Carter Coopera1c7cce2017-12-15 13:29:29 -07001705 return _iommu_unmap_sync_pc(pt, addr + offset, size);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001706}
1707
1708static int
1709kgsl_iommu_unmap(struct kgsl_pagetable *pt, struct kgsl_memdesc *memdesc)
1710{
1711 if (memdesc->size == 0 || memdesc->gpuaddr == 0)
1712 return -EINVAL;
1713
1714 return kgsl_iommu_unmap_offset(pt, memdesc, memdesc->gpuaddr, 0,
1715 kgsl_memdesc_footprint(memdesc));
1716}
1717
1718/**
1719 * _iommu_map_guard_page - Map iommu guard page
1720 * @pt - Pointer to kgsl pagetable structure
1721 * @memdesc - memdesc to add guard page
1722 * @gpuaddr - GPU addr of guard page
1723 * @protflags - flags for mapping
1724 *
1725 * Return 0 on success, error on map fail
1726 */
1727static int _iommu_map_guard_page(struct kgsl_pagetable *pt,
1728 struct kgsl_memdesc *memdesc,
1729 uint64_t gpuaddr,
1730 unsigned int protflags)
1731{
1732 phys_addr_t physaddr;
1733
1734 if (!kgsl_memdesc_has_guard_page(memdesc))
1735 return 0;
1736
1737 /*
1738 * Allocate guard page for secure buffers.
1739 * This has to be done after we attach a smmu pagetable.
1740 * Allocate the guard page when first secure buffer is.
1741 * mapped to save 1MB of memory if CPZ is not used.
1742 */
1743 if (kgsl_memdesc_is_secured(memdesc)) {
1744 struct scatterlist *sg;
1745 unsigned int sgp_size = pt->mmu->secure_align_mask + 1;
1746
1747 if (!kgsl_secure_guard_page_memdesc.sgt) {
1748 if (kgsl_allocate_user(KGSL_MMU_DEVICE(pt->mmu),
1749 &kgsl_secure_guard_page_memdesc,
1750 sgp_size, KGSL_MEMFLAGS_SECURE)) {
1751 KGSL_CORE_ERR(
1752 "Secure guard page alloc failed\n");
1753 return -ENOMEM;
1754 }
1755 }
1756
1757 sg = kgsl_secure_guard_page_memdesc.sgt->sgl;
1758 physaddr = page_to_phys(sg_page(sg));
1759 } else {
1760 if (kgsl_guard_page == NULL) {
1761 kgsl_guard_page = alloc_page(GFP_KERNEL | __GFP_ZERO |
1762 __GFP_NORETRY | __GFP_HIGHMEM);
1763 if (kgsl_guard_page == NULL)
1764 return -ENOMEM;
1765 }
1766
1767 physaddr = page_to_phys(kgsl_guard_page);
1768 }
1769
Carter Coopera1c7cce2017-12-15 13:29:29 -07001770 return _iommu_map_sync_pc(pt, gpuaddr, physaddr,
Shrenuj Bansala419c792016-10-20 14:05:11 -07001771 kgsl_memdesc_guard_page_size(memdesc),
1772 protflags & ~IOMMU_WRITE);
1773}
1774
1775static unsigned int _get_protection_flags(struct kgsl_memdesc *memdesc)
1776{
Sushmita Susheelendra7f66cf72016-09-12 11:04:43 -06001777 unsigned int flags = IOMMU_READ | IOMMU_WRITE |
1778 IOMMU_NOEXEC | IOMMU_USE_UPSTREAM_HINT;
Shrenuj Bansala419c792016-10-20 14:05:11 -07001779
1780 if (memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY)
1781 flags &= ~IOMMU_WRITE;
1782
1783 if (memdesc->priv & KGSL_MEMDESC_PRIVILEGED)
1784 flags |= IOMMU_PRIV;
1785
Shrenuj Bansal4fd6a562017-08-07 15:12:54 -07001786 if (memdesc->flags & KGSL_MEMFLAGS_IOCOHERENT)
1787 flags |= IOMMU_CACHE;
1788
Shrenuj Bansala419c792016-10-20 14:05:11 -07001789 return flags;
1790}
1791
1792static int
1793kgsl_iommu_map(struct kgsl_pagetable *pt,
1794 struct kgsl_memdesc *memdesc)
1795{
1796 int ret;
1797 uint64_t addr = memdesc->gpuaddr;
1798 uint64_t size = memdesc->size;
1799 unsigned int flags = _get_protection_flags(memdesc);
1800 struct sg_table *sgt = NULL;
1801
1802 /*
1803 * For paged memory allocated through kgsl, memdesc->pages is not NULL.
1804 * Allocate sgt here just for its map operation. Contiguous memory
1805 * already has its sgt, so no need to allocate it here.
1806 */
1807 if (memdesc->pages != NULL)
1808 sgt = kgsl_alloc_sgt_from_pages(memdesc);
1809 else
1810 sgt = memdesc->sgt;
1811
1812 if (IS_ERR(sgt))
1813 return PTR_ERR(sgt);
1814
Carter Coopera1c7cce2017-12-15 13:29:29 -07001815 ret = _iommu_map_sg_sync_pc(pt, addr, sgt->sgl, sgt->nents, flags);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001816 if (ret)
1817 goto done;
1818
1819 ret = _iommu_map_guard_page(pt, memdesc, addr + size, flags);
1820 if (ret)
Carter Coopera1c7cce2017-12-15 13:29:29 -07001821 _iommu_unmap_sync_pc(pt, addr, size);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001822
1823done:
1824 if (memdesc->pages != NULL)
1825 kgsl_free_sgt(sgt);
1826
1827 return ret;
1828}
1829
1830static int kgsl_iommu_sparse_dummy_map(struct kgsl_pagetable *pt,
1831 struct kgsl_memdesc *memdesc, uint64_t offset, uint64_t size)
1832{
1833 int ret = 0, i;
1834 struct page **pages = NULL;
1835 struct sg_table sgt;
1836 int count = size >> PAGE_SHIFT;
1837
1838 /* verify the offset is within our range */
1839 if (size + offset > memdesc->size)
1840 return -EINVAL;
1841
1842 if (kgsl_dummy_page == NULL) {
1843 kgsl_dummy_page = alloc_page(GFP_KERNEL | __GFP_ZERO |
1844 __GFP_HIGHMEM);
1845 if (kgsl_dummy_page == NULL)
1846 return -ENOMEM;
1847 }
1848
1849 pages = kcalloc(count, sizeof(struct page *), GFP_KERNEL);
1850 if (pages == NULL)
1851 return -ENOMEM;
1852
1853 for (i = 0; i < count; i++)
1854 pages[i] = kgsl_dummy_page;
1855
1856 ret = sg_alloc_table_from_pages(&sgt, pages, count,
1857 0, size, GFP_KERNEL);
1858 if (ret == 0) {
1859 ret = _iommu_map_sg_sync_pc(pt, memdesc->gpuaddr + offset,
Carter Coopera1c7cce2017-12-15 13:29:29 -07001860 sgt.sgl, sgt.nents, IOMMU_READ | IOMMU_NOEXEC);
Shrenuj Bansala419c792016-10-20 14:05:11 -07001861 sg_free_table(&sgt);
1862 }
1863
1864 kfree(pages);
1865
1866 return ret;
1867}
1868
1869static int _map_to_one_page(struct kgsl_pagetable *pt, uint64_t addr,
1870 struct kgsl_memdesc *memdesc, uint64_t physoffset,
1871 uint64_t size, unsigned int map_flags)
1872{
1873 int ret = 0, i;
1874 int pg_sz = kgsl_memdesc_get_pagesize(memdesc);
1875 int count = size >> PAGE_SHIFT;
1876 struct page *page = NULL;
1877 struct page **pages = NULL;
1878 struct sg_page_iter sg_iter;
1879 struct sg_table sgt;
1880
1881 /* Find our physaddr offset addr */
1882 if (memdesc->pages != NULL)
1883 page = memdesc->pages[physoffset >> PAGE_SHIFT];
1884 else {
1885 for_each_sg_page(memdesc->sgt->sgl, &sg_iter,
1886 memdesc->sgt->nents, physoffset >> PAGE_SHIFT) {
1887 page = sg_page_iter_page(&sg_iter);
1888 break;
1889 }
1890 }
1891
1892 if (page == NULL)
1893 return -EINVAL;
1894
1895 pages = kcalloc(count, sizeof(struct page *), GFP_KERNEL);
1896 if (pages == NULL)
1897 return -ENOMEM;
1898
1899 for (i = 0; i < count; i++) {
1900 if (pg_sz != PAGE_SIZE) {
1901 struct page *tmp_page = page;
1902 int j;
1903
1904 for (j = 0; j < 16; j++, tmp_page += PAGE_SIZE)
1905 pages[i++] = tmp_page;
1906 } else
1907 pages[i] = page;
1908 }
1909
1910 ret = sg_alloc_table_from_pages(&sgt, pages, count,
1911 0, size, GFP_KERNEL);
1912 if (ret == 0) {
Carter Coopera1c7cce2017-12-15 13:29:29 -07001913 ret = _iommu_map_sg_sync_pc(pt, addr, sgt.sgl,
Shrenuj Bansala419c792016-10-20 14:05:11 -07001914 sgt.nents, map_flags);
1915 sg_free_table(&sgt);
1916 }
1917
1918 kfree(pages);
1919
1920 return ret;
1921}
1922
1923static int kgsl_iommu_map_offset(struct kgsl_pagetable *pt,
1924 uint64_t virtaddr, uint64_t virtoffset,
1925 struct kgsl_memdesc *memdesc, uint64_t physoffset,
1926 uint64_t size, uint64_t feature_flag)
1927{
1928 int pg_sz;
1929 unsigned int protflags = _get_protection_flags(memdesc);
1930 int ret;
1931 struct sg_table *sgt = NULL;
1932
1933 pg_sz = kgsl_memdesc_get_pagesize(memdesc);
1934 if (!IS_ALIGNED(virtaddr | virtoffset | physoffset | size, pg_sz))
1935 return -EINVAL;
1936
1937 if (size == 0)
1938 return -EINVAL;
1939
1940 if (!(feature_flag & KGSL_SPARSE_BIND_MULTIPLE_TO_PHYS) &&
1941 size + physoffset > kgsl_memdesc_footprint(memdesc))
1942 return -EINVAL;
1943
1944 /*
1945 * For paged memory allocated through kgsl, memdesc->pages is not NULL.
1946 * Allocate sgt here just for its map operation. Contiguous memory
1947 * already has its sgt, so no need to allocate it here.
1948 */
1949 if (memdesc->pages != NULL)
1950 sgt = kgsl_alloc_sgt_from_pages(memdesc);
1951 else
1952 sgt = memdesc->sgt;
1953
1954 if (IS_ERR(sgt))
1955 return PTR_ERR(sgt);
1956
1957 if (feature_flag & KGSL_SPARSE_BIND_MULTIPLE_TO_PHYS)
1958 ret = _map_to_one_page(pt, virtaddr + virtoffset,
1959 memdesc, physoffset, size, protflags);
1960 else
1961 ret = _iommu_map_sg_offset_sync_pc(pt, virtaddr + virtoffset,
Carter Coopera1c7cce2017-12-15 13:29:29 -07001962 sgt->sgl, sgt->nents,
Shrenuj Bansala419c792016-10-20 14:05:11 -07001963 physoffset, size, protflags);
1964
1965 if (memdesc->pages != NULL)
1966 kgsl_free_sgt(sgt);
1967
1968 return ret;
1969}
1970
1971/* This function must be called with context bank attached */
1972static void kgsl_iommu_clear_fsr(struct kgsl_mmu *mmu)
1973{
1974 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
1975 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
1976 unsigned int sctlr_val;
1977
1978 if (ctx->default_pt != NULL) {
1979 kgsl_iommu_enable_clk(mmu);
1980 KGSL_IOMMU_SET_CTX_REG(ctx, FSR, 0xffffffff);
1981 /*
1982 * Re-enable context fault interrupts after clearing
1983 * FSR to prevent the interrupt from firing repeatedly
1984 */
1985 sctlr_val = KGSL_IOMMU_GET_CTX_REG(ctx, SCTLR);
1986 sctlr_val |= (0x1 << KGSL_IOMMU_SCTLR_CFIE_SHIFT);
1987 KGSL_IOMMU_SET_CTX_REG(ctx, SCTLR, sctlr_val);
1988 /*
1989 * Make sure the above register writes
1990 * are not reordered across the barrier
1991 * as we use writel_relaxed to write them
1992 */
1993 wmb();
1994 kgsl_iommu_disable_clk(mmu);
1995 }
1996}
1997
1998static void kgsl_iommu_pagefault_resume(struct kgsl_mmu *mmu)
1999{
2000 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
2001 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
2002
2003 if (ctx->default_pt != NULL && ctx->fault) {
2004 /*
2005 * Write 1 to RESUME.TnR to terminate the
2006 * stalled transaction.
2007 */
2008 KGSL_IOMMU_SET_CTX_REG(ctx, RESUME, 1);
2009 /*
2010 * Make sure the above register writes
2011 * are not reordered across the barrier
2012 * as we use writel_relaxed to write them
2013 */
2014 wmb();
2015 ctx->fault = 0;
2016 }
2017}
2018
2019static void kgsl_iommu_stop(struct kgsl_mmu *mmu)
2020{
2021 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
2022 int i;
2023
2024 /*
2025 * If the iommu supports retention, we don't need
2026 * to detach when stopping.
2027 */
2028 if (!MMU_FEATURE(mmu, KGSL_MMU_RETENTION)) {
2029 for (i = 0; i < KGSL_IOMMU_CONTEXT_MAX; i++)
2030 _detach_context(&iommu->ctx[i]);
2031 }
2032}
2033
2034static u64
2035kgsl_iommu_get_current_ttbr0(struct kgsl_mmu *mmu)
2036{
2037 u64 val;
2038 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
2039 /*
2040 * We cannot enable or disable the clocks in interrupt context, this
2041 * function is called from interrupt context if there is an axi error
2042 */
2043 if (in_interrupt())
2044 return 0;
2045
2046 kgsl_iommu_enable_clk(mmu);
2047 val = KGSL_IOMMU_GET_CTX_REG_Q(&iommu->ctx[KGSL_IOMMU_CONTEXT_USER],
2048 TTBR0);
2049 kgsl_iommu_disable_clk(mmu);
2050 return val;
2051}
2052
2053/*
2054 * kgsl_iommu_set_pt - Change the IOMMU pagetable of the primary context bank
2055 * @mmu - Pointer to mmu structure
2056 * @pt - Pagetable to switch to
2057 *
2058 * Set the new pagetable for the IOMMU by doing direct register writes
2059 * to the IOMMU registers through the cpu
2060 *
2061 * Return - void
2062 */
2063static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
2064{
2065 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
2066 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
2067 uint64_t ttbr0, temp;
2068 unsigned int contextidr;
2069 unsigned long wait_for_flush;
2070
2071 if ((pt != mmu->defaultpagetable) && !kgsl_mmu_is_perprocess(mmu))
2072 return 0;
2073
2074 kgsl_iommu_enable_clk(mmu);
2075
2076 ttbr0 = kgsl_mmu_pagetable_get_ttbr0(pt);
2077 contextidr = kgsl_mmu_pagetable_get_contextidr(pt);
2078
2079 KGSL_IOMMU_SET_CTX_REG_Q(ctx, TTBR0, ttbr0);
2080 KGSL_IOMMU_SET_CTX_REG(ctx, CONTEXTIDR, contextidr);
2081
2082 /* memory barrier before reading TTBR0 register */
2083 mb();
2084 temp = KGSL_IOMMU_GET_CTX_REG_Q(ctx, TTBR0);
2085
2086 KGSL_IOMMU_SET_CTX_REG(ctx, TLBIALL, 1);
2087 /* make sure the TBLI write completes before we wait */
2088 mb();
2089 /*
2090 * Wait for flush to complete by polling the flush
2091 * status bit of TLBSTATUS register for not more than
2092 * 2 s. After 2s just exit, at that point the SMMU h/w
2093 * may be stuck and will eventually cause GPU to hang
2094 * or bring the system down.
2095 */
2096 wait_for_flush = jiffies + msecs_to_jiffies(2000);
2097 KGSL_IOMMU_SET_CTX_REG(ctx, TLBSYNC, 0);
2098 while (KGSL_IOMMU_GET_CTX_REG(ctx, TLBSTATUS) &
2099 (KGSL_IOMMU_CTX_TLBSTATUS_SACTIVE)) {
2100 if (time_after(jiffies, wait_for_flush)) {
2101 KGSL_DRV_WARN(KGSL_MMU_DEVICE(mmu),
2102 "Wait limit reached for IOMMU tlb flush\n");
2103 break;
2104 }
2105 cpu_relax();
2106 }
2107
2108 kgsl_iommu_disable_clk(mmu);
2109 return 0;
2110}
2111
2112/*
2113 * kgsl_iommu_set_pf_policy() - Set the pagefault policy for IOMMU
2114 * @mmu: Pointer to mmu structure
2115 * @pf_policy: The pagefault polict to set
2116 *
2117 * Check if the new policy indicated by pf_policy is same as current
2118 * policy, if same then return else set the policy
2119 */
2120static int kgsl_iommu_set_pf_policy(struct kgsl_mmu *mmu,
2121 unsigned long pf_policy)
2122{
2123 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
2124 struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
2125 struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
2126 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
2127
2128 if ((adreno_dev->ft_pf_policy &
2129 BIT(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE)) ==
2130 (pf_policy & BIT(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE)))
2131 return 0;
2132
2133 /* If not attached, policy will be updated during the next attach */
2134 if (ctx->default_pt != NULL) {
2135 unsigned int sctlr_val;
2136
2137 kgsl_iommu_enable_clk(mmu);
2138
2139 sctlr_val = KGSL_IOMMU_GET_CTX_REG(ctx, SCTLR);
2140
2141 if (test_bit(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE, &pf_policy)) {
2142 sctlr_val |= (0x1 << KGSL_IOMMU_SCTLR_CFCFG_SHIFT);
2143 sctlr_val &= ~(0x1 << KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
2144 } else {
2145 sctlr_val &= ~(0x1 << KGSL_IOMMU_SCTLR_CFCFG_SHIFT);
2146 sctlr_val |= (0x1 << KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
2147 }
2148
2149 KGSL_IOMMU_SET_CTX_REG(ctx, SCTLR, sctlr_val);
2150
2151 kgsl_iommu_disable_clk(mmu);
2152 }
2153
2154 return 0;
2155}
2156
2157static struct kgsl_protected_registers *
2158kgsl_iommu_get_prot_regs(struct kgsl_mmu *mmu)
2159{
2160 struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
2161
2162 return &iommu->protect;
2163}
2164
2165static struct kgsl_iommu_addr_entry *_find_gpuaddr(
2166 struct kgsl_pagetable *pagetable, uint64_t gpuaddr)
2167{
2168 struct kgsl_iommu_pt *pt = pagetable->priv;
2169 struct rb_node *node = pt->rbtree.rb_node;
2170
2171 while (node != NULL) {
2172 struct kgsl_iommu_addr_entry *entry = rb_entry(node,
2173 struct kgsl_iommu_addr_entry, node);
2174
2175 if (gpuaddr < entry->base)
2176 node = node->rb_left;
2177 else if (gpuaddr > entry->base)
2178 node = node->rb_right;
2179 else
2180 return entry;
2181 }
2182
2183 return NULL;
2184}
2185
2186static int _remove_gpuaddr(struct kgsl_pagetable *pagetable,
2187 uint64_t gpuaddr)
2188{
2189 struct kgsl_iommu_pt *pt = pagetable->priv;
2190 struct kgsl_iommu_addr_entry *entry;
2191
2192 entry = _find_gpuaddr(pagetable, gpuaddr);
2193
2194 if (entry != NULL) {
2195 rb_erase(&entry->node, &pt->rbtree);
2196 kmem_cache_free(addr_entry_cache, entry);
2197 return 0;
2198 }
2199
2200 WARN(1, "Couldn't remove gpuaddr: 0x%llx\n", gpuaddr);
2201 return -ENOMEM;
2202}
2203
2204static int _insert_gpuaddr(struct kgsl_pagetable *pagetable,
2205 uint64_t gpuaddr, uint64_t size)
2206{
2207 struct kgsl_iommu_pt *pt = pagetable->priv;
2208 struct rb_node **node, *parent = NULL;
2209 struct kgsl_iommu_addr_entry *new =
2210 kmem_cache_alloc(addr_entry_cache, GFP_ATOMIC);
2211
2212 if (new == NULL)
2213 return -ENOMEM;
2214
2215 new->base = gpuaddr;
2216 new->size = size;
2217
2218 node = &pt->rbtree.rb_node;
2219
2220 while (*node != NULL) {
2221 struct kgsl_iommu_addr_entry *this;
2222
2223 parent = *node;
2224 this = rb_entry(parent, struct kgsl_iommu_addr_entry, node);
2225
2226 if (new->base < this->base)
2227 node = &parent->rb_left;
2228 else if (new->base > this->base)
2229 node = &parent->rb_right;
2230 else {
2231 /* Duplicate entry */
2232 WARN(1, "duplicate gpuaddr: 0x%llx\n", gpuaddr);
2233 return -EEXIST;
2234 }
2235 }
2236
2237 rb_link_node(&new->node, parent, node);
2238 rb_insert_color(&new->node, &pt->rbtree);
2239
2240 return 0;
2241}
2242
2243static uint64_t _get_unmapped_area(struct kgsl_pagetable *pagetable,
2244 uint64_t bottom, uint64_t top, uint64_t size,
2245 uint64_t align)
2246{
2247 struct kgsl_iommu_pt *pt = pagetable->priv;
2248 struct rb_node *node = rb_first(&pt->rbtree);
2249 uint64_t start;
2250
2251 bottom = ALIGN(bottom, align);
2252 start = bottom;
2253
2254 while (node != NULL) {
2255 uint64_t gap;
2256 struct kgsl_iommu_addr_entry *entry = rb_entry(node,
2257 struct kgsl_iommu_addr_entry, node);
2258
2259 /*
2260 * Skip any entries that are outside of the range, but make sure
2261 * to account for some that might straddle the lower bound
2262 */
2263 if (entry->base < bottom) {
2264 if (entry->base + entry->size > bottom)
2265 start = ALIGN(entry->base + entry->size, align);
2266 node = rb_next(node);
2267 continue;
2268 }
2269
2270 /* Stop if we went over the top */
2271 if (entry->base >= top)
2272 break;
2273
2274 /* Make sure there is a gap to consider */
2275 if (start < entry->base) {
2276 gap = entry->base - start;
2277
2278 if (gap >= size)
2279 return start;
2280 }
2281
2282 /* Stop if there is no more room in the region */
2283 if (entry->base + entry->size >= top)
2284 return (uint64_t) -ENOMEM;
2285
2286 /* Start the next cycle at the end of the current entry */
2287 start = ALIGN(entry->base + entry->size, align);
2288 node = rb_next(node);
2289 }
2290
2291 if (start + size <= top)
2292 return start;
2293
2294 return (uint64_t) -ENOMEM;
2295}
2296
2297static uint64_t _get_unmapped_area_topdown(struct kgsl_pagetable *pagetable,
2298 uint64_t bottom, uint64_t top, uint64_t size,
2299 uint64_t align)
2300{
2301 struct kgsl_iommu_pt *pt = pagetable->priv;
2302 struct rb_node *node = rb_last(&pt->rbtree);
2303 uint64_t end = top;
2304 uint64_t mask = ~(align - 1);
2305 struct kgsl_iommu_addr_entry *entry;
2306
2307 /* Make sure that the bottom is correctly aligned */
2308 bottom = ALIGN(bottom, align);
2309
2310 /* Make sure the requested size will fit in the range */
2311 if (size > (top - bottom))
2312 return -ENOMEM;
2313
2314 /* Walk back through the list to find the highest entry in the range */
2315 for (node = rb_last(&pt->rbtree); node != NULL; node = rb_prev(node)) {
2316 entry = rb_entry(node, struct kgsl_iommu_addr_entry, node);
2317 if (entry->base < top)
2318 break;
2319 }
2320
2321 while (node != NULL) {
2322 uint64_t offset;
2323
2324 entry = rb_entry(node, struct kgsl_iommu_addr_entry, node);
2325
2326 /* If the entire entry is below the range the search is over */
2327 if ((entry->base + entry->size) < bottom)
2328 break;
2329
2330 /* Get the top of the entry properly aligned */
2331 offset = ALIGN(entry->base + entry->size, align);
2332
2333 /*
2334 * Try to allocate the memory from the top of the gap,
2335 * making sure that it fits between the top of this entry and
2336 * the bottom of the previous one
2337 */
2338
2339 if ((end > size) && (offset < end)) {
2340 uint64_t chunk = (end - size) & mask;
2341
2342 if (chunk >= offset)
2343 return chunk;
2344 }
2345
2346 /*
2347 * If we get here and the current entry is outside of the range
2348 * then we are officially out of room
2349 */
2350
2351 if (entry->base < bottom)
2352 return (uint64_t) -ENOMEM;
2353
2354 /* Set the top of the gap to the current entry->base */
2355 end = entry->base;
2356
2357 /* And move on to the next lower entry */
2358 node = rb_prev(node);
2359 }
2360
2361 /* If we get here then there are no more entries in the region */
2362 if ((end > size) && (((end - size) & mask) >= bottom))
2363 return (end - size) & mask;
2364
2365 return (uint64_t) -ENOMEM;
2366}
2367
2368static uint64_t kgsl_iommu_find_svm_region(struct kgsl_pagetable *pagetable,
2369 uint64_t start, uint64_t end, uint64_t size,
2370 uint64_t alignment)
2371{
2372 uint64_t addr;
2373
2374 /* Avoid black holes */
2375 if (WARN(end <= start, "Bad search range: 0x%llx-0x%llx", start, end))
2376 return (uint64_t) -EINVAL;
2377
2378 spin_lock(&pagetable->lock);
2379 addr = _get_unmapped_area_topdown(pagetable,
2380 start, end, size, alignment);
2381 spin_unlock(&pagetable->lock);
2382 return addr;
2383}
2384
2385static int kgsl_iommu_set_svm_region(struct kgsl_pagetable *pagetable,
2386 uint64_t gpuaddr, uint64_t size)
2387{
2388 int ret = -ENOMEM;
2389 struct kgsl_iommu_pt *pt = pagetable->priv;
2390 struct rb_node *node;
2391
2392 /* Make sure the requested address doesn't fall in the global range */
Deepak Kumar756d6a92017-11-28 16:58:29 +05302393 if (ADDR_IN_GLOBAL(pagetable->mmu, gpuaddr) ||
2394 ADDR_IN_GLOBAL(pagetable->mmu, gpuaddr + size))
Shrenuj Bansala419c792016-10-20 14:05:11 -07002395 return -ENOMEM;
2396
2397 spin_lock(&pagetable->lock);
2398 node = pt->rbtree.rb_node;
2399
2400 while (node != NULL) {
2401 uint64_t start, end;
2402 struct kgsl_iommu_addr_entry *entry = rb_entry(node,
2403 struct kgsl_iommu_addr_entry, node);
2404
2405 start = entry->base;
2406 end = entry->base + entry->size;
2407
2408 if (gpuaddr + size <= start)
2409 node = node->rb_left;
2410 else if (end <= gpuaddr)
2411 node = node->rb_right;
2412 else
2413 goto out;
2414 }
2415
2416 ret = _insert_gpuaddr(pagetable, gpuaddr, size);
2417out:
2418 spin_unlock(&pagetable->lock);
2419 return ret;
2420}
2421
2422
2423static int kgsl_iommu_get_gpuaddr(struct kgsl_pagetable *pagetable,
2424 struct kgsl_memdesc *memdesc)
2425{
2426 struct kgsl_iommu_pt *pt = pagetable->priv;
2427 int ret = 0;
2428 uint64_t addr, start, end, size;
2429 unsigned int align;
2430
2431 if (WARN_ON(kgsl_memdesc_use_cpu_map(memdesc)))
2432 return -EINVAL;
2433
2434 if (memdesc->flags & KGSL_MEMFLAGS_SECURE &&
2435 pagetable->name != KGSL_MMU_SECURE_PT)
2436 return -EINVAL;
2437
2438 size = kgsl_memdesc_footprint(memdesc);
2439
2440 align = 1 << kgsl_memdesc_get_align(memdesc);
2441
2442 if (memdesc->flags & KGSL_MEMFLAGS_FORCE_32BIT) {
2443 start = pt->compat_va_start;
2444 end = pt->compat_va_end;
2445 } else {
2446 start = pt->va_start;
2447 end = pt->va_end;
2448 }
2449
Harshdeep Dhatt1f408332017-03-27 11:35:13 -06002450 /*
2451 * When mapping secure buffers, adjust the start of the va range
2452 * to the end of secure global buffers.
2453 */
2454 if (kgsl_memdesc_is_secured(memdesc))
2455 start += secure_global_size;
2456
Shrenuj Bansala419c792016-10-20 14:05:11 -07002457 spin_lock(&pagetable->lock);
2458
2459 addr = _get_unmapped_area(pagetable, start, end, size, align);
2460
2461 if (addr == (uint64_t) -ENOMEM) {
2462 ret = -ENOMEM;
2463 goto out;
2464 }
2465
2466 ret = _insert_gpuaddr(pagetable, addr, size);
2467 if (ret == 0) {
2468 memdesc->gpuaddr = addr;
2469 memdesc->pagetable = pagetable;
2470 }
2471
2472out:
2473 spin_unlock(&pagetable->lock);
2474 return ret;
2475}
2476
2477static void kgsl_iommu_put_gpuaddr(struct kgsl_memdesc *memdesc)
2478{
2479 if (memdesc->pagetable == NULL)
2480 return;
2481
2482 spin_lock(&memdesc->pagetable->lock);
2483
2484 _remove_gpuaddr(memdesc->pagetable, memdesc->gpuaddr);
2485
2486 spin_unlock(&memdesc->pagetable->lock);
2487}
2488
2489static int kgsl_iommu_svm_range(struct kgsl_pagetable *pagetable,
2490 uint64_t *lo, uint64_t *hi, uint64_t memflags)
2491{
2492 struct kgsl_iommu_pt *pt = pagetable->priv;
2493 bool gpu_compat = (memflags & KGSL_MEMFLAGS_FORCE_32BIT) != 0;
2494
2495 if (lo != NULL)
2496 *lo = gpu_compat ? pt->compat_va_start : pt->svm_start;
2497 if (hi != NULL)
2498 *hi = gpu_compat ? pt->compat_va_end : pt->svm_end;
2499
2500 return 0;
2501}
2502
2503static bool kgsl_iommu_addr_in_range(struct kgsl_pagetable *pagetable,
2504 uint64_t gpuaddr)
2505{
2506 struct kgsl_iommu_pt *pt = pagetable->priv;
2507
2508 if (gpuaddr == 0)
2509 return false;
2510
2511 if (gpuaddr >= pt->va_start && gpuaddr < pt->va_end)
2512 return true;
2513
2514 if (gpuaddr >= pt->compat_va_start && gpuaddr < pt->compat_va_end)
2515 return true;
2516
2517 if (gpuaddr >= pt->svm_start && gpuaddr < pt->svm_end)
2518 return true;
2519
2520 return false;
2521}
2522
2523static const struct {
2524 int id;
2525 char *name;
2526} kgsl_iommu_cbs[] = {
2527 { KGSL_IOMMU_CONTEXT_USER, "gfx3d_user", },
2528 { KGSL_IOMMU_CONTEXT_SECURE, "gfx3d_secure" },
Rajesh Kemisetti63d93582018-01-31 10:52:56 +05302529 { KGSL_IOMMU_CONTEXT_SECURE, "gfx3d_secure_alt" },
Shrenuj Bansala419c792016-10-20 14:05:11 -07002530};
2531
2532static int _kgsl_iommu_cb_probe(struct kgsl_device *device,
2533 struct kgsl_iommu *iommu, struct device_node *node)
2534{
2535 struct platform_device *pdev = of_find_device_by_node(node);
2536 struct kgsl_iommu_context *ctx = NULL;
Rajesh Kemisetti63d93582018-01-31 10:52:56 +05302537 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
Shrenuj Bansala419c792016-10-20 14:05:11 -07002538 int i;
2539
2540 for (i = 0; i < ARRAY_SIZE(kgsl_iommu_cbs); i++) {
2541 if (!strcmp(node->name, kgsl_iommu_cbs[i].name)) {
2542 int id = kgsl_iommu_cbs[i].id;
2543
Rajesh Kemisetti63d93582018-01-31 10:52:56 +05302544 if (ADRENO_QUIRK(adreno_dev,
2545 ADRENO_QUIRK_MMU_SECURE_CB_ALT)) {
2546 if (!strcmp(node->name, "gfx3d_secure"))
2547 continue;
2548 } else if (!strcmp(node->name, "gfx3d_secure_alt"))
2549 continue;
2550
Shrenuj Bansala419c792016-10-20 14:05:11 -07002551 ctx = &iommu->ctx[id];
2552 ctx->id = id;
2553 ctx->cb_num = -1;
2554 ctx->name = kgsl_iommu_cbs[i].name;
2555
2556 break;
2557 }
2558 }
2559
2560 if (ctx == NULL) {
Rajesh Kemisetti63d93582018-01-31 10:52:56 +05302561 KGSL_CORE_ERR("dt: Unused context label %s\n", node->name);
2562 return 0;
Shrenuj Bansala419c792016-10-20 14:05:11 -07002563 }
2564
2565 if (ctx->id == KGSL_IOMMU_CONTEXT_SECURE)
2566 device->mmu.secured = true;
2567
2568 /* this property won't be found for all context banks */
2569 if (of_property_read_u32(node, "qcom,gpu-offset", &ctx->gpu_offset))
2570 ctx->gpu_offset = UINT_MAX;
2571
2572 ctx->kgsldev = device;
2573
2574 /* arm-smmu driver we'll have the right device pointer here. */
2575 if (of_find_property(node, "iommus", NULL)) {
2576 ctx->dev = &pdev->dev;
2577 } else {
2578 ctx->dev = kgsl_mmu_get_ctx(ctx->name);
2579
2580 if (IS_ERR(ctx->dev))
2581 return PTR_ERR(ctx->dev);
2582 }
2583
2584 return 0;
2585}
2586
2587static const struct {
2588 char *feature;
Lynus Vazeb7af682017-04-17 18:36:01 +05302589 unsigned long bit;
Shrenuj Bansala419c792016-10-20 14:05:11 -07002590} kgsl_iommu_features[] = {
2591 { "qcom,retention", KGSL_MMU_RETENTION },
2592 { "qcom,global_pt", KGSL_MMU_GLOBAL_PAGETABLE },
2593 { "qcom,hyp_secure_alloc", KGSL_MMU_HYP_SECURE_ALLOC },
2594 { "qcom,force-32bit", KGSL_MMU_FORCE_32BIT },
2595};
2596
2597static int _kgsl_iommu_probe(struct kgsl_device *device,
2598 struct device_node *node)
2599{
2600 const char *cname;
2601 struct property *prop;
2602 u32 reg_val[2];
2603 int i = 0;
2604 struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
2605 struct device_node *child;
2606 struct platform_device *pdev = of_find_device_by_node(node);
2607
2608 memset(iommu, 0, sizeof(*iommu));
2609
2610 if (of_device_is_compatible(node, "qcom,kgsl-smmu-v1"))
2611 iommu->version = 1;
2612 else
2613 iommu->version = 2;
2614
2615 if (of_property_read_u32_array(node, "reg", reg_val, 2)) {
2616 KGSL_CORE_ERR("dt: Unable to read KGSL IOMMU register range\n");
2617 return -EINVAL;
2618 }
2619 iommu->regstart = reg_val[0];
2620 iommu->regsize = reg_val[1];
2621
2622 /* Protecting the SMMU registers is mandatory */
2623 if (of_property_read_u32_array(node, "qcom,protect", reg_val, 2)) {
2624 KGSL_CORE_ERR("dt: no iommu protection range specified\n");
2625 return -EINVAL;
2626 }
2627 iommu->protect.base = reg_val[0] / sizeof(u32);
2628 iommu->protect.range = ilog2(reg_val[1] / sizeof(u32));
2629
2630 of_property_for_each_string(node, "clock-names", prop, cname) {
2631 struct clk *c = devm_clk_get(&pdev->dev, cname);
2632
2633 if (IS_ERR(c)) {
2634 KGSL_CORE_ERR("dt: Couldn't get clock: %s\n", cname);
2635 return -ENODEV;
2636 }
2637 if (i >= KGSL_IOMMU_MAX_CLKS) {
2638 KGSL_CORE_ERR("dt: too many clocks defined.\n");
2639 return -EINVAL;
2640 }
2641
2642 iommu->clks[i] = c;
2643 ++i;
2644 }
2645
2646 for (i = 0; i < ARRAY_SIZE(kgsl_iommu_features); i++) {
2647 if (of_property_read_bool(node, kgsl_iommu_features[i].feature))
2648 device->mmu.features |= kgsl_iommu_features[i].bit;
2649 }
2650
2651 if (of_property_read_u32(node, "qcom,micro-mmu-control",
2652 &iommu->micro_mmu_ctrl))
2653 iommu->micro_mmu_ctrl = UINT_MAX;
2654
2655 if (of_property_read_u32(node, "qcom,secure_align_mask",
2656 &device->mmu.secure_align_mask))
2657 device->mmu.secure_align_mask = 0xfff;
2658
2659 /* Fill out the rest of the devices in the node */
2660 of_platform_populate(node, NULL, NULL, &pdev->dev);
2661
2662 for_each_child_of_node(node, child) {
2663 int ret;
2664
2665 if (!of_device_is_compatible(child, "qcom,smmu-kgsl-cb"))
2666 continue;
2667
2668 ret = _kgsl_iommu_cb_probe(device, iommu, child);
2669 if (ret)
2670 return ret;
2671 }
2672
2673 return 0;
2674}
2675
2676static const struct {
2677 char *compat;
2678 int (*probe)(struct kgsl_device *device, struct device_node *node);
2679} kgsl_dt_devices[] = {
2680 { "qcom,kgsl-smmu-v1", _kgsl_iommu_probe },
2681 { "qcom,kgsl-smmu-v2", _kgsl_iommu_probe },
2682};
2683
2684static int kgsl_iommu_probe(struct kgsl_device *device)
2685{
2686 int i;
2687
2688 for (i = 0; i < ARRAY_SIZE(kgsl_dt_devices); i++) {
2689 struct device_node *node;
2690
2691 node = of_find_compatible_node(device->pdev->dev.of_node,
2692 NULL, kgsl_dt_devices[i].compat);
2693
2694 if (node != NULL)
2695 return kgsl_dt_devices[i].probe(device, node);
2696 }
2697
2698 return -ENODEV;
2699}
2700
2701struct kgsl_mmu_ops kgsl_iommu_ops = {
2702 .mmu_init = kgsl_iommu_init,
2703 .mmu_close = kgsl_iommu_close,
2704 .mmu_start = kgsl_iommu_start,
2705 .mmu_stop = kgsl_iommu_stop,
2706 .mmu_set_pt = kgsl_iommu_set_pt,
2707 .mmu_clear_fsr = kgsl_iommu_clear_fsr,
2708 .mmu_get_current_ttbr0 = kgsl_iommu_get_current_ttbr0,
2709 .mmu_enable_clk = kgsl_iommu_enable_clk,
2710 .mmu_disable_clk = kgsl_iommu_disable_clk,
2711 .mmu_get_reg_ahbaddr = kgsl_iommu_get_reg_ahbaddr,
2712 .mmu_pt_equal = kgsl_iommu_pt_equal,
2713 .mmu_set_pf_policy = kgsl_iommu_set_pf_policy,
2714 .mmu_pagefault_resume = kgsl_iommu_pagefault_resume,
2715 .mmu_get_prot_regs = kgsl_iommu_get_prot_regs,
2716 .mmu_init_pt = kgsl_iommu_init_pt,
2717 .mmu_add_global = kgsl_iommu_add_global,
2718 .mmu_remove_global = kgsl_iommu_remove_global,
2719 .mmu_getpagetable = kgsl_iommu_getpagetable,
2720 .mmu_get_qdss_global_entry = kgsl_iommu_get_qdss_global_entry,
Jonathan Wicks4892d8d2017-02-24 16:21:26 -07002721 .mmu_get_qtimer_global_entry = kgsl_iommu_get_qtimer_global_entry,
Shrenuj Bansala419c792016-10-20 14:05:11 -07002722 .probe = kgsl_iommu_probe,
2723};
2724
2725static struct kgsl_mmu_pt_ops iommu_pt_ops = {
2726 .mmu_map = kgsl_iommu_map,
2727 .mmu_unmap = kgsl_iommu_unmap,
2728 .mmu_destroy_pagetable = kgsl_iommu_destroy_pagetable,
2729 .get_ttbr0 = kgsl_iommu_get_ttbr0,
2730 .get_contextidr = kgsl_iommu_get_contextidr,
2731 .get_gpuaddr = kgsl_iommu_get_gpuaddr,
2732 .put_gpuaddr = kgsl_iommu_put_gpuaddr,
2733 .set_svm_region = kgsl_iommu_set_svm_region,
2734 .find_svm_region = kgsl_iommu_find_svm_region,
2735 .svm_range = kgsl_iommu_svm_range,
2736 .addr_in_range = kgsl_iommu_addr_in_range,
2737 .mmu_map_offset = kgsl_iommu_map_offset,
2738 .mmu_unmap_offset = kgsl_iommu_unmap_offset,
2739 .mmu_sparse_dummy_map = kgsl_iommu_sparse_dummy_map,
2740};