On 2/11/21 11:50 AM, AngeloGioacchino Del Regno wrote:
In GSI v1.0 the register GSI_HW_PARAM_2_OFFSET has different layout
so the number of channels and events per EE are, of course, laid out
in 8 bits each (0-7, 8-15 respectively).
This is actually wrong. The fields you are fetching here
define the total number of channels (events) supported by
the IPA hardware, not the number of channels (events) per EE.
The fields we want are in the HW_PARAM_2 register, which
is not present until IPA v3.5.1.
As you did with the FLAVOR_0 register in an earlier patch,
I will update the code so the HW_PARAM_2 register is not
read unless it's defined, and will just skip these validity
checks on the endpoint configuration in that case. We'll
just assume the hardware supports the maximum number of
channels and endpoints supported by the driver if we don't
know otherwise.
-Alex
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxxx>
---
drivers/net/ipa/gsi.c | 16 +++++++++++++---
drivers/net/ipa/gsi_reg.h | 5 +++++
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index b5460cbb085c..3311ffe514c9 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -1790,7 +1790,7 @@ static void gsi_channel_teardown(struct gsi *gsi)
int gsi_setup(struct gsi *gsi)
{
struct device *dev = gsi->dev;
- u32 val;
+ u32 val, mask;
int ret;
/* Here is where we first touch the GSI hardware */
@@ -1804,7 +1804,12 @@ int gsi_setup(struct gsi *gsi)
val = ioread32(gsi->virt + GSI_GSI_HW_PARAM_2_OFFSET);
- gsi->channel_count = u32_get_bits(val, NUM_CH_PER_EE_FMASK);
+ if (gsi->version == IPA_VERSION_3_1)
+ mask = GSIV1_NUM_CH_PER_EE_FMASK;
+ else
+ mask = NUM_CH_PER_EE_FMASK;
+
+ gsi->channel_count = u32_get_bits(val, mask);
if (!gsi->channel_count) {
dev_err(dev, "GSI reports zero channels supported\n");
return -EINVAL;
@@ -1816,7 +1821,12 @@ int gsi_setup(struct gsi *gsi)
gsi->channel_count = GSI_CHANNEL_COUNT_MAX;
}
- gsi->evt_ring_count = u32_get_bits(val, NUM_EV_PER_EE_FMASK);
+ if (gsi->version == IPA_VERSION_3_1)
+ mask = GSIV1_NUM_EV_PER_EE_FMASK;
+ else
+ mask = NUM_EV_PER_EE_FMASK;
+
+ gsi->evt_ring_count = u32_get_bits(val, mask);
if (!gsi->evt_ring_count) {
dev_err(dev, "GSI reports zero event rings supported\n");
return -EINVAL;
diff --git a/drivers/net/ipa/gsi_reg.h b/drivers/net/ipa/gsi_reg.h
index 0e138bbd8205..4ba579fa21c2 100644
--- a/drivers/net/ipa/gsi_reg.h
+++ b/drivers/net/ipa/gsi_reg.h
@@ -287,6 +287,11 @@ enum gsi_generic_cmd_opcode {
GSI_EE_N_GSI_HW_PARAM_2_OFFSET(GSI_EE_AP)
#define GSI_EE_N_GSI_HW_PARAM_2_OFFSET(ee) \
(0x0001f040 + 0x4000 * (ee))
+
+/* Fields below are present for IPA v3.1 with GSI version 1 */
+#define GSIV1_NUM_EV_PER_EE_FMASK GENMASK(8, 0)
+#define GSIV1_NUM_CH_PER_EE_FMASK GENMASK(15, 8)
+/* Fields below are present for IPA v3.5.1 and above */
#define IRAM_SIZE_FMASK GENMASK(2, 0)
#define NUM_CH_PER_EE_FMASK GENMASK(7, 3)
#define NUM_EV_PER_EE_FMASK GENMASK(12, 8)