xref: /optee_os/core/drivers/imx_csu.c (revision 9b2c7a624ab7dfc92f8bc573adeb2d979ac84837)
192b64e4fSClement Faure // SPDX-License-Identifier: BSD-2-Clause
292b64e4fSClement Faure /*
3aaba1361SClement 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>
12aaba1361SClement 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 
75*9b2c7a62SRouven Czerwinski /* Set all masters to non-secure except the Cortex-A cores */
76*9b2c7a62SRouven Czerwinski const struct csu_sa_setting csu_sa_imx6 = { 0x15554554, 0x2aaa8aaa };
7792b64e4fSClement Faure const struct csu_sa_setting csu_sa_imx6ul = { 0x10554550, 0x20aa8aa2 };
7892b64e4fSClement Faure const struct csu_sa_setting csu_sa_imx7ds = { 0x15554554, 0x2aaa8aaa };
7992b64e4fSClement Faure 
80*9b2c7a62SRouven Czerwinski const struct csu_config csu_imx6 = { &csu_sa_imx6, csu_setting_imx6 };
8192b64e4fSClement Faure const struct csu_config csu_imx6ul = { &csu_sa_imx6ul, csu_setting_imx6ul };
8292b64e4fSClement Faure const struct csu_config csu_imx6ull = { NULL, csu_setting_imx6ull };
8392b64e4fSClement Faure const struct csu_config csu_imx6sl = { NULL, csu_setting_imx6sl };
8492b64e4fSClement Faure const struct csu_config csu_imx6sx = { NULL, csu_setting_imx6sx };
8592b64e4fSClement Faure const struct csu_config csu_imx7ds = { &csu_sa_imx7ds, csu_setting_imx7ds };
8692b64e4fSClement Faure 
8792b64e4fSClement Faure static void rngb_configure(vaddr_t csu_base)
8892b64e4fSClement Faure {
8992b64e4fSClement Faure 	int csu_index = 0;
9092b64e4fSClement Faure 
9192b64e4fSClement Faure 	if (soc_is_imx6sl() || soc_is_imx6sll())
9292b64e4fSClement Faure 		csu_index = 16;
9392b64e4fSClement Faure 	else if (soc_is_imx6ull())
9492b64e4fSClement Faure 		csu_index = 34;
9592b64e4fSClement Faure 	else
9692b64e4fSClement Faure 		return;
9792b64e4fSClement Faure 
9892b64e4fSClement Faure 	/* Protect RNGB */
9992b64e4fSClement Faure 	io_mask32(csu_base + csu_index * 4, 0x330000, 0xFF0000);
10092b64e4fSClement Faure }
10192b64e4fSClement Faure 
102aaba1361SClement Faure static TEE_Result csu_configure(void)
10392b64e4fSClement Faure {
10492b64e4fSClement Faure 	vaddr_t csu_base;
10592b64e4fSClement Faure 	vaddr_t offset;
10692b64e4fSClement Faure 	const struct csu_config *csu_config = NULL;
10792b64e4fSClement Faure 	const struct csu_setting *csu_setting = NULL;
10892b64e4fSClement Faure 
10992b64e4fSClement Faure 	csu_base = core_mmu_get_va(CSU_BASE, MEM_AREA_IO_SEC, 1);
11092b64e4fSClement Faure 	if (!csu_base)
11192b64e4fSClement Faure 		panic();
11292b64e4fSClement Faure 
11392b64e4fSClement Faure 	if (soc_is_imx6sx())
11492b64e4fSClement Faure 		csu_config = &csu_imx6sx;
11592b64e4fSClement Faure 	else if (soc_is_imx6ul())
11692b64e4fSClement Faure 		csu_config = &csu_imx6ul;
11792b64e4fSClement Faure 	else if (soc_is_imx6ull())
11892b64e4fSClement Faure 		csu_config = &csu_imx6ull;
11992b64e4fSClement Faure 	else if (soc_is_imx6sll() || soc_is_imx6sl())
12092b64e4fSClement Faure 		csu_config = &csu_imx6sl;
12192b64e4fSClement Faure 	else if (soc_is_imx6())
12292b64e4fSClement Faure 		csu_config = &csu_imx6;
12392b64e4fSClement Faure 	else if (soc_is_imx7ds())
12492b64e4fSClement Faure 		csu_config = &csu_imx7ds;
12592b64e4fSClement Faure 	else
12692b64e4fSClement Faure 		return TEE_SUCCESS;
12792b64e4fSClement Faure 
12892b64e4fSClement Faure 	/* first grant all peripherals */
12992b64e4fSClement Faure 	for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4)
13092b64e4fSClement Faure 		io_write32(csu_base + offset, CSU_ACCESS_ALL);
13192b64e4fSClement Faure 
13292b64e4fSClement Faure 	csu_setting = csu_config->csl;
13392b64e4fSClement Faure 
13492b64e4fSClement Faure 	while (csu_setting->csu_index >= 0) {
13592b64e4fSClement Faure 		io_write32(csu_base + (csu_setting->csu_index * 4),
13692b64e4fSClement Faure 				csu_setting->value);
13792b64e4fSClement Faure 
13892b64e4fSClement Faure 		csu_setting++;
13992b64e4fSClement Faure 	}
14092b64e4fSClement Faure 
14192b64e4fSClement Faure 	if (IS_ENABLED(CFG_IMX_RNGB))
14292b64e4fSClement Faure 		rngb_configure(csu_base);
14392b64e4fSClement Faure 
14492b64e4fSClement Faure 	/* lock the settings */
14592b64e4fSClement Faure 	for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) {
14692b64e4fSClement Faure 		io_write32(csu_base + offset,
14792b64e4fSClement Faure 			io_read32(csu_base + offset) | CSU_SETTING_LOCK);
14892b64e4fSClement Faure 	}
14992b64e4fSClement Faure 
15092b64e4fSClement Faure 	if (csu_config->sa) {
15192b64e4fSClement Faure 		io_write32(csu_base + CSU_SA, csu_config->sa->access_value);
15292b64e4fSClement Faure 		io_setbits32(csu_base + CSU_SA, csu_config->sa->lock_value);
15392b64e4fSClement Faure 	}
15492b64e4fSClement Faure 
15592b64e4fSClement Faure 	return TEE_SUCCESS;
15692b64e4fSClement Faure }
15792b64e4fSClement Faure 
158aaba1361SClement Faure static TEE_Result
159aaba1361SClement Faure pm_enter_resume(enum pm_op op, uint32_t pm_hint __unused,
160aaba1361SClement Faure 		const struct pm_callback_handle *pm_handle __unused)
161aaba1361SClement Faure {
162aaba1361SClement Faure 	if (op == PM_OP_RESUME)
163aaba1361SClement Faure 		csu_configure();
164aaba1361SClement Faure 
165aaba1361SClement Faure 	return TEE_SUCCESS;
166aaba1361SClement Faure }
167aaba1361SClement Faure 
168aaba1361SClement Faure static TEE_Result csu_init(void)
169aaba1361SClement Faure {
170aaba1361SClement Faure 	csu_configure();
171aaba1361SClement Faure 	register_pm_driver_cb(pm_enter_resume, NULL, "imx-csu");
172aaba1361SClement Faure 
173aaba1361SClement Faure 	return TEE_SUCCESS;
174aaba1361SClement Faure }
175aaba1361SClement Faure 
17692b64e4fSClement Faure driver_init(csu_init);
177