xref: /rk3399_ARM-atf/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c (revision 3eb25ebeb301fdca0e6ceb57060ffceb0886187e)
142f2fa82SXi Chen /*
242f2fa82SXi Chen  * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
342f2fa82SXi Chen  *
442f2fa82SXi Chen  * SPDX-License-Identifier: BSD-3-Clause
542f2fa82SXi Chen  */
642f2fa82SXi Chen 
742f2fa82SXi Chen #include <common/debug.h>
842f2fa82SXi Chen #include <emi_mpu.h>
942f2fa82SXi Chen #include <lib/mmio.h>
1042f2fa82SXi Chen 
1142f2fa82SXi Chen /*
1242f2fa82SXi Chen  * emi_mpu_set_region_protection: protect a region.
1342f2fa82SXi Chen  * @start: start address of the region
1442f2fa82SXi Chen  * @end: end address of the region
1542f2fa82SXi Chen  * @access_permission: EMI MPU access permission
1642f2fa82SXi Chen  * Return 0 for success, otherwise negative status code.
1742f2fa82SXi Chen  */
_emi_mpu_set_protection(unsigned long start,unsigned long end,unsigned int apc)1842f2fa82SXi Chen static int _emi_mpu_set_protection(
1942f2fa82SXi Chen 	unsigned long start, unsigned long end,
2042f2fa82SXi Chen 	unsigned int apc)
2142f2fa82SXi Chen {
2242f2fa82SXi Chen 	unsigned int dgroup;
2342f2fa82SXi Chen 	unsigned int region;
2442f2fa82SXi Chen 
2542f2fa82SXi Chen 	region = (start >> 24) & 0xFF;
2642f2fa82SXi Chen 	start &= 0x00FFFFFF;
2742f2fa82SXi Chen 	dgroup = (end >> 24) & 0xFF;
2842f2fa82SXi Chen 	end &= 0x00FFFFFF;
2942f2fa82SXi Chen 
3042f2fa82SXi Chen 	if  ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) {
3142f2fa82SXi Chen 		WARN("Region:%u or dgroup:%u is wrong!\n", region, dgroup);
3242f2fa82SXi Chen 		return -1;
3342f2fa82SXi Chen 	}
3442f2fa82SXi Chen 
3542f2fa82SXi Chen 	apc &= 0x80FFFFFF;
3642f2fa82SXi Chen 
3742f2fa82SXi Chen 	if ((start >= DRAM_OFFSET) && (end >= start)) {
3842f2fa82SXi Chen 		start -= DRAM_OFFSET;
3942f2fa82SXi Chen 		end -= DRAM_OFFSET;
4042f2fa82SXi Chen 	} else {
4142f2fa82SXi Chen 		WARN("start:0x%lx or end:0x%lx address is wrong!\n",
4242f2fa82SXi Chen 		     start, end);
4342f2fa82SXi Chen 		return -2;
4442f2fa82SXi Chen 	}
4542f2fa82SXi Chen 
4642f2fa82SXi Chen 	mmio_write_32(EMI_MPU_SA(region), start);
4742f2fa82SXi Chen 	mmio_write_32(EMI_MPU_EA(region), end);
4842f2fa82SXi Chen 	mmio_write_32(EMI_MPU_APC(region, dgroup), apc);
4942f2fa82SXi Chen 
5042f2fa82SXi Chen 	return 0;
5142f2fa82SXi Chen }
5242f2fa82SXi Chen 
dump_emi_mpu_regions(void)5342f2fa82SXi Chen void dump_emi_mpu_regions(void)
5442f2fa82SXi Chen {
5542f2fa82SXi Chen 	unsigned long apc[EMI_MPU_DGROUP_NUM], sa, ea;
5642f2fa82SXi Chen 
5742f2fa82SXi Chen 	int region, i;
5842f2fa82SXi Chen 
5942f2fa82SXi Chen 	/* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */
6042f2fa82SXi Chen 	for (region = 0; region < 8; ++region) {
6142f2fa82SXi Chen 		for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i)
6242f2fa82SXi Chen 			apc[i] = mmio_read_32(EMI_MPU_APC(region, i));
6342f2fa82SXi Chen 		sa = mmio_read_32(EMI_MPU_SA(region));
6442f2fa82SXi Chen 		ea = mmio_read_32(EMI_MPU_EA(region));
6542f2fa82SXi Chen 
6642f2fa82SXi Chen 		WARN("region %d:\n", region);
6742f2fa82SXi Chen 		WARN("\tsa:0x%lx, ea:0x%lx, apc0: 0x%lx apc1: 0x%lx\n",
6842f2fa82SXi Chen 		     sa, ea, apc[0], apc[1]);
6942f2fa82SXi Chen 	}
7042f2fa82SXi Chen }
7142f2fa82SXi Chen 
emi_mpu_set_protection(struct emi_region_info_t * region_info)7242f2fa82SXi Chen int emi_mpu_set_protection(struct emi_region_info_t *region_info)
7342f2fa82SXi Chen {
7442f2fa82SXi Chen 	unsigned long start, end;
7542f2fa82SXi Chen 	int i;
7642f2fa82SXi Chen 
7742f2fa82SXi Chen 	if (region_info->region >= EMI_MPU_REGION_NUM)
7842f2fa82SXi Chen 		return -1;
7942f2fa82SXi Chen 
8042f2fa82SXi Chen 	start = (unsigned long)(region_info->start >> EMI_MPU_ALIGN_BITS) |
8142f2fa82SXi Chen 		(region_info->region << 24);
8242f2fa82SXi Chen 
8342f2fa82SXi Chen 	for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) {
8442f2fa82SXi Chen 		end = (unsigned long)(region_info->end >> EMI_MPU_ALIGN_BITS) |
8542f2fa82SXi Chen 			(i << 24);
8642f2fa82SXi Chen 		_emi_mpu_set_protection(start, end, region_info->apc[i]);
8742f2fa82SXi Chen 	}
8842f2fa82SXi Chen 
8942f2fa82SXi Chen 	return 0;
9042f2fa82SXi Chen }
9142f2fa82SXi Chen 
emi_mpu_init(void)9242f2fa82SXi Chen void emi_mpu_init(void)
9342f2fa82SXi Chen {
9442f2fa82SXi Chen 	struct emi_region_info_t region_info;
9542f2fa82SXi Chen 
96a564bdc5SXi Chen 	/* reserve region 0 for future use */
97a564bdc5SXi Chen 
98a564bdc5SXi Chen 	/* PCI-e protect address(64MB) */
99a564bdc5SXi Chen 	region_info.start = 0xC0000000ULL;
100*7587cfddSkiwi liu 	region_info.end = 0xC3FFFFFFULL;
10142f2fa82SXi Chen 	region_info.region = 1;
10242f2fa82SXi Chen 	SET_ACCESS_PERMISSION(region_info.apc, 1,
10342f2fa82SXi Chen 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
10442f2fa82SXi Chen 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
10542f2fa82SXi Chen 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
106a564bdc5SXi Chen 			      FORBIDDEN, FORBIDDEN, NO_PROT, NO_PROT);
107a564bdc5SXi Chen 	emi_mpu_set_protection(&region_info);
108a564bdc5SXi Chen 
109a564bdc5SXi Chen 	/* SCP protect address */
110a564bdc5SXi Chen 	region_info.start = 0x50000000ULL;
111*7587cfddSkiwi liu 	region_info.end = 0x513FFFFFULL;
112a564bdc5SXi Chen 	region_info.region = 2;
113a564bdc5SXi Chen 	SET_ACCESS_PERMISSION(region_info.apc, 1,
114a564bdc5SXi Chen 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
115a564bdc5SXi Chen 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
116a564bdc5SXi Chen 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
117a564bdc5SXi Chen 			      NO_PROT, FORBIDDEN, FORBIDDEN, NO_PROT);
11842f2fa82SXi Chen 	emi_mpu_set_protection(&region_info);
11942f2fa82SXi Chen 
1206c4973b0SJiaxin Yu 	/* Forbidden All */
1216c4973b0SJiaxin Yu 	region_info.start = 0x40000000ULL;	/* dram base addr */
122*7587cfddSkiwi liu 	region_info.end = 0x1FFFFFFFFULL;
123*7587cfddSkiwi liu 	region_info.region = 3;
1246c4973b0SJiaxin Yu 	SET_ACCESS_PERMISSION(region_info.apc, 1,
1256c4973b0SJiaxin Yu 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1266c4973b0SJiaxin Yu 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1276c4973b0SJiaxin Yu 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1286c4973b0SJiaxin Yu 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
1296c4973b0SJiaxin Yu 	emi_mpu_set_protection(&region_info);
1306c4973b0SJiaxin Yu 
13142f2fa82SXi Chen 	dump_emi_mpu_regions();
13242f2fa82SXi Chen }
13342f2fa82SXi Chen 
134