1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2019 Pengutronix
4  * All rights reserved.
5  * Copyright 2023 NXP
6  *
7  * Rouven Czerwinski <entwicklung@pengutronix.de>
8  */
9 
10 #include <config.h>
11 #include <drivers/tzc380.h>
12 #include <imx-regs.h>
13 #include <initcall.h>
14 #include <kernel/panic.h>
15 #include <kernel/pm.h>
16 #include <mm/core_memprot.h>
17 #include <mm/generic_ram_layout.h>
18 
19 /*
20  * TZASC2_BASE is asserted non null when used.
21  * This is needed to compile the code for i.MX6UL/L
22  * and i.MX8MQ.
23  */
24 #ifndef TZASC2_BASE
25 #define TZASC2_BASE			0
26 #else
27 register_phys_mem(MEM_AREA_IO_SEC, TZASC2_BASE, TZASC_SIZE);
28 #endif
29 
30 register_phys_mem(MEM_AREA_IO_SEC, TZASC_BASE, TZASC_SIZE);
31 
imx_tzc_auto_configure(vaddr_t addr,vaddr_t rsize,uint32_t attr,uint8_t region)32 static int imx_tzc_auto_configure(vaddr_t addr, vaddr_t rsize, uint32_t attr,
33 				  uint8_t region)
34 {
35 	vaddr_t addr_imx = 0;
36 
37 	/*
38 	 * On 8mscale platforms, the TZASC controller for the DRAM protection,
39 	 * has the memory regions starting at address 0x0 instead of the DRAM
40 	 * base address (0x40000000)
41 	 */
42 	if (IS_ENABLED(CFG_MX8M))
43 		addr_imx = addr - CFG_DRAM_BASE;
44 	else
45 		addr_imx = addr;
46 
47 	return tzc_auto_configure(addr_imx, rsize, attr, region);
48 }
49 
imx_configure_tzasc(void)50 static TEE_Result imx_configure_tzasc(void)
51 {
52 	vaddr_t addr[2] = {0};
53 	int end = 1;
54 	int i = 0;
55 
56 	addr[0] = core_mmu_get_va(TZASC_BASE, MEM_AREA_IO_SEC, 1);
57 
58 	if (IS_ENABLED(CFG_MX6Q) || IS_ENABLED(CFG_MX6D) ||
59 	    IS_ENABLED(CFG_MX6DL)) {
60 		assert(TZASC2_BASE != 0);
61 		addr[1] = core_mmu_get_va(TZASC2_BASE, MEM_AREA_IO_SEC, 1);
62 		end = 2;
63 	}
64 
65 	for (i = 0; i < end; i++) {
66 		uint8_t region = 1;
67 
68 		tzc_init(addr[i]);
69 
70 		region = imx_tzc_auto_configure(CFG_DRAM_BASE, CFG_DDR_SIZE,
71 						TZC_ATTR_SP_NS_RW, region);
72 		region = imx_tzc_auto_configure(CFG_TZDRAM_START,
73 						CFG_TZDRAM_SIZE,
74 						TZC_ATTR_SP_S_RW, region);
75 		region = imx_tzc_auto_configure(CFG_SHMEM_START, CFG_SHMEM_SIZE,
76 						TZC_ATTR_SP_ALL, region);
77 
78 		if (tzc_regions_lockdown() != TEE_SUCCESS)
79 			panic("Region lockdown failed!");
80 
81 		tzc_dump_state();
82 	}
83 	return TEE_SUCCESS;
84 }
85 
86 static TEE_Result
pm_enter_resume(enum pm_op op,uint32_t pm_hint __unused,const struct pm_callback_handle * pm_handle __unused)87 pm_enter_resume(enum pm_op op, uint32_t pm_hint __unused,
88 		const struct pm_callback_handle *pm_handle __unused)
89 {
90 	if (op == PM_OP_RESUME)
91 		return imx_configure_tzasc();
92 
93 	return TEE_SUCCESS;
94 }
95 
tzasc_init(void)96 static TEE_Result tzasc_init(void)
97 {
98 	register_pm_driver_cb(pm_enter_resume, NULL, "imx-tzasc");
99 
100 	return imx_configure_tzasc();
101 }
102 driver_init(tzasc_init);
103