Commit d2bb6e65 authored by Alex Elder's avatar Alex Elder Committed by David S. Miller

net: ipa: start creating GSI register definitions

Create a new register definition file in the "reg" subdirectory,
and begin populating it with GSI register definitions based on IPA
version.  The GSI registers haven't changed much, so several IPA
versions can share the same GSI register definitions.

As with IPA registers, an array of pointers indexed by GSI register ID
refers to these register definitions, and a new "regs" field in the
GSI structure is initialized in gsi_reg_init() to refer to register
information based on the IPA version (though for now there's only
one).  The new function gsi_reg() returns register information for
a given GSI register, and the result can be used to look up that
register's offset.

This patch is meant only to put the infrastructure in place, so only
eon register (CH_C_QOS) is defined for each version, and only the
offset and stride are defined for that register.  Use new function
gsi_reg() to look up that register's information to get its offset,
This makes the GSI_CH_C_QOS_OFFSET() unnecessary, so get rid of it.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8f0fece6
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
IPA_VERSIONS := 3.1 3.5.1 4.2 4.5 4.7 4.9 4.11 IPA_VERSIONS := 3.1 3.5.1 4.2 4.5 4.7 4.9 4.11
# Some IPA versions can reuse another set of GSI register definitions.
GSI_IPA_VERSIONS := 3.1
obj-$(CONFIG_QCOM_IPA) += ipa.o obj-$(CONFIG_QCOM_IPA) += ipa.o
ipa-y := ipa_main.o ipa_power.o ipa_reg.o ipa_mem.o \ ipa-y := ipa_main.o ipa_power.o ipa_reg.o ipa_mem.o \
...@@ -13,6 +16,8 @@ ipa-y := ipa_main.o ipa_power.o ipa_reg.o ipa_mem.o \ ...@@ -13,6 +16,8 @@ ipa-y := ipa_main.o ipa_power.o ipa_reg.o ipa_mem.o \
ipa_resource.o ipa_qmi.o ipa_qmi_msg.o \ ipa_resource.o ipa_qmi.o ipa_qmi_msg.o \
ipa_sysfs.o ipa_sysfs.o
ipa-y += $(GSI_IPA_VERSIONS:%=reg/gsi_reg-v%.o)
ipa-y += $(IPA_VERSIONS:%=reg/ipa_reg-v%.o) ipa-y += $(IPA_VERSIONS:%=reg/ipa_reg-v%.o)
ipa-y += $(IPA_VERSIONS:%=data/ipa_data-v%.o) ipa-y += $(IPA_VERSIONS:%=data/ipa_data-v%.o)
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include "gsi.h" #include "gsi.h"
#include "reg.h"
#include "gsi_reg.h" #include "gsi_reg.h"
#include "gsi_private.h" #include "gsi_private.h"
#include "gsi_trans.h" #include "gsi_trans.h"
...@@ -796,6 +797,7 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell) ...@@ -796,6 +797,7 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell)
union gsi_channel_scratch scr = { }; union gsi_channel_scratch scr = { };
struct gsi_channel_scratch_gpi *gpi; struct gsi_channel_scratch_gpi *gpi;
struct gsi *gsi = channel->gsi; struct gsi *gsi = channel->gsi;
const struct reg *reg;
u32 wrr_weight = 0; u32 wrr_weight = 0;
u32 val; u32 val;
...@@ -819,6 +821,8 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell) ...@@ -819,6 +821,8 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell)
val = upper_32_bits(channel->tre_ring.addr); val = upper_32_bits(channel->tre_ring.addr);
iowrite32(val, gsi->virt + GSI_CH_C_CNTXT_3_OFFSET(channel_id)); iowrite32(val, gsi->virt + GSI_CH_C_CNTXT_3_OFFSET(channel_id));
reg = gsi_reg(gsi, CH_C_QOS);
/* Command channel gets low weighted round-robin priority */ /* Command channel gets low weighted round-robin priority */
if (channel->command) if (channel->command)
wrr_weight = field_max(WRR_WEIGHT_FMASK); wrr_weight = field_max(WRR_WEIGHT_FMASK);
...@@ -845,7 +849,7 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell) ...@@ -845,7 +849,7 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell)
if (gsi->version >= IPA_VERSION_4_9) if (gsi->version >= IPA_VERSION_4_9)
val |= DB_IN_BYTES; val |= DB_IN_BYTES;
iowrite32(val, gsi->virt + GSI_CH_C_QOS_OFFSET(channel_id)); iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id));
/* Now update the scratch registers for GPI protocol */ /* Now update the scratch registers for GPI protocol */
gpi = &scr.gpi; gpi = &scr.gpi;
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2018-2022 Linaro Ltd. * Copyright (C) 2018-2023 Linaro Ltd.
*/ */
#ifndef _GSI_H_ #ifndef _GSI_H_
#define _GSI_H_ #define _GSI_H_
...@@ -142,6 +142,8 @@ struct gsi { ...@@ -142,6 +142,8 @@ struct gsi {
enum ipa_version version; enum ipa_version version;
void __iomem *virt_raw; /* I/O mapped address range */ void __iomem *virt_raw; /* I/O mapped address range */
void __iomem *virt; /* Adjusted for most registers */ void __iomem *virt; /* Adjusted for most registers */
const struct regs *regs;
u32 irq; u32 irq;
u32 channel_count; u32 channel_count;
u32 evt_ring_count; u32 evt_ring_count;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/io.h> #include <linux/io.h>
#include "gsi.h" #include "gsi.h"
#include "reg.h"
#include "gsi_reg.h" #include "gsi_reg.h"
/* GSI EE registers as a group are shifted downward by a fixed constant amount /* GSI EE registers as a group are shifted downward by a fixed constant amount
...@@ -85,6 +86,31 @@ static bool gsi_reg_id_valid(struct gsi *gsi, enum gsi_reg_id reg_id) ...@@ -85,6 +86,31 @@ static bool gsi_reg_id_valid(struct gsi *gsi, enum gsi_reg_id reg_id)
} }
} }
const struct reg *gsi_reg(struct gsi *gsi, enum gsi_reg_id reg_id)
{
if (WARN(!gsi_reg_id_valid(gsi, reg_id), "invalid reg %u\n", reg_id))
return NULL;
return reg(gsi->regs, reg_id);
}
static const struct regs *gsi_regs(struct gsi *gsi)
{
switch (gsi->version) {
case IPA_VERSION_3_1:
case IPA_VERSION_3_5_1:
case IPA_VERSION_4_2:
case IPA_VERSION_4_5:
case IPA_VERSION_4_7:
case IPA_VERSION_4_9:
case IPA_VERSION_4_11:
return &gsi_regs_v3_1;
default:
return NULL;
}
}
/* Sets gsi->virt_raw and gsi->virt, and I/O maps the "gsi" memory range */ /* Sets gsi->virt_raw and gsi->virt, and I/O maps the "gsi" memory range */
int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev) int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
{ {
...@@ -93,8 +119,6 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev) ...@@ -93,8 +119,6 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
resource_size_t size; resource_size_t size;
u32 adjust; u32 adjust;
(void)gsi_reg_id_valid; /* Avoid a warning */
/* Get GSI memory range and map it */ /* Get GSI memory range and map it */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsi"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsi");
if (!res) { if (!res) {
...@@ -116,6 +140,12 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev) ...@@ -116,6 +140,12 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
gsi->regs = gsi_regs(gsi);
if (!gsi->regs) {
dev_err(dev, "unsupported IPA version %u (?)\n", gsi->version);
return -EINVAL;
}
gsi->virt_raw = ioremap(res->start, size); gsi->virt_raw = ioremap(res->start, size);
if (!gsi->virt_raw) { if (!gsi->virt_raw) {
dev_err(dev, "unable to remap \"gsi\" memory\n"); dev_err(dev, "unable to remap \"gsi\" memory\n");
......
...@@ -140,8 +140,7 @@ enum gsi_channel_type { ...@@ -140,8 +140,7 @@ enum gsi_channel_type {
#define GSI_CH_C_CNTXT_3_OFFSET(ch) \ #define GSI_CH_C_CNTXT_3_OFFSET(ch) \
(0x0001c00c + 0x4000 * GSI_EE_AP + 0x80 * (ch)) (0x0001c00c + 0x4000 * GSI_EE_AP + 0x80 * (ch))
#define GSI_CH_C_QOS_OFFSET(ch) \ /* CH_C_QOS register */
(0x0001c05c + 0x4000 * GSI_EE_AP + 0x80 * (ch))
#define WRR_WEIGHT_FMASK GENMASK(3, 0) #define WRR_WEIGHT_FMASK GENMASK(3, 0)
#define MAX_PREFETCH_FMASK GENMASK(8, 8) #define MAX_PREFETCH_FMASK GENMASK(8, 8)
#define USE_DB_ENG_FMASK GENMASK(9, 9) #define USE_DB_ENG_FMASK GENMASK(9, 9)
...@@ -443,6 +442,15 @@ enum gsi_generic_ee_result { ...@@ -443,6 +442,15 @@ enum gsi_generic_ee_result {
GENERIC_EE_NO_RESOURCES = 0x7, GENERIC_EE_NO_RESOURCES = 0x7,
}; };
extern const struct regs gsi_regs_v3_1;
/**
* gsi_reg() - Return the structure describing a GSI register
* @gsi: GSI pointer
* @reg_id: GSI register ID
*/
const struct reg *gsi_reg(struct gsi *gsi, enum gsi_reg_id reg_id);
/** /**
* gsi_reg_init() - Perform GSI register initialization * gsi_reg_init() - Perform GSI register initialization
* @gsi: GSI pointer * @gsi: GSI pointer
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2023 Linaro Ltd. */
#include <linux/types.h>
#include "../gsi.h"
#include "../reg.h"
#include "../gsi_reg.h"
REG_STRIDE(CH_C_QOS, ch_c_qos, 0x0001c05c + 0x4000 * GSI_EE_AP, 0x80);
static const struct reg *reg_array[] = {
[CH_C_QOS] = &reg_ch_c_qos,
};
const struct regs gsi_regs_v3_1 = {
.reg_count = ARRAY_SIZE(reg_array),
.reg = reg_array,
};
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