18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Imagination Technologies
48c2ecf20Sopenharmony_ci * Author: Paul Burton <paul.burton@mips.com>
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef __MIPS_ASM_MIPS_CPS_H__
88c2ecf20Sopenharmony_ci# error Please include asm/mips-cps.h rather than asm/mips-gic.h
98c2ecf20Sopenharmony_ci#endif
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef __MIPS_ASM_MIPS_GIC_H__
128c2ecf20Sopenharmony_ci#define __MIPS_ASM_MIPS_GIC_H__
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/bitops.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci/* The base address of the GIC registers */
178c2ecf20Sopenharmony_ciextern void __iomem *mips_gic_base;
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/* Offsets from the GIC base address to various control blocks */
208c2ecf20Sopenharmony_ci#define MIPS_GIC_SHARED_OFS	0x00000
218c2ecf20Sopenharmony_ci#define MIPS_GIC_SHARED_SZ	0x08000
228c2ecf20Sopenharmony_ci#define MIPS_GIC_LOCAL_OFS	0x08000
238c2ecf20Sopenharmony_ci#define MIPS_GIC_LOCAL_SZ	0x04000
248c2ecf20Sopenharmony_ci#define MIPS_GIC_REDIR_OFS	0x0c000
258c2ecf20Sopenharmony_ci#define MIPS_GIC_REDIR_SZ	0x04000
268c2ecf20Sopenharmony_ci#define MIPS_GIC_USER_OFS	0x10000
278c2ecf20Sopenharmony_ci#define MIPS_GIC_USER_SZ	0x10000
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/* For read-only shared registers */
308c2ecf20Sopenharmony_ci#define GIC_ACCESSOR_RO(sz, off, name)					\
318c2ecf20Sopenharmony_ci	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/* For read-write shared registers */
348c2ecf20Sopenharmony_ci#define GIC_ACCESSOR_RW(sz, off, name)					\
358c2ecf20Sopenharmony_ci	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/* For read-only local registers */
388c2ecf20Sopenharmony_ci#define GIC_VX_ACCESSOR_RO(sz, off, name)				\
398c2ecf20Sopenharmony_ci	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
408c2ecf20Sopenharmony_ci	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/* For read-write local registers */
438c2ecf20Sopenharmony_ci#define GIC_VX_ACCESSOR_RW(sz, off, name)				\
448c2ecf20Sopenharmony_ci	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
458c2ecf20Sopenharmony_ci	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/* For read-only shared per-interrupt registers */
488c2ecf20Sopenharmony_ci#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
498c2ecf20Sopenharmony_cistatic inline void __iomem *addr_gic_##name(unsigned int intr)		\
508c2ecf20Sopenharmony_ci{									\
518c2ecf20Sopenharmony_ci	return mips_gic_base + (off) + (intr * (stride));		\
528c2ecf20Sopenharmony_ci}									\
538c2ecf20Sopenharmony_ci									\
548c2ecf20Sopenharmony_cistatic inline unsigned int read_gic_##name(unsigned int intr)		\
558c2ecf20Sopenharmony_ci{									\
568c2ecf20Sopenharmony_ci	BUILD_BUG_ON(sz != 32);						\
578c2ecf20Sopenharmony_ci	return __raw_readl(addr_gic_##name(intr));			\
588c2ecf20Sopenharmony_ci}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci/* For read-write shared per-interrupt registers */
618c2ecf20Sopenharmony_ci#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
628c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
638c2ecf20Sopenharmony_ci									\
648c2ecf20Sopenharmony_cistatic inline void write_gic_##name(unsigned int intr,			\
658c2ecf20Sopenharmony_ci				    unsigned int val)			\
668c2ecf20Sopenharmony_ci{									\
678c2ecf20Sopenharmony_ci	BUILD_BUG_ON(sz != 32);						\
688c2ecf20Sopenharmony_ci	__raw_writel(val, addr_gic_##name(intr));			\
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci/* For read-only local per-interrupt registers */
728c2ecf20Sopenharmony_ci#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
738c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
748c2ecf20Sopenharmony_ci				 stride, vl_##name)			\
758c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
768c2ecf20Sopenharmony_ci				 stride, vo_##name)
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/* For read-write local per-interrupt registers */
798c2ecf20Sopenharmony_ci#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
808c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
818c2ecf20Sopenharmony_ci				 stride, vl_##name)			\
828c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
838c2ecf20Sopenharmony_ci				 stride, vo_##name)
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci/* For read-only shared bit-per-interrupt registers */
868c2ecf20Sopenharmony_ci#define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
878c2ecf20Sopenharmony_cistatic inline void __iomem *addr_gic_##name(void)			\
888c2ecf20Sopenharmony_ci{									\
898c2ecf20Sopenharmony_ci	return mips_gic_base + (off);					\
908c2ecf20Sopenharmony_ci}									\
918c2ecf20Sopenharmony_ci									\
928c2ecf20Sopenharmony_cistatic inline unsigned int read_gic_##name(unsigned int intr)		\
938c2ecf20Sopenharmony_ci{									\
948c2ecf20Sopenharmony_ci	void __iomem *addr = addr_gic_##name();				\
958c2ecf20Sopenharmony_ci	unsigned int val;						\
968c2ecf20Sopenharmony_ci									\
978c2ecf20Sopenharmony_ci	if (mips_cm_is64) {						\
988c2ecf20Sopenharmony_ci		addr += (intr / 64) * sizeof(uint64_t);			\
998c2ecf20Sopenharmony_ci		val = __raw_readq(addr) >> intr % 64;			\
1008c2ecf20Sopenharmony_ci	} else {							\
1018c2ecf20Sopenharmony_ci		addr += (intr / 32) * sizeof(uint32_t);			\
1028c2ecf20Sopenharmony_ci		val = __raw_readl(addr) >> intr % 32;			\
1038c2ecf20Sopenharmony_ci	}								\
1048c2ecf20Sopenharmony_ci									\
1058c2ecf20Sopenharmony_ci	return val & 0x1;						\
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci/* For read-write shared bit-per-interrupt registers */
1098c2ecf20Sopenharmony_ci#define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
1108c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
1118c2ecf20Sopenharmony_ci									\
1128c2ecf20Sopenharmony_cistatic inline void write_gic_##name(unsigned int intr)			\
1138c2ecf20Sopenharmony_ci{									\
1148c2ecf20Sopenharmony_ci	void __iomem *addr = addr_gic_##name();				\
1158c2ecf20Sopenharmony_ci									\
1168c2ecf20Sopenharmony_ci	if (mips_cm_is64) {						\
1178c2ecf20Sopenharmony_ci		addr += (intr / 64) * sizeof(uint64_t);			\
1188c2ecf20Sopenharmony_ci		__raw_writeq(BIT(intr % 64), addr);			\
1198c2ecf20Sopenharmony_ci	} else {							\
1208c2ecf20Sopenharmony_ci		addr += (intr / 32) * sizeof(uint32_t);			\
1218c2ecf20Sopenharmony_ci		__raw_writel(BIT(intr % 32), addr);			\
1228c2ecf20Sopenharmony_ci	}								\
1238c2ecf20Sopenharmony_ci}									\
1248c2ecf20Sopenharmony_ci									\
1258c2ecf20Sopenharmony_cistatic inline void change_gic_##name(unsigned int intr,			\
1268c2ecf20Sopenharmony_ci				     unsigned int val)			\
1278c2ecf20Sopenharmony_ci{									\
1288c2ecf20Sopenharmony_ci	void __iomem *addr = addr_gic_##name();				\
1298c2ecf20Sopenharmony_ci									\
1308c2ecf20Sopenharmony_ci	if (mips_cm_is64) {						\
1318c2ecf20Sopenharmony_ci		uint64_t _val;						\
1328c2ecf20Sopenharmony_ci									\
1338c2ecf20Sopenharmony_ci		addr += (intr / 64) * sizeof(uint64_t);			\
1348c2ecf20Sopenharmony_ci		_val = __raw_readq(addr);				\
1358c2ecf20Sopenharmony_ci		_val &= ~BIT_ULL(intr % 64);				\
1368c2ecf20Sopenharmony_ci		_val |= (uint64_t)val << (intr % 64);			\
1378c2ecf20Sopenharmony_ci		__raw_writeq(_val, addr);				\
1388c2ecf20Sopenharmony_ci	} else {							\
1398c2ecf20Sopenharmony_ci		uint32_t _val;						\
1408c2ecf20Sopenharmony_ci									\
1418c2ecf20Sopenharmony_ci		addr += (intr / 32) * sizeof(uint32_t);			\
1428c2ecf20Sopenharmony_ci		_val = __raw_readl(addr);				\
1438c2ecf20Sopenharmony_ci		_val &= ~BIT(intr % 32);				\
1448c2ecf20Sopenharmony_ci		_val |= val << (intr % 32);				\
1458c2ecf20Sopenharmony_ci		__raw_writel(_val, addr);				\
1468c2ecf20Sopenharmony_ci	}								\
1478c2ecf20Sopenharmony_ci}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci/* For read-only local bit-per-interrupt registers */
1508c2ecf20Sopenharmony_ci#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name)			\
1518c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
1528c2ecf20Sopenharmony_ci				 vl_##name)				\
1538c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
1548c2ecf20Sopenharmony_ci				 vo_##name)
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci/* For read-write local bit-per-interrupt registers */
1578c2ecf20Sopenharmony_ci#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name)			\
1588c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
1598c2ecf20Sopenharmony_ci				 vl_##name)				\
1608c2ecf20Sopenharmony_ci	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
1618c2ecf20Sopenharmony_ci				 vo_##name)
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci/* GIC_SH_CONFIG - Information about the GIC configuration */
1648c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW(32, 0x000, config)
1658c2ecf20Sopenharmony_ci#define GIC_CONFIG_COUNTSTOP		BIT(28)
1668c2ecf20Sopenharmony_ci#define GIC_CONFIG_COUNTBITS		GENMASK(27, 24)
1678c2ecf20Sopenharmony_ci#define GIC_CONFIG_NUMINTERRUPTS	GENMASK(23, 16)
1688c2ecf20Sopenharmony_ci#define GIC_CONFIG_PVPS			GENMASK(6, 0)
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci/* GIC_SH_COUNTER - Shared global counter value */
1718c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW(64, 0x010, counter)
1728c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW(32, 0x010, counter_32l)
1738c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW(32, 0x014, counter_32h)
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci/* GIC_SH_POL_* - Configures interrupt polarity */
1768c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
1778c2ecf20Sopenharmony_ci#define GIC_POL_ACTIVE_LOW		0	/* when level triggered */
1788c2ecf20Sopenharmony_ci#define GIC_POL_ACTIVE_HIGH		1	/* when level triggered */
1798c2ecf20Sopenharmony_ci#define GIC_POL_FALLING_EDGE		0	/* when single-edge triggered */
1808c2ecf20Sopenharmony_ci#define GIC_POL_RISING_EDGE		1	/* when single-edge triggered */
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci/* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */
1838c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
1848c2ecf20Sopenharmony_ci#define GIC_TRIG_LEVEL			0
1858c2ecf20Sopenharmony_ci#define GIC_TRIG_EDGE			1
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci/* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */
1888c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
1898c2ecf20Sopenharmony_ci#define GIC_DUAL_SINGLE			0	/* when edge-triggered */
1908c2ecf20Sopenharmony_ci#define GIC_DUAL_DUAL			1	/* when edge-triggered */
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci/* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */
1938c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW(32, 0x280, wedge)
1948c2ecf20Sopenharmony_ci#define GIC_WEDGE_RW			BIT(31)
1958c2ecf20Sopenharmony_ci#define GIC_WEDGE_INTR			GENMASK(7, 0)
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci/* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */
1988c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci/* GIC_SH_SMASK_* - Set shared interrupt mask bits */
2018c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci/* GIC_SH_MASK_* - Read the current shared interrupt mask */
2048c2ecf20Sopenharmony_ciGIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/* GIC_SH_PEND_* - Read currently pending shared interrupts */
2078c2ecf20Sopenharmony_ciGIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */
2108c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin)
2118c2ecf20Sopenharmony_ci#define GIC_MAP_PIN_MAP_TO_PIN		BIT(31)
2128c2ecf20Sopenharmony_ci#define GIC_MAP_PIN_MAP_TO_NMI		BIT(30)
2138c2ecf20Sopenharmony_ci#define GIC_MAP_PIN_MAP			GENMASK(5, 0)
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci/* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */
2168c2ecf20Sopenharmony_ciGIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci/* GIC_Vx_CTL - VP-level interrupt control */
2198c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x000, ctl)
2208c2ecf20Sopenharmony_ci#define GIC_VX_CTL_FDC_ROUTABLE		BIT(4)
2218c2ecf20Sopenharmony_ci#define GIC_VX_CTL_SWINT_ROUTABLE	BIT(3)
2228c2ecf20Sopenharmony_ci#define GIC_VX_CTL_PERFCNT_ROUTABLE	BIT(2)
2238c2ecf20Sopenharmony_ci#define GIC_VX_CTL_TIMER_ROUTABLE	BIT(1)
2248c2ecf20Sopenharmony_ci#define GIC_VX_CTL_EIC			BIT(0)
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci/* GIC_Vx_PEND - Read currently pending local interrupts */
2278c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RO(32, 0x004, pend)
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci/* GIC_Vx_MASK - Read the current local interrupt mask */
2308c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RO(32, 0x008, mask)
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */
2338c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci/* GIC_Vx_SMASK - Set local interrupt mask bits */
2368c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x010, smask)
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */
2398c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */
2428c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */
2458c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */
2488c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */
2518c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */
2548c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */
2578c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */
2608c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */
2638c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(32, 0x080, other)
2648c2ecf20Sopenharmony_ci#define GIC_VX_OTHER_VPNUM		GENMASK(5, 0)
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci/* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */
2678c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RO(32, 0x088, ident)
2688c2ecf20Sopenharmony_ci#define GIC_VX_IDENT_VPNUM		GENMASK(5, 0)
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci/* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */
2718c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
2748c2ecf20Sopenharmony_ciGIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci/**
2778c2ecf20Sopenharmony_ci * enum mips_gic_local_interrupt - GIC local interrupts
2788c2ecf20Sopenharmony_ci * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt
2798c2ecf20Sopenharmony_ci * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt
2808c2ecf20Sopenharmony_ci * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt
2818c2ecf20Sopenharmony_ci * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt
2828c2ecf20Sopenharmony_ci * @GIC_LOCAL_INT_SWINT0: Software interrupt 0
2838c2ecf20Sopenharmony_ci * @GIC_LOCAL_INT_SWINT1: Software interrupt 1
2848c2ecf20Sopenharmony_ci * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt
2858c2ecf20Sopenharmony_ci * @GIC_NUM_LOCAL_INTRS: The number of local interrupts
2868c2ecf20Sopenharmony_ci *
2878c2ecf20Sopenharmony_ci * Enumerates interrupts provided by the GIC that are local to a VP.
2888c2ecf20Sopenharmony_ci */
2898c2ecf20Sopenharmony_cienum mips_gic_local_interrupt {
2908c2ecf20Sopenharmony_ci	GIC_LOCAL_INT_WD,
2918c2ecf20Sopenharmony_ci	GIC_LOCAL_INT_COMPARE,
2928c2ecf20Sopenharmony_ci	GIC_LOCAL_INT_TIMER,
2938c2ecf20Sopenharmony_ci	GIC_LOCAL_INT_PERFCTR,
2948c2ecf20Sopenharmony_ci	GIC_LOCAL_INT_SWINT0,
2958c2ecf20Sopenharmony_ci	GIC_LOCAL_INT_SWINT1,
2968c2ecf20Sopenharmony_ci	GIC_LOCAL_INT_FDC,
2978c2ecf20Sopenharmony_ci	GIC_NUM_LOCAL_INTRS
2988c2ecf20Sopenharmony_ci};
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci/**
3018c2ecf20Sopenharmony_ci * mips_gic_present() - Determine whether a GIC is present
3028c2ecf20Sopenharmony_ci *
3038c2ecf20Sopenharmony_ci * Determines whether a MIPS Global Interrupt Controller (GIC) is present in
3048c2ecf20Sopenharmony_ci * the system that the kernel is running on.
3058c2ecf20Sopenharmony_ci *
3068c2ecf20Sopenharmony_ci * Return true if a GIC is present, else false.
3078c2ecf20Sopenharmony_ci */
3088c2ecf20Sopenharmony_cistatic inline bool mips_gic_present(void)
3098c2ecf20Sopenharmony_ci{
3108c2ecf20Sopenharmony_ci	return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
3118c2ecf20Sopenharmony_ci}
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci/**
3148c2ecf20Sopenharmony_ci * mips_gic_vx_map_reg() - Return GIC_Vx_<intr>_MAP register offset
3158c2ecf20Sopenharmony_ci * @intr: A GIC local interrupt
3168c2ecf20Sopenharmony_ci *
3178c2ecf20Sopenharmony_ci * Determine the index of the GIC_VL_<intr>_MAP or GIC_VO_<intr>_MAP register
3188c2ecf20Sopenharmony_ci * within the block of GIC map registers. This is almost the same as the order
3198c2ecf20Sopenharmony_ci * of interrupts in the pending & mask registers, as used by enum
3208c2ecf20Sopenharmony_ci * mips_gic_local_interrupt, but moves the FDC interrupt & thus offsets the
3218c2ecf20Sopenharmony_ci * interrupts after it...
3228c2ecf20Sopenharmony_ci *
3238c2ecf20Sopenharmony_ci * Return: The map register index corresponding to @intr.
3248c2ecf20Sopenharmony_ci *
3258c2ecf20Sopenharmony_ci * The return value is suitable for use with the (read|write)_gic_v[lo]_map
3268c2ecf20Sopenharmony_ci * accessor functions.
3278c2ecf20Sopenharmony_ci */
3288c2ecf20Sopenharmony_cistatic inline unsigned int
3298c2ecf20Sopenharmony_cimips_gic_vx_map_reg(enum mips_gic_local_interrupt intr)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	/* WD, Compare & Timer are 1:1 */
3328c2ecf20Sopenharmony_ci	if (intr <= GIC_LOCAL_INT_TIMER)
3338c2ecf20Sopenharmony_ci		return intr;
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	/* FDC moves to after Timer... */
3368c2ecf20Sopenharmony_ci	if (intr == GIC_LOCAL_INT_FDC)
3378c2ecf20Sopenharmony_ci		return GIC_LOCAL_INT_TIMER + 1;
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci	/* As a result everything else is offset by 1 */
3408c2ecf20Sopenharmony_ci	return intr + 1;
3418c2ecf20Sopenharmony_ci}
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci/**
3448c2ecf20Sopenharmony_ci * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq
3458c2ecf20Sopenharmony_ci *
3468c2ecf20Sopenharmony_ci * Determine the virq number to use for the coprocessor 0 count/compare
3478c2ecf20Sopenharmony_ci * interrupt, which may be routed via the GIC.
3488c2ecf20Sopenharmony_ci *
3498c2ecf20Sopenharmony_ci * Returns the virq number or a negative error number.
3508c2ecf20Sopenharmony_ci */
3518c2ecf20Sopenharmony_ciextern int gic_get_c0_compare_int(void);
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci/**
3548c2ecf20Sopenharmony_ci * gic_get_c0_perfcount_int() - Return performance counter interrupt virq
3558c2ecf20Sopenharmony_ci *
3568c2ecf20Sopenharmony_ci * Determine the virq number to use for CPU performance counter interrupts,
3578c2ecf20Sopenharmony_ci * which may be routed via the GIC.
3588c2ecf20Sopenharmony_ci *
3598c2ecf20Sopenharmony_ci * Returns the virq number or a negative error number.
3608c2ecf20Sopenharmony_ci */
3618c2ecf20Sopenharmony_ciextern int gic_get_c0_perfcount_int(void);
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci/**
3648c2ecf20Sopenharmony_ci * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq
3658c2ecf20Sopenharmony_ci *
3668c2ecf20Sopenharmony_ci * Determine the virq number to use for fast debug channel (FDC) interrupts,
3678c2ecf20Sopenharmony_ci * which may be routed via the GIC.
3688c2ecf20Sopenharmony_ci *
3698c2ecf20Sopenharmony_ci * Returns the virq number or a negative error number.
3708c2ecf20Sopenharmony_ci */
3718c2ecf20Sopenharmony_ciextern int gic_get_c0_fdc_int(void);
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci#endif /* __MIPS_ASM_MIPS_CPS_H__ */
374