1 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include <linux/kernel.h>
19 #include <linux/platform_device.h>
20 #include <linux/bootmem.h>
21 #include <linux/module.h>
22 #include <mach/irqs.h>
23 #include <mach/iommu.h>
24 
25 static struct resource msm_iommu_jpegd_resources[] = {
26 	{
27 		.start = 0x07300000,
28 		.end   = 0x07300000 + SZ_1M - 1,
29 		.name  = "physbase",
30 		.flags = IORESOURCE_MEM,
31 	},
32 	{
33 		.name = "nonsecure_irq",
34 		.start = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
35 		.end   = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
36 		.flags = IORESOURCE_IRQ,
37 	},
38 	{
39 		.name = "secure_irq",
40 		.start = SMMU_JPEGD_CB_SC_SECURE_IRQ,
41 		.end   = SMMU_JPEGD_CB_SC_SECURE_IRQ,
42 		.flags = IORESOURCE_IRQ,
43 	},
44 };
45 
46 static struct resource msm_iommu_vpe_resources[] = {
47 	{
48 		.start = 0x07400000,
49 		.end   = 0x07400000 + SZ_1M - 1,
50 		.name  = "physbase",
51 		.flags = IORESOURCE_MEM,
52 	},
53 	{
54 		.name = "nonsecure_irq",
55 		.start = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
56 		.end   = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
57 		.flags = IORESOURCE_IRQ,
58 	},
59 	{
60 		.name = "secure_irq",
61 		.start = SMMU_VPE_CB_SC_SECURE_IRQ,
62 		.end   = SMMU_VPE_CB_SC_SECURE_IRQ,
63 		.flags = IORESOURCE_IRQ,
64 	},
65 };
66 
67 static struct resource msm_iommu_mdp0_resources[] = {
68 	{
69 		.start = 0x07500000,
70 		.end   = 0x07500000 + SZ_1M - 1,
71 		.name  = "physbase",
72 		.flags = IORESOURCE_MEM,
73 	},
74 	{
75 		.name = "nonsecure_irq",
76 		.start = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
77 		.end   = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
78 		.flags = IORESOURCE_IRQ,
79 	},
80 	{
81 		.name = "secure_irq",
82 		.start = SMMU_MDP0_CB_SC_SECURE_IRQ,
83 		.end   = SMMU_MDP0_CB_SC_SECURE_IRQ,
84 		.flags = IORESOURCE_IRQ,
85 	},
86 };
87 
88 static struct resource msm_iommu_mdp1_resources[] = {
89 	{
90 		.start = 0x07600000,
91 		.end   = 0x07600000 + SZ_1M - 1,
92 		.name  = "physbase",
93 		.flags = IORESOURCE_MEM,
94 	},
95 	{
96 		.name = "nonsecure_irq",
97 		.start = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
98 		.end   = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
99 		.flags = IORESOURCE_IRQ,
100 	},
101 	{
102 		.name = "secure_irq",
103 		.start = SMMU_MDP1_CB_SC_SECURE_IRQ,
104 		.end   = SMMU_MDP1_CB_SC_SECURE_IRQ,
105 		.flags = IORESOURCE_IRQ,
106 	},
107 };
108 
109 static struct resource msm_iommu_rot_resources[] = {
110 	{
111 		.start = 0x07700000,
112 		.end   = 0x07700000 + SZ_1M - 1,
113 		.name  = "physbase",
114 		.flags = IORESOURCE_MEM,
115 	},
116 	{
117 		.name = "nonsecure_irq",
118 		.start = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
119 		.end   = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
120 		.flags = IORESOURCE_IRQ,
121 	},
122 	{
123 		.name = "secure_irq",
124 		.start = SMMU_ROT_CB_SC_SECURE_IRQ,
125 		.end   = SMMU_ROT_CB_SC_SECURE_IRQ,
126 		.flags = IORESOURCE_IRQ,
127 	},
128 };
129 
130 static struct resource msm_iommu_ijpeg_resources[] = {
131 	{
132 		.start = 0x07800000,
133 		.end   = 0x07800000 + SZ_1M - 1,
134 		.name  = "physbase",
135 		.flags = IORESOURCE_MEM,
136 	},
137 	{
138 		.name = "nonsecure_irq",
139 		.start = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
140 		.end   = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
141 		.flags = IORESOURCE_IRQ,
142 	},
143 	{
144 		.name = "secure_irq",
145 		.start = SMMU_IJPEG_CB_SC_SECURE_IRQ,
146 		.end   = SMMU_IJPEG_CB_SC_SECURE_IRQ,
147 		.flags = IORESOURCE_IRQ,
148 	},
149 };
150 
151 static struct resource msm_iommu_vfe_resources[] = {
152 	{
153 		.start = 0x07900000,
154 		.end   = 0x07900000 + SZ_1M - 1,
155 		.name  = "physbase",
156 		.flags = IORESOURCE_MEM,
157 	},
158 	{
159 		.name = "nonsecure_irq",
160 		.start = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
161 		.end   = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
162 		.flags = IORESOURCE_IRQ,
163 	},
164 	{
165 		.name = "secure_irq",
166 		.start = SMMU_VFE_CB_SC_SECURE_IRQ,
167 		.end   = SMMU_VFE_CB_SC_SECURE_IRQ,
168 		.flags = IORESOURCE_IRQ,
169 	},
170 };
171 
172 static struct resource msm_iommu_vcodec_a_resources[] = {
173 	{
174 		.start = 0x07A00000,
175 		.end   = 0x07A00000 + SZ_1M - 1,
176 		.name  = "physbase",
177 		.flags = IORESOURCE_MEM,
178 	},
179 	{
180 		.name = "nonsecure_irq",
181 		.start = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
182 		.end   = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
183 		.flags = IORESOURCE_IRQ,
184 	},
185 	{
186 		.name = "secure_irq",
187 		.start = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
188 		.end   = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
189 		.flags = IORESOURCE_IRQ,
190 	},
191 };
192 
193 static struct resource msm_iommu_vcodec_b_resources[] = {
194 	{
195 		.start = 0x07B00000,
196 		.end   = 0x07B00000 + SZ_1M - 1,
197 		.name  = "physbase",
198 		.flags = IORESOURCE_MEM,
199 	},
200 	{
201 		.name = "nonsecure_irq",
202 		.start = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
203 		.end   = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
204 		.flags = IORESOURCE_IRQ,
205 	},
206 	{
207 		.name = "secure_irq",
208 		.start = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
209 		.end   = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
210 		.flags = IORESOURCE_IRQ,
211 	},
212 };
213 
214 static struct resource msm_iommu_gfx3d_resources[] = {
215 	{
216 		.start = 0x07C00000,
217 		.end   = 0x07C00000 + SZ_1M - 1,
218 		.name  = "physbase",
219 		.flags = IORESOURCE_MEM,
220 	},
221 	{
222 		.name = "nonsecure_irq",
223 		.start = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
224 		.end   = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
225 		.flags = IORESOURCE_IRQ,
226 	},
227 	{
228 		.name = "secure_irq",
229 		.start = SMMU_GFX3D_CB_SC_SECURE_IRQ,
230 		.end   = SMMU_GFX3D_CB_SC_SECURE_IRQ,
231 		.flags = IORESOURCE_IRQ,
232 	},
233 };
234 
235 static struct resource msm_iommu_gfx2d0_resources[] = {
236 	{
237 		.start = 0x07D00000,
238 		.end   = 0x07D00000 + SZ_1M - 1,
239 		.name  = "physbase",
240 		.flags = IORESOURCE_MEM,
241 	},
242 	{
243 		.name = "nonsecure_irq",
244 		.start = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
245 		.end   = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
246 		.flags = IORESOURCE_IRQ,
247 	},
248 	{
249 		.name = "secure_irq",
250 		.start = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
251 		.end   = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
252 		.flags = IORESOURCE_IRQ,
253 	},
254 };
255 
256 static struct resource msm_iommu_gfx2d1_resources[] = {
257 	{
258 		.start = 0x07E00000,
259 		.end   = 0x07E00000 + SZ_1M - 1,
260 		.name  = "physbase",
261 		.flags = IORESOURCE_MEM,
262 	},
263 	{
264 		.name = "nonsecure_irq",
265 		.start = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
266 		.end   = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
267 		.flags = IORESOURCE_IRQ,
268 	},
269 	{
270 		.name = "secure_irq",
271 		.start = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
272 		.end   = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
273 		.flags = IORESOURCE_IRQ,
274 	},
275 };
276 
277 static struct platform_device msm_root_iommu_dev = {
278 	.name = "msm_iommu",
279 	.id = -1,
280 };
281 
282 static struct msm_iommu_dev jpegd_iommu = {
283 	.name = "jpegd",
284 	.ncb = 2,
285 };
286 
287 static struct msm_iommu_dev vpe_iommu = {
288 	.name = "vpe",
289 	.ncb = 2,
290 };
291 
292 static struct msm_iommu_dev mdp0_iommu = {
293 	.name = "mdp0",
294 	.ncb = 2,
295 };
296 
297 static struct msm_iommu_dev mdp1_iommu = {
298 	.name = "mdp1",
299 	.ncb = 2,
300 };
301 
302 static struct msm_iommu_dev rot_iommu = {
303 	.name = "rot",
304 	.ncb = 2,
305 };
306 
307 static struct msm_iommu_dev ijpeg_iommu = {
308 	.name = "ijpeg",
309 	.ncb = 2,
310 };
311 
312 static struct msm_iommu_dev vfe_iommu = {
313 	.name = "vfe",
314 	.ncb = 2,
315 };
316 
317 static struct msm_iommu_dev vcodec_a_iommu = {
318 	.name = "vcodec_a",
319 	.ncb = 2,
320 };
321 
322 static struct msm_iommu_dev vcodec_b_iommu = {
323 	.name = "vcodec_b",
324 	.ncb = 2,
325 };
326 
327 static struct msm_iommu_dev gfx3d_iommu = {
328 	.name = "gfx3d",
329 	.ncb = 3,
330 };
331 
332 static struct msm_iommu_dev gfx2d0_iommu = {
333 	.name = "gfx2d0",
334 	.ncb = 2,
335 };
336 
337 static struct msm_iommu_dev gfx2d1_iommu = {
338 	.name = "gfx2d1",
339 	.ncb = 2,
340 };
341 
342 static struct platform_device msm_device_iommu_jpegd = {
343 	.name = "msm_iommu",
344 	.id = 0,
345 	.dev = {
346 		.parent = &msm_root_iommu_dev.dev,
347 	},
348 	.num_resources = ARRAY_SIZE(msm_iommu_jpegd_resources),
349 	.resource = msm_iommu_jpegd_resources,
350 };
351 
352 static struct platform_device msm_device_iommu_vpe = {
353 	.name = "msm_iommu",
354 	.id = 1,
355 	.dev = {
356 		.parent = &msm_root_iommu_dev.dev,
357 	},
358 	.num_resources = ARRAY_SIZE(msm_iommu_vpe_resources),
359 	.resource = msm_iommu_vpe_resources,
360 };
361 
362 static struct platform_device msm_device_iommu_mdp0 = {
363 	.name = "msm_iommu",
364 	.id = 2,
365 	.dev = {
366 		.parent = &msm_root_iommu_dev.dev,
367 	},
368 	.num_resources = ARRAY_SIZE(msm_iommu_mdp0_resources),
369 	.resource = msm_iommu_mdp0_resources,
370 };
371 
372 static struct platform_device msm_device_iommu_mdp1 = {
373 	.name = "msm_iommu",
374 	.id = 3,
375 	.dev = {
376 		.parent = &msm_root_iommu_dev.dev,
377 	},
378 	.num_resources = ARRAY_SIZE(msm_iommu_mdp1_resources),
379 	.resource = msm_iommu_mdp1_resources,
380 };
381 
382 static struct platform_device msm_device_iommu_rot = {
383 	.name = "msm_iommu",
384 	.id = 4,
385 	.dev = {
386 		.parent = &msm_root_iommu_dev.dev,
387 	},
388 	.num_resources = ARRAY_SIZE(msm_iommu_rot_resources),
389 	.resource = msm_iommu_rot_resources,
390 };
391 
392 static struct platform_device msm_device_iommu_ijpeg = {
393 	.name = "msm_iommu",
394 	.id = 5,
395 	.dev = {
396 		.parent = &msm_root_iommu_dev.dev,
397 	},
398 	.num_resources = ARRAY_SIZE(msm_iommu_ijpeg_resources),
399 	.resource = msm_iommu_ijpeg_resources,
400 };
401 
402 static struct platform_device msm_device_iommu_vfe = {
403 	.name = "msm_iommu",
404 	.id = 6,
405 	.dev = {
406 		.parent = &msm_root_iommu_dev.dev,
407 	},
408 	.num_resources = ARRAY_SIZE(msm_iommu_vfe_resources),
409 	.resource = msm_iommu_vfe_resources,
410 };
411 
412 static struct platform_device msm_device_iommu_vcodec_a = {
413 	.name = "msm_iommu",
414 	.id = 7,
415 	.dev = {
416 		.parent = &msm_root_iommu_dev.dev,
417 	},
418 	.num_resources = ARRAY_SIZE(msm_iommu_vcodec_a_resources),
419 	.resource = msm_iommu_vcodec_a_resources,
420 };
421 
422 static struct platform_device msm_device_iommu_vcodec_b = {
423 	.name = "msm_iommu",
424 	.id = 8,
425 	.dev = {
426 		.parent = &msm_root_iommu_dev.dev,
427 	},
428 	.num_resources = ARRAY_SIZE(msm_iommu_vcodec_b_resources),
429 	.resource = msm_iommu_vcodec_b_resources,
430 };
431 
432 static struct platform_device msm_device_iommu_gfx3d = {
433 	.name = "msm_iommu",
434 	.id = 9,
435 	.dev = {
436 		.parent = &msm_root_iommu_dev.dev,
437 	},
438 	.num_resources = ARRAY_SIZE(msm_iommu_gfx3d_resources),
439 	.resource = msm_iommu_gfx3d_resources,
440 };
441 
442 static struct platform_device msm_device_iommu_gfx2d0 = {
443 	.name = "msm_iommu",
444 	.id = 10,
445 	.dev = {
446 		.parent = &msm_root_iommu_dev.dev,
447 	},
448 	.num_resources = ARRAY_SIZE(msm_iommu_gfx2d0_resources),
449 	.resource = msm_iommu_gfx2d0_resources,
450 };
451 
452 struct platform_device msm_device_iommu_gfx2d1 = {
453 	.name = "msm_iommu",
454 	.id = 11,
455 	.dev = {
456 		.parent = &msm_root_iommu_dev.dev,
457 	},
458 	.num_resources = ARRAY_SIZE(msm_iommu_gfx2d1_resources),
459 	.resource = msm_iommu_gfx2d1_resources,
460 };
461 
462 static struct msm_iommu_ctx_dev jpegd_src_ctx = {
463 	.name = "jpegd_src",
464 	.num = 0,
465 	.mids = {0, -1}
466 };
467 
468 static struct msm_iommu_ctx_dev jpegd_dst_ctx = {
469 	.name = "jpegd_dst",
470 	.num = 1,
471 	.mids = {1, -1}
472 };
473 
474 static struct msm_iommu_ctx_dev vpe_src_ctx = {
475 	.name = "vpe_src",
476 	.num = 0,
477 	.mids = {0, -1}
478 };
479 
480 static struct msm_iommu_ctx_dev vpe_dst_ctx = {
481 	.name = "vpe_dst",
482 	.num = 1,
483 	.mids = {1, -1}
484 };
485 
486 static struct msm_iommu_ctx_dev mdp_vg1_ctx = {
487 	.name = "mdp_vg1",
488 	.num = 0,
489 	.mids = {0, 2, -1}
490 };
491 
492 static struct msm_iommu_ctx_dev mdp_rgb1_ctx = {
493 	.name = "mdp_rgb1",
494 	.num = 1,
495 	.mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
496 };
497 
498 static struct msm_iommu_ctx_dev mdp_vg2_ctx = {
499 	.name = "mdp_vg2",
500 	.num = 0,
501 	.mids = {0, 2, -1}
502 };
503 
504 static struct msm_iommu_ctx_dev mdp_rgb2_ctx = {
505 	.name = "mdp_rgb2",
506 	.num = 1,
507 	.mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
508 };
509 
510 static struct msm_iommu_ctx_dev rot_src_ctx = {
511 	.name = "rot_src",
512 	.num = 0,
513 	.mids = {0, -1}
514 };
515 
516 static struct msm_iommu_ctx_dev rot_dst_ctx = {
517 	.name = "rot_dst",
518 	.num = 1,
519 	.mids = {1, -1}
520 };
521 
522 static struct msm_iommu_ctx_dev ijpeg_src_ctx = {
523 	.name = "ijpeg_src",
524 	.num = 0,
525 	.mids = {0, -1}
526 };
527 
528 static struct msm_iommu_ctx_dev ijpeg_dst_ctx = {
529 	.name = "ijpeg_dst",
530 	.num = 1,
531 	.mids = {1, -1}
532 };
533 
534 static struct msm_iommu_ctx_dev vfe_imgwr_ctx = {
535 	.name = "vfe_imgwr",
536 	.num = 0,
537 	.mids = {2, 3, 4, 5, 6, 7, 8, -1}
538 };
539 
540 static struct msm_iommu_ctx_dev vfe_misc_ctx = {
541 	.name = "vfe_misc",
542 	.num = 1,
543 	.mids = {0, 1, 9, -1}
544 };
545 
546 static struct msm_iommu_ctx_dev vcodec_a_stream_ctx = {
547 	.name = "vcodec_a_stream",
548 	.num = 0,
549 	.mids = {2, 5, -1}
550 };
551 
552 static struct msm_iommu_ctx_dev vcodec_a_mm1_ctx = {
553 	.name = "vcodec_a_mm1",
554 	.num = 1,
555 	.mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
556 };
557 
558 static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = {
559 	.name = "vcodec_b_mm2",
560 	.num = 0,
561 	.mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
562 };
563 
564 static struct msm_iommu_ctx_dev gfx3d_user_ctx = {
565 	.name = "gfx3d_user",
566 	.num = 0,
567 	.mids = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
568 };
569 
570 static struct msm_iommu_ctx_dev gfx3d_priv_ctx = {
571 	.name = "gfx3d_priv",
572 	.num = 1,
573 	.mids = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
574 		 31, -1}
575 };
576 
577 static struct msm_iommu_ctx_dev gfx2d0_2d0_ctx = {
578 	.name = "gfx2d0_2d0",
579 	.num = 0,
580 	.mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
581 };
582 
583 static struct msm_iommu_ctx_dev gfx2d1_2d1_ctx = {
584 	.name = "gfx2d1_2d1",
585 	.num = 0,
586 	.mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
587 };
588 
589 static struct platform_device msm_device_jpegd_src_ctx = {
590 	.name = "msm_iommu_ctx",
591 	.id = 0,
592 	.dev = {
593 		.parent = &msm_device_iommu_jpegd.dev,
594 	},
595 };
596 
597 static struct platform_device msm_device_jpegd_dst_ctx = {
598 	.name = "msm_iommu_ctx",
599 	.id = 1,
600 	.dev = {
601 		.parent = &msm_device_iommu_jpegd.dev,
602 	},
603 };
604 
605 static struct platform_device msm_device_vpe_src_ctx = {
606 	.name = "msm_iommu_ctx",
607 	.id = 2,
608 	.dev = {
609 		.parent = &msm_device_iommu_vpe.dev,
610 	},
611 };
612 
613 static struct platform_device msm_device_vpe_dst_ctx = {
614 	.name = "msm_iommu_ctx",
615 	.id = 3,
616 	.dev = {
617 		.parent = &msm_device_iommu_vpe.dev,
618 	},
619 };
620 
621 static struct platform_device msm_device_mdp_vg1_ctx = {
622 	.name = "msm_iommu_ctx",
623 	.id = 4,
624 	.dev = {
625 		.parent = &msm_device_iommu_mdp0.dev,
626 	},
627 };
628 
629 static struct platform_device msm_device_mdp_rgb1_ctx = {
630 	.name = "msm_iommu_ctx",
631 	.id = 5,
632 	.dev = {
633 		.parent = &msm_device_iommu_mdp0.dev,
634 	},
635 };
636 
637 static struct platform_device msm_device_mdp_vg2_ctx = {
638 	.name = "msm_iommu_ctx",
639 	.id = 6,
640 	.dev = {
641 		.parent = &msm_device_iommu_mdp1.dev,
642 	},
643 };
644 
645 static struct platform_device msm_device_mdp_rgb2_ctx = {
646 	.name = "msm_iommu_ctx",
647 	.id = 7,
648 	.dev = {
649 		.parent = &msm_device_iommu_mdp1.dev,
650 	},
651 };
652 
653 static struct platform_device msm_device_rot_src_ctx = {
654 	.name = "msm_iommu_ctx",
655 	.id = 8,
656 	.dev = {
657 		.parent = &msm_device_iommu_rot.dev,
658 	},
659 };
660 
661 static struct platform_device msm_device_rot_dst_ctx = {
662 	.name = "msm_iommu_ctx",
663 	.id = 9,
664 	.dev = {
665 		.parent = &msm_device_iommu_rot.dev,
666 	},
667 };
668 
669 static struct platform_device msm_device_ijpeg_src_ctx = {
670 	.name = "msm_iommu_ctx",
671 	.id = 10,
672 	.dev = {
673 		.parent = &msm_device_iommu_ijpeg.dev,
674 	},
675 };
676 
677 static struct platform_device msm_device_ijpeg_dst_ctx = {
678 	.name = "msm_iommu_ctx",
679 	.id = 11,
680 	.dev = {
681 		.parent = &msm_device_iommu_ijpeg.dev,
682 	},
683 };
684 
685 static struct platform_device msm_device_vfe_imgwr_ctx = {
686 	.name = "msm_iommu_ctx",
687 	.id = 12,
688 	.dev = {
689 		.parent = &msm_device_iommu_vfe.dev,
690 	},
691 };
692 
693 static struct platform_device msm_device_vfe_misc_ctx = {
694 	.name = "msm_iommu_ctx",
695 	.id = 13,
696 	.dev = {
697 		.parent = &msm_device_iommu_vfe.dev,
698 	},
699 };
700 
701 static struct platform_device msm_device_vcodec_a_stream_ctx = {
702 	.name = "msm_iommu_ctx",
703 	.id = 14,
704 	.dev = {
705 		.parent = &msm_device_iommu_vcodec_a.dev,
706 	},
707 };
708 
709 static struct platform_device msm_device_vcodec_a_mm1_ctx = {
710 	.name = "msm_iommu_ctx",
711 	.id = 15,
712 	.dev = {
713 		.parent = &msm_device_iommu_vcodec_a.dev,
714 	},
715 };
716 
717 static struct platform_device msm_device_vcodec_b_mm2_ctx = {
718 	.name = "msm_iommu_ctx",
719 	.id = 16,
720 	.dev = {
721 		.parent = &msm_device_iommu_vcodec_b.dev,
722 	},
723 };
724 
725 static struct platform_device msm_device_gfx3d_user_ctx = {
726 	.name = "msm_iommu_ctx",
727 	.id = 17,
728 	.dev = {
729 		.parent = &msm_device_iommu_gfx3d.dev,
730 	},
731 };
732 
733 static struct platform_device msm_device_gfx3d_priv_ctx = {
734 	.name = "msm_iommu_ctx",
735 	.id = 18,
736 	.dev = {
737 		.parent = &msm_device_iommu_gfx3d.dev,
738 	},
739 };
740 
741 static struct platform_device msm_device_gfx2d0_2d0_ctx = {
742 	.name = "msm_iommu_ctx",
743 	.id = 19,
744 	.dev = {
745 		.parent = &msm_device_iommu_gfx2d0.dev,
746 	},
747 };
748 
749 static struct platform_device msm_device_gfx2d1_2d1_ctx = {
750 	.name = "msm_iommu_ctx",
751 	.id = 20,
752 	.dev = {
753 		.parent = &msm_device_iommu_gfx2d1.dev,
754 	},
755 };
756 
757 static struct platform_device *msm_iommu_devs[] = {
758 	&msm_device_iommu_jpegd,
759 	&msm_device_iommu_vpe,
760 	&msm_device_iommu_mdp0,
761 	&msm_device_iommu_mdp1,
762 	&msm_device_iommu_rot,
763 	&msm_device_iommu_ijpeg,
764 	&msm_device_iommu_vfe,
765 	&msm_device_iommu_vcodec_a,
766 	&msm_device_iommu_vcodec_b,
767 	&msm_device_iommu_gfx3d,
768 	&msm_device_iommu_gfx2d0,
769 	&msm_device_iommu_gfx2d1,
770 };
771 
772 static struct msm_iommu_dev *msm_iommu_data[] = {
773 	&jpegd_iommu,
774 	&vpe_iommu,
775 	&mdp0_iommu,
776 	&mdp1_iommu,
777 	&rot_iommu,
778 	&ijpeg_iommu,
779 	&vfe_iommu,
780 	&vcodec_a_iommu,
781 	&vcodec_b_iommu,
782 	&gfx3d_iommu,
783 	&gfx2d0_iommu,
784 	&gfx2d1_iommu,
785 };
786 
787 static struct platform_device *msm_iommu_ctx_devs[] = {
788 	&msm_device_jpegd_src_ctx,
789 	&msm_device_jpegd_dst_ctx,
790 	&msm_device_vpe_src_ctx,
791 	&msm_device_vpe_dst_ctx,
792 	&msm_device_mdp_vg1_ctx,
793 	&msm_device_mdp_rgb1_ctx,
794 	&msm_device_mdp_vg2_ctx,
795 	&msm_device_mdp_rgb2_ctx,
796 	&msm_device_rot_src_ctx,
797 	&msm_device_rot_dst_ctx,
798 	&msm_device_ijpeg_src_ctx,
799 	&msm_device_ijpeg_dst_ctx,
800 	&msm_device_vfe_imgwr_ctx,
801 	&msm_device_vfe_misc_ctx,
802 	&msm_device_vcodec_a_stream_ctx,
803 	&msm_device_vcodec_a_mm1_ctx,
804 	&msm_device_vcodec_b_mm2_ctx,
805 	&msm_device_gfx3d_user_ctx,
806 	&msm_device_gfx3d_priv_ctx,
807 	&msm_device_gfx2d0_2d0_ctx,
808 	&msm_device_gfx2d1_2d1_ctx,
809 };
810 
811 static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
812 	&jpegd_src_ctx,
813 	&jpegd_dst_ctx,
814 	&vpe_src_ctx,
815 	&vpe_dst_ctx,
816 	&mdp_vg1_ctx,
817 	&mdp_rgb1_ctx,
818 	&mdp_vg2_ctx,
819 	&mdp_rgb2_ctx,
820 	&rot_src_ctx,
821 	&rot_dst_ctx,
822 	&ijpeg_src_ctx,
823 	&ijpeg_dst_ctx,
824 	&vfe_imgwr_ctx,
825 	&vfe_misc_ctx,
826 	&vcodec_a_stream_ctx,
827 	&vcodec_a_mm1_ctx,
828 	&vcodec_b_mm2_ctx,
829 	&gfx3d_user_ctx,
830 	&gfx3d_priv_ctx,
831 	&gfx2d0_2d0_ctx,
832 	&gfx2d1_2d1_ctx,
833 };
834 
msm8x60_iommu_init(void)835 static int __init msm8x60_iommu_init(void)
836 {
837 	int ret, i;
838 
839 	ret = platform_device_register(&msm_root_iommu_dev);
840 	if (ret != 0) {
841 		pr_err("Failed to register root IOMMU device!\n");
842 		goto failure;
843 	}
844 
845 	for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); i++) {
846 		ret = platform_device_add_data(msm_iommu_devs[i],
847 					       msm_iommu_data[i],
848 					       sizeof(struct msm_iommu_dev));
849 		if (ret != 0) {
850 			pr_err("platform_device_add_data failed, "
851 			       "i = %d\n", i);
852 			goto failure_unwind;
853 		}
854 
855 		ret = platform_device_register(msm_iommu_devs[i]);
856 
857 		if (ret != 0) {
858 			pr_err("platform_device_register iommu failed, "
859 			       "i = %d\n", i);
860 			goto failure_unwind;
861 		}
862 	}
863 
864 	for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++) {
865 		ret = platform_device_add_data(msm_iommu_ctx_devs[i],
866 					       msm_iommu_ctx_data[i],
867 					       sizeof(*msm_iommu_ctx_devs[i]));
868 		if (ret != 0) {
869 			pr_err("platform_device_add_data iommu failed, "
870 			       "i = %d\n", i);
871 			goto failure_unwind2;
872 		}
873 
874 		ret = platform_device_register(msm_iommu_ctx_devs[i]);
875 		if (ret != 0) {
876 			pr_err("platform_device_register ctx failed, "
877 			       "i = %d\n", i);
878 			goto failure_unwind2;
879 		}
880 	}
881 	return 0;
882 
883 failure_unwind2:
884 	while (--i >= 0)
885 		platform_device_unregister(msm_iommu_ctx_devs[i]);
886 failure_unwind:
887 	while (--i >= 0)
888 		platform_device_unregister(msm_iommu_devs[i]);
889 
890 	platform_device_unregister(&msm_root_iommu_dev);
891 failure:
892 	return ret;
893 }
894 
msm8x60_iommu_exit(void)895 static void __exit msm8x60_iommu_exit(void)
896 {
897 	int i;
898 
899 	for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++)
900 		platform_device_unregister(msm_iommu_ctx_devs[i]);
901 
902 	for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); ++i)
903 		platform_device_unregister(msm_iommu_devs[i]);
904 
905 	platform_device_unregister(&msm_root_iommu_dev);
906 }
907 
908 subsys_initcall(msm8x60_iommu_init);
909 module_exit(msm8x60_iommu_exit);
910 
911 MODULE_LICENSE("GPL v2");
912 MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
913