/* 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 0 x0001
#define PDS_CORE_INTR_F_TIMER_RESET 0 x0002
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 0 x3F
#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 = 0 x7fffu,
PDS_CORE_INTR_CRED_COUNT_SIGNED = 0 xffffu,
PDS_CORE_INTR_CRED_UNMASK = 0 x10000u,
PDS_CORE_INTR_CRED_RESET_COALESCE = 0 x20000u,
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_ */
Messung V0.5 in Prozent C=95 H=93 G=93
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland