Commit | Line | Data |
---|---|---|
a9dcad5e HD |
1 | /* |
2 | * omap iommu: main structures | |
3 | * | |
4 | * Copyright (C) 2008-2009 Nokia Corporation | |
5 | * | |
6 | * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | */ | |
12 | ||
13 | #ifndef __MACH_IOMMU_H | |
14 | #define __MACH_IOMMU_H | |
15 | ||
16 | struct iotlb_entry { | |
17 | u32 da; | |
18 | u32 pa; | |
19 | u32 pgsz, prsvd, valid; | |
20 | union { | |
21 | u16 ap; | |
22 | struct { | |
23 | u32 endian, elsz, mixed; | |
24 | }; | |
25 | }; | |
26 | }; | |
27 | ||
28 | struct iommu { | |
29 | const char *name; | |
30 | struct module *owner; | |
31 | struct clk *clk; | |
32 | void __iomem *regbase; | |
33 | struct device *dev; | |
d594f1f3 | 34 | void *isr_priv; |
a9dcad5e HD |
35 | |
36 | unsigned int refcount; | |
f626b52d | 37 | spinlock_t iommu_lock; /* global for this whole object */ |
a9dcad5e HD |
38 | |
39 | /* | |
40 | * We don't change iopgd for a situation like pgd for a task, | |
41 | * but share it globally for each iommu. | |
42 | */ | |
43 | u32 *iopgd; | |
44 | spinlock_t page_table_lock; /* protect iopgd */ | |
45 | ||
46 | int nr_tlb_entries; | |
47 | ||
48 | struct list_head mmap; | |
49 | struct mutex mmap_lock; /* protect mmap */ | |
50 | ||
d594f1f3 | 51 | int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, void *priv); |
a9dcad5e HD |
52 | |
53 | void *ctx; /* iommu context: registres saved area */ | |
c7f4ab26 GLF |
54 | u32 da_start; |
55 | u32 da_end; | |
a9dcad5e HD |
56 | }; |
57 | ||
58 | struct cr_regs { | |
59 | union { | |
60 | struct { | |
61 | u16 cam_l; | |
62 | u16 cam_h; | |
63 | }; | |
64 | u32 cam; | |
65 | }; | |
66 | union { | |
67 | struct { | |
68 | u16 ram_l; | |
69 | u16 ram_h; | |
70 | }; | |
71 | u32 ram; | |
72 | }; | |
73 | }; | |
74 | ||
75 | struct iotlb_lock { | |
76 | short base; | |
77 | short vict; | |
78 | }; | |
79 | ||
80 | /* architecture specific functions */ | |
81 | struct iommu_functions { | |
82 | unsigned long version; | |
83 | ||
84 | int (*enable)(struct iommu *obj); | |
85 | void (*disable)(struct iommu *obj); | |
ddfa975a | 86 | void (*set_twl)(struct iommu *obj, bool on); |
a9dcad5e HD |
87 | u32 (*fault_isr)(struct iommu *obj, u32 *ra); |
88 | ||
89 | void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); | |
90 | void (*tlb_load_cr)(struct iommu *obj, struct cr_regs *cr); | |
91 | ||
92 | struct cr_regs *(*alloc_cr)(struct iommu *obj, struct iotlb_entry *e); | |
93 | int (*cr_valid)(struct cr_regs *cr); | |
94 | u32 (*cr_to_virt)(struct cr_regs *cr); | |
95 | void (*cr_to_e)(struct cr_regs *cr, struct iotlb_entry *e); | |
96 | ssize_t (*dump_cr)(struct iommu *obj, struct cr_regs *cr, char *buf); | |
97 | ||
98 | u32 (*get_pte_attr)(struct iotlb_entry *e); | |
99 | ||
100 | void (*save_ctx)(struct iommu *obj); | |
101 | void (*restore_ctx)(struct iommu *obj); | |
14e0e679 | 102 | ssize_t (*dump_ctx)(struct iommu *obj, char *buf, ssize_t len); |
a9dcad5e HD |
103 | }; |
104 | ||
105 | struct iommu_platform_data { | |
106 | const char *name; | |
107 | const char *clk_name; | |
108 | const int nr_tlb_entries; | |
c7f4ab26 GLF |
109 | u32 da_start; |
110 | u32 da_end; | |
a9dcad5e HD |
111 | }; |
112 | ||
d594f1f3 DC |
113 | /* IOMMU errors */ |
114 | #define OMAP_IOMMU_ERR_TLB_MISS (1 << 0) | |
115 | #define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1) | |
116 | #define OMAP_IOMMU_ERR_EMU_MISS (1 << 2) | |
117 | #define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3) | |
118 | #define OMAP_IOMMU_ERR_MULTIHIT_FAULT (1 << 4) | |
119 | ||
a9dcad5e HD |
120 | #if defined(CONFIG_ARCH_OMAP1) |
121 | #error "iommu for this processor not implemented yet" | |
122 | #else | |
ce491cf8 | 123 | #include <plat/iommu2.h> |
a9dcad5e HD |
124 | #endif |
125 | ||
126 | /* | |
127 | * utilities for super page(16MB, 1MB, 64KB and 4KB) | |
128 | */ | |
129 | ||
130 | #define iopgsz_max(bytes) \ | |
131 | (((bytes) >= SZ_16M) ? SZ_16M : \ | |
132 | ((bytes) >= SZ_1M) ? SZ_1M : \ | |
133 | ((bytes) >= SZ_64K) ? SZ_64K : \ | |
134 | ((bytes) >= SZ_4K) ? SZ_4K : 0) | |
135 | ||
136 | #define bytes_to_iopgsz(bytes) \ | |
137 | (((bytes) == SZ_16M) ? MMU_CAM_PGSZ_16M : \ | |
138 | ((bytes) == SZ_1M) ? MMU_CAM_PGSZ_1M : \ | |
139 | ((bytes) == SZ_64K) ? MMU_CAM_PGSZ_64K : \ | |
140 | ((bytes) == SZ_4K) ? MMU_CAM_PGSZ_4K : -1) | |
141 | ||
142 | #define iopgsz_to_bytes(iopgsz) \ | |
143 | (((iopgsz) == MMU_CAM_PGSZ_16M) ? SZ_16M : \ | |
144 | ((iopgsz) == MMU_CAM_PGSZ_1M) ? SZ_1M : \ | |
145 | ((iopgsz) == MMU_CAM_PGSZ_64K) ? SZ_64K : \ | |
146 | ((iopgsz) == MMU_CAM_PGSZ_4K) ? SZ_4K : 0) | |
147 | ||
148 | #define iopgsz_ok(bytes) (bytes_to_iopgsz(bytes) >= 0) | |
149 | ||
150 | /* | |
151 | * global functions | |
152 | */ | |
153 | extern u32 iommu_arch_version(void); | |
154 | ||
155 | extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); | |
156 | extern u32 iotlb_cr_to_virt(struct cr_regs *cr); | |
157 | ||
158 | extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); | |
ddfa975a | 159 | extern void iommu_set_twl(struct iommu *obj, bool on); |
a9dcad5e HD |
160 | extern void flush_iotlb_page(struct iommu *obj, u32 da); |
161 | extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); | |
162 | extern void flush_iotlb_all(struct iommu *obj); | |
163 | ||
164 | extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); | |
4f85f99b DC |
165 | extern void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, |
166 | u32 **ppte); | |
a9dcad5e HD |
167 | extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); |
168 | ||
c7f4ab26 | 169 | extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); |
d594f1f3 DC |
170 | extern int iommu_set_isr(const char *name, |
171 | int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, | |
172 | void *priv), | |
173 | void *isr_priv); | |
a9dcad5e HD |
174 | |
175 | extern void iommu_save_ctx(struct iommu *obj); | |
176 | extern void iommu_restore_ctx(struct iommu *obj); | |
177 | ||
178 | extern int install_iommu_arch(const struct iommu_functions *ops); | |
179 | extern void uninstall_iommu_arch(const struct iommu_functions *ops); | |
180 | ||
181 | extern int foreach_iommu_device(void *data, | |
182 | int (*fn)(struct device *, void *)); | |
183 | ||
14e0e679 HD |
184 | extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len); |
185 | extern size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t len); | |
f626b52d | 186 | struct device *omap_find_iommu_device(const char *name); |
a9dcad5e HD |
187 | |
188 | #endif /* __MACH_IOMMU_H */ |