Re: [RFC PATCH 12/17] net: ipa: Add support for IPA v2.x memory map

From: Alex Elder
Date: Wed Oct 13 2021 - 18:30:58 EST


On 9/19/21 10:08 PM, Sireesh Kodali wrote:
IPA v2.6L has an extra region to handle compression/decompression
acceleration. This region is used by some modems during modem init.

So it has to be initialized? (I guess so.)

The memory size register apparently doesn't express things in
units of 8 bytes either.

-Alex

Signed-off-by: Sireesh Kodali <sireeshkodali1@xxxxxxxxx>
---
drivers/net/ipa/ipa_mem.c | 36 ++++++++++++++++++++++++++++++------
drivers/net/ipa/ipa_mem.h | 5 ++++-
2 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index 8acc88070a6f..bfcdc7e08de2 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -84,7 +84,7 @@ int ipa_mem_setup(struct ipa *ipa)
/* Get a transaction to define the header memory region and to zero
* the processing context and modem memory regions.
*/
- trans = ipa_cmd_trans_alloc(ipa, 4);
+ trans = ipa_cmd_trans_alloc(ipa, 5);
if (!trans) {
dev_err(&ipa->pdev->dev, "no transaction for memory setup\n");
return -EBUSY;
@@ -107,8 +107,14 @@ int ipa_mem_setup(struct ipa *ipa)
ipa_mem_zero_region_add(trans, IPA_MEM_AP_PROC_CTX);
ipa_mem_zero_region_add(trans, IPA_MEM_MODEM);
+ ipa_mem_zero_region_add(trans, IPA_MEM_ZIP);
+
ipa_trans_commit_wait(trans);
+ /* On IPA version <=2.6L (except 2.5) there is no PROC_CTX. */
+ if (ipa->version != IPA_VERSION_2_5 && ipa->version <= IPA_VERSION_2_6L)
+ return 0;
+
/* Tell the hardware where the processing context area is located */
mem = ipa_mem_find(ipa, IPA_MEM_MODEM_PROC_CTX);
offset = ipa->mem_offset + mem->offset;
@@ -147,6 +153,11 @@ static bool ipa_mem_id_valid(struct ipa *ipa, enum ipa_mem_id mem_id)
case IPA_MEM_END_MARKER: /* pseudo region */
break;
+ case IPA_MEM_ZIP:
+ if (version == IPA_VERSION_2_6L)
+ return true;
+ break;
+
case IPA_MEM_STATS_TETHERING:
case IPA_MEM_STATS_DROP:
if (version < IPA_VERSION_4_0)
@@ -319,10 +330,15 @@ int ipa_mem_config(struct ipa *ipa)
/* Check the advertised location and size of the shared memory area */
val = ioread32(ipa->reg_virt + ipa_reg_shared_mem_size_offset(ipa->version));
- /* The fields in the register are in 8 byte units */
- ipa->mem_offset = 8 * u32_get_bits(val, SHARED_MEM_BADDR_FMASK);
- /* Make sure the end is within the region's mapped space */
- mem_size = 8 * u32_get_bits(val, SHARED_MEM_SIZE_FMASK);
+ if (IPA_VERSION_RANGE(ipa->version, 2_0, 2_6L)) {
+ /* The fields in the register are in 8 byte units */
+ ipa->mem_offset = 8 * u32_get_bits(val, SHARED_MEM_BADDR_FMASK);
+ /* Make sure the end is within the region's mapped space */
+ mem_size = 8 * u32_get_bits(val, SHARED_MEM_SIZE_FMASK);
+ } else {
+ ipa->mem_offset = u32_get_bits(val, SHARED_MEM_BADDR_FMASK);
+ mem_size = u32_get_bits(val, SHARED_MEM_SIZE_FMASK);
+ }
/* If the sizes don't match, issue a warning */
if (ipa->mem_offset + mem_size < ipa->mem_size) {
@@ -564,6 +580,10 @@ static int ipa_smem_init(struct ipa *ipa, u32 item, size_t size)
return -EINVAL;
}
+ /* IPA v2.6L does not use IOMMU */
+ if (ipa->version <= IPA_VERSION_2_6L)
+ return 0;
+
domain = iommu_get_domain_for_dev(dev);
if (!domain) {
dev_err(dev, "no IOMMU domain found for SMEM\n");
@@ -591,6 +611,9 @@ static void ipa_smem_exit(struct ipa *ipa)
struct device *dev = &ipa->pdev->dev;
struct iommu_domain *domain;
+ if (ipa->version <= IPA_VERSION_2_6L)
+ return;
+
domain = iommu_get_domain_for_dev(dev);
if (domain) {
size_t size;
@@ -622,7 +645,8 @@ int ipa_mem_init(struct ipa *ipa, const struct ipa_mem_data *mem_data)
ipa->mem_count = mem_data->local_count;
ipa->mem = mem_data->local;
- ret = dma_set_mask_and_coherent(&ipa->pdev->dev, DMA_BIT_MASK(64));
+ ret = dma_set_mask_and_coherent(&ipa->pdev->dev, IPA_IS_64BIT(ipa->version) ?
+ DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
if (ret) {
dev_err(dev, "error %d setting DMA mask\n", ret);
return ret;
diff --git a/drivers/net/ipa/ipa_mem.h b/drivers/net/ipa/ipa_mem.h
index 570bfdd99bff..be91cb38b6a8 100644
--- a/drivers/net/ipa/ipa_mem.h
+++ b/drivers/net/ipa/ipa_mem.h
@@ -47,8 +47,10 @@ enum ipa_mem_id {
IPA_MEM_UC_INFO, /* 0 canaries */
IPA_MEM_V4_FILTER_HASHED, /* 2 canaries */
IPA_MEM_V4_FILTER, /* 2 canaries */
+ IPA_MEM_V4_FILTER_AP, /* 2 canaries (IPA v2.0) */
IPA_MEM_V6_FILTER_HASHED, /* 2 canaries */
IPA_MEM_V6_FILTER, /* 2 canaries */
+ IPA_MEM_V6_FILTER_AP, /* 0 canaries (IPA v2.0) */
IPA_MEM_V4_ROUTE_HASHED, /* 2 canaries */
IPA_MEM_V4_ROUTE, /* 2 canaries */
IPA_MEM_V6_ROUTE_HASHED, /* 2 canaries */
@@ -57,7 +59,8 @@ enum ipa_mem_id {
IPA_MEM_AP_HEADER, /* 0 canaries, optional */
IPA_MEM_MODEM_PROC_CTX, /* 2 canaries */
IPA_MEM_AP_PROC_CTX, /* 0 canaries */
- IPA_MEM_MODEM, /* 0/2 canaries */
+ IPA_MEM_ZIP, /* 1 canary (IPA v2.6L) */
+ IPA_MEM_MODEM, /* 0-2 canaries */
IPA_MEM_UC_EVENT_RING, /* 1 canary, optional */
IPA_MEM_PDN_CONFIG, /* 0/2 canaries (IPA v4.0+) */
IPA_MEM_STATS_QUOTA_MODEM, /* 2/4 canaries (IPA v4.0+) */