1*484027bfSAndrew Boyer /* SPDX-License-Identifier: BSD-3-Clause
2*484027bfSAndrew Boyer * Copyright 2018-2024 Advanced Micro Devices, Inc.
3*484027bfSAndrew Boyer */
4*484027bfSAndrew Boyer
5*484027bfSAndrew Boyer #ifndef _IONIC_REGS_H_
6*484027bfSAndrew Boyer #define _IONIC_REGS_H_
7*484027bfSAndrew Boyer
8*484027bfSAndrew Boyer /** struct ionic_intr - interrupt control register set.
9*484027bfSAndrew Boyer * @coal_init: coalesce timer initial value.
10*484027bfSAndrew Boyer * @mask: interrupt mask value.
11*484027bfSAndrew Boyer * @credits: interrupt credit count and return.
12*484027bfSAndrew Boyer * @mask_assert: interrupt mask value on assert.
13*484027bfSAndrew Boyer * @coal: coalesce timer time remaining.
14*484027bfSAndrew Boyer */
15*484027bfSAndrew Boyer struct ionic_intr {
16*484027bfSAndrew Boyer uint32_t coal_init;
17*484027bfSAndrew Boyer uint32_t mask;
18*484027bfSAndrew Boyer uint32_t credits;
19*484027bfSAndrew Boyer uint32_t mask_assert;
20*484027bfSAndrew Boyer uint32_t coal;
21*484027bfSAndrew Boyer uint32_t rsvd[3];
22*484027bfSAndrew Boyer };
23*484027bfSAndrew Boyer
24*484027bfSAndrew Boyer /** enum ionic_intr_mask_vals - valid values for mask and mask_assert.
25*484027bfSAndrew Boyer * @IONIC_INTR_MASK_CLEAR: unmask interrupt.
26*484027bfSAndrew Boyer * @IONIC_INTR_MASK_SET: mask interrupt.
27*484027bfSAndrew Boyer */
28*484027bfSAndrew Boyer enum ionic_intr_mask_vals {
29*484027bfSAndrew Boyer IONIC_INTR_MASK_CLEAR = 0,
30*484027bfSAndrew Boyer IONIC_INTR_MASK_SET = 1,
31*484027bfSAndrew Boyer };
32*484027bfSAndrew Boyer
33*484027bfSAndrew Boyer /** enum ionic_intr_credits_bits - bitwise composition of credits values.
34*484027bfSAndrew Boyer * @IONIC_INTR_CRED_COUNT: bit mask of credit count, no shift needed.
35*484027bfSAndrew Boyer * @IONIC_INTR_CRED_COUNT_SIGNED: bit mask of credit count, including sign bit.
36*484027bfSAndrew Boyer * @IONIC_INTR_CRED_UNMASK: unmask the interrupt.
37*484027bfSAndrew Boyer * @IONIC_INTR_CRED_RESET_COALESCE: reset the coalesce timer.
38*484027bfSAndrew Boyer * @IONIC_INTR_CRED_REARM: unmask the and reset the timer.
39*484027bfSAndrew Boyer */
40*484027bfSAndrew Boyer enum ionic_intr_credits_bits {
41*484027bfSAndrew Boyer IONIC_INTR_CRED_COUNT = 0x7fffu,
42*484027bfSAndrew Boyer IONIC_INTR_CRED_COUNT_SIGNED = 0xffffu,
43*484027bfSAndrew Boyer IONIC_INTR_CRED_UNMASK = 0x10000u,
44*484027bfSAndrew Boyer IONIC_INTR_CRED_RESET_COALESCE = 0x20000u,
45*484027bfSAndrew Boyer IONIC_INTR_CRED_REARM = (IONIC_INTR_CRED_UNMASK |
46*484027bfSAndrew Boyer IONIC_INTR_CRED_RESET_COALESCE),
47*484027bfSAndrew Boyer };
48*484027bfSAndrew Boyer
49*484027bfSAndrew Boyer #define IONIC_INTR_NONE (-1)
50*484027bfSAndrew Boyer #define IONIC_INTR_CTRL_REGS_MAX 2048
51*484027bfSAndrew Boyer
52*484027bfSAndrew Boyer struct ionic_intr_info {
53*484027bfSAndrew Boyer int index;
54*484027bfSAndrew Boyer uint32_t vector;
55*484027bfSAndrew Boyer struct ionic_intr __iomem *ctrl;
56*484027bfSAndrew Boyer };
57*484027bfSAndrew Boyer
58*484027bfSAndrew Boyer struct ionic_intr_status {
59*484027bfSAndrew Boyer uint32_t status[2];
60*484027bfSAndrew Boyer };
61*484027bfSAndrew Boyer
62*484027bfSAndrew Boyer static inline void
ionic_intr_coal_init(struct ionic_intr __iomem * intr_ctrl,int intr_idx,uint32_t coal)63*484027bfSAndrew Boyer ionic_intr_coal_init(struct ionic_intr __iomem *intr_ctrl,
64*484027bfSAndrew Boyer int intr_idx, uint32_t coal)
65*484027bfSAndrew Boyer {
66*484027bfSAndrew Boyer iowrite32(coal, &intr_ctrl[intr_idx].coal_init);
67*484027bfSAndrew Boyer }
68*484027bfSAndrew Boyer
69*484027bfSAndrew Boyer static inline void
ionic_intr_mask(struct ionic_intr __iomem * intr_ctrl,int intr_idx,uint32_t mask)70*484027bfSAndrew Boyer ionic_intr_mask(struct ionic_intr __iomem *intr_ctrl,
71*484027bfSAndrew Boyer int intr_idx, uint32_t mask)
72*484027bfSAndrew Boyer {
73*484027bfSAndrew Boyer iowrite32(mask, &intr_ctrl[intr_idx].mask);
74*484027bfSAndrew Boyer }
75*484027bfSAndrew Boyer
76*484027bfSAndrew Boyer static inline void
ionic_intr_credits(struct ionic_intr __iomem * intr_ctrl,int intr_idx,uint32_t cred,uint32_t flags)77*484027bfSAndrew Boyer ionic_intr_credits(struct ionic_intr __iomem *intr_ctrl,
78*484027bfSAndrew Boyer int intr_idx, uint32_t cred, uint32_t flags)
79*484027bfSAndrew Boyer {
80*484027bfSAndrew Boyer if (cred > IONIC_INTR_CRED_COUNT) {
81*484027bfSAndrew Boyer cred = ioread32(&intr_ctrl[intr_idx].credits);
82*484027bfSAndrew Boyer cred &= IONIC_INTR_CRED_COUNT_SIGNED;
83*484027bfSAndrew Boyer }
84*484027bfSAndrew Boyer
85*484027bfSAndrew Boyer iowrite32(cred | flags, &intr_ctrl[intr_idx].credits);
86*484027bfSAndrew Boyer }
87*484027bfSAndrew Boyer
88*484027bfSAndrew Boyer static inline void
ionic_intr_clean(struct ionic_intr __iomem * intr_ctrl,int intr_idx)89*484027bfSAndrew Boyer ionic_intr_clean(struct ionic_intr __iomem *intr_ctrl,
90*484027bfSAndrew Boyer int intr_idx)
91*484027bfSAndrew Boyer {
92*484027bfSAndrew Boyer uint32_t cred;
93*484027bfSAndrew Boyer
94*484027bfSAndrew Boyer cred = ioread32(&intr_ctrl[intr_idx].credits);
95*484027bfSAndrew Boyer cred &= IONIC_INTR_CRED_COUNT_SIGNED;
96*484027bfSAndrew Boyer cred |= IONIC_INTR_CRED_RESET_COALESCE;
97*484027bfSAndrew Boyer iowrite32(cred, &intr_ctrl[intr_idx].credits);
98*484027bfSAndrew Boyer }
99*484027bfSAndrew Boyer
100*484027bfSAndrew Boyer static inline void
ionic_intr_mask_assert(struct ionic_intr __iomem * intr_ctrl,int intr_idx,uint32_t mask)101*484027bfSAndrew Boyer ionic_intr_mask_assert(struct ionic_intr __iomem *intr_ctrl,
102*484027bfSAndrew Boyer int intr_idx, uint32_t mask)
103*484027bfSAndrew Boyer {
104*484027bfSAndrew Boyer iowrite32(mask, &intr_ctrl[intr_idx].mask_assert);
105*484027bfSAndrew Boyer }
106*484027bfSAndrew Boyer
107*484027bfSAndrew Boyer /** enum ionic_dbell_bits - bitwise composition of dbell values.
108*484027bfSAndrew Boyer *
109*484027bfSAndrew Boyer * @IONIC_DBELL_QID_MASK: unshifted mask of valid queue id bits.
110*484027bfSAndrew Boyer * @IONIC_DBELL_QID_SHIFT: queue id shift amount in dbell value.
111*484027bfSAndrew Boyer * @IONIC_DBELL_QID: macro to build QID component of dbell value.
112*484027bfSAndrew Boyer *
113*484027bfSAndrew Boyer * @IONIC_DBELL_RING_MASK: unshifted mask of valid ring bits.
114*484027bfSAndrew Boyer * @IONIC_DBELL_RING_SHIFT: ring shift amount in dbell value.
115*484027bfSAndrew Boyer * @IONIC_DBELL_RING: macro to build ring component of dbell value.
116*484027bfSAndrew Boyer *
117*484027bfSAndrew Boyer * @IONIC_DBELL_RING_0: ring zero dbell component value.
118*484027bfSAndrew Boyer * @IONIC_DBELL_RING_1: ring one dbell component value.
119*484027bfSAndrew Boyer * @IONIC_DBELL_RING_2: ring two dbell component value.
120*484027bfSAndrew Boyer * @IONIC_DBELL_RING_3: ring three dbell component value.
121*484027bfSAndrew Boyer *
122*484027bfSAndrew Boyer * @IONIC_DBELL_INDEX_MASK: bit mask of valid index bits, no shift needed.
123*484027bfSAndrew Boyer */
124*484027bfSAndrew Boyer enum ionic_dbell_bits {
125*484027bfSAndrew Boyer IONIC_DBELL_QID_MASK = 0xffffff,
126*484027bfSAndrew Boyer IONIC_DBELL_QID_SHIFT = 24,
127*484027bfSAndrew Boyer
128*484027bfSAndrew Boyer #define IONIC_DBELL_QID(n) \
129*484027bfSAndrew Boyer (((u64)(n) & IONIC_DBELL_QID_MASK) << IONIC_DBELL_QID_SHIFT)
130*484027bfSAndrew Boyer
131*484027bfSAndrew Boyer IONIC_DBELL_RING_MASK = 0x7,
132*484027bfSAndrew Boyer IONIC_DBELL_RING_SHIFT = 16,
133*484027bfSAndrew Boyer
134*484027bfSAndrew Boyer #define IONIC_DBELL_RING(n) \
135*484027bfSAndrew Boyer (((u64)(n) & IONIC_DBELL_RING_MASK) << IONIC_DBELL_RING_SHIFT)
136*484027bfSAndrew Boyer
137*484027bfSAndrew Boyer IONIC_DBELL_RING_0 = 0,
138*484027bfSAndrew Boyer IONIC_DBELL_RING_1 = IONIC_DBELL_RING(1),
139*484027bfSAndrew Boyer IONIC_DBELL_RING_2 = IONIC_DBELL_RING(2),
140*484027bfSAndrew Boyer IONIC_DBELL_RING_3 = IONIC_DBELL_RING(3),
141*484027bfSAndrew Boyer
142*484027bfSAndrew Boyer IONIC_DBELL_INDEX_MASK = 0xffff,
143*484027bfSAndrew Boyer };
144*484027bfSAndrew Boyer
145*484027bfSAndrew Boyer #define IONIC_BARS_MIN 2
146*484027bfSAndrew Boyer #define IONIC_BARS_MAX 6
147*484027bfSAndrew Boyer #define IONIC_PCI_BAR_DBELL 1
148*484027bfSAndrew Boyer
149*484027bfSAndrew Boyer /* BAR0 */
150*484027bfSAndrew Boyer #define IONIC_BAR0_SIZE 0x8000
151*484027bfSAndrew Boyer
152*484027bfSAndrew Boyer #define IONIC_BAR0_DEV_INFO_REGS_OFFSET 0x0000
153*484027bfSAndrew Boyer #define IONIC_BAR0_DEV_CMD_REGS_OFFSET 0x0800
154*484027bfSAndrew Boyer #define IONIC_BAR0_DEV_CMD_DATA_REGS_OFFSET 0x0c00
155*484027bfSAndrew Boyer #define IONIC_BAR0_INTR_STATUS_OFFSET 0x1000
156*484027bfSAndrew Boyer #define IONIC_BAR0_INTR_CTRL_OFFSET 0x2000
157*484027bfSAndrew Boyer #define IONIC_DEV_CMD_DONE 0x00000001
158*484027bfSAndrew Boyer
159*484027bfSAndrew Boyer /**
160*484027bfSAndrew Boyer * struct ionic_doorbell - Doorbell register layout
161*484027bfSAndrew Boyer * @p_index: Producer index
162*484027bfSAndrew Boyer * @ring: Selects the specific ring of the queue to update
163*484027bfSAndrew Boyer * Type-specific meaning:
164*484027bfSAndrew Boyer * ring=0: Default producer/consumer queue
165*484027bfSAndrew Boyer * ring=1: (CQ, EQ) Re-Arm queue. CQs send events to EQs
166*484027bfSAndrew Boyer * when armed. EQs send interrupts when armed.
167*484027bfSAndrew Boyer * @qid_lo: Queue destination for the producer index and flags (low bits)
168*484027bfSAndrew Boyer * @qid_hi: Queue destination for the producer index and flags (high bits)
169*484027bfSAndrew Boyer */
170*484027bfSAndrew Boyer struct ionic_doorbell {
171*484027bfSAndrew Boyer __le16 p_index;
172*484027bfSAndrew Boyer u8 ring;
173*484027bfSAndrew Boyer u8 qid_lo;
174*484027bfSAndrew Boyer __le16 qid_hi;
175*484027bfSAndrew Boyer u16 rsvd2;
176*484027bfSAndrew Boyer };
177*484027bfSAndrew Boyer
178*484027bfSAndrew Boyer #endif /* _IONIC_REGS_H_ */
179