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