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
759b2c7a62SRouven Czerwinski /* Set all masters to non-secure except the Cortex-A cores */
769b2c7a62SRouven 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
809b2c7a62SRouven 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 };
82*71958437SRouven Czerwinski const struct csu_config csu_imx6ull = { &csu_sa_imx6ul, 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
rngb_configure(vaddr_t csu_base)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
csu_configure(void)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
pm_enter_resume(enum pm_op op,uint32_t pm_hint __unused,const struct pm_callback_handle * pm_handle __unused)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
csu_init(void)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