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