2 * Copyright (C) 2015 Etnaviv Project
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "common.xml.h"
18 #include "etnaviv_drv.h"
19 #include "etnaviv_gem.h"
20 #include "etnaviv_gpu.h"
21 #include "etnaviv_iommu.h"
22 #include "etnaviv_mmu.h"
24 static int etnaviv_fault_handler(struct iommu_domain
*iommu
, struct device
*dev
,
25 unsigned long iova
, int flags
, void *arg
)
27 DBG("*** fault: iova=%08lx, flags=%d", iova
, flags
);
31 int etnaviv_iommu_map(struct etnaviv_iommu
*iommu
, u32 iova
,
32 struct sg_table
*sgt
, unsigned len
, int prot
)
34 struct iommu_domain
*domain
= iommu
->domain
;
35 struct scatterlist
*sg
;
36 unsigned int da
= iova
;
43 for_each_sg(sgt
->sgl
, sg
, sgt
->nents
, i
) {
44 u32 pa
= sg_dma_address(sg
) - sg
->offset
;
45 size_t bytes
= sg_dma_len(sg
) + sg
->offset
;
47 VERB("map[%d]: %08x %08x(%zx)", i
, iova
, pa
, bytes
);
49 ret
= iommu_map(domain
, da
, pa
, bytes
, prot
);
61 for_each_sg(sgt
->sgl
, sg
, i
, j
) {
62 size_t bytes
= sg_dma_len(sg
) + sg
->offset
;
64 iommu_unmap(domain
, da
, bytes
);
70 int etnaviv_iommu_unmap(struct etnaviv_iommu
*iommu
, u32 iova
,
71 struct sg_table
*sgt
, unsigned len
)
73 struct iommu_domain
*domain
= iommu
->domain
;
74 struct scatterlist
*sg
;
75 unsigned int da
= iova
;
78 for_each_sg(sgt
->sgl
, sg
, sgt
->nents
, i
) {
79 size_t bytes
= sg_dma_len(sg
) + sg
->offset
;
82 unmapped
= iommu_unmap(domain
, da
, bytes
);
86 VERB("unmap[%d]: %08x(%zx)", i
, iova
, bytes
);
88 BUG_ON(!PAGE_ALIGNED(bytes
));
96 static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu
*mmu
,
97 struct etnaviv_vram_mapping
*mapping
)
99 struct etnaviv_gem_object
*etnaviv_obj
= mapping
->object
;
101 etnaviv_iommu_unmap(mmu
, mapping
->vram_node
.start
,
102 etnaviv_obj
->sgt
, etnaviv_obj
->base
.size
);
103 drm_mm_remove_node(&mapping
->vram_node
);
106 static int etnaviv_iommu_find_iova(struct etnaviv_iommu
*mmu
,
107 struct drm_mm_node
*node
, size_t size
)
109 struct etnaviv_vram_mapping
*free
= NULL
;
112 lockdep_assert_held(&mmu
->lock
);
115 struct etnaviv_vram_mapping
*m
, *n
;
116 struct drm_mm_scan scan
;
117 struct list_head list
;
121 * XXX: The DRM_MM_SEARCH_BELOW is really a hack to trick
122 * drm_mm into giving out a low IOVA after address space
123 * rollover. This needs a proper fix.
125 ret
= drm_mm_insert_node_in_range(&mmu
->mm
, node
,
126 size
, 0, mmu
->last_iova
, ~0UL,
127 mmu
->last_iova
? DRM_MM_SEARCH_DEFAULT
: DRM_MM_SEARCH_BELOW
);
133 * If we did not search from the start of the MMU region,
134 * try again in case there are free slots.
136 if (mmu
->last_iova
) {
138 mmu
->need_flush
= true;
142 /* Try to retire some entries */
143 drm_mm_scan_init(&scan
, &mmu
->mm
, size
, 0, 0, 0);
146 INIT_LIST_HEAD(&list
);
147 list_for_each_entry(free
, &mmu
->mappings
, mmu_node
) {
148 /* If this vram node has not been used, skip this. */
149 if (!free
->vram_node
.mm
)
153 * If the iova is pinned, then it's in-use,
154 * so we must keep its mapping.
159 list_add(&free
->scan_node
, &list
);
160 if (drm_mm_scan_add_block(&scan
, &free
->vram_node
)) {
167 /* Nothing found, clean up and fail */
168 list_for_each_entry_safe(m
, n
, &list
, scan_node
)
169 BUG_ON(drm_mm_scan_remove_block(&scan
, &m
->vram_node
));
174 * drm_mm does not allow any other operations while
175 * scanning, so we have to remove all blocks first.
176 * If drm_mm_scan_remove_block() returns false, we
177 * can leave the block pinned.
179 list_for_each_entry_safe(m
, n
, &list
, scan_node
)
180 if (!drm_mm_scan_remove_block(&scan
, &m
->vram_node
))
181 list_del_init(&m
->scan_node
);
184 * Unmap the blocks which need to be reaped from the MMU.
185 * Clear the mmu pointer to prevent the mapping_get finding
188 list_for_each_entry_safe(m
, n
, &list
, scan_node
) {
189 etnaviv_iommu_remove_mapping(mmu
, m
);
191 list_del_init(&m
->mmu_node
);
192 list_del_init(&m
->scan_node
);
196 * We removed enough mappings so that the new allocation will
197 * succeed. Ensure that the MMU will be flushed before the
198 * associated commit requesting this mapping, and retry the
199 * allocation one more time.
201 mmu
->need_flush
= true;
207 int etnaviv_iommu_map_gem(struct etnaviv_iommu
*mmu
,
208 struct etnaviv_gem_object
*etnaviv_obj
, u32 memory_base
,
209 struct etnaviv_vram_mapping
*mapping
)
211 struct sg_table
*sgt
= etnaviv_obj
->sgt
;
212 struct drm_mm_node
*node
;
215 lockdep_assert_held(&etnaviv_obj
->lock
);
217 mutex_lock(&mmu
->lock
);
219 /* v1 MMU can optimize single entry (contiguous) scatterlists */
220 if (mmu
->version
== ETNAVIV_IOMMU_V1
&&
221 sgt
->nents
== 1 && !(etnaviv_obj
->flags
& ETNA_BO_FORCE_MMU
)) {
224 iova
= sg_dma_address(sgt
->sgl
) - memory_base
;
225 if (iova
< 0x80000000 - sg_dma_len(sgt
->sgl
)) {
226 mapping
->iova
= iova
;
227 list_add_tail(&mapping
->mmu_node
, &mmu
->mappings
);
228 mutex_unlock(&mmu
->lock
);
233 node
= &mapping
->vram_node
;
235 ret
= etnaviv_iommu_find_iova(mmu
, node
, etnaviv_obj
->base
.size
);
237 mutex_unlock(&mmu
->lock
);
241 mmu
->last_iova
= node
->start
+ etnaviv_obj
->base
.size
;
242 mapping
->iova
= node
->start
;
243 ret
= etnaviv_iommu_map(mmu
, node
->start
, sgt
, etnaviv_obj
->base
.size
,
244 IOMMU_READ
| IOMMU_WRITE
);
247 drm_mm_remove_node(node
);
248 mutex_unlock(&mmu
->lock
);
252 list_add_tail(&mapping
->mmu_node
, &mmu
->mappings
);
253 mutex_unlock(&mmu
->lock
);
258 void etnaviv_iommu_unmap_gem(struct etnaviv_iommu
*mmu
,
259 struct etnaviv_vram_mapping
*mapping
)
261 WARN_ON(mapping
->use
);
263 mutex_lock(&mmu
->lock
);
265 /* If the vram node is on the mm, unmap and remove the node */
266 if (mapping
->vram_node
.mm
== &mmu
->mm
)
267 etnaviv_iommu_remove_mapping(mmu
, mapping
);
269 list_del(&mapping
->mmu_node
);
270 mutex_unlock(&mmu
->lock
);
273 void etnaviv_iommu_destroy(struct etnaviv_iommu
*mmu
)
275 drm_mm_takedown(&mmu
->mm
);
276 iommu_domain_free(mmu
->domain
);
280 struct etnaviv_iommu
*etnaviv_iommu_new(struct etnaviv_gpu
*gpu
)
282 enum etnaviv_iommu_version version
;
283 struct etnaviv_iommu
*mmu
;
285 mmu
= kzalloc(sizeof(*mmu
), GFP_KERNEL
);
287 return ERR_PTR(-ENOMEM
);
289 if (!(gpu
->identity
.minor_features1
& chipMinorFeatures1_MMU_VERSION
)) {
290 mmu
->domain
= etnaviv_iommuv1_domain_alloc(gpu
);
291 version
= ETNAVIV_IOMMU_V1
;
293 mmu
->domain
= etnaviv_iommuv2_domain_alloc(gpu
);
294 version
= ETNAVIV_IOMMU_V2
;
298 dev_err(gpu
->dev
, "Failed to allocate GPU IOMMU domain\n");
300 return ERR_PTR(-ENOMEM
);
304 mmu
->version
= version
;
305 mutex_init(&mmu
->lock
);
306 INIT_LIST_HEAD(&mmu
->mappings
);
308 drm_mm_init(&mmu
->mm
, mmu
->domain
->geometry
.aperture_start
,
309 mmu
->domain
->geometry
.aperture_end
-
310 mmu
->domain
->geometry
.aperture_start
+ 1);
312 iommu_set_fault_handler(mmu
->domain
, etnaviv_fault_handler
, gpu
->dev
);
317 void etnaviv_iommu_restore(struct etnaviv_gpu
*gpu
)
319 if (gpu
->mmu
->version
== ETNAVIV_IOMMU_V1
)
320 etnaviv_iommuv1_restore(gpu
);
322 etnaviv_iommuv2_restore(gpu
);
325 u32
etnaviv_iommu_get_cmdbuf_va(struct etnaviv_gpu
*gpu
,
326 struct etnaviv_cmdbuf
*buf
)
328 struct etnaviv_iommu
*mmu
= gpu
->mmu
;
330 if (mmu
->version
== ETNAVIV_IOMMU_V1
) {
331 return buf
->paddr
- gpu
->memory_base
;
335 if (buf
->vram_node
.allocated
)
336 return (u32
)buf
->vram_node
.start
;
338 mutex_lock(&mmu
->lock
);
339 ret
= etnaviv_iommu_find_iova(mmu
, &buf
->vram_node
,
342 mutex_unlock(&mmu
->lock
);
345 ret
= iommu_map(mmu
->domain
, buf
->vram_node
.start
, buf
->paddr
,
346 buf
->size
, IOMMU_READ
);
348 drm_mm_remove_node(&buf
->vram_node
);
349 mutex_unlock(&mmu
->lock
);
353 * At least on GC3000 the FE MMU doesn't properly flush old TLB
354 * entries. Make sure to space the command buffers out in a way
355 * that the FE MMU prefetch won't load invalid entries.
357 mmu
->last_iova
= buf
->vram_node
.start
+ buf
->size
+ SZ_64K
;
358 gpu
->mmu
->need_flush
= true;
359 mutex_unlock(&mmu
->lock
);
361 return (u32
)buf
->vram_node
.start
;
365 void etnaviv_iommu_put_cmdbuf_va(struct etnaviv_gpu
*gpu
,
366 struct etnaviv_cmdbuf
*buf
)
368 struct etnaviv_iommu
*mmu
= gpu
->mmu
;
370 if (mmu
->version
== ETNAVIV_IOMMU_V2
&& buf
->vram_node
.allocated
) {
371 mutex_lock(&mmu
->lock
);
372 iommu_unmap(mmu
->domain
, buf
->vram_node
.start
, buf
->size
);
373 drm_mm_remove_node(&buf
->vram_node
);
374 mutex_unlock(&mmu
->lock
);
377 size_t etnaviv_iommu_dump_size(struct etnaviv_iommu
*iommu
)
379 struct etnaviv_iommu_ops
*ops
;
381 ops
= container_of(iommu
->domain
->ops
, struct etnaviv_iommu_ops
, ops
);
383 return ops
->dump_size(iommu
->domain
);
386 void etnaviv_iommu_dump(struct etnaviv_iommu
*iommu
, void *buf
)
388 struct etnaviv_iommu_ops
*ops
;
390 ops
= container_of(iommu
->domain
->ops
, struct etnaviv_iommu_ops
, ops
);
392 ops
->dump(iommu
->domain
, buf
);