xref: /optee_os/core/drivers/imx_csu.c (revision aaba13614eaff9d9a09269652b53b7ee415eff78)
192b64e4fSClement Faure // SPDX-License-Identifier: BSD-2-Clause
292b64e4fSClement Faure /*
3*aaba1361SClement Faure  * Copyright 2017-2023 NXP
492b64e4fSClement Faure  *
592b64e4fSClement Faure  */
692b64e4fSClement Faure 
792b64e4fSClement Faure #include <config.h>
892b64e4fSClement Faure #include <imx.h>
992b64e4fSClement Faure #include <initcall.h>
1092b64e4fSClement Faure #include <io.h>
1192b64e4fSClement Faure #include <kernel/panic.h>
12*aaba1361SClement Faure #include <kernel/pm.h>
1392b64e4fSClement Faure #include <mm/core_memprot.h>
1492b64e4fSClement Faure 
1592b64e4fSClement Faure struct csu_setting {
1692b64e4fSClement Faure 	int csu_index;
1792b64e4fSClement Faure 	uint32_t value;
1892b64e4fSClement Faure };
1992b64e4fSClement Faure 
2092b64e4fSClement Faure const struct csu_setting csu_setting_imx6[] = {
2192b64e4fSClement Faure 	{13, 0xFF0033},		/* Protect ROMCP */
2292b64e4fSClement Faure 	{16, 0x330033},		/* Protect TZASC */
2392b64e4fSClement Faure 	{26, 0xFF0033},		/* Protect OCRAM */
2492b64e4fSClement Faure 	{(-1), 0},
2592b64e4fSClement Faure };
2692b64e4fSClement Faure 
2792b64e4fSClement Faure struct csu_sa_setting {
2892b64e4fSClement Faure 	uint32_t access_value;
2992b64e4fSClement Faure 	uint32_t lock_value;
3092b64e4fSClement Faure };
3192b64e4fSClement Faure 
3292b64e4fSClement Faure struct csu_config {
3392b64e4fSClement Faure 	const struct csu_sa_setting * const sa;
3492b64e4fSClement Faure 	const struct csu_setting * const csl;
3592b64e4fSClement Faure };
3692b64e4fSClement Faure 
3792b64e4fSClement Faure const struct csu_setting csu_setting_imx6ul[] = {
3892b64e4fSClement Faure 	{13, 0xFF0033},		/* Protect ROMCP */
3992b64e4fSClement Faure 	{16, 0x3300FF},		/* Protect TZASC */
4092b64e4fSClement Faure 	{39, 0x3300FF},		/* Protect OCRAM */
4192b64e4fSClement Faure 	{(-1), 0},
4292b64e4fSClement Faure };
4392b64e4fSClement Faure 
4492b64e4fSClement Faure const struct csu_setting csu_setting_imx6ull[] = {
4592b64e4fSClement Faure 	{ 13, 0xFF0033 },	/* Protect ROMCP */
4692b64e4fSClement Faure 	{ 16, 0x3300FF },	/* Protect TZASC */
4792b64e4fSClement Faure 	{ 34, 0xFF0033 },	/* Protect DCP */
4892b64e4fSClement Faure 	{ 39, 0x3300FF },	/* Protect OCRAM */
4992b64e4fSClement Faure 	{ (-1), 0 },
5092b64e4fSClement Faure };
5192b64e4fSClement Faure 
5292b64e4fSClement Faure const struct csu_setting csu_setting_imx6sl[] = {
5392b64e4fSClement Faure 	{ 13, 0x3F0033 },	/* Protect DCP/ROMCP */
5492b64e4fSClement Faure 	{ 16, 0xFF0033 },	/* Protect TZASC */
5592b64e4fSClement Faure 	{ 26, 0xFF0033 },	/* Protect OCRAM */
5692b64e4fSClement Faure 	{ (-1), 0 },
5792b64e4fSClement Faure };
5892b64e4fSClement Faure 
5992b64e4fSClement Faure const struct csu_setting csu_setting_imx6sx[] = {
6092b64e4fSClement Faure 	{13, 0xFF0033},		/* Protect ROMCP */
6192b64e4fSClement Faure 	{15, 0xFF0033},		/* Protect RDC   */
6292b64e4fSClement Faure 	{16, 0x3300FF},		/* Protect TZASC */
6392b64e4fSClement Faure 	{34, 0x3300FF},		/* Protect OCRAM */
6492b64e4fSClement Faure 	{(-1), 0},
6592b64e4fSClement Faure };
6692b64e4fSClement Faure 
6792b64e4fSClement Faure const struct csu_setting csu_setting_imx7ds[] = {
6892b64e4fSClement Faure 	{14, 0x3300FF},		/* Protect RDC     */
6992b64e4fSClement Faure 	{15, 0xFF0033},		/* Protect CSU     */
7092b64e4fSClement Faure 	{28, 0xFF0033},		/* Protect TZASC   */
7192b64e4fSClement Faure 	{59, 0x3300FF},		/* Protect OCRAM_S */
7292b64e4fSClement Faure 	{(-1), 0},
7392b64e4fSClement Faure };
7492b64e4fSClement Faure 
7592b64e4fSClement Faure /* Set all masters to non-secure except the Cortex-A7 */
7692b64e4fSClement Faure const struct csu_sa_setting csu_sa_imx6ul = { 0x10554550, 0x20aa8aa2 };
7792b64e4fSClement Faure const struct csu_sa_setting csu_sa_imx7ds = { 0x15554554, 0x2aaa8aaa };
7892b64e4fSClement Faure 
7992b64e4fSClement Faure const struct csu_config csu_imx6 = { NULL, csu_setting_imx6 };
8092b64e4fSClement Faure const struct csu_config csu_imx6ul = { &csu_sa_imx6ul, csu_setting_imx6ul };
8192b64e4fSClement Faure const struct csu_config csu_imx6ull = { NULL, csu_setting_imx6ull };
8292b64e4fSClement Faure const struct csu_config csu_imx6sl = { NULL, csu_setting_imx6sl };
8392b64e4fSClement Faure const struct csu_config csu_imx6sx = { NULL, csu_setting_imx6sx };
8492b64e4fSClement Faure const struct csu_config csu_imx7ds = { &csu_sa_imx7ds, csu_setting_imx7ds };
8592b64e4fSClement Faure 
8692b64e4fSClement Faure static void rngb_configure(vaddr_t csu_base)
8792b64e4fSClement Faure {
8892b64e4fSClement Faure 	int csu_index = 0;
8992b64e4fSClement Faure 
9092b64e4fSClement Faure 	if (soc_is_imx6sl() || soc_is_imx6sll())
9192b64e4fSClement Faure 		csu_index = 16;
9292b64e4fSClement Faure 	else if (soc_is_imx6ull())
9392b64e4fSClement Faure 		csu_index = 34;
9492b64e4fSClement Faure 	else
9592b64e4fSClement Faure 		return;
9692b64e4fSClement Faure 
9792b64e4fSClement Faure 	/* Protect RNGB */
9892b64e4fSClement Faure 	io_mask32(csu_base + csu_index * 4, 0x330000, 0xFF0000);
9992b64e4fSClement Faure }
10092b64e4fSClement Faure 
101*aaba1361SClement Faure static TEE_Result csu_configure(void)
10292b64e4fSClement Faure {
10392b64e4fSClement Faure 	vaddr_t csu_base;
10492b64e4fSClement Faure 	vaddr_t offset;
10592b64e4fSClement Faure 	const struct csu_config *csu_config = NULL;
10692b64e4fSClement Faure 	const struct csu_setting *csu_setting = NULL;
10792b64e4fSClement Faure 
10892b64e4fSClement Faure 	csu_base = core_mmu_get_va(CSU_BASE, MEM_AREA_IO_SEC, 1);
10992b64e4fSClement Faure 	if (!csu_base)
11092b64e4fSClement Faure 		panic();
11192b64e4fSClement Faure 
11292b64e4fSClement Faure 	if (soc_is_imx6sx())
11392b64e4fSClement Faure 		csu_config = &csu_imx6sx;
11492b64e4fSClement Faure 	else if (soc_is_imx6ul())
11592b64e4fSClement Faure 		csu_config = &csu_imx6ul;
11692b64e4fSClement Faure 	else if (soc_is_imx6ull())
11792b64e4fSClement Faure 		csu_config = &csu_imx6ull;
11892b64e4fSClement Faure 	else if (soc_is_imx6sll() || soc_is_imx6sl())
11992b64e4fSClement Faure 		csu_config = &csu_imx6sl;
12092b64e4fSClement Faure 	else if (soc_is_imx6())
12192b64e4fSClement Faure 		csu_config = &csu_imx6;
12292b64e4fSClement Faure 	else if (soc_is_imx7ds())
12392b64e4fSClement Faure 		csu_config = &csu_imx7ds;
12492b64e4fSClement Faure 	else
12592b64e4fSClement Faure 		return TEE_SUCCESS;
12692b64e4fSClement Faure 
12792b64e4fSClement Faure 	/* first grant all peripherals */
12892b64e4fSClement Faure 	for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4)
12992b64e4fSClement Faure 		io_write32(csu_base + offset, CSU_ACCESS_ALL);
13092b64e4fSClement Faure 
13192b64e4fSClement Faure 	csu_setting = csu_config->csl;
13292b64e4fSClement Faure 
13392b64e4fSClement Faure 	while (csu_setting->csu_index >= 0) {
13492b64e4fSClement Faure 		io_write32(csu_base + (csu_setting->csu_index * 4),
13592b64e4fSClement Faure 				csu_setting->value);
13692b64e4fSClement Faure 
13792b64e4fSClement Faure 		csu_setting++;
13892b64e4fSClement Faure 	}
13992b64e4fSClement Faure 
14092b64e4fSClement Faure 	if (IS_ENABLED(CFG_IMX_RNGB))
14192b64e4fSClement Faure 		rngb_configure(csu_base);
14292b64e4fSClement Faure 
14392b64e4fSClement Faure 	/* lock the settings */
14492b64e4fSClement Faure 	for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) {
14592b64e4fSClement Faure 		io_write32(csu_base + offset,
14692b64e4fSClement Faure 			io_read32(csu_base + offset) | CSU_SETTING_LOCK);
14792b64e4fSClement Faure 	}
14892b64e4fSClement Faure 
14992b64e4fSClement Faure 	if (csu_config->sa) {
15092b64e4fSClement Faure 		io_write32(csu_base + CSU_SA, csu_config->sa->access_value);
15192b64e4fSClement Faure 		io_setbits32(csu_base + CSU_SA, csu_config->sa->lock_value);
15292b64e4fSClement Faure 	}
15392b64e4fSClement Faure 
15492b64e4fSClement Faure 	return TEE_SUCCESS;
15592b64e4fSClement Faure }
15692b64e4fSClement Faure 
157*aaba1361SClement Faure static TEE_Result
158*aaba1361SClement Faure pm_enter_resume(enum pm_op op, uint32_t pm_hint __unused,
159*aaba1361SClement Faure 		const struct pm_callback_handle *pm_handle __unused)
160*aaba1361SClement Faure {
161*aaba1361SClement Faure 	if (op == PM_OP_RESUME)
162*aaba1361SClement Faure 		csu_configure();
163*aaba1361SClement Faure 
164*aaba1361SClement Faure 	return TEE_SUCCESS;
165*aaba1361SClement Faure }
166*aaba1361SClement Faure 
167*aaba1361SClement Faure static TEE_Result csu_init(void)
168*aaba1361SClement Faure {
169*aaba1361SClement Faure 	csu_configure();
170*aaba1361SClement Faure 	register_pm_driver_cb(pm_enter_resume, NULL, "imx-csu");
171*aaba1361SClement Faure 
172*aaba1361SClement Faure 	return TEE_SUCCESS;
173*aaba1361SClement Faure }
174*aaba1361SClement Faure 
17592b64e4fSClement Faure driver_init(csu_init);
176