Commit 63d66ec9 authored by David S. Miller's avatar David S. Miller

Merge branch 'ipa-v3.1'

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: default avatarDavid S. Miller <davem@davemloft.net>
parents be752283 1bb1a117
......@@ -44,6 +44,7 @@ description:
properties:
compatible:
enum:
- qcom,msm8998-ipa
- qcom,sc7180-ipa
- qcom,sc7280-ipa
- qcom,sdm845-ipa
......
......@@ -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
......@@ -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
......@@ -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);
......
......@@ -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
......
......@@ -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) \
......
This diff is collapsed.
......@@ -300,6 +300,7 @@ struct ipa_data {
const struct ipa_clock_data *clock_data;
};
extern const struct ipa_data ipa_data_v3_1;
extern const struct ipa_data ipa_data_v3_5_1;
extern const struct ipa_data ipa_data_v4_2;
extern const struct ipa_data ipa_data_v4_5;
......
......@@ -1731,6 +1731,21 @@ int ipa_endpoint_config(struct ipa *ipa)
u32 max;
u32 val;
/* Prior to IPAv3.5, the FLAVOR_0 register was not supported.
* Furthermore, the endpoints were not grouped such that TX
* endpoint numbers started with 0 and RX endpoints had numbers
* higher than all TX endpoints, so we can't do the simple
* direction check used for newer hardware below.
*
* For hardware that doesn't support the FLAVOR_0 register,
* just set the available mask to support any endpoint, and
* assume the configuration is valid.
*/
if (ipa->version < IPA_VERSION_3_5) {
ipa->available = ~0;
return 0;
}
/* Find out about the endpoints supplied by the hardware, and ensure
* the highest one doesn't exceed the number we support.
*/
......
......@@ -400,16 +400,20 @@ static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data)
/* Implement some hardware workarounds */
if (version >= IPA_VERSION_4_0 && version < IPA_VERSION_4_5) {
/* Enable open global clocks (not needed for IPA v4.5) */
val = GLOBAL_FMASK;
val |= GLOBAL_2X_CLK_FMASK;
iowrite32(val, ipa->reg_virt + IPA_REG_CLKON_CFG_OFFSET);
/* Disable PA mask to allow HOLB drop */
val = ioread32(ipa->reg_virt + IPA_REG_TX_CFG_OFFSET);
val &= ~PA_MASK_EN_FMASK;
iowrite32(val, ipa->reg_virt + IPA_REG_TX_CFG_OFFSET);
/* Enable open global clocks in the CLKON configuration */
val = GLOBAL_FMASK | GLOBAL_2X_CLK_FMASK;
} else if (version == IPA_VERSION_3_1) {
val = MISC_FMASK; /* Disable MISC clock gating */
} else {
val = 0; /* No CLKON configuration needed */
}
if (val)
iowrite32(val, ipa->reg_virt + IPA_REG_CLKON_CFG_OFFSET);
ipa_hardware_config_comp(ipa);
......@@ -574,6 +578,10 @@ static int ipa_firmware_load(struct device *dev)
}
static const struct of_device_id ipa_match[] = {
{
.compatible = "qcom,msm8998-ipa",
.data = &ipa_data_v3_1,
},
{
.compatible = "qcom,sdm845-ipa",
.data = &ipa_data_v3_5_1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment