1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2017-2023 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 <kernel/pm.h> 13 #include <mm/core_memprot.h> 14 15 struct csu_setting { 16 int csu_index; 17 uint32_t value; 18 }; 19 20 const struct csu_setting csu_setting_imx6[] = { 21 {13, 0xFF0033}, /* Protect ROMCP */ 22 {16, 0x330033}, /* Protect TZASC */ 23 {26, 0xFF0033}, /* Protect OCRAM */ 24 {(-1), 0}, 25 }; 26 27 struct csu_sa_setting { 28 uint32_t access_value; 29 uint32_t lock_value; 30 }; 31 32 struct csu_config { 33 const struct csu_sa_setting * const sa; 34 const struct csu_setting * const csl; 35 }; 36 37 const struct csu_setting csu_setting_imx6ul[] = { 38 {13, 0xFF0033}, /* Protect ROMCP */ 39 {16, 0x3300FF}, /* Protect TZASC */ 40 {39, 0x3300FF}, /* Protect OCRAM */ 41 {(-1), 0}, 42 }; 43 44 const struct csu_setting csu_setting_imx6ull[] = { 45 { 13, 0xFF0033 }, /* Protect ROMCP */ 46 { 16, 0x3300FF }, /* Protect TZASC */ 47 { 34, 0xFF0033 }, /* Protect DCP */ 48 { 39, 0x3300FF }, /* Protect OCRAM */ 49 { (-1), 0 }, 50 }; 51 52 const struct csu_setting csu_setting_imx6sl[] = { 53 { 13, 0x3F0033 }, /* Protect DCP/ROMCP */ 54 { 16, 0xFF0033 }, /* Protect TZASC */ 55 { 26, 0xFF0033 }, /* Protect OCRAM */ 56 { (-1), 0 }, 57 }; 58 59 const struct csu_setting csu_setting_imx6sx[] = { 60 {13, 0xFF0033}, /* Protect ROMCP */ 61 {15, 0xFF0033}, /* Protect RDC */ 62 {16, 0x3300FF}, /* Protect TZASC */ 63 {34, 0x3300FF}, /* Protect OCRAM */ 64 {(-1), 0}, 65 }; 66 67 const struct csu_setting csu_setting_imx7ds[] = { 68 {14, 0x3300FF}, /* Protect RDC */ 69 {15, 0xFF0033}, /* Protect CSU */ 70 {28, 0xFF0033}, /* Protect TZASC */ 71 {59, 0x3300FF}, /* Protect OCRAM_S */ 72 {(-1), 0}, 73 }; 74 75 /* Set all masters to non-secure except the Cortex-A cores */ 76 const struct csu_sa_setting csu_sa_imx6 = { 0x15554554, 0x2aaa8aaa }; 77 const struct csu_sa_setting csu_sa_imx6ul = { 0x10554550, 0x20aa8aa2 }; 78 const struct csu_sa_setting csu_sa_imx7ds = { 0x15554554, 0x2aaa8aaa }; 79 80 const struct csu_config csu_imx6 = { &csu_sa_imx6, csu_setting_imx6 }; 81 const struct csu_config csu_imx6ul = { &csu_sa_imx6ul, csu_setting_imx6ul }; 82 const struct csu_config csu_imx6ull = { NULL, csu_setting_imx6ull }; 83 const struct csu_config csu_imx6sl = { NULL, csu_setting_imx6sl }; 84 const struct csu_config csu_imx6sx = { NULL, csu_setting_imx6sx }; 85 const struct csu_config csu_imx7ds = { &csu_sa_imx7ds, csu_setting_imx7ds }; 86 87 static void rngb_configure(vaddr_t csu_base) 88 { 89 int csu_index = 0; 90 91 if (soc_is_imx6sl() || soc_is_imx6sll()) 92 csu_index = 16; 93 else if (soc_is_imx6ull()) 94 csu_index = 34; 95 else 96 return; 97 98 /* Protect RNGB */ 99 io_mask32(csu_base + csu_index * 4, 0x330000, 0xFF0000); 100 } 101 102 static TEE_Result csu_configure(void) 103 { 104 vaddr_t csu_base; 105 vaddr_t offset; 106 const struct csu_config *csu_config = NULL; 107 const struct csu_setting *csu_setting = NULL; 108 109 csu_base = core_mmu_get_va(CSU_BASE, MEM_AREA_IO_SEC, 1); 110 if (!csu_base) 111 panic(); 112 113 if (soc_is_imx6sx()) 114 csu_config = &csu_imx6sx; 115 else if (soc_is_imx6ul()) 116 csu_config = &csu_imx6ul; 117 else if (soc_is_imx6ull()) 118 csu_config = &csu_imx6ull; 119 else if (soc_is_imx6sll() || soc_is_imx6sl()) 120 csu_config = &csu_imx6sl; 121 else if (soc_is_imx6()) 122 csu_config = &csu_imx6; 123 else if (soc_is_imx7ds()) 124 csu_config = &csu_imx7ds; 125 else 126 return TEE_SUCCESS; 127 128 /* first grant all peripherals */ 129 for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) 130 io_write32(csu_base + offset, CSU_ACCESS_ALL); 131 132 csu_setting = csu_config->csl; 133 134 while (csu_setting->csu_index >= 0) { 135 io_write32(csu_base + (csu_setting->csu_index * 4), 136 csu_setting->value); 137 138 csu_setting++; 139 } 140 141 if (IS_ENABLED(CFG_IMX_RNGB)) 142 rngb_configure(csu_base); 143 144 /* lock the settings */ 145 for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) { 146 io_write32(csu_base + offset, 147 io_read32(csu_base + offset) | CSU_SETTING_LOCK); 148 } 149 150 if (csu_config->sa) { 151 io_write32(csu_base + CSU_SA, csu_config->sa->access_value); 152 io_setbits32(csu_base + CSU_SA, csu_config->sa->lock_value); 153 } 154 155 return TEE_SUCCESS; 156 } 157 158 static TEE_Result 159 pm_enter_resume(enum pm_op op, uint32_t pm_hint __unused, 160 const struct pm_callback_handle *pm_handle __unused) 161 { 162 if (op == PM_OP_RESUME) 163 csu_configure(); 164 165 return TEE_SUCCESS; 166 } 167 168 static TEE_Result csu_init(void) 169 { 170 csu_configure(); 171 register_pm_driver_cb(pm_enter_resume, NULL, "imx-csu"); 172 173 return TEE_SUCCESS; 174 } 175 176 driver_init(csu_init); 177