1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2021 NXP 4 */ 5 #include <arm.h> 6 #include <initcall.h> 7 #include <mm/core_memprot.h> 8 #include <mm/core_mmu.h> 9 #include <imx.h> 10 #include <io.h> 11 #include <drivers/imx_ocotp.h> 12 #include <kernel/delay_arch.h> 13 #include <kernel/tee_common_otp.h> 14 15 #define OCOTP_CTRL 0x0 16 #define OCOTP_CTRL_CLR 0x8 17 18 #if defined(CFG_MX8MP) 19 #define OCOTP_CTRL_ERROR BIT32(10) 20 #define OCOTP_CTRL_BUSY BIT32(9) 21 #else 22 #define OCOTP_CTRL_ERROR BIT32(9) 23 #define OCOTP_CTRL_BUSY BIT32(8) 24 #endif 25 26 #if defined(CFG_MX6) || defined(CFG_MX7ULP) 27 #define OCOTP_SHADOW_OFFSET(_b, _w) ((_b) * (0x80) + (_w) * (0x10) + 0x400) 28 #else 29 #define OCOTP_SHADOW_OFFSET(_b, _w) ((_b) * (0x40) + (_w) * (0x10) + 0x400) 30 #endif 31 32 #define OCOTP_OP_BUSY_TIMEOUT_US 20 33 34 struct ocotp_instance { 35 unsigned char nb_banks; 36 unsigned char nb_words; 37 TEE_Result (*get_die_id)(uint64_t *ret_uid); 38 }; 39 40 static vaddr_t g_base_addr; 41 static struct mutex fuse_read = MUTEX_INITIALIZER; 42 static const struct ocotp_instance *g_ocotp; 43 44 #if defined(CFG_MX6) 45 static void ocotp_clock_enable(void) 46 { 47 vaddr_t va = core_mmu_get_va(CCM_BASE, MEM_AREA_IO_SEC, CCM_SIZE); 48 49 io_setbits32(va + CCM_CCGR2, BM_CCM_CCGR2_OCOTP_CTRL); 50 } 51 #elif defined(CFG_MX7) 52 static void ocotp_clock_enable(void) 53 { 54 vaddr_t va = core_mmu_get_va(CCM_BASE, MEM_AREA_IO_SEC, CCM_SIZE); 55 56 io_setbits32(va + CCM_CCGRx_SET(CCM_CLOCK_DOMAIN_OCOTP), 57 CCM_CCGRx_ALWAYS_ON(0)); 58 } 59 #elif defined(CFG_MX8M) 60 static void ocotp_clock_enable(void) 61 { 62 vaddr_t va = core_mmu_get_va(CCM_BASE, MEM_AREA_IO_SEC, CCM_SIZE); 63 64 io_setbits32(va + CCM_CCGRx_SET(CCM_CCRG_OCOTP), 65 CCM_CCGRx_ALWAYS_ON(0)); 66 } 67 #elif defined(CFG_MX7ULP) 68 /* The i.MX7ULP has the OCOTP always powered on */ 69 static inline void ocotp_clock_enable(void) { } 70 #else 71 #error "Platform not supported" 72 #endif 73 74 #if defined(CFG_CORE_HAS_GENERIC_TIMER) 75 static TEE_Result ocotp_ctrl_wait_for(uint32_t mask) 76 { 77 uint32_t val = 0; 78 79 assert(g_base_addr); 80 if (IO_READ32_POLL_TIMEOUT(g_base_addr + OCOTP_CTRL, val, 81 !(val & mask), 0, OCOTP_OP_BUSY_TIMEOUT_US)) 82 return TEE_ERROR_BUSY; 83 84 return TEE_SUCCESS; 85 } 86 #else 87 static TEE_Result ocotp_ctrl_wait_for(uint32_t mask) 88 { 89 unsigned int loop = 0; 90 uint32_t reg = 0; 91 92 assert(g_base_addr); 93 94 /* 20us delay assuming the CPU clock running at 500MHz */ 95 for (loop = 10000; loop > 0; loop--) { 96 reg = io_read32(g_base_addr + OCOTP_CTRL) & mask; 97 if (!reg) 98 return TEE_SUCCESS; 99 dsb(); 100 isb(); 101 } 102 103 return TEE_ERROR_BUSY; 104 } 105 #endif 106 107 TEE_Result imx_ocotp_read(unsigned int bank, unsigned int word, uint32_t *val) 108 { 109 TEE_Result ret = TEE_ERROR_GENERIC; 110 111 if (!val) 112 return TEE_ERROR_BAD_PARAMETERS; 113 114 assert(g_base_addr && g_ocotp); 115 116 if (bank > g_ocotp->nb_banks || word > g_ocotp->nb_words) 117 return TEE_ERROR_BAD_PARAMETERS; 118 119 mutex_lock(&fuse_read); 120 121 ocotp_clock_enable(); 122 123 /* Clear error bit */ 124 io_write32(g_base_addr + OCOTP_CTRL_CLR, OCOTP_CTRL_ERROR); 125 126 /* Wait for busy flag to be cleared */ 127 ret = ocotp_ctrl_wait_for(OCOTP_CTRL_BUSY); 128 if (ret) { 129 EMSG("OCOTP is busy"); 130 goto out; 131 } 132 133 /* Read shadow register */ 134 *val = io_read32(g_base_addr + OCOTP_SHADOW_OFFSET(bank, word)); 135 136 DMSG("OCOTP Bank %d Word %d Fuse 0x%" PRIx32, bank, word, *val); 137 out: 138 mutex_unlock(&fuse_read); 139 140 return ret; 141 } 142 143 static TEE_Result ocotp_get_die_id_mx7ulp(uint64_t *ret_uid) 144 { 145 TEE_Result res = TEE_ERROR_GENERIC; 146 uint32_t val = 0; 147 uint64_t uid = 0; 148 149 res = imx_ocotp_read(1, 6, &val); 150 if (res) 151 goto out; 152 uid = val & GENMASK_32(15, 0); 153 154 res = imx_ocotp_read(1, 5, &val); 155 if (res) 156 goto out; 157 uid = SHIFT_U64(uid, 16) | (val & GENMASK_32(15, 0)); 158 159 res = imx_ocotp_read(1, 4, &val); 160 if (res) 161 goto out; 162 uid = SHIFT_U64(uid, 16) | (val & GENMASK_32(15, 0)); 163 164 res = imx_ocotp_read(1, 3, &val); 165 if (res) 166 goto out; 167 uid = SHIFT_U64(uid, 16) | (val & GENMASK_32(15, 0)); 168 169 out: 170 if (res == TEE_SUCCESS) 171 *ret_uid = uid; 172 173 return res; 174 } 175 176 static TEE_Result ocotp_get_die_id_mx(uint64_t *ret_uid) 177 { 178 TEE_Result res = TEE_ERROR_GENERIC; 179 uint32_t val = 0; 180 uint64_t uid = 0; 181 182 res = imx_ocotp_read(0, 2, &val); 183 if (res) 184 goto out; 185 uid = val; 186 187 res = imx_ocotp_read(0, 1, &val); 188 if (res) 189 goto out; 190 uid = SHIFT_U64(uid, 32) | val; 191 192 out: 193 if (res == TEE_SUCCESS) 194 *ret_uid = uid; 195 196 return res; 197 } 198 199 static const struct ocotp_instance ocotp_imx6q = { 200 .nb_banks = 16, 201 .nb_words = 8, 202 .get_die_id = ocotp_get_die_id_mx, 203 }; 204 205 static const struct ocotp_instance ocotp_imx6sl = { 206 .nb_banks = 8, 207 .nb_words = 8, 208 .get_die_id = ocotp_get_die_id_mx, 209 }; 210 211 static const struct ocotp_instance ocotp_imx6sll = { 212 .nb_banks = 16, 213 .nb_words = 8, 214 .get_die_id = ocotp_get_die_id_mx, 215 }; 216 217 static const struct ocotp_instance ocotp_imx6sx = { 218 .nb_banks = 16, 219 .nb_words = 8, 220 .get_die_id = ocotp_get_die_id_mx, 221 }; 222 223 static const struct ocotp_instance ocotp_imx6ul = { 224 .nb_banks = 16, 225 .nb_words = 8, 226 .get_die_id = ocotp_get_die_id_mx, 227 }; 228 229 static const struct ocotp_instance ocotp_imx6ull = { 230 .nb_banks = 8, 231 .nb_words = 8, 232 .get_die_id = ocotp_get_die_id_mx, 233 }; 234 235 static const struct ocotp_instance ocotp_imx7d = { 236 .nb_banks = 8, 237 .nb_words = 8, 238 .get_die_id = ocotp_get_die_id_mx, 239 }; 240 241 static const struct ocotp_instance ocotp_imx7ulp = { 242 .nb_banks = 32, 243 .nb_words = 8, 244 .get_die_id = ocotp_get_die_id_mx7ulp, 245 }; 246 247 static const struct ocotp_instance ocotp_imx8m = { 248 .nb_banks = 32, 249 .nb_words = 8, 250 .get_die_id = ocotp_get_die_id_mx, 251 }; 252 253 static const struct ocotp_instance ocotp_imx8mp = { 254 .nb_banks = 48, 255 .nb_words = 8, 256 .get_die_id = ocotp_get_die_id_mx, 257 }; 258 259 int tee_otp_get_die_id(uint8_t *buffer, size_t len) 260 { 261 size_t max_size_uid = IMX_UID_SIZE; 262 uint64_t uid = 0; 263 264 assert(buffer); 265 assert(g_base_addr && g_ocotp); 266 267 if (g_ocotp->get_die_id(&uid)) 268 goto err; 269 270 memcpy(buffer, &uid, MIN(max_size_uid, len)); 271 return 0; 272 273 err: 274 EMSG("Error while getting die ID"); 275 return -1; 276 } 277 278 register_phys_mem_pgdir(MEM_AREA_IO_SEC, OCOTP_BASE, CORE_MMU_PGDIR_SIZE); 279 static TEE_Result imx_ocotp_init(void) 280 { 281 g_base_addr = core_mmu_get_va(OCOTP_BASE, MEM_AREA_IO_SEC, OCOTP_SIZE); 282 if (!g_base_addr) 283 return TEE_ERROR_GENERIC; 284 285 if (soc_is_imx6sdl() || soc_is_imx6dq() || soc_is_imx6dqp()) { 286 g_ocotp = &ocotp_imx6q; 287 } else if (soc_is_imx6sl()) { 288 g_ocotp = &ocotp_imx6sl; 289 } else if (soc_is_imx6sll()) { 290 g_ocotp = &ocotp_imx6sll; 291 } else if (soc_is_imx6sx()) { 292 g_ocotp = &ocotp_imx6sx; 293 } else if (soc_is_imx6ul()) { 294 g_ocotp = &ocotp_imx6ul; 295 } else if (soc_is_imx6ull()) { 296 g_ocotp = &ocotp_imx6ull; 297 } else if (soc_is_imx7ds()) { 298 g_ocotp = &ocotp_imx7d; 299 } else if (soc_is_imx7ulp()) { 300 g_ocotp = &ocotp_imx7ulp; 301 } else if (soc_is_imx8mm() || soc_is_imx8mn() || soc_is_imx8mq()) { 302 g_ocotp = &ocotp_imx8m; 303 } else if (soc_is_imx8mp()) { 304 g_ocotp = &ocotp_imx8mp; 305 } else { 306 g_ocotp = NULL; 307 return TEE_ERROR_NOT_SUPPORTED; 308 } 309 310 return TEE_SUCCESS; 311 } 312 service_init(imx_ocotp_init); 313