xref: /rk3399_ARM-atf/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c (revision 3546afffa6d7dd595be3d4fd6ff4100bfb637854)
1f25ea7e3Skenny liang /*
2f25ea7e3Skenny liang  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
3f25ea7e3Skenny liang  *
4f25ea7e3Skenny liang  * SPDX-License-Identifier: BSD-3-Clause
5f25ea7e3Skenny liang  */
6f25ea7e3Skenny liang 
7f25ea7e3Skenny liang #include <common/debug.h>
8f25ea7e3Skenny liang #include <lib/mmio.h>
9f25ea7e3Skenny liang #include <emi_mpu.h>
10f25ea7e3Skenny liang 
is_4GB(void)11f25ea7e3Skenny liang int is_4GB(void)
12f25ea7e3Skenny liang {
13f25ea7e3Skenny liang 	return 0; /* 8183 doesn't use 4GB */
14f25ea7e3Skenny liang }
15f25ea7e3Skenny liang 
16f25ea7e3Skenny liang /*
17f25ea7e3Skenny liang  * emi_mpu_set_region_protection: protect a region.
18f25ea7e3Skenny liang  * @start: start address of the region
19f25ea7e3Skenny liang  * @end: end address of the region
20f25ea7e3Skenny liang  * @region: EMI MPU region id
21f25ea7e3Skenny liang  * @access_permission: EMI MPU access permission
22f25ea7e3Skenny liang  * Return 0 for success, otherwise negative status code.
23f25ea7e3Skenny liang  */
emi_mpu_set_region_protection(unsigned long start,unsigned long end,int region,unsigned int access_permission)24f25ea7e3Skenny liang int emi_mpu_set_region_protection(
25f25ea7e3Skenny liang 	unsigned long start, unsigned long end,
26f25ea7e3Skenny liang 	int region,
27f25ea7e3Skenny liang 	unsigned int access_permission)
28f25ea7e3Skenny liang {
29f25ea7e3Skenny liang 	int ret = 0;
30f25ea7e3Skenny liang 
31f25ea7e3Skenny liang 	if (end <= start) {
32f25ea7e3Skenny liang 		ERROR("[EMI][MTEE][MPU] Invalid address!.\n");
33f25ea7e3Skenny liang 		return -1;
34f25ea7e3Skenny liang 	}
35f25ea7e3Skenny liang 
36f25ea7e3Skenny liang 	if (is_4GB()) {
37f25ea7e3Skenny liang 		/* 4GB mode: emi_addr = phy_addr & 0xffff */
38f25ea7e3Skenny liang 		start = EMI_PHY_OFFSET & 0xffff;
39f25ea7e3Skenny liang 		end = EMI_PHY_OFFSET & 0xffff;
40f25ea7e3Skenny liang 	} else {
41f25ea7e3Skenny liang 		/* non-4GB mode: emi_addr = phy_addr - MEM_OFFSET */
42f25ea7e3Skenny liang 		start = start - EMI_PHY_OFFSET;
43f25ea7e3Skenny liang 		end = end - EMI_PHY_OFFSET;
44f25ea7e3Skenny liang 	}
45f25ea7e3Skenny liang 
46f25ea7e3Skenny liang 	/*Address 64KB alignment*/
47f25ea7e3Skenny liang 	start = start >> 16;
48f25ea7e3Skenny liang 	end = end >> 16;
49f25ea7e3Skenny liang 
50f25ea7e3Skenny liang 	switch (region) {
51f25ea7e3Skenny liang 	case 0:
52f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC0, 0);
53f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA0, start);
54f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA0, end);
55f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC0, access_permission);
56f25ea7e3Skenny liang 		break;
57f25ea7e3Skenny liang 
58f25ea7e3Skenny liang 	case 1:
59f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC1, 0);
60f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA1, start);
61f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA1, end);
62f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC1, access_permission);
63f25ea7e3Skenny liang 		break;
64f25ea7e3Skenny liang 
65f25ea7e3Skenny liang 	case 2:
66f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC2, 0);
67f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA2, start);
68f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA2, end);
69f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC2, access_permission);
70f25ea7e3Skenny liang 		break;
71f25ea7e3Skenny liang 
72f25ea7e3Skenny liang 	case 3:
73f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC3, 0);
74f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA3, start);
75f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA3, end);
76f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC3, access_permission);
77f25ea7e3Skenny liang 		break;
78f25ea7e3Skenny liang 
79f25ea7e3Skenny liang 	case 4:
80f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC4, 0);
81f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA4, start);
82f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA4, end);
83f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC4, access_permission);
84f25ea7e3Skenny liang 		break;
85f25ea7e3Skenny liang 
86f25ea7e3Skenny liang 	case 5:
87f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC5, 0);
88f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA5, start);
89f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA5, end);
90f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC5, access_permission);
91f25ea7e3Skenny liang 		break;
92f25ea7e3Skenny liang 
93f25ea7e3Skenny liang 	case 6:
94f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC6, 0);
95f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA6, start);
96f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA6, end);
97f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC6, access_permission);
98f25ea7e3Skenny liang 		break;
99f25ea7e3Skenny liang 
100f25ea7e3Skenny liang 	case 7:
101f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC7, 0);
102f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_SA7, start);
103f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_EA7, end);
104f25ea7e3Skenny liang 		mmio_write_32(EMI_MPU_APC7, access_permission);
105f25ea7e3Skenny liang 		break;
106f25ea7e3Skenny liang 
107f25ea7e3Skenny liang 	default:
108f25ea7e3Skenny liang 		ret = -1;
109f25ea7e3Skenny liang 		break;
110f25ea7e3Skenny liang 	}
111f25ea7e3Skenny liang 
112f25ea7e3Skenny liang 	return ret;
113f25ea7e3Skenny liang }
114f25ea7e3Skenny liang 
dump_emi_mpu_regions(void)115f25ea7e3Skenny liang void dump_emi_mpu_regions(void)
116f25ea7e3Skenny liang {
117f25ea7e3Skenny liang 	unsigned int apc, sa, ea;
118f25ea7e3Skenny liang 	unsigned int apc_addr = EMI_MPU_APC0;
119f25ea7e3Skenny liang 	unsigned int sa_addr = EMI_MPU_SA0;
120f25ea7e3Skenny liang 	unsigned int ea_addr = EMI_MPU_EA0;
121f25ea7e3Skenny liang 	int i;
122f25ea7e3Skenny liang 
123f25ea7e3Skenny liang 	for (i = 0; i < 8; ++i) {
124f25ea7e3Skenny liang 		apc = mmio_read_32(apc_addr + i * 4);
125f25ea7e3Skenny liang 		sa = mmio_read_32(sa_addr + i * 4);
126f25ea7e3Skenny liang 		ea = mmio_read_32(ea_addr + i * 4);
127f25ea7e3Skenny liang 		WARN("region %d:\n", i);
128f25ea7e3Skenny liang 		WARN("\tapc:0x%x, sa:0x%x, ea:0x%x\n", apc, sa, ea);
129f25ea7e3Skenny liang 	}
130f25ea7e3Skenny liang }
131f25ea7e3Skenny liang 
emi_mpu_init(void)132f25ea7e3Skenny liang void emi_mpu_init(void)
133f25ea7e3Skenny liang {
134f25ea7e3Skenny liang 	/* Set permission */
135f25ea7e3Skenny liang 	emi_mpu_set_region_protection(0x40000000UL, 0x4FFFFFFFUL, 0,
136f25ea7e3Skenny liang 				(FORBIDDEN << 3 | FORBIDDEN << 6));
137f25ea7e3Skenny liang 	emi_mpu_set_region_protection(0x50000000UL, 0x528FFFFFUL, 1,
138f25ea7e3Skenny liang 				(FORBIDDEN << 6));
139f25ea7e3Skenny liang 	emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2,
140f25ea7e3Skenny liang 				(FORBIDDEN << 3 | FORBIDDEN << 6));
141*95d3c46aSXi Chen 	emi_mpu_set_region_protection(0x60000000UL, 0xFFFFFFFFUL, 3,
142f25ea7e3Skenny liang 				(FORBIDDEN << 3 | FORBIDDEN << 6));
143*95d3c46aSXi Chen 	emi_mpu_set_region_protection(0x100000000UL, 0x23FFFFFFFUL, 4,
144f25ea7e3Skenny liang 				(FORBIDDEN << 3 | FORBIDDEN << 6));
145f25ea7e3Skenny liang 	dump_emi_mpu_regions();
146f25ea7e3Skenny liang }
147f25ea7e3Skenny liang 
148