• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * sunxi 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 /*
14  * Register of IOMMU device
15  */
16 #define IOMMU_VERSION_REG			0x0000
17 #define IOMMU_RESET_REG				0x0010
18 #define IOMMU_ENABLE_REG			0x0020
19 #define IOMMU_BYPASS_REG			0x0030
20 #define IOMMU_AUTO_GATING_REG			0x0040
21 #define IOMMU_WBUF_CTRL_REG			0x0044
22 #define IOMMU_OOO_CTRL_REG			0x0048
23 #define IOMMU_4KB_BDY_PRT_CTRL_REG		0x004C
24 #define IOMMU_TTB_REG				0x0050
25 #define IOMMU_TLB_ENABLE_REG			0x0060
26 #define IOMMU_TLB_PREFETCH_REG			0x0070
27 #define IOMMU_TLB_FLUSH_ENABLE_REG		0x0080
28 #define IOMMU_TLB_IVLD_MODE_SEL_REG		0x0084
29 #define IOMMU_TLB_IVLD_START_ADDR_REG		0x0088
30 #define IOMMU_TLB_IVLD_END_ADDR_REG		0x008C
31 #define IOMMU_TLB_IVLD_ADDR_REG			0x0090
32 #define IOMMU_TLB_IVLD_ADDR_MASK_REG		0x0094
33 #define IOMMU_TLB_IVLD_ENABLE_REG		0x0098
34 #define IOMMU_PC_IVLD_MODE_SEL_REG		0x009C
35 #define IOMMU_PC_IVLD_ADDR_REG			0x00A0
36 #define IOMMU_PC_IVLD_START_ADDR_REG		0x00A4
37 #define IOMMU_PC_IVLD_ENABLE_REG		0x00A8
38 #define IOMMU_PC_IVLD_END_ADDR_REG		0x00Ac
39 #define IOMMU_DM_AUT_CTRL_REG0			0x00B0
40 #define IOMMU_DM_AUT_CTRL_REG1			0x00B4
41 #define IOMMU_DM_AUT_CTRL_REG2			0x00B8
42 #define IOMMU_DM_AUT_CTRL_REG3			0x00BC
43 #define IOMMU_DM_AUT_CTRL_REG4			0x00C0
44 #define IOMMU_DM_AUT_CTRL_REG5			0x00C4
45 #define IOMMU_DM_AUT_CTRL_REG6			0x00C8
46 #define IOMMU_DM_AUT_CTRL_REG7			0x00CC
47 #define IOMMU_DM_AUT_OVWT_REG			0x00D0
48 #define IOMMU_INT_ENABLE_REG			0x0100
49 #define IOMMU_INT_CLR_REG			0x0104
50 #define IOMMU_INT_STA_REG			0x0108
51 #define IOMMU_INT_ERR_ADDR_REG0			0x0110
52 
53 #define IOMMU_INT_ERR_ADDR_REG1			0x0114
54 #define IOMMU_INT_ERR_ADDR_REG2			0x0118
55 
56 #define IOMMU_INT_ERR_ADDR_REG3			0x011C
57 #define IOMMU_INT_ERR_ADDR_REG4			0x0120
58 #define IOMMU_INT_ERR_ADDR_REG5			0x0124
59 
60 #define IOMMU_INT_ERR_ADDR_REG6			0x0128
61 #define IOMMU_INT_ERR_ADDR_REG7			0x0130
62 #define IOMMU_INT_ERR_ADDR_REG8			0x0134
63 
64 #define IOMMU_INT_ERR_DATA_REG0			0x0150
65 #define IOMMU_INT_ERR_DATA_REG1			0x0154
66 #define IOMMU_INT_ERR_DATA_REG2			0x0158
67 #define IOMMU_INT_ERR_DATA_REG3			0x015C
68 #define IOMMU_INT_ERR_DATA_REG4			0x0160
69 #define IOMMU_INT_ERR_DATA_REG5			0x0164
70 
71 #define IOMMU_INT_ERR_DATA_REG6			0x0168
72 #define IOMMU_INT_ERR_DATA_REG7			0x0170
73 #define IOMMU_INT_ERR_DATA_REG8			0x0174
74 
75 #define IOMMU_L1PG_INT_REG			0x0180
76 #define IOMMU_L2PG_INT_REG			0x0184
77 #define IOMMU_VA_REG				0x0190
78 #define IOMMU_VA_DATA_REG			0x0194
79 #define IOMMU_VA_CONFIG_REG			0x0198
80 #define IOMMU_PMU_ENABLE_REG			0x0200
81 #define IOMMU_PMU_CLR_REG			0x0210
82 #define IOMMU_PMU_ACCESS_LOW_REG0		0x0230
83 #define IOMMU_PMU_ACCESS_HIGH_REG0		0x0234
84 #define IOMMU_PMU_HIT_LOW_REG0			0x0238
85 #define IOMMU_PMU_HIT_HIGH_REG0			0x023C
86 #define IOMMU_PMU_ACCESS_LOW_REG1		0x0240
87 #define IOMMU_PMU_ACCESS_HIGH_REG1		0x0244
88 #define IOMMU_PMU_HIT_LOW_REG1			0x0248
89 #define IOMMU_PMU_HIT_HIGH_REG1			0x024C
90 #define IOMMU_PMU_ACCESS_LOW_REG2		0x0250
91 #define IOMMU_PMU_ACCESS_HIGH_REG2		0x0254
92 #define IOMMU_PMU_HIT_LOW_REG2			0x0258
93 #define IOMMU_PMU_HIT_HIGH_REG2			0x025C
94 #define IOMMU_PMU_ACCESS_LOW_REG3		0x0260
95 #define IOMMU_PMU_ACCESS_HIGH_REG3		0x0264
96 #define IOMMU_PMU_HIT_LOW_REG3			0x0268
97 #define IOMMU_PMU_HIT_HIGH_REG3			0x026C
98 #define IOMMU_PMU_ACCESS_LOW_REG4		0x0270
99 #define IOMMU_PMU_ACCESS_HIGH_REG4		0x0274
100 #define IOMMU_PMU_HIT_LOW_REG4			0x0278
101 #define IOMMU_PMU_HIT_HIGH_REG4			0x027C
102 #define IOMMU_PMU_ACCESS_LOW_REG5		0x0280
103 #define IOMMU_PMU_ACCESS_HIGH_REG5		0x0284
104 #define IOMMU_PMU_HIT_LOW_REG5			0x0288
105 #define IOMMU_PMU_HIT_HIGH_REG5			0x028C
106 
107 #define IOMMU_PMU_ACCESS_LOW_REG6		0x0290
108 #define IOMMU_PMU_ACCESS_HIGH_REG6		0x0294
109 #define IOMMU_PMU_HIT_LOW_REG6			0x0298
110 #define IOMMU_PMU_HIT_HIGH_REG6			0x029C
111 #define IOMMU_PMU_ACCESS_LOW_REG7		0x02D0
112 #define IOMMU_PMU_ACCESS_HIGH_REG7		0x02D4
113 #define IOMMU_PMU_HIT_LOW_REG7			0x02D8
114 #define IOMMU_PMU_HIT_HIGH_REG7			0x02DC
115 #define IOMMU_PMU_ACCESS_LOW_REG8		0x02E0
116 #define IOMMU_PMU_ACCESS_HIGH_REG8		0x02E4
117 #define IOMMU_PMU_HIT_LOW_REG8			0x02E8
118 #define IOMMU_PMU_HIT_HIGH_REG8			0x02EC
119 
120 #define IOMMU_PMU_TL_LOW_REG0			0x0300
121 #define IOMMU_PMU_TL_HIGH_REG0			0x0304
122 #define IOMMU_PMU_ML_REG0			0x0308
123 
124 #define IOMMU_PMU_TL_LOW_REG1			0x0310
125 #define IOMMU_PMU_TL_HIGH_REG1			0x0314
126 #define IOMMU_PMU_ML_REG1			0x0318
127 
128 #define IOMMU_PMU_TL_LOW_REG2			0x0320
129 #define IOMMU_PMU_TL_HIGH_REG2			0x0324
130 #define IOMMU_PMU_ML_REG2			0x0328
131 
132 #define IOMMU_PMU_TL_LOW_REG3			0x0330
133 #define IOMMU_PMU_TL_HIGH_REG3			0x0334
134 #define IOMMU_PMU_ML_REG3			0x0338
135 
136 #define IOMMU_PMU_TL_LOW_REG4			0x0340
137 #define IOMMU_PMU_TL_HIGH_REG4			0x0344
138 #define IOMMU_PMU_ML_REG4			0x0348
139 
140 #define IOMMU_PMU_TL_LOW_REG5			0x0350
141 #define IOMMU_PMU_TL_HIGH_REG5			0x0354
142 #define IOMMU_PMU_ML_REG5			0x0358
143 
144 #define IOMMU_PMU_TL_LOW_REG6			0x0360
145 #define IOMMU_PMU_TL_HIGH_REG6			0x0364
146 #define IOMMU_PMU_ML_REG6			0x0368
147 
148 #define IOMMU_RESET_SHIFT   31
149 #define IOMMU_RESET_MASK (1 << IOMMU_RESET_SHIFT)
150 #define IOMMU_RESET_SET (0 << 31)
151 #define IOMMU_RESET_RELEASE (1 << 31)
152 
153 /*
154  * IOMMU enable register field
155  */
156 #define IOMMU_ENABLE	0x1
157 
158 /*
159  * IOMMU interrupt id mask
160  */
161 #define MICRO_TLB0_INVALID_INTER_MASK   0x1
162 #define MICRO_TLB1_INVALID_INTER_MASK   0x2
163 #define MICRO_TLB2_INVALID_INTER_MASK   0x4
164 #define MICRO_TLB3_INVALID_INTER_MASK   0x8
165 #define MICRO_TLB4_INVALID_INTER_MASK   0x10
166 #define MICRO_TLB5_INVALID_INTER_MASK   0x20
167 #define MICRO_TLB6_INVALID_INTER_MASK   0x40
168 
169 #define L1_PAGETABLE_INVALID_INTER_MASK   0x10000
170 #define L2_PAGETABLE_INVALID_INTER_MASK   0x20000
171 
172 /*
173  * This version Hardware just only support 4KB page. It have
174  * a two level page table structure, where the first level has
175  * 4096 entries, and the second level has 256 entries. And, the
176  * first level is "Page Directory(PG)", every entry include a
177  * Page Table base address and a few of control bits. Second
178  * level is "Page Table(PT)", every entry include a physical
179  * page address and a few of control bits. Each entry is one
180  * 32-bit word. Most of the bits in the second level entry are
181  * used by hardware.
182  *
183  * Virtual Address Format:
184  *     31              20|19        12|11     0
185  *     +-----------------+------------+--------+
186  *     |    PDE Index    |  PTE Index | offset |
187  *     +-----------------+------------+--------+
188  *
189  * Table Layout:
190  *
191  *      First Level         Second Level
192  *   (Page Directory)       (Page Table)
193  *   ----+---------+0
194  *    ∧  |  PDE   |   ---> -+--------+----
195  *    |  ----------+1       |  PTE   |  ∧
196  *    |  |        |         +--------+  |
197  *       ----------+2       |        |  1K
198  *   16K |        |         +--------+  |
199  *       ----------+3       |        |  ∨
200  *    |  |        |         +--------+----
201  *    |  ----------
202  *    |  |        |
203  *    ∨  |        |
204  *   ----+--------+
205  *
206  * IOPDE:
207  * 31                     10|9       0
208  * +------------------------+--------+
209  * |   PTE Base Address     |CTRL BIT|
210  * +------------------------+--------+
211  *
212  * IOPTE:
213  * 31                  12|11         0
214  * +---------------------+-----------+
215  * |  Phy Page Address   |  CTRL BIT |
216  * +---------------------+-----------+
217  *
218  */
219 
220 #define NUM_ENTRIES_PDE 4096
221 #define NUM_ENTRIES_PTE 256
222 #define PD_SIZE (NUM_ENTRIES_PDE * sizeof(u32))
223 #define PT_SIZE	(NUM_ENTRIES_PTE * sizeof(u32))
224 
225 #define IOMMU_PD_SHIFT 20
226 #define IOMMU_PD_MASK  (~((1UL << IOMMU_PD_SHIFT) - 1))
227 
228 #define IOMMU_PT_SHIFT 12
229 #define IOMMU_PT_MASK  (~((1UL << IOMMU_PT_SHIFT) - 1))
230 
231 #define PAGE_OFFSET_MASK  ((1UL << IOMMU_PT_SHIFT) - 1)
232 #define IOPTE_BASE_MASK	 (~(PT_SIZE - 1))
233 
234 /*
235  * Page Directory Entry Control Bits
236  */
237 #define DENT_VALID	0x01
238 #define DENT_PTE_SHFIT	10
239 #define DENT_WRITABLE	  BIT(3)
240 #define DENT_READABLE	  BIT(2)
241 
242 /*
243  * Page Table Entry Control Bits
244  */
245 #define SUNXI_PTE_PAGE_WRITABLE	  BIT(3)
246 #define SUNXI_PTE_PAGE_READABLE	  BIT(2)
247 #define SUNXI_PTE_PAGE_VALID		  BIT(1)
248 
249 #define IS_VALID(x)	(((x) & 0x03) == DENT_VALID)
250 
251 #define IOPDE_INDEX(va)	(((va) >> IOMMU_PD_SHIFT) & (NUM_ENTRIES_PDE - 1))
252 #define IOPTE_INDEX(va)	(((va) >> IOMMU_PT_SHIFT) & (NUM_ENTRIES_PTE - 1))
253 
254 #define IOPTE_BASE(ent) ((ent) & IOPTE_BASE_MASK)
255 
256 #define IOPTE_TO_PFN(ent) ((*ent) & IOMMU_PT_MASK)
257 #define IOVA_PAGE_OFT(va) ((va) & PAGE_OFFSET_MASK)
258 
259 #define SPAGE_SIZE (1 << IOMMU_PT_SHIFT)
260 #define SPD_SIZE (1 << IOMMU_PD_SHIFT)
261 #define SPAGE_ALIGN(addr) ALIGN(addr, SPAGE_SIZE)
262 #define SPDE_ALIGN(addr) ALIGN(addr, SPD_SIZE)
263 #define MAX_SG_SIZE  (128 << 20)
264 #define MAX_SG_TABLE_SIZE ((MAX_SG_SIZE / SPAGE_SIZE) * sizeof(u32))
265 
266 /* IO virtual address start page frame number */
267 #define IOVA_START_PFN		(1)
268 #define IOVA_PFN(addr)		((addr) >> PAGE_SHIFT)
269 #define DMA_32BIT_PFN		IOVA_PFN(DMA_BIT_MASK(32))
270 
271 /* TLB Invalid ALIGN */
272 #define IOVA_4M_ALIGN(iova)	((iova) & (~0x3fffff))
273 
274 #define SUNXI_PHYS_OFFSET    	0x40000000UL
275 #define SUNXI_4G_PHYS_OFFSET    0x100000000UL
276 
277 /**
278  * sun8iw15p1
279  *	DE :		masterID 0
280  *	E_EDMA:		masterID 1
281  *	E_FE:		masterID 2
282  *	VE:		masterID 3
283  *	CSI:		masterID 4
284  *	G2D:		masterID 5
285  *	E_BE:		masterID 6
286  *
287  * sun50iw9p1:
288  *	DE :		masterID 0
289  *	DI:			masterID 1
290  *	VE_R:		masterID 2
291  *	VE:			masterID 3
292  *	CSI0:		masterID 4
293  *	CSI1:		masterID 5
294  *	G2D:		masterID 6
295  * sun8iw19p1:
296  *	DE :>--->-------masterID 0
297  *	EISE:		masterID 1
298  *	AI:		masterID 2
299  *	VE:>---->-------masterID 3
300  *	CSI:	>-->----masterID 4
301  *	ISP:>-->------	masterID 5
302  *	G2D:>--->-------masterID 6
303  */
304 #define DEFAULT_BYPASS_VALUE     0x7f
305 static const u32 master_id_bitmap[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40};
306 
307 #define sunxi_wait_when(COND, MS) ({ \
308 	unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1;	\
309 	int ret__ = 0;							\
310 	while ((COND)) {						\
311 		if (time_after(jiffies, timeout__)) {			\
312 			ret__ = (!COND) ? 0 : -ETIMEDOUT;		\
313 			break;						\
314 		}							\
315 		udelay(1);					\
316 	}								\
317 	ret__;								\
318 })
319 
320 /*
321  * The format of device tree, and client device how to use it.
322  *
323  * /{
324  *	....
325  *	smmu: iommu@xxxxx {
326  *		compatible = "allwinner,iommu";
327  *		reg = <xxx xxx xxx xxx>;
328  *		interrupts = <GIC_SPI xxx IRQ_TYPE_LEVEL_HIGH>;
329  *		interrupt-names = "iommu-irq";
330  *		clocks = <&iommu_clk>;
331  *		clock-name = "iommu-clk";
332  *		#iommu-cells = <1>;
333  *		status = "enabled";
334  *	};
335  *
336  *	de@xxxxx {
337  *		.....
338  *		iommus = <&smmu ID>;
339  *	};
340  *
341  * }
342  *
343  * Here, ID number is 0 ~ 5, every client device have a unique id.
344  * Every id represent a micro TLB, also represent a master device.
345  *
346  */
347 
348 enum sunxi_iommu_version {
349 	IOMMU_VERSION_V10 = 0x10,
350 	IOMMU_VERSION_V11,
351 	IOMMU_VERSION_V12,
352 	IOMMU_VERSION_V13,
353 	IOMMU_VERSION_V14,
354 };
355 
356 struct sunxi_iommu_plat_data {
357 	u32 version;
358 	u32 tlb_prefetch;
359 	u32 tlb_invalid_mode;
360 	u32 ptw_invalid_mode;
361 	const char *master[8];
362 };
363 
364 struct sunxi_iommu_dev {
365 	struct iommu_device iommu;
366 	struct device *dev;
367 	void __iomem *base;
368 	struct clk *clk;
369 	int irq;
370 	u32 bypass;
371 	spinlock_t iommu_lock;
372 	const struct sunxi_iommu_plat_data *plat_data;
373 };
374 
375 struct sunxi_iommu_domain {
376 	unsigned int *pgtable;		/* first page directory, size is 16KB */
377 	u32 *sg_buffer;
378 	struct mutex  dt_lock;	/* lock for modifying page table @ pgtable */
379 	struct dma_iommu_mapping *mapping;
380 	struct iommu_domain domain;
381 	//struct iova_domain iovad;
382 	/* list of master device, it represent a micro TLB */
383 	struct list_head mdevs;
384 	spinlock_t lock;
385 };
386 
387 /*
388  * sunxi master device which use iommu.
389  */
390 struct sunxi_mdev {
391 	struct list_head node;	/* for sunxi_iommu mdevs list */
392 	struct device *dev;	/* the master device */
393 	unsigned int tlbid;	/* micro TLB id, distinguish device by it */
394 	bool flag;
395 };
396 
397 struct sunxi_iommu_owner {
398 	unsigned int tlbid;
399 	bool flag;
400 	struct sunxi_iommu_dev *data;
401 	struct device *dev;
402 	struct dma_iommu_mapping *mapping;
403 };
404 
405 int sunxi_iova_test_write(dma_addr_t iova, u32 val);
406 unsigned long sunxi_iova_test_read(dma_addr_t iova);
407 void sunxi_set_debug_mode(void);
408 void sunxi_set_prefetch_mode(void);
409 extern struct iommu_domain *global_iommu_domain;
410 
411 
412