summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-07-29 11:24:30 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-07-29 11:24:29 -0700
commit29e6a3b9239df8aa7096b46356db3f474e4ec9ef (patch)
tree62515d9fb3b379acce2c1a53bb1948da21022df4 /drivers/platform
parent4065bfcc2ffed38db78ec422817687c1c1394429 (diff)
parentd106457a6017841632c49a349fa8e4aa8c2c6c23 (diff)
Merge "msm: ipa3: add support for additional mappings to smmu"
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index c553be1ad717..ef54d88024a9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -75,6 +75,15 @@
#define IPA3_ACTIVE_CLIENT_LOG_TYPE_RESOURCE 2
#define IPA3_ACTIVE_CLIENT_LOG_TYPE_SPECIAL 3
+/* round addresses for closes page per SMMU requirements */
+#define IPA_SMMU_ROUND_TO_PAGE(iova, pa, size, iova_p, pa_p, size_p) \
+ do { \
+ (iova_p) = rounddown((iova), PAGE_SIZE); \
+ (pa_p) = rounddown((pa), PAGE_SIZE); \
+ (size_p) = roundup((size) + (pa) - (pa_p), PAGE_SIZE); \
+ } while (0)
+
+
/* The relative location in /lib/firmware where the FWs will reside */
#define IPA_FWS_PATH "ipa/ipa_fws.elf"
@@ -4813,6 +4822,9 @@ static int ipa_smmu_ap_cb_probe(struct device *dev)
int fast = 1;
int bypass = 1;
u32 iova_ap_mapping[2];
+ u32 add_map_size;
+ const u32 *add_map;
+ int i;
IPADBG("AP CB probe: sub pdev=%p\n", dev);
@@ -4902,6 +4914,35 @@ static int ipa_smmu_ap_cb_probe(struct device *dev)
return result;
}
+ add_map = of_get_property(dev->of_node,
+ "qcom,additional-mapping", &add_map_size);
+ if (add_map) {
+ /* mapping size is an array of 3-tuple of u32 */
+ if (add_map_size % (3 * sizeof(u32))) {
+ IPAERR("wrong additional mapping format\n");
+ cb->valid = false;
+ return -EFAULT;
+ }
+
+ /* iterate of each entry of the additional mapping array */
+ for (i = 0; i < add_map_size / sizeof(u32); i += 3) {
+ u32 iova = be32_to_cpu(add_map[i]);
+ u32 pa = be32_to_cpu(add_map[i + 1]);
+ u32 size = be32_to_cpu(add_map[i + 2]);
+ unsigned long iova_p;
+ phys_addr_t pa_p;
+ u32 size_p;
+
+ IPA_SMMU_ROUND_TO_PAGE(iova, pa, size,
+ iova_p, pa_p, size_p);
+ IPADBG("mapping 0x%lx to 0x%pa size %d\n",
+ iova_p, &pa_p, size_p);
+ ipa3_iommu_map(cb->mapping->domain,
+ iova_p, pa_p, size_p,
+ IOMMU_READ | IOMMU_WRITE | IOMMU_DEVICE);
+ }
+ }
+
smmu_info.present = true;
if (!ipa3_bus_scale_table)