Lokesh Vutla | 076ee45 | 2018-04-26 18:21:30 +0530 | [diff] [blame] | 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 | |
Simon Glass | 4dcacfc | 2020-05-10 11:40:13 -0600 | [diff] [blame^] | 10 | #ifndef __ASSEMBLY__ |
| 11 | #include <linux/bitops.h> |
| 12 | #endif |
| 13 | |
Lokesh Vutla | 076ee45 | 2018-04-26 18:21:30 +0530 | [diff] [blame] | 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 */ |