diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-07-29 11:24:30 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-07-29 11:24:29 -0700 |
| commit | 29e6a3b9239df8aa7096b46356db3f474e4ec9ef (patch) | |
| tree | 62515d9fb3b379acce2c1a53bb1948da21022df4 /drivers/platform | |
| parent | 4065bfcc2ffed38db78ec422817687c1c1394429 (diff) | |
| parent | d106457a6017841632c49a349fa8e4aa8c2c6c23 (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.c | 41 |
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) |
