From b20a8dd9071d5d0681c8b91fec197f18fcc24621 Mon Sep 17 00:00:00 2001 From: Amir Levy Date: Sun, 14 Feb 2021 15:19:40 +0200 Subject: [PATCH] msm: ipa: add shared CB support for ETH Add support for sharing page tables between IPA ETH context bank and ETH context bank. In case of shared CB no need to map ETH buffers. Fix double mapping in case of two buffers lay on the same page (non shared CB mode). Change-Id: Ic52479da3c26a2db4075c260044428a0ef93bb6a Signed-off-by: Amir Levy --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 5 +++ drivers/platform/msm/ipa/ipa_v3/ipa_eth_i.c | 36 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index f76e5004f9..b3bf888839 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -9117,6 +9117,11 @@ static int ipa_smmu_perph_cb_probe(struct device *dev, ipa3_ctx->s1_bypass_arr[cb_type] = (bypass != 0); + if (of_property_read_bool(dev->of_node, "qcom,shared-cb")) { + IPADBG("CB %d using shared CB\n", cb_type); + cb->shared = true; + } + /* MAP ipa-uc ram */ add_map = of_get_property(dev->of_node, "qcom,additional-mapping", &add_map_size); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_eth_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_eth_i.c index ba78985723..4b155f035e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_eth_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_eth_i.c @@ -465,6 +465,17 @@ static bool ipa_eth_is_smmu_buff_cb_bypass( return false; } +static enum ipa_smmu_cb_type ipa_eth_get_cb_type( + enum ipa_client_type client_type) +{ + if (IPA_CLIENT_IS_SMMU_ETH_INSTANCE(client_type)) + return IPA_SMMU_CB_ETH; + if (IPA_CLIENT_IS_SMMU_ETH1_INSTANCE(client_type)) + return IPA_SMMU_CB_ETH1; + + return IPA_SMMU_CB_MAX; +} + static int ipa3_smmu_map_eth_pipes(struct ipa_eth_client_pipe_info *pipe, enum ipa_client_type client_type, bool map) { @@ -474,8 +485,10 @@ static int ipa3_smmu_map_eth_pipes(struct ipa_eth_client_pipe_info *pipe, u64 iova; phys_addr_t pa; u64 iova_p; + u64 prev_iova_p; phys_addr_t pa_p; u32 size_p; + enum ipa_smmu_cb_type cb_type; if (pipe->info.fix_buffer_size > PAGE_SIZE) { IPAERR("invalid data buff size\n"); @@ -505,6 +518,20 @@ map_buffer: return 0; } + cb_type = ipa_eth_get_cb_type(client_type); + if (cb_type >= IPA_SMMU_CB_MAX) { + IPAERR("invalid CB type %d\n", cb_type); + goto fail_map_buffer_smmu_enabled; + } + + if ((ipa3_get_smmu_ctx(cb_type))->shared) { + IPADBG("SMMU cb %d is shared, no need to map buffers\n", cb_type); + return 0; + } else { + IPADBG( + "SMMU cb %d is not shared, continue to map buffers\n", cb_type); + } + smmu_domain = ipa_eth_get_smmu_domain(client_type); if (!smmu_domain) { IPAERR("invalid smmu domain\n"); @@ -512,11 +539,20 @@ map_buffer: goto fail_map_buffer_smmu_enabled; } + prev_iova_p = 0; for (i = 0; i < pipe->info.data_buff_list_size; i++) { iova = (u64)pipe->info.data_buff_list[i].iova; pa = (phys_addr_t)pipe->info.data_buff_list[i].pa; IPA_SMMU_ROUND_TO_PAGE(iova, pa, pipe->info.fix_buffer_size, iova_p, pa_p, size_p); + /* Add check on every 2nd buffer for AQC smmu-dup issue */ + if (prev_iova_p == iova_p) { + IPADBG_LOW( + "current buffer and previous are on the same page, skip page mapping\n" + ); + continue; + } + prev_iova_p = iova_p; IPADBG_LOW("%s 0x%llx to 0x%pa size %d\n", map ? "mapping" : "unmapping", iova_p, &pa_p, size_p); if (map) {