1
/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
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.
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.
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
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>
25
static struct resource msm_iommu_jpegd_resources[] = {
28
.end = 0x07300000 + SZ_1M - 1,
30
.flags = IORESOURCE_MEM,
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,
40
.start = SMMU_JPEGD_CB_SC_SECURE_IRQ,
41
.end = SMMU_JPEGD_CB_SC_SECURE_IRQ,
42
.flags = IORESOURCE_IRQ,
46
static struct resource msm_iommu_vpe_resources[] = {
49
.end = 0x07400000 + SZ_1M - 1,
51
.flags = IORESOURCE_MEM,
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,
61
.start = SMMU_VPE_CB_SC_SECURE_IRQ,
62
.end = SMMU_VPE_CB_SC_SECURE_IRQ,
63
.flags = IORESOURCE_IRQ,
67
static struct resource msm_iommu_mdp0_resources[] = {
70
.end = 0x07500000 + SZ_1M - 1,
72
.flags = IORESOURCE_MEM,
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,
82
.start = SMMU_MDP0_CB_SC_SECURE_IRQ,
83
.end = SMMU_MDP0_CB_SC_SECURE_IRQ,
84
.flags = IORESOURCE_IRQ,
88
static struct resource msm_iommu_mdp1_resources[] = {
91
.end = 0x07600000 + SZ_1M - 1,
93
.flags = IORESOURCE_MEM,
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,
102
.name = "secure_irq",
103
.start = SMMU_MDP1_CB_SC_SECURE_IRQ,
104
.end = SMMU_MDP1_CB_SC_SECURE_IRQ,
105
.flags = IORESOURCE_IRQ,
109
static struct resource msm_iommu_rot_resources[] = {
112
.end = 0x07700000 + SZ_1M - 1,
114
.flags = IORESOURCE_MEM,
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,
123
.name = "secure_irq",
124
.start = SMMU_ROT_CB_SC_SECURE_IRQ,
125
.end = SMMU_ROT_CB_SC_SECURE_IRQ,
126
.flags = IORESOURCE_IRQ,
130
static struct resource msm_iommu_ijpeg_resources[] = {
133
.end = 0x07800000 + SZ_1M - 1,
135
.flags = IORESOURCE_MEM,
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,
144
.name = "secure_irq",
145
.start = SMMU_IJPEG_CB_SC_SECURE_IRQ,
146
.end = SMMU_IJPEG_CB_SC_SECURE_IRQ,
147
.flags = IORESOURCE_IRQ,
151
static struct resource msm_iommu_vfe_resources[] = {
154
.end = 0x07900000 + SZ_1M - 1,
156
.flags = IORESOURCE_MEM,
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,
165
.name = "secure_irq",
166
.start = SMMU_VFE_CB_SC_SECURE_IRQ,
167
.end = SMMU_VFE_CB_SC_SECURE_IRQ,
168
.flags = IORESOURCE_IRQ,
172
static struct resource msm_iommu_vcodec_a_resources[] = {
175
.end = 0x07A00000 + SZ_1M - 1,
177
.flags = IORESOURCE_MEM,
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,
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,
193
static struct resource msm_iommu_vcodec_b_resources[] = {
196
.end = 0x07B00000 + SZ_1M - 1,
198
.flags = IORESOURCE_MEM,
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,
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,
214
static struct resource msm_iommu_gfx3d_resources[] = {
217
.end = 0x07C00000 + SZ_1M - 1,
219
.flags = IORESOURCE_MEM,
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,
228
.name = "secure_irq",
229
.start = SMMU_GFX3D_CB_SC_SECURE_IRQ,
230
.end = SMMU_GFX3D_CB_SC_SECURE_IRQ,
231
.flags = IORESOURCE_IRQ,
235
static struct resource msm_iommu_gfx2d0_resources[] = {
238
.end = 0x07D00000 + SZ_1M - 1,
240
.flags = IORESOURCE_MEM,
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,
249
.name = "secure_irq",
250
.start = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
251
.end = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
252
.flags = IORESOURCE_IRQ,
256
static struct resource msm_iommu_gfx2d1_resources[] = {
259
.end = 0x07E00000 + SZ_1M - 1,
261
.flags = IORESOURCE_MEM,
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,
270
.name = "secure_irq",
271
.start = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
272
.end = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
273
.flags = IORESOURCE_IRQ,
277
static struct platform_device msm_root_iommu_dev = {
282
static struct msm_iommu_dev jpegd_iommu = {
287
static struct msm_iommu_dev vpe_iommu = {
292
static struct msm_iommu_dev mdp0_iommu = {
297
static struct msm_iommu_dev mdp1_iommu = {
302
static struct msm_iommu_dev rot_iommu = {
307
static struct msm_iommu_dev ijpeg_iommu = {
312
static struct msm_iommu_dev vfe_iommu = {
317
static struct msm_iommu_dev vcodec_a_iommu = {
322
static struct msm_iommu_dev vcodec_b_iommu = {
327
static struct msm_iommu_dev gfx3d_iommu = {
332
static struct msm_iommu_dev gfx2d0_iommu = {
337
static struct msm_iommu_dev gfx2d1_iommu = {
342
static struct platform_device msm_device_iommu_jpegd = {
346
.parent = &msm_root_iommu_dev.dev,
348
.num_resources = ARRAY_SIZE(msm_iommu_jpegd_resources),
349
.resource = msm_iommu_jpegd_resources,
352
static struct platform_device msm_device_iommu_vpe = {
356
.parent = &msm_root_iommu_dev.dev,
358
.num_resources = ARRAY_SIZE(msm_iommu_vpe_resources),
359
.resource = msm_iommu_vpe_resources,
362
static struct platform_device msm_device_iommu_mdp0 = {
366
.parent = &msm_root_iommu_dev.dev,
368
.num_resources = ARRAY_SIZE(msm_iommu_mdp0_resources),
369
.resource = msm_iommu_mdp0_resources,
372
static struct platform_device msm_device_iommu_mdp1 = {
376
.parent = &msm_root_iommu_dev.dev,
378
.num_resources = ARRAY_SIZE(msm_iommu_mdp1_resources),
379
.resource = msm_iommu_mdp1_resources,
382
static struct platform_device msm_device_iommu_rot = {
386
.parent = &msm_root_iommu_dev.dev,
388
.num_resources = ARRAY_SIZE(msm_iommu_rot_resources),
389
.resource = msm_iommu_rot_resources,
392
static struct platform_device msm_device_iommu_ijpeg = {
396
.parent = &msm_root_iommu_dev.dev,
398
.num_resources = ARRAY_SIZE(msm_iommu_ijpeg_resources),
399
.resource = msm_iommu_ijpeg_resources,
402
static struct platform_device msm_device_iommu_vfe = {
406
.parent = &msm_root_iommu_dev.dev,
408
.num_resources = ARRAY_SIZE(msm_iommu_vfe_resources),
409
.resource = msm_iommu_vfe_resources,
412
static struct platform_device msm_device_iommu_vcodec_a = {
416
.parent = &msm_root_iommu_dev.dev,
418
.num_resources = ARRAY_SIZE(msm_iommu_vcodec_a_resources),
419
.resource = msm_iommu_vcodec_a_resources,
422
static struct platform_device msm_device_iommu_vcodec_b = {
426
.parent = &msm_root_iommu_dev.dev,
428
.num_resources = ARRAY_SIZE(msm_iommu_vcodec_b_resources),
429
.resource = msm_iommu_vcodec_b_resources,
432
static struct platform_device msm_device_iommu_gfx3d = {
436
.parent = &msm_root_iommu_dev.dev,
438
.num_resources = ARRAY_SIZE(msm_iommu_gfx3d_resources),
439
.resource = msm_iommu_gfx3d_resources,
442
static struct platform_device msm_device_iommu_gfx2d0 = {
446
.parent = &msm_root_iommu_dev.dev,
448
.num_resources = ARRAY_SIZE(msm_iommu_gfx2d0_resources),
449
.resource = msm_iommu_gfx2d0_resources,
452
struct platform_device msm_device_iommu_gfx2d1 = {
456
.parent = &msm_root_iommu_dev.dev,
458
.num_resources = ARRAY_SIZE(msm_iommu_gfx2d1_resources),
459
.resource = msm_iommu_gfx2d1_resources,
462
static struct msm_iommu_ctx_dev jpegd_src_ctx = {
468
static struct msm_iommu_ctx_dev jpegd_dst_ctx = {
474
static struct msm_iommu_ctx_dev vpe_src_ctx = {
480
static struct msm_iommu_ctx_dev vpe_dst_ctx = {
486
static struct msm_iommu_ctx_dev mdp_vg1_ctx = {
492
static struct msm_iommu_ctx_dev mdp_rgb1_ctx = {
495
.mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
498
static struct msm_iommu_ctx_dev mdp_vg2_ctx = {
504
static struct msm_iommu_ctx_dev mdp_rgb2_ctx = {
507
.mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
510
static struct msm_iommu_ctx_dev rot_src_ctx = {
516
static struct msm_iommu_ctx_dev rot_dst_ctx = {
522
static struct msm_iommu_ctx_dev ijpeg_src_ctx = {
528
static struct msm_iommu_ctx_dev ijpeg_dst_ctx = {
534
static struct msm_iommu_ctx_dev vfe_imgwr_ctx = {
537
.mids = {2, 3, 4, 5, 6, 7, 8, -1}
540
static struct msm_iommu_ctx_dev vfe_misc_ctx = {
543
.mids = {0, 1, 9, -1}
546
static struct msm_iommu_ctx_dev vcodec_a_stream_ctx = {
547
.name = "vcodec_a_stream",
552
static struct msm_iommu_ctx_dev vcodec_a_mm1_ctx = {
553
.name = "vcodec_a_mm1",
555
.mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
558
static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = {
559
.name = "vcodec_b_mm2",
561
.mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
564
static struct msm_iommu_ctx_dev gfx3d_user_ctx = {
565
.name = "gfx3d_user",
567
.mids = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
570
static struct msm_iommu_ctx_dev gfx3d_priv_ctx = {
571
.name = "gfx3d_priv",
573
.mids = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
577
static struct msm_iommu_ctx_dev gfx2d0_2d0_ctx = {
578
.name = "gfx2d0_2d0",
580
.mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
583
static struct msm_iommu_ctx_dev gfx2d1_2d1_ctx = {
584
.name = "gfx2d1_2d1",
586
.mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
589
static struct platform_device msm_device_jpegd_src_ctx = {
590
.name = "msm_iommu_ctx",
593
.parent = &msm_device_iommu_jpegd.dev,
597
static struct platform_device msm_device_jpegd_dst_ctx = {
598
.name = "msm_iommu_ctx",
601
.parent = &msm_device_iommu_jpegd.dev,
605
static struct platform_device msm_device_vpe_src_ctx = {
606
.name = "msm_iommu_ctx",
609
.parent = &msm_device_iommu_vpe.dev,
613
static struct platform_device msm_device_vpe_dst_ctx = {
614
.name = "msm_iommu_ctx",
617
.parent = &msm_device_iommu_vpe.dev,
621
static struct platform_device msm_device_mdp_vg1_ctx = {
622
.name = "msm_iommu_ctx",
625
.parent = &msm_device_iommu_mdp0.dev,
629
static struct platform_device msm_device_mdp_rgb1_ctx = {
630
.name = "msm_iommu_ctx",
633
.parent = &msm_device_iommu_mdp0.dev,
637
static struct platform_device msm_device_mdp_vg2_ctx = {
638
.name = "msm_iommu_ctx",
641
.parent = &msm_device_iommu_mdp1.dev,
645
static struct platform_device msm_device_mdp_rgb2_ctx = {
646
.name = "msm_iommu_ctx",
649
.parent = &msm_device_iommu_mdp1.dev,
653
static struct platform_device msm_device_rot_src_ctx = {
654
.name = "msm_iommu_ctx",
657
.parent = &msm_device_iommu_rot.dev,
661
static struct platform_device msm_device_rot_dst_ctx = {
662
.name = "msm_iommu_ctx",
665
.parent = &msm_device_iommu_rot.dev,
669
static struct platform_device msm_device_ijpeg_src_ctx = {
670
.name = "msm_iommu_ctx",
673
.parent = &msm_device_iommu_ijpeg.dev,
677
static struct platform_device msm_device_ijpeg_dst_ctx = {
678
.name = "msm_iommu_ctx",
681
.parent = &msm_device_iommu_ijpeg.dev,
685
static struct platform_device msm_device_vfe_imgwr_ctx = {
686
.name = "msm_iommu_ctx",
689
.parent = &msm_device_iommu_vfe.dev,
693
static struct platform_device msm_device_vfe_misc_ctx = {
694
.name = "msm_iommu_ctx",
697
.parent = &msm_device_iommu_vfe.dev,
701
static struct platform_device msm_device_vcodec_a_stream_ctx = {
702
.name = "msm_iommu_ctx",
705
.parent = &msm_device_iommu_vcodec_a.dev,
709
static struct platform_device msm_device_vcodec_a_mm1_ctx = {
710
.name = "msm_iommu_ctx",
713
.parent = &msm_device_iommu_vcodec_a.dev,
717
static struct platform_device msm_device_vcodec_b_mm2_ctx = {
718
.name = "msm_iommu_ctx",
721
.parent = &msm_device_iommu_vcodec_b.dev,
725
static struct platform_device msm_device_gfx3d_user_ctx = {
726
.name = "msm_iommu_ctx",
729
.parent = &msm_device_iommu_gfx3d.dev,
733
static struct platform_device msm_device_gfx3d_priv_ctx = {
734
.name = "msm_iommu_ctx",
737
.parent = &msm_device_iommu_gfx3d.dev,
741
static struct platform_device msm_device_gfx2d0_2d0_ctx = {
742
.name = "msm_iommu_ctx",
745
.parent = &msm_device_iommu_gfx2d0.dev,
749
static struct platform_device msm_device_gfx2d1_2d1_ctx = {
750
.name = "msm_iommu_ctx",
753
.parent = &msm_device_iommu_gfx2d1.dev,
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,
772
static struct msm_iommu_dev *msm_iommu_data[] = {
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,
811
static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
826
&vcodec_a_stream_ctx,
835
static int __init msm8x60_iommu_init(void)
839
ret = platform_device_register(&msm_root_iommu_dev);
841
pr_err("Failed to register root IOMMU device!\n");
845
for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); i++) {
846
ret = platform_device_add_data(msm_iommu_devs[i],
848
sizeof(struct msm_iommu_dev));
850
pr_err("platform_device_add_data failed, "
855
ret = platform_device_register(msm_iommu_devs[i]);
858
pr_err("platform_device_register iommu failed, "
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]));
869
pr_err("platform_device_add_data iommu failed, "
871
goto failure_unwind2;
874
ret = platform_device_register(msm_iommu_ctx_devs[i]);
876
pr_err("platform_device_register ctx failed, "
878
goto failure_unwind2;
885
platform_device_unregister(msm_iommu_ctx_devs[i]);
888
platform_device_unregister(msm_iommu_devs[i]);
890
platform_device_unregister(&msm_root_iommu_dev);
895
static void __exit msm8x60_iommu_exit(void)
899
for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++)
900
platform_device_unregister(msm_iommu_ctx_devs[i]);
902
for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); ++i)
903
platform_device_unregister(msm_iommu_devs[i]);
905
platform_device_unregister(&msm_root_iommu_dev);
908
subsys_initcall(msm8x60_iommu_init);
909
module_exit(msm8x60_iommu_exit);
911
MODULE_LICENSE("GPL v2");
912
MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");