Commit d1ce6395 authored by Alex Elder's avatar Alex Elder Committed by David S. Miller
Browse files

net: ipa: define IPA v3.1 GSI event ring register offsets



Add definitions of the offsets and strides for registers whose
offset depends on an event ring ID, and use gsi_reg() and its
returned value to determine offsets for these registers.  Get
rid of the corresponding GSI_EV_CH_E_*_OFFSET() macros.

Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 76924eb9
Loading
Loading
Loading
Loading
+32 −13
Original line number Diff line number Diff line
@@ -392,9 +392,10 @@ static bool gsi_command(struct gsi *gsi, u32 reg, u32 val)
static enum gsi_evt_ring_state
gsi_evt_ring_state(struct gsi *gsi, u32 evt_ring_id)
{
	const struct reg *reg = gsi_reg(gsi, EV_CH_E_CNTXT_0);
	u32 val;

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

	return u32_get_bits(val, EV_CHSTATE_FMASK);
}
@@ -690,6 +691,7 @@ static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id)
 */
static void gsi_evt_ring_doorbell(struct gsi *gsi, u32 evt_ring_id, u32 index)
{
	const struct reg *reg = gsi_reg(gsi, EV_CH_E_DOORBELL_0);
	struct gsi_ring *ring = &gsi->evt_ring[evt_ring_id].ring;
	u32 val;

@@ -697,7 +699,7 @@ static void gsi_evt_ring_doorbell(struct gsi *gsi, u32 evt_ring_id, u32 index)

	/* Note: index *must* be used modulo the ring count here */
	val = gsi_ring_addr(ring, (index - 1) % ring->count);
	iowrite32(val, gsi->virt + GSI_EV_CH_E_DOORBELL_0_OFFSET(evt_ring_id));
	iowrite32(val, gsi->virt + reg_n_offset(reg, evt_ring_id));
}

/* Program an event ring for use */
@@ -705,41 +707,56 @@ static void gsi_evt_ring_program(struct gsi *gsi, u32 evt_ring_id)
{
	struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id];
	struct gsi_ring *ring = &evt_ring->ring;
	const struct reg *reg;
	size_t size;
	u32 val;

	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);
	iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_0_OFFSET(evt_ring_id));
	iowrite32(val, gsi->virt + reg_n_offset(reg, evt_ring_id));

	reg = gsi_reg(gsi, EV_CH_E_CNTXT_1);
	size = ring->count * GSI_RING_ELEMENT_SIZE;
	val = ev_ch_e_cntxt_1_length_encode(gsi->version, size);
	iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_1_OFFSET(evt_ring_id));
	iowrite32(val, gsi->virt + reg_n_offset(reg, evt_ring_id));

	/* The context 2 and 3 registers store the low-order and
	 * high-order 32 bits of the address of the event ring,
	 * respectively.
	 */
	reg = gsi_reg(gsi, EV_CH_E_CNTXT_2);
	val = lower_32_bits(ring->addr);
	iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_2_OFFSET(evt_ring_id));
	iowrite32(val, gsi->virt + reg_n_offset(reg, evt_ring_id));

	reg = gsi_reg(gsi, EV_CH_E_CNTXT_3);
	val = upper_32_bits(ring->addr);
	iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_3_OFFSET(evt_ring_id));
	iowrite32(val, gsi->virt + reg_n_offset(reg, 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 */
	iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_8_OFFSET(evt_ring_id));
	iowrite32(val, gsi->virt + reg_n_offset(reg, evt_ring_id));

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

	reg = gsi_reg(gsi, EV_CH_E_CNTXT_10);
	iowrite32(0, gsi->virt + reg_n_offset(reg, evt_ring_id));

	reg = gsi_reg(gsi, EV_CH_E_CNTXT_11);
	iowrite32(0, gsi->virt + reg_n_offset(reg, evt_ring_id));

	/* We don't need to get event read pointer updates */
	iowrite32(0, gsi->virt + GSI_EV_CH_E_CNTXT_12_OFFSET(evt_ring_id));
	iowrite32(0, gsi->virt + GSI_EV_CH_E_CNTXT_13_OFFSET(evt_ring_id));
	reg = gsi_reg(gsi, EV_CH_E_CNTXT_12);
	iowrite32(0, gsi->virt + reg_n_offset(reg, evt_ring_id));

	reg = gsi_reg(gsi, EV_CH_E_CNTXT_13);
	iowrite32(0, gsi->virt + reg_n_offset(reg, evt_ring_id));

	/* Finally, tell the hardware our "last processed" event (arbitrary) */
	gsi_evt_ring_doorbell(gsi, evt_ring_id, ring->index);
@@ -1538,6 +1555,7 @@ void gsi_channel_update(struct gsi_channel *channel)
	struct gsi_evt_ring *evt_ring;
	struct gsi_trans *trans;
	struct gsi_ring *ring;
	const struct reg *reg;
	u32 offset;
	u32 index;

@@ -1547,7 +1565,8 @@ void gsi_channel_update(struct gsi_channel *channel)
	/* See if there's anything new to process; if not, we're done.  Note
	 * that index always refers to an entry *within* the event ring.
	 */
	offset = GSI_EV_CH_E_CNTXT_4_OFFSET(evt_ring_id);
	reg = gsi_reg(gsi, EV_CH_E_CNTXT_4);
	offset = reg_n_offset(reg, evt_ring_id);
	index = gsi_ring_index(ring, ioread32(gsi->virt + offset));
	if (index == ring->index % ring->count)
		return;
+2 −40
Original line number Diff line number Diff line
@@ -150,8 +150,7 @@ enum gsi_prefetch_mode {
	GSI_FREE_PREFETCH			= 0x3,
};

#define GSI_EV_CH_E_CNTXT_0_OFFSET(ev) \
			(0x0001d000 + 0x4000 * GSI_EE_AP + 0x80 * (ev))
/* 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)
@@ -160,48 +159,11 @@ enum gsi_prefetch_mode {
#define EV_CHSTATE_FMASK		GENMASK(23, 20)
#define EV_ELEMENT_SIZE_FMASK		GENMASK(31, 24)

#define GSI_EV_CH_E_CNTXT_1_OFFSET(ev) \
			(0x0001d004 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_2_OFFSET(ev) \
			(0x0001d008 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_3_OFFSET(ev) \
			(0x0001d00c + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_4_OFFSET(ev) \
			(0x0001d010 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_8_OFFSET(ev) \
			(0x0001d020 + 0x4000 * GSI_EE_AP + 0x80 * (ev))
/* 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)

#define GSI_EV_CH_E_CNTXT_9_OFFSET(ev) \
			(0x0001d024 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_10_OFFSET(ev) \
			(0x0001d028 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_11_OFFSET(ev) \
			(0x0001d02c + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_12_OFFSET(ev) \
			(0x0001d030 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_CNTXT_13_OFFSET(ev) \
			(0x0001d034 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_SCRATCH_0_OFFSET(ev) \
			(0x0001d048 + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_SCRATCH_1_OFFSET(ev) \
			(0x0001d04c + 0x4000 * GSI_EE_AP + 0x80 * (ev))

#define GSI_EV_CH_E_DOORBELL_0_OFFSET(ev) \
			(0x0001e100 + 0x4000 * GSI_EE_AP + 0x08 * (ev))

#define GSI_GSI_STATUS_OFFSET \
			(0x0001f000 + 0x4000 * GSI_EE_AP)
#define ENABLED_FMASK			GENMASK(0, 0)
+56 −0
Original line number Diff line number Diff line
@@ -30,9 +30,51 @@ 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,
	   0x0001d000 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_1, ev_ch_e_cntxt_1,
	   0x0001d004 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_2, ev_ch_e_cntxt_2,
	   0x0001d008 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_3, ev_ch_e_cntxt_3,
	   0x0001d00c + 0x4000 * GSI_EE_AP, 0x80);

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,
	   0x0001d020 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_9, ev_ch_e_cntxt_9,
	   0x0001d024 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_10, ev_ch_e_cntxt_10,
	   0x0001d028 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_11, ev_ch_e_cntxt_11,
	   0x0001d02c + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_12, ev_ch_e_cntxt_12,
	   0x0001d030 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_CNTXT_13, ev_ch_e_cntxt_13,
	   0x0001d034 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_SCRATCH_0, ev_ch_e_scratch_0,
	   0x0001d048 + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(EV_CH_E_SCRATCH_1, ev_ch_e_scratch_1,
	   0x0001d04c + 0x4000 * GSI_EE_AP, 0x80);

REG_STRIDE(CH_C_DOORBELL_0, ch_c_doorbell_0,
	   0x0001e000 + 0x4000 * GSI_EE_AP, 0x08);

REG_STRIDE(EV_CH_E_DOORBELL_0, ev_ch_e_doorbell_0,
	   0x0001e100 + 0x4000 * GSI_EE_AP, 0x08);

static const struct reg *reg_array[] = {
	[CH_C_CNTXT_0]			= &reg_ch_c_cntxt_0,
	[CH_C_CNTXT_1]			= &reg_ch_c_cntxt_1,
@@ -43,7 +85,21 @@ static const struct reg *reg_array[] = {
	[CH_C_SCRATCH_1]		= &reg_ch_c_scratch_1,
	[CH_C_SCRATCH_2]		= &reg_ch_c_scratch_2,
	[CH_C_SCRATCH_3]		= &reg_ch_c_scratch_3,
	[EV_CH_E_CNTXT_0]		= &reg_ev_ch_e_cntxt_0,
	[EV_CH_E_CNTXT_1]		= &reg_ev_ch_e_cntxt_1,
	[EV_CH_E_CNTXT_2]		= &reg_ev_ch_e_cntxt_2,
	[EV_CH_E_CNTXT_3]		= &reg_ev_ch_e_cntxt_3,
	[EV_CH_E_CNTXT_4]		= &reg_ev_ch_e_cntxt_4,
	[EV_CH_E_CNTXT_8]		= &reg_ev_ch_e_cntxt_8,
	[EV_CH_E_CNTXT_9]		= &reg_ev_ch_e_cntxt_9,
	[EV_CH_E_CNTXT_10]		= &reg_ev_ch_e_cntxt_10,
	[EV_CH_E_CNTXT_11]		= &reg_ev_ch_e_cntxt_11,
	[EV_CH_E_CNTXT_12]		= &reg_ev_ch_e_cntxt_12,
	[EV_CH_E_CNTXT_13]		= &reg_ev_ch_e_cntxt_13,
	[EV_CH_E_SCRATCH_0]		= &reg_ev_ch_e_scratch_0,
	[EV_CH_E_SCRATCH_1]		= &reg_ev_ch_e_scratch_1,
	[CH_C_DOORBELL_0]		= &reg_ch_c_doorbell_0,
	[EV_CH_E_DOORBELL_0]		= &reg_ev_ch_e_doorbell_0,
};

const struct regs gsi_regs_v3_1 = {