18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */
28c2ecf20Sopenharmony_ci/* Copyright (c) 2018-2019 Pensando Systems, Inc.  All rights reserved. */
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#ifndef IONIC_REGS_H
58c2ecf20Sopenharmony_ci#define IONIC_REGS_H
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/io.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/** struct ionic_intr - interrupt control register set.
108c2ecf20Sopenharmony_ci * @coal_init:			coalesce timer initial value.
118c2ecf20Sopenharmony_ci * @mask:			interrupt mask value.
128c2ecf20Sopenharmony_ci * @credits:			interrupt credit count and return.
138c2ecf20Sopenharmony_ci * @mask_assert:		interrupt mask value on assert.
148c2ecf20Sopenharmony_ci * @coal:			coalesce timer time remaining.
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_cistruct ionic_intr {
178c2ecf20Sopenharmony_ci	u32 coal_init;
188c2ecf20Sopenharmony_ci	u32 mask;
198c2ecf20Sopenharmony_ci	u32 credits;
208c2ecf20Sopenharmony_ci	u32 mask_assert;
218c2ecf20Sopenharmony_ci	u32 coal;
228c2ecf20Sopenharmony_ci	u32 rsvd[3];
238c2ecf20Sopenharmony_ci};
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define IONIC_INTR_CTRL_REGS_MAX	2048
268c2ecf20Sopenharmony_ci#define IONIC_INTR_CTRL_COAL_MAX	0x3F
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/** enum ionic_intr_mask_vals - valid values for mask and mask_assert.
298c2ecf20Sopenharmony_ci * @IONIC_INTR_MASK_CLEAR:	unmask interrupt.
308c2ecf20Sopenharmony_ci * @IONIC_INTR_MASK_SET:	mask interrupt.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_cienum ionic_intr_mask_vals {
338c2ecf20Sopenharmony_ci	IONIC_INTR_MASK_CLEAR		= 0,
348c2ecf20Sopenharmony_ci	IONIC_INTR_MASK_SET		= 1,
358c2ecf20Sopenharmony_ci};
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/** enum ionic_intr_credits_bits - bitwise composition of credits values.
388c2ecf20Sopenharmony_ci * @IONIC_INTR_CRED_COUNT:	bit mask of credit count, no shift needed.
398c2ecf20Sopenharmony_ci * @IONIC_INTR_CRED_COUNT_SIGNED: bit mask of credit count, including sign bit.
408c2ecf20Sopenharmony_ci * @IONIC_INTR_CRED_UNMASK:	unmask the interrupt.
418c2ecf20Sopenharmony_ci * @IONIC_INTR_CRED_RESET_COALESCE: reset the coalesce timer.
428c2ecf20Sopenharmony_ci * @IONIC_INTR_CRED_REARM:	unmask the and reset the timer.
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_cienum ionic_intr_credits_bits {
458c2ecf20Sopenharmony_ci	IONIC_INTR_CRED_COUNT		= 0x7fffu,
468c2ecf20Sopenharmony_ci	IONIC_INTR_CRED_COUNT_SIGNED	= 0xffffu,
478c2ecf20Sopenharmony_ci	IONIC_INTR_CRED_UNMASK		= 0x10000u,
488c2ecf20Sopenharmony_ci	IONIC_INTR_CRED_RESET_COALESCE	= 0x20000u,
498c2ecf20Sopenharmony_ci	IONIC_INTR_CRED_REARM		= (IONIC_INTR_CRED_UNMASK |
508c2ecf20Sopenharmony_ci					   IONIC_INTR_CRED_RESET_COALESCE),
518c2ecf20Sopenharmony_ci};
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistatic inline void ionic_intr_coal_init(struct ionic_intr __iomem *intr_ctrl,
548c2ecf20Sopenharmony_ci					int intr_idx, u32 coal)
558c2ecf20Sopenharmony_ci{
568c2ecf20Sopenharmony_ci	iowrite32(coal, &intr_ctrl[intr_idx].coal_init);
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistatic inline void ionic_intr_mask(struct ionic_intr __iomem *intr_ctrl,
608c2ecf20Sopenharmony_ci				   int intr_idx, u32 mask)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	iowrite32(mask, &intr_ctrl[intr_idx].mask);
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic inline void ionic_intr_credits(struct ionic_intr __iomem *intr_ctrl,
668c2ecf20Sopenharmony_ci				      int intr_idx, u32 cred, u32 flags)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(cred > IONIC_INTR_CRED_COUNT)) {
698c2ecf20Sopenharmony_ci		cred = ioread32(&intr_ctrl[intr_idx].credits);
708c2ecf20Sopenharmony_ci		cred &= IONIC_INTR_CRED_COUNT_SIGNED;
718c2ecf20Sopenharmony_ci	}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	iowrite32(cred | flags, &intr_ctrl[intr_idx].credits);
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic inline void ionic_intr_clean(struct ionic_intr __iomem *intr_ctrl,
778c2ecf20Sopenharmony_ci				    int intr_idx)
788c2ecf20Sopenharmony_ci{
798c2ecf20Sopenharmony_ci	u32 cred;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	cred = ioread32(&intr_ctrl[intr_idx].credits);
828c2ecf20Sopenharmony_ci	cred &= IONIC_INTR_CRED_COUNT_SIGNED;
838c2ecf20Sopenharmony_ci	cred |= IONIC_INTR_CRED_RESET_COALESCE;
848c2ecf20Sopenharmony_ci	iowrite32(cred, &intr_ctrl[intr_idx].credits);
858c2ecf20Sopenharmony_ci}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistatic inline void ionic_intr_mask_assert(struct ionic_intr __iomem *intr_ctrl,
888c2ecf20Sopenharmony_ci					  int intr_idx, u32 mask)
898c2ecf20Sopenharmony_ci{
908c2ecf20Sopenharmony_ci	iowrite32(mask, &intr_ctrl[intr_idx].mask_assert);
918c2ecf20Sopenharmony_ci}
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci/** enum ionic_dbell_bits - bitwise composition of dbell values.
948c2ecf20Sopenharmony_ci *
958c2ecf20Sopenharmony_ci * @IONIC_DBELL_QID_MASK:	unshifted mask of valid queue id bits.
968c2ecf20Sopenharmony_ci * @IONIC_DBELL_QID_SHIFT:	queue id shift amount in dbell value.
978c2ecf20Sopenharmony_ci * @IONIC_DBELL_QID:		macro to build QID component of dbell value.
988c2ecf20Sopenharmony_ci *
998c2ecf20Sopenharmony_ci * @IONIC_DBELL_RING_MASK:	unshifted mask of valid ring bits.
1008c2ecf20Sopenharmony_ci * @IONIC_DBELL_RING_SHIFT:	ring shift amount in dbell value.
1018c2ecf20Sopenharmony_ci * @IONIC_DBELL_RING:		macro to build ring component of dbell value.
1028c2ecf20Sopenharmony_ci *
1038c2ecf20Sopenharmony_ci * @IONIC_DBELL_RING_0:		ring zero dbell component value.
1048c2ecf20Sopenharmony_ci * @IONIC_DBELL_RING_1:		ring one dbell component value.
1058c2ecf20Sopenharmony_ci * @IONIC_DBELL_RING_2:		ring two dbell component value.
1068c2ecf20Sopenharmony_ci * @IONIC_DBELL_RING_3:		ring three dbell component value.
1078c2ecf20Sopenharmony_ci *
1088c2ecf20Sopenharmony_ci * @IONIC_DBELL_INDEX_MASK:	bit mask of valid index bits, no shift needed.
1098c2ecf20Sopenharmony_ci */
1108c2ecf20Sopenharmony_cienum ionic_dbell_bits {
1118c2ecf20Sopenharmony_ci	IONIC_DBELL_QID_MASK		= 0xffffff,
1128c2ecf20Sopenharmony_ci	IONIC_DBELL_QID_SHIFT		= 24,
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci#define IONIC_DBELL_QID(n) \
1158c2ecf20Sopenharmony_ci	(((u64)(n) & IONIC_DBELL_QID_MASK) << IONIC_DBELL_QID_SHIFT)
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	IONIC_DBELL_RING_MASK		= 0x7,
1188c2ecf20Sopenharmony_ci	IONIC_DBELL_RING_SHIFT		= 16,
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci#define IONIC_DBELL_RING(n) \
1218c2ecf20Sopenharmony_ci	(((u64)(n) & IONIC_DBELL_RING_MASK) << IONIC_DBELL_RING_SHIFT)
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	IONIC_DBELL_RING_0		= 0,
1248c2ecf20Sopenharmony_ci	IONIC_DBELL_RING_1		= IONIC_DBELL_RING(1),
1258c2ecf20Sopenharmony_ci	IONIC_DBELL_RING_2		= IONIC_DBELL_RING(2),
1268c2ecf20Sopenharmony_ci	IONIC_DBELL_RING_3		= IONIC_DBELL_RING(3),
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	IONIC_DBELL_INDEX_MASK		= 0xffff,
1298c2ecf20Sopenharmony_ci};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_cistatic inline void ionic_dbell_ring(u64 __iomem *db_page, int qtype, u64 val)
1328c2ecf20Sopenharmony_ci{
1338c2ecf20Sopenharmony_ci	writeq(val, &db_page[qtype]);
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci#endif /* IONIC_REGS_H */
137