1 /* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */ 2 /* Copyright(c) 2023 Advanced Micro Devices, Inc. */ 3 4 #ifndef _PDS_INTR_H_ 5 #define _PDS_INTR_H_ 6 7 /* 8 * Interrupt control register 9 * @coal_init: Coalescing timer initial value, in 10 * device units. Use @identity->intr_coal_mult 11 * and @identity->intr_coal_div to convert from 12 * usecs to device units: 13 * 14 * coal_init = coal_usecs * coal_mutl / coal_div 15 * 16 * When an interrupt is sent the interrupt 17 * coalescing timer current value 18 * (@coalescing_curr) is initialized with this 19 * value and begins counting down. No more 20 * interrupts are sent until the coalescing 21 * timer reaches 0. When @coalescing_init=0 22 * interrupt coalescing is effectively disabled 23 * and every interrupt assert results in an 24 * interrupt. Reset value: 0 25 * @mask: Interrupt mask. When @mask=1 the interrupt 26 * resource will not send an interrupt. When 27 * @mask=0 the interrupt resource will send an 28 * interrupt if an interrupt event is pending 29 * or on the next interrupt assertion event. 30 * Reset value: 1 31 * @credits: Interrupt credits. This register indicates 32 * how many interrupt events the hardware has 33 * sent. When written by software this 34 * register atomically decrements @int_credits 35 * by the value written. When @int_credits 36 * becomes 0 then the "pending interrupt" bit 37 * in the Interrupt Status register is cleared 38 * by the hardware and any pending but unsent 39 * interrupts are cleared. 40 * !!!IMPORTANT!!! This is a signed register. 41 * @flags: Interrupt control flags 42 * @unmask -- When this bit is written with a 1 43 * the interrupt resource will set mask=0. 44 * @coal_timer_reset -- When this 45 * bit is written with a 1 the 46 * @coalescing_curr will be reloaded with 47 * @coalescing_init to reset the coalescing 48 * timer. 49 * @mask_on_assert: Automatically mask on assertion. When 50 * @mask_on_assert=1 the interrupt resource 51 * will set @mask=1 whenever an interrupt is 52 * sent. When using interrupts in Legacy 53 * Interrupt mode the driver must select 54 * @mask_on_assert=0 for proper interrupt 55 * operation. 56 * @coalescing_curr: Coalescing timer current value, in 57 * microseconds. When this value reaches 0 58 * the interrupt resource is again eligible to 59 * send an interrupt. If an interrupt event 60 * is already pending when @coalescing_curr 61 * reaches 0 the pending interrupt will be 62 * sent, otherwise an interrupt will be sent 63 * on the next interrupt assertion event. 64 */ 65 struct pds_core_intr { 66 u32 coal_init; 67 u32 mask; 68 u16 credits; 69 u16 flags; 70 #define PDS_CORE_INTR_F_UNMASK 0x0001 71 #define PDS_CORE_INTR_F_TIMER_RESET 0x0002 72 u32 mask_on_assert; 73 u32 coalescing_curr; 74 u32 rsvd6[3]; 75 }; 76 77 #ifndef __CHECKER__ 78 static_assert(sizeof(struct pds_core_intr) == 32); 79 #endif /* __CHECKER__ */ 80 81 #define PDS_CORE_INTR_CTRL_REGS_MAX 2048 82 #define PDS_CORE_INTR_CTRL_COAL_MAX 0x3F 83 #define PDS_CORE_INTR_INDEX_NOT_ASSIGNED -1 84 85 struct pds_core_intr_status { 86 u32 status[2]; 87 }; 88 89 /** 90 * enum pds_core_intr_mask_vals - valid values for mask and mask_assert. 91 * @PDS_CORE_INTR_MASK_CLEAR: unmask interrupt. 92 * @PDS_CORE_INTR_MASK_SET: mask interrupt. 93 */ 94 enum pds_core_intr_mask_vals { 95 PDS_CORE_INTR_MASK_CLEAR = 0, 96 PDS_CORE_INTR_MASK_SET = 1, 97 }; 98 99 /** 100 * enum pds_core_intr_credits_bits - Bitwise composition of credits values. 101 * @PDS_CORE_INTR_CRED_COUNT: bit mask of credit count, no shift needed. 102 * @PDS_CORE_INTR_CRED_COUNT_SIGNED: bit mask of credit count, including sign bit. 103 * @PDS_CORE_INTR_CRED_UNMASK: unmask the interrupt. 104 * @PDS_CORE_INTR_CRED_RESET_COALESCE: reset the coalesce timer. 105 * @PDS_CORE_INTR_CRED_REARM: unmask the and reset the timer. 106 */ 107 enum pds_core_intr_credits_bits { 108 PDS_CORE_INTR_CRED_COUNT = 0x7fffu, 109 PDS_CORE_INTR_CRED_COUNT_SIGNED = 0xffffu, 110 PDS_CORE_INTR_CRED_UNMASK = 0x10000u, 111 PDS_CORE_INTR_CRED_RESET_COALESCE = 0x20000u, 112 PDS_CORE_INTR_CRED_REARM = (PDS_CORE_INTR_CRED_UNMASK | 113 PDS_CORE_INTR_CRED_RESET_COALESCE), 114 }; 115 116 static inline void 117 pds_core_intr_coal_init(struct pds_core_intr __iomem *intr_ctrl, u32 coal) 118 { 119 iowrite32(coal, &intr_ctrl->coal_init); 120 } 121 122 static inline void 123 pds_core_intr_mask(struct pds_core_intr __iomem *intr_ctrl, u32 mask) 124 { 125 iowrite32(mask, &intr_ctrl->mask); 126 } 127 128 static inline void 129 pds_core_intr_credits(struct pds_core_intr __iomem *intr_ctrl, 130 u32 cred, u32 flags) 131 { 132 if (WARN_ON_ONCE(cred > PDS_CORE_INTR_CRED_COUNT)) { 133 cred = ioread32(&intr_ctrl->credits); 134 cred &= PDS_CORE_INTR_CRED_COUNT_SIGNED; 135 } 136 137 iowrite32(cred | flags, &intr_ctrl->credits); 138 } 139 140 static inline void 141 pds_core_intr_clean_flags(struct pds_core_intr __iomem *intr_ctrl, u32 flags) 142 { 143 u32 cred; 144 145 cred = ioread32(&intr_ctrl->credits); 146 cred &= PDS_CORE_INTR_CRED_COUNT_SIGNED; 147 cred |= flags; 148 iowrite32(cred, &intr_ctrl->credits); 149 } 150 151 static inline void 152 pds_core_intr_clean(struct pds_core_intr __iomem *intr_ctrl) 153 { 154 pds_core_intr_clean_flags(intr_ctrl, PDS_CORE_INTR_CRED_RESET_COALESCE); 155 } 156 157 static inline void 158 pds_core_intr_mask_assert(struct pds_core_intr __iomem *intr_ctrl, u32 mask) 159 { 160 iowrite32(mask, &intr_ctrl->mask_on_assert); 161 } 162 163 #endif /* _PDS_INTR_H_ */ 164
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.