1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
4 * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
5 */
6
7 #ifndef _ASM_ARMV7_MPU_H
8 #define _ASM_ARMV7_MPU_H
9
10 #ifndef __ASSEMBLY__
11 #include <linux/bitops.h>
12 #endif
13
14 #ifdef CONFIG_CPU_V7M
15 #define AP_SHIFT 24
16 #define XN_SHIFT 28
17 #define TEX_SHIFT 19
18 #define S_SHIFT 18
19 #define C_SHIFT 17
20 #define B_SHIFT 16
21 #else /* CONFIG_CPU_V7R */
22 #define XN_SHIFT 12
23 #define AP_SHIFT 8
24 #define TEX_SHIFT 3
25 #define S_SHIFT 2
26 #define C_SHIFT 1
27 #define B_SHIFT 0
28 #endif /* CONFIG_CPU_V7R */
29
30 #define CACHEABLE BIT(C_SHIFT)
31 #define BUFFERABLE BIT(B_SHIFT)
32 #define SHAREABLE BIT(S_SHIFT)
33 #define REGION_SIZE_SHIFT 1
34 #define ENABLE_REGION BIT(0)
35 #define DISABLE_REGION 0
36
37 enum region_number {
38 REGION_0 = 0,
39 REGION_1,
40 REGION_2,
41 REGION_3,
42 REGION_4,
43 REGION_5,
44 REGION_6,
45 REGION_7,
46 };
47
48 enum ap {
49 NO_ACCESS = 0,
50 PRIV_RW_USR_NO,
51 PRIV_RW_USR_RO,
52 PRIV_RW_USR_RW,
53 UNPREDICTABLE,
54 PRIV_RO_USR_NO,
55 PRIV_RO_USR_RO,
56 };
57
58 enum mr_attr {
59 STRONG_ORDER = 0,
60 SHARED_WRITE_BUFFERED,
61 O_I_WT_NO_WR_ALLOC,
62 O_I_WB_NO_WR_ALLOC,
63 O_I_NON_CACHEABLE,
64 O_I_WB_RD_WR_ALLOC,
65 DEVICE_NON_SHARED,
66 };
67 enum size {
68 REGION_8MB = 22,
69 REGION_16MB,
70 REGION_32MB,
71 REGION_64MB,
72 REGION_128MB,
73 REGION_256MB,
74 REGION_512MB,
75 REGION_1GB,
76 REGION_2GB,
77 REGION_4GB,
78 };
79
80 enum xn {
81 XN_DIS = 0,
82 XN_EN,
83 };
84
85 struct mpu_region_config {
86 uint32_t start_addr;
87 enum region_number region_no;
88 enum xn xn;
89 enum ap ap;
90 enum mr_attr mr_attr;
91 enum size reg_size;
92 };
93
94 void disable_mpu(void);
95 void enable_mpu(void);
96 int mpu_enabled(void);
97 void mpu_config(struct mpu_region_config *reg_config);
98 void setup_mpu_regions(struct mpu_region_config *rgns, u32 num_rgns);
99
get_attr_encoding(u32 mr_attr)100 static inline u32 get_attr_encoding(u32 mr_attr)
101 {
102 u32 attr;
103
104 switch (mr_attr) {
105 case STRONG_ORDER:
106 attr = SHAREABLE;
107 break;
108 case SHARED_WRITE_BUFFERED:
109 attr = BUFFERABLE;
110 break;
111 case O_I_WT_NO_WR_ALLOC:
112 attr = CACHEABLE;
113 break;
114 case O_I_WB_NO_WR_ALLOC:
115 attr = CACHEABLE | BUFFERABLE;
116 break;
117 case O_I_NON_CACHEABLE:
118 attr = 1 << TEX_SHIFT;
119 break;
120 case O_I_WB_RD_WR_ALLOC:
121 attr = (1 << TEX_SHIFT) | CACHEABLE | BUFFERABLE;
122 break;
123 case DEVICE_NON_SHARED:
124 attr = (2 << TEX_SHIFT) | BUFFERABLE;
125 break;
126 default:
127 attr = 0; /* strongly ordered */
128 break;
129 };
130
131 return attr;
132 }
133
134 #endif /* _ASM_ARMV7_MPU_H */
135