1 /* 2 * Copyright 2007,2009-2014 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <command.h> 9 #include <pci.h> 10 #include <asm/processor.h> 11 #include <asm/mmu.h> 12 #include <asm/fsl_pci.h> 13 #include <asm/io.h> 14 #include <libfdt.h> 15 #include <fdt_support.h> 16 #include <netdev.h> 17 #include <fdtdec.h> 18 #include <errno.h> 19 #include <malloc.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 static void *get_fdt_virt(void) 24 { 25 return (void *)CONFIG_SYS_TMPVIRT; 26 } 27 28 static uint64_t get_fdt_phys(void) 29 { 30 return (uint64_t)(uintptr_t)gd->fdt_blob; 31 } 32 33 static void map_fdt_as(int esel) 34 { 35 u32 mas0, mas1, mas2, mas3, mas7; 36 uint64_t fdt_phys = get_fdt_phys(); 37 unsigned long fdt_phys_tlb = fdt_phys & ~0xffffful; 38 unsigned long fdt_virt_tlb = (ulong)get_fdt_virt() & ~0xffffful; 39 40 mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(esel); 41 mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M); 42 mas2 = FSL_BOOKE_MAS2(fdt_virt_tlb, 0); 43 mas3 = FSL_BOOKE_MAS3(fdt_phys_tlb, 0, MAS3_SW|MAS3_SR); 44 mas7 = FSL_BOOKE_MAS7(fdt_phys_tlb); 45 46 write_tlb(mas0, mas1, mas2, mas3, mas7); 47 } 48 49 uint64_t get_phys_ccsrbar_addr_early(void) 50 { 51 void *fdt = get_fdt_virt(); 52 uint64_t r; 53 54 /* 55 * To be able to read the FDT we need to create a temporary TLB 56 * map for it. 57 */ 58 map_fdt_as(10); 59 r = fdt_get_base_address(fdt, fdt_path_offset(fdt, "/soc")); 60 disable_tlb(10); 61 62 return r; 63 } 64 65 int board_early_init_f(void) 66 { 67 return 0; 68 } 69 70 int checkboard(void) 71 { 72 return 0; 73 } 74 75 static int pci_map_region(void *fdt, int pci_node, int range_id, 76 phys_size_t *ppaddr, pci_addr_t *pvaddr, 77 pci_size_t *psize, ulong *pmap_addr) 78 { 79 uint64_t addr; 80 uint64_t size; 81 ulong map_addr; 82 int r; 83 84 r = fdt_read_range(fdt, pci_node, 0, NULL, &addr, &size); 85 if (r) 86 return r; 87 88 if (ppaddr) 89 *ppaddr = addr; 90 if (psize) 91 *psize = size; 92 93 if (!pmap_addr) 94 return 0; 95 96 map_addr = *pmap_addr; 97 98 /* Align map_addr */ 99 map_addr += size - 1; 100 map_addr &= ~(size - 1); 101 102 if (map_addr + size >= CONFIG_SYS_PCI_MAP_END) 103 return -1; 104 105 /* Map virtual memory for range */ 106 assert(!tlb_map_range(map_addr, addr, size, TLB_MAP_IO)); 107 *pmap_addr = map_addr + size; 108 109 if (pvaddr) 110 *pvaddr = map_addr; 111 112 return 0; 113 } 114 115 void pci_init_board(void) 116 { 117 struct pci_controller *pci_hoses; 118 void *fdt = get_fdt_virt(); 119 int pci_node = -1; 120 int pci_num = 0; 121 int pci_count = 0; 122 ulong map_addr; 123 124 puts("\n"); 125 126 /* Start MMIO and PIO range maps above RAM */ 127 map_addr = CONFIG_SYS_PCI_MAP_START; 128 129 /* Count and allocate PCI buses */ 130 pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, 131 "device_type", "pci", 4); 132 while (pci_node != -FDT_ERR_NOTFOUND) { 133 pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, 134 "device_type", "pci", 4); 135 pci_count++; 136 } 137 138 if (pci_count) { 139 pci_hoses = malloc(sizeof(struct pci_controller) * pci_count); 140 } else { 141 printf("PCI: disabled\n\n"); 142 return; 143 } 144 145 /* Spawn PCI buses based on device tree */ 146 pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, 147 "device_type", "pci", 4); 148 while (pci_node != -FDT_ERR_NOTFOUND) { 149 struct fsl_pci_info pci_info = { }; 150 const fdt32_t *reg; 151 int r; 152 153 reg = fdt_getprop(fdt, pci_node, "reg", NULL); 154 pci_info.regs = fdt_translate_address(fdt, pci_node, reg); 155 156 /* Map MMIO range */ 157 r = pci_map_region(fdt, pci_node, 0, &pci_info.mem_phys, NULL, 158 &pci_info.mem_size, &map_addr); 159 if (r) 160 break; 161 162 /* Map PIO range */ 163 r = pci_map_region(fdt, pci_node, 1, &pci_info.io_phys, NULL, 164 &pci_info.io_size, &map_addr); 165 if (r) 166 break; 167 168 /* 169 * The PCI framework finds virtual addresses for the buses 170 * through our address map, so tell it the physical addresses. 171 */ 172 pci_info.mem_bus = pci_info.mem_phys; 173 pci_info.io_bus = pci_info.io_phys; 174 175 /* Instantiate */ 176 pci_info.pci_num = pci_num + 1; 177 178 fsl_setup_hose(&pci_hoses[pci_num], pci_info.regs); 179 printf("PCI: base address %lx\n", pci_info.regs); 180 181 fsl_pci_init_port(&pci_info, &pci_hoses[pci_num], pci_num); 182 183 /* Jump to next PCI node */ 184 pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, 185 "device_type", "pci", 4); 186 pci_num++; 187 } 188 189 puts("\n"); 190 } 191 192 int last_stage_init(void) 193 { 194 void *fdt = get_fdt_virt(); 195 int len = 0; 196 const uint64_t *prop; 197 int chosen; 198 199 chosen = fdt_path_offset(fdt, "/chosen"); 200 if (chosen < 0) { 201 printf("Couldn't find /chosen node in fdt\n"); 202 return -EIO; 203 } 204 205 /* -kernel boot */ 206 prop = fdt_getprop(fdt, chosen, "qemu,boot-kernel", &len); 207 if (prop && (len >= 8)) 208 setenv_hex("qemu_kernel_addr", *prop); 209 210 /* Give the user a variable for the host fdt */ 211 setenv_hex("fdt_addr_r", (ulong)fdt); 212 213 return 0; 214 } 215 216 static uint64_t get_linear_ram_size(void) 217 { 218 void *fdt = get_fdt_virt(); 219 const void *prop; 220 int memory; 221 int len; 222 223 memory = fdt_path_offset(fdt, "/memory"); 224 prop = fdt_getprop(fdt, memory, "reg", &len); 225 226 if (prop && len >= 16) 227 return *(uint64_t *)(prop+8); 228 229 panic("Couldn't determine RAM size"); 230 } 231 232 int board_eth_init(bd_t *bis) 233 { 234 return pci_eth_init(bis); 235 } 236 237 #if defined(CONFIG_OF_BOARD_SETUP) 238 int ft_board_setup(void *blob, bd_t *bd) 239 { 240 FT_FSL_PCI_SETUP; 241 242 return 0; 243 } 244 #endif 245 246 void print_laws(void) 247 { 248 /* We don't emulate LAWs yet */ 249 } 250 251 phys_size_t fixed_sdram(void) 252 { 253 return get_linear_ram_size(); 254 } 255 256 phys_size_t fsl_ddr_sdram_size(void) 257 { 258 return get_linear_ram_size(); 259 } 260 261 void init_tlbs(void) 262 { 263 phys_size_t ram_size; 264 265 /* 266 * Create a temporary AS=1 map for the fdt 267 * 268 * We use ESEL=0 here to overwrite the previous AS=0 map for ourselves 269 * which was only 4k big. This way we don't have to clear any other maps. 270 */ 271 map_fdt_as(0); 272 273 /* Fetch RAM size from the fdt */ 274 ram_size = get_linear_ram_size(); 275 276 /* And remove our fdt map again */ 277 disable_tlb(0); 278 279 /* Create an internal map of manually created TLB maps */ 280 init_used_tlb_cams(); 281 282 /* Create a dynamic AS=0 CCSRBAR mapping */ 283 assert(!tlb_map_range(CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, 284 1024 * 1024, TLB_MAP_IO)); 285 286 /* Create a RAM map that spans all accessible RAM */ 287 setup_ddr_tlbs(ram_size >> 20); 288 289 /* Create a map for the TLB */ 290 assert(!tlb_map_range((ulong)get_fdt_virt(), get_fdt_phys(), 291 1024 * 1024, TLB_MAP_RAM)); 292 } 293 294 void init_laws(void) 295 { 296 /* We don't emulate LAWs yet */ 297 } 298 299 static uint32_t get_cpu_freq(void) 300 { 301 void *fdt = get_fdt_virt(); 302 int cpus_node = fdt_path_offset(fdt, "/cpus"); 303 int cpu_node = fdt_first_subnode(fdt, cpus_node); 304 const char *prop = "clock-frequency"; 305 return fdt_getprop_u32_default_node(fdt, cpu_node, 0, prop, 0); 306 } 307 308 void get_sys_info(sys_info_t *sys_info) 309 { 310 int freq = get_cpu_freq(); 311 312 memset(sys_info, 0, sizeof(sys_info_t)); 313 sys_info->freq_systembus = freq; 314 sys_info->freq_ddrbus = freq; 315 sys_info->freq_processor[0] = freq; 316 } 317 318 int get_clocks (void) 319 { 320 sys_info_t sys_info; 321 322 get_sys_info(&sys_info); 323 324 gd->cpu_clk = sys_info.freq_processor[0]; 325 gd->bus_clk = sys_info.freq_systembus; 326 gd->mem_clk = sys_info.freq_ddrbus; 327 gd->arch.lbc_clk = sys_info.freq_ddrbus; 328 329 return 0; 330 } 331 332 unsigned long get_tbclk (void) 333 { 334 void *fdt = get_fdt_virt(); 335 int cpus_node = fdt_path_offset(fdt, "/cpus"); 336 int cpu_node = fdt_first_subnode(fdt, cpus_node); 337 const char *prop = "timebase-frequency"; 338 return fdt_getprop_u32_default_node(fdt, cpu_node, 0, prop, 0); 339 } 340 341 /******************************************** 342 * get_bus_freq 343 * return system bus freq in Hz 344 *********************************************/ 345 ulong get_bus_freq (ulong dummy) 346 { 347 sys_info_t sys_info; 348 get_sys_info(&sys_info); 349 return sys_info.freq_systembus; 350 } 351 352 /* 353 * Return the number of cores on this SOC. 354 */ 355 int cpu_numcores(void) 356 { 357 /* 358 * The QEMU u-boot target only needs to drive the first core, 359 * spinning and device tree nodes get driven by QEMU itself 360 */ 361 return 1; 362 } 363 364 /* 365 * Return a 32-bit mask indicating which cores are present on this SOC. 366 */ 367 u32 cpu_mask(void) 368 { 369 return (1 << cpu_numcores()) - 1; 370 } 371