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-A7 */ 76 const struct csu_sa_setting csu_sa_imx6ul = { 0x10554550, 0x20aa8aa2 }; 77 const struct csu_sa_setting csu_sa_imx7ds = { 0x15554554, 0x2aaa8aaa }; 78 79 const struct csu_config csu_imx6 = { NULL, csu_setting_imx6 }; 80 const struct csu_config csu_imx6ul = { &csu_sa_imx6ul, csu_setting_imx6ul }; 81 const struct csu_config csu_imx6ull = { NULL, csu_setting_imx6ull }; 82 const struct csu_config csu_imx6sl = { NULL, csu_setting_imx6sl }; 83 const struct csu_config csu_imx6sx = { NULL, csu_setting_imx6sx }; 84 const struct csu_config csu_imx7ds = { &csu_sa_imx7ds, csu_setting_imx7ds }; 85 86 static void rngb_configure(vaddr_t csu_base) 87 { 88 int csu_index = 0; 89 90 if (soc_is_imx6sl() || soc_is_imx6sll()) 91 csu_index = 16; 92 else if (soc_is_imx6ull()) 93 csu_index = 34; 94 else 95 return; 96 97 /* Protect RNGB */ 98 io_mask32(csu_base + csu_index * 4, 0x330000, 0xFF0000); 99 } 100 101 static TEE_Result csu_configure(void) 102 { 103 vaddr_t csu_base; 104 vaddr_t offset; 105 const struct csu_config *csu_config = NULL; 106 const struct csu_setting *csu_setting = NULL; 107 108 csu_base = core_mmu_get_va(CSU_BASE, MEM_AREA_IO_SEC, 1); 109 if (!csu_base) 110 panic(); 111 112 if (soc_is_imx6sx()) 113 csu_config = &csu_imx6sx; 114 else if (soc_is_imx6ul()) 115 csu_config = &csu_imx6ul; 116 else if (soc_is_imx6ull()) 117 csu_config = &csu_imx6ull; 118 else if (soc_is_imx6sll() || soc_is_imx6sl()) 119 csu_config = &csu_imx6sl; 120 else if (soc_is_imx6()) 121 csu_config = &csu_imx6; 122 else if (soc_is_imx7ds()) 123 csu_config = &csu_imx7ds; 124 else 125 return TEE_SUCCESS; 126 127 /* first grant all peripherals */ 128 for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) 129 io_write32(csu_base + offset, CSU_ACCESS_ALL); 130 131 csu_setting = csu_config->csl; 132 133 while (csu_setting->csu_index >= 0) { 134 io_write32(csu_base + (csu_setting->csu_index * 4), 135 csu_setting->value); 136 137 csu_setting++; 138 } 139 140 if (IS_ENABLED(CFG_IMX_RNGB)) 141 rngb_configure(csu_base); 142 143 /* lock the settings */ 144 for (offset = CSU_CSL_START; offset < CSU_CSL_END; offset += 4) { 145 io_write32(csu_base + offset, 146 io_read32(csu_base + offset) | CSU_SETTING_LOCK); 147 } 148 149 if (csu_config->sa) { 150 io_write32(csu_base + CSU_SA, csu_config->sa->access_value); 151 io_setbits32(csu_base + CSU_SA, csu_config->sa->lock_value); 152 } 153 154 return TEE_SUCCESS; 155 } 156 157 static TEE_Result 158 pm_enter_resume(enum pm_op op, uint32_t pm_hint __unused, 159 const struct pm_callback_handle *pm_handle __unused) 160 { 161 if (op == PM_OP_RESUME) 162 csu_configure(); 163 164 return TEE_SUCCESS; 165 } 166 167 static TEE_Result csu_init(void) 168 { 169 csu_configure(); 170 register_pm_driver_cb(pm_enter_resume, NULL, "imx-csu"); 171 172 return TEE_SUCCESS; 173 } 174 175 driver_init(csu_init); 176