Skip to content

Commit

Permalink
Merge branch 'ipa-v3.1'
Browse files Browse the repository at this point in the history
Alex Elder says:

====================
net: ipa: add support for IPA v3.1

This series adds support for IPA v3.1, used by the Qualcomm
Snapdragon 835 (MSM8998).

The first patch adds "qcom,msm8998-ipa" to the DT binding.

The next four patches add code to ensure correct operation on
IPA v3.1:
  - Avoid touching unsupported inter-EE interrupt mask registers
  - Set the proper flags in the clock configuration register
  - Work around the lack of an IPA FLAVOR_0 register
  - Work around the lack of a GSI PARAM_2 register

The last patch defines configuration data for this version of IPA.

Many thanks are due to AngeloGioacchino Del Regno and Jami Kettunen,
both associated with SoMainline.  Angelo first posted code to
implement most of what was required for this, and Jami has been
helpful testing these changes on his hardware.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 21, 2021
2 parents be75228 + 1bb1a11 commit 63d66ec
Show file tree
Hide file tree
Showing 9 changed files with 629 additions and 40 deletions.
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/net/qcom,ipa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ description:
properties:
compatible:
enum:
- qcom,msm8998-ipa
- qcom,sc7180-ipa
- qcom,sc7280-ipa
- qcom,sdm845-ipa
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ipa/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ ipa-y := ipa_main.o ipa_clock.o ipa_reg.o ipa_mem.o \
ipa_resource.o ipa_qmi.o ipa_qmi_msg.o \
ipa_sysfs.o

ipa-y += ipa_data-v3.5.1.o ipa_data-v4.2.o \
ipa_data-v4.5.o ipa_data-v4.9.o \
ipa_data-v4.11.o
ipa-y += ipa_data-v3.1.o ipa_data-v3.5.1.o \
ipa_data-v4.2.o ipa_data-v4.5.o \
ipa_data-v4.9.o ipa_data-v4.11.o
90 changes: 60 additions & 30 deletions drivers/net/ipa/gsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,65 @@ static void gsi_irq_setup(struct gsi *gsi)
iowrite32(0, gsi->virt + GSI_CNTXT_GLOB_IRQ_EN_OFFSET);
iowrite32(0, gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_MSK_OFFSET);

/* The inter-EE registers are in the non-adjusted address range */
iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_CH_IRQ_MSK_OFFSET);
iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_EV_CH_IRQ_MSK_OFFSET);
/* The inter-EE interrupts are not supported for IPA v3.0-v3.1 */
if (gsi->version > IPA_VERSION_3_1) {
u32 offset;

/* These registers are in the non-adjusted address range */
offset = GSI_INTER_EE_SRC_CH_IRQ_MSK_OFFSET;
iowrite32(0, gsi->virt_raw + offset);
offset = GSI_INTER_EE_SRC_EV_CH_IRQ_MSK_OFFSET;
iowrite32(0, gsi->virt_raw + offset);
}

iowrite32(0, gsi->virt + GSI_CNTXT_GSI_IRQ_EN_OFFSET);
}

/* Get # supported channel and event rings; there is no gsi_ring_teardown() */
static int gsi_ring_setup(struct gsi *gsi)
{
struct device *dev = gsi->dev;
u32 count;
u32 val;

if (gsi->version < IPA_VERSION_3_5_1) {
/* No HW_PARAM_2 register prior to IPA v3.5.1, assume the max */
gsi->channel_count = GSI_CHANNEL_COUNT_MAX;
gsi->evt_ring_count = GSI_EVT_RING_COUNT_MAX;

return 0;
}

val = ioread32(gsi->virt + GSI_GSI_HW_PARAM_2_OFFSET);

count = u32_get_bits(val, NUM_CH_PER_EE_FMASK);
if (!count) {
dev_err(dev, "GSI reports zero channels supported\n");
return -EINVAL;
}
if (count > GSI_CHANNEL_COUNT_MAX) {
dev_warn(dev, "limiting to %u channels; hardware supports %u\n",
GSI_CHANNEL_COUNT_MAX, count);
count = GSI_CHANNEL_COUNT_MAX;
}
gsi->channel_count = count;

count = u32_get_bits(val, NUM_EV_PER_EE_FMASK);
if (!count) {
dev_err(dev, "GSI reports zero event rings supported\n");
return -EINVAL;
}
if (count > GSI_EVT_RING_COUNT_MAX) {
dev_warn(dev,
"limiting to %u event rings; hardware supports %u\n",
GSI_EVT_RING_COUNT_MAX, count);
count = GSI_EVT_RING_COUNT_MAX;
}
gsi->evt_ring_count = count;

return 0;
}

/* Event ring commands are performed one at a time. Their completion
* is signaled by the event ring control GSI interrupt type, which is
* only enabled when we issue an event ring command. Only the event
Expand Down Expand Up @@ -1827,43 +1879,21 @@ static void gsi_channel_teardown(struct gsi *gsi)
/* Setup function for GSI. GSI firmware must be loaded and initialized */
int gsi_setup(struct gsi *gsi)
{
struct device *dev = gsi->dev;
u32 val;
int ret;

/* Here is where we first touch the GSI hardware */
val = ioread32(gsi->virt + GSI_GSI_STATUS_OFFSET);
if (!(val & ENABLED_FMASK)) {
dev_err(dev, "GSI has not been enabled\n");
dev_err(gsi->dev, "GSI has not been enabled\n");
return -EIO;
}

gsi_irq_setup(gsi); /* No matching teardown required */

val = ioread32(gsi->virt + GSI_GSI_HW_PARAM_2_OFFSET);

gsi->channel_count = u32_get_bits(val, NUM_CH_PER_EE_FMASK);
if (!gsi->channel_count) {
dev_err(dev, "GSI reports zero channels supported\n");
return -EINVAL;
}
if (gsi->channel_count > GSI_CHANNEL_COUNT_MAX) {
dev_warn(dev,
"limiting to %u channels; hardware supports %u\n",
GSI_CHANNEL_COUNT_MAX, gsi->channel_count);
gsi->channel_count = GSI_CHANNEL_COUNT_MAX;
}

gsi->evt_ring_count = u32_get_bits(val, NUM_EV_PER_EE_FMASK);
if (!gsi->evt_ring_count) {
dev_err(dev, "GSI reports zero event rings supported\n");
return -EINVAL;
}
if (gsi->evt_ring_count > GSI_EVT_RING_COUNT_MAX) {
dev_warn(dev,
"limiting to %u event rings; hardware supports %u\n",
GSI_EVT_RING_COUNT_MAX, gsi->evt_ring_count);
gsi->evt_ring_count = GSI_EVT_RING_COUNT_MAX;
}
ret = gsi_ring_setup(gsi); /* No matching teardown required */
if (ret)
return ret;

/* Initialize the error log */
iowrite32(0, gsi->virt + GSI_ERROR_LOG_OFFSET);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ipa/gsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

/* Maximum number of channels and event rings supported by the driver */
#define GSI_CHANNEL_COUNT_MAX 23
#define GSI_EVT_RING_COUNT_MAX 20
#define GSI_EVT_RING_COUNT_MAX 24

/* Maximum TLV FIFO size for a channel; 64 here is arbitrary (and high) */
#define GSI_TLV_MAX 64
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ipa/gsi_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
*/
#define GSI_EE_REG_ADJUST 0x0000d000 /* IPA v4.5+ */

/* The two inter-EE IRQ register offsets are relative to gsi->virt_raw */
/* The inter-EE IRQ registers are relative to gsi->virt_raw (IPA v3.5+) */

#define GSI_INTER_EE_SRC_CH_IRQ_MSK_OFFSET \
GSI_INTER_EE_N_SRC_CH_IRQ_MSK_OFFSET(GSI_EE_AP)
#define GSI_INTER_EE_N_SRC_CH_IRQ_MSK_OFFSET(ee) \
Expand Down
Loading

0 comments on commit 63d66ec

Please sign in to comment.