1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2021 Western Digital Corporation or its affiliates.
4 * Copyright (C) 2022 Ventana Micro Systems Inc.
5 */
6#ifndef __LINUX_IRQCHIP_RISCV_IMSIC_H
7#define __LINUX_IRQCHIP_RISCV_IMSIC_H
8
9#include <linux/types.h>
10#include <linux/bitops.h>
11#include <asm/csr.h>
12
13#define IMSIC_MMIO_PAGE_SHIFT		12
14#define IMSIC_MMIO_PAGE_SZ		BIT(IMSIC_MMIO_PAGE_SHIFT)
15#define IMSIC_MMIO_PAGE_LE		0x00
16#define IMSIC_MMIO_PAGE_BE		0x04
17
18#define IMSIC_MIN_ID			63
19#define IMSIC_MAX_ID			2048
20
21#define IMSIC_EIDELIVERY		0x70
22
23#define IMSIC_EITHRESHOLD		0x72
24
25#define IMSIC_EIP0			0x80
26#define IMSIC_EIP63			0xbf
27#define IMSIC_EIPx_BITS			32
28
29#define IMSIC_EIE0			0xc0
30#define IMSIC_EIE63			0xff
31#define IMSIC_EIEx_BITS			32
32
33#define IMSIC_FIRST			IMSIC_EIDELIVERY
34#define IMSIC_LAST			IMSIC_EIE63
35
36#define IMSIC_MMIO_SETIPNUM_LE		0x00
37#define IMSIC_MMIO_SETIPNUM_BE		0x04
38
39struct imsic_local_config {
40	phys_addr_t				msi_pa;
41	void __iomem				*msi_va;
42};
43
44struct imsic_global_config {
45	/*
46	 * MSI Target Address Scheme
47	 *
48	 * XLEN-1                                                12     0
49	 * |                                                     |     |
50	 * -------------------------------------------------------------
51	 * |xxxxxx|Group Index|xxxxxxxxxxx|HART Index|Guest Index|  0  |
52	 * -------------------------------------------------------------
53	 */
54
55	/* Bits representing Guest index, HART index, and Group index */
56	u32					guest_index_bits;
57	u32					hart_index_bits;
58	u32					group_index_bits;
59	u32					group_index_shift;
60
61	/* Global base address matching all target MSI addresses */
62	phys_addr_t				base_addr;
63
64	/* Number of interrupt identities */
65	u32					nr_ids;
66
67	/* Number of guest interrupt identities */
68	u32					nr_guest_ids;
69
70	/* Per-CPU IMSIC addresses */
71	struct imsic_local_config __percpu	*local;
72};
73
74#ifdef CONFIG_RISCV_IMSIC
75
76const struct imsic_global_config *imsic_get_global_config(void);
77
78#else
79
80static inline const struct imsic_global_config *imsic_get_global_config(void)
81{
82	return NULL;
83}
84
85#endif
86
87#endif
88