Commit 56193cf9 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-ipa-define-gsi-register-fields-differently'

Alex Elder says:

====================
net: ipa: define GSI register fields differently

Now that we have "reg" definitions in place to define GSI register
offsets, add the definitions for the fields of GSI registers that
have them.

There aren't many differences between versions, but a few fields are
present only in some versions of IPA, so additional "gsi_reg-vX.Y.c"
files are created to capture such differences.  As in the previous
series, these files are created as near-copies of existing files
just before they're needed to represent these differences.  The
first patch adds files for IPA v4.0, v4.5, and v4.9; the fifth patch
adds a file for IPA v4.11.

Note that the first and fifth patch cause some checkpatch warnings
because they align some continued lines with an open parenthesis
that at the fourth column.
====================

Link: https://lore.kernel.org/r/20230213162229.604438-1-elder@linaro.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2edd9257 3f3741c9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
IPA_VERSIONS		:=	3.1 3.5.1 4.2 4.5 4.7 4.9 4.11

# Some IPA versions can reuse another set of GSI register definitions.
GSI_IPA_VERSIONS	:=	3.1 3.5.1
GSI_IPA_VERSIONS	:=	3.1 3.5.1 4.0 4.5 4.9 4.11

obj-$(CONFIG_QCOM_IPA)	+=	ipa.o

+49 −61
Original line number Diff line number Diff line
@@ -163,12 +163,6 @@ static void gsi_validate_build(void)
	 * ensure the elements themselves meet the requirement.
	 */
	BUILD_BUG_ON(!is_power_of_2(GSI_RING_ELEMENT_SIZE));

	/* The channel element size must fit in this field */
	BUILD_BUG_ON(GSI_RING_ELEMENT_SIZE > field_max(ELEMENT_SIZE_FMASK));

	/* The event ring element size must fit in this field */
	BUILD_BUG_ON(GSI_RING_ELEMENT_SIZE > field_max(EV_ELEMENT_SIZE_FMASK));
}

/* Return the channel id associated with a given channel */
@@ -185,26 +179,18 @@ static bool gsi_channel_initialized(struct gsi_channel *channel)

/* Encode the channel protocol for the CH_C_CNTXT_0 register */
static u32 ch_c_cntxt_0_type_encode(enum ipa_version version,
				    const struct reg *reg,
				    enum gsi_channel_type type)
{
	u32 val;

	val = u32_encode_bits(type, CHTYPE_PROTOCOL_FMASK);
	val = reg_encode(reg, CHTYPE_PROTOCOL, type);
	if (version < IPA_VERSION_4_5)
		return val;

	type >>= hweight32(CHTYPE_PROTOCOL_FMASK);
	type >>= hweight32(reg_fmask(reg, CHTYPE_PROTOCOL));

	return val | u32_encode_bits(type, CHTYPE_PROTOCOL_MSB_FMASK);
}

/* Encode a channel ring buffer length for the CH_C_CNTXT_1 register */
static u32 ch_c_cntxt_1_length_encode(enum ipa_version version, u32 length)
{
	if (version < IPA_VERSION_4_9)
		return u32_encode_bits(length, GENMASK(15, 0));

	return u32_encode_bits(length, GENMASK(19, 0));
	return val | reg_encode(reg, CHTYPE_PROTOCOL_MSB, type);
}

/* Encode the length of the event channel ring buffer for the
@@ -429,7 +415,7 @@ gsi_evt_ring_state(struct gsi *gsi, u32 evt_ring_id)

	val = ioread32(gsi->virt + reg_n_offset(reg, evt_ring_id));

	return u32_get_bits(val, EV_CHSTATE_FMASK);
	return reg_decode(reg, EV_CHSTATE, val);
}

/* Issue an event ring command and wait for it to complete */
@@ -445,8 +431,8 @@ static void gsi_evt_ring_command(struct gsi *gsi, u32 evt_ring_id,
	gsi_irq_ev_ctrl_enable(gsi, evt_ring_id);

	reg = gsi_reg(gsi, EV_CH_CMD);
	val = u32_encode_bits(evt_ring_id, EV_CHID_FMASK);
	val |= u32_encode_bits(opcode, EV_OPCODE_FMASK);
	val = reg_encode(reg, EV_CHID, evt_ring_id);
	val |= reg_encode(reg, EV_OPCODE, opcode);

	timeout = !gsi_command(gsi, reg_offset(reg), val);

@@ -544,7 +530,7 @@ static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel)
	reg = gsi_reg(gsi, CH_C_CNTXT_0);
	val = ioread32(virt + reg_n_offset(reg, channel_id));

	return u32_get_bits(val, CHSTATE_FMASK);
	return reg_decode(reg, CHSTATE, val);
}

/* Issue a channel command and wait for it to complete */
@@ -562,8 +548,8 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode)
	gsi_irq_ch_ctrl_enable(gsi, channel_id);

	reg = gsi_reg(gsi, CH_CMD);
	val = u32_encode_bits(channel_id, CH_CHID_FMASK);
	val |= u32_encode_bits(opcode, CH_OPCODE_FMASK);
	val = reg_encode(reg, CH_CHID, channel_id);
	val |= reg_encode(reg, CH_OPCODE, opcode);

	timeout = !gsi_command(gsi, reg_offset(reg), val);

@@ -750,9 +736,10 @@ static void gsi_evt_ring_program(struct gsi *gsi, u32 evt_ring_id)

	reg = gsi_reg(gsi, EV_CH_E_CNTXT_0);
	/* We program all event rings as GPI type/protocol */
	val = u32_encode_bits(GSI_CHANNEL_TYPE_GPI, EV_CHTYPE_FMASK);
	val |= EV_INTYPE_FMASK;
	val |= u32_encode_bits(GSI_RING_ELEMENT_SIZE, EV_ELEMENT_SIZE_FMASK);
	val = reg_encode(reg, EV_CHTYPE, GSI_CHANNEL_TYPE_GPI);
	/* EV_EE field is 0 (GSI_EE_AP) */
	val |= reg_bit(reg, EV_INTYPE);
	val |= reg_encode(reg, EV_ELEMENT_SIZE, GSI_RING_ELEMENT_SIZE);
	iowrite32(val, gsi->virt + reg_n_offset(reg, evt_ring_id));

	reg = gsi_reg(gsi, EV_CH_E_CNTXT_1);
@@ -774,11 +761,12 @@ static void gsi_evt_ring_program(struct gsi *gsi, u32 evt_ring_id)

	/* Enable interrupt moderation by setting the moderation delay */
	reg = gsi_reg(gsi, EV_CH_E_CNTXT_8);
	val = u32_encode_bits(GSI_EVT_RING_INT_MODT, MODT_FMASK);
	val |= u32_encode_bits(1, MODC_FMASK);	/* comes from channel */
	val = reg_encode(reg, EV_MODT, GSI_EVT_RING_INT_MODT);
	val = reg_encode(reg, EV_MODC, 1);	/* comes from channel */
	/* EV_MOD_CNT is 0 (no counter-based interrupt coalescing) */
	iowrite32(val, gsi->virt + reg_n_offset(reg, evt_ring_id));

	/* No MSI write data, and MSI address high and low address is 0 */
	/* No MSI write data, and MSI high and low address is 0 */
	reg = gsi_reg(gsi, EV_CH_E_CNTXT_9);
	iowrite32(0, gsi->virt + reg_n_offset(reg, evt_ring_id));

@@ -862,15 +850,15 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell)
	reg = gsi_reg(gsi, CH_C_CNTXT_0);

	/* We program all channels as GPI type/protocol */
	val = ch_c_cntxt_0_type_encode(gsi->version, GSI_CHANNEL_TYPE_GPI);
	val = ch_c_cntxt_0_type_encode(gsi->version, reg, GSI_CHANNEL_TYPE_GPI);
	if (channel->toward_ipa)
		val |= CHTYPE_DIR_FMASK;
	val |= u32_encode_bits(channel->evt_ring_id, ERINDEX_FMASK);
	val |= u32_encode_bits(GSI_RING_ELEMENT_SIZE, ELEMENT_SIZE_FMASK);
		val |= reg_bit(reg, CHTYPE_DIR);
	val |= reg_encode(reg, ERINDEX, channel->evt_ring_id);
	val |= reg_encode(reg, ELEMENT_SIZE, GSI_RING_ELEMENT_SIZE);
	iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id));

	reg = gsi_reg(gsi, CH_C_CNTXT_1);
	val = ch_c_cntxt_1_length_encode(gsi->version, size);
	val = reg_encode(reg, CH_R_LENGTH, size);
	iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id));

	/* The context 2 and 3 registers store the low-order and
@@ -889,14 +877,14 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell)

	/* Command channel gets low weighted round-robin priority */
	if (channel->command)
		wrr_weight = field_max(WRR_WEIGHT_FMASK);
	val = u32_encode_bits(wrr_weight, WRR_WEIGHT_FMASK);
		wrr_weight = reg_field_max(reg, WRR_WEIGHT);
	val = reg_encode(reg, WRR_WEIGHT, wrr_weight);

	/* Max prefetch is 1 segment (do not set MAX_PREFETCH_FMASK) */

	/* No need to use the doorbell engine starting at IPA v4.0 */
	if (gsi->version < IPA_VERSION_4_0 && doorbell)
		val |= USE_DB_ENG_FMASK;
		val |= reg_bit(reg, USE_DB_ENG);

	/* v4.0 introduces an escape buffer for prefetch.  We use it
	 * on all but the AP command channel.
@@ -904,14 +892,13 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell)
	if (gsi->version >= IPA_VERSION_4_0 && !channel->command) {
		/* If not otherwise set, prefetch buffers are used */
		if (gsi->version < IPA_VERSION_4_5)
			val |= USE_ESCAPE_BUF_ONLY_FMASK;
			val |= reg_bit(reg, USE_ESCAPE_BUF_ONLY);
		else
			val |= u32_encode_bits(GSI_ESCAPE_BUF_ONLY,
					       PREFETCH_MODE_FMASK);
			val |= reg_encode(reg, PREFETCH_MODE, ESCAPE_BUF_ONLY);
	}
	/* All channels set DB_IN_BYTES */
	if (gsi->version >= IPA_VERSION_4_9)
		val |= DB_IN_BYTES;
		val |= reg_bit(reg, DB_IN_BYTES);

	iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id));

@@ -1233,28 +1220,29 @@ gsi_isr_glob_evt_err(struct gsi *gsi, u32 err_ee, u32 evt_ring_id, u32 code)
/* Global error interrupt handler */
static void gsi_isr_glob_err(struct gsi *gsi)
{
	const struct reg *log_reg;
	const struct reg *clr_reg;
	enum gsi_err_type type;
	enum gsi_err_code code;
	const struct reg *reg;
	u32 offset;
	u32 which;
	u32 val;
	u32 ee;

	/* Get the logged error, then reinitialize the log */
	reg = gsi_reg(gsi, ERROR_LOG);
	offset = reg_offset(reg);
	log_reg = gsi_reg(gsi, ERROR_LOG);
	offset = reg_offset(log_reg);
	val = ioread32(gsi->virt + offset);
	iowrite32(0, gsi->virt + offset);

	reg = gsi_reg(gsi, ERROR_LOG_CLR);
	iowrite32(~0, gsi->virt + reg_offset(reg));
	clr_reg = gsi_reg(gsi, ERROR_LOG_CLR);
	iowrite32(~0, gsi->virt + reg_offset(clr_reg));

	/* Parse the error value */
	ee = u32_get_bits(val, ERR_EE_FMASK);
	type = u32_get_bits(val, ERR_TYPE_FMASK);
	which = u32_get_bits(val, ERR_VIRT_IDX_FMASK);
	code = u32_get_bits(val, ERR_CODE_FMASK);
	ee = reg_decode(log_reg, ERR_EE, val);
	type = reg_decode(log_reg, ERR_TYPE, val);
	which = reg_decode(log_reg, ERR_VIRT_IDX, val);
	code = reg_decode(log_reg, ERR_CODE, val);

	if (type == GSI_ERR_TYPE_CHAN)
		gsi_isr_glob_chan_err(gsi, ee, which, code);
@@ -1292,7 +1280,7 @@ static void gsi_isr_gp_int1(struct gsi *gsi)
	 */
	reg = gsi_reg(gsi, CNTXT_SCRATCH_0);
	val = ioread32(gsi->virt + reg_offset(reg));
	result = u32_get_bits(val, GENERIC_EE_RESULT_FMASK);
	result = reg_decode(reg, GENERIC_EE_RESULT, val);

	switch (result) {
	case GENERIC_EE_SUCCESS:
@@ -1814,16 +1802,16 @@ static int gsi_generic_command(struct gsi *gsi, u32 channel_id,
	offset = reg_offset(reg);
	val = ioread32(gsi->virt + offset);

	val &= ~GENERIC_EE_RESULT_FMASK;
	val &= ~reg_fmask(reg, GENERIC_EE_RESULT);
	iowrite32(val, gsi->virt + offset);

	/* Now issue the command */
	reg = gsi_reg(gsi, GENERIC_CMD);
	val = u32_encode_bits(opcode, GENERIC_OPCODE_FMASK);
	val |= u32_encode_bits(channel_id, GENERIC_CHID_FMASK);
	val |= u32_encode_bits(GSI_EE_MODEM, GENERIC_EE_FMASK);
	val = reg_encode(reg, GENERIC_OPCODE, opcode);
	val |= reg_encode(reg, GENERIC_CHID, channel_id);
	val |= reg_encode(reg, GENERIC_EE, GSI_EE_MODEM);
	if (gsi->version >= IPA_VERSION_4_11)
		val |= u32_encode_bits(params, GENERIC_PARAMS_FMASK);
		val |= reg_encode(reg, GENERIC_PARAMS, params);

	timeout = !gsi_command(gsi, reg_offset(reg), val);

@@ -1991,7 +1979,7 @@ static int gsi_irq_setup(struct gsi *gsi)

	/* Writing 1 indicates IRQ interrupts; 0 would be MSI */
	reg = gsi_reg(gsi, CNTXT_INTSET);
	iowrite32(1, gsi->virt + reg_offset(reg));
	iowrite32(reg_bit(reg, INTYPE), gsi->virt + reg_offset(reg));

	/* Disable all interrupt types */
	gsi_irq_type_update(gsi, 0);
@@ -2053,7 +2041,7 @@ static int gsi_ring_setup(struct gsi *gsi)
	reg = gsi_reg(gsi, HW_PARAM_2);
	val = ioread32(gsi->virt + reg_offset(reg));

	count = u32_get_bits(val, NUM_CH_PER_EE_FMASK);
	count = reg_decode(reg, NUM_CH_PER_EE, val);
	if (!count) {
		dev_err(dev, "GSI reports zero channels supported\n");
		return -EINVAL;
@@ -2065,7 +2053,7 @@ static int gsi_ring_setup(struct gsi *gsi)
	}
	gsi->channel_count = count;

	count = u32_get_bits(val, NUM_EV_PER_EE_FMASK);
	count = reg_decode(reg, NUM_EV_PER_EE, val);
	if (!count) {
		dev_err(dev, "GSI reports zero event rings supported\n");
		return -EINVAL;
@@ -2091,7 +2079,7 @@ int gsi_setup(struct gsi *gsi)
	/* Here is where we first touch the GSI hardware */
	reg = gsi_reg(gsi, GSI_STATUS);
	val = ioread32(gsi->virt + reg_offset(reg));
	if (!(val & ENABLED_FMASK)) {
	if (!(val & reg_bit(reg, ENABLED))) {
		dev_err(gsi->dev, "GSI has not been enabled\n");
		return -EIO;
	}
+9 −1
Original line number Diff line number Diff line
@@ -101,12 +101,20 @@ static const struct regs *gsi_regs(struct gsi *gsi)
		return &gsi_regs_v3_1;

	case IPA_VERSION_3_5_1:
		return &gsi_regs_v3_5_1;

	case IPA_VERSION_4_2:
		return &gsi_regs_v4_0;

	case IPA_VERSION_4_5:
	case IPA_VERSION_4_7:
		return &gsi_regs_v4_5;

	case IPA_VERSION_4_9:
		return &gsi_regs_v4_9;

	case IPA_VERSION_4_11:
		return &gsi_regs_v3_5_1;
		return &gsi_regs_v4_11;

	default:
		return NULL;
+91 −65
Original line number Diff line number Diff line
@@ -96,15 +96,16 @@ enum gsi_reg_id {
};

/* CH_C_CNTXT_0 register */
#define CHTYPE_PROTOCOL_FMASK		GENMASK(2, 0)
#define CHTYPE_DIR_FMASK		GENMASK(3, 3)
#define EE_FMASK			GENMASK(7, 4)
#define CHID_FMASK			GENMASK(12, 8)
/* The next field is present for IPA v4.5 and above */
#define CHTYPE_PROTOCOL_MSB_FMASK	GENMASK(13, 13)
#define ERINDEX_FMASK			GENMASK(18, 14)
#define CHSTATE_FMASK			GENMASK(23, 20)
#define ELEMENT_SIZE_FMASK		GENMASK(31, 24)
enum gsi_reg_ch_c_cntxt_0_field_id {
	CHTYPE_PROTOCOL,
	CHTYPE_DIR,
	CH_EE,
	CHID,
	CHTYPE_PROTOCOL_MSB,				/* IPA v4.9+ */
	ERINDEX,
	CHSTATE,
	ELEMENT_SIZE,
};

/** enum gsi_channel_type - CHTYPE_PROTOCOL field values in CH_C_CNTXT_0 */
enum gsi_channel_type {
@@ -120,46 +121,57 @@ enum gsi_channel_type {
	GSI_CHANNEL_TYPE_11AD			= 0x9,
};

/* CH_C_CNTXT_1 register */
enum gsi_reg_ch_c_cntxt_1_field_id {
	CH_R_LENGTH,
};

/* CH_C_QOS register */
#define WRR_WEIGHT_FMASK		GENMASK(3, 0)
#define MAX_PREFETCH_FMASK		GENMASK(8, 8)
#define USE_DB_ENG_FMASK		GENMASK(9, 9)
/* The next field is only present for IPA v4.0, v4.1, and v4.2 */
#define USE_ESCAPE_BUF_ONLY_FMASK	GENMASK(10, 10)
/* The next two fields are present for IPA v4.5 and above */
#define PREFETCH_MODE_FMASK		GENMASK(13, 10)
#define EMPTY_LVL_THRSHOLD_FMASK	GENMASK(23, 16)
/* The next field is present for IPA v4.9 and above */
#define DB_IN_BYTES			GENMASK(24, 24)
enum gsi_reg_ch_c_qos_field_id {
	WRR_WEIGHT,
	MAX_PREFETCH,
	USE_DB_ENG,
	USE_ESCAPE_BUF_ONLY,				/* IPA v4.0-4.2 */
	PREFETCH_MODE,					/* IPA v4.5+ */
	EMPTY_LVL_THRSHOLD,				/* IPA v4.5+ */
	DB_IN_BYTES,					/* IPA v4.9+ */
};

/** enum gsi_prefetch_mode - PREFETCH_MODE field in CH_C_QOS */
enum gsi_prefetch_mode {
	GSI_USE_PREFETCH_BUFS			= 0x0,
	GSI_ESCAPE_BUF_ONLY			= 0x1,
	GSI_SMART_PREFETCH			= 0x2,
	GSI_FREE_PREFETCH			= 0x3,
	USE_PREFETCH_BUFS			= 0,
	ESCAPE_BUF_ONLY				= 1,
	SMART_PREFETCH				= 2,
	FREE_PREFETCH				= 3,
};

/* EV_CH_E_CNTXT_0 register */
/* enum gsi_channel_type defines EV_CHTYPE field values in EV_CH_E_CNTXT_0 */
#define EV_CHTYPE_FMASK			GENMASK(3, 0)
#define EV_EE_FMASK			GENMASK(7, 4)
#define EV_EVCHID_FMASK			GENMASK(15, 8)
#define EV_INTYPE_FMASK			GENMASK(16, 16)
#define EV_CHSTATE_FMASK		GENMASK(23, 20)
#define EV_ELEMENT_SIZE_FMASK		GENMASK(31, 24)
enum gsi_reg_ch_c_ev_ch_e_cntxt_0_field_id {
	EV_CHTYPE,	/* enum gsi_channel_type */
	EV_EE,		/* enum gsi_ee_id; always GSI_EE_AP for us */
	EV_EVCHID,
	EV_INTYPE,
	EV_CHSTATE,
	EV_ELEMENT_SIZE,
};

/* EV_CH_E_CNTXT_8 register */
#define MODT_FMASK			GENMASK(15, 0)
#define MODC_FMASK			GENMASK(23, 16)
#define MOD_CNT_FMASK			GENMASK(31, 24)
enum gsi_reg_ch_c_ev_ch_e_cntxt_8_field_id {
	EV_MODT,
	EV_MODC,
	EV_MOD_CNT,
};

/* GSI_STATUS register */
#define ENABLED_FMASK			GENMASK(0, 0)
enum gsi_reg_gsi_status_field_id {
	ENABLED,
};

/* CH_CMD register */
#define CH_CHID_FMASK			GENMASK(7, 0)
#define CH_OPCODE_FMASK			GENMASK(31, 24)
enum gsi_reg_gsi_ch_cmd_field_id {
	CH_CHID,
	CH_OPCODE,
};

/** enum gsi_ch_cmd_opcode - CH_OPCODE field values in CH_CMD */
enum gsi_ch_cmd_opcode {
@@ -172,8 +184,10 @@ enum gsi_ch_cmd_opcode {
};

/* EV_CH_CMD register */
#define EV_CHID_FMASK			GENMASK(7, 0)
#define EV_OPCODE_FMASK			GENMASK(31, 24)
enum gsi_ev_ch_cmd_field_id {
	EV_CHID,
	EV_OPCODE,
};

/** enum gsi_evt_cmd_opcode - EV_OPCODE field values in EV_CH_CMD */
enum gsi_evt_cmd_opcode {
@@ -183,10 +197,12 @@ enum gsi_evt_cmd_opcode {
};

/* GENERIC_CMD register */
#define GENERIC_OPCODE_FMASK		GENMASK(4, 0)
#define GENERIC_CHID_FMASK		GENMASK(9, 5)
#define GENERIC_EE_FMASK		GENMASK(13, 10)
#define GENERIC_PARAMS_FMASK		GENMASK(31, 24)	/* IPA v4.11+ */
enum gsi_generic_cmd_field_id {
	GENERIC_OPCODE,
	GENERIC_CHID,
	GENERIC_EE,
	GENERIC_PARAMS,					/* IPA v4.11+ */
};

/** enum gsi_generic_cmd_opcode - GENERIC_OPCODE field values in GENERIC_CMD */
enum gsi_generic_cmd_opcode {
@@ -198,19 +214,19 @@ enum gsi_generic_cmd_opcode {
};

/* HW_PARAM_2 register */				/* IPA v3.5.1+ */
#define IRAM_SIZE_FMASK			GENMASK(2, 0)
#define NUM_CH_PER_EE_FMASK		GENMASK(7, 3)
#define NUM_EV_PER_EE_FMASK		GENMASK(12, 8)
#define GSI_CH_PEND_TRANSLATE_FMASK	GENMASK(13, 13)
#define GSI_CH_FULL_LOGIC_FMASK		GENMASK(14, 14)
/* Fields below are present for IPA v4.0 and above */
#define GSI_USE_SDMA_FMASK		GENMASK(15, 15)
#define GSI_SDMA_N_INT_FMASK		GENMASK(18, 16)
#define GSI_SDMA_MAX_BURST_FMASK	GENMASK(26, 19)
#define GSI_SDMA_N_IOVEC_FMASK		GENMASK(29, 27)
/* Fields below are present for IPA v4.2 and above */
#define GSI_USE_RD_WR_ENG_FMASK		GENMASK(30, 30)
#define GSI_USE_INTER_EE_FMASK		GENMASK(31, 31)
enum gsi_hw_param_2_field_id {
	IRAM_SIZE,
	NUM_CH_PER_EE,
	NUM_EV_PER_EE,
	GSI_CH_PEND_TRANSLATE,
	GSI_CH_FULL_LOGIC,
	GSI_USE_SDMA,					/* IPA v4.0+ */
	GSI_SDMA_N_INT,					/* IPA v4.0+ */
	GSI_SDMA_MAX_BURST,				/* IPA v4.0+ */
	GSI_SDMA_N_IOVEC,				/* IPA v4.0+ */
	GSI_USE_RD_WR_ENG,				/* IPA v4.2+ */
	GSI_USE_INTER_EE,				/* IPA v4.2+ */
};

/** enum gsi_iram_size - IRAM_SIZE field values in HW_PARAM_2 */
enum gsi_iram_size {
@@ -264,16 +280,20 @@ enum gsi_general_irq_id {
};

/* CNTXT_INTSET register */
#define INTYPE_FMASK			GENMASK(0, 0)
enum gsi_cntxt_intset_field_id {
	INTYPE,
};

/* ERROR_LOG register */
#define ERR_ARG3_FMASK			GENMASK(3, 0)
#define ERR_ARG2_FMASK			GENMASK(7, 4)
#define ERR_ARG1_FMASK			GENMASK(11, 8)
#define ERR_CODE_FMASK			GENMASK(15, 12)
#define ERR_VIRT_IDX_FMASK		GENMASK(23, 19)
#define ERR_TYPE_FMASK			GENMASK(27, 24)
#define ERR_EE_FMASK			GENMASK(31, 28)
enum gsi_error_log_field_id {
	ERR_ARG3,
	ERR_ARG2,
	ERR_ARG1,
	ERR_CODE,
	ERR_VIRT_IDX,
	ERR_TYPE,
	ERR_EE,
};

/** enum gsi_err_code - ERR_CODE field values in EE_ERR_LOG */
enum gsi_err_code {
@@ -295,8 +315,10 @@ enum gsi_err_type {
};

/* CNTXT_SCRATCH_0 register */
#define INTER_EE_RESULT_FMASK		GENMASK(2, 0)
#define GENERIC_EE_RESULT_FMASK		GENMASK(7, 5)
enum gsi_cntxt_scratch_0_field_id {
	INTER_EE_RESULT,
	GENERIC_EE_RESULT,
};

/** enum gsi_generic_ee_result - GENERIC_EE_RESULT field values in SCRATCH_0 */
enum gsi_generic_ee_result {
@@ -311,6 +333,10 @@ enum gsi_generic_ee_result {

extern const struct regs gsi_regs_v3_1;
extern const struct regs gsi_regs_v3_5_1;
extern const struct regs gsi_regs_v4_0;
extern const struct regs gsi_regs_v4_5;
extern const struct regs gsi_regs_v4_9;
extern const struct regs gsi_regs_v4_11;

/**
 * gsi_reg() - Return the structure describing a GSI register
+102 −14
Original line number Diff line number Diff line
@@ -18,17 +18,55 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,

/* All other register offsets are relative to gsi->virt */

REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);
static const u32 reg_ch_c_cntxt_0_fmask[] = {
	[CHTYPE_PROTOCOL]				= GENMASK(2, 0),
	[CHTYPE_DIR]					= BIT(3),
	[CH_EE]						= GENMASK(7, 4),
	[CHID]						= GENMASK(12, 8),
						/* Bit 13 reserved */
	[ERINDEX]					= GENMASK(18, 14),
						/* Bit 19 reserved */
	[CHSTATE]					= GENMASK(23, 20),
	[ELEMENT_SIZE]					= GENMASK(31, 24),
};

REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0,
		  0x0001c000 + 0x4000 * GSI_EE_AP, 0x80);

static const u32 reg_ch_c_cntxt_1_fmask[] = {
	[CH_R_LENGTH]					= GENMASK(15, 0),
						/* Bits 16-31 reserved */
};

REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);
REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1,
		  0x0001c004 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(CH_C_CNTXT_3, ch_c_cntxt_3, 0x0001c00c + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(CH_C_QOS, ch_c_qos, 0x0001c05c + 0x4000 * GSI_EE_AP, 0x80);
static const u32 reg_ch_c_qos_fmask[] = {
	[WRR_WEIGHT]					= GENMASK(3, 0),
						/* Bits 4-7 reserved */
	[MAX_PREFETCH]					= BIT(8),
	[USE_DB_ENG]					= BIT(9),
						/* Bits 10-31 reserved */
};

REG_STRIDE_FIELDS(CH_C_QOS, ch_c_qos, 0x0001c05c + 0x4000 * GSI_EE_AP, 0x80);

static const u32 reg_error_log_fmask[] = {
	[ERR_ARG3]					= GENMASK(3, 0),
	[ERR_ARG2]					= GENMASK(7, 4),
	[ERR_ARG1]					= GENMASK(11, 8),
	[ERR_CODE]					= GENMASK(15, 12),
						/* Bits 16-18 reserved */
	[ERR_VIRT_IDX]					= GENMASK(23, 19),
	[ERR_TYPE]					= GENMASK(27, 24),
	[ERR_EE]					= GENMASK(31, 28),
};

REG(ERROR_LOG, error_log, 0x0001f200 + 0x4000 * GSI_EE_AP);
REG_FIELDS(ERROR_LOG, error_log, 0x0001f200 + 0x4000 * GSI_EE_AP);

REG(ERROR_LOG_CLR, error_log_clr, 0x0001f210 + 0x4000 * GSI_EE_AP);

@@ -44,7 +82,17 @@ REG_STRIDE(CH_C_SCRATCH_2, ch_c_scratch_2,
REG_STRIDE(CH_C_SCRATCH_3, ch_c_scratch_3,
	   0x0001c06c + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_0, ev_ch_e_cntxt_0,
static const u32 reg_ev_ch_e_cntxt_0_fmask[] = {
	[EV_CHTYPE]					= GENMASK(3, 0),
	[EV_EE]						= GENMASK(7, 4),
	[EV_EVCHID]					= GENMASK(15, 8),
	[EV_INTYPE]					= BIT(16),
						/* Bits 17-19 reserved */
	[EV_CHSTATE]					= GENMASK(23, 20),
	[EV_ELEMENT_SIZE]				= GENMASK(31, 24),
};

REG_STRIDE_FIELDS(EV_CH_E_CNTXT_0, ev_ch_e_cntxt_0,
		  0x0001d000 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_1, ev_ch_e_cntxt_1,
@@ -59,7 +107,13 @@ REG_STRIDE(EV_CH_E_CNTXT_3, ev_ch_e_cntxt_3,
REG_STRIDE(EV_CH_E_CNTXT_4, ev_ch_e_cntxt_4,
	   0x0001d010 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_8, ev_ch_e_cntxt_8,
static const u32 reg_ev_ch_e_cntxt_8_fmask[] = {
	[EV_MODT]					= GENMASK(15, 0),
	[EV_MODC]					= GENMASK(23, 16),
	[EV_MOD_CNT]					= GENMASK(31, 24),
};

REG_STRIDE_FIELDS(EV_CH_E_CNTXT_8, ev_ch_e_cntxt_8,
		  0x0001d020 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_9, ev_ch_e_cntxt_9,
@@ -89,13 +143,35 @@ REG_STRIDE(CH_C_DOORBELL_0, ch_c_doorbell_0,
REG_STRIDE(EV_CH_E_DOORBELL_0, ev_ch_e_doorbell_0,
	   0x0001e100 + 0x4000 * GSI_EE_AP, 0x08);

REG(GSI_STATUS, gsi_status, 0x0001f000 + 0x4000 * GSI_EE_AP);
static const u32 reg_gsi_status_fmask[] = {
	[ENABLED]					= BIT(0),
						/* Bits 1-31 reserved */
};

REG(CH_CMD, ch_cmd, 0x0001f008 + 0x4000 * GSI_EE_AP);
REG_FIELDS(GSI_STATUS, gsi_status, 0x0001f000 + 0x4000 * GSI_EE_AP);

REG(EV_CH_CMD, ev_ch_cmd, 0x0001f010 + 0x4000 * GSI_EE_AP);
static const u32 reg_ch_cmd_fmask[] = {
	[CH_CHID]					= GENMASK(7, 0),
	[CH_OPCODE]					= GENMASK(31, 24),
};

REG_FIELDS(CH_CMD, ch_cmd, 0x0001f008 + 0x4000 * GSI_EE_AP);

static const u32 reg_ev_ch_cmd_fmask[] = {
	[EV_CHID]					= GENMASK(7, 0),
	[EV_OPCODE]					= GENMASK(31, 24),
};

REG_FIELDS(EV_CH_CMD, ev_ch_cmd, 0x0001f010 + 0x4000 * GSI_EE_AP);

REG(GENERIC_CMD, generic_cmd, 0x0001f018 + 0x4000 * GSI_EE_AP);
static const u32 reg_generic_cmd_fmask[] = {
	[GENERIC_OPCODE]				= GENMASK(4, 0),
	[GENERIC_CHID]					= GENMASK(9, 5),
	[GENERIC_EE]					= GENMASK(13, 10),
						/* Bits 14-31 reserved */
};

REG_FIELDS(GENERIC_CMD, generic_cmd, 0x0001f018 + 0x4000 * GSI_EE_AP);

REG(CNTXT_TYPE_IRQ, cntxt_type_irq, 0x0001f080 + 0x4000 * GSI_EE_AP);

@@ -137,9 +213,21 @@ REG(CNTXT_GSI_IRQ_EN, cntxt_gsi_irq_en, 0x0001f120 + 0x4000 * GSI_EE_AP);

REG(CNTXT_GSI_IRQ_CLR, cntxt_gsi_irq_clr, 0x0001f128 + 0x4000 * GSI_EE_AP);

REG(CNTXT_INTSET, cntxt_intset, 0x0001f180 + 0x4000 * GSI_EE_AP);
static const u32 reg_cntxt_intset_fmask[] = {
	[INTYPE]					= BIT(0)
						/* Bits 1-31 reserved */
};

REG_FIELDS(CNTXT_INTSET, cntxt_intset, 0x0001f180 + 0x4000 * GSI_EE_AP);

static const u32 reg_cntxt_scratch_0_fmask[] = {
	[INTER_EE_RESULT]				= GENMASK(2, 0),
						/* Bits 3-4 reserved */
	[GENERIC_EE_RESULT]				= GENMASK(7, 5),
						/* Bits 8-31 reserved */
};

REG(CNTXT_SCRATCH_0, cntxt_scratch_0, 0x0001f400 + 0x4000 * GSI_EE_AP);
REG_FIELDS(CNTXT_SCRATCH_0, cntxt_scratch_0, 0x0001f400 + 0x4000 * GSI_EE_AP);

static const struct reg *reg_array[] = {
	[INTER_EE_SRC_CH_IRQ_MSK]	= &reg_inter_ee_src_ch_irq_msk,
Loading