mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-29 12:19:39 +00:00
![Shannon Nelson](/assets/img/avatar_default.png)
The devcmd interface is the basic connection to the device through the PCI BAR for low level identification and command services. This does the early device initialization and finds the identity data, and adds devcmd routines to be used by later driver bits. Signed-off-by: Shannon Nelson <shannon.nelson@amd.com> Acked-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
163 lines
5.9 KiB
C
163 lines
5.9 KiB
C
/* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */
|
|
/* Copyright(c) 2023 Advanced Micro Devices, Inc. */
|
|
|
|
#ifndef _PDS_INTR_H_
|
|
#define _PDS_INTR_H_
|
|
|
|
/*
|
|
* Interrupt control register
|
|
* @coal_init: Coalescing timer initial value, in
|
|
* device units. Use @identity->intr_coal_mult
|
|
* and @identity->intr_coal_div to convert from
|
|
* usecs to device units:
|
|
*
|
|
* coal_init = coal_usecs * coal_mutl / coal_div
|
|
*
|
|
* When an interrupt is sent the interrupt
|
|
* coalescing timer current value
|
|
* (@coalescing_curr) is initialized with this
|
|
* value and begins counting down. No more
|
|
* interrupts are sent until the coalescing
|
|
* timer reaches 0. When @coalescing_init=0
|
|
* interrupt coalescing is effectively disabled
|
|
* and every interrupt assert results in an
|
|
* interrupt. Reset value: 0
|
|
* @mask: Interrupt mask. When @mask=1 the interrupt
|
|
* resource will not send an interrupt. When
|
|
* @mask=0 the interrupt resource will send an
|
|
* interrupt if an interrupt event is pending
|
|
* or on the next interrupt assertion event.
|
|
* Reset value: 1
|
|
* @credits: Interrupt credits. This register indicates
|
|
* how many interrupt events the hardware has
|
|
* sent. When written by software this
|
|
* register atomically decrements @int_credits
|
|
* by the value written. When @int_credits
|
|
* becomes 0 then the "pending interrupt" bit
|
|
* in the Interrupt Status register is cleared
|
|
* by the hardware and any pending but unsent
|
|
* interrupts are cleared.
|
|
* !!!IMPORTANT!!! This is a signed register.
|
|
* @flags: Interrupt control flags
|
|
* @unmask -- When this bit is written with a 1
|
|
* the interrupt resource will set mask=0.
|
|
* @coal_timer_reset -- When this
|
|
* bit is written with a 1 the
|
|
* @coalescing_curr will be reloaded with
|
|
* @coalescing_init to reset the coalescing
|
|
* timer.
|
|
* @mask_on_assert: Automatically mask on assertion. When
|
|
* @mask_on_assert=1 the interrupt resource
|
|
* will set @mask=1 whenever an interrupt is
|
|
* sent. When using interrupts in Legacy
|
|
* Interrupt mode the driver must select
|
|
* @mask_on_assert=0 for proper interrupt
|
|
* operation.
|
|
* @coalescing_curr: Coalescing timer current value, in
|
|
* microseconds. When this value reaches 0
|
|
* the interrupt resource is again eligible to
|
|
* send an interrupt. If an interrupt event
|
|
* is already pending when @coalescing_curr
|
|
* reaches 0 the pending interrupt will be
|
|
* sent, otherwise an interrupt will be sent
|
|
* on the next interrupt assertion event.
|
|
*/
|
|
struct pds_core_intr {
|
|
u32 coal_init;
|
|
u32 mask;
|
|
u16 credits;
|
|
u16 flags;
|
|
#define PDS_CORE_INTR_F_UNMASK 0x0001
|
|
#define PDS_CORE_INTR_F_TIMER_RESET 0x0002
|
|
u32 mask_on_assert;
|
|
u32 coalescing_curr;
|
|
u32 rsvd6[3];
|
|
};
|
|
|
|
#ifndef __CHECKER__
|
|
static_assert(sizeof(struct pds_core_intr) == 32);
|
|
#endif /* __CHECKER__ */
|
|
|
|
#define PDS_CORE_INTR_CTRL_REGS_MAX 2048
|
|
#define PDS_CORE_INTR_CTRL_COAL_MAX 0x3F
|
|
#define PDS_CORE_INTR_INDEX_NOT_ASSIGNED -1
|
|
|
|
struct pds_core_intr_status {
|
|
u32 status[2];
|
|
};
|
|
|
|
/**
|
|
* enum pds_core_intr_mask_vals - valid values for mask and mask_assert.
|
|
* @PDS_CORE_INTR_MASK_CLEAR: unmask interrupt.
|
|
* @PDS_CORE_INTR_MASK_SET: mask interrupt.
|
|
*/
|
|
enum pds_core_intr_mask_vals {
|
|
PDS_CORE_INTR_MASK_CLEAR = 0,
|
|
PDS_CORE_INTR_MASK_SET = 1,
|
|
};
|
|
|
|
/**
|
|
* enum pds_core_intr_credits_bits - Bitwise composition of credits values.
|
|
* @PDS_CORE_INTR_CRED_COUNT: bit mask of credit count, no shift needed.
|
|
* @PDS_CORE_INTR_CRED_COUNT_SIGNED: bit mask of credit count, including sign bit.
|
|
* @PDS_CORE_INTR_CRED_UNMASK: unmask the interrupt.
|
|
* @PDS_CORE_INTR_CRED_RESET_COALESCE: reset the coalesce timer.
|
|
* @PDS_CORE_INTR_CRED_REARM: unmask the and reset the timer.
|
|
*/
|
|
enum pds_core_intr_credits_bits {
|
|
PDS_CORE_INTR_CRED_COUNT = 0x7fffu,
|
|
PDS_CORE_INTR_CRED_COUNT_SIGNED = 0xffffu,
|
|
PDS_CORE_INTR_CRED_UNMASK = 0x10000u,
|
|
PDS_CORE_INTR_CRED_RESET_COALESCE = 0x20000u,
|
|
PDS_CORE_INTR_CRED_REARM = (PDS_CORE_INTR_CRED_UNMASK |
|
|
PDS_CORE_INTR_CRED_RESET_COALESCE),
|
|
};
|
|
|
|
static inline void
|
|
pds_core_intr_coal_init(struct pds_core_intr __iomem *intr_ctrl, u32 coal)
|
|
{
|
|
iowrite32(coal, &intr_ctrl->coal_init);
|
|
}
|
|
|
|
static inline void
|
|
pds_core_intr_mask(struct pds_core_intr __iomem *intr_ctrl, u32 mask)
|
|
{
|
|
iowrite32(mask, &intr_ctrl->mask);
|
|
}
|
|
|
|
static inline void
|
|
pds_core_intr_credits(struct pds_core_intr __iomem *intr_ctrl,
|
|
u32 cred, u32 flags)
|
|
{
|
|
if (WARN_ON_ONCE(cred > PDS_CORE_INTR_CRED_COUNT)) {
|
|
cred = ioread32(&intr_ctrl->credits);
|
|
cred &= PDS_CORE_INTR_CRED_COUNT_SIGNED;
|
|
}
|
|
|
|
iowrite32(cred | flags, &intr_ctrl->credits);
|
|
}
|
|
|
|
static inline void
|
|
pds_core_intr_clean_flags(struct pds_core_intr __iomem *intr_ctrl, u32 flags)
|
|
{
|
|
u32 cred;
|
|
|
|
cred = ioread32(&intr_ctrl->credits);
|
|
cred &= PDS_CORE_INTR_CRED_COUNT_SIGNED;
|
|
cred |= flags;
|
|
iowrite32(cred, &intr_ctrl->credits);
|
|
}
|
|
|
|
static inline void
|
|
pds_core_intr_clean(struct pds_core_intr __iomem *intr_ctrl)
|
|
{
|
|
pds_core_intr_clean_flags(intr_ctrl, PDS_CORE_INTR_CRED_RESET_COALESCE);
|
|
}
|
|
|
|
static inline void
|
|
pds_core_intr_mask_assert(struct pds_core_intr __iomem *intr_ctrl, u32 mask)
|
|
{
|
|
iowrite32(mask, &intr_ctrl->mask_on_assert);
|
|
}
|
|
|
|
#endif /* _PDS_INTR_H_ */
|