net: ipa: update comments
This patch just updates comments throughout the IPA code. Transaction state is now tracked using indexes into an array rather than linked lists, and a few comments refer to the "old way" of doing things. The description of how transactions are used was changed to refer to "operations" rather than "commands", to (hopefully) remove a possible ambiguity. IPA register offsets and fields are now handled differently as well, and the register documentation is updated to better describe the code. A few minor updates to comments were made (e.g., adding a missing word, fixing a typo or punctuation, etc.). Finally, the local macro atomic_dec_not_zero() is no longer used, so it is deleted. Signed-off-by: Alex Elder <elder@linaro.org> Link: https://lore.kernel.org/r/20220930224527.3503404-1-elder@linaro.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
450a580fc4
commit
ace5dc6162
@ -56,9 +56,9 @@
|
||||
* 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 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
|
||||
* 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
|
||||
@ -1347,8 +1347,8 @@ gsi_event_trans(struct gsi *gsi, struct gsi_event *event)
|
||||
* we update transactions to record their actual received lengths.
|
||||
*
|
||||
* When an event for a TX channel arrives we use information in the
|
||||
* transaction to report the number of requests and bytes have been
|
||||
* transferred.
|
||||
* transaction to report the number of requests and bytes that have
|
||||
* been transferred.
|
||||
*
|
||||
* This function is called whenever we learn that the GSI hardware has filled
|
||||
* new events since the last time we checked. The ring's index field tells
|
||||
@ -1474,7 +1474,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel)
|
||||
iowrite32(val, gsi->virt + GSI_CH_C_DOORBELL_0_OFFSET(channel_id));
|
||||
}
|
||||
|
||||
/* Consult hardware, move any newly completed transactions to completed list */
|
||||
/* Consult hardware, move newly completed transactions to completed state */
|
||||
void gsi_channel_update(struct gsi_channel *channel)
|
||||
{
|
||||
u32 evt_ring_id = channel->evt_ring_id;
|
||||
@ -1515,17 +1515,17 @@ void gsi_channel_update(struct gsi_channel *channel)
|
||||
*
|
||||
* Return: Transaction pointer, or null if none are available
|
||||
*
|
||||
* This function returns the first entry on a channel's completed transaction
|
||||
* list. If that list is empty, the hardware is consulted to determine
|
||||
* whether any new transactions have completed. If so, they're moved to the
|
||||
* completed list and the new first entry is returned. If there are no more
|
||||
* completed transactions, a null pointer is returned.
|
||||
* This function returns the first of a channel's completed transactions.
|
||||
* If no transactions are in completed state, the hardware is consulted to
|
||||
* determine whether any new transactions have completed. If so, they're
|
||||
* moved to completed state and the first such transaction is returned.
|
||||
* If there are no more completed transactions, a null pointer is returned.
|
||||
*/
|
||||
static struct gsi_trans *gsi_channel_poll_one(struct gsi_channel *channel)
|
||||
{
|
||||
struct gsi_trans *trans;
|
||||
|
||||
/* Get the first transaction from the completed list */
|
||||
/* Get the first completed transaction */
|
||||
trans = gsi_channel_trans_complete(channel);
|
||||
if (trans)
|
||||
gsi_trans_move_polled(trans);
|
||||
|
@ -18,13 +18,13 @@ struct gsi_channel;
|
||||
|
||||
/**
|
||||
* gsi_trans_move_complete() - Mark a GSI transaction completed
|
||||
* @trans: Transaction to commit
|
||||
* @trans: Transaction whose state is to be updated
|
||||
*/
|
||||
void gsi_trans_move_complete(struct gsi_trans *trans);
|
||||
|
||||
/**
|
||||
* gsi_trans_move_polled() - Mark a transaction polled
|
||||
* @trans: Transaction to update
|
||||
* @trans: Transaction whose state is to be updated
|
||||
*/
|
||||
void gsi_trans_move_polled(struct gsi_trans *trans);
|
||||
|
||||
@ -97,8 +97,8 @@ void gsi_channel_doorbell(struct gsi_channel *channel);
|
||||
/* gsi_channel_update() - Update knowledge of channel hardware state
|
||||
* @channel: Channel to be updated
|
||||
*
|
||||
* Consult hardware, move any newly completed transactions to a
|
||||
* channel's completed list.
|
||||
* Consult hardware, change the state of any newly-completed transactions
|
||||
* on a channel.
|
||||
*/
|
||||
void gsi_channel_update(struct gsi_channel *channel);
|
||||
|
||||
|
@ -22,37 +22,36 @@
|
||||
* DOC: GSI Transactions
|
||||
*
|
||||
* A GSI transaction abstracts the behavior of a GSI channel by representing
|
||||
* everything about a related group of IPA commands in a single structure.
|
||||
* (A "command" in this sense is either a data transfer or an IPA immediate
|
||||
* everything about a related group of IPA operations in a single structure.
|
||||
* (A "operation" in this sense is either a data transfer or an IPA immediate
|
||||
* command.) Most details of interaction with the GSI hardware are managed
|
||||
* by the GSI transaction core, allowing users to simply describe commands
|
||||
* by the GSI transaction core, allowing users to simply describe operations
|
||||
* to be performed. When a transaction has completed a callback function
|
||||
* (dependent on the type of endpoint associated with the channel) allows
|
||||
* cleanup of resources associated with the transaction.
|
||||
*
|
||||
* To perform a command (or set of them), a user of the GSI transaction
|
||||
* To perform an operation (or set of them), a user of the GSI transaction
|
||||
* interface allocates a transaction, indicating the number of TREs required
|
||||
* (one per command). If sufficient TREs are available, they are reserved
|
||||
* (one per operation). If sufficient TREs are available, they are reserved
|
||||
* for use in the transaction and the allocation succeeds. This way
|
||||
* exhaustion of the available TREs in a channel ring is detected
|
||||
* as early as possible. All resources required to complete a transaction
|
||||
* are allocated at transaction allocation time.
|
||||
* exhaustion of the available TREs in a channel ring is detected as early
|
||||
* as possible. Any other resources that might be needed to complete a
|
||||
* transaction are also allocated when the transaction is allocated.
|
||||
*
|
||||
* Commands performed as part of a transaction are represented in an array
|
||||
* of Linux scatterlist structures. This array is allocated with the
|
||||
* transaction, and its entries are initialized using standard scatterlist
|
||||
* functions (such as sg_set_buf() or skb_to_sgvec()).
|
||||
* Operations performed as part of a transaction are represented in an array
|
||||
* of Linux scatterlist structures, allocated with the transaction. These
|
||||
* scatterlist structures are initialized by "adding" operations to the
|
||||
* transaction. If a buffer in an operation must be mapped for DMA, this is
|
||||
* done at the time it is added to the transaction. It is possible for a
|
||||
* mapping error to occur when an operation is added. In this case the
|
||||
* transaction should simply be freed; this correctly releases resources
|
||||
* associated with the transaction.
|
||||
*
|
||||
* Once a transaction's scatterlist structures have been initialized, the
|
||||
* transaction is committed. The caller is responsible for mapping buffers
|
||||
* for DMA if necessary, and this should be done *before* allocating
|
||||
* the transaction. Between a successful allocation and commit of a
|
||||
* transaction no errors should occur.
|
||||
*
|
||||
* Committing transfers ownership of the entire transaction to the GSI
|
||||
* transaction core. The GSI transaction code formats the content of
|
||||
* the scatterlist array into the channel ring buffer and informs the
|
||||
* hardware that new TREs are available to process.
|
||||
* Once all operations have been successfully added to a transaction, the
|
||||
* transaction is committed. Committing transfers ownership of the entire
|
||||
* transaction to the GSI transaction core. The GSI transaction code
|
||||
* formats the content of the scatterlist array into the channel ring
|
||||
* buffer and informs the hardware that new TREs are available to process.
|
||||
*
|
||||
* The last TRE in each transaction is marked to interrupt the AP when the
|
||||
* GSI hardware has completed it. Because transfers described by TREs are
|
||||
@ -125,11 +124,10 @@ void gsi_trans_pool_exit(struct gsi_trans_pool *pool)
|
||||
memset(pool, 0, sizeof(*pool));
|
||||
}
|
||||
|
||||
/* Allocate the requested number of (zeroed) entries from the pool */
|
||||
/* Home-grown DMA pool. This way we can preallocate and use the tre_count
|
||||
* to guarantee allocations will succeed. Even though we specify max_alloc
|
||||
* (and it can be more than one), we only allow allocation of a single
|
||||
* element from a DMA pool.
|
||||
/* Home-grown DMA pool. This way we can preallocate the pool, and guarantee
|
||||
* allocations will succeed. The immediate commands in a transaction can
|
||||
* require up to max_alloc elements from the pool. But we only allow
|
||||
* allocation of a single element from a DMA pool at a time.
|
||||
*/
|
||||
int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
|
||||
size_t size, u32 count, u32 max_alloc)
|
||||
@ -537,8 +535,8 @@ static void gsi_trans_tre_fill(struct gsi_tre *dest_tre, dma_addr_t addr,
|
||||
*
|
||||
* Formats channel ring TRE entries based on the content of the scatterlist.
|
||||
* Maps a transaction pointer to the last ring entry used for the transaction,
|
||||
* so it can be recovered when it completes. Moves the transaction to the
|
||||
* pending list. Finally, updates the channel ring pointer and optionally
|
||||
* so it can be recovered when it completes. Moves the transaction to
|
||||
* pending state. Finally, updates the channel ring pointer and optionally
|
||||
* rings the doorbell.
|
||||
*/
|
||||
static void __gsi_trans_commit(struct gsi_trans *trans, bool ring_db)
|
||||
|
@ -74,7 +74,7 @@ struct gsi_trans {
|
||||
|
||||
/**
|
||||
* gsi_trans_pool_init() - Initialize a pool of structures for transactions
|
||||
* @pool: GSI transaction poll pointer
|
||||
* @pool: GSI transaction pool pointer
|
||||
* @size: Size of elements in the pool
|
||||
* @count: Minimum number of elements in the pool
|
||||
* @max_alloc: Maximum number of elements allocated at a time from pool
|
||||
|
@ -32,7 +32,7 @@
|
||||
* immediate command's opcode. The payload for a command resides in AP
|
||||
* memory and is described by a single scatterlist entry in its transaction.
|
||||
* Commands do not require a transaction completion callback, and are
|
||||
* (currently) always issued using gsi_trans_commit_wait().
|
||||
* always issued using gsi_trans_commit_wait().
|
||||
*/
|
||||
|
||||
/* Some commands can wait until indicated pipeline stages are clear */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* communication path between the IPA and a particular execution environment
|
||||
* (EE), such as the AP or Modem. Each EE has a set of channels associated
|
||||
* with it, and each channel has an ID unique for that EE. For the most part
|
||||
* the only GSI channels of concern to this driver belong to the AP
|
||||
* the only GSI channels of concern to this driver belong to the AP.
|
||||
*
|
||||
* An endpoint is an IPA construct representing a single channel anywhere
|
||||
* in the system. An IPA endpoint ID maps directly to an (EE, channel_id)
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include "ipa_gsi.h"
|
||||
#include "ipa_power.h"
|
||||
|
||||
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
|
||||
|
||||
/* Hardware is told about receive buffers once a "batch" has been queued */
|
||||
#define IPA_REPLENISH_BATCH 16 /* Must be non-zero */
|
||||
|
||||
|
@ -17,53 +17,38 @@ struct ipa;
|
||||
* DOC: IPA Registers
|
||||
*
|
||||
* IPA registers are located within the "ipa-reg" address space defined by
|
||||
* Device Tree. The offset of each register within that space is specified
|
||||
* by symbols defined below. The address space is mapped to virtual memory
|
||||
* space in ipa_mem_init(). All IPA registers are 32 bits wide.
|
||||
* Device Tree. Each register has a specified offset within that space,
|
||||
* which is mapped into virtual memory space in ipa_mem_init(). Each
|
||||
* has a unique identifer, taken from the ipa_reg_id enumerated type.
|
||||
* All IPA registers are 32 bits wide.
|
||||
*
|
||||
* Certain register types are duplicated for a number of instances of
|
||||
* something. For example, each IPA endpoint has an set of registers
|
||||
* defining its configuration. The offset to an endpoint's set of registers
|
||||
* is computed based on an "base" offset, plus an endpoint's ID multiplied
|
||||
* and a "stride" value for the register. For such registers, the offset is
|
||||
* computed by a function-like macro that takes a parameter used in the
|
||||
* computation.
|
||||
* Certain "parameterized" register types are duplicated for a number of
|
||||
* instances of something. For example, each IPA endpoint has an set of
|
||||
* registers defining its configuration. The offset to an endpoint's set
|
||||
* of registers is computed based on an "base" offset, plus an endpoint's
|
||||
* ID multiplied and a "stride" value for the register. Similarly, some
|
||||
* registers have an offset that depends on execution environment. In
|
||||
* this case, the stride is multiplied by a member of the gsi_ee_id
|
||||
* enumerated type.
|
||||
*
|
||||
* Some register offsets depend on execution environment. For these an "ee"
|
||||
* parameter is supplied to the offset macro. The "ee" value is a member of
|
||||
* the gsi_ee enumerated type.
|
||||
* Each version of IPA implements an array of ipa_reg structures indexed
|
||||
* by register ID. Each entry in the array specifies the base offset and
|
||||
* (for parameterized registers) a non-zero stride value. Not all versions
|
||||
* of IPA define all registers. The offset for a register is returned by
|
||||
* ipa_reg_offset() when the register's ipa_reg structure is supplied;
|
||||
* zero is returned for an undefined register (this should never happen).
|
||||
*
|
||||
* The offset of a register dependent on endpoint ID is computed by a macro
|
||||
* that is supplied a parameter "ep", "txep", or "rxep". A register with an
|
||||
* "ep" parameter is valid for any endpoint; a register with a "txep" or
|
||||
* "rxep" parameter is valid only for TX or RX endpoints, respectively. The
|
||||
* "*ep" value is assumed to be less than the maximum valid endpoint ID
|
||||
* for the current hardware, and that will not exceed IPA_ENDPOINT_MAX.
|
||||
*
|
||||
* The offset of registers related to filter and route tables is computed
|
||||
* by a macro that is supplied a parameter "er". The "er" represents an
|
||||
* endpoint ID for filters, or a route ID for routes. For filters, the
|
||||
* endpoint ID must be less than IPA_ENDPOINT_MAX, but is further restricted
|
||||
* because not all endpoints support filtering. For routes, the route ID
|
||||
* must be less than IPA_ROUTE_MAX.
|
||||
*
|
||||
* The offset of registers related to resource types is computed by a macro
|
||||
* that is supplied a parameter "rt". The "rt" represents a resource type,
|
||||
* which is a member of the ipa_resource_type_src enumerated type for
|
||||
* source endpoint resources or the ipa_resource_type_dst enumerated type
|
||||
* for destination endpoint resources.
|
||||
*
|
||||
* Some registers encode multiple fields within them. For these, each field
|
||||
* has a symbol below defining a field mask that encodes both the position
|
||||
* and width of the field within its register.
|
||||
*
|
||||
* In some cases, different versions of IPA hardware use different offset or
|
||||
* field mask values. In such cases an inline_function(ipa) is used rather
|
||||
* than a MACRO to define the offset or field mask to use.
|
||||
*
|
||||
* Finally, some registers hold bitmasks representing endpoints. In such
|
||||
* cases the @available field in the @ipa structure defines the "full" set
|
||||
* of valid bits for the register.
|
||||
* Some registers encode multiple fields within them. Each field in
|
||||
* such a register has a unique identifier (from an enumerated type).
|
||||
* The position and width of the fields in a register are defined by
|
||||
* an array of field masks, indexed by field ID. Two functions are
|
||||
* used to access register fields; both take an ipa_reg structure as
|
||||
* argument. To encode a value to be represented in a register field,
|
||||
* the value and field ID are passed to ipa_reg_encode(). To extract
|
||||
* a value encoded in a register field, the field ID is passed to
|
||||
* ipa_reg_decode(). In addition, for single-bit fields, ipa_reg_bit()
|
||||
* can be used to either encode the bit value, or to generate a mask
|
||||
* used to extract the bit value.
|
||||
*/
|
||||
|
||||
/* enum ipa_reg_id - IPA register IDs */
|
||||
|
Loading…
Reference in New Issue
Block a user