.. | .. |
---|
16 | 16 | |
---|
17 | 17 | struct etnaviv_gpu; |
---|
18 | 18 | struct etnaviv_vram_mapping; |
---|
19 | | -struct etnaviv_iommu_domain; |
---|
| 19 | +struct etnaviv_iommu_global; |
---|
| 20 | +struct etnaviv_iommu_context; |
---|
20 | 21 | |
---|
21 | | -struct etnaviv_iommu_domain_ops { |
---|
22 | | - void (*free)(struct etnaviv_iommu_domain *); |
---|
23 | | - int (*map)(struct etnaviv_iommu_domain *domain, unsigned long iova, |
---|
| 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, |
---|
24 | 26 | phys_addr_t paddr, size_t size, int prot); |
---|
25 | | - size_t (*unmap)(struct etnaviv_iommu_domain *domain, unsigned long iova, |
---|
| 27 | + size_t (*unmap)(struct etnaviv_iommu_context *context, unsigned long iova, |
---|
26 | 28 | size_t size); |
---|
27 | | - size_t (*dump_size)(struct etnaviv_iommu_domain *); |
---|
28 | | - void (*dump)(struct etnaviv_iommu_domain *, void *); |
---|
| 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 *); |
---|
29 | 32 | }; |
---|
30 | 33 | |
---|
31 | | -struct etnaviv_iommu_domain { |
---|
| 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 { |
---|
32 | 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 | + |
---|
33 | 47 | void *bad_page_cpu; |
---|
34 | 48 | dma_addr_t bad_page_dma; |
---|
35 | | - u64 base; |
---|
36 | | - u64 size; |
---|
37 | 49 | |
---|
38 | | - const struct etnaviv_iommu_domain_ops *ops; |
---|
| 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 | + }; |
---|
39 | 68 | }; |
---|
40 | 69 | |
---|
41 | | -struct etnaviv_iommu { |
---|
42 | | - struct etnaviv_gpu *gpu; |
---|
43 | | - struct etnaviv_iommu_domain *domain; |
---|
44 | | - |
---|
45 | | - enum etnaviv_iommu_version version; |
---|
| 70 | +struct etnaviv_iommu_context { |
---|
| 71 | + struct kref refcount; |
---|
| 72 | + struct etnaviv_iommu_global *global; |
---|
46 | 73 | |
---|
47 | 74 | /* memory manager for GPU address area */ |
---|
48 | 75 | struct mutex lock; |
---|
49 | 76 | struct list_head mappings; |
---|
50 | 77 | struct drm_mm mm; |
---|
51 | 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; |
---|
52 | 82 | }; |
---|
| 83 | + |
---|
| 84 | +int etnaviv_iommu_global_init(struct etnaviv_gpu *gpu); |
---|
| 85 | +void etnaviv_iommu_global_fini(struct etnaviv_gpu *gpu); |
---|
53 | 86 | |
---|
54 | 87 | struct etnaviv_gem_object; |
---|
55 | 88 | |
---|
56 | | -int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu, |
---|
| 89 | +int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context, |
---|
57 | 90 | struct etnaviv_gem_object *etnaviv_obj, u32 memory_base, |
---|
58 | | - struct etnaviv_vram_mapping *mapping); |
---|
59 | | -void etnaviv_iommu_unmap_gem(struct etnaviv_iommu *mmu, |
---|
| 91 | + struct etnaviv_vram_mapping *mapping, u64 va); |
---|
| 92 | +void etnaviv_iommu_unmap_gem(struct etnaviv_iommu_context *context, |
---|
60 | 93 | struct etnaviv_vram_mapping *mapping); |
---|
61 | 94 | |
---|
62 | | -int etnaviv_iommu_get_suballoc_va(struct etnaviv_gpu *gpu, dma_addr_t paddr, |
---|
63 | | - struct drm_mm_node *vram_node, size_t size, |
---|
64 | | - u32 *iova); |
---|
65 | | -void etnaviv_iommu_put_suballoc_va(struct etnaviv_gpu *gpu, |
---|
66 | | - struct drm_mm_node *vram_node, size_t size, |
---|
67 | | - u32 iova); |
---|
| 95 | +int etnaviv_iommu_get_suballoc_va(struct etnaviv_iommu_context *ctx, |
---|
| 96 | + struct etnaviv_vram_mapping *mapping, |
---|
| 97 | + u32 memory_base, dma_addr_t paddr, |
---|
| 98 | + size_t size); |
---|
| 99 | +void etnaviv_iommu_put_suballoc_va(struct etnaviv_iommu_context *ctx, |
---|
| 100 | + struct etnaviv_vram_mapping *mapping); |
---|
68 | 101 | |
---|
69 | | -size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu); |
---|
70 | | -void etnaviv_iommu_dump(struct etnaviv_iommu *iommu, void *buf); |
---|
| 102 | +size_t etnaviv_iommu_dump_size(struct etnaviv_iommu_context *ctx); |
---|
| 103 | +void etnaviv_iommu_dump(struct etnaviv_iommu_context *ctx, void *buf); |
---|
71 | 104 | |
---|
72 | | -struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu); |
---|
73 | | -void etnaviv_iommu_destroy(struct etnaviv_iommu *iommu); |
---|
74 | | -void etnaviv_iommu_restore(struct etnaviv_gpu *gpu); |
---|
| 105 | +struct etnaviv_iommu_context * |
---|
| 106 | +etnaviv_iommu_context_init(struct etnaviv_iommu_global *global, |
---|
| 107 | + struct etnaviv_cmdbuf_suballoc *suballoc); |
---|
| 108 | +static inline struct etnaviv_iommu_context * |
---|
| 109 | +etnaviv_iommu_context_get(struct etnaviv_iommu_context *ctx) |
---|
| 110 | +{ |
---|
| 111 | + kref_get(&ctx->refcount); |
---|
| 112 | + return ctx; |
---|
| 113 | +} |
---|
| 114 | +void etnaviv_iommu_context_put(struct etnaviv_iommu_context *ctx); |
---|
| 115 | +void etnaviv_iommu_restore(struct etnaviv_gpu *gpu, |
---|
| 116 | + struct etnaviv_iommu_context *ctx); |
---|
| 117 | + |
---|
| 118 | +struct etnaviv_iommu_context * |
---|
| 119 | +etnaviv_iommuv1_context_alloc(struct etnaviv_iommu_global *global); |
---|
| 120 | +struct etnaviv_iommu_context * |
---|
| 121 | +etnaviv_iommuv2_context_alloc(struct etnaviv_iommu_global *global); |
---|
| 122 | + |
---|
| 123 | +u32 etnaviv_iommuv2_get_mtlb_addr(struct etnaviv_iommu_context *context); |
---|
| 124 | +unsigned short etnaviv_iommuv2_get_pta_id(struct etnaviv_iommu_context *context); |
---|
75 | 125 | |
---|
76 | 126 | #endif /* __ETNAVIV_MMU_H__ */ |
---|