1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __ASM_ARM_CACHETYPE_H
3#define __ASM_ARM_CACHETYPE_H
4
5#define CACHEID_VIVT			(1 << 0)
6#define CACHEID_VIPT_NONALIASING	(1 << 1)
7#define CACHEID_VIPT_ALIASING		(1 << 2)
8#define CACHEID_VIPT			(CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
9#define CACHEID_ASID_TAGGED		(1 << 3)
10#define CACHEID_VIPT_I_ALIASING		(1 << 4)
11#define CACHEID_PIPT			(1 << 5)
12
13extern unsigned int cacheid;
14
15#define cache_is_vivt()			cacheid_is(CACHEID_VIVT)
16#define cache_is_vipt()			cacheid_is(CACHEID_VIPT)
17#define cache_is_vipt_nonaliasing()	cacheid_is(CACHEID_VIPT_NONALIASING)
18#define cache_is_vipt_aliasing()	cacheid_is(CACHEID_VIPT_ALIASING)
19#define icache_is_vivt_asid_tagged()	cacheid_is(CACHEID_ASID_TAGGED)
20#define icache_is_vipt_aliasing()	cacheid_is(CACHEID_VIPT_I_ALIASING)
21#define icache_is_pipt()		cacheid_is(CACHEID_PIPT)
22
23#define cpu_dcache_is_aliasing()	(cache_is_vivt() || cache_is_vipt_aliasing())
24
25/*
26 * __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
27 * Mask out support which will never be present on newer CPUs.
28 * - v6+ is never VIVT
29 * - v7+ VIPT never aliases on D-side
30 */
31#if __LINUX_ARM_ARCH__ >= 7
32#define __CACHEID_ARCH_MIN	(CACHEID_VIPT_NONALIASING |\
33				 CACHEID_ASID_TAGGED |\
34				 CACHEID_VIPT_I_ALIASING |\
35				 CACHEID_PIPT)
36#elif __LINUX_ARM_ARCH__ >= 6
37#define	__CACHEID_ARCH_MIN	(~CACHEID_VIVT)
38#else
39#define __CACHEID_ARCH_MIN	(~0)
40#endif
41
42/*
43 * Mask out support which isn't configured
44 */
45#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
46#define __CACHEID_ALWAYS	(CACHEID_VIVT)
47#define __CACHEID_NEVER		(~CACHEID_VIVT)
48#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT)
49#define __CACHEID_ALWAYS	(0)
50#define __CACHEID_NEVER		(CACHEID_VIVT)
51#else
52#define __CACHEID_ALWAYS	(0)
53#define __CACHEID_NEVER		(0)
54#endif
55
56static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask)
57{
58	return (__CACHEID_ALWAYS & mask) |
59	       (~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid);
60}
61
62#define CSSELR_ICACHE	1
63#define CSSELR_DCACHE	0
64
65#define CSSELR_L1	(0 << 1)
66#define CSSELR_L2	(1 << 1)
67#define CSSELR_L3	(2 << 1)
68#define CSSELR_L4	(3 << 1)
69#define CSSELR_L5	(4 << 1)
70#define CSSELR_L6	(5 << 1)
71#define CSSELR_L7	(6 << 1)
72
73#ifndef CONFIG_CPU_V7M
74static inline void set_csselr(unsigned int cache_selector)
75{
76	asm volatile("mcr p15, 2, %0, c0, c0, 0" : : "r" (cache_selector));
77}
78
79static inline unsigned int read_ccsidr(void)
80{
81	unsigned int val;
82
83	asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (val));
84	return val;
85}
86#else /* CONFIG_CPU_V7M */
87#include <linux/io.h>
88#include "asm/v7m.h"
89
90static inline void set_csselr(unsigned int cache_selector)
91{
92	writel(cache_selector, BASEADDR_V7M_SCB + V7M_SCB_CTR);
93}
94
95static inline unsigned int read_ccsidr(void)
96{
97	return readl(BASEADDR_V7M_SCB + V7M_SCB_CCSIDR);
98}
99#endif
100
101#endif
102