1 /* 2 * Copyright 2016 Texas Instruments, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <libfdt.h> 9 #include <fdt_support.h> 10 #include <malloc.h> 11 12 #include <asm/omap_common.h> 13 #include <asm/arch-omap5/sys_proto.h> 14 15 #ifdef CONFIG_TI_SECURE_DEVICE 16 17 /* Give zero values if not already defined */ 18 #ifndef TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ 19 #define TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ (0) 20 #endif 21 #ifndef CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ 22 #define CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ (0) 23 #endif 24 25 static u32 hs_irq_skip[] = { 26 8, /* Secure violation reporting interrupt */ 27 15, /* One interrupt for SDMA by secure world */ 28 118 /* One interrupt for Crypto DMA by secure world */ 29 }; 30 31 static int ft_hs_fixup_crossbar(void *fdt, bd_t *bd) 32 { 33 const char *path; 34 int offs; 35 int ret; 36 int len, i, old_cnt, new_cnt; 37 u32 *temp; 38 const u32 *p_data; 39 40 /* 41 * Increase the size of the fdt 42 * so we have some breathing room 43 */ 44 ret = fdt_increase_size(fdt, 512); 45 if (ret < 0) { 46 printf("Could not increase size of device tree: %s\n", 47 fdt_strerror(ret)); 48 return ret; 49 } 50 51 /* Reserve IRQs that are used/needed by secure world */ 52 path = "/ocp/crossbar"; 53 offs = fdt_path_offset(fdt, path); 54 if (offs < 0) { 55 debug("Node %s not found.\n", path); 56 return 0; 57 } 58 59 /* Get current entries */ 60 p_data = fdt_getprop(fdt, offs, "ti,irqs-skip", &len); 61 if (p_data) 62 old_cnt = len / sizeof(u32); 63 else 64 old_cnt = 0; 65 66 new_cnt = sizeof(hs_irq_skip) / 67 sizeof(hs_irq_skip[0]); 68 69 /* Create new/updated skip list for HS parts */ 70 temp = malloc(sizeof(u32) * (old_cnt + new_cnt)); 71 for (i = 0; i < new_cnt; i++) 72 temp[i] = cpu_to_fdt32(hs_irq_skip[i]); 73 for (i = 0; i < old_cnt; i++) 74 temp[i + new_cnt] = p_data[i]; 75 76 /* Blow away old data and set new data */ 77 fdt_delprop(fdt, offs, "ti,irqs-skip"); 78 ret = fdt_setprop(fdt, offs, "ti,irqs-skip", 79 temp, 80 (old_cnt + new_cnt) * sizeof(u32)); 81 free(temp); 82 83 /* Check if the update worked */ 84 if (ret < 0) { 85 printf("Could not add ti,irqs-skip property to node %s: %s\n", 86 path, fdt_strerror(ret)); 87 return ret; 88 } 89 90 return 0; 91 } 92 93 static int ft_hs_disable_rng(void *fdt, bd_t *bd) 94 { 95 const char *path; 96 int offs; 97 int ret; 98 99 /* Make HW RNG reserved for secure world use */ 100 path = "/ocp/rng"; 101 offs = fdt_path_offset(fdt, path); 102 if (offs < 0) { 103 debug("Node %s not found.\n", path); 104 return 0; 105 } 106 ret = fdt_setprop_string(fdt, offs, 107 "status", "disabled"); 108 if (ret < 0) { 109 printf("Could not add status property to node %s: %s\n", 110 path, fdt_strerror(ret)); 111 return ret; 112 } 113 return 0; 114 } 115 116 #if ((TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ != 0) || \ 117 (CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ != 0)) 118 static int ft_hs_fixup_sram(void *fdt, bd_t *bd) 119 { 120 const char *path; 121 int offs; 122 int ret; 123 u32 temp[2]; 124 125 /* 126 * Update SRAM reservations on secure devices. The OCMC RAM 127 * is always reserved for secure use from the start of that 128 * memory region 129 */ 130 path = "/ocp/ocmcram@40300000/sram-hs"; 131 offs = fdt_path_offset(fdt, path); 132 if (offs < 0) { 133 debug("Node %s not found.\n", path); 134 return 0; 135 } 136 137 /* relative start offset */ 138 temp[0] = cpu_to_fdt32(0); 139 /* reservation size */ 140 temp[1] = cpu_to_fdt32(max(TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ, 141 CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ)); 142 fdt_delprop(fdt, offs, "reg"); 143 ret = fdt_setprop(fdt, offs, "reg", temp, 2 * sizeof(u32)); 144 if (ret < 0) { 145 printf("Could not add reg property to node %s: %s\n", 146 path, fdt_strerror(ret)); 147 return ret; 148 } 149 150 return 0; 151 } 152 #else 153 static int ft_hs_fixup_sram(void *fdt, bd_t *bd) { return 0; } 154 #endif 155 156 #if (CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE != 0) 157 static int ft_hs_fixup_dram(void *fdt, bd_t *bd) 158 { 159 const char *path, *subpath; 160 int offs; 161 u32 sec_mem_start = CONFIG_TI_SECURE_EMIF_REGION_START; 162 u32 sec_mem_size = CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE; 163 fdt64_t temp[2]; 164 fdt32_t two; 165 166 /* If start address is zero, place at end of DRAM */ 167 if (0 == sec_mem_start) 168 sec_mem_start = 169 (CONFIG_SYS_SDRAM_BASE + 170 (omap_sdram_size() - sec_mem_size)); 171 172 /* Delete any original secure_reserved node */ 173 path = "/reserved-memory/secure_reserved"; 174 offs = fdt_path_offset(fdt, path); 175 if (offs >= 0) 176 fdt_del_node(fdt, offs); 177 178 /* Add new secure_reserved node */ 179 path = "/reserved-memory"; 180 offs = fdt_path_offset(fdt, path); 181 if (offs < 0) { 182 debug("Node %s not found\n", path); 183 path = "/"; 184 subpath = "reserved-memory"; 185 offs = fdt_path_offset(fdt, path); 186 offs = fdt_add_subnode(fdt, offs, subpath); 187 if (offs < 0) { 188 printf("Could not create %s%s node.\n", path, subpath); 189 return 1; 190 } 191 path = "/reserved-memory"; 192 offs = fdt_path_offset(fdt, path); 193 two = cpu_to_fdt32(2); 194 fdt_setprop(fdt, offs, "#address-cells", &two, sizeof(two)); 195 fdt_setprop(fdt, offs, "#size-cells", &two, sizeof(two)); 196 fdt_setprop(fdt, offs, "ranges", NULL, 0); 197 } 198 199 subpath = "secure_reserved"; 200 offs = fdt_add_subnode(fdt, offs, subpath); 201 if (offs < 0) { 202 printf("Could not create %s%s node.\n", path, subpath); 203 return 1; 204 } 205 206 temp[0] = cpu_to_fdt64(((u64)sec_mem_start)); 207 temp[1] = cpu_to_fdt64(((u64)sec_mem_size)); 208 fdt_setprop_string(fdt, offs, "compatible", 209 "ti,dra7-secure-memory"); 210 fdt_setprop_string(fdt, offs, "status", "okay"); 211 fdt_setprop(fdt, offs, "no-map", NULL, 0); 212 fdt_setprop(fdt, offs, "reg", temp, sizeof(temp)); 213 214 return 0; 215 } 216 #else 217 static int ft_hs_fixup_dram(void *fdt, bd_t *bd) { return 0; } 218 #endif 219 220 static int ft_hs_add_tee(void *fdt, bd_t *bd) 221 { 222 const char *path, *subpath; 223 int offs; 224 225 extern int tee_loaded; 226 if (!tee_loaded) 227 return 0; 228 229 path = "/"; 230 offs = fdt_path_offset(fdt, path); 231 232 subpath = "firmware"; 233 offs = fdt_add_subnode(fdt, offs, subpath); 234 if (offs < 0) { 235 printf("Could not create %s node.\n", subpath); 236 return 1; 237 } 238 239 subpath = "optee"; 240 offs = fdt_add_subnode(fdt, offs, subpath); 241 if (offs < 0) { 242 printf("Could not create %s node.\n", subpath); 243 return 1; 244 } 245 246 fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz"); 247 fdt_setprop_string(fdt, offs, "method", "smc"); 248 249 return 0; 250 } 251 252 static void ft_hs_fixups(void *fdt, bd_t *bd) 253 { 254 /* Check we are running on an HS/EMU device type */ 255 if (GP_DEVICE != get_device_type()) { 256 if ((ft_hs_fixup_crossbar(fdt, bd) == 0) && 257 (ft_hs_disable_rng(fdt, bd) == 0) && 258 (ft_hs_fixup_sram(fdt, bd) == 0) && 259 (ft_hs_fixup_dram(fdt, bd) == 0) && 260 (ft_hs_add_tee(fdt, bd) == 0)) 261 return; 262 } else { 263 printf("ERROR: Incorrect device type (GP) detected!"); 264 } 265 /* Fixup failed or wrong device type */ 266 hang(); 267 } 268 #else 269 static void ft_hs_fixups(void *fdt, bd_t *bd) 270 { 271 } 272 #endif /* #ifdef CONFIG_TI_SECURE_DEVICE */ 273 274 #if defined(CONFIG_TARGET_DRA7XX_EVM) || defined(CONFIG_TARGET_AM57XX_EVM) 275 #define OPP_DSP_CLK_NUM 3 276 #define OPP_IVA_CLK_NUM 2 277 #define OPP_GPU_CLK_NUM 2 278 279 const char *dra7_opp_dsp_clk_names[OPP_DSP_CLK_NUM] = { 280 "dpll_dsp_ck", 281 "dpll_dsp_m2_ck", 282 "dpll_dsp_m3x2_ck", 283 }; 284 285 const char *dra7_opp_iva_clk_names[OPP_IVA_CLK_NUM] = { 286 "dpll_iva_ck", 287 "dpll_iva_m2_ck", 288 }; 289 290 const char *dra7_opp_gpu_clk_names[OPP_GPU_CLK_NUM] = { 291 "dpll_gpu_ck", 292 "dpll_gpu_m2_ck", 293 }; 294 295 /* DSPEVE voltage domain */ 296 u32 dra7_opp_dsp_clk_rates[NUM_OPPS][OPP_DSP_CLK_NUM] = { 297 {}, /*OPP_LOW */ 298 {600000000, 600000000, 400000000}, /* OPP_NOM */ 299 {700000000, 700000000, 466666667}, /* OPP_OD */ 300 {750000000, 750000000, 500000000}, /* OPP_HIGH */ 301 }; 302 303 /* IVA voltage domain */ 304 u32 dra7_opp_iva_clk_rates[NUM_OPPS][OPP_IVA_CLK_NUM] = { 305 {}, /* OPP_LOW */ 306 {1165000000, 388333334}, /* OPP_NOM */ 307 {860000000, 430000000}, /* OPP_OD */ 308 {1064000000, 532000000}, /* OPP_HIGH */ 309 }; 310 311 /* GPU voltage domain */ 312 u32 dra7_opp_gpu_clk_rates[NUM_OPPS][OPP_GPU_CLK_NUM] = { 313 {}, /* OPP_LOW */ 314 {1277000000, 425666667}, /* OPP_NOM */ 315 {1000000000, 500000000}, /* OPP_OD */ 316 {1064000000, 532000000}, /* OPP_HIGH */ 317 }; 318 319 static int ft_fixup_clocks(void *fdt, const char **names, u32 *rates, int num) 320 { 321 int offs, node_offs, ret, i; 322 uint32_t phandle; 323 324 offs = fdt_path_offset(fdt, "/ocp/l4@4a000000/cm_core_aon@5000/clocks"); 325 if (offs < 0) { 326 debug("Could not find cm_core_aon clocks node path offset : %s\n", 327 fdt_strerror(offs)); 328 return offs; 329 } 330 331 for (i = 0; i < num; i++) { 332 node_offs = fdt_subnode_offset(fdt, offs, names[i]); 333 if (node_offs < 0) { 334 debug("Could not find clock sub-node %s: %s\n", 335 names[i], fdt_strerror(node_offs)); 336 return offs; 337 } 338 339 phandle = fdt_get_phandle(fdt, node_offs); 340 if (!phandle) { 341 debug("Could not find phandle for clock %s\n", 342 names[i]); 343 return -1; 344 } 345 346 ret = fdt_setprop_u32(fdt, node_offs, "assigned-clocks", 347 phandle); 348 if (ret < 0) { 349 debug("Could not add assigned-clocks property to clock node %s: %s\n", 350 names[i], fdt_strerror(ret)); 351 return ret; 352 } 353 354 ret = fdt_setprop_u32(fdt, node_offs, "assigned-clock-rates", 355 rates[i]); 356 if (ret < 0) { 357 debug("Could not add assigned-clock-rates property to clock node %s: %s\n", 358 names[i], fdt_strerror(ret)); 359 return ret; 360 } 361 } 362 363 return 0; 364 } 365 366 static void ft_opp_clock_fixups(void *fdt, bd_t *bd) 367 { 368 const char **clk_names; 369 u32 *clk_rates; 370 int ret; 371 372 if (!is_dra72x() && !is_dra7xx()) 373 return; 374 375 /* fixup DSP clocks */ 376 clk_names = dra7_opp_dsp_clk_names; 377 clk_rates = dra7_opp_dsp_clk_rates[get_voltrail_opp(VOLT_EVE)]; 378 ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_DSP_CLK_NUM); 379 if (ret) { 380 printf("ft_fixup_clocks failed for DSP voltage domain: %s\n", 381 fdt_strerror(ret)); 382 return; 383 } 384 385 /* fixup IVA clocks */ 386 clk_names = dra7_opp_iva_clk_names; 387 clk_rates = dra7_opp_iva_clk_rates[get_voltrail_opp(VOLT_IVA)]; 388 ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_IVA_CLK_NUM); 389 if (ret) { 390 printf("ft_fixup_clocks failed for IVA voltage domain: %s\n", 391 fdt_strerror(ret)); 392 return; 393 } 394 395 /* fixup GPU clocks */ 396 clk_names = dra7_opp_gpu_clk_names; 397 clk_rates = dra7_opp_gpu_clk_rates[get_voltrail_opp(VOLT_GPU)]; 398 ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_GPU_CLK_NUM); 399 if (ret) { 400 printf("ft_fixup_clocks failed for GPU voltage domain: %s\n", 401 fdt_strerror(ret)); 402 return; 403 } 404 } 405 #else 406 static void ft_opp_clock_fixups(void *fdt, bd_t *bd) { } 407 #endif /* CONFIG_TARGET_DRA7XX_EVM || CONFIG_TARGET_AM57XX_EVM */ 408 409 /* 410 * Place for general cpu/SoC FDT fixups. Board specific 411 * fixups should remain in the board files which is where 412 * this function should be called from. 413 */ 414 void ft_cpu_setup(void *fdt, bd_t *bd) 415 { 416 ft_hs_fixups(fdt, bd); 417 ft_opp_clock_fixups(fdt, bd); 418 } 419