196b61ab1SVikas Manocha /* 296b61ab1SVikas Manocha * (C) Copyright 2017 396b61ab1SVikas Manocha * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. 496b61ab1SVikas Manocha * 596b61ab1SVikas Manocha * SPDX-License-Identifier: GPL-2.0+ 696b61ab1SVikas Manocha */ 796b61ab1SVikas Manocha 896b61ab1SVikas Manocha #include <linux/bitops.h> 996b61ab1SVikas Manocha #include <asm/armv7m.h> 1096b61ab1SVikas Manocha #include <asm/armv7m_mpu.h> 1196b61ab1SVikas Manocha #include <asm/io.h> 1296b61ab1SVikas Manocha 1396b61ab1SVikas Manocha #define V7M_MPU_CTRL_ENABLE (1 << 0) 1496b61ab1SVikas Manocha #define V7M_MPU_CTRL_DISABLE (0 << 0) 1596b61ab1SVikas Manocha #define V7M_MPU_CTRL_HFNMIENA (1 << 1) 1696b61ab1SVikas Manocha #define VALID_REGION (1 << 4) 1796b61ab1SVikas Manocha 1896b61ab1SVikas Manocha #define ENABLE_REGION (1 << 0) 1996b61ab1SVikas Manocha 2096b61ab1SVikas Manocha #define AP_SHIFT 24 2196b61ab1SVikas Manocha #define XN_SHIFT 28 2296b61ab1SVikas Manocha #define TEX_SHIFT 19 2396b61ab1SVikas Manocha #define S_SHIFT 18 2496b61ab1SVikas Manocha #define C_SHIFT 17 2596b61ab1SVikas Manocha #define B_SHIFT 16 2696b61ab1SVikas Manocha #define REGION_SIZE_SHIFT 1 2796b61ab1SVikas Manocha 2896b61ab1SVikas Manocha #define CACHEABLE (1 << C_SHIFT) 2996b61ab1SVikas Manocha #define BUFFERABLE (1 << B_SHIFT) 3096b61ab1SVikas Manocha #define SHAREABLE (1 << S_SHIFT) 3196b61ab1SVikas Manocha disable_mpu(void)3296b61ab1SVikas Manochavoid disable_mpu(void) 3396b61ab1SVikas Manocha { 3496b61ab1SVikas Manocha writel(0, &V7M_MPU->ctrl); 3596b61ab1SVikas Manocha } 3696b61ab1SVikas Manocha enable_mpu(void)3796b61ab1SVikas Manochavoid enable_mpu(void) 3896b61ab1SVikas Manocha { 3996b61ab1SVikas Manocha writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl); 4096b61ab1SVikas Manocha 4196b61ab1SVikas Manocha /* Make sure new mpu config is effective for next memory access */ 4296b61ab1SVikas Manocha dsb(); 4396b61ab1SVikas Manocha isb(); /* Make sure instruction stream sees it */ 4496b61ab1SVikas Manocha } 4596b61ab1SVikas Manocha mpu_config(struct mpu_region_config * reg_config)4696b61ab1SVikas Manochavoid mpu_config(struct mpu_region_config *reg_config) 4796b61ab1SVikas Manocha { 4896b61ab1SVikas Manocha uint32_t attr; 4996b61ab1SVikas Manocha 5096b61ab1SVikas Manocha switch (reg_config->mr_attr) { 5196b61ab1SVikas Manocha case STRONG_ORDER: 5296b61ab1SVikas Manocha attr = SHAREABLE; 5396b61ab1SVikas Manocha break; 5496b61ab1SVikas Manocha case SHARED_WRITE_BUFFERED: 5596b61ab1SVikas Manocha attr = BUFFERABLE; 5696b61ab1SVikas Manocha break; 5796b61ab1SVikas Manocha case O_I_WT_NO_WR_ALLOC: 5896b61ab1SVikas Manocha attr = CACHEABLE; 5996b61ab1SVikas Manocha break; 6096b61ab1SVikas Manocha case O_I_WB_NO_WR_ALLOC: 6196b61ab1SVikas Manocha attr = CACHEABLE | BUFFERABLE; 6296b61ab1SVikas Manocha break; 6396b61ab1SVikas Manocha case O_I_NON_CACHEABLE: 6496b61ab1SVikas Manocha attr = 1 << TEX_SHIFT; 6596b61ab1SVikas Manocha break; 6696b61ab1SVikas Manocha case O_I_WB_RD_WR_ALLOC: 6796b61ab1SVikas Manocha attr = (1 << TEX_SHIFT) | CACHEABLE | BUFFERABLE; 6896b61ab1SVikas Manocha break; 6996b61ab1SVikas Manocha case DEVICE_NON_SHARED: 7096b61ab1SVikas Manocha attr = (2 << TEX_SHIFT) | BUFFERABLE; 71*a5981734Sxypron.glpk@gmx.de break; 7296b61ab1SVikas Manocha default: 7396b61ab1SVikas Manocha attr = 0; /* strongly ordered */ 7496b61ab1SVikas Manocha break; 7596b61ab1SVikas Manocha }; 7696b61ab1SVikas Manocha 7796b61ab1SVikas Manocha writel(reg_config->start_addr | VALID_REGION | reg_config->region_no, 7896b61ab1SVikas Manocha &V7M_MPU->rbar); 7996b61ab1SVikas Manocha 8096b61ab1SVikas Manocha writel(reg_config->xn << XN_SHIFT | reg_config->ap << AP_SHIFT | attr 8196b61ab1SVikas Manocha | reg_config->reg_size << REGION_SIZE_SHIFT | ENABLE_REGION 8296b61ab1SVikas Manocha , &V7M_MPU->rasr); 8396b61ab1SVikas Manocha } 84