// SPDX-License-Identifier: BSD-2-Clause /* * Copyright 2017-2023 NXP * */ #include #include #include #include #include #include #include struct csu_setting { int csu_index; uint32_t value; }; const struct csu_setting csu_setting_imx6[] = { {13, 0xFF0033}, /* Protect ROMCP */ {16, 0x330033}, /* Protect TZASC */ {26, 0xFF0033}, /* Protect OCRAM */ {(-1), 0}, }; struct csu_sa_setting { uint32_t access_value; uint32_t lock_value; }; struct csu_config { const struct csu_sa_setting * const sa; const struct csu_setting * const csl; }; const struct csu_setting csu_setting_imx6ul[] = { {13, 0xFF0033}, /* Protect ROMCP */ {16, 0x3300FF}, /* Protect TZASC */ {39, 0x3300FF}, /* Protect OCRAM */ {(-1), 0}, }; const struct csu_setting csu_setting_imx6ull[] = { { 13, 0xFF0033 }, /* Protect ROMCP */ { 16, 0x3300FF }, /* Protect TZASC */ { 34, 0xFF0033 }, /* Protect DCP */ { 39, 0x3300FF }, /* Protect OCRAM */ { (-1), 0 }, }; const struct csu_setting csu_setting_imx6sl[] = { { 13, 0x3F0033 }, /* Protect DCP/ROMCP */ { 16, 0xFF0033 }, /* Protect TZASC */ { 26, 0xFF0033 }, /* Protect OCRAM */ { (-1), 0 }, }; const struct csu_setting csu_setting_imx6sx[] = { {13, 0xFF0033}, /* Protect ROMCP */ {15, 0xFF0033}, /* Protect RDC */ {16, 0x3300FF}, /* Protect TZASC */ {34, 0x3300FF}, /* Protect OCRAM */ {(-1), 0}, }; const struct csu_setting csu_setting_imx7ds[] = { {14, 0x3300FF}, /* Protect RDC */ {15, 0xFF0033}, /* Protect CSU */ {28, 0xFF0033}, /* Protect TZASC */ {59, 0x3300FF}, /* Protect OCRAM_S */ {(-1), 0}, }; /* Set all masters to non-secure except the Cortex-A cores */ const struct csu_sa_setting csu_sa_imx6 = { 0x15554554, 0x2aaa8aaa }; const struct csu_sa_setting csu_sa_imx6ul = { 0x10554550, 0x20aa8aa2 }; const struct csu_sa_setting csu_sa_imx7ds = { 0x15554554, 0x2aaa8aaa }; const struct csu_config csu_imx6 = { &csu_sa_imx6, csu_setting_imx6 }; const struct csu_config csu_imx6ul = { &csu_sa_imx6ul, csu_setting_imx6ul }; const struct csu_config csu_imx6ull = { &csu_sa_imx6ul, csu_setting_imx6ull }; const struct csu_config csu_imx6sl = { NULL, csu_setting_imx6sl }; const struct csu_config csu_imx6sx = { NULL, csu_setting_imx6sx }; const struct csu_config csu_imx7ds = { &csu_sa_imx7ds, csu_setting_imx7ds }; static void rngb_configure(vaddr_t csu_base) { int csu_index = 0; if (soc_is_imx6sl() || soc_is_imx6sll()) csu_index = 16; else if (soc_is_imx6ull()) csu_index = 34; else return; /* Protect RNGB */ io_mask32(csu_base + csu_index * 4, 0x330000, 0xFF0000); } static TEE_Result csu_configure(void) { vaddr_t csu_base; vaddr_t offset; const struct csu_config *csu_config = NULL; const struct csu_setting *csu_setting = NULL; csu_base = core_mmu_get_va(CSU_BASE, MEM_AREA_IO_SEC, 1); if (!csu_base) panic(); if (soc_is_imx6sx()) csu_config = &csu_imx6sx; else if (soc_is_imx6ul()) csu_config = &csu_imx6ul; else if (soc_is_imx6ull()) csu_config = &csu_imx6ull; else if (soc_is_imx6sll() || soc_is_imx6sl()) csu_config = &csu_imx6sl; else if (soc_is_imx6()) csu_config = &csu_imx6; else if (soc_is_imx7ds()) csu_config = &csu_imx7ds; else return TEE_SUCCESS; /* first grant all peripherals */ for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) io_write32(csu_base + offset, CSU_ACCESS_ALL); csu_setting = csu_config->csl; while (csu_setting->csu_index >= 0) { io_write32(csu_base + (csu_setting->csu_index * 4), csu_setting->value); csu_setting++; } if (IS_ENABLED(CFG_IMX_RNGB)) rngb_configure(csu_base); /* lock the settings */ for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) { io_write32(csu_base + offset, io_read32(csu_base + offset) | CSU_SETTING_LOCK); } if (csu_config->sa) { io_write32(csu_base + CSU_SA, csu_config->sa->access_value); io_setbits32(csu_base + CSU_SA, csu_config->sa->lock_value); } return TEE_SUCCESS; } static TEE_Result pm_enter_resume(enum pm_op op, uint32_t pm_hint __unused, const struct pm_callback_handle *pm_handle __unused) { if (op == PM_OP_RESUME) csu_configure(); return TEE_SUCCESS; } static TEE_Result csu_init(void) { csu_configure(); register_pm_driver_cb(pm_enter_resume, NULL, "imx-csu"); return TEE_SUCCESS; } driver_init(csu_init);