1 /* 2 * Copyright 2014-2015 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <efi_loader.h> 9 #include <libfdt.h> 10 #include <fdt_support.h> 11 #include <phy.h> 12 #ifdef CONFIG_FSL_LSCH3 13 #include <asm/arch/fdt.h> 14 #endif 15 #ifdef CONFIG_FSL_ESDHC 16 #include <fsl_esdhc.h> 17 #endif 18 #ifdef CONFIG_SYS_DPAA_FMAN 19 #include <fsl_fman.h> 20 #endif 21 #ifdef CONFIG_MP 22 #include <asm/arch/mp.h> 23 #endif 24 #include <fsl_sec.h> 25 #include <asm/arch-fsl-layerscape/soc.h> 26 #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT 27 #include <asm/armv8/sec_firmware.h> 28 #endif 29 30 int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc) 31 { 32 return fdt_setprop_string(blob, offset, "phy-connection-type", 33 phy_string_for_interface(phyc)); 34 } 35 36 #ifdef CONFIG_MP 37 void ft_fixup_cpu(void *blob) 38 { 39 int off; 40 __maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr(); 41 fdt32_t *reg; 42 int addr_cells; 43 u64 val, core_id; 44 size_t *boot_code_size = &(__secondary_boot_code_size); 45 #if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI) 46 int node; 47 u32 psci_ver; 48 49 /* Check the psci version to determine if the psci is supported */ 50 psci_ver = sec_firmware_support_psci_version(); 51 if (psci_ver == 0xffffffff) { 52 /* remove psci DT node */ 53 node = fdt_path_offset(blob, "/psci"); 54 if (node >= 0) 55 goto remove_psci_node; 56 57 node = fdt_node_offset_by_compatible(blob, -1, "arm,psci"); 58 if (node >= 0) 59 goto remove_psci_node; 60 61 node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-0.2"); 62 if (node >= 0) 63 goto remove_psci_node; 64 65 node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-1.0"); 66 if (node >= 0) 67 goto remove_psci_node; 68 69 remove_psci_node: 70 if (node >= 0) 71 fdt_del_node(blob, node); 72 } else { 73 return; 74 } 75 #endif 76 off = fdt_path_offset(blob, "/cpus"); 77 if (off < 0) { 78 puts("couldn't find /cpus node\n"); 79 return; 80 } 81 of_bus_default_count_cells(blob, off, &addr_cells, NULL); 82 83 off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); 84 while (off != -FDT_ERR_NOTFOUND) { 85 reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0); 86 if (reg) { 87 core_id = of_read_number(reg, addr_cells); 88 if (core_id == 0 || (is_core_online(core_id))) { 89 val = spin_tbl_addr; 90 val += id_to_core(core_id) * 91 SPIN_TABLE_ELEM_SIZE; 92 val = cpu_to_fdt64(val); 93 fdt_setprop_string(blob, off, "enable-method", 94 "spin-table"); 95 fdt_setprop(blob, off, "cpu-release-addr", 96 &val, sizeof(val)); 97 } else { 98 debug("skipping offline core\n"); 99 } 100 } else { 101 puts("Warning: found cpu node without reg property\n"); 102 } 103 off = fdt_node_offset_by_prop_value(blob, off, "device_type", 104 "cpu", 4); 105 } 106 107 fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code, 108 *boot_code_size); 109 #if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD) 110 efi_add_memory_map((uintptr_t)&secondary_boot_code, 111 ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT, 112 EFI_RESERVED_MEMORY_TYPE, false); 113 #endif 114 } 115 #endif 116 117 void fsl_fdt_disable_usb(void *blob) 118 { 119 int off; 120 /* 121 * SYSCLK is used as a reference clock for USB. When the USB 122 * controller is used, SYSCLK must meet the additional requirement 123 * of 100 MHz. 124 */ 125 if (CONFIG_SYS_CLK_FREQ != 100000000) { 126 off = fdt_node_offset_by_compatible(blob, -1, "snps,dwc3"); 127 while (off != -FDT_ERR_NOTFOUND) { 128 fdt_status_disabled(blob, off); 129 off = fdt_node_offset_by_compatible(blob, off, 130 "snps,dwc3"); 131 } 132 } 133 } 134 135 void ft_cpu_setup(void *blob, bd_t *bd) 136 { 137 #ifdef CONFIG_FSL_LSCH2 138 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 139 unsigned int svr = in_be32(&gur->svr); 140 141 /* delete crypto node if not on an E-processor */ 142 if (!IS_E_PROCESSOR(svr)) 143 fdt_fixup_crypto_node(blob, 0); 144 #if CONFIG_SYS_FSL_SEC_COMPAT >= 4 145 else { 146 ccsr_sec_t __iomem *sec; 147 148 sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR; 149 fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms)); 150 } 151 #endif 152 #endif 153 154 #ifdef CONFIG_MP 155 ft_fixup_cpu(blob); 156 #endif 157 158 #ifdef CONFIG_SYS_NS16550 159 do_fixup_by_compat_u32(blob, "fsl,ns16550", 160 "clock-frequency", CONFIG_SYS_NS16550_CLK, 1); 161 #endif 162 163 do_fixup_by_compat_u32(blob, "fixed-clock", 164 "clock-frequency", CONFIG_SYS_CLK_FREQ, 1); 165 166 #ifdef CONFIG_PCI 167 ft_pci_setup(blob, bd); 168 #endif 169 170 #ifdef CONFIG_FSL_ESDHC 171 fdt_fixup_esdhc(blob, bd); 172 #endif 173 174 #ifdef CONFIG_SYS_DPAA_FMAN 175 fdt_fixup_fman_firmware(blob); 176 #endif 177 fsl_fdt_disable_usb(blob); 178 179 } 180