1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */
2*4882a593Smuzhiyun /* Copyright (c) 2018-2019 Pensando Systems, Inc. All rights reserved. */
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun #ifndef IONIC_REGS_H
5*4882a593Smuzhiyun #define IONIC_REGS_H
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/io.h>
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun /** struct ionic_intr - interrupt control register set.
10*4882a593Smuzhiyun * @coal_init: coalesce timer initial value.
11*4882a593Smuzhiyun * @mask: interrupt mask value.
12*4882a593Smuzhiyun * @credits: interrupt credit count and return.
13*4882a593Smuzhiyun * @mask_assert: interrupt mask value on assert.
14*4882a593Smuzhiyun * @coal: coalesce timer time remaining.
15*4882a593Smuzhiyun */
16*4882a593Smuzhiyun struct ionic_intr {
17*4882a593Smuzhiyun u32 coal_init;
18*4882a593Smuzhiyun u32 mask;
19*4882a593Smuzhiyun u32 credits;
20*4882a593Smuzhiyun u32 mask_assert;
21*4882a593Smuzhiyun u32 coal;
22*4882a593Smuzhiyun u32 rsvd[3];
23*4882a593Smuzhiyun };
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #define IONIC_INTR_CTRL_REGS_MAX 2048
26*4882a593Smuzhiyun #define IONIC_INTR_CTRL_COAL_MAX 0x3F
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /** enum ionic_intr_mask_vals - valid values for mask and mask_assert.
29*4882a593Smuzhiyun * @IONIC_INTR_MASK_CLEAR: unmask interrupt.
30*4882a593Smuzhiyun * @IONIC_INTR_MASK_SET: mask interrupt.
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun enum ionic_intr_mask_vals {
33*4882a593Smuzhiyun IONIC_INTR_MASK_CLEAR = 0,
34*4882a593Smuzhiyun IONIC_INTR_MASK_SET = 1,
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /** enum ionic_intr_credits_bits - bitwise composition of credits values.
38*4882a593Smuzhiyun * @IONIC_INTR_CRED_COUNT: bit mask of credit count, no shift needed.
39*4882a593Smuzhiyun * @IONIC_INTR_CRED_COUNT_SIGNED: bit mask of credit count, including sign bit.
40*4882a593Smuzhiyun * @IONIC_INTR_CRED_UNMASK: unmask the interrupt.
41*4882a593Smuzhiyun * @IONIC_INTR_CRED_RESET_COALESCE: reset the coalesce timer.
42*4882a593Smuzhiyun * @IONIC_INTR_CRED_REARM: unmask the and reset the timer.
43*4882a593Smuzhiyun */
44*4882a593Smuzhiyun enum ionic_intr_credits_bits {
45*4882a593Smuzhiyun IONIC_INTR_CRED_COUNT = 0x7fffu,
46*4882a593Smuzhiyun IONIC_INTR_CRED_COUNT_SIGNED = 0xffffu,
47*4882a593Smuzhiyun IONIC_INTR_CRED_UNMASK = 0x10000u,
48*4882a593Smuzhiyun IONIC_INTR_CRED_RESET_COALESCE = 0x20000u,
49*4882a593Smuzhiyun IONIC_INTR_CRED_REARM = (IONIC_INTR_CRED_UNMASK |
50*4882a593Smuzhiyun IONIC_INTR_CRED_RESET_COALESCE),
51*4882a593Smuzhiyun };
52*4882a593Smuzhiyun
ionic_intr_coal_init(struct ionic_intr __iomem * intr_ctrl,int intr_idx,u32 coal)53*4882a593Smuzhiyun static inline void ionic_intr_coal_init(struct ionic_intr __iomem *intr_ctrl,
54*4882a593Smuzhiyun int intr_idx, u32 coal)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun iowrite32(coal, &intr_ctrl[intr_idx].coal_init);
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun
ionic_intr_mask(struct ionic_intr __iomem * intr_ctrl,int intr_idx,u32 mask)59*4882a593Smuzhiyun static inline void ionic_intr_mask(struct ionic_intr __iomem *intr_ctrl,
60*4882a593Smuzhiyun int intr_idx, u32 mask)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun iowrite32(mask, &intr_ctrl[intr_idx].mask);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
ionic_intr_credits(struct ionic_intr __iomem * intr_ctrl,int intr_idx,u32 cred,u32 flags)65*4882a593Smuzhiyun static inline void ionic_intr_credits(struct ionic_intr __iomem *intr_ctrl,
66*4882a593Smuzhiyun int intr_idx, u32 cred, u32 flags)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun if (WARN_ON_ONCE(cred > IONIC_INTR_CRED_COUNT)) {
69*4882a593Smuzhiyun cred = ioread32(&intr_ctrl[intr_idx].credits);
70*4882a593Smuzhiyun cred &= IONIC_INTR_CRED_COUNT_SIGNED;
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun iowrite32(cred | flags, &intr_ctrl[intr_idx].credits);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
ionic_intr_clean(struct ionic_intr __iomem * intr_ctrl,int intr_idx)76*4882a593Smuzhiyun static inline void ionic_intr_clean(struct ionic_intr __iomem *intr_ctrl,
77*4882a593Smuzhiyun int intr_idx)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun u32 cred;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun cred = ioread32(&intr_ctrl[intr_idx].credits);
82*4882a593Smuzhiyun cred &= IONIC_INTR_CRED_COUNT_SIGNED;
83*4882a593Smuzhiyun cred |= IONIC_INTR_CRED_RESET_COALESCE;
84*4882a593Smuzhiyun iowrite32(cred, &intr_ctrl[intr_idx].credits);
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
ionic_intr_mask_assert(struct ionic_intr __iomem * intr_ctrl,int intr_idx,u32 mask)87*4882a593Smuzhiyun static inline void ionic_intr_mask_assert(struct ionic_intr __iomem *intr_ctrl,
88*4882a593Smuzhiyun int intr_idx, u32 mask)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun iowrite32(mask, &intr_ctrl[intr_idx].mask_assert);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /** enum ionic_dbell_bits - bitwise composition of dbell values.
94*4882a593Smuzhiyun *
95*4882a593Smuzhiyun * @IONIC_DBELL_QID_MASK: unshifted mask of valid queue id bits.
96*4882a593Smuzhiyun * @IONIC_DBELL_QID_SHIFT: queue id shift amount in dbell value.
97*4882a593Smuzhiyun * @IONIC_DBELL_QID: macro to build QID component of dbell value.
98*4882a593Smuzhiyun *
99*4882a593Smuzhiyun * @IONIC_DBELL_RING_MASK: unshifted mask of valid ring bits.
100*4882a593Smuzhiyun * @IONIC_DBELL_RING_SHIFT: ring shift amount in dbell value.
101*4882a593Smuzhiyun * @IONIC_DBELL_RING: macro to build ring component of dbell value.
102*4882a593Smuzhiyun *
103*4882a593Smuzhiyun * @IONIC_DBELL_RING_0: ring zero dbell component value.
104*4882a593Smuzhiyun * @IONIC_DBELL_RING_1: ring one dbell component value.
105*4882a593Smuzhiyun * @IONIC_DBELL_RING_2: ring two dbell component value.
106*4882a593Smuzhiyun * @IONIC_DBELL_RING_3: ring three dbell component value.
107*4882a593Smuzhiyun *
108*4882a593Smuzhiyun * @IONIC_DBELL_INDEX_MASK: bit mask of valid index bits, no shift needed.
109*4882a593Smuzhiyun */
110*4882a593Smuzhiyun enum ionic_dbell_bits {
111*4882a593Smuzhiyun IONIC_DBELL_QID_MASK = 0xffffff,
112*4882a593Smuzhiyun IONIC_DBELL_QID_SHIFT = 24,
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun #define IONIC_DBELL_QID(n) \
115*4882a593Smuzhiyun (((u64)(n) & IONIC_DBELL_QID_MASK) << IONIC_DBELL_QID_SHIFT)
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun IONIC_DBELL_RING_MASK = 0x7,
118*4882a593Smuzhiyun IONIC_DBELL_RING_SHIFT = 16,
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun #define IONIC_DBELL_RING(n) \
121*4882a593Smuzhiyun (((u64)(n) & IONIC_DBELL_RING_MASK) << IONIC_DBELL_RING_SHIFT)
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun IONIC_DBELL_RING_0 = 0,
124*4882a593Smuzhiyun IONIC_DBELL_RING_1 = IONIC_DBELL_RING(1),
125*4882a593Smuzhiyun IONIC_DBELL_RING_2 = IONIC_DBELL_RING(2),
126*4882a593Smuzhiyun IONIC_DBELL_RING_3 = IONIC_DBELL_RING(3),
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun IONIC_DBELL_INDEX_MASK = 0xffff,
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun
ionic_dbell_ring(u64 __iomem * db_page,int qtype,u64 val)131*4882a593Smuzhiyun static inline void ionic_dbell_ring(u64 __iomem *db_page, int qtype, u64 val)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun writeq(val, &db_page[qtype]);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun #endif /* IONIC_REGS_H */
137