Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[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 #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
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 */