msm: Allow iova address alignment specification
Some clients have specific alignment requirements for
iova addresses. Allow those requirements to be specified
via the upper bits of the flag field. Since all iommu
alignment must be at least 4k, the lower bits can specify
other options while the upper bits specify the alignment.
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
index 34bfec9..85a5f10 100644
--- a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
+++ b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
@@ -24,6 +24,14 @@
#define MSM_SUBSYSTEM_MAP_CACHED 0x4
/* ioremaps in the kernel address space are uncached */
#define MSM_SUBSYSTEM_MAP_UNCACHED 0x8
+/*
+ * Shortcut flags for alignment.
+ * The flag must be equal to the alignment requested.
+ * e.g. for 8k alignment the flags must be (0x2000 | other flags)
+ */
+#define MSM_SUBSYSTEM_ALIGN_IOVA_8K SZ_8K
+#define MSM_SUBSYSTEM_ALIGN_IOVA_1M SZ_1M
+
#define MSM_SUBSYSTEM_VIDEO VCODEC_A_SUBSYS_ID
#define MSM_SUBSYSTEM_VIDEO_FWARE VIDEO_FWARE_ID
diff --git a/arch/arm/mach-msm/subsystem_map.c b/arch/arm/mach-msm/subsystem_map.c
index 93aabf2..d242370 100644
--- a/arch/arm/mach-msm/subsystem_map.c
+++ b/arch/arm/mach-msm/subsystem_map.c
@@ -349,6 +349,7 @@
}
if ((flags & MSM_SUBSYSTEM_MAP_IOVA) && subsys_ids) {
+ unsigned int min_align;
pg_size = SZ_4K;
@@ -369,6 +370,13 @@
}
order = get_order(pg_size);
+
+ /*
+ * The alignment must be specified as the exact value wanted
+ * e.g. 8k alignment must pass (0x2000 | other flags)
+ */
+ min_align = flags & ~(SZ_4K - 1);
+
for (i = 0; i < nsubsys; i++) {
if (!subsys_validate(subsys_ids[i])) {
buf->iova[i] = phys;
@@ -378,7 +386,8 @@
d = msm_subsystem_get_domain(subsys_ids[i]);
iova_start = allocate_iova_address(length,
- subsys_ids[i], pg_size);
+ subsys_ids[i],
+ max(min_align, pg_size));
if (!iova_start) {
pr_err("%s: could not allocate iova address\n",