2434 lines · 67.8 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2018-2024 Linaro Ltd. */ #include <linux/bits.h>#include <linux/bug.h>#include <linux/completion.h>#include <linux/interrupt.h>#include <linux/mutex.h>#include <linux/netdevice.h>#include <linux/platform_device.h>#include <linux/types.h> #include "gsi.h"#include "gsi_private.h"#include "gsi_reg.h"#include "gsi_trans.h"#include "ipa_data.h"#include "ipa_gsi.h"#include "ipa_version.h"#include "reg.h" /** * DOC: The IPA Generic Software Interface * * The generic software interface (GSI) is an integral component of the IPA, * providing a well-defined communication layer between the AP subsystem * and the IPA core.  The modem uses the GSI layer as well. * *	--------	     --------- *	|      |	     |	     | *	|  AP  +<---.	.----+ Modem | *	|      +--. |	| .->+	     | *	|      |  | |	| |  |	     | *	--------  | |	| |  --------- *		  v |	v | *		--+-+---+-+-- *		|    GSI    | *		|-----------| *		|	    | *		|    IPA    | *		|	    | *		------------- * * In the above diagram, the AP and Modem represent "execution environments" * (EEs), which are independent operating environments that use the IPA for * data transfer. * * Each EE uses a set of unidirectional GSI "channels," which allow transfer * of data to or from the IPA.  A channel is implemented as a ring buffer, * with a DRAM-resident array of "transfer elements" (TREs) available to * describe transfers to or from other EEs through the IPA.  A transfer * element can also contain an immediate command, requesting the IPA perform * actions other than data transfer. * * Each TRE refers to a block of data--also located in DRAM.  After writing * one or more TREs to a channel, the writer (either the IPA or an EE) writes * a doorbell register to inform the receiving side how many elements have * been written. * * Each channel has a GSI "event ring" associated with it.  An event ring * is implemented very much like a channel ring, but is always directed from * the IPA to an EE.  The IPA notifies an EE (such as the AP) about channel * events by adding an entry to the event ring associated with the channel. * The GSI then writes its doorbell for the event ring, causing the target * EE to be interrupted.  Each entry in an event ring contains a pointer * to the channel TRE whose completion the event represents. * * Each TRE in a channel ring has a set of flags.  One flag indicates whether * the completion of the transfer operation generates an entry (and possibly * an interrupt) in the channel's event ring.  Other flags allow transfer * elements to be chained together, forming a single logical transaction. * TRE flags are used to control whether and when interrupts are generated * to signal completion of channel transfers. * * Elements in channel and event rings are completed (or consumed) strictly * in order.  Completion of one entry implies the completion of all preceding * entries.  A single completion interrupt can therefore communicate the * completion of many transfers. * * Note that all GSI registers are little-endian, which is the assumed * endianness of I/O space accesses.  The accessor functions perform byte * swapping if needed (i.e., for a big endian CPU). */ /* Delay period for interrupt moderation (in 32KHz IPA internal timer ticks) */#define GSI_EVT_RING_INT_MODT		(32 * 1) /* 1ms under 32KHz clock */ #define GSI_CMD_TIMEOUT			50	/* milliseconds */ #define GSI_CHANNEL_STOP_RETRIES	10#define GSI_CHANNEL_MODEM_HALT_RETRIES	10#define GSI_CHANNEL_MODEM_FLOW_RETRIES	5	/* disable flow control only */ #define GSI_MHI_EVENT_ID_START		10	/* 1st reserved event id */#define GSI_MHI_EVENT_ID_END		16	/* Last reserved event id */ #define GSI_ISR_MAX_ITER		50	/* Detect interrupt storms */ /* An entry in an event ring */struct gsi_event {	__le64 xfer_ptr;	__le16 len;	u8 reserved1;	u8 code;	__le16 reserved2;	u8 type;	u8 chid;}; /** gsi_channel_scratch_gpi - GPI protocol scratch register * @max_outstanding_tre: *	Defines the maximum number of TREs allowed in a single transaction *	on a channel (in bytes).  This determines the amount of prefetch *	performed by the hardware.  We configure this to equal the size of *	the TLV FIFO for the channel. * @outstanding_threshold: *	Defines the threshold (in bytes) determining when the sequencer *	should update the channel doorbell.  We configure this to equal *	the size of two TREs. */struct gsi_channel_scratch_gpi {	u64 reserved1;	u16 reserved2;	u16 max_outstanding_tre;	u16 reserved3;	u16 outstanding_threshold;}; /** gsi_channel_scratch - channel scratch configuration area * * The exact interpretation of this register is protocol-specific. * We only use GPI channels; see struct gsi_channel_scratch_gpi, above. */union gsi_channel_scratch {	struct gsi_channel_scratch_gpi gpi;	struct {		u32 word1;		u32 word2;		u32 word3;		u32 word4;	} data;}; /* Check things that can be validated at build time. */static void gsi_validate_build(void){	/* This is used as a divisor */	BUILD_BUG_ON(!GSI_RING_ELEMENT_SIZE); 	/* Code assumes the size of channel and event ring element are	 * the same (and fixed).  Make sure the size of an event ring	 * element is what's expected.	 */	BUILD_BUG_ON(sizeof(struct gsi_event) != GSI_RING_ELEMENT_SIZE); 	/* Hardware requires a 2^n ring size.  We ensure the number of	 * elements in an event ring is a power of 2 elsewhere; this	 * ensure the elements themselves meet the requirement.	 */	BUILD_BUG_ON(!is_power_of_2(GSI_RING_ELEMENT_SIZE));} /* Return the channel id associated with a given channel */static u32 gsi_channel_id(struct gsi_channel *channel){	return channel - &channel->gsi->channel[0];} /* An initialized channel has a non-null GSI pointer */static bool gsi_channel_initialized(struct gsi_channel *channel){	return !!channel->gsi;} /* 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 = reg_encode(reg, CHTYPE_PROTOCOL, type);	if (version < IPA_VERSION_4_5 || version >= IPA_VERSION_5_0)		return val; 	type >>= hweight32(reg_fmask(reg, CHTYPE_PROTOCOL)); 	return val | reg_encode(reg, CHTYPE_PROTOCOL_MSB, type);} /* Update the GSI IRQ type register with the cached value */static void gsi_irq_type_update(struct gsi *gsi, u32 val){	const struct reg *reg = gsi_reg(gsi, CNTXT_TYPE_IRQ_MSK); 	gsi->type_enabled_bitmap = val;	iowrite32(val, gsi->virt + reg_offset(reg));} static void gsi_irq_type_enable(struct gsi *gsi, enum gsi_irq_type_id type_id){	gsi_irq_type_update(gsi, gsi->type_enabled_bitmap | type_id);} static void gsi_irq_type_disable(struct gsi *gsi, enum gsi_irq_type_id type_id){	gsi_irq_type_update(gsi, gsi->type_enabled_bitmap & ~type_id);} /* Event ring commands are performed one at a time.  Their completion * is signaled by the event ring control GSI interrupt type, which is * only enabled when we issue an event ring command.  Only the event * ring being operated on has this interrupt enabled. */static void gsi_irq_ev_ctrl_enable(struct gsi *gsi, u32 evt_ring_id){	u32 val = BIT(evt_ring_id);	const struct reg *reg; 	/* There's a small chance that a previous command completed	 * after the interrupt was disabled, so make sure we have no	 * pending interrupts before we enable them.	 */	reg = gsi_reg(gsi, CNTXT_SRC_EV_CH_IRQ_CLR);	iowrite32(~0, gsi->virt + reg_offset(reg)); 	reg = gsi_reg(gsi, CNTXT_SRC_EV_CH_IRQ_MSK);	iowrite32(val, gsi->virt + reg_offset(reg));	gsi_irq_type_enable(gsi, GSI_EV_CTRL);} /* Disable event ring control interrupts */static void gsi_irq_ev_ctrl_disable(struct gsi *gsi){	const struct reg *reg; 	gsi_irq_type_disable(gsi, GSI_EV_CTRL); 	reg = gsi_reg(gsi, CNTXT_SRC_EV_CH_IRQ_MSK);	iowrite32(0, gsi->virt + reg_offset(reg));} /* Channel commands are performed one at a time.  Their completion is * signaled by the channel control GSI interrupt type, which is only * enabled when we issue a channel command.  Only the channel being * operated on has this interrupt enabled. */static void gsi_irq_ch_ctrl_enable(struct gsi *gsi, u32 channel_id){	u32 val = BIT(channel_id);	const struct reg *reg; 	/* There's a small chance that a previous command completed	 * after the interrupt was disabled, so make sure we have no	 * pending interrupts before we enable them.	 */	reg = gsi_reg(gsi, CNTXT_SRC_CH_IRQ_CLR);	iowrite32(~0, gsi->virt + reg_offset(reg)); 	reg = gsi_reg(gsi, CNTXT_SRC_CH_IRQ_MSK);	iowrite32(val, gsi->virt + reg_offset(reg)); 	gsi_irq_type_enable(gsi, GSI_CH_CTRL);} /* Disable channel control interrupts */static void gsi_irq_ch_ctrl_disable(struct gsi *gsi){	const struct reg *reg; 	gsi_irq_type_disable(gsi, GSI_CH_CTRL); 	reg = gsi_reg(gsi, CNTXT_SRC_CH_IRQ_MSK);	iowrite32(0, gsi->virt + reg_offset(reg));} static void gsi_irq_ieob_enable_one(struct gsi *gsi, u32 evt_ring_id){	bool enable_ieob = !gsi->ieob_enabled_bitmap;	const struct reg *reg;	u32 val; 	gsi->ieob_enabled_bitmap |= BIT(evt_ring_id); 	reg = gsi_reg(gsi, CNTXT_SRC_IEOB_IRQ_MSK);	val = gsi->ieob_enabled_bitmap;	iowrite32(val, gsi->virt + reg_offset(reg)); 	/* Enable the interrupt type if this is the first channel enabled */	if (enable_ieob)		gsi_irq_type_enable(gsi, GSI_IEOB);} static void gsi_irq_ieob_disable(struct gsi *gsi, u32 event_mask){	const struct reg *reg;	u32 val; 	gsi->ieob_enabled_bitmap &= ~event_mask; 	/* Disable the interrupt type if this was the last enabled channel */	if (!gsi->ieob_enabled_bitmap)		gsi_irq_type_disable(gsi, GSI_IEOB); 	reg = gsi_reg(gsi, CNTXT_SRC_IEOB_IRQ_MSK);	val = gsi->ieob_enabled_bitmap;	iowrite32(val, gsi->virt + reg_offset(reg));} static void gsi_irq_ieob_disable_one(struct gsi *gsi, u32 evt_ring_id){	gsi_irq_ieob_disable(gsi, BIT(evt_ring_id));} /* Enable all GSI_interrupt types */static void gsi_irq_enable(struct gsi *gsi){	const struct reg *reg;	u32 val; 	/* Global interrupts include hardware error reports.  Enable	 * that so we can at least report the error should it occur.	 */	reg = gsi_reg(gsi, CNTXT_GLOB_IRQ_EN);	iowrite32(ERROR_INT, gsi->virt + reg_offset(reg)); 	gsi_irq_type_update(gsi, gsi->type_enabled_bitmap | GSI_GLOB_EE); 	/* General GSI interrupts are reported to all EEs; if they occur	 * they are unrecoverable (without reset).  A breakpoint interrupt	 * also exists, but we don't support that.  We want to be notified	 * of errors so we can report them, even if they can't be handled.	 */	reg = gsi_reg(gsi, CNTXT_GSI_IRQ_EN);	val = BUS_ERROR;	val |= CMD_FIFO_OVRFLOW;	val |= MCS_STACK_OVRFLOW;	iowrite32(val, gsi->virt + reg_offset(reg)); 	gsi_irq_type_update(gsi, gsi->type_enabled_bitmap | GSI_GENERAL);} /* Disable all GSI interrupt types */static void gsi_irq_disable(struct gsi *gsi){	const struct reg *reg; 	gsi_irq_type_update(gsi, 0); 	/* Clear the type-specific interrupt masks set by gsi_irq_enable() */	reg = gsi_reg(gsi, CNTXT_GSI_IRQ_EN);	iowrite32(0, gsi->virt + reg_offset(reg)); 	reg = gsi_reg(gsi, CNTXT_GLOB_IRQ_EN);	iowrite32(0, gsi->virt + reg_offset(reg));} /* Return the virtual address associated with a ring index */void *gsi_ring_virt(struct gsi_ring *ring, u32 index){	/* Note: index *must* be used modulo the ring count here */	return ring->virt + (index % ring->count) * GSI_RING_ELEMENT_SIZE;} /* Return the 32-bit DMA address associated with a ring index */static u32 gsi_ring_addr(struct gsi_ring *ring, u32 index){	return lower_32_bits(ring->addr) + index * GSI_RING_ELEMENT_SIZE;} /* Return the ring index of a 32-bit ring offset */static u32 gsi_ring_index(struct gsi_ring *ring, u32 offset){	return (offset - gsi_ring_addr(ring, 0)) / GSI_RING_ELEMENT_SIZE;} /* Issue a GSI command by writing a value to a register, then wait for * completion to be signaled.  Returns true if the command completes * or false if it times out. */static bool gsi_command(struct gsi *gsi, u32 reg, u32 val){	unsigned long timeout = msecs_to_jiffies(GSI_CMD_TIMEOUT);	struct completion *completion = &gsi->completion; 	reinit_completion(completion); 	iowrite32(val, gsi->virt + reg); 	return !!wait_for_completion_timeout(completion, timeout);} /* Return the hardware's notion of the current state of an event ring */static enum gsi_evt_ring_stategsi_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 + reg_n_offset(reg, evt_ring_id)); 	return reg_decode(reg, EV_CHSTATE, val);} /* Issue an event ring command and wait for it to complete */static void gsi_evt_ring_command(struct gsi *gsi, u32 evt_ring_id,				 enum gsi_evt_cmd_opcode opcode){	struct device *dev = gsi->dev;	const struct reg *reg;	bool timeout;	u32 val; 	/* Enable the completion interrupt for the command */	gsi_irq_ev_ctrl_enable(gsi, evt_ring_id); 	reg = gsi_reg(gsi, EV_CH_CMD);	val = reg_encode(reg, EV_CHID, evt_ring_id);	val |= reg_encode(reg, EV_OPCODE, opcode); 	timeout = !gsi_command(gsi, reg_offset(reg), val); 	gsi_irq_ev_ctrl_disable(gsi); 	if (!timeout)		return; 	dev_err(dev, "GSI command %u for event ring %u timed out, state %u\n",		opcode, evt_ring_id, gsi_evt_ring_state(gsi, evt_ring_id));} /* Allocate an event ring in NOT_ALLOCATED state */static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id){	enum gsi_evt_ring_state state; 	/* Get initial event ring state */	state = gsi_evt_ring_state(gsi, evt_ring_id);	if (state != GSI_EVT_RING_STATE_NOT_ALLOCATED) {		dev_err(gsi->dev, "event ring %u bad state %u before alloc\n",			evt_ring_id, state);		return -EINVAL;	} 	gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_ALLOCATE); 	/* If successful the event ring state will have changed */	state = gsi_evt_ring_state(gsi, evt_ring_id);	if (state == GSI_EVT_RING_STATE_ALLOCATED)		return 0; 	dev_err(gsi->dev, "event ring %u bad state %u after alloc\n",		evt_ring_id, state); 	return -EIO;} /* Reset a GSI event ring in ALLOCATED or ERROR state. */static void gsi_evt_ring_reset_command(struct gsi *gsi, u32 evt_ring_id){	enum gsi_evt_ring_state state; 	state = gsi_evt_ring_state(gsi, evt_ring_id);	if (state != GSI_EVT_RING_STATE_ALLOCATED &&	    state != GSI_EVT_RING_STATE_ERROR) {		dev_err(gsi->dev, "event ring %u bad state %u before reset\n",			evt_ring_id, state);		return;	} 	gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET); 	/* If successful the event ring state will have changed */	state = gsi_evt_ring_state(gsi, evt_ring_id);	if (state == GSI_EVT_RING_STATE_ALLOCATED)		return; 	dev_err(gsi->dev, "event ring %u bad state %u after reset\n",		evt_ring_id, state);} /* Issue a hardware de-allocation request for an allocated event ring */static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id){	enum gsi_evt_ring_state state; 	state = gsi_evt_ring_state(gsi, evt_ring_id);	if (state != GSI_EVT_RING_STATE_ALLOCATED) {		dev_err(gsi->dev, "event ring %u state %u before dealloc\n",			evt_ring_id, state);		return;	} 	gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC); 	/* If successful the event ring state will have changed */	state = gsi_evt_ring_state(gsi, evt_ring_id);

Lines 1–500 of 2434.