blob: 16b9d0d1aeb3ad8f8146038910ec72e45e9ba820 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
* Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
*/
#ifndef _ASM_ARMV7_MPU_H
#define _ASM_ARMV7_MPU_H
#ifndef __ASSEMBLY__
#include <linux/bitops.h>
#endif
#ifdef CONFIG_CPU_V7M
#define AP_SHIFT 24
#define XN_SHIFT 28
#define TEX_SHIFT 19
#define S_SHIFT 18
#define C_SHIFT 17
#define B_SHIFT 16
#else /* CONFIG_CPU_V7R */
#define XN_SHIFT 12
#define AP_SHIFT 8
#define TEX_SHIFT 3
#define S_SHIFT 2
#define C_SHIFT 1
#define B_SHIFT 0
#endif /* CONFIG_CPU_V7R */
#define CACHEABLE BIT(C_SHIFT)
#define BUFFERABLE BIT(B_SHIFT)
#define SHAREABLE BIT(S_SHIFT)
#define REGION_SIZE_SHIFT 1
#define ENABLE_REGION BIT(0)
#define DISABLE_REGION 0
enum region_number {
REGION_0 = 0,
REGION_1,
REGION_2,
REGION_3,
REGION_4,
REGION_5,
REGION_6,
REGION_7,
};
enum ap {
NO_ACCESS = 0,
PRIV_RW_USR_NO,
PRIV_RW_USR_RO,
PRIV_RW_USR_RW,
UNPREDICTABLE,
PRIV_RO_USR_NO,
PRIV_RO_USR_RO,
};
enum mr_attr {
STRONG_ORDER = 0,
SHARED_WRITE_BUFFERED,
O_I_WT_NO_WR_ALLOC,
O_I_WB_NO_WR_ALLOC,
O_I_NON_CACHEABLE,
O_I_WB_RD_WR_ALLOC,
DEVICE_NON_SHARED,
};
enum size {
REGION_8MB = 22,
REGION_16MB,
REGION_32MB,
REGION_64MB,
REGION_128MB,
REGION_256MB,
REGION_512MB,
REGION_1GB,
REGION_2GB,
REGION_4GB,
};
enum xn {
XN_DIS = 0,
XN_EN,
};
struct mpu_region_config {
uint32_t start_addr;
enum region_number region_no;
enum xn xn;
enum ap ap;
enum mr_attr mr_attr;
enum size reg_size;
};
void disable_mpu(void);
void enable_mpu(void);
int mpu_enabled(void);
void mpu_config(struct mpu_region_config *reg_config);
void setup_mpu_regions(struct mpu_region_config *rgns, u32 num_rgns);
static inline u32 get_attr_encoding(u32 mr_attr)
{
u32 attr;
switch (mr_attr) {
case STRONG_ORDER:
attr = SHAREABLE;
break;
case SHARED_WRITE_BUFFERED:
attr = BUFFERABLE;
break;
case O_I_WT_NO_WR_ALLOC:
attr = CACHEABLE;
break;
case O_I_WB_NO_WR_ALLOC:
attr = CACHEABLE | BUFFERABLE;
break;
case O_I_NON_CACHEABLE:
attr = 1 << TEX_SHIFT;
break;
case O_I_WB_RD_WR_ALLOC:
attr = (1 << TEX_SHIFT) | CACHEABLE | BUFFERABLE;
break;
case DEVICE_NON_SHARED:
attr = (2 << TEX_SHIFT) | BUFFERABLE;
break;
default:
attr = 0; /* strongly ordered */
break;
};
return attr;
}
#endif /* _ASM_ARMV7_MPU_H */