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 
77 const struct csu_config csu_imx6 = { NULL, csu_setting_imx6 };
78 const struct csu_config csu_imx6ul = { &csu_sa_imx6ul, csu_setting_imx6ul };
79 const struct csu_config csu_imx6ull = { NULL, csu_setting_imx6ull };
80 const struct csu_config csu_imx6sl = { NULL, csu_setting_imx6sl };
81 const struct csu_config csu_imx6sx = { NULL, csu_setting_imx6sx };
82 const struct csu_config csu_imx7ds = { NULL, csu_setting_imx7ds };
83 
rngb_configure(vaddr_t csu_base)84 static void rngb_configure(vaddr_t csu_base)
85 {
86 	int csu_index = 0;
87 
88 	if (soc_is_imx6sl() || soc_is_imx6sll())
89 		csu_index = 16;
90 	else if (soc_is_imx6ull())
91 		csu_index = 34;
92 	else
93 		return;
94 
95 	/* Protect RNGB */
96 	io_mask32(csu_base + csu_index * 4, 0x330000, 0xFF0000);
97 }
98 
csu_init(void)99 static TEE_Result csu_init(void)
100 {
101 	vaddr_t csu_base;
102 	vaddr_t offset;
103 	const struct csu_config *csu_config = NULL;
104 	const struct csu_setting *csu_setting = NULL;
105 
106 	csu_base = core_mmu_get_va(CSU_BASE, MEM_AREA_IO_SEC, 1);
107 	if (!csu_base)
108 		panic();
109 
110 	if (soc_is_imx6sx())
111 		csu_config = &csu_imx6sx;
112 	else if (soc_is_imx6ul())
113 		csu_config = &csu_imx6ul;
114 	else if (soc_is_imx6ull())
115 		csu_config = &csu_imx6ull;
116 	else if (soc_is_imx6sll() || soc_is_imx6sl())
117 		csu_config = &csu_imx6sl;
118 	else if (soc_is_imx6())
119 		csu_config = &csu_imx6;
120 	else if (soc_is_imx7ds())
121 		csu_config = &csu_imx7ds;
122 	else
123 		return TEE_SUCCESS;
124 
125 	/* first grant all peripherals */
126 	for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4)
127 		io_write32(csu_base + offset, CSU_ACCESS_ALL);
128 
129 	csu_setting = csu_config->csl;
130 
131 	while (csu_setting->csu_index >= 0) {
132 		io_write32(csu_base + (csu_setting->csu_index * 4),
133 				csu_setting->value);
134 
135 		csu_setting++;
136 	}
137 
138 	if (IS_ENABLED(CFG_IMX_RNGB))
139 		rngb_configure(csu_base);
140 
141 	/* lock the settings */
142 	for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) {
143 		io_write32(csu_base + offset,
144 			io_read32(csu_base + offset) | CSU_SETTING_LOCK);
145 	}
146 
147 	if (csu_config->sa) {
148 		io_write32(csu_base + CSU_SA, csu_config->sa->access_value);
149 		io_setbits32(csu_base + CSU_SA, csu_config->sa->lock_value);
150 	}
151 
152 	return TEE_SUCCESS;
153 }
154 
155 driver_init(csu_init);
156