162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */
262306a36Sopenharmony_ci/* Copyright (c) 2018-2019 Pensando Systems, Inc.  All rights reserved. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#ifndef IONIC_REGS_H
562306a36Sopenharmony_ci#define IONIC_REGS_H
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/io.h>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/** struct ionic_intr - interrupt control register set.
1062306a36Sopenharmony_ci * @coal_init:			coalesce timer initial value.
1162306a36Sopenharmony_ci * @mask:			interrupt mask value.
1262306a36Sopenharmony_ci * @credits:			interrupt credit count and return.
1362306a36Sopenharmony_ci * @mask_assert:		interrupt mask value on assert.
1462306a36Sopenharmony_ci * @coal:			coalesce timer time remaining.
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_cistruct ionic_intr {
1762306a36Sopenharmony_ci	u32 coal_init;
1862306a36Sopenharmony_ci	u32 mask;
1962306a36Sopenharmony_ci	u32 credits;
2062306a36Sopenharmony_ci	u32 mask_assert;
2162306a36Sopenharmony_ci	u32 coal;
2262306a36Sopenharmony_ci	u32 rsvd[3];
2362306a36Sopenharmony_ci};
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define IONIC_INTR_CTRL_REGS_MAX	2048
2662306a36Sopenharmony_ci#define IONIC_INTR_CTRL_COAL_MAX	0x3F
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/** enum ionic_intr_mask_vals - valid values for mask and mask_assert.
2962306a36Sopenharmony_ci * @IONIC_INTR_MASK_CLEAR:	unmask interrupt.
3062306a36Sopenharmony_ci * @IONIC_INTR_MASK_SET:	mask interrupt.
3162306a36Sopenharmony_ci */
3262306a36Sopenharmony_cienum ionic_intr_mask_vals {
3362306a36Sopenharmony_ci	IONIC_INTR_MASK_CLEAR		= 0,
3462306a36Sopenharmony_ci	IONIC_INTR_MASK_SET		= 1,
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/** enum ionic_intr_credits_bits - bitwise composition of credits values.
3862306a36Sopenharmony_ci * @IONIC_INTR_CRED_COUNT:	bit mask of credit count, no shift needed.
3962306a36Sopenharmony_ci * @IONIC_INTR_CRED_COUNT_SIGNED: bit mask of credit count, including sign bit.
4062306a36Sopenharmony_ci * @IONIC_INTR_CRED_UNMASK:	unmask the interrupt.
4162306a36Sopenharmony_ci * @IONIC_INTR_CRED_RESET_COALESCE: reset the coalesce timer.
4262306a36Sopenharmony_ci * @IONIC_INTR_CRED_REARM:	unmask the and reset the timer.
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_cienum ionic_intr_credits_bits {
4562306a36Sopenharmony_ci	IONIC_INTR_CRED_COUNT		= 0x7fffu,
4662306a36Sopenharmony_ci	IONIC_INTR_CRED_COUNT_SIGNED	= 0xffffu,
4762306a36Sopenharmony_ci	IONIC_INTR_CRED_UNMASK		= 0x10000u,
4862306a36Sopenharmony_ci	IONIC_INTR_CRED_RESET_COALESCE	= 0x20000u,
4962306a36Sopenharmony_ci	IONIC_INTR_CRED_REARM		= (IONIC_INTR_CRED_UNMASK |
5062306a36Sopenharmony_ci					   IONIC_INTR_CRED_RESET_COALESCE),
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline void ionic_intr_coal_init(struct ionic_intr __iomem *intr_ctrl,
5462306a36Sopenharmony_ci					int intr_idx, u32 coal)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	iowrite32(coal, &intr_ctrl[intr_idx].coal_init);
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic inline void ionic_intr_mask(struct ionic_intr __iomem *intr_ctrl,
6062306a36Sopenharmony_ci				   int intr_idx, u32 mask)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	iowrite32(mask, &intr_ctrl[intr_idx].mask);
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistatic inline void ionic_intr_credits(struct ionic_intr __iomem *intr_ctrl,
6662306a36Sopenharmony_ci				      int intr_idx, u32 cred, u32 flags)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	if (WARN_ON_ONCE(cred > IONIC_INTR_CRED_COUNT)) {
6962306a36Sopenharmony_ci		cred = ioread32(&intr_ctrl[intr_idx].credits);
7062306a36Sopenharmony_ci		cred &= IONIC_INTR_CRED_COUNT_SIGNED;
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	iowrite32(cred | flags, &intr_ctrl[intr_idx].credits);
7462306a36Sopenharmony_ci}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistatic inline void ionic_intr_clean(struct ionic_intr __iomem *intr_ctrl,
7762306a36Sopenharmony_ci				    int intr_idx)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	u32 cred;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	cred = ioread32(&intr_ctrl[intr_idx].credits);
8262306a36Sopenharmony_ci	cred &= IONIC_INTR_CRED_COUNT_SIGNED;
8362306a36Sopenharmony_ci	cred |= IONIC_INTR_CRED_RESET_COALESCE;
8462306a36Sopenharmony_ci	iowrite32(cred, &intr_ctrl[intr_idx].credits);
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic inline void ionic_intr_mask_assert(struct ionic_intr __iomem *intr_ctrl,
8862306a36Sopenharmony_ci					  int intr_idx, u32 mask)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	iowrite32(mask, &intr_ctrl[intr_idx].mask_assert);
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/** enum ionic_dbell_bits - bitwise composition of dbell values.
9462306a36Sopenharmony_ci *
9562306a36Sopenharmony_ci * @IONIC_DBELL_QID_MASK:	unshifted mask of valid queue id bits.
9662306a36Sopenharmony_ci * @IONIC_DBELL_QID_SHIFT:	queue id shift amount in dbell value.
9762306a36Sopenharmony_ci * @IONIC_DBELL_QID:		macro to build QID component of dbell value.
9862306a36Sopenharmony_ci *
9962306a36Sopenharmony_ci * @IONIC_DBELL_RING_MASK:	unshifted mask of valid ring bits.
10062306a36Sopenharmony_ci * @IONIC_DBELL_RING_SHIFT:	ring shift amount in dbell value.
10162306a36Sopenharmony_ci * @IONIC_DBELL_RING:		macro to build ring component of dbell value.
10262306a36Sopenharmony_ci *
10362306a36Sopenharmony_ci * @IONIC_DBELL_RING_0:		ring zero dbell component value.
10462306a36Sopenharmony_ci * @IONIC_DBELL_RING_1:		ring one dbell component value.
10562306a36Sopenharmony_ci * @IONIC_DBELL_RING_2:		ring two dbell component value.
10662306a36Sopenharmony_ci * @IONIC_DBELL_RING_3:		ring three dbell component value.
10762306a36Sopenharmony_ci *
10862306a36Sopenharmony_ci * @IONIC_DBELL_INDEX_MASK:	bit mask of valid index bits, no shift needed.
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_cienum ionic_dbell_bits {
11162306a36Sopenharmony_ci	IONIC_DBELL_QID_MASK		= 0xffffff,
11262306a36Sopenharmony_ci	IONIC_DBELL_QID_SHIFT		= 24,
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci#define IONIC_DBELL_QID(n) \
11562306a36Sopenharmony_ci	(((u64)(n) & IONIC_DBELL_QID_MASK) << IONIC_DBELL_QID_SHIFT)
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	IONIC_DBELL_RING_MASK		= 0x7,
11862306a36Sopenharmony_ci	IONIC_DBELL_RING_SHIFT		= 16,
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#define IONIC_DBELL_RING(n) \
12162306a36Sopenharmony_ci	(((u64)(n) & IONIC_DBELL_RING_MASK) << IONIC_DBELL_RING_SHIFT)
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	IONIC_DBELL_RING_0		= 0,
12462306a36Sopenharmony_ci	IONIC_DBELL_RING_1		= IONIC_DBELL_RING(1),
12562306a36Sopenharmony_ci	IONIC_DBELL_RING_2		= IONIC_DBELL_RING(2),
12662306a36Sopenharmony_ci	IONIC_DBELL_RING_3		= IONIC_DBELL_RING(3),
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	IONIC_DBELL_INDEX_MASK		= 0xffff,
12962306a36Sopenharmony_ci};
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cistatic inline void ionic_dbell_ring(u64 __iomem *db_page, int qtype, u64 val)
13262306a36Sopenharmony_ci{
13362306a36Sopenharmony_ci	writeq(val, &db_page[qtype]);
13462306a36Sopenharmony_ci}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci#endif /* IONIC_REGS_H */
137