1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (C) 2015-2018 Etnaviv Project |
4 | */ |
5 | |
6 | #ifndef __ETNAVIV_MMU_H__ |
7 | #define __ETNAVIV_MMU_H__ |
8 | |
9 | #define ETNAVIV_PROT_READ (1 << 0) |
10 | #define ETNAVIV_PROT_WRITE (1 << 1) |
11 | |
12 | enum etnaviv_iommu_version { |
13 | ETNAVIV_IOMMU_V1 = 0, |
14 | ETNAVIV_IOMMU_V2, |
15 | }; |
16 | |
17 | struct etnaviv_gpu; |
18 | struct etnaviv_vram_mapping; |
19 | struct etnaviv_iommu_global; |
20 | struct etnaviv_iommu_context; |
21 | |
22 | struct etnaviv_iommu_ops { |
23 | struct etnaviv_iommu_context *(*init)(struct etnaviv_iommu_global *); |
24 | void (*free)(struct etnaviv_iommu_context *); |
25 | int (*map)(struct etnaviv_iommu_context *context, unsigned long iova, |
26 | phys_addr_t paddr, size_t size, int prot); |
27 | size_t (*unmap)(struct etnaviv_iommu_context *context, unsigned long iova, |
28 | size_t size); |
29 | size_t (*dump_size)(struct etnaviv_iommu_context *); |
30 | void (*dump)(struct etnaviv_iommu_context *, void *); |
31 | void (*restore)(struct etnaviv_gpu *, struct etnaviv_iommu_context *); |
32 | }; |
33 | |
34 | extern const struct etnaviv_iommu_ops etnaviv_iommuv1_ops; |
35 | extern const struct etnaviv_iommu_ops etnaviv_iommuv2_ops; |
36 | |
37 | #define ETNAVIV_PTA_SIZE SZ_4K |
38 | #define ETNAVIV_PTA_ENTRIES (ETNAVIV_PTA_SIZE / sizeof(u64)) |
39 | |
40 | struct etnaviv_iommu_global { |
41 | struct device *dev; |
42 | enum etnaviv_iommu_version version; |
43 | const struct etnaviv_iommu_ops *ops; |
44 | unsigned int use; |
45 | struct mutex lock; |
46 | |
47 | void *bad_page_cpu; |
48 | dma_addr_t bad_page_dma; |
49 | |
50 | u32 memory_base; |
51 | |
52 | /* |
53 | * This union holds members needed by either MMUv1 or MMUv2, which |
54 | * can not exist at the same time. |
55 | */ |
56 | union { |
57 | struct { |
58 | struct etnaviv_iommu_context *shared_context; |
59 | } v1; |
60 | struct { |
61 | /* P(age) T(able) A(rray) */ |
62 | u64 *pta_cpu; |
63 | dma_addr_t pta_dma; |
64 | struct spinlock pta_lock; |
65 | DECLARE_BITMAP(pta_alloc, ETNAVIV_PTA_ENTRIES); |
66 | } v2; |
67 | }; |
68 | }; |
69 | |
70 | struct etnaviv_iommu_context { |
71 | struct kref refcount; |
72 | struct etnaviv_iommu_global *global; |
73 | |
74 | /* memory manager for GPU address area */ |
75 | struct mutex lock; |
76 | struct list_head mappings; |
77 | struct drm_mm mm; |
78 | unsigned int flush_seq; |
79 | |
80 | /* Not part of the context, but needs to have the same lifetime */ |
81 | struct etnaviv_vram_mapping cmdbuf_mapping; |
82 | }; |
83 | |
84 | int etnaviv_iommu_global_init(struct etnaviv_gpu *gpu); |
85 | void etnaviv_iommu_global_fini(struct etnaviv_gpu *gpu); |
86 | |
87 | struct etnaviv_gem_object; |
88 | |
89 | int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context, |
90 | struct etnaviv_gem_object *etnaviv_obj, u32 memory_base, |
91 | struct etnaviv_vram_mapping *mapping, u64 va); |
92 | void etnaviv_iommu_unmap_gem(struct etnaviv_iommu_context *context, |
93 | struct etnaviv_vram_mapping *mapping); |
94 | void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping); |
95 | |
96 | int etnaviv_iommu_get_suballoc_va(struct etnaviv_iommu_context *ctx, |
97 | struct etnaviv_vram_mapping *mapping, |
98 | u32 memory_base, dma_addr_t paddr, |
99 | size_t size); |
100 | void etnaviv_iommu_put_suballoc_va(struct etnaviv_iommu_context *ctx, |
101 | struct etnaviv_vram_mapping *mapping); |
102 | |
103 | size_t etnaviv_iommu_dump_size(struct etnaviv_iommu_context *ctx); |
104 | void etnaviv_iommu_dump(struct etnaviv_iommu_context *ctx, void *buf); |
105 | |
106 | struct etnaviv_iommu_context * |
107 | etnaviv_iommu_context_init(struct etnaviv_iommu_global *global, |
108 | struct etnaviv_cmdbuf_suballoc *suballoc); |
109 | static inline struct etnaviv_iommu_context * |
110 | etnaviv_iommu_context_get(struct etnaviv_iommu_context *ctx) |
111 | { |
112 | kref_get(kref: &ctx->refcount); |
113 | return ctx; |
114 | } |
115 | void etnaviv_iommu_context_put(struct etnaviv_iommu_context *ctx); |
116 | void etnaviv_iommu_restore(struct etnaviv_gpu *gpu, |
117 | struct etnaviv_iommu_context *ctx); |
118 | |
119 | struct etnaviv_iommu_context * |
120 | etnaviv_iommuv1_context_alloc(struct etnaviv_iommu_global *global); |
121 | struct etnaviv_iommu_context * |
122 | etnaviv_iommuv2_context_alloc(struct etnaviv_iommu_global *global); |
123 | |
124 | u32 etnaviv_iommuv2_get_mtlb_addr(struct etnaviv_iommu_context *context); |
125 | unsigned short etnaviv_iommuv2_get_pta_id(struct etnaviv_iommu_context *context); |
126 | |
127 | #endif /* __ETNAVIV_MMU_H__ */ |
128 | |