Commit e1d07700 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-ipa-generalized-register-definitions'

Alex Elder says:

====================
net: ipa: generalized register definitions

This series is quite a bit bigger than what I normally like to send,
and I apologize for that.  I would like it to get incorporated in
its entirety this week if possible, and splitting up the series
carries a small risk that wouldn't happen.

Each IPA register has a defined offset, and in most cases, a set
of masks that define the width and position of fields within the
register.  Most registers currently use the same offset for all
versions of IPA.  Usually fields within registers are also the same
across many versions.  Offsets and fields like this are defined
using preprocessor constants.

When a register has a different offset for different versions of
IPA, an inline function is used to determine its offset.  And in
places where a field differs between versions, an inline function is
used to determine how a value is encoded within the field, depending
on IPA version.

Starting with IPA version 5.0, the number of IPA endpoints supported
is greater than 32.  As a consequence, *many* IPA register offsets
differ considerably from prior versions.  This increase in endpoints
also requires a lot of field sizes and/or positions to change (such
as those that contain an endpoint ID).

Defining these things with constants is no longer simple, and rather
than fill the code with one-off functions to define offsets and
encode field values, this series puts in place a new way of defining
IPA registers and their fields.  Note that this series creates this
new scheme, but does not add IPA v5.0+ support.

An enumerated type will now define a unique ID for each IPA register.
Each defined register will have a structure that contains its offset
and its name (a printable string).  Each version of IPA will have an
array of these register structures, indexed by register ID.

Some "parameterized" registers are duplicated (this is not new).
For example, each endpoint has an INIT_HDR register, and the offset
of a given endpoint's INIT_HDR register is dependent on the endpoint
number (the parameter).  In such cases, the register's "stride" is
defined as the distance between two of these registers.

If a register contains fields, each field will have a unique ID
that's used as an index into an array of field masks defined for the
register.  The register structure also defines the number of entries
in this field array.

When a register is to be used in code, its register structure will
be fetched using function ipa_reg().  Other functions are then used
to determine the register's offset, or to encode a value into one of
the register's fields, and so on.

Each version of IPA defines the set of registers that are available,
including all fields for these registers.  The array of defined
registers is set up at probe time based on the IPA version, and it
is associated with the main IPA structure.
====================

Link: https://lore.kernel.org/r/20220926220931.3261749-1-elder@linaro.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 8f1e1658 181ca020
......@@ -13,4 +13,6 @@ 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_sysfs.o
ipa-y += $(IPA_VERSIONS:%=reg/ipa_reg-v%.o)
ipa-y += $(IPA_VERSIONS:%=data/ipa_data-v%.o)
......@@ -44,6 +44,7 @@ struct ipa_interrupt;
* @uc_loaded: true after microcontroller has reported it's ready
* @reg_addr: DMA address used for IPA register access
* @reg_virt: Virtual address used for IPA register access
* @regs: IPA register definitions
* @mem_addr: DMA address of IPA-local memory space
* @mem_virt: Virtual address of IPA-local memory space
* @mem_offset: Offset from @mem_virt used for access to IPA memory
......@@ -90,6 +91,7 @@ struct ipa {
dma_addr_t reg_addr;
void __iomem *reg_virt;
const struct ipa_regs *regs;
dma_addr_t mem_addr;
void *mem_virt;
......
......@@ -305,6 +305,7 @@ static bool ipa_cmd_register_write_offset_valid(struct ipa *ipa,
/* Check whether offsets passed to register_write are valid */
static bool ipa_cmd_register_write_valid(struct ipa *ipa)
{
const struct ipa_reg *reg;
const char *name;
u32 offset;
......@@ -312,7 +313,8 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa)
* offset will fit in a register write IPA immediate command.
*/
if (ipa_table_hash_support(ipa)) {
offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
reg = ipa_reg(ipa, FILT_ROUT_HASH_FLUSH);
offset = ipa_reg_offset(reg);
name = "filter/route hash flush";
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
return false;
......@@ -325,7 +327,8 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa)
* worst case (highest endpoint number) offset of that endpoint
* fits in the register write command field(s) that must hold it.
*/
offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT - 1);
reg = ipa_reg(ipa, ENDP_STATUS);
offset = ipa_reg_n_offset(reg, IPA_ENDPOINT_COUNT - 1);
name = "maximal endpoint status";
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
return false;
......
......@@ -72,14 +72,6 @@ struct ipa_status {
#define IPA_STATUS_FLAGS1_RT_RULE_ID_FMASK GENMASK(31, 22)
#define IPA_STATUS_FLAGS2_TAG_FMASK GENMASK_ULL(63, 16)
static u32 aggr_byte_limit_max(enum ipa_version version)
{
if (version < IPA_VERSION_4_5)
return field_max(aggr_byte_limit_fmask(true));
return field_max(aggr_byte_limit_fmask(false));
}
/* Compute the aggregation size value to use for a given buffer size */
static u32 ipa_aggr_size_kb(u32 rx_buffer_size, bool aggr_hard_limit)
{
......@@ -111,6 +103,7 @@ static bool ipa_endpoint_data_valid_one(struct ipa *ipa, u32 count,
if (!data->toward_ipa) {
const struct ipa_endpoint_rx *rx_config;
const struct ipa_reg *reg;
u32 buffer_size;
u32 aggr_size;
u32 limit;
......@@ -171,7 +164,9 @@ static bool ipa_endpoint_data_valid_one(struct ipa *ipa, u32 count,
*/
aggr_size = ipa_aggr_size_kb(buffer_size - NET_SKB_PAD,
rx_config->aggr_hard_limit);
limit = aggr_byte_limit_max(ipa->version);
reg = ipa_reg(ipa, ENDP_INIT_AGGR);
limit = ipa_reg_field_max(reg, BYTE_LIMIT);
if (aggr_size > limit) {
dev_err(dev, "aggregated size too large for RX endpoint %u (%u KB > %u KB)\n",
data->endpoint_id, aggr_size, limit);
......@@ -308,8 +303,10 @@ static struct gsi_trans *ipa_endpoint_trans_alloc(struct ipa_endpoint *endpoint,
static bool
ipa_endpoint_init_ctrl(struct ipa_endpoint *endpoint, bool suspend_delay)
{
u32 offset = IPA_REG_ENDP_INIT_CTRL_N_OFFSET(endpoint->endpoint_id);
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 field_id;
u32 offset;
bool state;
u32 mask;
u32 val;
......@@ -319,9 +316,13 @@ ipa_endpoint_init_ctrl(struct ipa_endpoint *endpoint, bool suspend_delay)
else
WARN_ON(ipa->version >= IPA_VERSION_4_0);
mask = endpoint->toward_ipa ? ENDP_DELAY_FMASK : ENDP_SUSPEND_FMASK;
reg = ipa_reg(ipa, ENDP_INIT_CTRL);
offset = ipa_reg_n_offset(reg, endpoint->endpoint_id);
val = ioread32(ipa->reg_virt + offset);
field_id = endpoint->toward_ipa ? ENDP_DELAY : ENDP_SUSPEND;
mask = ipa_reg_bit(reg, field_id);
state = !!(val & mask);
/* Don't bother if it's already in the requested state */
......@@ -348,13 +349,13 @@ static bool ipa_endpoint_aggr_active(struct ipa_endpoint *endpoint)
{
u32 mask = BIT(endpoint->endpoint_id);
struct ipa *ipa = endpoint->ipa;
u32 offset;
const struct ipa_reg *reg;
u32 val;
WARN_ON(!(mask & ipa->available));
offset = ipa_reg_state_aggr_active_offset(ipa->version);
val = ioread32(ipa->reg_virt + offset);
reg = ipa_reg(ipa, STATE_AGGR_ACTIVE);
val = ioread32(ipa->reg_virt + ipa_reg_offset(reg));
return !!(val & mask);
}
......@@ -363,10 +364,12 @@ static void ipa_endpoint_force_close(struct ipa_endpoint *endpoint)
{
u32 mask = BIT(endpoint->endpoint_id);
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
WARN_ON(!(mask & ipa->available));
iowrite32(mask, ipa->reg_virt + IPA_REG_AGGR_FORCE_CLOSE_OFFSET);
reg = ipa_reg(ipa, AGGR_FORCE_CLOSE);
iowrite32(mask, ipa->reg_virt + ipa_reg_offset(reg));
}
/**
......@@ -465,6 +468,7 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
while (initialized) {
u32 endpoint_id = __ffs(initialized);
struct ipa_endpoint *endpoint;
const struct ipa_reg *reg;
u32 offset;
initialized ^= BIT(endpoint_id);
......@@ -474,7 +478,8 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
if (!(endpoint->ee_id == GSI_EE_MODEM && endpoint->toward_ipa))
continue;
offset = IPA_REG_ENDP_STATUS_N_OFFSET(endpoint_id);
reg = ipa_reg(ipa, ENDP_STATUS);
offset = ipa_reg_n_offset(reg, endpoint_id);
/* Value written is 0, and all bits are updated. That
* means status is disabled on the endpoint, and as a
......@@ -494,22 +499,23 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa)
static void ipa_endpoint_init_cfg(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_CFG_N_OFFSET(endpoint->endpoint_id);
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
enum ipa_cs_offload_en enabled;
const struct ipa_reg *reg;
u32 val = 0;
reg = ipa_reg(ipa, ENDP_INIT_CFG);
/* FRAG_OFFLOAD_EN is 0 */
if (endpoint->config.checksum) {
enum ipa_version version = endpoint->ipa->version;
enum ipa_version version = ipa->version;
if (endpoint->toward_ipa) {
u32 off;
/* Checksum header offset is in 4-byte units */
off = sizeof(struct rmnet_map_header);
off /= sizeof(u32);
val |= u32_encode_bits(off,
CS_METADATA_HDR_OFFSET_FMASK);
off = sizeof(struct rmnet_map_header) / sizeof(u32);
val |= ipa_reg_encode(reg, CS_METADATA_HDR_OFFSET, off);
enabled = version < IPA_VERSION_4_5
? IPA_CS_OFFLOAD_UL
......@@ -522,24 +528,26 @@ static void ipa_endpoint_init_cfg(struct ipa_endpoint *endpoint)
} else {
enabled = IPA_CS_OFFLOAD_NONE;
}
val |= u32_encode_bits(enabled, CS_OFFLOAD_EN_FMASK);
val |= ipa_reg_encode(reg, CS_OFFLOAD_EN, enabled);
/* CS_GEN_QMB_MASTER_SEL is 0 */
iowrite32(val, endpoint->ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static void ipa_endpoint_init_nat(struct ipa_endpoint *endpoint)
{
u32 offset;
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val;
if (!endpoint->toward_ipa)
return;
offset = IPA_REG_ENDP_INIT_NAT_N_OFFSET(endpoint->endpoint_id);
val = u32_encode_bits(IPA_NAT_BYPASS, NAT_EN_FMASK);
reg = ipa_reg(ipa, ENDP_INIT_NAT);
val = ipa_reg_encode(reg, NAT_EN, IPA_NAT_BYPASS);
iowrite32(val, endpoint->ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static u32
......@@ -563,6 +571,50 @@ ipa_qmap_header_size(enum ipa_version version, struct ipa_endpoint *endpoint)
return header_size;
}
/* Encoded value for ENDP_INIT_HDR register HDR_LEN* field(s) */
static u32 ipa_header_size_encode(enum ipa_version version,
const struct ipa_reg *reg, u32 header_size)
{
u32 field_max = ipa_reg_field_max(reg, HDR_LEN);
u32 val;
/* We know field_max can be used as a mask (2^n - 1) */
val = ipa_reg_encode(reg, HDR_LEN, header_size & field_max);
if (version < IPA_VERSION_4_5) {
WARN_ON(header_size > field_max);
return val;
}
/* IPA v4.5 adds a few more most-significant bits */
header_size >>= hweight32(field_max);
WARN_ON(header_size > ipa_reg_field_max(reg, HDR_LEN_MSB));
val |= ipa_reg_encode(reg, HDR_LEN_MSB, header_size);
return val;
}
/* Encoded value for ENDP_INIT_HDR register OFST_METADATA* field(s) */
static u32 ipa_metadata_offset_encode(enum ipa_version version,
const struct ipa_reg *reg, u32 offset)
{
u32 field_max = ipa_reg_field_max(reg, HDR_OFST_METADATA);
u32 val;
/* We know field_max can be used as a mask (2^n - 1) */
val = ipa_reg_encode(reg, HDR_OFST_METADATA, offset);
if (version < IPA_VERSION_4_5) {
WARN_ON(offset > field_max);
return val;
}
/* IPA v4.5 adds a few more most-significant bits */
offset >>= hweight32(field_max);
WARN_ON(offset > ipa_reg_field_max(reg, HDR_OFST_METADATA_MSB));
val |= ipa_reg_encode(reg, HDR_OFST_METADATA_MSB, offset);
return val;
}
/**
* ipa_endpoint_init_hdr() - Initialize HDR endpoint configuration register
* @endpoint: Endpoint pointer
......@@ -586,36 +638,38 @@ ipa_qmap_header_size(enum ipa_version version, struct ipa_endpoint *endpoint)
*/
static void ipa_endpoint_init_hdr(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_HDR_N_OFFSET(endpoint->endpoint_id);
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val = 0;
reg = ipa_reg(ipa, ENDP_INIT_HDR);
if (endpoint->config.qmap) {
enum ipa_version version = ipa->version;
size_t header_size;
header_size = ipa_qmap_header_size(version, endpoint);
val = ipa_header_size_encoded(version, header_size);
val = ipa_header_size_encode(version, reg, header_size);
/* Define how to fill fields in a received QMAP header */
if (!endpoint->toward_ipa) {
u32 off; /* Field offset within header */
u32 off; /* Field offset within header */
/* Where IPA will write the metadata value */
off = offsetof(struct rmnet_map_header, mux_id);
val |= ipa_metadata_offset_encoded(version, off);
val |= ipa_metadata_offset_encode(version, reg, off);
/* Where IPA will write the length */
off = offsetof(struct rmnet_map_header, pkt_len);
/* Upper bits are stored in HDR_EXT with IPA v4.5 */
if (version >= IPA_VERSION_4_5)
off &= field_mask(HDR_OFST_PKT_SIZE_FMASK);
off &= ipa_reg_field_max(reg, HDR_OFST_PKT_SIZE);
val |= HDR_OFST_PKT_SIZE_VALID_FMASK;
val |= u32_encode_bits(off, HDR_OFST_PKT_SIZE_FMASK);
val |= ipa_reg_bit(reg, HDR_OFST_PKT_SIZE_VALID);
val |= ipa_reg_encode(reg, HDR_OFST_PKT_SIZE, off);
}
/* For QMAP TX, metadata offset is 0 (modem assumes this) */
val |= HDR_OFST_METADATA_VALID_FMASK;
val |= ipa_reg_bit(reg, HDR_OFST_METADATA_VALID);
/* HDR_ADDITIONAL_CONST_LEN is 0; (RX only) */
/* HDR_A5_MUX is 0 */
......@@ -623,19 +677,21 @@ static void ipa_endpoint_init_hdr(struct ipa_endpoint *endpoint)
/* HDR_METADATA_REG_VALID is 0 (TX only, version < v4.5) */
}
iowrite32(val, ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_HDR_EXT_N_OFFSET(endpoint->endpoint_id);
u32 pad_align = endpoint->config.rx.pad_align;
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val = 0;
reg = ipa_reg(ipa, ENDP_INIT_HDR_EXT);
if (endpoint->config.qmap) {
/* We have a header, so we must specify its endianness */
val |= HDR_ENDIANNESS_FMASK; /* big endian */
val |= ipa_reg_bit(reg, HDR_ENDIANNESS); /* big endian */
/* A QMAP header contains a 6 bit pad field at offset 0.
* The RMNet driver assumes this field is meaningful in
......@@ -645,16 +701,16 @@ static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint)
* (although 0) should be ignored.
*/
if (!endpoint->toward_ipa) {
val |= HDR_TOTAL_LEN_OR_PAD_VALID_FMASK;
val |= ipa_reg_bit(reg, HDR_TOTAL_LEN_OR_PAD_VALID);
/* HDR_TOTAL_LEN_OR_PAD is 0 (pad, not total_len) */
val |= HDR_PAYLOAD_LEN_INC_PADDING_FMASK;
val |= ipa_reg_bit(reg, HDR_PAYLOAD_LEN_INC_PADDING);
/* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0 */
}
}
/* HDR_PAYLOAD_LEN_INC_PADDING is 0 */
if (!endpoint->toward_ipa)
val |= u32_encode_bits(pad_align, HDR_PAD_TO_ALIGNMENT_FMASK);
val |= ipa_reg_encode(reg, HDR_PAD_TO_ALIGNMENT, pad_align);
/* IPA v4.5 adds some most-significant bits to a few fields,
* two of which are defined in the HDR (not HDR_EXT) register.
......@@ -662,67 +718,65 @@ static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint)
if (ipa->version >= IPA_VERSION_4_5) {
/* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0, so MSB is 0 */
if (endpoint->config.qmap && !endpoint->toward_ipa) {
u32 off;
u32 mask = ipa_reg_field_max(reg, HDR_OFST_PKT_SIZE);
u32 off; /* Field offset within header */
off = offsetof(struct rmnet_map_header, pkt_len);
off >>= hweight32(HDR_OFST_PKT_SIZE_FMASK);
val |= u32_encode_bits(off,
HDR_OFST_PKT_SIZE_MSB_FMASK);
/* Low bits are in the ENDP_INIT_HDR register */
off >>= hweight32(mask);
val |= ipa_reg_encode(reg, HDR_OFST_PKT_SIZE_MSB, off);
/* HDR_ADDITIONAL_CONST_LEN is 0 so MSB is 0 */
}
}
iowrite32(val, ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static void ipa_endpoint_init_hdr_metadata_mask(struct ipa_endpoint *endpoint)
{
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val = 0;
u32 offset;
if (endpoint->toward_ipa)
return; /* Register not valid for TX endpoints */
offset = IPA_REG_ENDP_INIT_HDR_METADATA_MASK_N_OFFSET(endpoint_id);
reg = ipa_reg(ipa, ENDP_INIT_HDR_METADATA_MASK);
offset = ipa_reg_n_offset(reg, endpoint_id);
/* Note that HDR_ENDIANNESS indicates big endian header fields */
if (endpoint->config.qmap)
val = (__force u32)cpu_to_be32(IPA_ENDPOINT_QMAP_METADATA_MASK);
iowrite32(val, endpoint->ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + offset);
}
static void ipa_endpoint_init_mode(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_MODE_N_OFFSET(endpoint->endpoint_id);
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 offset;
u32 val;
if (!endpoint->toward_ipa)
return; /* Register not valid for RX endpoints */
reg = ipa_reg(ipa, ENDP_INIT_MODE);
if (endpoint->config.dma_mode) {
enum ipa_endpoint_name name = endpoint->config.dma_endpoint;
u32 dma_endpoint_id;
dma_endpoint_id = endpoint->ipa->name_map[name]->endpoint_id;
u32 dma_endpoint_id = ipa->name_map[name]->endpoint_id;
val = u32_encode_bits(IPA_DMA, MODE_FMASK);
val |= u32_encode_bits(dma_endpoint_id, DEST_PIPE_INDEX_FMASK);
val = ipa_reg_encode(reg, ENDP_MODE, IPA_DMA);
val |= ipa_reg_encode(reg, DEST_PIPE_INDEX, dma_endpoint_id);
} else {
val = u32_encode_bits(IPA_BASIC, MODE_FMASK);
val = ipa_reg_encode(reg, ENDP_MODE, IPA_BASIC);
}
/* All other bits unspecified (and 0) */
iowrite32(val, endpoint->ipa->reg_virt + offset);
}
/* Encoded values for AGGR endpoint register fields */
static u32 aggr_byte_limit_encoded(enum ipa_version version, u32 limit)
{
if (version < IPA_VERSION_4_5)
return u32_encode_bits(limit, aggr_byte_limit_fmask(true));
return u32_encode_bits(limit, aggr_byte_limit_fmask(false));
offset = ipa_reg_n_offset(reg, endpoint->endpoint_id);
iowrite32(val, ipa->reg_virt + offset);
}
/* For IPA v4.5+, times are expressed using Qtime. The AP uses one of two
......@@ -750,95 +804,84 @@ static int ipa_qtime_val(u32 microseconds, u32 max)
}
/* Encode the aggregation timer limit (microseconds) based on IPA version */
static u32 aggr_time_limit_encode(enum ipa_version version, u32 microseconds)
static u32 aggr_time_limit_encode(struct ipa *ipa, const struct ipa_reg *reg,
u32 microseconds)
{
u32 fmask;
u32 max;
u32 val;
if (!microseconds)
return 0; /* Nothing to compute if time limit is 0 */
if (version >= IPA_VERSION_4_5) {
max = ipa_reg_field_max(reg, TIME_LIMIT);
if (ipa->version >= IPA_VERSION_4_5) {
u32 gran_sel;
int ret;
/* Compute the Qtime limit value to use */
fmask = aggr_time_limit_fmask(false);
ret = ipa_qtime_val(microseconds, field_max(fmask));
ret = ipa_qtime_val(microseconds, max);
if (ret < 0) {
val = -ret;
gran_sel = AGGR_GRAN_SEL_FMASK;
gran_sel = ipa_reg_bit(reg, AGGR_GRAN_SEL);
} else {
val = ret;
gran_sel = 0;
}
return gran_sel | u32_encode_bits(val, fmask);
return gran_sel | ipa_reg_encode(reg, TIME_LIMIT, val);
}
/* We set aggregation granularity in ipa_hardware_config() */
fmask = aggr_time_limit_fmask(true);
/* We program aggregation granularity in ipa_hardware_config() */
val = DIV_ROUND_CLOSEST(microseconds, IPA_AGGR_GRANULARITY);
WARN(val > field_max(fmask),
"aggr_time_limit too large (%u > %u usec)\n",
val, field_max(fmask) * IPA_AGGR_GRANULARITY);
return u32_encode_bits(val, fmask);
}
static u32 aggr_sw_eof_active_encoded(enum ipa_version version, bool enabled)
{
u32 val = enabled ? 1 : 0;
if (version < IPA_VERSION_4_5)
return u32_encode_bits(val, aggr_sw_eof_active_fmask(true));
WARN(val > max, "aggr_time_limit too large (%u > %u usec)\n",
microseconds, max * IPA_AGGR_GRANULARITY);
return u32_encode_bits(val, aggr_sw_eof_active_fmask(false));
return ipa_reg_encode(reg, TIME_LIMIT, val);
}
static void ipa_endpoint_init_aggr(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_AGGR_N_OFFSET(endpoint->endpoint_id);
enum ipa_version version = endpoint->ipa->version;
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val = 0;
reg = ipa_reg(ipa, ENDP_INIT_AGGR);
if (endpoint->config.aggregation) {
if (!endpoint->toward_ipa) {
const struct ipa_endpoint_rx *rx_config;
u32 buffer_size;
bool close_eof;
u32 limit;
rx_config = &endpoint->config.rx;
val |= u32_encode_bits(IPA_ENABLE_AGGR, AGGR_EN_FMASK);
val |= u32_encode_bits(IPA_GENERIC, AGGR_TYPE_FMASK);
val |= ipa_reg_encode(reg, AGGR_EN, IPA_ENABLE_AGGR);
val |= ipa_reg_encode(reg, AGGR_TYPE, IPA_GENERIC);
buffer_size = rx_config->buffer_size;
limit = ipa_aggr_size_kb(buffer_size - NET_SKB_PAD,
rx_config->aggr_hard_limit);
val |= aggr_byte_limit_encoded(version, limit);
val |= ipa_reg_encode(reg, BYTE_LIMIT, limit);
limit = rx_config->aggr_time_limit;
val |= aggr_time_limit_encode(version, limit);
val |= aggr_time_limit_encode(ipa, reg, limit);
/* AGGR_PKT_LIMIT is 0 (unlimited) */
close_eof = rx_config->aggr_close_eof;
val |= aggr_sw_eof_active_encoded(version, close_eof);
if (rx_config->aggr_close_eof)
val |= ipa_reg_bit(reg, SW_EOF_ACTIVE);
} else {
val |= u32_encode_bits(IPA_ENABLE_DEAGGR,
AGGR_EN_FMASK);
val |= u32_encode_bits(IPA_QCMAP, AGGR_TYPE_FMASK);
val |= ipa_reg_encode(reg, AGGR_EN, IPA_ENABLE_DEAGGR);
val |= ipa_reg_encode(reg, AGGR_TYPE, IPA_QCMAP);
/* other fields ignored */
}
/* AGGR_FORCE_CLOSE is 0 */
/* AGGR_GRAN_SEL is 0 for IPA v4.5 */
} else {
val |= u32_encode_bits(IPA_BYPASS_AGGR, AGGR_EN_FMASK);
val |= ipa_reg_encode(reg, AGGR_EN, IPA_BYPASS_AGGR);
/* other fields ignored */
}
iowrite32(val, endpoint->ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
/* The head-of-line blocking timer is defined as a tick count. For
......@@ -849,7 +892,8 @@ static void ipa_endpoint_init_aggr(struct ipa_endpoint *endpoint)
* Return the encoded value representing the timeout period provided
* that should be written to the ENDP_INIT_HOL_BLOCK_TIMER register.
*/
static u32 hol_block_timer_encode(struct ipa *ipa, u32 microseconds)
static u32 hol_block_timer_encode(struct ipa *ipa, const struct ipa_reg *reg,
u32 microseconds)
{
u32 width;
u32 scale;
......@@ -862,31 +906,33 @@ static u32 hol_block_timer_encode(struct ipa *ipa, u32 microseconds)
return 0; /* Nothing to compute if timer period is 0 */
if (ipa->version >= IPA_VERSION_4_5) {
u32 max = ipa_reg_field_max(reg, TIMER_LIMIT);
u32 gran_sel;
int ret;
/* Compute the Qtime limit value to use */
ret = ipa_qtime_val(microseconds, field_max(TIME_LIMIT_FMASK));
ret = ipa_qtime_val(microseconds, max);
if (ret < 0) {
val = -ret;
gran_sel = GRAN_SEL_FMASK;
gran_sel = ipa_reg_bit(reg, TIMER_GRAN_SEL);
} else {
val = ret;
gran_sel = 0;
}
return gran_sel | u32_encode_bits(val, TIME_LIMIT_FMASK);
return gran_sel | ipa_reg_encode(reg, TIMER_LIMIT, val);
}
/* Use 64 bit arithmetic to avoid overflow... */
/* Use 64 bit arithmetic to avoid overflow */
rate = ipa_core_clock_rate(ipa);
ticks = DIV_ROUND_CLOSEST(microseconds * rate, 128 * USEC_PER_SEC);
/* ...but we still need to fit into a 32-bit register */
WARN_ON(ticks > U32_MAX);
/* We still need the result to fit into the field */
WARN_ON(ticks > ipa_reg_field_max(reg, TIMER_BASE_VALUE));
/* IPA v3.5.1 through v4.1 just record the tick count */
if (ipa->version < IPA_VERSION_4_2)
return (u32)ticks;
return ipa_reg_encode(reg, TIMER_BASE_VALUE, (u32)ticks);
/* For IPA v4.2, the tick count is represented by base and
* scale fields within the 32-bit timer register, where:
......@@ -896,8 +942,8 @@ static u32 hol_block_timer_encode(struct ipa *ipa, u32 microseconds)
* count, and extract the number of bits in the base field
* such that high bit is included.
*/
high = fls(ticks); /* 1..32 */
width = HWEIGHT32(BASE_VALUE_FMASK);
high = fls(ticks); /* 1..32 (or warning above) */
width = hweight32(ipa_reg_fmask(reg, TIMER_BASE_VALUE));
scale = high > width ? high - width : 0;
if (scale) {
/* If we're scaling, round up to get a closer result */
......@@ -907,8 +953,8 @@ static u32 hol_block_timer_encode(struct ipa *ipa, u32 microseconds)
scale++;
}
val = u32_encode_bits(scale, SCALE_FMASK);
val |= u32_encode_bits(ticks >> scale, BASE_VALUE_FMASK);
val = ipa_reg_encode(reg, TIMER_SCALE, scale);
val |= ipa_reg_encode(reg, TIMER_BASE_VALUE, (u32)ticks >> scale);
return val;
}
......@@ -919,28 +965,34 @@ static void ipa_endpoint_init_hol_block_timer(struct ipa_endpoint *endpoint,
{
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
u32 offset;
const struct ipa_reg *reg;
u32 val;
/* This should only be changed when HOL_BLOCK_EN is disabled */
offset = IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(endpoint_id);
val = hol_block_timer_encode(ipa, microseconds);
iowrite32(val, ipa->reg_virt + offset);
reg = ipa_reg(ipa, ENDP_INIT_HOL_BLOCK_TIMER);
val = hol_block_timer_encode(ipa, reg, microseconds);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static void
ipa_endpoint_init_hol_block_en(struct ipa_endpoint *endpoint, bool enable)
{
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 offset;
u32 val;
val = enable ? HOL_BLOCK_EN_FMASK : 0;
offset = IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(endpoint_id);
iowrite32(val, endpoint->ipa->reg_virt + offset);
reg = ipa_reg(ipa, ENDP_INIT_HOL_BLOCK_EN);
offset = ipa_reg_n_offset(reg, endpoint_id);
val = enable ? ipa_reg_bit(reg, HOL_BLOCK_EN) : 0;
iowrite32(val, ipa->reg_virt + offset);
/* When enabling, the register must be written twice for IPA v4.5+ */
if (enable && endpoint->ipa->version >= IPA_VERSION_4_5)
iowrite32(val, endpoint->ipa->reg_virt + offset);
if (enable && ipa->version >= IPA_VERSION_4_5)
iowrite32(val, ipa->reg_virt + offset);
}
/* Assumes HOL_BLOCK is in disabled state */
......@@ -973,47 +1025,58 @@ void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa)
static void ipa_endpoint_init_deaggr(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_DEAGGR_N_OFFSET(endpoint->endpoint_id);
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val = 0;
if (!endpoint->toward_ipa)
return; /* Register not valid for RX endpoints */
reg = ipa_reg(ipa, ENDP_INIT_DEAGGR);
/* DEAGGR_HDR_LEN is 0 */
/* PACKET_OFFSET_VALID is 0 */
/* PACKET_OFFSET_LOCATION is ignored (not valid) */
/* MAX_PACKET_LEN is 0 (not enforced) */
iowrite32(val, endpoint->ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static void ipa_endpoint_init_rsrc_grp(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_RSRC_GRP_N_OFFSET(endpoint->endpoint_id);
u32 resource_group = endpoint->config.resource_group;
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val;
val = rsrc_grp_encoded(ipa->version, endpoint->config.resource_group);
iowrite32(val, ipa->reg_virt + offset);
reg = ipa_reg(ipa, ENDP_INIT_RSRC_GRP);
val = ipa_reg_encode(reg, ENDP_RSRC_GRP, resource_group);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static void ipa_endpoint_init_seq(struct ipa_endpoint *endpoint)
{
u32 offset = IPA_REG_ENDP_INIT_SEQ_N_OFFSET(endpoint->endpoint_id);
u32 val = 0;
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val;
if (!endpoint->toward_ipa)
return; /* Register not valid for RX endpoints */
reg = ipa_reg(ipa, ENDP_INIT_SEQ);
/* Low-order byte configures primary packet processing */
val |= u32_encode_bits(endpoint->config.tx.seq_type, SEQ_TYPE_FMASK);
val = ipa_reg_encode(reg, SEQ_TYPE, endpoint->config.tx.seq_type);
/* Second byte (if supported) configures replicated packet processing */
if (endpoint->ipa->version < IPA_VERSION_4_5)
val |= u32_encode_bits(endpoint->config.tx.seq_rep_type,
SEQ_REP_TYPE_FMASK);
if (ipa->version < IPA_VERSION_4_5)
val |= ipa_reg_encode(reg, SEQ_REP_TYPE,
endpoint->config.tx.seq_rep_type);
iowrite32(val, endpoint->ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
/**
......@@ -1063,13 +1126,12 @@ static void ipa_endpoint_status(struct ipa_endpoint *endpoint)
{
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 val = 0;
u32 offset;
offset = IPA_REG_ENDP_STATUS_N_OFFSET(endpoint_id);
reg = ipa_reg(ipa, ENDP_STATUS);
if (endpoint->config.status_enable) {
val |= STATUS_EN_FMASK;
val |= ipa_reg_bit(reg, STATUS_EN);
if (endpoint->toward_ipa) {
enum ipa_endpoint_name name;
u32 status_endpoint_id;
......@@ -1077,16 +1139,16 @@ static void ipa_endpoint_status(struct ipa_endpoint *endpoint)
name = endpoint->config.tx.status_endpoint;
status_endpoint_id = ipa->name_map[name]->endpoint_id;
val |= u32_encode_bits(status_endpoint_id,
STATUS_ENDP_FMASK);
val |= ipa_reg_encode(reg, STATUS_ENDP,
status_endpoint_id);
}
/* STATUS_LOCATION is 0, meaning status element precedes
* packet (not present for IPA v4.5)
* packet (not present for IPA v4.5+)
*/
/* STATUS_PKT_SUPPRESS_FMASK is 0 (not present for v3.5.1) */
/* STATUS_PKT_SUPPRESS_FMASK is 0 (not present for v4.0+) */
}
iowrite32(val, ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, endpoint_id));
}
static int ipa_endpoint_replenish_one(struct ipa_endpoint *endpoint,
......@@ -1426,16 +1488,18 @@ void ipa_endpoint_trans_release(struct ipa_endpoint *endpoint,
void ipa_endpoint_default_route_set(struct ipa *ipa, u32 endpoint_id)
{
const struct ipa_reg *reg;
u32 val;
reg = ipa_reg(ipa, ROUTE);
/* ROUTE_DIS is 0 */
val = u32_encode_bits(endpoint_id, ROUTE_DEF_PIPE_FMASK);
val |= ROUTE_DEF_HDR_TABLE_FMASK;
val |= u32_encode_bits(0, ROUTE_DEF_HDR_OFST_FMASK);
val |= u32_encode_bits(endpoint_id, ROUTE_FRAG_DEF_PIPE_FMASK);
val |= ROUTE_DEF_RETAIN_HDR_FMASK;
val = ipa_reg_encode(reg, ROUTE_DEF_PIPE, endpoint_id);
val |= ipa_reg_bit(reg, ROUTE_DEF_HDR_TABLE);
/* ROUTE_DEF_HDR_OFST is 0 */
val |= ipa_reg_encode(reg, ROUTE_FRAG_DEF_PIPE, endpoint_id);
val |= ipa_reg_bit(reg, ROUTE_DEF_RETAIN_HDR);
iowrite32(val, ipa->reg_virt + IPA_REG_ROUTE_OFFSET);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
void ipa_endpoint_default_route_clear(struct ipa *ipa)
......@@ -1779,6 +1843,7 @@ void ipa_endpoint_teardown(struct ipa *ipa)
int ipa_endpoint_config(struct ipa *ipa)
{
struct device *dev = &ipa->pdev->dev;
const struct ipa_reg *reg;
u32 initialized;
u32 rx_base;
u32 rx_mask;
......@@ -1805,11 +1870,12 @@ int ipa_endpoint_config(struct ipa *ipa)
/* Find out about the endpoints supplied by the hardware, and ensure
* the highest one doesn't exceed the number we support.
*/
val = ioread32(ipa->reg_virt + IPA_REG_FLAVOR_0_OFFSET);
reg = ipa_reg(ipa, FLAVOR_0);
val = ioread32(ipa->reg_virt + ipa_reg_offset(reg));
/* Our RX is an IPA producer */
rx_base = u32_get_bits(val, IPA_PROD_LOWEST_FMASK);
max = rx_base + u32_get_bits(val, IPA_MAX_PROD_PIPES_FMASK);
rx_base = ipa_reg_decode(reg, PROD_LOWEST, val);
max = rx_base + ipa_reg_decode(reg, MAX_PROD_PIPES, val);
if (max > IPA_ENDPOINT_MAX) {
dev_err(dev, "too many endpoints (%u > %u)\n",
max, IPA_ENDPOINT_MAX);
......@@ -1818,7 +1884,7 @@ int ipa_endpoint_config(struct ipa *ipa)
rx_mask = GENMASK(max - 1, rx_base);
/* Our TX is an IPA consumer */
max = u32_get_bits(val, IPA_MAX_CONS_PIPES_FMASK);
max = ipa_reg_decode(reg, MAX_CONS_PIPES, val);
tx_mask = GENMASK(max - 1, 0);
ipa->available = rx_mask | tx_mask;
......
......@@ -53,13 +53,15 @@ static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id)
{
bool uc_irq = ipa_interrupt_uc(interrupt, irq_id);
struct ipa *ipa = interrupt->ipa;
const struct ipa_reg *reg;
u32 mask = BIT(irq_id);
u32 offset;
/* For microcontroller interrupts, clear the interrupt right away,
* "to avoid clearing unhandled interrupts."
*/
offset = ipa_reg_irq_clr_offset(ipa->version);
reg = ipa_reg(ipa, IPA_IRQ_CLR);
offset = ipa_reg_offset(reg);
if (uc_irq)
iowrite32(mask, ipa->reg_virt + offset);
......@@ -80,6 +82,7 @@ static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
struct ipa_interrupt *interrupt = dev_id;
struct ipa *ipa = interrupt->ipa;
u32 enabled = interrupt->enabled;
const struct ipa_reg *reg;
struct device *dev;
u32 pending;
u32 offset;
......@@ -95,7 +98,8 @@ static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
* including conditions whose interrupt is not enabled. Handle
* only the enabled ones.
*/
offset = ipa_reg_irq_stts_offset(ipa->version);
reg = ipa_reg(ipa, IPA_IRQ_STTS);
offset = ipa_reg_offset(reg);
pending = ioread32(ipa->reg_virt + offset);
while ((mask = pending & enabled)) {
do {
......@@ -112,7 +116,8 @@ static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
if (pending) {
dev_dbg(dev, "clearing disabled IPA interrupts 0x%08x\n",
pending);
offset = ipa_reg_irq_clr_offset(ipa->version);
reg = ipa_reg(ipa, IPA_IRQ_CLR);
offset = ipa_reg_offset(reg);
iowrite32(pending, ipa->reg_virt + offset);
}
out_power_put:
......@@ -128,6 +133,7 @@ static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt,
{
struct ipa *ipa = interrupt->ipa;
u32 mask = BIT(endpoint_id);
const struct ipa_reg *reg;
u32 offset;
u32 val;
......@@ -137,7 +143,8 @@ static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt,
if (ipa->version == IPA_VERSION_3_0)
return;
offset = ipa_reg_irq_suspend_en_offset(ipa->version);
reg = ipa_reg(ipa, IRQ_SUSPEND_EN);
offset = ipa_reg_offset(reg);
val = ioread32(ipa->reg_virt + offset);
if (enable)
val |= mask;
......@@ -164,18 +171,18 @@ ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, u32 endpoint_id)
void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt)
{
struct ipa *ipa = interrupt->ipa;
u32 offset;
const struct ipa_reg *reg;
u32 val;
offset = ipa_reg_irq_suspend_info_offset(ipa->version);
val = ioread32(ipa->reg_virt + offset);
reg = ipa_reg(ipa, IRQ_SUSPEND_INFO);
val = ioread32(ipa->reg_virt + ipa_reg_offset(reg));
/* SUSPEND interrupt status isn't cleared on IPA version 3.0 */
if (ipa->version == IPA_VERSION_3_0)
return;
offset = ipa_reg_irq_suspend_clr_offset(ipa->version);
iowrite32(val, ipa->reg_virt + offset);
reg = ipa_reg(ipa, IRQ_SUSPEND_CLR);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
/* Simulate arrival of an IPA TX_SUSPEND interrupt */
......@@ -189,7 +196,7 @@ void ipa_interrupt_add(struct ipa_interrupt *interrupt,
enum ipa_irq_id ipa_irq, ipa_irq_handler_t handler)
{
struct ipa *ipa = interrupt->ipa;
u32 offset;
const struct ipa_reg *reg;
if (WARN_ON(ipa_irq >= IPA_IRQ_COUNT))
return;
......@@ -198,8 +205,9 @@ void ipa_interrupt_add(struct ipa_interrupt *interrupt,
/* Update the IPA interrupt mask to enable it */
interrupt->enabled |= BIT(ipa_irq);
offset = ipa_reg_irq_en_offset(ipa->version);
iowrite32(interrupt->enabled, ipa->reg_virt + offset);
reg = ipa_reg(ipa, IPA_IRQ_EN);
iowrite32(interrupt->enabled, ipa->reg_virt + ipa_reg_offset(reg));
}
/* Remove the handler for an IPA interrupt type */
......@@ -207,15 +215,16 @@ void
ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq)
{
struct ipa *ipa = interrupt->ipa;
u32 offset;
const struct ipa_reg *reg;
if (WARN_ON(ipa_irq >= IPA_IRQ_COUNT))
return;
/* Update the IPA interrupt mask to disable it */
interrupt->enabled &= ~BIT(ipa_irq);
offset = ipa_reg_irq_en_offset(ipa->version);
iowrite32(interrupt->enabled, ipa->reg_virt + offset);
reg = ipa_reg(ipa, IPA_IRQ_EN);
iowrite32(interrupt->enabled, ipa->reg_virt + ipa_reg_offset(reg));
interrupt->handler[ipa_irq] = NULL;
}
......@@ -225,8 +234,8 @@ struct ipa_interrupt *ipa_interrupt_config(struct ipa *ipa)
{
struct device *dev = &ipa->pdev->dev;
struct ipa_interrupt *interrupt;
const struct ipa_reg *reg;
unsigned int irq;
u32 offset;
int ret;
ret = platform_get_irq_byname(ipa->pdev, "ipa");
......@@ -244,8 +253,8 @@ struct ipa_interrupt *ipa_interrupt_config(struct ipa *ipa)
interrupt->irq = irq;
/* Start with all IPA interrupts disabled */
offset = ipa_reg_irq_en_offset(ipa->version);
iowrite32(0, ipa->reg_virt + offset);
reg = ipa_reg(ipa, IPA_IRQ_EN);
iowrite32(0, ipa->reg_virt + ipa_reg_offset(reg));
ret = request_threaded_irq(irq, NULL, ipa_isr_thread, IRQF_ONESHOT,
"ipa", interrupt);
......
......@@ -186,78 +186,94 @@ static void ipa_teardown(struct ipa *ipa)
static void
ipa_hardware_config_bcr(struct ipa *ipa, const struct ipa_data *data)
{
const struct ipa_reg *reg;
u32 val;
/* IPA v4.5+ has no backward compatibility register */
if (ipa->version >= IPA_VERSION_4_5)
return;
reg = ipa_reg(ipa, IPA_BCR);
val = data->backward_compat;
iowrite32(val, ipa->reg_virt + IPA_REG_BCR_OFFSET);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
static void ipa_hardware_config_tx(struct ipa *ipa)
{
enum ipa_version version = ipa->version;
const struct ipa_reg *reg;
u32 offset;
u32 val;
if (version <= IPA_VERSION_4_0 || version >= IPA_VERSION_4_5)
return;
/* Disable PA mask to allow HOLB drop */
val = ioread32(ipa->reg_virt + IPA_REG_TX_CFG_OFFSET);
reg = ipa_reg(ipa, IPA_TX_CFG);
offset = ipa_reg_offset(reg);
val = ioread32(ipa->reg_virt + offset);
val &= ~PA_MASK_EN_FMASK;
val &= ~ipa_reg_bit(reg, PA_MASK_EN);
iowrite32(val, ipa->reg_virt + IPA_REG_TX_CFG_OFFSET);
iowrite32(val, ipa->reg_virt + offset);
}
static void ipa_hardware_config_clkon(struct ipa *ipa)
{
enum ipa_version version = ipa->version;
const struct ipa_reg *reg;
u32 val;
if (version < IPA_VERSION_3_1 || version >= IPA_VERSION_4_5)
if (version >= IPA_VERSION_4_5)
return;
if (version < IPA_VERSION_4_0 && version != IPA_VERSION_3_1)
return;
/* Implement some hardware workarounds */
if (version >= IPA_VERSION_4_0) {
reg = ipa_reg(ipa, CLKON_CFG);
if (version == IPA_VERSION_3_1) {
/* Disable MISC clock gating */
val = ipa_reg_bit(reg, CLKON_MISC);
} else { /* IPA v4.0+ */
/* 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 {
return;
val = ipa_reg_bit(reg, CLKON_GLOBAL);
val |= ipa_reg_bit(reg, GLOBAL_2X_CLK);
}
iowrite32(val, ipa->reg_virt + IPA_REG_CLKON_CFG_OFFSET);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
/* Configure bus access behavior for IPA components */
static void ipa_hardware_config_comp(struct ipa *ipa)
{
const struct ipa_reg *reg;
u32 offset;
u32 val;
/* Nothing to configure prior to IPA v4.0 */
if (ipa->version < IPA_VERSION_4_0)
return;
val = ioread32(ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET);
reg = ipa_reg(ipa, COMP_CFG);
offset = ipa_reg_offset(reg);
val = ioread32(ipa->reg_virt + offset);
if (ipa->version == IPA_VERSION_4_0) {
val &= ~IPA_QMB_SELECT_CONS_EN_FMASK;
val &= ~IPA_QMB_SELECT_PROD_EN_FMASK;
val &= ~IPA_QMB_SELECT_GLOBAL_EN_FMASK;
val &= ~ipa_reg_bit(reg, IPA_QMB_SELECT_CONS_EN);
val &= ~ipa_reg_bit(reg, IPA_QMB_SELECT_PROD_EN);
val &= ~ipa_reg_bit(reg, IPA_QMB_SELECT_GLOBAL_EN);
} else if (ipa->version < IPA_VERSION_4_5) {
val |= GSI_MULTI_AXI_MASTERS_DIS_FMASK;
val |= ipa_reg_bit(reg, GSI_MULTI_AXI_MASTERS_DIS);
} else {
/* For IPA v4.5 IPA_FULL_FLUSH_WAIT_RSC_CLOSE_EN is 0 */
/* For IPA v4.5 FULL_FLUSH_WAIT_RS_CLOSURE_EN is 0 */
}
val |= GSI_MULTI_INORDER_RD_DIS_FMASK;
val |= GSI_MULTI_INORDER_WR_DIS_FMASK;
val |= ipa_reg_bit(reg, GSI_MULTI_INORDER_RD_DIS);
val |= ipa_reg_bit(reg, GSI_MULTI_INORDER_WR_DIS);
iowrite32(val, ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET);
iowrite32(val, ipa->reg_virt + offset);
}
/* Configure DDR and (possibly) PCIe max read/write QSB values */
......@@ -266,6 +282,7 @@ ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data)
{
const struct ipa_qsb_data *data0;
const struct ipa_qsb_data *data1;
const struct ipa_reg *reg;
u32 val;
/* QMB 0 represents DDR; QMB 1 (if present) represents PCIe */
......@@ -274,25 +291,31 @@ ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data)
data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE];
/* Max outstanding write accesses for QSB masters */
val = u32_encode_bits(data0->max_writes, GEN_QMB_0_MAX_WRITES_FMASK);
reg = ipa_reg(ipa, QSB_MAX_WRITES);
val = ipa_reg_encode(reg, GEN_QMB_0_MAX_WRITES, data0->max_writes);
if (data->qsb_count > 1)
val |= u32_encode_bits(data1->max_writes,
GEN_QMB_1_MAX_WRITES_FMASK);
iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_WRITES_OFFSET);
val |= ipa_reg_encode(reg, GEN_QMB_1_MAX_WRITES,
data1->max_writes);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
/* Max outstanding read accesses for QSB masters */
val = u32_encode_bits(data0->max_reads, GEN_QMB_0_MAX_READS_FMASK);
reg = ipa_reg(ipa, QSB_MAX_READS);
val = ipa_reg_encode(reg, GEN_QMB_0_MAX_READS, data0->max_reads);
if (ipa->version >= IPA_VERSION_4_0)
val |= u32_encode_bits(data0->max_reads_beats,
GEN_QMB_0_MAX_READS_BEATS_FMASK);
val |= ipa_reg_encode(reg, GEN_QMB_0_MAX_READS_BEATS,
data0->max_reads_beats);
if (data->qsb_count > 1) {
val |= u32_encode_bits(data1->max_reads,
GEN_QMB_1_MAX_READS_FMASK);
val = ipa_reg_encode(reg, GEN_QMB_1_MAX_READS,
data1->max_reads);
if (ipa->version >= IPA_VERSION_4_0)
val |= u32_encode_bits(data1->max_reads_beats,
GEN_QMB_1_MAX_READS_BEATS_FMASK);
val |= ipa_reg_encode(reg, GEN_QMB_1_MAX_READS_BEATS,
data1->max_reads_beats);
}
iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_READS_OFFSET);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
/* The internal inactivity timer clock is used for the aggregation timer */
......@@ -328,45 +351,56 @@ static __always_inline u32 ipa_aggr_granularity_val(u32 usec)
*/
static void ipa_qtime_config(struct ipa *ipa)
{
const struct ipa_reg *reg;
u32 offset;
u32 val;
/* Timer clock divider must be disabled when we change the rate */
iowrite32(0, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET);
reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG);
iowrite32(0, ipa->reg_virt + ipa_reg_offset(reg));
reg = ipa_reg(ipa, QTIME_TIMESTAMP_CFG);
/* Set DPL time stamp resolution to use Qtime (instead of 1 msec) */
val = u32_encode_bits(DPL_TIMESTAMP_SHIFT, DPL_TIMESTAMP_LSB_FMASK);
val |= u32_encode_bits(1, DPL_TIMESTAMP_SEL_FMASK);
val = ipa_reg_encode(reg, DPL_TIMESTAMP_LSB, DPL_TIMESTAMP_SHIFT);
val |= ipa_reg_bit(reg, DPL_TIMESTAMP_SEL);
/* Configure tag and NAT Qtime timestamp resolution as well */
val |= u32_encode_bits(TAG_TIMESTAMP_SHIFT, TAG_TIMESTAMP_LSB_FMASK);
val |= u32_encode_bits(NAT_TIMESTAMP_SHIFT, NAT_TIMESTAMP_LSB_FMASK);
iowrite32(val, ipa->reg_virt + IPA_REG_QTIME_TIMESTAMP_CFG_OFFSET);
val = ipa_reg_encode(reg, TAG_TIMESTAMP_LSB, TAG_TIMESTAMP_SHIFT);
val = ipa_reg_encode(reg, NAT_TIMESTAMP_LSB, NAT_TIMESTAMP_SHIFT);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
/* Set granularity of pulse generators used for other timers */
val = u32_encode_bits(IPA_GRAN_100_US, GRAN_0_FMASK);
val |= u32_encode_bits(IPA_GRAN_1_MS, GRAN_1_FMASK);
val |= u32_encode_bits(IPA_GRAN_1_MS, GRAN_2_FMASK);
iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_PULSE_GRAN_CFG_OFFSET);
reg = ipa_reg(ipa, TIMERS_PULSE_GRAN_CFG);
val = ipa_reg_encode(reg, PULSE_GRAN_0, IPA_GRAN_100_US);
val |= ipa_reg_encode(reg, PULSE_GRAN_1, IPA_GRAN_1_MS);
val |= ipa_reg_encode(reg, PULSE_GRAN_2, IPA_GRAN_1_MS);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
/* Actual divider is 1 more than value supplied here */
val = u32_encode_bits(IPA_XO_CLOCK_DIVIDER - 1, DIV_VALUE_FMASK);
iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET);
reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG);
offset = ipa_reg_offset(reg);
val = ipa_reg_encode(reg, DIV_VALUE, IPA_XO_CLOCK_DIVIDER - 1);
iowrite32(val, ipa->reg_virt + offset);
/* Divider value is set; re-enable the common timer clock divider */
val |= u32_encode_bits(1, DIV_ENABLE_FMASK);
iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET);
val |= ipa_reg_bit(reg, DIV_ENABLE);
iowrite32(val, ipa->reg_virt + offset);
}
/* Before IPA v4.5 timing is controlled by a counter register */
static void ipa_hardware_config_counter(struct ipa *ipa)
{
u32 granularity;
u32 granularity = ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY);
const struct ipa_reg *reg;
u32 val;
granularity = ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY);
val = u32_encode_bits(granularity, AGGR_GRANULARITY_FMASK);
iowrite32(val, ipa->reg_virt + IPA_REG_COUNTER_CFG_OFFSET);
reg = ipa_reg(ipa, COUNTER_CFG);
/* If defined, EOT_COAL_GRANULARITY is 0 */
val = ipa_reg_encode(reg, AGGR_GRANULARITY, granularity);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
static void ipa_hardware_config_timing(struct ipa *ipa)
......@@ -379,30 +413,34 @@ static void ipa_hardware_config_timing(struct ipa *ipa)
static void ipa_hardware_config_hashing(struct ipa *ipa)
{
u32 offset;
const struct ipa_reg *reg;
if (ipa->version != IPA_VERSION_4_2)
return;
/* IPA v4.2 does not support hashed tables, so disable them */
offset = ipa_reg_filt_rout_hash_en_offset(IPA_VERSION_4_2);
iowrite32(0, ipa->reg_virt + offset);
reg = ipa_reg(ipa, FILT_ROUT_HASH_EN);
/* IPV6_ROUTER_HASH, IPV6_FILTER_HASH, IPV4_ROUTER_HASH,
* IPV4_FILTER_HASH are all zero.
*/
iowrite32(0, ipa->reg_virt + ipa_reg_offset(reg));
}
static void ipa_idle_indication_cfg(struct ipa *ipa,
u32 enter_idle_debounce_thresh,
bool const_non_idle_enable)
{
u32 offset;
const struct ipa_reg *reg;
u32 val;
val = u32_encode_bits(enter_idle_debounce_thresh,
ENTER_IDLE_DEBOUNCE_THRESH_FMASK);
reg = ipa_reg(ipa, IDLE_INDICATION_CFG);
val = ipa_reg_encode(reg, ENTER_IDLE_DEBOUNCE_THRESH,
enter_idle_debounce_thresh);
if (const_non_idle_enable)
val |= CONST_NON_IDLE_ENABLE_FMASK;
val |= ipa_reg_bit(reg, CONST_NON_IDLE_ENABLE);
offset = ipa_reg_idle_indication_cfg_offset(ipa->version);
iowrite32(val, ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
/**
......@@ -653,8 +691,6 @@ static void ipa_validate_build(void)
/* Aggregation granularity value can't be 0, and must fit */
BUILD_BUG_ON(!ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY));
BUILD_BUG_ON(ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY) >
field_max(AGGR_GRANULARITY_FMASK));
}
/**
......
......@@ -75,6 +75,7 @@ ipa_mem_zero_region_add(struct gsi_trans *trans, enum ipa_mem_id mem_id)
int ipa_mem_setup(struct ipa *ipa)
{
dma_addr_t addr = ipa->zero_addr;
const struct ipa_reg *reg;
const struct ipa_mem *mem;
struct gsi_trans *trans;
u32 offset;
......@@ -112,8 +113,10 @@ int ipa_mem_setup(struct ipa *ipa)
/* 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;
val = proc_cntxt_base_addr_encoded(ipa->version, offset);
iowrite32(val, ipa->reg_virt + IPA_REG_LOCAL_PKT_PROC_CNTXT_OFFSET);
reg = ipa_reg(ipa, LOCAL_PKT_PROC_CNTXT);
val = ipa_reg_encode(reg, IPA_BASE_ADDR, offset);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
return 0;
}
......@@ -306,6 +309,7 @@ static bool ipa_mem_size_valid(struct ipa *ipa)
int ipa_mem_config(struct ipa *ipa)
{
struct device *dev = &ipa->pdev->dev;
const struct ipa_reg *reg;
const struct ipa_mem *mem;
dma_addr_t addr;
u32 mem_size;
......@@ -314,12 +318,14 @@ int ipa_mem_config(struct ipa *ipa)
u32 i;
/* Check the advertised location and size of the shared memory area */
val = ioread32(ipa->reg_virt + IPA_REG_SHARED_MEM_SIZE_OFFSET);
reg = ipa_reg(ipa, SHARED_MEM_SIZE);
val = ioread32(ipa->reg_virt + ipa_reg_offset(reg));
/* The fields in the register are in 8 byte units */
ipa->mem_offset = 8 * u32_get_bits(val, SHARED_MEM_BADDR_FMASK);
ipa->mem_offset = 8 * ipa_reg_decode(reg, MEM_BADDR, val);
/* Make sure the end is within the region's mapped space */
mem_size = 8 * u32_get_bits(val, SHARED_MEM_SIZE_FMASK);
mem_size = 8 * ipa_reg_decode(reg, MEM_SIZE, val);
/* If the sizes don't match, issue a warning */
if (ipa->mem_offset + mem_size < ipa->mem_size) {
......
......@@ -9,11 +9,105 @@
#include "ipa.h"
#include "ipa_reg.h"
/* Is this register valid and defined for the current IPA version? */
static bool ipa_reg_valid(struct ipa *ipa, enum ipa_reg_id reg_id)
{
enum ipa_version version = ipa->version;
bool valid;
/* Check for bogus (out of range) register IDs */
if ((u32)reg_id >= ipa->regs->reg_count)
return false;
switch (reg_id) {
case IPA_BCR:
case COUNTER_CFG:
valid = version < IPA_VERSION_4_5;
break;
case IPA_TX_CFG:
case FLAVOR_0:
case IDLE_INDICATION_CFG:
valid = version >= IPA_VERSION_3_5;
break;
case QTIME_TIMESTAMP_CFG:
case TIMERS_XO_CLK_DIV_CFG:
case TIMERS_PULSE_GRAN_CFG:
valid = version >= IPA_VERSION_4_5;
break;
case SRC_RSRC_GRP_45_RSRC_TYPE:
case DST_RSRC_GRP_45_RSRC_TYPE:
valid = version <= IPA_VERSION_3_1 ||
version == IPA_VERSION_4_5;
break;
case SRC_RSRC_GRP_67_RSRC_TYPE:
case DST_RSRC_GRP_67_RSRC_TYPE:
valid = version <= IPA_VERSION_3_1;
break;
case ENDP_FILTER_ROUTER_HSH_CFG:
valid = version != IPA_VERSION_4_2;
break;
case IRQ_SUSPEND_EN:
case IRQ_SUSPEND_CLR:
valid = version >= IPA_VERSION_3_1;
break;
default:
valid = true; /* Others should be defined for all versions */
break;
}
/* To be valid, it must be defined */
return valid && ipa->regs->reg[reg_id];
}
const struct ipa_reg *ipa_reg(struct ipa *ipa, enum ipa_reg_id reg_id)
{
if (WARN_ON(!ipa_reg_valid(ipa, reg_id)))
return NULL;
return ipa->regs->reg[reg_id];
}
static const struct ipa_regs *ipa_regs(enum ipa_version version)
{
switch (version) {
case IPA_VERSION_3_1:
return &ipa_regs_v3_1;
case IPA_VERSION_3_5_1:
return &ipa_regs_v3_5_1;
case IPA_VERSION_4_2:
return &ipa_regs_v4_2;
case IPA_VERSION_4_5:
return &ipa_regs_v4_5;
case IPA_VERSION_4_9:
return &ipa_regs_v4_9;
case IPA_VERSION_4_11:
return &ipa_regs_v4_11;
default:
return NULL;
}
}
int ipa_reg_init(struct ipa *ipa)
{
struct device *dev = &ipa->pdev->dev;
const struct ipa_regs *regs;
struct resource *res;
regs = ipa_regs(ipa->version);
if (!regs)
return -EINVAL;
if (WARN_ON(regs->reg_count > IPA_REG_ID_COUNT))
return -EINVAL;
/* Setup IPA register memory */
res = platform_get_resource_byname(ipa->pdev, IORESOURCE_MEM,
"ipa-reg");
......@@ -28,6 +122,7 @@ int ipa_reg_init(struct ipa *ipa)
return -ENOMEM;
}
ipa->reg_addr = res->start;
ipa->regs = regs;
return 0;
}
......
......@@ -7,6 +7,7 @@
#define _IPA_REG_H_
#include <linux/bitfield.h>
#include <linux/bug.h>
#include "ipa_version.h"
......@@ -65,161 +66,215 @@ struct ipa;
* of valid bits for the register.
*/
#define IPA_REG_COMP_CFG_OFFSET 0x0000003c
/* The next field is not supported for IPA v4.0+, not present for IPA v4.5+ */
#define ENABLE_FMASK GENMASK(0, 0)
/* The next field is present for IPA v4.7+ */
#define RAM_ARB_PRI_CLIENT_SAMP_FIX_DIS_FMASK GENMASK(0, 0)
#define GSI_SNOC_BYPASS_DIS_FMASK GENMASK(1, 1)
#define GEN_QMB_0_SNOC_BYPASS_DIS_FMASK GENMASK(2, 2)
#define GEN_QMB_1_SNOC_BYPASS_DIS_FMASK GENMASK(3, 3)
/* The next field is not present for IPA v4.5+ */
#define IPA_DCMP_FAST_CLK_EN_FMASK GENMASK(4, 4)
/* The next twelve fields are present for IPA v4.0+ */
#define IPA_QMB_SELECT_CONS_EN_FMASK GENMASK(5, 5)
#define IPA_QMB_SELECT_PROD_EN_FMASK GENMASK(6, 6)
#define GSI_MULTI_INORDER_RD_DIS_FMASK GENMASK(7, 7)
#define GSI_MULTI_INORDER_WR_DIS_FMASK GENMASK(8, 8)
#define GEN_QMB_0_MULTI_INORDER_RD_DIS_FMASK GENMASK(9, 9)
#define GEN_QMB_1_MULTI_INORDER_RD_DIS_FMASK GENMASK(10, 10)
#define GEN_QMB_0_MULTI_INORDER_WR_DIS_FMASK GENMASK(11, 11)
#define GEN_QMB_1_MULTI_INORDER_WR_DIS_FMASK GENMASK(12, 12)
#define GEN_QMB_0_SNOC_CNOC_LOOP_PROT_DIS_FMASK GENMASK(13, 13)
#define GSI_SNOC_CNOC_LOOP_PROT_DISABLE_FMASK GENMASK(14, 14)
#define GSI_MULTI_AXI_MASTERS_DIS_FMASK GENMASK(15, 15)
#define IPA_QMB_SELECT_GLOBAL_EN_FMASK GENMASK(16, 16)
/* The next five fields are present for IPA v4.9+ */
#define QMB_RAM_RD_CACHE_DISABLE_FMASK GENMASK(19, 19)
#define GENQMB_AOOOWR_FMASK GENMASK(20, 20)
#define IF_OUT_OF_BUF_STOP_RESET_MASK_EN_FMASK GENMASK(21, 21)
#define GEN_QMB_1_DYNAMIC_ASIZE_FMASK GENMASK(30, 30)
#define GEN_QMB_0_DYNAMIC_ASIZE_FMASK GENMASK(31, 31)
/* Encoded value for COMP_CFG register ATOMIC_FETCHER_ARB_LOCK_DIS field */
static inline u32 arbitration_lock_disable_encoded(enum ipa_version version,
u32 mask)
{
WARN_ON(version < IPA_VERSION_4_0);
if (version < IPA_VERSION_4_9)
return u32_encode_bits(mask, GENMASK(20, 17));
/* enum ipa_reg_id - IPA register IDs */
enum ipa_reg_id {
COMP_CFG,
CLKON_CFG,
ROUTE,
SHARED_MEM_SIZE,
QSB_MAX_WRITES,
QSB_MAX_READS,
FILT_ROUT_HASH_EN,
FILT_ROUT_HASH_FLUSH,
STATE_AGGR_ACTIVE,
IPA_BCR, /* Not IPA v4.5+ */
LOCAL_PKT_PROC_CNTXT,
AGGR_FORCE_CLOSE,
COUNTER_CFG, /* Not IPA v4.5+ */
IPA_TX_CFG, /* IPA v3.5+ */
FLAVOR_0, /* IPA v3.5+ */
IDLE_INDICATION_CFG, /* IPA v3.5+ */
QTIME_TIMESTAMP_CFG, /* IPA v4.5+ */
TIMERS_XO_CLK_DIV_CFG, /* IPA v4.5+ */
TIMERS_PULSE_GRAN_CFG, /* IPA v4.5+ */
SRC_RSRC_GRP_01_RSRC_TYPE,
SRC_RSRC_GRP_23_RSRC_TYPE,
SRC_RSRC_GRP_45_RSRC_TYPE, /* Not IPA v3.5+, IPA v4.5 */
SRC_RSRC_GRP_67_RSRC_TYPE, /* Not IPA v3.5+ */
DST_RSRC_GRP_01_RSRC_TYPE,
DST_RSRC_GRP_23_RSRC_TYPE,
DST_RSRC_GRP_45_RSRC_TYPE, /* Not IPA v3.5+, IPA v4.5 */
DST_RSRC_GRP_67_RSRC_TYPE, /* Not IPA v3.5+ */
ENDP_INIT_CTRL, /* Not IPA v4.2+ for TX, not IPA v4.0+ for RX */
ENDP_INIT_CFG,
ENDP_INIT_NAT, /* TX only */
ENDP_INIT_HDR,
ENDP_INIT_HDR_EXT,
ENDP_INIT_HDR_METADATA_MASK, /* RX only */
ENDP_INIT_MODE, /* TX only */
ENDP_INIT_AGGR,
ENDP_INIT_HOL_BLOCK_EN, /* RX only */
ENDP_INIT_HOL_BLOCK_TIMER, /* RX only */
ENDP_INIT_DEAGGR, /* TX only */
ENDP_INIT_RSRC_GRP,
ENDP_INIT_SEQ, /* TX only */
ENDP_STATUS,
ENDP_FILTER_ROUTER_HSH_CFG, /* Not IPA v4.2 */
/* The IRQ registers are only used for GSI_EE_AP */
IPA_IRQ_STTS,
IPA_IRQ_EN,
IPA_IRQ_CLR,
IPA_IRQ_UC,
IRQ_SUSPEND_INFO,
IRQ_SUSPEND_EN, /* IPA v3.1+ */
IRQ_SUSPEND_CLR, /* IPA v3.1+ */
IPA_REG_ID_COUNT, /* Last; not an ID */
};
if (version == IPA_VERSION_4_9)
return u32_encode_bits(mask, GENMASK(24, 22));
/**
* struct ipa_reg - An IPA register descriptor
* @offset: Register offset relative to base of the "ipa-reg" memory
* @stride: Distance between two instances, if parameterized
* @fcount: Number of entries in the @fmask array
* @fmask: Array of mask values defining position and width of fields
* @name: Upper-case name of the IPA register
*/
struct ipa_reg {
u32 offset;
u32 stride;
u32 fcount;
const u32 *fmask; /* BIT(nr) or GENMASK(h, l) */
const char *name;
};
return u32_encode_bits(mask, GENMASK(23, 22));
}
/* Helper macro for defining "simple" (non-parameterized) registers */
#define IPA_REG(__NAME, __reg_id, __offset) \
IPA_REG_STRIDE(__NAME, __reg_id, __offset, 0)
/* Encoded value for COMP_CFG register FULL_FLUSH_WAIT_RS_CLOSURE_EN field */
static inline u32 full_flush_rsc_closure_en_encoded(enum ipa_version version,
bool enable)
{
u32 val = enable ? 1 : 0;
/* Helper macro for defining parameterized registers, specifying stride */
#define IPA_REG_STRIDE(__NAME, __reg_id, __offset, __stride) \
static const struct ipa_reg ipa_reg_ ## __reg_id = { \
.name = #__NAME, \
.offset = __offset, \
.stride = __stride, \
}
WARN_ON(version < IPA_VERSION_4_5);
#define IPA_REG_FIELDS(__NAME, __name, __offset) \
IPA_REG_STRIDE_FIELDS(__NAME, __name, __offset, 0)
if (version == IPA_VERSION_4_5 || version == IPA_VERSION_4_7)
return u32_encode_bits(val, GENMASK(21, 21));
#define IPA_REG_STRIDE_FIELDS(__NAME, __name, __offset, __stride) \
static const struct ipa_reg ipa_reg_ ## __name = { \
.name = #__NAME, \
.offset = __offset, \
.stride = __stride, \
.fcount = ARRAY_SIZE(ipa_reg_ ## __name ## _fmask), \
.fmask = ipa_reg_ ## __name ## _fmask, \
}
return u32_encode_bits(val, GENMASK(17, 17));
}
/**
* struct ipa_regs - Description of registers supported by hardware
* @reg_count: Number of registers in the @reg[] array
* @reg: Array of register descriptors
*/
struct ipa_regs {
u32 reg_count;
const struct ipa_reg **reg;
};
#define IPA_REG_CLKON_CFG_OFFSET 0x00000044
#define RX_FMASK GENMASK(0, 0)
#define PROC_FMASK GENMASK(1, 1)
#define TX_WRAPPER_FMASK GENMASK(2, 2)
#define MISC_FMASK GENMASK(3, 3)
#define RAM_ARB_FMASK GENMASK(4, 4)
#define FTCH_HPS_FMASK GENMASK(5, 5)
#define FTCH_DPS_FMASK GENMASK(6, 6)
#define HPS_FMASK GENMASK(7, 7)
#define DPS_FMASK GENMASK(8, 8)
#define RX_HPS_CMDQS_FMASK GENMASK(9, 9)
#define HPS_DPS_CMDQS_FMASK GENMASK(10, 10)
#define DPS_TX_CMDQS_FMASK GENMASK(11, 11)
#define RSRC_MNGR_FMASK GENMASK(12, 12)
#define CTX_HANDLER_FMASK GENMASK(13, 13)
#define ACK_MNGR_FMASK GENMASK(14, 14)
#define D_DCPH_FMASK GENMASK(15, 15)
#define H_DCPH_FMASK GENMASK(16, 16)
/* The next field is not present for IPA v4.5+ */
#define DCMP_FMASK GENMASK(17, 17)
/* The next three fields are present for IPA v3.5+ */
#define NTF_TX_CMDQS_FMASK GENMASK(18, 18)
#define TX_0_FMASK GENMASK(19, 19)
#define TX_1_FMASK GENMASK(20, 20)
/* The next field is present for IPA v3.5.1+ */
#define FNR_FMASK GENMASK(21, 21)
/* The next eight fields are present for IPA v4.0+ */
#define QSB2AXI_CMDQ_L_FMASK GENMASK(22, 22)
#define AGGR_WRAPPER_FMASK GENMASK(23, 23)
#define RAM_SLAVEWAY_FMASK GENMASK(24, 24)
#define QMB_FMASK GENMASK(25, 25)
#define WEIGHT_ARB_FMASK GENMASK(26, 26)
#define GSI_IF_FMASK GENMASK(27, 27)
#define GLOBAL_FMASK GENMASK(28, 28)
#define GLOBAL_2X_CLK_FMASK GENMASK(29, 29)
/* The next field is present for IPA v4.5+ */
#define DPL_FIFO_FMASK GENMASK(30, 30)
/* The next field is present for IPA v4.7+ */
#define DRBIP_FMASK GENMASK(31, 31)
#define IPA_REG_ROUTE_OFFSET 0x00000048
#define ROUTE_DIS_FMASK GENMASK(0, 0)
#define ROUTE_DEF_PIPE_FMASK GENMASK(5, 1)
#define ROUTE_DEF_HDR_TABLE_FMASK GENMASK(6, 6)
#define ROUTE_DEF_HDR_OFST_FMASK GENMASK(16, 7)
#define ROUTE_FRAG_DEF_PIPE_FMASK GENMASK(21, 17)
#define ROUTE_DEF_RETAIN_HDR_FMASK GENMASK(24, 24)
#define IPA_REG_SHARED_MEM_SIZE_OFFSET 0x00000054
#define SHARED_MEM_SIZE_FMASK GENMASK(15, 0)
#define SHARED_MEM_BADDR_FMASK GENMASK(31, 16)
#define IPA_REG_QSB_MAX_WRITES_OFFSET 0x00000074
#define GEN_QMB_0_MAX_WRITES_FMASK GENMASK(3, 0)
#define GEN_QMB_1_MAX_WRITES_FMASK GENMASK(7, 4)
#define IPA_REG_QSB_MAX_READS_OFFSET 0x00000078
#define GEN_QMB_0_MAX_READS_FMASK GENMASK(3, 0)
#define GEN_QMB_1_MAX_READS_FMASK GENMASK(7, 4)
/* The next two fields are present for IPA v4.0+ */
#define GEN_QMB_0_MAX_READS_BEATS_FMASK GENMASK(23, 16)
#define GEN_QMB_1_MAX_READS_BEATS_FMASK GENMASK(31, 24)
static inline u32 ipa_reg_filt_rout_hash_en_offset(enum ipa_version version)
{
if (version < IPA_VERSION_4_0)
return 0x000008c;
/* COMP_CFG register */
enum ipa_reg_comp_cfg_field_id {
COMP_CFG_ENABLE, /* Not IPA v4.0+ */
RAM_ARB_PRI_CLIENT_SAMP_FIX_DIS, /* IPA v4.7+ */
GSI_SNOC_BYPASS_DIS,
GEN_QMB_0_SNOC_BYPASS_DIS,
GEN_QMB_1_SNOC_BYPASS_DIS,
IPA_DCMP_FAST_CLK_EN, /* Not IPA v4.5+ */
IPA_QMB_SELECT_CONS_EN, /* IPA v4.0+ */
IPA_QMB_SELECT_PROD_EN, /* IPA v4.0+ */
GSI_MULTI_INORDER_RD_DIS, /* IPA v4.0+ */
GSI_MULTI_INORDER_WR_DIS, /* IPA v4.0+ */
GEN_QMB_0_MULTI_INORDER_RD_DIS, /* IPA v4.0+ */
GEN_QMB_1_MULTI_INORDER_RD_DIS, /* IPA v4.0+ */
GEN_QMB_0_MULTI_INORDER_WR_DIS, /* IPA v4.0+ */
GEN_QMB_1_MULTI_INORDER_WR_DIS, /* IPA v4.0+ */
GEN_QMB_0_SNOC_CNOC_LOOP_PROT_DIS, /* IPA v4.0+ */
GSI_SNOC_CNOC_LOOP_PROT_DISABLE, /* IPA v4.0+ */
GSI_MULTI_AXI_MASTERS_DIS, /* IPA v4.0+ */
IPA_QMB_SELECT_GLOBAL_EN, /* IPA v4.0+ */
QMB_RAM_RD_CACHE_DISABLE, /* IPA v4.9+ */
GENQMB_AOOOWR, /* IPA v4.9+ */
IF_OUT_OF_BUF_STOP_RESET_MASK_EN, /* IPA v4.9+ */
GEN_QMB_1_DYNAMIC_ASIZE, /* IPA v4.9+ */
GEN_QMB_0_DYNAMIC_ASIZE, /* IPA v4.9+ */
ATOMIC_FETCHER_ARB_LOCK_DIS, /* IPA v4.0+ */
FULL_FLUSH_WAIT_RS_CLOSURE_EN, /* IPA v4.5+ */
};
return 0x0000148;
}
/* CLKON_CFG register */
enum ipa_reg_clkon_cfg_field_id {
CLKON_RX,
CLKON_PROC,
TX_WRAPPER,
CLKON_MISC,
RAM_ARB,
FTCH_HPS,
FTCH_DPS,
CLKON_HPS,
CLKON_DPS,
RX_HPS_CMDQS,
HPS_DPS_CMDQS,
DPS_TX_CMDQS,
RSRC_MNGR,
CTX_HANDLER,
ACK_MNGR,
D_DCPH,
H_DCPH,
CLKON_DCMP, /* IPA v4.5+ */
NTF_TX_CMDQS, /* IPA v3.5+ */
CLKON_TX_0, /* IPA v3.5+ */
CLKON_TX_1, /* IPA v3.5+ */
CLKON_FNR, /* IPA v3.5.1+ */
QSB2AXI_CMDQ_L, /* IPA v4.0+ */
AGGR_WRAPPER, /* IPA v4.0+ */
RAM_SLAVEWAY, /* IPA v4.0+ */
CLKON_QMB, /* IPA v4.0+ */
WEIGHT_ARB, /* IPA v4.0+ */
GSI_IF, /* IPA v4.0+ */
CLKON_GLOBAL, /* IPA v4.0+ */
GLOBAL_2X_CLK, /* IPA v4.0+ */
DPL_FIFO, /* IPA v4.5+ */
DRBIP, /* IPA v4.7+ */
};
static inline u32 ipa_reg_filt_rout_hash_flush_offset(enum ipa_version version)
{
if (version < IPA_VERSION_4_0)
return 0x0000090;
/* ROUTE register */
enum ipa_reg_route_field_id {
ROUTE_DIS,
ROUTE_DEF_PIPE,
ROUTE_DEF_HDR_TABLE,
ROUTE_DEF_HDR_OFST,
ROUTE_FRAG_DEF_PIPE,
ROUTE_DEF_RETAIN_HDR,
};
return 0x000014c;
}
/* SHARED_MEM_SIZE register */
enum ipa_reg_shared_mem_size_field_id {
MEM_SIZE,
MEM_BADDR,
};
/* The next four fields are used for the hash enable and flush registers */
#define IPV6_ROUTER_HASH_FMASK GENMASK(0, 0)
#define IPV6_FILTER_HASH_FMASK GENMASK(4, 4)
#define IPV4_ROUTER_HASH_FMASK GENMASK(8, 8)
#define IPV4_FILTER_HASH_FMASK GENMASK(12, 12)
/* QSB_MAX_WRITES register */
enum ipa_reg_qsb_max_writes_field_id {
GEN_QMB_0_MAX_WRITES,
GEN_QMB_1_MAX_WRITES,
};
/* ipa->available defines the valid bits in the STATE_AGGR_ACTIVE register */
static inline u32 ipa_reg_state_aggr_active_offset(enum ipa_version version)
{
if (version < IPA_VERSION_4_0)
return 0x0000010c;
/* QSB_MAX_READS register */
enum ipa_reg_qsb_max_reads_field_id {
GEN_QMB_0_MAX_READS,
GEN_QMB_1_MAX_READS,
GEN_QMB_0_MAX_READS_BEATS, /* IPA v4.0+ */
GEN_QMB_1_MAX_READS_BEATS, /* IPA v4.0+ */
};
return 0x000000b4;
}
/* FILT_ROUT_HASH_EN and FILT_ROUT_HASH_FLUSH registers */
enum ipa_reg_rout_hash_field_id {
IPV6_ROUTER_HASH,
IPV6_FILTER_HASH,
IPV4_ROUTER_HASH,
IPV4_FILTER_HASH,
};
/* The next register is not present for IPA v4.5+ */
#define IPA_REG_BCR_OFFSET 0x000001d0
/* BCR register */
enum ipa_bcr_compat {
BCR_CMDQ_L_LACK_ONE_ENTRY = 0x0, /* Not IPA v4.2+ */
BCR_TX_NOT_USING_BRESP = 0x1, /* Not IPA v4.2+ */
......@@ -233,85 +288,69 @@ enum ipa_bcr_compat {
BCR_ROUTER_PREFETCH_EN = 0x9, /* IPA v3.5+ */
};
/* The value of the next register must be a multiple of 8 (bottom 3 bits 0) */
#define IPA_REG_LOCAL_PKT_PROC_CNTXT_OFFSET 0x000001e8
/* LOCAL_PKT_PROC_CNTXT register */
enum ipa_reg_local_pkt_proc_cntxt_field_id {
IPA_BASE_ADDR,
};
/* Encoded value for LOCAL_PKT_PROC_CNTXT register BASE_ADDR field */
static inline u32 proc_cntxt_base_addr_encoded(enum ipa_version version,
u32 addr)
{
if (version < IPA_VERSION_4_5)
return u32_encode_bits(addr, GENMASK(16, 0));
/* COUNTER_CFG register */
enum ipa_reg_counter_cfg_field_id {
EOT_COAL_GRANULARITY, /* Not v3.5+ */
AGGR_GRANULARITY,
};
return u32_encode_bits(addr, GENMASK(17, 0));
}
/* IPA_TX_CFG register */
enum ipa_reg_ipa_tx_cfg_field_id {
TX0_PREFETCH_DISABLE, /* Not v4.0+ */
TX1_PREFETCH_DISABLE, /* Not v4.0+ */
PREFETCH_ALMOST_EMPTY_SIZE, /* Not v4.0+ */
PREFETCH_ALMOST_EMPTY_SIZE_TX0, /* v4.0+ */
DMAW_SCND_OUTSD_PRED_THRESHOLD, /* v4.0+ */
DMAW_SCND_OUTSD_PRED_EN, /* v4.0+ */
DMAW_MAX_BEATS_256_DIS, /* v4.0+ */
PA_MASK_EN, /* v4.0+ */
PREFETCH_ALMOST_EMPTY_SIZE_TX1, /* v4.0+ */
DUAL_TX_ENABLE, /* v4.5+ */
SSPND_PA_NO_START_STATE, /* v4,2+, not v4.5 */
SSPND_PA_NO_BQ_STATE, /* v4.2 only */
};
/* ipa->available defines the valid bits in the AGGR_FORCE_CLOSE register */
#define IPA_REG_AGGR_FORCE_CLOSE_OFFSET 0x000001ec
/* The next register is not present for IPA v4.5+ */
#define IPA_REG_COUNTER_CFG_OFFSET 0x000001f0
/* The next field is not present for IPA v3.5+ */
#define EOT_COAL_GRANULARITY_FMASK GENMASK(3, 0)
#define AGGR_GRANULARITY_FMASK GENMASK(8, 4)
/* The next register is present for IPA v3.5+ */
#define IPA_REG_TX_CFG_OFFSET 0x000001fc
/* The next three fields are not present for IPA v4.0+ */
#define TX0_PREFETCH_DISABLE_FMASK GENMASK(0, 0)
#define TX1_PREFETCH_DISABLE_FMASK GENMASK(1, 1)
#define PREFETCH_ALMOST_EMPTY_SIZE_FMASK GENMASK(4, 2)
/* The next six fields are present for IPA v4.0+ */
#define PREFETCH_ALMOST_EMPTY_SIZE_TX0_FMASK GENMASK(5, 2)
#define DMAW_SCND_OUTSD_PRED_THRESHOLD_FMASK GENMASK(9, 6)
#define DMAW_SCND_OUTSD_PRED_EN_FMASK GENMASK(10, 10)
#define DMAW_MAX_BEATS_256_DIS_FMASK GENMASK(11, 11)
#define PA_MASK_EN_FMASK GENMASK(12, 12)
#define PREFETCH_ALMOST_EMPTY_SIZE_TX1_FMASK GENMASK(16, 13)
/* The next field is present for IPA v4.5+ */
#define DUAL_TX_ENABLE_FMASK GENMASK(17, 17)
/* The next field is present for IPA v4.2+, but not IPA v4.5 */
#define SSPND_PA_NO_START_STATE_FMASK GENMASK(18, 18)
/* The next field is present for IPA v4.2 only */
#define SSPND_PA_NO_BQ_STATE_FMASK GENMASK(19, 19)
/* The next register is present for IPA v3.5+ */
#define IPA_REG_FLAVOR_0_OFFSET 0x00000210
#define IPA_MAX_PIPES_FMASK GENMASK(3, 0)
#define IPA_MAX_CONS_PIPES_FMASK GENMASK(12, 8)
#define IPA_MAX_PROD_PIPES_FMASK GENMASK(20, 16)
#define IPA_PROD_LOWEST_FMASK GENMASK(27, 24)
/* The next register is present for IPA v3.5+ */
static inline u32 ipa_reg_idle_indication_cfg_offset(enum ipa_version version)
{
if (version >= IPA_VERSION_4_2)
return 0x00000240;
/* FLAVOR_0 register */
enum ipa_reg_flavor_0_field_id {
MAX_PIPES,
MAX_CONS_PIPES,
MAX_PROD_PIPES,
PROD_LOWEST,
};
return 0x00000220;
}
/* IDLE_INDICATION_CFG register */
enum ipa_reg_idle_indication_cfg_field_id {
ENTER_IDLE_DEBOUNCE_THRESH,
CONST_NON_IDLE_ENABLE,
};
/* QTIME_TIMESTAMP_CFG register */
enum ipa_reg_qtime_timestamp_cfg_field_id {
DPL_TIMESTAMP_LSB,
DPL_TIMESTAMP_SEL,
TAG_TIMESTAMP_LSB,
NAT_TIMESTAMP_LSB,
};
/* TIMERS_XO_CLK_DIV_CFG register */
enum ipa_reg_timers_xo_clk_div_cfg_field_id {
DIV_VALUE,
DIV_ENABLE,
};
/* TIMERS_PULSE_GRAN_CFG register */
enum ipa_reg_timers_pulse_gran_cfg_field_id {
PULSE_GRAN_0,
PULSE_GRAN_1,
PULSE_GRAN_2,
};
#define ENTER_IDLE_DEBOUNCE_THRESH_FMASK GENMASK(15, 0)
#define CONST_NON_IDLE_ENABLE_FMASK GENMASK(16, 16)
/* The next register is present for IPA v4.5+ */
#define IPA_REG_QTIME_TIMESTAMP_CFG_OFFSET 0x0000024c
#define DPL_TIMESTAMP_LSB_FMASK GENMASK(4, 0)
#define DPL_TIMESTAMP_SEL_FMASK GENMASK(7, 7)
#define TAG_TIMESTAMP_LSB_FMASK GENMASK(12, 8)
#define NAT_TIMESTAMP_LSB_FMASK GENMASK(20, 16)
/* The next register is present for IPA v4.5+ */
#define IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET 0x00000250
#define DIV_VALUE_FMASK GENMASK(8, 0)
#define DIV_ENABLE_FMASK GENMASK(31, 31)
/* The next register is present for IPA v4.5+ */
#define IPA_REG_TIMERS_PULSE_GRAN_CFG_OFFSET 0x00000254
#define GRAN_0_FMASK GENMASK(2, 0)
#define GRAN_1_FMASK GENMASK(5, 3)
#define GRAN_2_FMASK GENMASK(8, 6)
/* Values for GRAN_x fields of TIMERS_PULSE_GRAN_CFG */
/* Values for IPA_GRAN_x fields of TIMERS_PULSE_GRAN_CFG */
enum ipa_pulse_gran {
IPA_GRAN_10_US = 0x0,
IPA_GRAN_20_US = 0x1,
......@@ -323,43 +362,27 @@ enum ipa_pulse_gran {
IPA_GRAN_655350_US = 0x7,
};
/* Not all of the following are present (depends on IPA version) */
#define IPA_REG_SRC_RSRC_GRP_01_RSRC_TYPE_N_OFFSET(rt) \
(0x00000400 + 0x0020 * (rt))
#define IPA_REG_SRC_RSRC_GRP_23_RSRC_TYPE_N_OFFSET(rt) \
(0x00000404 + 0x0020 * (rt))
#define IPA_REG_SRC_RSRC_GRP_45_RSRC_TYPE_N_OFFSET(rt) \
(0x00000408 + 0x0020 * (rt))
#define IPA_REG_SRC_RSRC_GRP_67_RSRC_TYPE_N_OFFSET(rt) \
(0x0000040c + 0x0020 * (rt))
#define IPA_REG_DST_RSRC_GRP_01_RSRC_TYPE_N_OFFSET(rt) \
(0x00000500 + 0x0020 * (rt))
#define IPA_REG_DST_RSRC_GRP_23_RSRC_TYPE_N_OFFSET(rt) \
(0x00000504 + 0x0020 * (rt))
#define IPA_REG_DST_RSRC_GRP_45_RSRC_TYPE_N_OFFSET(rt) \
(0x00000508 + 0x0020 * (rt))
#define IPA_REG_DST_RSRC_GRP_67_RSRC_TYPE_N_OFFSET(rt) \
(0x0000050c + 0x0020 * (rt))
/* The next four fields are used for all resource group registers */
#define X_MIN_LIM_FMASK GENMASK(5, 0)
#define X_MAX_LIM_FMASK GENMASK(13, 8)
/* The next two fields are not always present (if resource count is odd) */
#define Y_MIN_LIM_FMASK GENMASK(21, 16)
#define Y_MAX_LIM_FMASK GENMASK(29, 24)
#define IPA_REG_ENDP_INIT_CTRL_N_OFFSET(ep) \
(0x00000800 + 0x0070 * (ep))
/* Valid only for RX (IPA producer) endpoints (do not use for IPA v4.0+) */
#define ENDP_SUSPEND_FMASK GENMASK(0, 0)
/* Valid only for TX (IPA consumer) endpoints */
#define ENDP_DELAY_FMASK GENMASK(1, 1)
#define IPA_REG_ENDP_INIT_CFG_N_OFFSET(ep) \
(0x00000808 + 0x0070 * (ep))
#define FRAG_OFFLOAD_EN_FMASK GENMASK(0, 0)
#define CS_OFFLOAD_EN_FMASK GENMASK(2, 1)
#define CS_METADATA_HDR_OFFSET_FMASK GENMASK(6, 3)
#define CS_GEN_QMB_MASTER_SEL_FMASK GENMASK(8, 8)
/* {SRC,DST}_RSRC_GRP_{01,23,45,67}_RSRC_TYPE registers */
enum ipa_reg_rsrc_grp_rsrc_type_field_id {
X_MIN_LIM,
X_MAX_LIM,
Y_MIN_LIM,
Y_MAX_LIM,
};
/* ENDP_INIT_CTRL register */
enum ipa_reg_endp_init_ctrl_field_id {
ENDP_SUSPEND, /* Not v4.0+ */
ENDP_DELAY, /* Not v4.2+ */
};
/* ENDP_INIT_CFG register */
enum ipa_reg_endp_init_cfg_field_id {
FRAG_OFFLOAD_EN,
CS_OFFLOAD_EN,
CS_METADATA_HDR_OFFSET,
CS_GEN_QMB_MASTER_SEL,
};
/** enum ipa_cs_offload_en - ENDP_INIT_CFG register CS_OFFLOAD_EN field value */
enum ipa_cs_offload_en {
......@@ -369,10 +392,10 @@ enum ipa_cs_offload_en {
IPA_CS_OFFLOAD_INLINE /* TX and RX */ = 0x1, /* IPA v4.5+ */
};
/* Valid only for TX (IPA consumer) endpoints */
#define IPA_REG_ENDP_INIT_NAT_N_OFFSET(ep) \
(0x0000080c + 0x0070 * (ep))
#define NAT_EN_FMASK GENMASK(1, 0)
/* ENDP_INIT_NAT register */
enum ipa_reg_endp_init_nat_field_id {
NAT_EN,
};
/** enum ipa_nat_en - ENDP_INIT_NAT register NAT_EN field value */
enum ipa_nat_en {
......@@ -381,94 +404,45 @@ enum ipa_nat_en {
IPA_NAT_DST = 0x2,
};
#define IPA_REG_ENDP_INIT_HDR_N_OFFSET(ep) \
(0x00000810 + 0x0070 * (ep))
#define HDR_LEN_FMASK GENMASK(5, 0)
#define HDR_OFST_METADATA_VALID_FMASK GENMASK(6, 6)
#define HDR_OFST_METADATA_FMASK GENMASK(12, 7)
#define HDR_ADDITIONAL_CONST_LEN_FMASK GENMASK(18, 13)
#define HDR_OFST_PKT_SIZE_VALID_FMASK GENMASK(19, 19)
#define HDR_OFST_PKT_SIZE_FMASK GENMASK(25, 20)
/* The next field is not present for IPA v4.9+ */
#define HDR_A5_MUX_FMASK GENMASK(26, 26)
#define HDR_LEN_INC_DEAGG_HDR_FMASK GENMASK(27, 27)
/* The next field is not present for IPA v4.5+ */
#define HDR_METADATA_REG_VALID_FMASK GENMASK(28, 28)
/* The next two fields are present for IPA v4.5+ */
#define HDR_LEN_MSB_FMASK GENMASK(29, 28)
#define HDR_OFST_METADATA_MSB_FMASK GENMASK(31, 30)
/* Encoded value for ENDP_INIT_HDR register HDR_LEN* field(s) */
static inline u32 ipa_header_size_encoded(enum ipa_version version,
u32 header_size)
{
u32 size = header_size & field_mask(HDR_LEN_FMASK);
u32 val;
val = u32_encode_bits(size, HDR_LEN_FMASK);
if (version < IPA_VERSION_4_5) {
WARN_ON(header_size != size);
return val;
}
/* IPA v4.5 adds a few more most-significant bits */
size = header_size >> hweight32(HDR_LEN_FMASK);
val |= u32_encode_bits(size, HDR_LEN_MSB_FMASK);
return val;
}
/* Encoded value for ENDP_INIT_HDR register OFST_METADATA* field(s) */
static inline u32 ipa_metadata_offset_encoded(enum ipa_version version,
u32 offset)
{
u32 off = offset & field_mask(HDR_OFST_METADATA_FMASK);
u32 val;
val = u32_encode_bits(off, HDR_OFST_METADATA_FMASK);
if (version < IPA_VERSION_4_5) {
WARN_ON(offset != off);
return val;
}
/* IPA v4.5 adds a few more most-significant bits */
off = offset >> hweight32(HDR_OFST_METADATA_FMASK);
val |= u32_encode_bits(off, HDR_OFST_METADATA_MSB_FMASK);
/* ENDP_INIT_HDR register */
enum ipa_reg_endp_init_hdr_field_id {
HDR_LEN,
HDR_OFST_METADATA_VALID,
HDR_OFST_METADATA,
HDR_ADDITIONAL_CONST_LEN,
HDR_OFST_PKT_SIZE_VALID,
HDR_OFST_PKT_SIZE,
HDR_A5_MUX, /* Not v4.9+ */
HDR_LEN_INC_DEAGG_HDR,
HDR_METADATA_REG_VALID, /* Not v4.5+ */
HDR_LEN_MSB, /* v4.5+ */
HDR_OFST_METADATA_MSB, /* v4.5+ */
};
return val;
}
/* ENDP_INIT_HDR_EXT register */
enum ipa_reg_endp_init_hdr_ext_field_id {
HDR_ENDIANNESS,
HDR_TOTAL_LEN_OR_PAD_VALID,
HDR_TOTAL_LEN_OR_PAD,
HDR_PAYLOAD_LEN_INC_PADDING,
HDR_TOTAL_LEN_OR_PAD_OFFSET,
HDR_PAD_TO_ALIGNMENT,
HDR_TOTAL_LEN_OR_PAD_OFFSET_MSB, /* v4.5+ */
HDR_OFST_PKT_SIZE_MSB, /* v4.5+ */
HDR_ADDITIONAL_CONST_LEN_MSB, /* v4.5+ */
};
#define IPA_REG_ENDP_INIT_HDR_EXT_N_OFFSET(ep) \
(0x00000814 + 0x0070 * (ep))
#define HDR_ENDIANNESS_FMASK GENMASK(0, 0)
#define HDR_TOTAL_LEN_OR_PAD_VALID_FMASK GENMASK(1, 1)
#define HDR_TOTAL_LEN_OR_PAD_FMASK GENMASK(2, 2)
#define HDR_PAYLOAD_LEN_INC_PADDING_FMASK GENMASK(3, 3)
#define HDR_TOTAL_LEN_OR_PAD_OFFSET_FMASK GENMASK(9, 4)
#define HDR_PAD_TO_ALIGNMENT_FMASK GENMASK(13, 10)
/* The next three fields are present for IPA v4.5+ */
#define HDR_TOTAL_LEN_OR_PAD_OFFSET_MSB_FMASK GENMASK(17, 16)
#define HDR_OFST_PKT_SIZE_MSB_FMASK GENMASK(19, 18)
#define HDR_ADDITIONAL_CONST_LEN_MSB_FMASK GENMASK(21, 20)
/* Valid only for RX (IPA producer) endpoints */
#define IPA_REG_ENDP_INIT_HDR_METADATA_MASK_N_OFFSET(rxep) \
(0x00000818 + 0x0070 * (rxep))
/* Valid only for TX (IPA consumer) endpoints */
#define IPA_REG_ENDP_INIT_MODE_N_OFFSET(txep) \
(0x00000820 + 0x0070 * (txep))
#define MODE_FMASK GENMASK(2, 0)
/* The next field is present for IPA v4.5+ */
#define DCPH_ENABLE_FMASK GENMASK(3, 3)
#define DEST_PIPE_INDEX_FMASK GENMASK(8, 4)
#define BYTE_THRESHOLD_FMASK GENMASK(27, 12)
#define PIPE_REPLICATION_EN_FMASK GENMASK(28, 28)
#define PAD_EN_FMASK GENMASK(29, 29)
/* The next field is not present for IPA v4.5+ */
#define HDR_FTCH_DISABLE_FMASK GENMASK(30, 30)
/* The next field is present for IPA v4.9+ */
#define DRBIP_ACL_ENABLE_FMASK GENMASK(30, 30)
/* ENDP_INIT_MODE register */
enum ipa_reg_endp_init_mode_field_id {
ENDP_MODE,
DCPH_ENABLE, /* v4.5+ */
DEST_PIPE_INDEX,
BYTE_THRESHOLD,
PIPE_REPLICATION_EN,
PAD_EN,
HDR_FTCH_DISABLE, /* v4.5+ */
DRBIP_ACL_ENABLE, /* v4.9+ */
};
/** enum ipa_mode - ENDP_INIT_MODE register MODE field value */
enum ipa_mode {
......@@ -478,49 +452,18 @@ enum ipa_mode {
IPA_DMA = 0x3,
};
#define IPA_REG_ENDP_INIT_AGGR_N_OFFSET(ep) \
(0x00000824 + 0x0070 * (ep))
#define AGGR_EN_FMASK GENMASK(1, 0)
#define AGGR_TYPE_FMASK GENMASK(4, 2)
/* The legacy value is used for IPA hardware before IPA v4.5 */
static inline u32 aggr_byte_limit_fmask(bool legacy)
{
return legacy ? GENMASK(9, 5) : GENMASK(10, 5);
}
/* The legacy value is used for IPA hardware before IPA v4.5 */
static inline u32 aggr_time_limit_fmask(bool legacy)
{
return legacy ? GENMASK(14, 10) : GENMASK(16, 12);
}
/* The legacy value is used for IPA hardware before IPA v4.5 */
static inline u32 aggr_pkt_limit_fmask(bool legacy)
{
return legacy ? GENMASK(20, 15) : GENMASK(22, 17);
}
/* The legacy value is used for IPA hardware before IPA v4.5 */
static inline u32 aggr_sw_eof_active_fmask(bool legacy)
{
return legacy ? GENMASK(21, 21) : GENMASK(23, 23);
}
/* The legacy value is used for IPA hardware before IPA v4.5 */
static inline u32 aggr_force_close_fmask(bool legacy)
{
return legacy ? GENMASK(22, 22) : GENMASK(24, 24);
}
/* The legacy value is used for IPA hardware before IPA v4.5 */
static inline u32 aggr_hard_byte_limit_enable_fmask(bool legacy)
{
return legacy ? GENMASK(24, 24) : GENMASK(26, 26);
}
/* The next field is present for IPA v4.5+ */
#define AGGR_GRAN_SEL_FMASK GENMASK(27, 27)
/* ENDP_INIT_AGGR register */
enum ipa_reg_endp_init_aggr_field_id {
AGGR_EN,
AGGR_TYPE,
BYTE_LIMIT,
TIME_LIMIT,
PKT_LIMIT,
SW_EOF_ACTIVE,
FORCE_CLOSE,
HARD_BYTE_LIMIT_EN,
AGGR_GRAN_SEL,
};
/** enum ipa_aggr_en - ENDP_INIT_AGGR register AGGR_EN field value */
enum ipa_aggr_en {
......@@ -540,51 +483,39 @@ enum ipa_aggr_type {
IPA_QCMAP = 0x6,
};
/* Valid only for RX (IPA producer) endpoints */
#define IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(rxep) \
(0x0000082c + 0x0070 * (rxep))
#define HOL_BLOCK_EN_FMASK GENMASK(0, 0)
/* Valid only for RX (IPA producer) endpoints */
#define IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(rxep) \
(0x00000830 + 0x0070 * (rxep))
/* The next two fields are present for IPA v4.2 only */
#define BASE_VALUE_FMASK GENMASK(4, 0)
#define SCALE_FMASK GENMASK(12, 8)
/* The next two fields are present for IPA v4.5 */
#define TIME_LIMIT_FMASK GENMASK(4, 0)
#define GRAN_SEL_FMASK GENMASK(8, 8)
/* Valid only for TX (IPA consumer) endpoints */
#define IPA_REG_ENDP_INIT_DEAGGR_N_OFFSET(txep) \
(0x00000834 + 0x0070 * (txep))
#define DEAGGR_HDR_LEN_FMASK GENMASK(5, 0)
#define SYSPIPE_ERR_DETECTION_FMASK GENMASK(6, 6)
#define PACKET_OFFSET_VALID_FMASK GENMASK(7, 7)
#define PACKET_OFFSET_LOCATION_FMASK GENMASK(13, 8)
#define IGNORE_MIN_PKT_ERR_FMASK GENMASK(14, 14)
#define MAX_PACKET_LEN_FMASK GENMASK(31, 16)
#define IPA_REG_ENDP_INIT_RSRC_GRP_N_OFFSET(ep) \
(0x00000838 + 0x0070 * (ep))
/* Encoded value for ENDP_INIT_RSRC_GRP register RSRC_GRP field */
static inline u32 rsrc_grp_encoded(enum ipa_version version, u32 rsrc_grp)
{
if (version < IPA_VERSION_3_5 || version == IPA_VERSION_4_5)
return u32_encode_bits(rsrc_grp, GENMASK(2, 0));
/* ENDP_INIT_HOL_BLOCK_EN register */
enum ipa_reg_endp_init_hol_block_en_field_id {
HOL_BLOCK_EN,
};
if (version == IPA_VERSION_4_2 || version == IPA_VERSION_4_7)
return u32_encode_bits(rsrc_grp, GENMASK(0, 0));
/* ENDP_INIT_HOL_BLOCK_TIMER register */
enum ipa_reg_endp_init_hol_block_timer_field_id {
TIMER_BASE_VALUE, /* Not v4.5+ */
TIMER_SCALE, /* v4.2 only */
TIMER_LIMIT, /* v4.5+ */
TIMER_GRAN_SEL, /* v4.5+ */
};
return u32_encode_bits(rsrc_grp, GENMASK(1, 0));
}
/* ENDP_INIT_DEAGGR register */
enum ipa_reg_endp_deaggr_field_id {
DEAGGR_HDR_LEN,
SYSPIPE_ERR_DETECTION,
PACKET_OFFSET_VALID,
PACKET_OFFSET_LOCATION,
IGNORE_MIN_PKT_ERR,
MAX_PACKET_LEN,
};
/* Valid only for TX (IPA consumer) endpoints */
#define IPA_REG_ENDP_INIT_SEQ_N_OFFSET(txep) \
(0x0000083c + 0x0070 * (txep))
#define SEQ_TYPE_FMASK GENMASK(7, 0)
/* The next field must be zero for IPA v4.5+ */
#define SEQ_REP_TYPE_FMASK GENMASK(15, 8)
/* ENDP_INIT_RSRC_GRP register */
enum ipa_reg_endp_init_rsrc_grp_field_id {
ENDP_RSRC_GRP,
};
/* ENDP_INIT_SEQ register */
enum ipa_reg_endp_init_seq_field_id {
SEQ_TYPE,
SEQ_REP_TYPE, /* Not v4.5+ */
};
/**
* enum ipa_seq_type - HPS and DPS sequencer type
......@@ -628,76 +559,36 @@ enum ipa_seq_rep_type {
IPA_SEQ_REP_DMA_PARSER = 0x08,
};
#define IPA_REG_ENDP_STATUS_N_OFFSET(ep) \
(0x00000840 + 0x0070 * (ep))
#define STATUS_EN_FMASK GENMASK(0, 0)
#define STATUS_ENDP_FMASK GENMASK(5, 1)
/* The next field is not present for IPA v4.5+ */
#define STATUS_LOCATION_FMASK GENMASK(8, 8)
/* The next field is present for IPA v4.0+ */
#define STATUS_PKT_SUPPRESS_FMASK GENMASK(9, 9)
/* The next register is not present for IPA v4.2 (which no hashing support) */
#define IPA_REG_ENDP_FILTER_ROUTER_HSH_CFG_N_OFFSET(er) \
(0x0000085c + 0x0070 * (er))
#define FILTER_HASH_MSK_SRC_ID_FMASK GENMASK(0, 0)
#define FILTER_HASH_MSK_SRC_IP_FMASK GENMASK(1, 1)
#define FILTER_HASH_MSK_DST_IP_FMASK GENMASK(2, 2)
#define FILTER_HASH_MSK_SRC_PORT_FMASK GENMASK(3, 3)
#define FILTER_HASH_MSK_DST_PORT_FMASK GENMASK(4, 4)
#define FILTER_HASH_MSK_PROTOCOL_FMASK GENMASK(5, 5)
#define FILTER_HASH_MSK_METADATA_FMASK GENMASK(6, 6)
#define IPA_REG_ENDP_FILTER_HASH_MSK_ALL GENMASK(6, 0)
#define ROUTER_HASH_MSK_SRC_ID_FMASK GENMASK(16, 16)
#define ROUTER_HASH_MSK_SRC_IP_FMASK GENMASK(17, 17)
#define ROUTER_HASH_MSK_DST_IP_FMASK GENMASK(18, 18)
#define ROUTER_HASH_MSK_SRC_PORT_FMASK GENMASK(19, 19)
#define ROUTER_HASH_MSK_DST_PORT_FMASK GENMASK(20, 20)
#define ROUTER_HASH_MSK_PROTOCOL_FMASK GENMASK(21, 21)
#define ROUTER_HASH_MSK_METADATA_FMASK GENMASK(22, 22)
#define IPA_REG_ENDP_ROUTER_HASH_MSK_ALL GENMASK(22, 16)
static inline u32 ipa_reg_irq_stts_ee_n_offset(enum ipa_version version,
u32 ee)
{
if (version < IPA_VERSION_4_9)
return 0x00003008 + 0x1000 * ee;
return 0x00004008 + 0x1000 * ee;
}
static inline u32 ipa_reg_irq_stts_offset(enum ipa_version version)
{
return ipa_reg_irq_stts_ee_n_offset(version, GSI_EE_AP);
}
static inline u32 ipa_reg_irq_en_ee_n_offset(enum ipa_version version, u32 ee)
{
if (version < IPA_VERSION_4_9)
return 0x0000300c + 0x1000 * ee;
return 0x0000400c + 0x1000 * ee;
}
static inline u32 ipa_reg_irq_en_offset(enum ipa_version version)
{
return ipa_reg_irq_en_ee_n_offset(version, GSI_EE_AP);
}
static inline u32 ipa_reg_irq_clr_ee_n_offset(enum ipa_version version, u32 ee)
{
if (version < IPA_VERSION_4_9)
return 0x00003010 + 0x1000 * ee;
return 0x00004010 + 0x1000 * ee;
}
/* ENDP_STATUS register */
enum ipa_reg_endp_status_field_id {
STATUS_EN,
STATUS_ENDP,
STATUS_LOCATION, /* Not v4.5+ */
STATUS_PKT_SUPPRESS, /* v4.0+ */
};
static inline u32 ipa_reg_irq_clr_offset(enum ipa_version version)
{
return ipa_reg_irq_clr_ee_n_offset(version, GSI_EE_AP);
}
/* ENDP_FILTER_ROUTER_HSH_CFG register */
enum ipa_reg_endp_filter_router_hsh_cfg_field_id {
FILTER_HASH_MSK_SRC_ID,
FILTER_HASH_MSK_SRC_IP,
FILTER_HASH_MSK_DST_IP,
FILTER_HASH_MSK_SRC_PORT,
FILTER_HASH_MSK_DST_PORT,
FILTER_HASH_MSK_PROTOCOL,
FILTER_HASH_MSK_METADATA,
FILTER_HASH_MSK_ALL, /* Bitwise OR of the above 6 fields */
ROUTER_HASH_MSK_SRC_ID,
ROUTER_HASH_MSK_SRC_IP,
ROUTER_HASH_MSK_DST_IP,
ROUTER_HASH_MSK_SRC_PORT,
ROUTER_HASH_MSK_DST_PORT,
ROUTER_HASH_MSK_PROTOCOL,
ROUTER_HASH_MSK_METADATA,
ROUTER_HASH_MSK_ALL, /* Bitwise OR of the above 6 fields */
};
/* IPA_IRQ_STTS, IPA_IRQ_EN, and IPA_IRQ_CLR registers */
/**
* enum ipa_irq_id - Bit positions representing type of IPA IRQ
* @IPA_IRQ_UC_0: Microcontroller event interrupt
......@@ -773,74 +664,82 @@ enum ipa_irq_id {
IPA_IRQ_COUNT, /* Last; not an id */
};
static inline u32 ipa_reg_irq_uc_ee_n_offset(enum ipa_version version, u32 ee)
{
if (version < IPA_VERSION_4_9)
return 0x0000301c + 0x1000 * ee;
/* IPA_IRQ_UC register */
enum ipa_reg_ipa_irq_uc_field_id {
UC_INTR,
};
return 0x0000401c + 0x1000 * ee;
}
extern const struct ipa_regs ipa_regs_v3_1;
extern const struct ipa_regs ipa_regs_v3_5_1;
extern const struct ipa_regs ipa_regs_v4_2;
extern const struct ipa_regs ipa_regs_v4_5;
extern const struct ipa_regs ipa_regs_v4_9;
extern const struct ipa_regs ipa_regs_v4_11;
static inline u32 ipa_reg_irq_uc_offset(enum ipa_version version)
/* Return the field mask for a field in a register */
static inline u32 ipa_reg_fmask(const struct ipa_reg *reg, u32 field_id)
{
return ipa_reg_irq_uc_ee_n_offset(version, GSI_EE_AP);
}
if (!reg || WARN_ON(field_id >= reg->fcount))
return 0;
#define UC_INTR_FMASK GENMASK(0, 0)
return reg->fmask[field_id];
}
/* ipa->available defines the valid bits in the SUSPEND_INFO register */
static inline u32
ipa_reg_irq_suspend_info_ee_n_offset(enum ipa_version version, u32 ee)
/* Return the mask for a single-bit field in a register */
static inline u32 ipa_reg_bit(const struct ipa_reg *reg, u32 field_id)
{
if (version == IPA_VERSION_3_0)
return 0x00003098 + 0x1000 * ee;
u32 fmask = ipa_reg_fmask(reg, field_id);
if (version < IPA_VERSION_4_9)
return 0x00003030 + 0x1000 * ee;
WARN_ON(!is_power_of_2(fmask));
return 0x00004030 + 0x1000 * ee;
return fmask;
}
/* Encode a value into the given field of a register */
static inline u32
ipa_reg_irq_suspend_info_offset(enum ipa_version version)
ipa_reg_encode(const struct ipa_reg *reg, u32 field_id, u32 val)
{
return ipa_reg_irq_suspend_info_ee_n_offset(version, GSI_EE_AP);
}
u32 fmask = ipa_reg_fmask(reg, field_id);
/* ipa->available defines the valid bits in the SUSPEND_EN register */
static inline u32
ipa_reg_irq_suspend_en_ee_n_offset(enum ipa_version version, u32 ee)
{
WARN_ON(version == IPA_VERSION_3_0);
if (!fmask)
return 0;
if (version < IPA_VERSION_4_9)
return 0x00003034 + 0x1000 * ee;
val <<= __ffs(fmask);
if (WARN_ON(val & ~fmask))
return 0;
return 0x00004034 + 0x1000 * ee;
return val;
}
/* Given a register value, decode (extract) the value in the given field */
static inline u32
ipa_reg_irq_suspend_en_offset(enum ipa_version version)
ipa_reg_decode(const struct ipa_reg *reg, u32 field_id, u32 val)
{
return ipa_reg_irq_suspend_en_ee_n_offset(version, GSI_EE_AP);
u32 fmask = ipa_reg_fmask(reg, field_id);
return fmask ? (val & fmask) >> __ffs(fmask) : 0;
}
/* ipa->available defines the valid bits in the SUSPEND_CLR register */
static inline u32
ipa_reg_irq_suspend_clr_ee_n_offset(enum ipa_version version, u32 ee)
/* Return the maximum value representable by the given field; always 2^n - 1 */
static inline u32 ipa_reg_field_max(const struct ipa_reg *reg, u32 field_id)
{
WARN_ON(version == IPA_VERSION_3_0);
u32 fmask = ipa_reg_fmask(reg, field_id);
if (version < IPA_VERSION_4_9)
return 0x00003038 + 0x1000 * ee;
return fmask ? fmask >> __ffs(fmask) : 0;
}
const struct ipa_reg *ipa_reg(struct ipa *ipa, enum ipa_reg_id reg_id);
return 0x00004038 + 0x1000 * ee;
/* Returns 0 for NULL reg; warning will have already been issued */
static inline u32 ipa_reg_offset(const struct ipa_reg *reg)
{
return reg ? reg->offset : 0;
}
static inline u32
ipa_reg_irq_suspend_clr_offset(enum ipa_version version)
/* Returns 0 for NULL reg; warning will have already been issued */
static inline u32 ipa_reg_n_offset(const struct ipa_reg *reg, u32 n)
{
return ipa_reg_irq_suspend_clr_ee_n_offset(version, GSI_EE_AP);
return reg ? reg->offset + n * reg->stride : 0;
}
int ipa_reg_init(struct ipa *ipa);
......
......@@ -69,20 +69,21 @@ static bool ipa_resource_limits_valid(struct ipa *ipa,
}
static void
ipa_resource_config_common(struct ipa *ipa, u32 offset,
ipa_resource_config_common(struct ipa *ipa, u32 resource_type,
const struct ipa_reg *reg,
const struct ipa_resource_limits *xlimits,
const struct ipa_resource_limits *ylimits)
{
u32 val;
val = u32_encode_bits(xlimits->min, X_MIN_LIM_FMASK);
val |= u32_encode_bits(xlimits->max, X_MAX_LIM_FMASK);
val = ipa_reg_encode(reg, X_MIN_LIM, xlimits->min);
val |= ipa_reg_encode(reg, X_MAX_LIM, xlimits->max);
if (ylimits) {
val |= u32_encode_bits(ylimits->min, Y_MIN_LIM_FMASK);
val |= u32_encode_bits(ylimits->max, Y_MAX_LIM_FMASK);
val |= ipa_reg_encode(reg, Y_MIN_LIM, ylimits->min);
val |= ipa_reg_encode(reg, Y_MAX_LIM, ylimits->max);
}
iowrite32(val, ipa->reg_virt + offset);
iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, resource_type));
}
static void ipa_resource_config_src(struct ipa *ipa, u32 resource_type,
......@@ -91,34 +92,35 @@ static void ipa_resource_config_src(struct ipa *ipa, u32 resource_type,
u32 group_count = data->rsrc_group_src_count;
const struct ipa_resource_limits *ylimits;
const struct ipa_resource *resource;
u32 offset;
const struct ipa_reg *reg;
resource = &data->resource_src[resource_type];
offset = IPA_REG_SRC_RSRC_GRP_01_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, SRC_RSRC_GRP_01_RSRC_TYPE);
ylimits = group_count == 1 ? NULL : &resource->limits[1];
ipa_resource_config_common(ipa, offset, &resource->limits[0], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[0], ylimits);
if (group_count < 3)
return;
offset = IPA_REG_SRC_RSRC_GRP_23_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, SRC_RSRC_GRP_23_RSRC_TYPE);
ylimits = group_count == 3 ? NULL : &resource->limits[3];
ipa_resource_config_common(ipa, offset, &resource->limits[2], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[2], ylimits);
if (group_count < 5)
return;
offset = IPA_REG_SRC_RSRC_GRP_45_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, SRC_RSRC_GRP_45_RSRC_TYPE);
ylimits = group_count == 5 ? NULL : &resource->limits[5];
ipa_resource_config_common(ipa, offset, &resource->limits[4], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[4], ylimits);
if (group_count < 7)
return;
offset = IPA_REG_SRC_RSRC_GRP_67_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, SRC_RSRC_GRP_67_RSRC_TYPE);
ylimits = group_count == 7 ? NULL : &resource->limits[7];
ipa_resource_config_common(ipa, offset, &resource->limits[6], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[6], ylimits);
}
static void ipa_resource_config_dst(struct ipa *ipa, u32 resource_type,
......@@ -127,34 +129,35 @@ static void ipa_resource_config_dst(struct ipa *ipa, u32 resource_type,
u32 group_count = data->rsrc_group_dst_count;
const struct ipa_resource_limits *ylimits;
const struct ipa_resource *resource;
u32 offset;
const struct ipa_reg *reg;
resource = &data->resource_dst[resource_type];
offset = IPA_REG_DST_RSRC_GRP_01_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, DST_RSRC_GRP_01_RSRC_TYPE);
ylimits = group_count == 1 ? NULL : &resource->limits[1];
ipa_resource_config_common(ipa, offset, &resource->limits[0], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[0], ylimits);
if (group_count < 3)
return;
offset = IPA_REG_DST_RSRC_GRP_23_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, DST_RSRC_GRP_23_RSRC_TYPE);
ylimits = group_count == 3 ? NULL : &resource->limits[3];
ipa_resource_config_common(ipa, offset, &resource->limits[2], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[2], ylimits);
if (group_count < 5)
return;
offset = IPA_REG_DST_RSRC_GRP_45_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, DST_RSRC_GRP_45_RSRC_TYPE);
ylimits = group_count == 5 ? NULL : &resource->limits[5];
ipa_resource_config_common(ipa, offset, &resource->limits[4], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[4], ylimits);
if (group_count < 7)
return;
offset = IPA_REG_DST_RSRC_GRP_67_RSRC_TYPE_N_OFFSET(resource_type);
reg = ipa_reg(ipa, DST_RSRC_GRP_67_RSRC_TYPE);
ylimits = group_count == 7 ? NULL : &resource->limits[7];
ipa_resource_config_common(ipa, offset, &resource->limits[6], ylimits);
ipa_resource_config_common(ipa, resource_type, reg,
&resource->limits[6], ylimits);
}
/* Configure resources; there is no ipa_resource_deconfig() */
......
......@@ -384,8 +384,9 @@ void ipa_table_reset(struct ipa *ipa, bool modem)
int ipa_table_hash_flush(struct ipa *ipa)
{
u32 offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
const struct ipa_reg *reg;
struct gsi_trans *trans;
u32 offset;
u32 val;
if (!ipa_table_hash_support(ipa))
......@@ -397,8 +398,13 @@ int ipa_table_hash_flush(struct ipa *ipa)
return -EBUSY;
}
val = IPV4_FILTER_HASH_FMASK | IPV6_FILTER_HASH_FMASK;
val |= IPV6_ROUTER_HASH_FMASK | IPV4_ROUTER_HASH_FMASK;
reg = ipa_reg(ipa, FILT_ROUT_HASH_FLUSH);
offset = ipa_reg_offset(reg);
val = ipa_reg_bit(reg, IPV6_ROUTER_HASH);
val |= ipa_reg_bit(reg, IPV6_FILTER_HASH);
val |= ipa_reg_bit(reg, IPV4_ROUTER_HASH);
val |= ipa_reg_bit(reg, IPV4_FILTER_HASH);
ipa_cmd_register_write_add(trans, offset, val, val, false);
......@@ -516,15 +522,18 @@ int ipa_table_setup(struct ipa *ipa)
static void ipa_filter_tuple_zero(struct ipa_endpoint *endpoint)
{
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
const struct ipa_reg *reg;
u32 offset;
u32 val;
offset = IPA_REG_ENDP_FILTER_ROUTER_HSH_CFG_N_OFFSET(endpoint_id);
reg = ipa_reg(ipa, ENDP_FILTER_ROUTER_HSH_CFG);
offset = ipa_reg_n_offset(reg, endpoint_id);
val = ioread32(endpoint->ipa->reg_virt + offset);
/* Zero all filter-related fields, preserving the rest */
val &= ~IPA_REG_ENDP_FILTER_HASH_MSK_ALL;
val &= ~ipa_reg_fmask(reg, FILTER_HASH_MSK_ALL);
iowrite32(val, endpoint->ipa->reg_virt + offset);
}
......@@ -565,13 +574,17 @@ static bool ipa_route_id_modem(u32 route_id)
*/
static void ipa_route_tuple_zero(struct ipa *ipa, u32 route_id)
{
u32 offset = IPA_REG_ENDP_FILTER_ROUTER_HSH_CFG_N_OFFSET(route_id);
const struct ipa_reg *reg;
u32 offset;
u32 val;
reg = ipa_reg(ipa, ENDP_FILTER_ROUTER_HSH_CFG);
offset = ipa_reg_n_offset(reg, route_id);
val = ioread32(ipa->reg_virt + offset);
/* Zero all route-related fields, preserving the rest */
val &= ~IPA_REG_ENDP_ROUTER_HASH_MSK_ALL;
val &= ~ipa_reg_fmask(reg, ROUTER_HASH_MSK_ALL);
iowrite32(val, ipa->reg_virt + offset);
}
......
......@@ -222,7 +222,7 @@ void ipa_uc_power(struct ipa *ipa)
static void send_uc_command(struct ipa *ipa, u32 command, u32 command_param)
{
struct ipa_uc_mem_area *shared = ipa_uc_shared(ipa);
u32 offset;
const struct ipa_reg *reg;
u32 val;
/* Fill in the command data */
......@@ -233,9 +233,10 @@ static void send_uc_command(struct ipa *ipa, u32 command, u32 command_param)
shared->response_param = 0;
/* Use an interrupt to tell the microcontroller the command is ready */
val = u32_encode_bits(1, UC_INTR_FMASK);
offset = ipa_reg_irq_uc_offset(ipa->version);
iowrite32(val, ipa->reg_virt + offset);
reg = ipa_reg(ipa, IPA_IRQ_UC);
val = ipa_reg_bit(reg, UC_INTR);
iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));
}
/* Tell the microcontroller the AP is shutting down */
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022 Linaro Ltd. */
#include <linux/types.h>
#include "../ipa.h"
#include "../ipa_reg.h"
static const u32 ipa_reg_comp_cfg_fmask[] = {
[COMP_CFG_ENABLE] = BIT(0),
[GSI_SNOC_BYPASS_DIS] = BIT(1),
[GEN_QMB_0_SNOC_BYPASS_DIS] = BIT(2),
[GEN_QMB_1_SNOC_BYPASS_DIS] = BIT(3),
[IPA_DCMP_FAST_CLK_EN] = BIT(4),
/* Bits 5-31 reserved */
};
IPA_REG_FIELDS(COMP_CFG, comp_cfg, 0x0000003c);
static const u32 ipa_reg_clkon_cfg_fmask[] = {
[CLKON_RX] = BIT(0),
[CLKON_PROC] = BIT(1),
[TX_WRAPPER] = BIT(2),
[CLKON_MISC] = BIT(3),
[RAM_ARB] = BIT(4),
[FTCH_HPS] = BIT(5),
[FTCH_DPS] = BIT(6),
[CLKON_HPS] = BIT(7),
[CLKON_DPS] = BIT(8),
[RX_HPS_CMDQS] = BIT(9),
[HPS_DPS_CMDQS] = BIT(10),
[DPS_TX_CMDQS] = BIT(11),
[RSRC_MNGR] = BIT(12),
[CTX_HANDLER] = BIT(13),
[ACK_MNGR] = BIT(14),
[D_DCPH] = BIT(15),
[H_DCPH] = BIT(16),
/* Bits 17-31 reserved */
};
IPA_REG_FIELDS(CLKON_CFG, clkon_cfg, 0x00000044);
static const u32 ipa_reg_route_fmask[] = {
[ROUTE_DIS] = BIT(0),
[ROUTE_DEF_PIPE] = GENMASK(5, 1),
[ROUTE_DEF_HDR_TABLE] = BIT(6),
[ROUTE_DEF_HDR_OFST] = GENMASK(16, 7),
[ROUTE_FRAG_DEF_PIPE] = GENMASK(21, 17),
/* Bits 22-23 reserved */
[ROUTE_DEF_RETAIN_HDR] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_FIELDS(ROUTE, route, 0x00000048);
static const u32 ipa_reg_shared_mem_size_fmask[] = {
[MEM_SIZE] = GENMASK(15, 0),
[MEM_BADDR] = GENMASK(31, 16),
};
IPA_REG_FIELDS(SHARED_MEM_SIZE, shared_mem_size, 0x00000054);
static const u32 ipa_reg_qsb_max_writes_fmask[] = {
[GEN_QMB_0_MAX_WRITES] = GENMASK(3, 0),
[GEN_QMB_1_MAX_WRITES] = GENMASK(7, 4),
/* Bits 8-31 reserved */
};
IPA_REG_FIELDS(QSB_MAX_WRITES, qsb_max_writes, 0x00000074);
static const u32 ipa_reg_qsb_max_reads_fmask[] = {
[GEN_QMB_0_MAX_READS] = GENMASK(3, 0),
[GEN_QMB_1_MAX_READS] = GENMASK(7, 4),
};
IPA_REG_FIELDS(QSB_MAX_READS, qsb_max_reads, 0x00000078);
static const u32 ipa_reg_filt_rout_hash_en_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_EN, filt_rout_hash_en, 0x000008c);
static const u32 ipa_reg_filt_rout_hash_flush_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_FLUSH, filt_rout_hash_flush, 0x0000090);
/* Valid bits defined by ipa->available */
IPA_REG(STATE_AGGR_ACTIVE, state_aggr_active, 0x0000010c);
IPA_REG(IPA_BCR, ipa_bcr, 0x000001d0);
static const u32 ipa_reg_local_pkt_proc_cntxt_fmask[] = {
[IPA_BASE_ADDR] = GENMASK(16, 0),
/* Bits 17-31 reserved */
};
/* Offset must be a multiple of 8 */
IPA_REG_FIELDS(LOCAL_PKT_PROC_CNTXT, local_pkt_proc_cntxt, 0x000001e8);
/* Valid bits defined by ipa->available */
IPA_REG(AGGR_FORCE_CLOSE, aggr_force_close, 0x000001ec);
static const u32 ipa_reg_counter_cfg_fmask[] = {
[EOT_COAL_GRANULARITY] = GENMASK(3, 0),
[AGGR_GRANULARITY] = GENMASK(8, 4),
/* Bits 5-31 reserved */
};
IPA_REG_FIELDS(COUNTER_CFG, counter_cfg, 0x000001f0);
static const u32 ipa_reg_src_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_01_RSRC_TYPE, src_rsrc_grp_01_rsrc_type,
0x00000400, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_23_RSRC_TYPE, src_rsrc_grp_23_rsrc_type,
0x00000404, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_45_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_45_RSRC_TYPE, src_rsrc_grp_45_rsrc_type,
0x00000408, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_67_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_67_RSRC_TYPE, src_rsrc_grp_67_rsrc_type,
0x0000040c, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_01_RSRC_TYPE, dst_rsrc_grp_01_rsrc_type,
0x00000500, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_23_RSRC_TYPE, dst_rsrc_grp_23_rsrc_type,
0x00000504, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_45_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_45_RSRC_TYPE, dst_rsrc_grp_45_rsrc_type,
0x00000508, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_67_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_67_RSRC_TYPE, dst_rsrc_grp_67_rsrc_type,
0x0000050c, 0x0020);
static const u32 ipa_reg_endp_init_ctrl_fmask[] = {
[ENDP_SUSPEND] = BIT(0),
[ENDP_DELAY] = BIT(1),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CTRL, endp_init_ctrl, 0x00000800, 0x0070);
static const u32 ipa_reg_endp_init_cfg_fmask[] = {
[FRAG_OFFLOAD_EN] = BIT(0),
[CS_OFFLOAD_EN] = GENMASK(2, 1),
[CS_METADATA_HDR_OFFSET] = GENMASK(6, 3),
/* Bit 7 reserved */
[CS_GEN_QMB_MASTER_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CFG, endp_init_cfg, 0x00000808, 0x0070);
static const u32 ipa_reg_endp_init_nat_fmask[] = {
[NAT_EN] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_NAT, endp_init_nat, 0x0000080c, 0x0070);
static const u32 ipa_reg_endp_init_hdr_fmask[] = {
[HDR_LEN] = GENMASK(5, 0),
[HDR_OFST_METADATA_VALID] = BIT(6),
[HDR_OFST_METADATA] = GENMASK(12, 7),
[HDR_ADDITIONAL_CONST_LEN] = GENMASK(18, 13),
[HDR_OFST_PKT_SIZE_VALID] = BIT(19),
[HDR_OFST_PKT_SIZE] = GENMASK(25, 20),
[HDR_A5_MUX] = BIT(26),
[HDR_LEN_INC_DEAGG_HDR] = BIT(27),
[HDR_METADATA_REG_VALID] = BIT(28),
/* Bits 29-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR, endp_init_hdr, 0x00000810, 0x0070);
static const u32 ipa_reg_endp_init_hdr_ext_fmask[] = {
[HDR_ENDIANNESS] = BIT(0),
[HDR_TOTAL_LEN_OR_PAD_VALID] = BIT(1),
[HDR_TOTAL_LEN_OR_PAD] = BIT(2),
[HDR_PAYLOAD_LEN_INC_PADDING] = BIT(3),
[HDR_TOTAL_LEN_OR_PAD_OFFSET] = GENMASK(9, 4),
[HDR_PAD_TO_ALIGNMENT] = GENMASK(13, 10),
/* Bits 14-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR_EXT, endp_init_hdr_ext, 0x00000814, 0x0070);
IPA_REG_STRIDE(ENDP_INIT_HDR_METADATA_MASK, endp_init_hdr_metadata_mask,
0x00000818, 0x0070);
static const u32 ipa_reg_endp_init_mode_fmask[] = {
[ENDP_MODE] = GENMASK(2, 0),
/* Bit 3 reserved */
[DEST_PIPE_INDEX] = GENMASK(8, 4),
/* Bits 9-11 reserved */
[BYTE_THRESHOLD] = GENMASK(27, 12),
[PIPE_REPLICATION_EN] = BIT(28),
[PAD_EN] = BIT(29),
[HDR_FTCH_DISABLE] = BIT(30),
/* Bit 31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_MODE, endp_init_mode, 0x00000820, 0x0070);
static const u32 ipa_reg_endp_init_aggr_fmask[] = {
[AGGR_EN] = GENMASK(1, 0),
[AGGR_TYPE] = GENMASK(4, 2),
[BYTE_LIMIT] = GENMASK(9, 5),
[TIME_LIMIT] = GENMASK(14, 10),
[PKT_LIMIT] = GENMASK(20, 15),
[SW_EOF_ACTIVE] = BIT(21),
[FORCE_CLOSE] = BIT(22),
/* Bit 23 reserved */
[HARD_BYTE_LIMIT_EN] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_AGGR, endp_init_aggr, 0x00000824, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_en_fmask[] = {
[HOL_BLOCK_EN] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_EN, endp_init_hol_block_en,
0x0000082c, 0x0070);
/* Entire register is a tick count */
static const u32 ipa_reg_endp_init_hol_block_timer_fmask[] = {
[TIMER_BASE_VALUE] = GENMASK(31, 0),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_TIMER, endp_init_hol_block_timer,
0x00000830, 0x0070);
static const u32 ipa_reg_endp_init_deaggr_fmask[] = {
[DEAGGR_HDR_LEN] = GENMASK(5, 0),
[SYSPIPE_ERR_DETECTION] = BIT(6),
[PACKET_OFFSET_VALID] = BIT(7),
[PACKET_OFFSET_LOCATION] = GENMASK(13, 8),
[IGNORE_MIN_PKT_ERR] = BIT(14),
/* Bit 15 reserved */
[MAX_PACKET_LEN] = GENMASK(31, 16),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_DEAGGR, endp_init_deaggr, 0x00000834, 0x0070);
static const u32 ipa_reg_endp_init_rsrc_grp_fmask[] = {
[ENDP_RSRC_GRP] = GENMASK(2, 0),
/* Bits 3-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_RSRC_GRP, endp_init_rsrc_grp,
0x00000838, 0x0070);
static const u32 ipa_reg_endp_init_seq_fmask[] = {
[SEQ_TYPE] = GENMASK(7, 0),
[SEQ_REP_TYPE] = GENMASK(15, 8),
/* Bits 16-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_SEQ, endp_init_seq, 0x0000083c, 0x0070);
static const u32 ipa_reg_endp_status_fmask[] = {
[STATUS_EN] = BIT(0),
[STATUS_ENDP] = GENMASK(5, 1),
/* Bits 6-7 reserved */
[STATUS_LOCATION] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_STATUS, endp_status, 0x00000840, 0x0070);
static const u32 ipa_reg_endp_filter_router_hsh_cfg_fmask[] = {
[FILTER_HASH_MSK_SRC_ID] = BIT(0),
[FILTER_HASH_MSK_SRC_IP] = BIT(1),
[FILTER_HASH_MSK_DST_IP] = BIT(2),
[FILTER_HASH_MSK_SRC_PORT] = BIT(3),
[FILTER_HASH_MSK_DST_PORT] = BIT(4),
[FILTER_HASH_MSK_PROTOCOL] = BIT(5),
[FILTER_HASH_MSK_METADATA] = BIT(6),
[FILTER_HASH_MSK_ALL] = GENMASK(6, 0),
/* Bits 7-15 reserved */
[ROUTER_HASH_MSK_SRC_ID] = BIT(16),
[ROUTER_HASH_MSK_SRC_IP] = BIT(17),
[ROUTER_HASH_MSK_DST_IP] = BIT(18),
[ROUTER_HASH_MSK_SRC_PORT] = BIT(19),
[ROUTER_HASH_MSK_DST_PORT] = BIT(20),
[ROUTER_HASH_MSK_PROTOCOL] = BIT(21),
[ROUTER_HASH_MSK_METADATA] = BIT(22),
[ROUTER_HASH_MSK_ALL] = GENMASK(22, 16),
/* Bits 23-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_FILTER_ROUTER_HSH_CFG, endp_filter_router_hsh_cfg,
0x0000085c, 0x0070);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_STTS, ipa_irq_stts, 0x00003008 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_EN, ipa_irq_en, 0x0000300c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_CLR, ipa_irq_clr, 0x00003010 + 0x1000 * GSI_EE_AP);
static const u32 ipa_reg_ipa_irq_uc_fmask[] = {
[UC_INTR] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_FIELDS(IPA_IRQ_UC, ipa_irq_uc, 0x0000301c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_INFO, irq_suspend_info, 0x00003030 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_EN, irq_suspend_en, 0x00003034 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_CLR, irq_suspend_clr, 0x00003038 + 0x1000 * GSI_EE_AP);
static const struct ipa_reg *ipa_reg_array[] = {
[COMP_CFG] = &ipa_reg_comp_cfg,
[CLKON_CFG] = &ipa_reg_clkon_cfg,
[ROUTE] = &ipa_reg_route,
[SHARED_MEM_SIZE] = &ipa_reg_shared_mem_size,
[QSB_MAX_WRITES] = &ipa_reg_qsb_max_writes,
[QSB_MAX_READS] = &ipa_reg_qsb_max_reads,
[FILT_ROUT_HASH_EN] = &ipa_reg_filt_rout_hash_en,
[FILT_ROUT_HASH_FLUSH] = &ipa_reg_filt_rout_hash_flush,
[STATE_AGGR_ACTIVE] = &ipa_reg_state_aggr_active,
[IPA_BCR] = &ipa_reg_ipa_bcr,
[LOCAL_PKT_PROC_CNTXT] = &ipa_reg_local_pkt_proc_cntxt,
[AGGR_FORCE_CLOSE] = &ipa_reg_aggr_force_close,
[COUNTER_CFG] = &ipa_reg_counter_cfg,
[SRC_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_01_rsrc_type,
[SRC_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_23_rsrc_type,
[SRC_RSRC_GRP_45_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_45_rsrc_type,
[SRC_RSRC_GRP_67_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_67_rsrc_type,
[DST_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_01_rsrc_type,
[DST_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_23_rsrc_type,
[DST_RSRC_GRP_45_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_45_rsrc_type,
[DST_RSRC_GRP_67_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_67_rsrc_type,
[ENDP_INIT_CTRL] = &ipa_reg_endp_init_ctrl,
[ENDP_INIT_CFG] = &ipa_reg_endp_init_cfg,
[ENDP_INIT_NAT] = &ipa_reg_endp_init_nat,
[ENDP_INIT_HDR] = &ipa_reg_endp_init_hdr,
[ENDP_INIT_HDR_EXT] = &ipa_reg_endp_init_hdr_ext,
[ENDP_INIT_HDR_METADATA_MASK] = &ipa_reg_endp_init_hdr_metadata_mask,
[ENDP_INIT_MODE] = &ipa_reg_endp_init_mode,
[ENDP_INIT_AGGR] = &ipa_reg_endp_init_aggr,
[ENDP_INIT_HOL_BLOCK_EN] = &ipa_reg_endp_init_hol_block_en,
[ENDP_INIT_HOL_BLOCK_TIMER] = &ipa_reg_endp_init_hol_block_timer,
[ENDP_INIT_DEAGGR] = &ipa_reg_endp_init_deaggr,
[ENDP_INIT_RSRC_GRP] = &ipa_reg_endp_init_rsrc_grp,
[ENDP_INIT_SEQ] = &ipa_reg_endp_init_seq,
[ENDP_STATUS] = &ipa_reg_endp_status,
[ENDP_FILTER_ROUTER_HSH_CFG] = &ipa_reg_endp_filter_router_hsh_cfg,
[IPA_IRQ_STTS] = &ipa_reg_ipa_irq_stts,
[IPA_IRQ_EN] = &ipa_reg_ipa_irq_en,
[IPA_IRQ_CLR] = &ipa_reg_ipa_irq_clr,
[IPA_IRQ_UC] = &ipa_reg_ipa_irq_uc,
[IRQ_SUSPEND_INFO] = &ipa_reg_irq_suspend_info,
[IRQ_SUSPEND_EN] = &ipa_reg_irq_suspend_en,
[IRQ_SUSPEND_CLR] = &ipa_reg_irq_suspend_clr,
};
const struct ipa_regs ipa_regs_v3_1 = {
.reg_count = ARRAY_SIZE(ipa_reg_array),
.reg = ipa_reg_array,
};
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022 Linaro Ltd. */
#include <linux/types.h>
#include "../ipa.h"
#include "../ipa_reg.h"
static const u32 ipa_reg_comp_cfg_fmask[] = {
[COMP_CFG_ENABLE] = BIT(0),
[GSI_SNOC_BYPASS_DIS] = BIT(1),
[GEN_QMB_0_SNOC_BYPASS_DIS] = BIT(2),
[GEN_QMB_1_SNOC_BYPASS_DIS] = BIT(3),
[IPA_DCMP_FAST_CLK_EN] = BIT(4),
/* Bits 5-31 reserved */
};
IPA_REG_FIELDS(COMP_CFG, comp_cfg, 0x0000003c);
static const u32 ipa_reg_clkon_cfg_fmask[] = {
[CLKON_RX] = BIT(0),
[CLKON_PROC] = BIT(1),
[TX_WRAPPER] = BIT(2),
[CLKON_MISC] = BIT(3),
[RAM_ARB] = BIT(4),
[FTCH_HPS] = BIT(5),
[FTCH_DPS] = BIT(6),
[CLKON_HPS] = BIT(7),
[CLKON_DPS] = BIT(8),
[RX_HPS_CMDQS] = BIT(9),
[HPS_DPS_CMDQS] = BIT(10),
[DPS_TX_CMDQS] = BIT(11),
[RSRC_MNGR] = BIT(12),
[CTX_HANDLER] = BIT(13),
[ACK_MNGR] = BIT(14),
[D_DCPH] = BIT(15),
[H_DCPH] = BIT(16),
/* Bit 17 reserved */
[NTF_TX_CMDQS] = BIT(18),
[CLKON_TX_0] = BIT(19),
[CLKON_TX_1] = BIT(20),
[CLKON_FNR] = BIT(21),
/* Bits 22-31 reserved */
};
IPA_REG_FIELDS(CLKON_CFG, clkon_cfg, 0x00000044);
static const u32 ipa_reg_route_fmask[] = {
[ROUTE_DIS] = BIT(0),
[ROUTE_DEF_PIPE] = GENMASK(5, 1),
[ROUTE_DEF_HDR_TABLE] = BIT(6),
[ROUTE_DEF_HDR_OFST] = GENMASK(16, 7),
[ROUTE_FRAG_DEF_PIPE] = GENMASK(21, 17),
/* Bits 22-23 reserved */
[ROUTE_DEF_RETAIN_HDR] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_FIELDS(ROUTE, route, 0x00000048);
static const u32 ipa_reg_shared_mem_size_fmask[] = {
[MEM_SIZE] = GENMASK(15, 0),
[MEM_BADDR] = GENMASK(31, 16),
};
IPA_REG_FIELDS(SHARED_MEM_SIZE, shared_mem_size, 0x00000054);
static const u32 ipa_reg_qsb_max_writes_fmask[] = {
[GEN_QMB_0_MAX_WRITES] = GENMASK(3, 0),
[GEN_QMB_1_MAX_WRITES] = GENMASK(7, 4),
/* Bits 8-31 reserved */
};
IPA_REG_FIELDS(QSB_MAX_WRITES, qsb_max_writes, 0x00000074);
static const u32 ipa_reg_qsb_max_reads_fmask[] = {
[GEN_QMB_0_MAX_READS] = GENMASK(3, 0),
[GEN_QMB_1_MAX_READS] = GENMASK(7, 4),
};
IPA_REG_FIELDS(QSB_MAX_READS, qsb_max_reads, 0x00000078);
static const u32 ipa_reg_filt_rout_hash_en_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_EN, filt_rout_hash_en, 0x000008c);
static const u32 ipa_reg_filt_rout_hash_flush_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_FLUSH, filt_rout_hash_flush, 0x0000090);
/* Valid bits defined by ipa->available */
IPA_REG(STATE_AGGR_ACTIVE, state_aggr_active, 0x0000010c);
IPA_REG(IPA_BCR, ipa_bcr, 0x000001d0);
static const u32 ipa_reg_local_pkt_proc_cntxt_fmask[] = {
[IPA_BASE_ADDR] = GENMASK(16, 0),
/* Bits 17-31 reserved */
};
/* Offset must be a multiple of 8 */
IPA_REG_FIELDS(LOCAL_PKT_PROC_CNTXT, local_pkt_proc_cntxt, 0x000001e8);
/* Valid bits defined by ipa->available */
IPA_REG(AGGR_FORCE_CLOSE, aggr_force_close, 0x000001ec);
static const u32 ipa_reg_counter_cfg_fmask[] = {
/* Bits 0-3 reserved */
[AGGR_GRANULARITY] = GENMASK(8, 4),
/* Bits 5-31 reserved */
};
IPA_REG_FIELDS(COUNTER_CFG, counter_cfg, 0x000001f0);
static const u32 ipa_reg_ipa_tx_cfg_fmask[] = {
[TX0_PREFETCH_DISABLE] = BIT(0),
[TX1_PREFETCH_DISABLE] = BIT(1),
[PREFETCH_ALMOST_EMPTY_SIZE] = GENMASK(4, 2),
/* Bits 5-31 reserved */
};
IPA_REG_FIELDS(IPA_TX_CFG, ipa_tx_cfg, 0x000001fc);
static const u32 ipa_reg_flavor_0_fmask[] = {
[MAX_PIPES] = GENMASK(3, 0),
/* Bits 4-7 reserved */
[MAX_CONS_PIPES] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[MAX_PROD_PIPES] = GENMASK(20, 16),
/* Bits 21-23 reserved */
[PROD_LOWEST] = GENMASK(27, 24),
/* Bits 28-31 reserved */
};
IPA_REG_FIELDS(FLAVOR_0, flavor_0, 0x00000210);
static const u32 ipa_reg_idle_indication_cfg_fmask[] = {
[ENTER_IDLE_DEBOUNCE_THRESH] = GENMASK(15, 0),
[CONST_NON_IDLE_ENABLE] = BIT(16),
/* Bits 17-31 reserved */
};
IPA_REG_FIELDS(IDLE_INDICATION_CFG, idle_indication_cfg, 0x00000220);
static const u32 ipa_reg_src_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_01_RSRC_TYPE, src_rsrc_grp_01_rsrc_type,
0x00000400, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_23_RSRC_TYPE, src_rsrc_grp_23_rsrc_type,
0x00000404, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_01_RSRC_TYPE, dst_rsrc_grp_01_rsrc_type,
0x00000500, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_23_RSRC_TYPE, dst_rsrc_grp_23_rsrc_type,
0x00000504, 0x0020);
static const u32 ipa_reg_endp_init_ctrl_fmask[] = {
[ENDP_SUSPEND] = BIT(0),
[ENDP_DELAY] = BIT(1),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CTRL, endp_init_ctrl, 0x00000800, 0x0070);
static const u32 ipa_reg_endp_init_cfg_fmask[] = {
[FRAG_OFFLOAD_EN] = BIT(0),
[CS_OFFLOAD_EN] = GENMASK(2, 1),
[CS_METADATA_HDR_OFFSET] = GENMASK(6, 3),
/* Bit 7 reserved */
[CS_GEN_QMB_MASTER_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CFG, endp_init_cfg, 0x00000808, 0x0070);
static const u32 ipa_reg_endp_init_nat_fmask[] = {
[NAT_EN] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_NAT, endp_init_nat, 0x0000080c, 0x0070);
static const u32 ipa_reg_endp_init_hdr_fmask[] = {
[HDR_LEN] = GENMASK(5, 0),
[HDR_OFST_METADATA_VALID] = BIT(6),
[HDR_OFST_METADATA] = GENMASK(12, 7),
[HDR_ADDITIONAL_CONST_LEN] = GENMASK(18, 13),
[HDR_OFST_PKT_SIZE_VALID] = BIT(19),
[HDR_OFST_PKT_SIZE] = GENMASK(25, 20),
[HDR_A5_MUX] = BIT(26),
[HDR_LEN_INC_DEAGG_HDR] = BIT(27),
[HDR_METADATA_REG_VALID] = BIT(28),
/* Bits 29-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR, endp_init_hdr, 0x00000810, 0x0070);
static const u32 ipa_reg_endp_init_hdr_ext_fmask[] = {
[HDR_ENDIANNESS] = BIT(0),
[HDR_TOTAL_LEN_OR_PAD_VALID] = BIT(1),
[HDR_TOTAL_LEN_OR_PAD] = BIT(2),
[HDR_PAYLOAD_LEN_INC_PADDING] = BIT(3),
[HDR_TOTAL_LEN_OR_PAD_OFFSET] = GENMASK(9, 4),
[HDR_PAD_TO_ALIGNMENT] = GENMASK(13, 10),
/* Bits 14-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR_EXT, endp_init_hdr_ext, 0x00000814, 0x0070);
IPA_REG_STRIDE(ENDP_INIT_HDR_METADATA_MASK, endp_init_hdr_metadata_mask,
0x00000818, 0x0070);
static const u32 ipa_reg_endp_init_mode_fmask[] = {
[ENDP_MODE] = GENMASK(2, 0),
/* Bit 3 reserved */
[DEST_PIPE_INDEX] = GENMASK(8, 4),
/* Bits 9-11 reserved */
[BYTE_THRESHOLD] = GENMASK(27, 12),
[PIPE_REPLICATION_EN] = BIT(28),
[PAD_EN] = BIT(29),
[HDR_FTCH_DISABLE] = BIT(30),
/* Bit 31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_MODE, endp_init_mode, 0x00000820, 0x0070);
static const u32 ipa_reg_endp_init_aggr_fmask[] = {
[AGGR_EN] = GENMASK(1, 0),
[AGGR_TYPE] = GENMASK(4, 2),
[BYTE_LIMIT] = GENMASK(9, 5),
[TIME_LIMIT] = GENMASK(14, 10),
[PKT_LIMIT] = GENMASK(20, 15),
[SW_EOF_ACTIVE] = BIT(21),
[FORCE_CLOSE] = BIT(22),
/* Bit 23 reserved */
[HARD_BYTE_LIMIT_EN] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_AGGR, endp_init_aggr, 0x00000824, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_en_fmask[] = {
[HOL_BLOCK_EN] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_EN, endp_init_hol_block_en,
0x0000082c, 0x0070);
/* Entire register is a tick count */
static const u32 ipa_reg_endp_init_hol_block_timer_fmask[] = {
[TIMER_BASE_VALUE] = GENMASK(31, 0),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_TIMER, endp_init_hol_block_timer,
0x00000830, 0x0070);
static const u32 ipa_reg_endp_init_deaggr_fmask[] = {
[DEAGGR_HDR_LEN] = GENMASK(5, 0),
[SYSPIPE_ERR_DETECTION] = BIT(6),
[PACKET_OFFSET_VALID] = BIT(7),
[PACKET_OFFSET_LOCATION] = GENMASK(13, 8),
[IGNORE_MIN_PKT_ERR] = BIT(14),
/* Bit 15 reserved */
[MAX_PACKET_LEN] = GENMASK(31, 16),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_DEAGGR, endp_init_deaggr, 0x00000834, 0x0070);
static const u32 ipa_reg_endp_init_rsrc_grp_fmask[] = {
[ENDP_RSRC_GRP] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_RSRC_GRP, endp_init_rsrc_grp,
0x00000838, 0x0070);
static const u32 ipa_reg_endp_init_seq_fmask[] = {
[SEQ_TYPE] = GENMASK(7, 0),
[SEQ_REP_TYPE] = GENMASK(15, 8),
/* Bits 16-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_SEQ, endp_init_seq, 0x0000083c, 0x0070);
static const u32 ipa_reg_endp_status_fmask[] = {
[STATUS_EN] = BIT(0),
[STATUS_ENDP] = GENMASK(5, 1),
/* Bits 6-7 reserved */
[STATUS_LOCATION] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_STATUS, endp_status, 0x00000840, 0x0070);
static const u32 ipa_reg_endp_filter_router_hsh_cfg_fmask[] = {
[FILTER_HASH_MSK_SRC_ID] = BIT(0),
[FILTER_HASH_MSK_SRC_IP] = BIT(1),
[FILTER_HASH_MSK_DST_IP] = BIT(2),
[FILTER_HASH_MSK_SRC_PORT] = BIT(3),
[FILTER_HASH_MSK_DST_PORT] = BIT(4),
[FILTER_HASH_MSK_PROTOCOL] = BIT(5),
[FILTER_HASH_MSK_METADATA] = BIT(6),
[FILTER_HASH_MSK_ALL] = GENMASK(6, 0),
/* Bits 7-15 reserved */
[ROUTER_HASH_MSK_SRC_ID] = BIT(16),
[ROUTER_HASH_MSK_SRC_IP] = BIT(17),
[ROUTER_HASH_MSK_DST_IP] = BIT(18),
[ROUTER_HASH_MSK_SRC_PORT] = BIT(19),
[ROUTER_HASH_MSK_DST_PORT] = BIT(20),
[ROUTER_HASH_MSK_PROTOCOL] = BIT(21),
[ROUTER_HASH_MSK_METADATA] = BIT(22),
[ROUTER_HASH_MSK_ALL] = GENMASK(22, 16),
/* Bits 23-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_FILTER_ROUTER_HSH_CFG, endp_filter_router_hsh_cfg,
0x0000085c, 0x0070);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_STTS, ipa_irq_stts, 0x00003008 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_EN, ipa_irq_en, 0x0000300c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_CLR, ipa_irq_clr, 0x00003010 + 0x1000 * GSI_EE_AP);
static const u32 ipa_reg_ipa_irq_uc_fmask[] = {
[UC_INTR] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_FIELDS(IPA_IRQ_UC, ipa_irq_uc, 0x0000301c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_INFO, irq_suspend_info, 0x00003030 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_EN, irq_suspend_en, 0x00003034 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_CLR, irq_suspend_clr, 0x00003038 + 0x1000 * GSI_EE_AP);
static const struct ipa_reg *ipa_reg_array[] = {
[COMP_CFG] = &ipa_reg_comp_cfg,
[CLKON_CFG] = &ipa_reg_clkon_cfg,
[ROUTE] = &ipa_reg_route,
[SHARED_MEM_SIZE] = &ipa_reg_shared_mem_size,
[QSB_MAX_WRITES] = &ipa_reg_qsb_max_writes,
[QSB_MAX_READS] = &ipa_reg_qsb_max_reads,
[FILT_ROUT_HASH_EN] = &ipa_reg_filt_rout_hash_en,
[FILT_ROUT_HASH_FLUSH] = &ipa_reg_filt_rout_hash_flush,
[STATE_AGGR_ACTIVE] = &ipa_reg_state_aggr_active,
[IPA_BCR] = &ipa_reg_ipa_bcr,
[LOCAL_PKT_PROC_CNTXT] = &ipa_reg_local_pkt_proc_cntxt,
[AGGR_FORCE_CLOSE] = &ipa_reg_aggr_force_close,
[COUNTER_CFG] = &ipa_reg_counter_cfg,
[IPA_TX_CFG] = &ipa_reg_ipa_tx_cfg,
[FLAVOR_0] = &ipa_reg_flavor_0,
[IDLE_INDICATION_CFG] = &ipa_reg_idle_indication_cfg,
[SRC_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_01_rsrc_type,
[SRC_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_23_rsrc_type,
[DST_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_01_rsrc_type,
[DST_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_23_rsrc_type,
[ENDP_INIT_CTRL] = &ipa_reg_endp_init_ctrl,
[ENDP_INIT_CFG] = &ipa_reg_endp_init_cfg,
[ENDP_INIT_NAT] = &ipa_reg_endp_init_nat,
[ENDP_INIT_HDR] = &ipa_reg_endp_init_hdr,
[ENDP_INIT_HDR_EXT] = &ipa_reg_endp_init_hdr_ext,
[ENDP_INIT_HDR_METADATA_MASK] = &ipa_reg_endp_init_hdr_metadata_mask,
[ENDP_INIT_MODE] = &ipa_reg_endp_init_mode,
[ENDP_INIT_AGGR] = &ipa_reg_endp_init_aggr,
[ENDP_INIT_HOL_BLOCK_EN] = &ipa_reg_endp_init_hol_block_en,
[ENDP_INIT_HOL_BLOCK_TIMER] = &ipa_reg_endp_init_hol_block_timer,
[ENDP_INIT_DEAGGR] = &ipa_reg_endp_init_deaggr,
[ENDP_INIT_RSRC_GRP] = &ipa_reg_endp_init_rsrc_grp,
[ENDP_INIT_SEQ] = &ipa_reg_endp_init_seq,
[ENDP_STATUS] = &ipa_reg_endp_status,
[ENDP_FILTER_ROUTER_HSH_CFG] = &ipa_reg_endp_filter_router_hsh_cfg,
[IPA_IRQ_STTS] = &ipa_reg_ipa_irq_stts,
[IPA_IRQ_EN] = &ipa_reg_ipa_irq_en,
[IPA_IRQ_CLR] = &ipa_reg_ipa_irq_clr,
[IPA_IRQ_UC] = &ipa_reg_ipa_irq_uc,
[IRQ_SUSPEND_INFO] = &ipa_reg_irq_suspend_info,
[IRQ_SUSPEND_EN] = &ipa_reg_irq_suspend_en,
[IRQ_SUSPEND_CLR] = &ipa_reg_irq_suspend_clr,
};
const struct ipa_regs ipa_regs_v3_5_1 = {
.reg_count = ARRAY_SIZE(ipa_reg_array),
.reg = ipa_reg_array,
};
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022 Linaro Ltd. */
#include <linux/types.h>
#include "../ipa.h"
#include "../ipa_reg.h"
static const u32 ipa_reg_comp_cfg_fmask[] = {
[RAM_ARB_PRI_CLIENT_SAMP_FIX_DIS] = BIT(0),
[GSI_SNOC_BYPASS_DIS] = BIT(1),
[GEN_QMB_0_SNOC_BYPASS_DIS] = BIT(2),
[GEN_QMB_1_SNOC_BYPASS_DIS] = BIT(3),
/* Bit 4 reserved */
[IPA_QMB_SELECT_CONS_EN] = BIT(5),
[IPA_QMB_SELECT_PROD_EN] = BIT(6),
[GSI_MULTI_INORDER_RD_DIS] = BIT(7),
[GSI_MULTI_INORDER_WR_DIS] = BIT(8),
[GEN_QMB_0_MULTI_INORDER_RD_DIS] = BIT(9),
[GEN_QMB_1_MULTI_INORDER_RD_DIS] = BIT(10),
[GEN_QMB_0_MULTI_INORDER_WR_DIS] = BIT(11),
[GEN_QMB_1_MULTI_INORDER_WR_DIS] = BIT(12),
[GEN_QMB_0_SNOC_CNOC_LOOP_PROT_DIS] = BIT(13),
[GSI_SNOC_CNOC_LOOP_PROT_DISABLE] = BIT(14),
[GSI_MULTI_AXI_MASTERS_DIS] = BIT(15),
[IPA_QMB_SELECT_GLOBAL_EN] = BIT(16),
[FULL_FLUSH_WAIT_RS_CLOSURE_EN] = BIT(17),
/* Bit 18 reserved */
[QMB_RAM_RD_CACHE_DISABLE] = BIT(19),
[GENQMB_AOOOWR] = BIT(20),
[IF_OUT_OF_BUF_STOP_RESET_MASK_EN] = BIT(21),
[ATOMIC_FETCHER_ARB_LOCK_DIS] = GENMASK(23, 22),
/* Bits 24-29 reserved */
[GEN_QMB_1_DYNAMIC_ASIZE] = BIT(30),
[GEN_QMB_0_DYNAMIC_ASIZE] = BIT(31),
};
IPA_REG_FIELDS(COMP_CFG, comp_cfg, 0x0000003c);
static const u32 ipa_reg_clkon_cfg_fmask[] = {
[CLKON_RX] = BIT(0),
[CLKON_PROC] = BIT(1),
[TX_WRAPPER] = BIT(2),
[CLKON_MISC] = BIT(3),
[RAM_ARB] = BIT(4),
[FTCH_HPS] = BIT(5),
[FTCH_DPS] = BIT(6),
[CLKON_HPS] = BIT(7),
[CLKON_DPS] = BIT(8),
[RX_HPS_CMDQS] = BIT(9),
[HPS_DPS_CMDQS] = BIT(10),
[DPS_TX_CMDQS] = BIT(11),
[RSRC_MNGR] = BIT(12),
[CTX_HANDLER] = BIT(13),
[ACK_MNGR] = BIT(14),
[D_DCPH] = BIT(15),
[H_DCPH] = BIT(16),
/* Bit 17 reserved */
[NTF_TX_CMDQS] = BIT(18),
[CLKON_TX_0] = BIT(19),
[CLKON_TX_1] = BIT(20),
[CLKON_FNR] = BIT(21),
[QSB2AXI_CMDQ_L] = BIT(22),
[AGGR_WRAPPER] = BIT(23),
[RAM_SLAVEWAY] = BIT(24),
[CLKON_QMB] = BIT(25),
[WEIGHT_ARB] = BIT(26),
[GSI_IF] = BIT(27),
[CLKON_GLOBAL] = BIT(28),
[GLOBAL_2X_CLK] = BIT(29),
[DPL_FIFO] = BIT(30),
[DRBIP] = BIT(31),
};
IPA_REG_FIELDS(CLKON_CFG, clkon_cfg, 0x00000044);
static const u32 ipa_reg_route_fmask[] = {
[ROUTE_DIS] = BIT(0),
[ROUTE_DEF_PIPE] = GENMASK(5, 1),
[ROUTE_DEF_HDR_TABLE] = BIT(6),
[ROUTE_DEF_HDR_OFST] = GENMASK(16, 7),
[ROUTE_FRAG_DEF_PIPE] = GENMASK(21, 17),
/* Bits 22-23 reserved */
[ROUTE_DEF_RETAIN_HDR] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_FIELDS(ROUTE, route, 0x00000048);
static const u32 ipa_reg_shared_mem_size_fmask[] = {
[MEM_SIZE] = GENMASK(15, 0),
[MEM_BADDR] = GENMASK(31, 16),
};
IPA_REG_FIELDS(SHARED_MEM_SIZE, shared_mem_size, 0x00000054);
static const u32 ipa_reg_qsb_max_writes_fmask[] = {
[GEN_QMB_0_MAX_WRITES] = GENMASK(3, 0),
[GEN_QMB_1_MAX_WRITES] = GENMASK(7, 4),
/* Bits 8-31 reserved */
};
IPA_REG_FIELDS(QSB_MAX_WRITES, qsb_max_writes, 0x00000074);
static const u32 ipa_reg_qsb_max_reads_fmask[] = {
[GEN_QMB_0_MAX_READS] = GENMASK(3, 0),
[GEN_QMB_1_MAX_READS] = GENMASK(7, 4),
/* Bits 8-15 reserved */
[GEN_QMB_0_MAX_READS_BEATS] = GENMASK(23, 16),
[GEN_QMB_1_MAX_READS_BEATS] = GENMASK(31, 24),
};
IPA_REG_FIELDS(QSB_MAX_READS, qsb_max_reads, 0x00000078);
static const u32 ipa_reg_filt_rout_hash_en_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_EN, filt_rout_hash_en, 0x0000148);
static const u32 ipa_reg_filt_rout_hash_flush_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_FLUSH, filt_rout_hash_flush, 0x000014c);
/* Valid bits defined by ipa->available */
IPA_REG(STATE_AGGR_ACTIVE, state_aggr_active, 0x000000b4);
static const u32 ipa_reg_local_pkt_proc_cntxt_fmask[] = {
[IPA_BASE_ADDR] = GENMASK(17, 0),
/* Bits 18-31 reserved */
};
/* Offset must be a multiple of 8 */
IPA_REG_FIELDS(LOCAL_PKT_PROC_CNTXT, local_pkt_proc_cntxt, 0x000001e8);
/* Valid bits defined by ipa->available */
IPA_REG(AGGR_FORCE_CLOSE, aggr_force_close, 0x000001ec);
static const u32 ipa_reg_ipa_tx_cfg_fmask[] = {
/* Bits 0-1 reserved */
[PREFETCH_ALMOST_EMPTY_SIZE_TX0] = GENMASK(5, 2),
[DMAW_SCND_OUTSD_PRED_THRESHOLD] = GENMASK(9, 6),
[DMAW_SCND_OUTSD_PRED_EN] = BIT(10),
[DMAW_MAX_BEATS_256_DIS] = BIT(11),
[PA_MASK_EN] = BIT(12),
[PREFETCH_ALMOST_EMPTY_SIZE_TX1] = GENMASK(16, 13),
[DUAL_TX_ENABLE] = BIT(17),
[SSPND_PA_NO_START_STATE] = BIT(18),
/* Bits 19-31 reserved */
};
IPA_REG_FIELDS(IPA_TX_CFG, ipa_tx_cfg, 0x000001fc);
static const u32 ipa_reg_flavor_0_fmask[] = {
[MAX_PIPES] = GENMASK(4, 0),
/* Bits 5-7 reserved */
[MAX_CONS_PIPES] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[MAX_PROD_PIPES] = GENMASK(20, 16),
/* Bits 21-23 reserved */
[PROD_LOWEST] = GENMASK(27, 24),
/* Bits 28-31 reserved */
};
IPA_REG_FIELDS(FLAVOR_0, flavor_0, 0x00000210);
static const u32 ipa_reg_idle_indication_cfg_fmask[] = {
[ENTER_IDLE_DEBOUNCE_THRESH] = GENMASK(15, 0),
[CONST_NON_IDLE_ENABLE] = BIT(16),
/* Bits 17-31 reserved */
};
IPA_REG_FIELDS(IDLE_INDICATION_CFG, idle_indication_cfg, 0x00000240);
static const u32 ipa_reg_qtime_timestamp_cfg_fmask[] = {
[DPL_TIMESTAMP_LSB] = GENMASK(4, 0),
/* Bits 5-6 reserved */
[DPL_TIMESTAMP_SEL] = BIT(7),
[TAG_TIMESTAMP_LSB] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[NAT_TIMESTAMP_LSB] = GENMASK(20, 16),
/* Bits 21-31 reserved */
};
IPA_REG_FIELDS(QTIME_TIMESTAMP_CFG, qtime_timestamp_cfg, 0x0000024c);
static const u32 ipa_reg_timers_xo_clk_div_cfg_fmask[] = {
[DIV_VALUE] = GENMASK(8, 0),
/* Bits 9-30 reserved */
[DIV_ENABLE] = BIT(31),
};
IPA_REG_FIELDS(TIMERS_XO_CLK_DIV_CFG, timers_xo_clk_div_cfg, 0x00000250);
static const u32 ipa_reg_timers_pulse_gran_cfg_fmask[] = {
[PULSE_GRAN_0] = GENMASK(2, 0),
[PULSE_GRAN_1] = GENMASK(5, 3),
[PULSE_GRAN_2] = GENMASK(8, 6),
/* Bits 9-31 reserved */
};
IPA_REG_FIELDS(TIMERS_PULSE_GRAN_CFG, timers_pulse_gran_cfg, 0x00000254);
static const u32 ipa_reg_src_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_01_RSRC_TYPE, src_rsrc_grp_01_rsrc_type,
0x00000400, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_23_RSRC_TYPE, src_rsrc_grp_23_rsrc_type,
0x00000404, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_01_RSRC_TYPE, dst_rsrc_grp_01_rsrc_type,
0x00000500, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_23_RSRC_TYPE, dst_rsrc_grp_23_rsrc_type,
0x00000504, 0x0020);
static const u32 ipa_reg_endp_init_cfg_fmask[] = {
[FRAG_OFFLOAD_EN] = BIT(0),
[CS_OFFLOAD_EN] = GENMASK(2, 1),
[CS_METADATA_HDR_OFFSET] = GENMASK(6, 3),
/* Bit 7 reserved */
[CS_GEN_QMB_MASTER_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CFG, endp_init_cfg, 0x00000808, 0x0070);
static const u32 ipa_reg_endp_init_nat_fmask[] = {
[NAT_EN] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_NAT, endp_init_nat, 0x0000080c, 0x0070);
static const u32 ipa_reg_endp_init_hdr_fmask[] = {
[HDR_LEN] = GENMASK(5, 0),
[HDR_OFST_METADATA_VALID] = BIT(6),
[HDR_OFST_METADATA] = GENMASK(12, 7),
[HDR_ADDITIONAL_CONST_LEN] = GENMASK(18, 13),
[HDR_OFST_PKT_SIZE_VALID] = BIT(19),
[HDR_OFST_PKT_SIZE] = GENMASK(25, 20),
/* Bit 26 reserved */
[HDR_LEN_INC_DEAGG_HDR] = BIT(27),
[HDR_LEN_MSB] = GENMASK(29, 28),
[HDR_OFST_METADATA_MSB] = GENMASK(31, 30),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR, endp_init_hdr, 0x00000810, 0x0070);
static const u32 ipa_reg_endp_init_hdr_ext_fmask[] = {
[HDR_ENDIANNESS] = BIT(0),
[HDR_TOTAL_LEN_OR_PAD_VALID] = BIT(1),
[HDR_TOTAL_LEN_OR_PAD] = BIT(2),
[HDR_PAYLOAD_LEN_INC_PADDING] = BIT(3),
[HDR_TOTAL_LEN_OR_PAD_OFFSET] = GENMASK(9, 4),
[HDR_PAD_TO_ALIGNMENT] = GENMASK(13, 10),
/* Bits 14-15 reserved */
[HDR_TOTAL_LEN_OR_PAD_OFFSET_MSB] = GENMASK(17, 16),
[HDR_OFST_PKT_SIZE_MSB] = GENMASK(19, 18),
[HDR_ADDITIONAL_CONST_LEN_MSB] = GENMASK(21, 20),
/* Bits 22-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR_EXT, endp_init_hdr_ext, 0x00000814, 0x0070);
IPA_REG_STRIDE(ENDP_INIT_HDR_METADATA_MASK, endp_init_hdr_metadata_mask,
0x00000818, 0x0070);
static const u32 ipa_reg_endp_init_mode_fmask[] = {
[ENDP_MODE] = GENMASK(2, 0),
[DCPH_ENABLE] = BIT(3),
[DEST_PIPE_INDEX] = GENMASK(8, 4),
/* Bits 9-11 reserved */
[BYTE_THRESHOLD] = GENMASK(27, 12),
[PIPE_REPLICATION_EN] = BIT(28),
[PAD_EN] = BIT(29),
[DRBIP_ACL_ENABLE] = BIT(30),
/* Bit 31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_MODE, endp_init_mode, 0x00000820, 0x0070);
static const u32 ipa_reg_endp_init_aggr_fmask[] = {
[AGGR_EN] = GENMASK(1, 0),
[AGGR_TYPE] = GENMASK(4, 2),
[BYTE_LIMIT] = GENMASK(10, 5),
/* Bit 11 reserved */
[TIME_LIMIT] = GENMASK(16, 12),
[PKT_LIMIT] = GENMASK(22, 17),
[SW_EOF_ACTIVE] = BIT(23),
[FORCE_CLOSE] = BIT(24),
/* Bit 25 reserved */
[HARD_BYTE_LIMIT_EN] = BIT(26),
[AGGR_GRAN_SEL] = BIT(27),
/* Bits 28-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_AGGR, endp_init_aggr, 0x00000824, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_en_fmask[] = {
[HOL_BLOCK_EN] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_EN, endp_init_hol_block_en,
0x0000082c, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_timer_fmask[] = {
[TIMER_LIMIT] = GENMASK(4, 0),
/* Bits 5-7 reserved */
[TIMER_GRAN_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_TIMER, endp_init_hol_block_timer,
0x00000830, 0x0070);
static const u32 ipa_reg_endp_init_deaggr_fmask[] = {
[DEAGGR_HDR_LEN] = GENMASK(5, 0),
[SYSPIPE_ERR_DETECTION] = BIT(6),
[PACKET_OFFSET_VALID] = BIT(7),
[PACKET_OFFSET_LOCATION] = GENMASK(13, 8),
[IGNORE_MIN_PKT_ERR] = BIT(14),
/* Bit 15 reserved */
[MAX_PACKET_LEN] = GENMASK(31, 16),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_DEAGGR, endp_init_deaggr, 0x00000834, 0x0070);
static const u32 ipa_reg_endp_init_rsrc_grp_fmask[] = {
[ENDP_RSRC_GRP] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_RSRC_GRP, endp_init_rsrc_grp,
0x00000838, 0x0070);
static const u32 ipa_reg_endp_init_seq_fmask[] = {
[SEQ_TYPE] = GENMASK(7, 0),
/* Bits 8-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_SEQ, endp_init_seq, 0x0000083c, 0x0070);
static const u32 ipa_reg_endp_status_fmask[] = {
[STATUS_EN] = BIT(0),
[STATUS_ENDP] = GENMASK(5, 1),
/* Bits 6-8 reserved */
[STATUS_PKT_SUPPRESS] = BIT(9),
/* Bits 10-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_STATUS, endp_status, 0x00000840, 0x0070);
static const u32 ipa_reg_endp_filter_router_hsh_cfg_fmask[] = {
[FILTER_HASH_MSK_SRC_ID] = BIT(0),
[FILTER_HASH_MSK_SRC_IP] = BIT(1),
[FILTER_HASH_MSK_DST_IP] = BIT(2),
[FILTER_HASH_MSK_SRC_PORT] = BIT(3),
[FILTER_HASH_MSK_DST_PORT] = BIT(4),
[FILTER_HASH_MSK_PROTOCOL] = BIT(5),
[FILTER_HASH_MSK_METADATA] = BIT(6),
[FILTER_HASH_MSK_ALL] = GENMASK(6, 0),
/* Bits 7-15 reserved */
[ROUTER_HASH_MSK_SRC_ID] = BIT(16),
[ROUTER_HASH_MSK_SRC_IP] = BIT(17),
[ROUTER_HASH_MSK_DST_IP] = BIT(18),
[ROUTER_HASH_MSK_SRC_PORT] = BIT(19),
[ROUTER_HASH_MSK_DST_PORT] = BIT(20),
[ROUTER_HASH_MSK_PROTOCOL] = BIT(21),
[ROUTER_HASH_MSK_METADATA] = BIT(22),
[ROUTER_HASH_MSK_ALL] = GENMASK(22, 16),
/* Bits 23-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_FILTER_ROUTER_HSH_CFG, endp_filter_router_hsh_cfg,
0x0000085c, 0x0070);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_STTS, ipa_irq_stts, 0x00004008 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_EN, ipa_irq_en, 0x0000400c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_CLR, ipa_irq_clr, 0x00004010 + 0x1000 * GSI_EE_AP);
static const u32 ipa_reg_ipa_irq_uc_fmask[] = {
[UC_INTR] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_FIELDS(IPA_IRQ_UC, ipa_irq_uc, 0x0000401c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_INFO, irq_suspend_info, 0x00004030 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_EN, irq_suspend_en, 0x00004034 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_CLR, irq_suspend_clr, 0x00004038 + 0x1000 * GSI_EE_AP);
static const struct ipa_reg *ipa_reg_array[] = {
[COMP_CFG] = &ipa_reg_comp_cfg,
[CLKON_CFG] = &ipa_reg_clkon_cfg,
[ROUTE] = &ipa_reg_route,
[SHARED_MEM_SIZE] = &ipa_reg_shared_mem_size,
[QSB_MAX_WRITES] = &ipa_reg_qsb_max_writes,
[QSB_MAX_READS] = &ipa_reg_qsb_max_reads,
[FILT_ROUT_HASH_EN] = &ipa_reg_filt_rout_hash_en,
[FILT_ROUT_HASH_FLUSH] = &ipa_reg_filt_rout_hash_flush,
[STATE_AGGR_ACTIVE] = &ipa_reg_state_aggr_active,
[LOCAL_PKT_PROC_CNTXT] = &ipa_reg_local_pkt_proc_cntxt,
[AGGR_FORCE_CLOSE] = &ipa_reg_aggr_force_close,
[IPA_TX_CFG] = &ipa_reg_ipa_tx_cfg,
[FLAVOR_0] = &ipa_reg_flavor_0,
[IDLE_INDICATION_CFG] = &ipa_reg_idle_indication_cfg,
[QTIME_TIMESTAMP_CFG] = &ipa_reg_qtime_timestamp_cfg,
[TIMERS_XO_CLK_DIV_CFG] = &ipa_reg_timers_xo_clk_div_cfg,
[TIMERS_PULSE_GRAN_CFG] = &ipa_reg_timers_pulse_gran_cfg,
[SRC_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_01_rsrc_type,
[SRC_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_23_rsrc_type,
[DST_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_01_rsrc_type,
[DST_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_23_rsrc_type,
[ENDP_INIT_CFG] = &ipa_reg_endp_init_cfg,
[ENDP_INIT_NAT] = &ipa_reg_endp_init_nat,
[ENDP_INIT_HDR] = &ipa_reg_endp_init_hdr,
[ENDP_INIT_HDR_EXT] = &ipa_reg_endp_init_hdr_ext,
[ENDP_INIT_HDR_METADATA_MASK] = &ipa_reg_endp_init_hdr_metadata_mask,
[ENDP_INIT_MODE] = &ipa_reg_endp_init_mode,
[ENDP_INIT_AGGR] = &ipa_reg_endp_init_aggr,
[ENDP_INIT_HOL_BLOCK_EN] = &ipa_reg_endp_init_hol_block_en,
[ENDP_INIT_HOL_BLOCK_TIMER] = &ipa_reg_endp_init_hol_block_timer,
[ENDP_INIT_DEAGGR] = &ipa_reg_endp_init_deaggr,
[ENDP_INIT_RSRC_GRP] = &ipa_reg_endp_init_rsrc_grp,
[ENDP_INIT_SEQ] = &ipa_reg_endp_init_seq,
[ENDP_STATUS] = &ipa_reg_endp_status,
[ENDP_FILTER_ROUTER_HSH_CFG] = &ipa_reg_endp_filter_router_hsh_cfg,
[IPA_IRQ_STTS] = &ipa_reg_ipa_irq_stts,
[IPA_IRQ_EN] = &ipa_reg_ipa_irq_en,
[IPA_IRQ_CLR] = &ipa_reg_ipa_irq_clr,
[IPA_IRQ_UC] = &ipa_reg_ipa_irq_uc,
[IRQ_SUSPEND_INFO] = &ipa_reg_irq_suspend_info,
[IRQ_SUSPEND_EN] = &ipa_reg_irq_suspend_en,
[IRQ_SUSPEND_CLR] = &ipa_reg_irq_suspend_clr,
};
const struct ipa_regs ipa_regs_v4_11 = {
.reg_count = ARRAY_SIZE(ipa_reg_array),
.reg = ipa_reg_array,
};
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022 Linaro Ltd. */
#include <linux/types.h>
#include "../ipa.h"
#include "../ipa_reg.h"
static const u32 ipa_reg_comp_cfg_fmask[] = {
/* Bit 0 reserved */
[GSI_SNOC_BYPASS_DIS] = BIT(1),
[GEN_QMB_0_SNOC_BYPASS_DIS] = BIT(2),
[GEN_QMB_1_SNOC_BYPASS_DIS] = BIT(3),
[IPA_DCMP_FAST_CLK_EN] = BIT(4),
[IPA_QMB_SELECT_CONS_EN] = BIT(5),
[IPA_QMB_SELECT_PROD_EN] = BIT(6),
[GSI_MULTI_INORDER_RD_DIS] = BIT(7),
[GSI_MULTI_INORDER_WR_DIS] = BIT(8),
[GEN_QMB_0_MULTI_INORDER_RD_DIS] = BIT(9),
[GEN_QMB_1_MULTI_INORDER_RD_DIS] = BIT(10),
[GEN_QMB_0_MULTI_INORDER_WR_DIS] = BIT(11),
[GEN_QMB_1_MULTI_INORDER_WR_DIS] = BIT(12),
[GEN_QMB_0_SNOC_CNOC_LOOP_PROT_DIS] = BIT(13),
[GSI_SNOC_CNOC_LOOP_PROT_DISABLE] = BIT(14),
[GSI_MULTI_AXI_MASTERS_DIS] = BIT(15),
[IPA_QMB_SELECT_GLOBAL_EN] = BIT(16),
[ATOMIC_FETCHER_ARB_LOCK_DIS] = GENMASK(20, 17),
/* Bits 21-31 reserved */
};
IPA_REG_FIELDS(COMP_CFG, comp_cfg, 0x0000003c);
static const u32 ipa_reg_clkon_cfg_fmask[] = {
[CLKON_RX] = BIT(0),
[CLKON_PROC] = BIT(1),
[TX_WRAPPER] = BIT(2),
[CLKON_MISC] = BIT(3),
[RAM_ARB] = BIT(4),
[FTCH_HPS] = BIT(5),
[FTCH_DPS] = BIT(6),
[CLKON_HPS] = BIT(7),
[CLKON_DPS] = BIT(8),
[RX_HPS_CMDQS] = BIT(9),
[HPS_DPS_CMDQS] = BIT(10),
[DPS_TX_CMDQS] = BIT(11),
[RSRC_MNGR] = BIT(12),
[CTX_HANDLER] = BIT(13),
[ACK_MNGR] = BIT(14),
[D_DCPH] = BIT(15),
[H_DCPH] = BIT(16),
/* Bit 17 reserved */
[NTF_TX_CMDQS] = BIT(18),
[CLKON_TX_0] = BIT(19),
[CLKON_TX_1] = BIT(20),
[CLKON_FNR] = BIT(21),
[QSB2AXI_CMDQ_L] = BIT(22),
[AGGR_WRAPPER] = BIT(23),
[RAM_SLAVEWAY] = BIT(24),
[CLKON_QMB] = BIT(25),
[WEIGHT_ARB] = BIT(26),
[GSI_IF] = BIT(27),
[CLKON_GLOBAL] = BIT(28),
[GLOBAL_2X_CLK] = BIT(29),
/* Bits 30-31 reserved */
};
IPA_REG_FIELDS(CLKON_CFG, clkon_cfg, 0x00000044);
static const u32 ipa_reg_route_fmask[] = {
[ROUTE_DIS] = BIT(0),
[ROUTE_DEF_PIPE] = GENMASK(5, 1),
[ROUTE_DEF_HDR_TABLE] = BIT(6),
[ROUTE_DEF_HDR_OFST] = GENMASK(16, 7),
[ROUTE_FRAG_DEF_PIPE] = GENMASK(21, 17),
/* Bits 22-23 reserved */
[ROUTE_DEF_RETAIN_HDR] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_FIELDS(ROUTE, route, 0x00000048);
static const u32 ipa_reg_shared_mem_size_fmask[] = {
[MEM_SIZE] = GENMASK(15, 0),
[MEM_BADDR] = GENMASK(31, 16),
};
IPA_REG_FIELDS(SHARED_MEM_SIZE, shared_mem_size, 0x00000054);
static const u32 ipa_reg_qsb_max_writes_fmask[] = {
[GEN_QMB_0_MAX_WRITES] = GENMASK(3, 0),
[GEN_QMB_1_MAX_WRITES] = GENMASK(7, 4),
/* Bits 8-31 reserved */
};
IPA_REG_FIELDS(QSB_MAX_WRITES, qsb_max_writes, 0x00000074);
static const u32 ipa_reg_qsb_max_reads_fmask[] = {
[GEN_QMB_0_MAX_READS] = GENMASK(3, 0),
[GEN_QMB_1_MAX_READS] = GENMASK(7, 4),
/* Bits 8-15 reserved */
[GEN_QMB_0_MAX_READS_BEATS] = GENMASK(23, 16),
[GEN_QMB_1_MAX_READS_BEATS] = GENMASK(31, 24),
};
IPA_REG_FIELDS(QSB_MAX_READS, qsb_max_reads, 0x00000078);
static const u32 ipa_reg_filt_rout_hash_en_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_EN, filt_rout_hash_en, 0x0000148);
static const u32 ipa_reg_filt_rout_hash_flush_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_FLUSH, filt_rout_hash_flush, 0x000014c);
/* Valid bits defined by ipa->available */
IPA_REG(STATE_AGGR_ACTIVE, state_aggr_active, 0x000000b4);
IPA_REG(IPA_BCR, ipa_bcr, 0x000001d0);
static const u32 ipa_reg_local_pkt_proc_cntxt_fmask[] = {
[IPA_BASE_ADDR] = GENMASK(16, 0),
/* Bits 17-31 reserved */
};
/* Offset must be a multiple of 8 */
IPA_REG_FIELDS(LOCAL_PKT_PROC_CNTXT, local_pkt_proc_cntxt, 0x000001e8);
/* Valid bits defined by ipa->available */
IPA_REG(AGGR_FORCE_CLOSE, aggr_force_close, 0x000001ec);
static const u32 ipa_reg_counter_cfg_fmask[] = {
/* Bits 0-3 reserved */
[AGGR_GRANULARITY] = GENMASK(8, 4),
/* Bits 9-31 reserved */
};
IPA_REG_FIELDS(COUNTER_CFG, counter_cfg, 0x000001f0);
static const u32 ipa_reg_ipa_tx_cfg_fmask[] = {
/* Bits 0-1 reserved */
[PREFETCH_ALMOST_EMPTY_SIZE_TX0] = GENMASK(5, 2),
[DMAW_SCND_OUTSD_PRED_THRESHOLD] = GENMASK(9, 6),
[DMAW_SCND_OUTSD_PRED_EN] = BIT(10),
[DMAW_MAX_BEATS_256_DIS] = BIT(11),
[PA_MASK_EN] = BIT(12),
[PREFETCH_ALMOST_EMPTY_SIZE_TX1] = GENMASK(16, 13),
/* Bit 17 reserved */
[SSPND_PA_NO_START_STATE] = BIT(18),
[SSPND_PA_NO_BQ_STATE] = BIT(19),
/* Bits 20-31 reserved */
};
IPA_REG_FIELDS(IPA_TX_CFG, ipa_tx_cfg, 0x000001fc);
static const u32 ipa_reg_flavor_0_fmask[] = {
[MAX_PIPES] = GENMASK(3, 0),
/* Bits 4-7 reserved */
[MAX_CONS_PIPES] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[MAX_PROD_PIPES] = GENMASK(20, 16),
/* Bits 21-23 reserved */
[PROD_LOWEST] = GENMASK(27, 24),
/* Bits 28-31 reserved */
};
IPA_REG_FIELDS(FLAVOR_0, flavor_0, 0x00000210);
static const u32 ipa_reg_idle_indication_cfg_fmask[] = {
[ENTER_IDLE_DEBOUNCE_THRESH] = GENMASK(15, 0),
[CONST_NON_IDLE_ENABLE] = BIT(16),
/* Bits 17-31 reserved */
};
IPA_REG_FIELDS(IDLE_INDICATION_CFG, idle_indication_cfg, 0x00000240);
static const u32 ipa_reg_src_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_01_RSRC_TYPE, src_rsrc_grp_01_rsrc_type,
0x00000400, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_23_RSRC_TYPE, src_rsrc_grp_23_rsrc_type,
0x00000404, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_01_RSRC_TYPE, dst_rsrc_grp_01_rsrc_type,
0x00000500, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_23_RSRC_TYPE, dst_rsrc_grp_23_rsrc_type,
0x00000504, 0x0020);
static const u32 ipa_reg_endp_init_cfg_fmask[] = {
[FRAG_OFFLOAD_EN] = BIT(0),
[CS_OFFLOAD_EN] = GENMASK(2, 1),
[CS_METADATA_HDR_OFFSET] = GENMASK(6, 3),
/* Bit 7 reserved */
[CS_GEN_QMB_MASTER_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CFG, endp_init_cfg, 0x00000808, 0x0070);
static const u32 ipa_reg_endp_init_nat_fmask[] = {
[NAT_EN] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_NAT, endp_init_nat, 0x0000080c, 0x0070);
static const u32 ipa_reg_endp_init_hdr_fmask[] = {
[HDR_LEN] = GENMASK(5, 0),
[HDR_OFST_METADATA_VALID] = BIT(6),
[HDR_OFST_METADATA] = GENMASK(12, 7),
[HDR_ADDITIONAL_CONST_LEN] = GENMASK(18, 13),
[HDR_OFST_PKT_SIZE_VALID] = BIT(19),
[HDR_OFST_PKT_SIZE] = GENMASK(25, 20),
[HDR_A5_MUX] = BIT(26),
[HDR_LEN_INC_DEAGG_HDR] = BIT(27),
[HDR_METADATA_REG_VALID] = BIT(28),
/* Bits 29-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR, endp_init_hdr, 0x00000810, 0x0070);
static const u32 ipa_reg_endp_init_hdr_ext_fmask[] = {
[HDR_ENDIANNESS] = BIT(0),
[HDR_TOTAL_LEN_OR_PAD_VALID] = BIT(1),
[HDR_TOTAL_LEN_OR_PAD] = BIT(2),
[HDR_PAYLOAD_LEN_INC_PADDING] = BIT(3),
[HDR_TOTAL_LEN_OR_PAD_OFFSET] = GENMASK(9, 4),
[HDR_PAD_TO_ALIGNMENT] = GENMASK(13, 10),
/* Bits 14-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR_EXT, endp_init_hdr_ext, 0x00000814, 0x0070);
IPA_REG_STRIDE(ENDP_INIT_HDR_METADATA_MASK, endp_init_hdr_metadata_mask,
0x00000818, 0x0070);
static const u32 ipa_reg_endp_init_mode_fmask[] = {
[ENDP_MODE] = GENMASK(2, 0),
/* Bit 3 reserved */
[DEST_PIPE_INDEX] = GENMASK(8, 4),
/* Bits 9-11 reserved */
[BYTE_THRESHOLD] = GENMASK(27, 12),
[PIPE_REPLICATION_EN] = BIT(28),
[PAD_EN] = BIT(29),
[HDR_FTCH_DISABLE] = BIT(30),
/* Bit 31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_MODE, endp_init_mode, 0x00000820, 0x0070);
static const u32 ipa_reg_endp_init_aggr_fmask[] = {
[AGGR_EN] = GENMASK(1, 0),
[AGGR_TYPE] = GENMASK(4, 2),
[BYTE_LIMIT] = GENMASK(9, 5),
[TIME_LIMIT] = GENMASK(14, 10),
[PKT_LIMIT] = GENMASK(20, 15),
[SW_EOF_ACTIVE] = BIT(21),
[FORCE_CLOSE] = BIT(22),
/* Bit 23 reserved */
[HARD_BYTE_LIMIT_EN] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_AGGR, endp_init_aggr, 0x00000824, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_en_fmask[] = {
[HOL_BLOCK_EN] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_EN, endp_init_hol_block_en,
0x0000082c, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_timer_fmask[] = {
[TIMER_BASE_VALUE] = GENMASK(4, 0),
/* Bits 5-7 reserved */
[TIMER_SCALE] = GENMASK(12, 8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_TIMER, endp_init_hol_block_timer,
0x00000830, 0x0070);
static const u32 ipa_reg_endp_init_deaggr_fmask[] = {
[DEAGGR_HDR_LEN] = GENMASK(5, 0),
[SYSPIPE_ERR_DETECTION] = BIT(6),
[PACKET_OFFSET_VALID] = BIT(7),
[PACKET_OFFSET_LOCATION] = GENMASK(13, 8),
[IGNORE_MIN_PKT_ERR] = BIT(14),
/* Bit 15 reserved */
[MAX_PACKET_LEN] = GENMASK(31, 16),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_DEAGGR, endp_init_deaggr, 0x00000834, 0x0070);
static const u32 ipa_reg_endp_init_rsrc_grp_fmask[] = {
[ENDP_RSRC_GRP] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_RSRC_GRP, endp_init_rsrc_grp,
0x00000838, 0x0070);
static const u32 ipa_reg_endp_init_seq_fmask[] = {
[SEQ_TYPE] = GENMASK(7, 0),
[SEQ_REP_TYPE] = GENMASK(15, 8),
/* Bits 16-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_SEQ, endp_init_seq, 0x0000083c, 0x0070);
static const u32 ipa_reg_endp_status_fmask[] = {
[STATUS_EN] = BIT(0),
[STATUS_ENDP] = GENMASK(5, 1),
/* Bits 6-7 reserved */
[STATUS_LOCATION] = BIT(8),
[STATUS_PKT_SUPPRESS] = BIT(9),
/* Bits 10-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_STATUS, endp_status, 0x00000840, 0x0070);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_STTS, ipa_irq_stts, 0x00003008 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_EN, ipa_irq_en, 0x0000300c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_CLR, ipa_irq_clr, 0x00003010 + 0x1000 * GSI_EE_AP);
static const u32 ipa_reg_ipa_irq_uc_fmask[] = {
[UC_INTR] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_FIELDS(IPA_IRQ_UC, ipa_irq_uc, 0x0000301c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_INFO, irq_suspend_info, 0x00003030 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_EN, irq_suspend_en, 0x00003034 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_CLR, irq_suspend_clr, 0x00003038 + 0x1000 * GSI_EE_AP);
static const struct ipa_reg *ipa_reg_array[] = {
[COMP_CFG] = &ipa_reg_comp_cfg,
[CLKON_CFG] = &ipa_reg_clkon_cfg,
[ROUTE] = &ipa_reg_route,
[SHARED_MEM_SIZE] = &ipa_reg_shared_mem_size,
[QSB_MAX_WRITES] = &ipa_reg_qsb_max_writes,
[QSB_MAX_READS] = &ipa_reg_qsb_max_reads,
[FILT_ROUT_HASH_EN] = &ipa_reg_filt_rout_hash_en,
[FILT_ROUT_HASH_FLUSH] = &ipa_reg_filt_rout_hash_flush,
[STATE_AGGR_ACTIVE] = &ipa_reg_state_aggr_active,
[IPA_BCR] = &ipa_reg_ipa_bcr,
[LOCAL_PKT_PROC_CNTXT] = &ipa_reg_local_pkt_proc_cntxt,
[AGGR_FORCE_CLOSE] = &ipa_reg_aggr_force_close,
[COUNTER_CFG] = &ipa_reg_counter_cfg,
[IPA_TX_CFG] = &ipa_reg_ipa_tx_cfg,
[FLAVOR_0] = &ipa_reg_flavor_0,
[IDLE_INDICATION_CFG] = &ipa_reg_idle_indication_cfg,
[SRC_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_01_rsrc_type,
[SRC_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_23_rsrc_type,
[DST_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_01_rsrc_type,
[DST_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_23_rsrc_type,
[ENDP_INIT_CFG] = &ipa_reg_endp_init_cfg,
[ENDP_INIT_NAT] = &ipa_reg_endp_init_nat,
[ENDP_INIT_HDR] = &ipa_reg_endp_init_hdr,
[ENDP_INIT_HDR_EXT] = &ipa_reg_endp_init_hdr_ext,
[ENDP_INIT_HDR_METADATA_MASK] = &ipa_reg_endp_init_hdr_metadata_mask,
[ENDP_INIT_MODE] = &ipa_reg_endp_init_mode,
[ENDP_INIT_AGGR] = &ipa_reg_endp_init_aggr,
[ENDP_INIT_HOL_BLOCK_EN] = &ipa_reg_endp_init_hol_block_en,
[ENDP_INIT_HOL_BLOCK_TIMER] = &ipa_reg_endp_init_hol_block_timer,
[ENDP_INIT_DEAGGR] = &ipa_reg_endp_init_deaggr,
[ENDP_INIT_RSRC_GRP] = &ipa_reg_endp_init_rsrc_grp,
[ENDP_INIT_SEQ] = &ipa_reg_endp_init_seq,
[ENDP_STATUS] = &ipa_reg_endp_status,
[IPA_IRQ_STTS] = &ipa_reg_ipa_irq_stts,
[IPA_IRQ_EN] = &ipa_reg_ipa_irq_en,
[IPA_IRQ_CLR] = &ipa_reg_ipa_irq_clr,
[IPA_IRQ_UC] = &ipa_reg_ipa_irq_uc,
[IRQ_SUSPEND_INFO] = &ipa_reg_irq_suspend_info,
[IRQ_SUSPEND_EN] = &ipa_reg_irq_suspend_en,
[IRQ_SUSPEND_CLR] = &ipa_reg_irq_suspend_clr,
};
const struct ipa_regs ipa_regs_v4_2 = {
.reg_count = ARRAY_SIZE(ipa_reg_array),
.reg = ipa_reg_array,
};
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022 Linaro Ltd. */
#include <linux/types.h>
#include "../ipa.h"
#include "../ipa_reg.h"
static const u32 ipa_reg_comp_cfg_fmask[] = {
/* Bit 0 reserved */
[GSI_SNOC_BYPASS_DIS] = BIT(1),
[GEN_QMB_0_SNOC_BYPASS_DIS] = BIT(2),
[GEN_QMB_1_SNOC_BYPASS_DIS] = BIT(3),
/* Bit 4 reserved */
[IPA_QMB_SELECT_CONS_EN] = BIT(5),
[IPA_QMB_SELECT_PROD_EN] = BIT(6),
[GSI_MULTI_INORDER_RD_DIS] = BIT(7),
[GSI_MULTI_INORDER_WR_DIS] = BIT(8),
[GEN_QMB_0_MULTI_INORDER_RD_DIS] = BIT(9),
[GEN_QMB_1_MULTI_INORDER_RD_DIS] = BIT(10),
[GEN_QMB_0_MULTI_INORDER_WR_DIS] = BIT(11),
[GEN_QMB_1_MULTI_INORDER_WR_DIS] = BIT(12),
[GEN_QMB_0_SNOC_CNOC_LOOP_PROT_DIS] = BIT(13),
[GSI_SNOC_CNOC_LOOP_PROT_DISABLE] = BIT(14),
[GSI_MULTI_AXI_MASTERS_DIS] = BIT(15),
[IPA_QMB_SELECT_GLOBAL_EN] = BIT(16),
[ATOMIC_FETCHER_ARB_LOCK_DIS] = GENMASK(20, 17),
[FULL_FLUSH_WAIT_RS_CLOSURE_EN] = BIT(21),
/* Bits 22-31 reserved */
};
IPA_REG_FIELDS(COMP_CFG, comp_cfg, 0x0000003c);
static const u32 ipa_reg_clkon_cfg_fmask[] = {
[CLKON_RX] = BIT(0),
[CLKON_PROC] = BIT(1),
[TX_WRAPPER] = BIT(2),
[CLKON_MISC] = BIT(3),
[RAM_ARB] = BIT(4),
[FTCH_HPS] = BIT(5),
[FTCH_DPS] = BIT(6),
[CLKON_HPS] = BIT(7),
[CLKON_DPS] = BIT(8),
[RX_HPS_CMDQS] = BIT(9),
[HPS_DPS_CMDQS] = BIT(10),
[DPS_TX_CMDQS] = BIT(11),
[RSRC_MNGR] = BIT(12),
[CTX_HANDLER] = BIT(13),
[ACK_MNGR] = BIT(14),
[D_DCPH] = BIT(15),
[H_DCPH] = BIT(16),
[CLKON_DCMP] = BIT(17),
[NTF_TX_CMDQS] = BIT(18),
[CLKON_TX_0] = BIT(19),
[CLKON_TX_1] = BIT(20),
[CLKON_FNR] = BIT(21),
[QSB2AXI_CMDQ_L] = BIT(22),
[AGGR_WRAPPER] = BIT(23),
[RAM_SLAVEWAY] = BIT(24),
[CLKON_QMB] = BIT(25),
[WEIGHT_ARB] = BIT(26),
[GSI_IF] = BIT(27),
[CLKON_GLOBAL] = BIT(28),
[GLOBAL_2X_CLK] = BIT(29),
[DPL_FIFO] = BIT(30),
/* Bit 31 reserved */
};
IPA_REG_FIELDS(CLKON_CFG, clkon_cfg, 0x00000044);
static const u32 ipa_reg_route_fmask[] = {
[ROUTE_DIS] = BIT(0),
[ROUTE_DEF_PIPE] = GENMASK(5, 1),
[ROUTE_DEF_HDR_TABLE] = BIT(6),
[ROUTE_DEF_HDR_OFST] = GENMASK(16, 7),
[ROUTE_FRAG_DEF_PIPE] = GENMASK(21, 17),
/* Bits 22-23 reserved */
[ROUTE_DEF_RETAIN_HDR] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_FIELDS(ROUTE, route, 0x00000048);
static const u32 ipa_reg_shared_mem_size_fmask[] = {
[MEM_SIZE] = GENMASK(15, 0),
[MEM_BADDR] = GENMASK(31, 16),
};
IPA_REG_FIELDS(SHARED_MEM_SIZE, shared_mem_size, 0x00000054);
static const u32 ipa_reg_qsb_max_writes_fmask[] = {
[GEN_QMB_0_MAX_WRITES] = GENMASK(3, 0),
[GEN_QMB_1_MAX_WRITES] = GENMASK(7, 4),
/* Bits 8-31 reserved */
};
IPA_REG_FIELDS(QSB_MAX_WRITES, qsb_max_writes, 0x00000074);
static const u32 ipa_reg_qsb_max_reads_fmask[] = {
[GEN_QMB_0_MAX_READS] = GENMASK(3, 0),
[GEN_QMB_1_MAX_READS] = GENMASK(7, 4),
/* Bits 8-15 reserved */
[GEN_QMB_0_MAX_READS_BEATS] = GENMASK(23, 16),
[GEN_QMB_1_MAX_READS_BEATS] = GENMASK(31, 24),
};
IPA_REG_FIELDS(QSB_MAX_READS, qsb_max_reads, 0x00000078);
static const u32 ipa_reg_filt_rout_hash_en_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_EN, filt_rout_hash_en, 0x0000148);
static const u32 ipa_reg_filt_rout_hash_flush_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_FLUSH, filt_rout_hash_flush, 0x000014c);
/* Valid bits defined by ipa->available */
IPA_REG(STATE_AGGR_ACTIVE, state_aggr_active, 0x000000b4);
static const u32 ipa_reg_local_pkt_proc_cntxt_fmask[] = {
[IPA_BASE_ADDR] = GENMASK(17, 0),
/* Bits 18-31 reserved */
};
/* Offset must be a multiple of 8 */
IPA_REG_FIELDS(LOCAL_PKT_PROC_CNTXT, local_pkt_proc_cntxt, 0x000001e8);
/* Valid bits defined by ipa->available */
IPA_REG(AGGR_FORCE_CLOSE, aggr_force_close, 0x000001ec);
static const u32 ipa_reg_ipa_tx_cfg_fmask[] = {
/* Bits 0-1 reserved */
[PREFETCH_ALMOST_EMPTY_SIZE_TX0] = GENMASK(5, 2),
[DMAW_SCND_OUTSD_PRED_THRESHOLD] = GENMASK(9, 6),
[DMAW_SCND_OUTSD_PRED_EN] = BIT(10),
[DMAW_MAX_BEATS_256_DIS] = BIT(11),
[PA_MASK_EN] = BIT(12),
[PREFETCH_ALMOST_EMPTY_SIZE_TX1] = GENMASK(16, 13),
[DUAL_TX_ENABLE] = BIT(17),
/* Bits 18-31 reserved */
};
IPA_REG_FIELDS(IPA_TX_CFG, ipa_tx_cfg, 0x000001fc);
static const u32 ipa_reg_flavor_0_fmask[] = {
[MAX_PIPES] = GENMASK(3, 0),
/* Bits 4-7 reserved */
[MAX_CONS_PIPES] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[MAX_PROD_PIPES] = GENMASK(20, 16),
/* Bits 21-23 reserved */
[PROD_LOWEST] = GENMASK(27, 24),
/* Bits 28-31 reserved */
};
IPA_REG_FIELDS(FLAVOR_0, flavor_0, 0x00000210);
static const u32 ipa_reg_idle_indication_cfg_fmask[] = {
[ENTER_IDLE_DEBOUNCE_THRESH] = GENMASK(15, 0),
[CONST_NON_IDLE_ENABLE] = BIT(16),
/* Bits 17-31 reserved */
};
IPA_REG_FIELDS(IDLE_INDICATION_CFG, idle_indication_cfg, 0x00000240);
static const u32 ipa_reg_qtime_timestamp_cfg_fmask[] = {
[DPL_TIMESTAMP_LSB] = GENMASK(4, 0),
/* Bits 5-6 reserved */
[DPL_TIMESTAMP_SEL] = BIT(7),
[TAG_TIMESTAMP_LSB] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[NAT_TIMESTAMP_LSB] = GENMASK(20, 16),
/* Bits 21-31 reserved */
};
IPA_REG_FIELDS(QTIME_TIMESTAMP_CFG, qtime_timestamp_cfg, 0x0000024c);
static const u32 ipa_reg_timers_xo_clk_div_cfg_fmask[] = {
[DIV_VALUE] = GENMASK(8, 0),
/* Bits 9-30 reserved */
[DIV_ENABLE] = BIT(31),
};
IPA_REG_FIELDS(TIMERS_XO_CLK_DIV_CFG, timers_xo_clk_div_cfg, 0x00000250);
static const u32 ipa_reg_timers_pulse_gran_cfg_fmask[] = {
[PULSE_GRAN_0] = GENMASK(2, 0),
[PULSE_GRAN_1] = GENMASK(5, 3),
[PULSE_GRAN_2] = GENMASK(8, 6),
};
IPA_REG_FIELDS(TIMERS_PULSE_GRAN_CFG, timers_pulse_gran_cfg, 0x00000254);
static const u32 ipa_reg_src_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_01_RSRC_TYPE, src_rsrc_grp_01_rsrc_type,
0x00000400, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_23_RSRC_TYPE, src_rsrc_grp_23_rsrc_type,
0x00000404, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_45_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_45_RSRC_TYPE, src_rsrc_grp_45_rsrc_type,
0x00000408, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_01_RSRC_TYPE, dst_rsrc_grp_01_rsrc_type,
0x00000500, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_23_RSRC_TYPE, dst_rsrc_grp_23_rsrc_type,
0x00000504, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_45_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_45_RSRC_TYPE, dst_rsrc_grp_45_rsrc_type,
0x00000508, 0x0020);
static const u32 ipa_reg_endp_init_cfg_fmask[] = {
[FRAG_OFFLOAD_EN] = BIT(0),
[CS_OFFLOAD_EN] = GENMASK(2, 1),
[CS_METADATA_HDR_OFFSET] = GENMASK(6, 3),
/* Bit 7 reserved */
[CS_GEN_QMB_MASTER_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CFG, endp_init_cfg, 0x00000808, 0x0070);
static const u32 ipa_reg_endp_init_nat_fmask[] = {
[NAT_EN] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_NAT, endp_init_nat, 0x0000080c, 0x0070);
static const u32 ipa_reg_endp_init_hdr_fmask[] = {
[HDR_LEN] = GENMASK(5, 0),
[HDR_OFST_METADATA_VALID] = BIT(6),
[HDR_OFST_METADATA] = GENMASK(12, 7),
[HDR_ADDITIONAL_CONST_LEN] = GENMASK(18, 13),
[HDR_OFST_PKT_SIZE_VALID] = BIT(19),
[HDR_OFST_PKT_SIZE] = GENMASK(25, 20),
[HDR_A5_MUX] = BIT(26),
[HDR_LEN_INC_DEAGG_HDR] = BIT(27),
[HDR_LEN_MSB] = GENMASK(29, 28),
[HDR_OFST_METADATA_MSB] = GENMASK(31, 30),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR, endp_init_hdr, 0x00000810, 0x0070);
static const u32 ipa_reg_endp_init_hdr_ext_fmask[] = {
[HDR_ENDIANNESS] = BIT(0),
[HDR_TOTAL_LEN_OR_PAD_VALID] = BIT(1),
[HDR_TOTAL_LEN_OR_PAD] = BIT(2),
[HDR_PAYLOAD_LEN_INC_PADDING] = BIT(3),
[HDR_TOTAL_LEN_OR_PAD_OFFSET] = GENMASK(9, 4),
[HDR_PAD_TO_ALIGNMENT] = GENMASK(13, 10),
/* Bits 14-15 reserved */
[HDR_TOTAL_LEN_OR_PAD_OFFSET_MSB] = GENMASK(17, 16),
[HDR_OFST_PKT_SIZE_MSB] = GENMASK(19, 18),
[HDR_ADDITIONAL_CONST_LEN_MSB] = GENMASK(21, 20),
/* Bits 22-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR_EXT, endp_init_hdr_ext, 0x00000814, 0x0070);
IPA_REG_STRIDE(ENDP_INIT_HDR_METADATA_MASK, endp_init_hdr_metadata_mask,
0x00000818, 0x0070);
static const u32 ipa_reg_endp_init_mode_fmask[] = {
[ENDP_MODE] = GENMASK(2, 0),
[DCPH_ENABLE] = BIT(3),
[DEST_PIPE_INDEX] = GENMASK(8, 4),
/* Bits 9-11 reserved */
[BYTE_THRESHOLD] = GENMASK(27, 12),
[PIPE_REPLICATION_EN] = BIT(28),
[PAD_EN] = BIT(29),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_MODE, endp_init_mode, 0x00000820, 0x0070);
static const u32 ipa_reg_endp_init_aggr_fmask[] = {
[AGGR_EN] = GENMASK(1, 0),
[AGGR_TYPE] = GENMASK(4, 2),
[BYTE_LIMIT] = GENMASK(10, 5),
/* Bit 11 reserved */
[TIME_LIMIT] = GENMASK(16, 12),
[PKT_LIMIT] = GENMASK(22, 17),
[SW_EOF_ACTIVE] = BIT(23),
[FORCE_CLOSE] = BIT(24),
/* Bit 25 reserved */
[HARD_BYTE_LIMIT_EN] = BIT(26),
[AGGR_GRAN_SEL] = BIT(27),
/* Bits 28-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_AGGR, endp_init_aggr, 0x00000824, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_en_fmask[] = {
[HOL_BLOCK_EN] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_EN, endp_init_hol_block_en,
0x0000082c, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_timer_fmask[] = {
[TIMER_LIMIT] = GENMASK(4, 0),
/* Bits 5-7 reserved */
[TIMER_GRAN_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_TIMER, endp_init_hol_block_timer,
0x00000830, 0x0070);
static const u32 ipa_reg_endp_init_deaggr_fmask[] = {
[DEAGGR_HDR_LEN] = GENMASK(5, 0),
[SYSPIPE_ERR_DETECTION] = BIT(6),
[PACKET_OFFSET_VALID] = BIT(7),
[PACKET_OFFSET_LOCATION] = GENMASK(13, 8),
[IGNORE_MIN_PKT_ERR] = BIT(14),
/* Bit 15 reserved */
[MAX_PACKET_LEN] = GENMASK(31, 16),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_DEAGGR, endp_init_deaggr, 0x00000834, 0x0070);
static const u32 ipa_reg_endp_init_rsrc_grp_fmask[] = {
[ENDP_RSRC_GRP] = GENMASK(2, 0),
/* Bits 3-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_RSRC_GRP, endp_init_rsrc_grp,
0x00000838, 0x0070);
static const u32 ipa_reg_endp_init_seq_fmask[] = {
[SEQ_TYPE] = GENMASK(7, 0),
/* Bits 8-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_SEQ, endp_init_seq, 0x0000083c, 0x0070);
static const u32 ipa_reg_endp_status_fmask[] = {
[STATUS_EN] = BIT(0),
[STATUS_ENDP] = GENMASK(5, 1),
/* Bits 6-8 reserved */
[STATUS_PKT_SUPPRESS] = BIT(9),
/* Bits 10-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_STATUS, endp_status, 0x00000840, 0x0070);
static const u32 ipa_reg_endp_filter_router_hsh_cfg_fmask[] = {
[FILTER_HASH_MSK_SRC_ID] = BIT(0),
[FILTER_HASH_MSK_SRC_IP] = BIT(1),
[FILTER_HASH_MSK_DST_IP] = BIT(2),
[FILTER_HASH_MSK_SRC_PORT] = BIT(3),
[FILTER_HASH_MSK_DST_PORT] = BIT(4),
[FILTER_HASH_MSK_PROTOCOL] = BIT(5),
[FILTER_HASH_MSK_METADATA] = BIT(6),
[FILTER_HASH_MSK_ALL] = GENMASK(6, 0),
/* Bits 7-15 reserved */
[ROUTER_HASH_MSK_SRC_ID] = BIT(16),
[ROUTER_HASH_MSK_SRC_IP] = BIT(17),
[ROUTER_HASH_MSK_DST_IP] = BIT(18),
[ROUTER_HASH_MSK_SRC_PORT] = BIT(19),
[ROUTER_HASH_MSK_DST_PORT] = BIT(20),
[ROUTER_HASH_MSK_PROTOCOL] = BIT(21),
[ROUTER_HASH_MSK_METADATA] = BIT(22),
[ROUTER_HASH_MSK_ALL] = GENMASK(22, 16),
/* Bits 23-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_FILTER_ROUTER_HSH_CFG, endp_filter_router_hsh_cfg,
0x0000085c, 0x0070);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_STTS, ipa_irq_stts, 0x00003008 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_EN, ipa_irq_en, 0x0000300c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_CLR, ipa_irq_clr, 0x00003010 + 0x1000 * GSI_EE_AP);
static const u32 ipa_reg_ipa_irq_uc_fmask[] = {
[UC_INTR] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_FIELDS(IPA_IRQ_UC, ipa_irq_uc, 0x0000301c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_INFO, irq_suspend_info, 0x00003030 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_EN, irq_suspend_en, 0x00003034 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_CLR, irq_suspend_clr, 0x00003038 + 0x1000 * GSI_EE_AP);
static const struct ipa_reg *ipa_reg_array[] = {
[COMP_CFG] = &ipa_reg_comp_cfg,
[CLKON_CFG] = &ipa_reg_clkon_cfg,
[ROUTE] = &ipa_reg_route,
[SHARED_MEM_SIZE] = &ipa_reg_shared_mem_size,
[QSB_MAX_WRITES] = &ipa_reg_qsb_max_writes,
[QSB_MAX_READS] = &ipa_reg_qsb_max_reads,
[FILT_ROUT_HASH_EN] = &ipa_reg_filt_rout_hash_en,
[FILT_ROUT_HASH_FLUSH] = &ipa_reg_filt_rout_hash_flush,
[STATE_AGGR_ACTIVE] = &ipa_reg_state_aggr_active,
[LOCAL_PKT_PROC_CNTXT] = &ipa_reg_local_pkt_proc_cntxt,
[AGGR_FORCE_CLOSE] = &ipa_reg_aggr_force_close,
[IPA_TX_CFG] = &ipa_reg_ipa_tx_cfg,
[FLAVOR_0] = &ipa_reg_flavor_0,
[IDLE_INDICATION_CFG] = &ipa_reg_idle_indication_cfg,
[QTIME_TIMESTAMP_CFG] = &ipa_reg_qtime_timestamp_cfg,
[TIMERS_XO_CLK_DIV_CFG] = &ipa_reg_timers_xo_clk_div_cfg,
[TIMERS_PULSE_GRAN_CFG] = &ipa_reg_timers_pulse_gran_cfg,
[SRC_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_01_rsrc_type,
[SRC_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_23_rsrc_type,
[SRC_RSRC_GRP_45_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_45_rsrc_type,
[DST_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_01_rsrc_type,
[DST_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_23_rsrc_type,
[DST_RSRC_GRP_45_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_45_rsrc_type,
[ENDP_INIT_CFG] = &ipa_reg_endp_init_cfg,
[ENDP_INIT_NAT] = &ipa_reg_endp_init_nat,
[ENDP_INIT_HDR] = &ipa_reg_endp_init_hdr,
[ENDP_INIT_HDR_EXT] = &ipa_reg_endp_init_hdr_ext,
[ENDP_INIT_HDR_METADATA_MASK] = &ipa_reg_endp_init_hdr_metadata_mask,
[ENDP_INIT_MODE] = &ipa_reg_endp_init_mode,
[ENDP_INIT_AGGR] = &ipa_reg_endp_init_aggr,
[ENDP_INIT_HOL_BLOCK_EN] = &ipa_reg_endp_init_hol_block_en,
[ENDP_INIT_HOL_BLOCK_TIMER] = &ipa_reg_endp_init_hol_block_timer,
[ENDP_INIT_DEAGGR] = &ipa_reg_endp_init_deaggr,
[ENDP_INIT_RSRC_GRP] = &ipa_reg_endp_init_rsrc_grp,
[ENDP_INIT_SEQ] = &ipa_reg_endp_init_seq,
[ENDP_STATUS] = &ipa_reg_endp_status,
[ENDP_FILTER_ROUTER_HSH_CFG] = &ipa_reg_endp_filter_router_hsh_cfg,
[IPA_IRQ_STTS] = &ipa_reg_ipa_irq_stts,
[IPA_IRQ_EN] = &ipa_reg_ipa_irq_en,
[IPA_IRQ_CLR] = &ipa_reg_ipa_irq_clr,
[IPA_IRQ_UC] = &ipa_reg_ipa_irq_uc,
[IRQ_SUSPEND_INFO] = &ipa_reg_irq_suspend_info,
[IRQ_SUSPEND_EN] = &ipa_reg_irq_suspend_en,
[IRQ_SUSPEND_CLR] = &ipa_reg_irq_suspend_clr,
};
const struct ipa_regs ipa_regs_v4_5 = {
.reg_count = ARRAY_SIZE(ipa_reg_array),
.reg = ipa_reg_array,
};
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022 Linaro Ltd. */
#include <linux/types.h>
#include "../ipa.h"
#include "../ipa_reg.h"
static const u32 ipa_reg_comp_cfg_fmask[] = {
[RAM_ARB_PRI_CLIENT_SAMP_FIX_DIS] = BIT(0),
[GSI_SNOC_BYPASS_DIS] = BIT(1),
[GEN_QMB_0_SNOC_BYPASS_DIS] = BIT(2),
[GEN_QMB_1_SNOC_BYPASS_DIS] = BIT(3),
/* Bit 4 reserved */
[IPA_QMB_SELECT_CONS_EN] = BIT(5),
[IPA_QMB_SELECT_PROD_EN] = BIT(6),
[GSI_MULTI_INORDER_RD_DIS] = BIT(7),
[GSI_MULTI_INORDER_WR_DIS] = BIT(8),
[GEN_QMB_0_MULTI_INORDER_RD_DIS] = BIT(9),
[GEN_QMB_1_MULTI_INORDER_RD_DIS] = BIT(10),
[GEN_QMB_0_MULTI_INORDER_WR_DIS] = BIT(11),
[GEN_QMB_1_MULTI_INORDER_WR_DIS] = BIT(12),
[GEN_QMB_0_SNOC_CNOC_LOOP_PROT_DIS] = BIT(13),
[GSI_SNOC_CNOC_LOOP_PROT_DISABLE] = BIT(14),
[GSI_MULTI_AXI_MASTERS_DIS] = BIT(15),
[IPA_QMB_SELECT_GLOBAL_EN] = BIT(16),
[FULL_FLUSH_WAIT_RS_CLOSURE_EN] = BIT(17),
[QMB_RAM_RD_CACHE_DISABLE] = BIT(19),
[GENQMB_AOOOWR] = BIT(20),
[IF_OUT_OF_BUF_STOP_RESET_MASK_EN] = BIT(21),
[ATOMIC_FETCHER_ARB_LOCK_DIS] = GENMASK(24, 22),
/* Bits 25-29 reserved */
[GEN_QMB_1_DYNAMIC_ASIZE] = BIT(30),
[GEN_QMB_0_DYNAMIC_ASIZE] = BIT(31),
};
IPA_REG_FIELDS(COMP_CFG, comp_cfg, 0x0000003c);
static const u32 ipa_reg_clkon_cfg_fmask[] = {
[CLKON_RX] = BIT(0),
[CLKON_PROC] = BIT(1),
[TX_WRAPPER] = BIT(2),
[CLKON_MISC] = BIT(3),
[RAM_ARB] = BIT(4),
[FTCH_HPS] = BIT(5),
[FTCH_DPS] = BIT(6),
[CLKON_HPS] = BIT(7),
[CLKON_DPS] = BIT(8),
[RX_HPS_CMDQS] = BIT(9),
[HPS_DPS_CMDQS] = BIT(10),
[DPS_TX_CMDQS] = BIT(11),
[RSRC_MNGR] = BIT(12),
[CTX_HANDLER] = BIT(13),
[ACK_MNGR] = BIT(14),
[D_DCPH] = BIT(15),
[H_DCPH] = BIT(16),
[CLKON_DCMP] = BIT(17),
[NTF_TX_CMDQS] = BIT(18),
[CLKON_TX_0] = BIT(19),
[CLKON_TX_1] = BIT(20),
[CLKON_FNR] = BIT(21),
[QSB2AXI_CMDQ_L] = BIT(22),
[AGGR_WRAPPER] = BIT(23),
[RAM_SLAVEWAY] = BIT(24),
[CLKON_QMB] = BIT(25),
[WEIGHT_ARB] = BIT(26),
[GSI_IF] = BIT(27),
[CLKON_GLOBAL] = BIT(28),
[GLOBAL_2X_CLK] = BIT(29),
[DPL_FIFO] = BIT(30),
[DRBIP] = BIT(31),
};
IPA_REG_FIELDS(CLKON_CFG, clkon_cfg, 0x00000044);
static const u32 ipa_reg_route_fmask[] = {
[ROUTE_DIS] = BIT(0),
[ROUTE_DEF_PIPE] = GENMASK(5, 1),
[ROUTE_DEF_HDR_TABLE] = BIT(6),
[ROUTE_DEF_HDR_OFST] = GENMASK(16, 7),
[ROUTE_FRAG_DEF_PIPE] = GENMASK(21, 17),
/* Bits 22-23 reserved */
[ROUTE_DEF_RETAIN_HDR] = BIT(24),
/* Bits 25-31 reserved */
};
IPA_REG_FIELDS(ROUTE, route, 0x00000048);
static const u32 ipa_reg_shared_mem_size_fmask[] = {
[MEM_SIZE] = GENMASK(15, 0),
[MEM_BADDR] = GENMASK(31, 16),
};
IPA_REG_FIELDS(SHARED_MEM_SIZE, shared_mem_size, 0x00000054);
static const u32 ipa_reg_qsb_max_writes_fmask[] = {
[GEN_QMB_0_MAX_WRITES] = GENMASK(3, 0),
[GEN_QMB_1_MAX_WRITES] = GENMASK(7, 4),
/* Bits 8-31 reserved */
};
IPA_REG_FIELDS(QSB_MAX_WRITES, qsb_max_writes, 0x00000074);
static const u32 ipa_reg_qsb_max_reads_fmask[] = {
[GEN_QMB_0_MAX_READS] = GENMASK(3, 0),
[GEN_QMB_1_MAX_READS] = GENMASK(7, 4),
/* Bits 8-15 reserved */
[GEN_QMB_0_MAX_READS_BEATS] = GENMASK(23, 16),
[GEN_QMB_1_MAX_READS_BEATS] = GENMASK(31, 24),
};
IPA_REG_FIELDS(QSB_MAX_READS, qsb_max_reads, 0x00000078);
static const u32 ipa_reg_filt_rout_hash_en_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_EN, filt_rout_hash_en, 0x0000148);
static const u32 ipa_reg_filt_rout_hash_flush_fmask[] = {
[IPV6_ROUTER_HASH] = BIT(0),
/* Bits 1-3 reserved */
[IPV6_FILTER_HASH] = BIT(4),
/* Bits 5-7 reserved */
[IPV4_ROUTER_HASH] = BIT(8),
/* Bits 9-11 reserved */
[IPV4_FILTER_HASH] = BIT(12),
/* Bits 13-31 reserved */
};
IPA_REG_FIELDS(FILT_ROUT_HASH_FLUSH, filt_rout_hash_flush, 0x000014c);
/* Valid bits defined by ipa->available */
IPA_REG(STATE_AGGR_ACTIVE, state_aggr_active, 0x000000b4);
static const u32 ipa_reg_local_pkt_proc_cntxt_fmask[] = {
[IPA_BASE_ADDR] = GENMASK(17, 0),
/* Bits 18-31 reserved */
};
/* Offset must be a multiple of 8 */
IPA_REG_FIELDS(LOCAL_PKT_PROC_CNTXT, local_pkt_proc_cntxt, 0x000001e8);
/* Valid bits defined by ipa->available */
IPA_REG(AGGR_FORCE_CLOSE, aggr_force_close, 0x000001ec);
static const u32 ipa_reg_ipa_tx_cfg_fmask[] = {
/* Bits 0-1 reserved */
[PREFETCH_ALMOST_EMPTY_SIZE_TX0] = GENMASK(5, 2),
[DMAW_SCND_OUTSD_PRED_THRESHOLD] = GENMASK(9, 6),
[DMAW_SCND_OUTSD_PRED_EN] = BIT(10),
[DMAW_MAX_BEATS_256_DIS] = BIT(11),
[PA_MASK_EN] = BIT(12),
[PREFETCH_ALMOST_EMPTY_SIZE_TX1] = GENMASK(16, 13),
[DUAL_TX_ENABLE] = BIT(17),
[SSPND_PA_NO_START_STATE] = BIT(18),
/* Bits 19-31 reserved */
};
IPA_REG_FIELDS(IPA_TX_CFG, ipa_tx_cfg, 0x000001fc);
static const u32 ipa_reg_flavor_0_fmask[] = {
[MAX_PIPES] = GENMASK(3, 0),
/* Bits 4-7 reserved */
[MAX_CONS_PIPES] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[MAX_PROD_PIPES] = GENMASK(20, 16),
/* Bits 21-23 reserved */
[PROD_LOWEST] = GENMASK(27, 24),
/* Bits 28-31 reserved */
};
IPA_REG_FIELDS(FLAVOR_0, flavor_0, 0x00000210);
static const u32 ipa_reg_idle_indication_cfg_fmask[] = {
[ENTER_IDLE_DEBOUNCE_THRESH] = GENMASK(15, 0),
[CONST_NON_IDLE_ENABLE] = BIT(16),
/* Bits 17-31 reserved */
};
IPA_REG_FIELDS(IDLE_INDICATION_CFG, idle_indication_cfg, 0x00000240);
static const u32 ipa_reg_qtime_timestamp_cfg_fmask[] = {
[DPL_TIMESTAMP_LSB] = GENMASK(4, 0),
/* Bits 5-6 reserved */
[DPL_TIMESTAMP_SEL] = BIT(7),
[TAG_TIMESTAMP_LSB] = GENMASK(12, 8),
/* Bits 13-15 reserved */
[NAT_TIMESTAMP_LSB] = GENMASK(20, 16),
/* Bits 21-31 reserved */
};
IPA_REG_FIELDS(QTIME_TIMESTAMP_CFG, qtime_timestamp_cfg, 0x0000024c);
static const u32 ipa_reg_timers_xo_clk_div_cfg_fmask[] = {
[DIV_VALUE] = GENMASK(8, 0),
/* Bits 9-30 reserved */
[DIV_ENABLE] = BIT(31),
};
IPA_REG_FIELDS(TIMERS_XO_CLK_DIV_CFG, timers_xo_clk_div_cfg, 0x00000250);
static const u32 ipa_reg_timers_pulse_gran_cfg_fmask[] = {
[PULSE_GRAN_0] = GENMASK(2, 0),
[PULSE_GRAN_1] = GENMASK(5, 3),
[PULSE_GRAN_2] = GENMASK(8, 6),
};
IPA_REG_FIELDS(TIMERS_PULSE_GRAN_CFG, timers_pulse_gran_cfg, 0x00000254);
static const u32 ipa_reg_src_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_01_RSRC_TYPE, src_rsrc_grp_01_rsrc_type,
0x00000400, 0x0020);
static const u32 ipa_reg_src_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_23_RSRC_TYPE, src_rsrc_grp_23_rsrc_type,
0x00000404, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_01_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_01_RSRC_TYPE, dst_rsrc_grp_01_rsrc_type,
0x00000500, 0x0020);
static const u32 ipa_reg_dst_rsrc_grp_23_rsrc_type_fmask[] = {
[X_MIN_LIM] = GENMASK(5, 0),
/* Bits 6-7 reserved */
[X_MAX_LIM] = GENMASK(13, 8),
/* Bits 14-15 reserved */
[Y_MIN_LIM] = GENMASK(21, 16),
/* Bits 22-23 reserved */
[Y_MAX_LIM] = GENMASK(29, 24),
/* Bits 30-31 reserved */
};
IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_23_RSRC_TYPE, dst_rsrc_grp_23_rsrc_type,
0x00000504, 0x0020);
static const u32 ipa_reg_endp_init_cfg_fmask[] = {
[FRAG_OFFLOAD_EN] = BIT(0),
[CS_OFFLOAD_EN] = GENMASK(2, 1),
[CS_METADATA_HDR_OFFSET] = GENMASK(6, 3),
/* Bit 7 reserved */
[CS_GEN_QMB_MASTER_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_CFG, endp_init_cfg, 0x00000808, 0x0070);
static const u32 ipa_reg_endp_init_nat_fmask[] = {
[NAT_EN] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_NAT, endp_init_nat, 0x0000080c, 0x0070);
static const u32 ipa_reg_endp_init_hdr_fmask[] = {
[HDR_LEN] = GENMASK(5, 0),
[HDR_OFST_METADATA_VALID] = BIT(6),
[HDR_OFST_METADATA] = GENMASK(12, 7),
[HDR_ADDITIONAL_CONST_LEN] = GENMASK(18, 13),
[HDR_OFST_PKT_SIZE_VALID] = BIT(19),
[HDR_OFST_PKT_SIZE] = GENMASK(25, 20),
[HDR_LEN_INC_DEAGG_HDR] = BIT(27),
[HDR_LEN_MSB] = GENMASK(29, 28),
[HDR_OFST_METADATA_MSB] = GENMASK(31, 30),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR, endp_init_hdr, 0x00000810, 0x0070);
static const u32 ipa_reg_endp_init_hdr_ext_fmask[] = {
[HDR_ENDIANNESS] = BIT(0),
[HDR_TOTAL_LEN_OR_PAD_VALID] = BIT(1),
[HDR_TOTAL_LEN_OR_PAD] = BIT(2),
[HDR_PAYLOAD_LEN_INC_PADDING] = BIT(3),
[HDR_TOTAL_LEN_OR_PAD_OFFSET] = GENMASK(9, 4),
[HDR_PAD_TO_ALIGNMENT] = GENMASK(13, 10),
/* Bits 14-15 reserved */
[HDR_TOTAL_LEN_OR_PAD_OFFSET_MSB] = GENMASK(17, 16),
[HDR_OFST_PKT_SIZE_MSB] = GENMASK(19, 18),
[HDR_ADDITIONAL_CONST_LEN_MSB] = GENMASK(21, 20),
/* Bits 22-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HDR_EXT, endp_init_hdr_ext, 0x00000814, 0x0070);
IPA_REG_STRIDE(ENDP_INIT_HDR_METADATA_MASK, endp_init_hdr_metadata_mask,
0x00000818, 0x0070);
static const u32 ipa_reg_endp_init_mode_fmask[] = {
[ENDP_MODE] = GENMASK(2, 0),
[DCPH_ENABLE] = BIT(3),
[DEST_PIPE_INDEX] = GENMASK(8, 4),
/* Bits 9-11 reserved */
[BYTE_THRESHOLD] = GENMASK(27, 12),
[PIPE_REPLICATION_EN] = BIT(28),
[PAD_EN] = BIT(29),
[DRBIP_ACL_ENABLE] = BIT(30),
/* Bit 31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_MODE, endp_init_mode, 0x00000820, 0x0070);
static const u32 ipa_reg_endp_init_aggr_fmask[] = {
[AGGR_EN] = GENMASK(1, 0),
[AGGR_TYPE] = GENMASK(4, 2),
[BYTE_LIMIT] = GENMASK(10, 5),
/* Bit 11 reserved */
[TIME_LIMIT] = GENMASK(16, 12),
[PKT_LIMIT] = GENMASK(22, 17),
[SW_EOF_ACTIVE] = BIT(23),
[FORCE_CLOSE] = BIT(24),
/* Bit 25 reserved */
[HARD_BYTE_LIMIT_EN] = BIT(26),
[AGGR_GRAN_SEL] = BIT(27),
/* Bits 28-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_AGGR, endp_init_aggr, 0x00000824, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_en_fmask[] = {
[HOL_BLOCK_EN] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_EN, endp_init_hol_block_en,
0x0000082c, 0x0070);
static const u32 ipa_reg_endp_init_hol_block_timer_fmask[] = {
[TIMER_LIMIT] = GENMASK(4, 0),
/* Bits 5-7 reserved */
[TIMER_GRAN_SEL] = BIT(8),
/* Bits 9-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_HOL_BLOCK_TIMER, endp_init_hol_block_timer,
0x00000830, 0x0070);
static const u32 ipa_reg_endp_init_deaggr_fmask[] = {
[DEAGGR_HDR_LEN] = GENMASK(5, 0),
[SYSPIPE_ERR_DETECTION] = BIT(6),
[PACKET_OFFSET_VALID] = BIT(7),
[PACKET_OFFSET_LOCATION] = GENMASK(13, 8),
[IGNORE_MIN_PKT_ERR] = BIT(14),
/* Bit 15 reserved */
[MAX_PACKET_LEN] = GENMASK(31, 16),
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_DEAGGR, endp_init_deaggr, 0x00000834, 0x0070);
static const u32 ipa_reg_endp_init_rsrc_grp_fmask[] = {
[ENDP_RSRC_GRP] = GENMASK(1, 0),
/* Bits 2-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_RSRC_GRP, endp_init_rsrc_grp,
0x00000838, 0x0070);
static const u32 ipa_reg_endp_init_seq_fmask[] = {
[SEQ_TYPE] = GENMASK(7, 0),
/* Bits 8-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_INIT_SEQ, endp_init_seq, 0x0000083c, 0x0070);
static const u32 ipa_reg_endp_status_fmask[] = {
[STATUS_EN] = BIT(0),
[STATUS_ENDP] = GENMASK(5, 1),
/* Bits 6-8 reserved */
[STATUS_PKT_SUPPRESS] = BIT(9),
/* Bits 10-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_STATUS, endp_status, 0x00000840, 0x0070);
static const u32 ipa_reg_endp_filter_router_hsh_cfg_fmask[] = {
[FILTER_HASH_MSK_SRC_ID] = BIT(0),
[FILTER_HASH_MSK_SRC_IP] = BIT(1),
[FILTER_HASH_MSK_DST_IP] = BIT(2),
[FILTER_HASH_MSK_SRC_PORT] = BIT(3),
[FILTER_HASH_MSK_DST_PORT] = BIT(4),
[FILTER_HASH_MSK_PROTOCOL] = BIT(5),
[FILTER_HASH_MSK_METADATA] = BIT(6),
[FILTER_HASH_MSK_ALL] = GENMASK(6, 0),
/* Bits 7-15 reserved */
[ROUTER_HASH_MSK_SRC_ID] = BIT(16),
[ROUTER_HASH_MSK_SRC_IP] = BIT(17),
[ROUTER_HASH_MSK_DST_IP] = BIT(18),
[ROUTER_HASH_MSK_SRC_PORT] = BIT(19),
[ROUTER_HASH_MSK_DST_PORT] = BIT(20),
[ROUTER_HASH_MSK_PROTOCOL] = BIT(21),
[ROUTER_HASH_MSK_METADATA] = BIT(22),
[ROUTER_HASH_MSK_ALL] = GENMASK(22, 16),
/* Bits 23-31 reserved */
};
IPA_REG_STRIDE_FIELDS(ENDP_FILTER_ROUTER_HSH_CFG, endp_filter_router_hsh_cfg,
0x0000085c, 0x0070);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_STTS, ipa_irq_stts, 0x00004008 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_EN, ipa_irq_en, 0x0000400c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by enum ipa_irq_id; only used for GSI_EE_AP */
IPA_REG(IPA_IRQ_CLR, ipa_irq_clr, 0x00004010 + 0x1000 * GSI_EE_AP);
static const u32 ipa_reg_ipa_irq_uc_fmask[] = {
[UC_INTR] = BIT(0),
/* Bits 1-31 reserved */
};
IPA_REG_FIELDS(IPA_IRQ_UC, ipa_irq_uc, 0x0000401c + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_INFO, irq_suspend_info, 0x00004030 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_EN, irq_suspend_en, 0x00004034 + 0x1000 * GSI_EE_AP);
/* Valid bits defined by ipa->available */
IPA_REG(IRQ_SUSPEND_CLR, irq_suspend_clr, 0x00004038 + 0x1000 * GSI_EE_AP);
static const struct ipa_reg *ipa_reg_array[] = {
[COMP_CFG] = &ipa_reg_comp_cfg,
[CLKON_CFG] = &ipa_reg_clkon_cfg,
[ROUTE] = &ipa_reg_route,
[SHARED_MEM_SIZE] = &ipa_reg_shared_mem_size,
[QSB_MAX_WRITES] = &ipa_reg_qsb_max_writes,
[QSB_MAX_READS] = &ipa_reg_qsb_max_reads,
[FILT_ROUT_HASH_EN] = &ipa_reg_filt_rout_hash_en,
[FILT_ROUT_HASH_FLUSH] = &ipa_reg_filt_rout_hash_flush,
[STATE_AGGR_ACTIVE] = &ipa_reg_state_aggr_active,
[LOCAL_PKT_PROC_CNTXT] = &ipa_reg_local_pkt_proc_cntxt,
[AGGR_FORCE_CLOSE] = &ipa_reg_aggr_force_close,
[IPA_TX_CFG] = &ipa_reg_ipa_tx_cfg,
[FLAVOR_0] = &ipa_reg_flavor_0,
[IDLE_INDICATION_CFG] = &ipa_reg_idle_indication_cfg,
[QTIME_TIMESTAMP_CFG] = &ipa_reg_qtime_timestamp_cfg,
[TIMERS_XO_CLK_DIV_CFG] = &ipa_reg_timers_xo_clk_div_cfg,
[TIMERS_PULSE_GRAN_CFG] = &ipa_reg_timers_pulse_gran_cfg,
[SRC_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_01_rsrc_type,
[SRC_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_src_rsrc_grp_23_rsrc_type,
[DST_RSRC_GRP_01_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_01_rsrc_type,
[DST_RSRC_GRP_23_RSRC_TYPE] = &ipa_reg_dst_rsrc_grp_23_rsrc_type,
[ENDP_INIT_CFG] = &ipa_reg_endp_init_cfg,
[ENDP_INIT_NAT] = &ipa_reg_endp_init_nat,
[ENDP_INIT_HDR] = &ipa_reg_endp_init_hdr,
[ENDP_INIT_HDR_EXT] = &ipa_reg_endp_init_hdr_ext,
[ENDP_INIT_HDR_METADATA_MASK] = &ipa_reg_endp_init_hdr_metadata_mask,
[ENDP_INIT_MODE] = &ipa_reg_endp_init_mode,
[ENDP_INIT_AGGR] = &ipa_reg_endp_init_aggr,
[ENDP_INIT_HOL_BLOCK_EN] = &ipa_reg_endp_init_hol_block_en,
[ENDP_INIT_HOL_BLOCK_TIMER] = &ipa_reg_endp_init_hol_block_timer,
[ENDP_INIT_DEAGGR] = &ipa_reg_endp_init_deaggr,
[ENDP_INIT_RSRC_GRP] = &ipa_reg_endp_init_rsrc_grp,
[ENDP_INIT_SEQ] = &ipa_reg_endp_init_seq,
[ENDP_STATUS] = &ipa_reg_endp_status,
[ENDP_FILTER_ROUTER_HSH_CFG] = &ipa_reg_endp_filter_router_hsh_cfg,
[IPA_IRQ_STTS] = &ipa_reg_ipa_irq_stts,
[IPA_IRQ_EN] = &ipa_reg_ipa_irq_en,
[IPA_IRQ_CLR] = &ipa_reg_ipa_irq_clr,
[IPA_IRQ_UC] = &ipa_reg_ipa_irq_uc,
[IRQ_SUSPEND_INFO] = &ipa_reg_irq_suspend_info,
[IRQ_SUSPEND_EN] = &ipa_reg_irq_suspend_en,
[IRQ_SUSPEND_CLR] = &ipa_reg_irq_suspend_clr,
};
const struct ipa_regs ipa_regs_v4_9 = {
.reg_count = ARRAY_SIZE(ipa_reg_array),
.reg = ipa_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