xref: /linux/arch/loongarch/include/asm/kvm_eiointc.h (revision c34e9ab9a612ee8b18273398ef75c207b01f516d)
12e8b9df8SXianglai Li /* SPDX-License-Identifier: GPL-2.0 */
22e8b9df8SXianglai Li /*
32e8b9df8SXianglai Li  * Copyright (C) 2024 Loongson Technology Corporation Limited
42e8b9df8SXianglai Li  */
52e8b9df8SXianglai Li 
62e8b9df8SXianglai Li #ifndef __ASM_KVM_EIOINTC_H
72e8b9df8SXianglai Li #define __ASM_KVM_EIOINTC_H
82e8b9df8SXianglai Li 
92e8b9df8SXianglai Li #include <kvm/iodev.h>
102e8b9df8SXianglai Li 
112e8b9df8SXianglai Li #define EIOINTC_IRQS			256
122e8b9df8SXianglai Li #define EIOINTC_ROUTE_MAX_VCPUS		256
132e8b9df8SXianglai Li #define EIOINTC_IRQS_U8_NUMS		(EIOINTC_IRQS / 8)
142e8b9df8SXianglai Li #define EIOINTC_IRQS_U16_NUMS		(EIOINTC_IRQS_U8_NUMS / 2)
152e8b9df8SXianglai Li #define EIOINTC_IRQS_U32_NUMS		(EIOINTC_IRQS_U8_NUMS / 4)
162e8b9df8SXianglai Li #define EIOINTC_IRQS_U64_NUMS		(EIOINTC_IRQS_U8_NUMS / 8)
172e8b9df8SXianglai Li /* map to ipnum per 32 irqs */
182e8b9df8SXianglai Li #define EIOINTC_IRQS_NODETYPE_COUNT	16
192e8b9df8SXianglai Li 
202e8b9df8SXianglai Li #define EIOINTC_BASE			0x1400
212e8b9df8SXianglai Li #define EIOINTC_SIZE			0x900
222e8b9df8SXianglai Li 
23*3956a52bSXianglai Li #define EIOINTC_NODETYPE_START		0xa0
24*3956a52bSXianglai Li #define EIOINTC_NODETYPE_END		0xbf
25*3956a52bSXianglai Li #define EIOINTC_IPMAP_START		0xc0
26*3956a52bSXianglai Li #define EIOINTC_IPMAP_END		0xc7
27*3956a52bSXianglai Li #define EIOINTC_ENABLE_START		0x200
28*3956a52bSXianglai Li #define EIOINTC_ENABLE_END		0x21f
29*3956a52bSXianglai Li #define EIOINTC_BOUNCE_START		0x280
30*3956a52bSXianglai Li #define EIOINTC_BOUNCE_END		0x29f
31*3956a52bSXianglai Li #define EIOINTC_ISR_START		0x300
32*3956a52bSXianglai Li #define EIOINTC_ISR_END			0x31f
33*3956a52bSXianglai Li #define EIOINTC_COREISR_START		0x400
34*3956a52bSXianglai Li #define EIOINTC_COREISR_END		0x41f
35*3956a52bSXianglai Li #define EIOINTC_COREMAP_START		0x800
36*3956a52bSXianglai Li #define EIOINTC_COREMAP_END		0x8ff
37*3956a52bSXianglai Li 
382e8b9df8SXianglai Li #define EIOINTC_VIRT_BASE		(0x40000000)
392e8b9df8SXianglai Li #define EIOINTC_VIRT_SIZE		(0x1000)
402e8b9df8SXianglai Li 
41*3956a52bSXianglai Li #define EIOINTC_VIRT_FEATURES		(0x0)
42*3956a52bSXianglai Li #define EIOINTC_HAS_VIRT_EXTENSION	(0)
43*3956a52bSXianglai Li #define EIOINTC_HAS_ENABLE_OPTION	(1)
44*3956a52bSXianglai Li #define EIOINTC_HAS_INT_ENCODE		(2)
45*3956a52bSXianglai Li #define EIOINTC_HAS_CPU_ENCODE		(3)
46*3956a52bSXianglai Li #define EIOINTC_VIRT_HAS_FEATURES	((1U << EIOINTC_HAS_VIRT_EXTENSION) \
47*3956a52bSXianglai Li 					| (1U << EIOINTC_HAS_ENABLE_OPTION) \
48*3956a52bSXianglai Li 					| (1U << EIOINTC_HAS_INT_ENCODE)    \
49*3956a52bSXianglai Li 					| (1U << EIOINTC_HAS_CPU_ENCODE))
50*3956a52bSXianglai Li #define EIOINTC_VIRT_CONFIG		(0x4)
51*3956a52bSXianglai Li #define EIOINTC_ENABLE			(1)
52*3956a52bSXianglai Li #define EIOINTC_ENABLE_INT_ENCODE	(2)
53*3956a52bSXianglai Li #define EIOINTC_ENABLE_CPU_ENCODE	(3)
54*3956a52bSXianglai Li 
552e8b9df8SXianglai Li #define LOONGSON_IP_NUM			8
562e8b9df8SXianglai Li 
572e8b9df8SXianglai Li struct loongarch_eiointc {
582e8b9df8SXianglai Li 	spinlock_t lock;
592e8b9df8SXianglai Li 	struct kvm *kvm;
602e8b9df8SXianglai Li 	struct kvm_io_device device;
612e8b9df8SXianglai Li 	struct kvm_io_device device_vext;
622e8b9df8SXianglai Li 	uint32_t num_cpu;
632e8b9df8SXianglai Li 	uint32_t features;
642e8b9df8SXianglai Li 	uint32_t status;
652e8b9df8SXianglai Li 
662e8b9df8SXianglai Li 	/* hardware state */
672e8b9df8SXianglai Li 	union nodetype {
682e8b9df8SXianglai Li 		u64 reg_u64[EIOINTC_IRQS_NODETYPE_COUNT / 4];
692e8b9df8SXianglai Li 		u32 reg_u32[EIOINTC_IRQS_NODETYPE_COUNT / 2];
702e8b9df8SXianglai Li 		u16 reg_u16[EIOINTC_IRQS_NODETYPE_COUNT];
712e8b9df8SXianglai Li 		u8 reg_u8[EIOINTC_IRQS_NODETYPE_COUNT * 2];
722e8b9df8SXianglai Li 	} nodetype;
732e8b9df8SXianglai Li 
742e8b9df8SXianglai Li 	/* one bit shows the state of one irq */
752e8b9df8SXianglai Li 	union bounce {
762e8b9df8SXianglai Li 		u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
772e8b9df8SXianglai Li 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
782e8b9df8SXianglai Li 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
792e8b9df8SXianglai Li 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
802e8b9df8SXianglai Li 	} bounce;
812e8b9df8SXianglai Li 
822e8b9df8SXianglai Li 	union isr {
832e8b9df8SXianglai Li 		u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
842e8b9df8SXianglai Li 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
852e8b9df8SXianglai Li 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
862e8b9df8SXianglai Li 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
872e8b9df8SXianglai Li 	} isr;
882e8b9df8SXianglai Li 	union coreisr {
892e8b9df8SXianglai Li 		u64 reg_u64[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS];
902e8b9df8SXianglai Li 		u32 reg_u32[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U32_NUMS];
912e8b9df8SXianglai Li 		u16 reg_u16[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U16_NUMS];
922e8b9df8SXianglai Li 		u8 reg_u8[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U8_NUMS];
932e8b9df8SXianglai Li 	} coreisr;
942e8b9df8SXianglai Li 	union enable {
952e8b9df8SXianglai Li 		u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
962e8b9df8SXianglai Li 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
972e8b9df8SXianglai Li 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
982e8b9df8SXianglai Li 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
992e8b9df8SXianglai Li 	} enable;
1002e8b9df8SXianglai Li 
1012e8b9df8SXianglai Li 	/* use one byte to config ipmap for 32 irqs at once */
1022e8b9df8SXianglai Li 	union ipmap {
1032e8b9df8SXianglai Li 		u64 reg_u64;
1042e8b9df8SXianglai Li 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS / 4];
1052e8b9df8SXianglai Li 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS / 4];
1062e8b9df8SXianglai Li 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS / 4];
1072e8b9df8SXianglai Li 	} ipmap;
1082e8b9df8SXianglai Li 	/* use one byte to config coremap for one irq */
1092e8b9df8SXianglai Li 	union coremap {
1102e8b9df8SXianglai Li 		u64 reg_u64[EIOINTC_IRQS / 8];
1112e8b9df8SXianglai Li 		u32 reg_u32[EIOINTC_IRQS / 4];
1122e8b9df8SXianglai Li 		u16 reg_u16[EIOINTC_IRQS / 2];
1132e8b9df8SXianglai Li 		u8 reg_u8[EIOINTC_IRQS];
1142e8b9df8SXianglai Li 	} coremap;
1152e8b9df8SXianglai Li 
1162e8b9df8SXianglai Li 	DECLARE_BITMAP(sw_coreisr[EIOINTC_ROUTE_MAX_VCPUS][LOONGSON_IP_NUM], EIOINTC_IRQS);
1172e8b9df8SXianglai Li 	uint8_t  sw_coremap[EIOINTC_IRQS];
1182e8b9df8SXianglai Li };
1192e8b9df8SXianglai Li 
1202e8b9df8SXianglai Li int kvm_loongarch_register_eiointc_device(void);
121*3956a52bSXianglai Li void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level);
1222e8b9df8SXianglai Li 
1232e8b9df8SXianglai Li #endif /* __ASM_KVM_EIOINTC_H */
124