1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2017-2023 NXP
4 *
5 */
6
7 #include <config.h>
8 #include <imx.h>
9 #include <initcall.h>
10 #include <io.h>
11 #include <kernel/panic.h>
12 #include <kernel/pm.h>
13 #include <mm/core_memprot.h>
14
15 struct csu_setting {
16 int csu_index;
17 uint32_t value;
18 };
19
20 const struct csu_setting csu_setting_imx6[] = {
21 {13, 0xFF0033}, /* Protect ROMCP */
22 {16, 0x330033}, /* Protect TZASC */
23 {26, 0xFF0033}, /* Protect OCRAM */
24 {(-1), 0},
25 };
26
27 struct csu_sa_setting {
28 uint32_t access_value;
29 uint32_t lock_value;
30 };
31
32 struct csu_config {
33 const struct csu_sa_setting * const sa;
34 const struct csu_setting * const csl;
35 };
36
37 const struct csu_setting csu_setting_imx6ul[] = {
38 {13, 0xFF0033}, /* Protect ROMCP */
39 {16, 0x3300FF}, /* Protect TZASC */
40 {39, 0x3300FF}, /* Protect OCRAM */
41 {(-1), 0},
42 };
43
44 const struct csu_setting csu_setting_imx6ull[] = {
45 { 13, 0xFF0033 }, /* Protect ROMCP */
46 { 16, 0x3300FF }, /* Protect TZASC */
47 { 34, 0xFF0033 }, /* Protect DCP */
48 { 39, 0x3300FF }, /* Protect OCRAM */
49 { (-1), 0 },
50 };
51
52 const struct csu_setting csu_setting_imx6sl[] = {
53 { 13, 0x3F0033 }, /* Protect DCP/ROMCP */
54 { 16, 0xFF0033 }, /* Protect TZASC */
55 { 26, 0xFF0033 }, /* Protect OCRAM */
56 { (-1), 0 },
57 };
58
59 const struct csu_setting csu_setting_imx6sx[] = {
60 {13, 0xFF0033}, /* Protect ROMCP */
61 {15, 0xFF0033}, /* Protect RDC */
62 {16, 0x3300FF}, /* Protect TZASC */
63 {34, 0x3300FF}, /* Protect OCRAM */
64 {(-1), 0},
65 };
66
67 const struct csu_setting csu_setting_imx7ds[] = {
68 {14, 0x3300FF}, /* Protect RDC */
69 {15, 0xFF0033}, /* Protect CSU */
70 {28, 0xFF0033}, /* Protect TZASC */
71 {59, 0x3300FF}, /* Protect OCRAM_S */
72 {(-1), 0},
73 };
74
75 /* Set all masters to non-secure except the Cortex-A cores */
76 const struct csu_sa_setting csu_sa_imx6 = { 0x15554554, 0x2aaa8aaa };
77 const struct csu_sa_setting csu_sa_imx6ul = { 0x10554550, 0x20aa8aa2 };
78 const struct csu_sa_setting csu_sa_imx7ds = { 0x15554554, 0x2aaa8aaa };
79
80 const struct csu_config csu_imx6 = { &csu_sa_imx6, csu_setting_imx6 };
81 const struct csu_config csu_imx6ul = { &csu_sa_imx6ul, csu_setting_imx6ul };
82 const struct csu_config csu_imx6ull = { NULL, csu_setting_imx6ull };
83 const struct csu_config csu_imx6sl = { NULL, csu_setting_imx6sl };
84 const struct csu_config csu_imx6sx = { NULL, csu_setting_imx6sx };
85 const struct csu_config csu_imx7ds = { &csu_sa_imx7ds, csu_setting_imx7ds };
86
rngb_configure(vaddr_t csu_base)87 static void rngb_configure(vaddr_t csu_base)
88 {
89 int csu_index = 0;
90
91 if (soc_is_imx6sl() || soc_is_imx6sll())
92 csu_index = 16;
93 else if (soc_is_imx6ull())
94 csu_index = 34;
95 else
96 return;
97
98 /* Protect RNGB */
99 io_mask32(csu_base + csu_index * 4, 0x330000, 0xFF0000);
100 }
101
csu_configure(void)102 static TEE_Result csu_configure(void)
103 {
104 vaddr_t csu_base;
105 vaddr_t offset;
106 const struct csu_config *csu_config = NULL;
107 const struct csu_setting *csu_setting = NULL;
108
109 csu_base = core_mmu_get_va(CSU_BASE, MEM_AREA_IO_SEC, 1);
110 if (!csu_base)
111 panic();
112
113 if (soc_is_imx6sx())
114 csu_config = &csu_imx6sx;
115 else if (soc_is_imx6ul())
116 csu_config = &csu_imx6ul;
117 else if (soc_is_imx6ull())
118 csu_config = &csu_imx6ull;
119 else if (soc_is_imx6sll() || soc_is_imx6sl())
120 csu_config = &csu_imx6sl;
121 else if (soc_is_imx6())
122 csu_config = &csu_imx6;
123 else if (soc_is_imx7ds())
124 csu_config = &csu_imx7ds;
125 else
126 return TEE_SUCCESS;
127
128 /* first grant all peripherals */
129 for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4)
130 io_write32(csu_base + offset, CSU_ACCESS_ALL);
131
132 csu_setting = csu_config->csl;
133
134 while (csu_setting->csu_index >= 0) {
135 io_write32(csu_base + (csu_setting->csu_index * 4),
136 csu_setting->value);
137
138 csu_setting++;
139 }
140
141 if (IS_ENABLED(CFG_IMX_RNGB))
142 rngb_configure(csu_base);
143
144 /* lock the settings */
145 for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) {
146 io_write32(csu_base + offset,
147 io_read32(csu_base + offset) | CSU_SETTING_LOCK);
148 }
149
150 if (csu_config->sa) {
151 io_write32(csu_base + CSU_SA, csu_config->sa->access_value);
152 io_setbits32(csu_base + CSU_SA, csu_config->sa->lock_value);
153 }
154
155 return TEE_SUCCESS;
156 }
157
158 static TEE_Result
pm_enter_resume(enum pm_op op,uint32_t pm_hint __unused,const struct pm_callback_handle * pm_handle __unused)159 pm_enter_resume(enum pm_op op, uint32_t pm_hint __unused,
160 const struct pm_callback_handle *pm_handle __unused)
161 {
162 if (op == PM_OP_RESUME)
163 csu_configure();
164
165 return TEE_SUCCESS;
166 }
167
csu_init(void)168 static TEE_Result csu_init(void)
169 {
170 csu_configure();
171 register_pm_driver_cb(pm_enter_resume, NULL, "imx-csu");
172
173 return TEE_SUCCESS;
174 }
175
176 driver_init(csu_init);
177