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