msm: iommu: Configure iommu devices for 8064
Add support for new SMMUs found on the APQ8064
target and enable the iommu driver for 8064.
Change-Id: I0b4d42f5b47dd5299c44e381dd4320b7570c3ce5
Signed-off-by: Joel King <joelking@codeaurora.org>
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index a945349..73c96fb 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -15,6 +15,9 @@
#include <linux/bootmem.h>
#include <mach/irqs.h>
#include <mach/iommu.h>
+#include <mach/socinfo.h>
+#include <mach/irqs-8960.h>
+#include <mach/irqs-8064.h>
static struct resource msm_iommu_jpegd_resources[] = {
{
@@ -226,6 +229,27 @@
},
};
+static struct resource msm_iommu_gfx3d1_resources[] = {
+ {
+ .start = 0x07D00000,
+ .end = 0x07D00000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_GFX3D1_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_GFX3D1_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_GFX3D1_CB_SC_SECURE_IRQ,
+ .end = SMMU_GFX3D1_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static struct resource msm_iommu_gfx2d0_resources[] = {
{
.start = 0x07D00000,
@@ -268,6 +292,27 @@
},
};
+static struct resource msm_iommu_vcap_resources[] = {
+ {
+ .start = 0x07200000,
+ .end = 0x07200000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VCAP_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VCAP_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VCAP_CB_SC_SECURE_IRQ,
+ .end = SMMU_VCAP_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static struct platform_device msm_root_iommu_dev = {
.name = "msm_iommu",
.id = -1,
@@ -323,6 +368,11 @@
.ncb = 3,
};
+static struct msm_iommu_dev gfx3d1_iommu = {
+ .name = "gfx3d1",
+ .ncb = 3,
+};
+
static struct msm_iommu_dev gfx2d0_iommu = {
.name = "gfx2d0",
.ncb = 2,
@@ -333,6 +383,11 @@
.ncb = 2,
};
+static struct msm_iommu_dev vcap_iommu = {
+ .name = "vcap",
+ .ncb = 2,
+};
+
static struct platform_device msm_device_iommu_jpegd = {
.name = "msm_iommu",
.id = 0,
@@ -433,6 +488,16 @@
.resource = msm_iommu_gfx3d_resources,
};
+static struct platform_device msm_device_iommu_gfx3d1 = {
+ .name = "msm_iommu",
+ .id = 10,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_gfx3d1_resources),
+ .resource = msm_iommu_gfx3d1_resources,
+};
+
static struct platform_device msm_device_iommu_gfx2d0 = {
.name = "msm_iommu",
.id = 10,
@@ -443,7 +508,7 @@
.resource = msm_iommu_gfx2d0_resources,
};
-struct platform_device msm_device_iommu_gfx2d1 = {
+static struct platform_device msm_device_iommu_gfx2d1 = {
.name = "msm_iommu",
.id = 11,
.dev = {
@@ -453,6 +518,16 @@
.resource = msm_iommu_gfx2d1_resources,
};
+static struct platform_device msm_device_iommu_vcap = {
+ .name = "msm_iommu",
+ .id = 11,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vcap_resources),
+ .resource = msm_iommu_vcap_resources,
+};
+
static struct msm_iommu_ctx_dev jpegd_src_ctx = {
.name = "jpegd_src",
.num = 0,
@@ -568,6 +643,19 @@
31, -1}
};
+static struct msm_iommu_ctx_dev gfx3d1_user_ctx = {
+ .name = "gfx3d1_user",
+ .num = 0,
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d1_priv_ctx = {
+ .name = "gfx3d1_priv",
+ .num = 1,
+ .mids = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, -1}
+};
+
static struct msm_iommu_ctx_dev gfx2d0_2d0_ctx = {
.name = "gfx2d0_2d0",
.num = 0,
@@ -580,6 +668,18 @@
.mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
};
+static struct msm_iommu_ctx_dev vcap_vc_ctx = {
+ .name = "vcap_vc",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev vcap_vp_ctx = {
+ .name = "vcap_vp",
+ .num = 1,
+ .mids = {1, -1}
+};
+
static struct platform_device msm_device_jpegd_src_ctx = {
.name = "msm_iommu_ctx",
.id = 0,
@@ -732,6 +832,22 @@
},
};
+static struct platform_device msm_device_gfx3d1_user_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 19,
+ .dev = {
+ .parent = &msm_device_iommu_gfx3d1.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx3d1_priv_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 20,
+ .dev = {
+ .parent = &msm_device_iommu_gfx3d1.dev,
+ },
+};
+
static struct platform_device msm_device_gfx2d0_2d0_ctx = {
.name = "msm_iommu_ctx",
.id = 19,
@@ -748,7 +864,23 @@
},
};
-static struct platform_device *msm_iommu_devs[] = {
+static struct platform_device msm_device_vcap_vc_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 21,
+ .dev = {
+ .parent = &msm_device_iommu_vcap.dev,
+ },
+};
+
+static struct platform_device msm_device_vcap_vp_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 22,
+ .dev = {
+ .parent = &msm_device_iommu_vcap.dev,
+ },
+};
+
+static struct platform_device *msm_iommu_common_devs[] = {
&msm_device_iommu_jpegd,
&msm_device_iommu_vpe,
&msm_device_iommu_mdp0,
@@ -759,11 +891,19 @@
&msm_device_iommu_vcodec_a,
&msm_device_iommu_vcodec_b,
&msm_device_iommu_gfx3d,
+};
+
+static struct platform_device *msm_iommu_gfx2d_devs[] = {
&msm_device_iommu_gfx2d0,
&msm_device_iommu_gfx2d1,
};
-static struct msm_iommu_dev *msm_iommu_data[] = {
+static struct platform_device *msm_iommu_8064_devs[] = {
+ &msm_device_iommu_gfx3d1,
+ &msm_device_iommu_vcap,
+};
+
+static struct msm_iommu_dev *msm_iommu_common_data[] = {
&jpegd_iommu,
&vpe_iommu,
&mdp0_iommu,
@@ -774,11 +914,19 @@
&vcodec_a_iommu,
&vcodec_b_iommu,
&gfx3d_iommu,
+};
+
+static struct msm_iommu_dev *msm_iommu_gfx2d_data[] = {
&gfx2d0_iommu,
&gfx2d1_iommu,
};
-static struct platform_device *msm_iommu_ctx_devs[] = {
+static struct msm_iommu_dev *msm_iommu_8064_data[] = {
+ &gfx3d1_iommu,
+ &vcap_iommu,
+};
+
+static struct platform_device *msm_iommu_common_ctx_devs[] = {
&msm_device_jpegd_src_ctx,
&msm_device_jpegd_dst_ctx,
&msm_device_vpe_src_ctx,
@@ -798,11 +946,21 @@
&msm_device_vcodec_b_mm2_ctx,
&msm_device_gfx3d_user_ctx,
&msm_device_gfx3d_priv_ctx,
+};
+
+static struct platform_device *msm_iommu_gfx2d_ctx_devs[] = {
&msm_device_gfx2d0_2d0_ctx,
&msm_device_gfx2d1_2d1_ctx,
};
-static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
+static struct platform_device *msm_iommu_8064_ctx_devs[] = {
+ &msm_device_gfx3d1_user_ctx,
+ &msm_device_gfx3d1_priv_ctx,
+ &msm_device_vcap_vc_ctx,
+ &msm_device_vcap_vp_ctx,
+};
+
+static struct msm_iommu_ctx_dev *msm_iommu_common_ctx_data[] = {
&jpegd_src_ctx,
&jpegd_dst_ctx,
&vpe_src_ctx,
@@ -822,31 +980,35 @@
&vcodec_b_mm2_ctx,
&gfx3d_user_ctx,
&gfx3d_priv_ctx,
+};
+
+static struct msm_iommu_ctx_dev *msm_iommu_gfx2d_ctx_data[] = {
&gfx2d0_2d0_ctx,
&gfx2d1_2d1_ctx,
};
-static int __init msm8x60_iommu_init(void)
+static struct msm_iommu_ctx_dev *msm_iommu_8064_ctx_data[] = {
+ &gfx3d1_user_ctx,
+ &gfx3d1_priv_ctx,
+ &vcap_vc_ctx,
+ &vcap_vp_ctx,
+};
+
+static int iommu_init_devs(struct platform_device *devs[],
+ struct msm_iommu_dev *data[], int size)
{
int ret, i;
- ret = platform_device_register(&msm_root_iommu_dev);
- if (ret != 0) {
- pr_err("Failed to register root IOMMU device!\n");
- goto failure;
- }
-
- for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); i++) {
- ret = platform_device_add_data(msm_iommu_devs[i],
- msm_iommu_data[i],
- sizeof(struct msm_iommu_dev));
+ for (i = 0; i < size; i++) {
+ ret = platform_device_add_data(devs[i],
+ data[i], sizeof(struct msm_iommu_dev));
if (ret != 0) {
pr_err("platform_device_add_data failed, "
"i = %d\n", i);
goto failure_unwind;
}
- ret = platform_device_register(msm_iommu_devs[i]);
+ ret = platform_device_register(devs[i]);
if (ret != 0) {
pr_err("platform_device_register iommu failed, "
@@ -854,53 +1016,139 @@
goto failure_unwind;
}
}
+ return 0;
- for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++) {
- ret = platform_device_add_data(msm_iommu_ctx_devs[i],
- msm_iommu_ctx_data[i],
- sizeof(*msm_iommu_ctx_devs[i]));
+failure_unwind:
+ while (--i >= 0)
+ platform_device_unregister(devs[i]);
+
+ return ret;
+}
+
+
+static int iommu_init_ctx_devs(struct platform_device *ctx_devs[],
+ struct msm_iommu_ctx_dev *ctx_data[], int size)
+{
+ int ret, i;
+
+ for (i = 0; i < size; i++) {
+ ret = platform_device_add_data(ctx_devs[i],
+ ctx_data[i], sizeof(struct msm_iommu_ctx_dev));
if (ret != 0) {
pr_err("platform_device_add_data iommu failed, "
"i = %d\n", i);
- goto failure_unwind2;
+ goto failure_unwind;
}
- ret = platform_device_register(msm_iommu_ctx_devs[i]);
+ ret = platform_device_register(ctx_devs[i]);
if (ret != 0) {
pr_err("platform_device_register ctx failed, "
"i = %d\n", i);
- goto failure_unwind2;
+ goto failure_unwind;
}
}
return 0;
-failure_unwind2:
- while (--i >= 0)
- platform_device_unregister(msm_iommu_ctx_devs[i]);
failure_unwind:
while (--i >= 0)
- platform_device_unregister(msm_iommu_devs[i]);
+ platform_device_unregister(ctx_devs[i]);
+ return ret;
+}
+
+static int __init iommu_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&msm_root_iommu_dev);
+ if (ret != 0) {
+ pr_err("Failed to register root IOMMU device!\n");
+ goto failure;
+ }
+
+ /* Initialize common devs */
+ ret = iommu_init_devs(msm_iommu_common_devs,
+ msm_iommu_common_data,
+ ARRAY_SIZE(msm_iommu_common_devs));
+ if (ret != 0)
+ goto failure2;
+
+ /* Initialize soc-specific devs */
+ if (cpu_is_apq8064()) {
+ ret = iommu_init_devs(msm_iommu_8064_devs,
+ msm_iommu_8064_data,
+ ARRAY_SIZE(msm_iommu_8064_devs));
+ } else {
+ ret = iommu_init_devs(msm_iommu_gfx2d_devs,
+ msm_iommu_gfx2d_data,
+ ARRAY_SIZE(msm_iommu_gfx2d_devs));
+ }
+ if (ret != 0)
+ goto failure2;
+
+ /* Initialize common ctx_devs */
+ ret = iommu_init_ctx_devs(msm_iommu_common_ctx_devs,
+ msm_iommu_common_ctx_data,
+ ARRAY_SIZE(msm_iommu_common_ctx_devs));
+ if (ret != 0)
+ goto failure2;
+
+ /* Initialize soc-specific ctx_devs */
+ if (cpu_is_apq8064()) {
+ ret = iommu_init_ctx_devs(msm_iommu_8064_ctx_devs,
+ msm_iommu_8064_ctx_data,
+ ARRAY_SIZE(msm_iommu_8064_ctx_devs));
+ } else {
+ ret = iommu_init_ctx_devs(msm_iommu_gfx2d_ctx_devs,
+ msm_iommu_gfx2d_ctx_data,
+ ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs));
+ }
+ if (ret != 0)
+ goto failure2;
+
+ return 0;
+
+failure2:
platform_device_unregister(&msm_root_iommu_dev);
failure:
return ret;
}
-static void __exit msm8x60_iommu_exit(void)
+static void __exit iommu_exit(void)
{
int i;
- for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++)
- platform_device_unregister(msm_iommu_ctx_devs[i]);
+ /* Common ctx_devs */
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_common_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_common_ctx_devs[i]);
- for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); ++i)
- platform_device_unregister(msm_iommu_devs[i]);
+ /* soc-specific ctx_devs. */
+ if (cpu_is_apq8064()) {
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_8064_ctx_devs[i]);
+ } else {
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_gfx2d_ctx_devs[i]);
+ }
+
+ /* Common devs. */
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_common_devs); ++i)
+ platform_device_unregister(msm_iommu_common_devs[i]);
+
+ /* soc-specific devs. */
+ if (cpu_is_apq8064()) {
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_devs); i++)
+ platform_device_unregister(msm_iommu_8064_devs[i]);
+ } else {
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_devs); i++)
+ platform_device_unregister(msm_iommu_gfx2d_devs[i]);
+ }
platform_device_unregister(&msm_root_iommu_dev);
}
-subsys_initcall(msm8x60_iommu_init);
-module_exit(msm8x60_iommu_exit);
+subsys_initcall(iommu_init);
+module_exit(iommu_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");