1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2018, 2021 NXP 4 */ 5 6#include <common.h> 7#include <clk.h> 8#include <cpu.h> 9#include <cpu_func.h> 10#include <dm.h> 11#include <event.h> 12#include <init.h> 13#include <log.h> 14#include <asm/cache.h> 15#include <asm/global_data.h> 16#include <dm/device-internal.h> 17#include <dm/lists.h> 18#include <dm/uclass.h> 19#include <errno.h> 20#include <spl.h> 21#include <thermal.h> 22#include <firmware/imx/sci/sci.h> 23#include <asm/arch/sys_proto.h> 24#include <asm/arch-imx/cpu.h> 25#include <asm/armv8/cpu.h> 26#include <asm/armv8/mmu.h> 27#include <asm/setup.h> 28#include <asm/mach-imx/boot_mode.h> 29#include <power-domain.h> 30#include <elf.h> 31#include <spl.h> 32 33DECLARE_GLOBAL_DATA_PTR; 34 35#define BT_PASSOVER_TAG 0x504F 36struct pass_over_info_t *get_pass_over_info(void) 37{ 38 struct pass_over_info_t *p = 39 (struct pass_over_info_t *)PASS_OVER_INFO_ADDR; 40 41 if (p->barker != BT_PASSOVER_TAG || 42 p->len != sizeof(struct pass_over_info_t)) 43 return NULL; 44 45 return p; 46} 47 48static char *get_reset_cause(void) 49{ 50 sc_pm_reset_reason_t reason; 51 52 if (sc_pm_reset_reason(-1, &reason) != SC_ERR_NONE) 53 return "Unknown reset"; 54 55 switch (reason) { 56 case SC_PM_RESET_REASON_POR: 57 return "POR"; 58 case SC_PM_RESET_REASON_JTAG: 59 return "JTAG reset "; 60 case SC_PM_RESET_REASON_SW: 61 return "Software reset"; 62 case SC_PM_RESET_REASON_WDOG: 63 return "Watchdog reset"; 64 case SC_PM_RESET_REASON_LOCKUP: 65 return "SCU lockup reset"; 66 case SC_PM_RESET_REASON_SNVS: 67 return "SNVS reset"; 68 case SC_PM_RESET_REASON_TEMP: 69 return "Temp panic reset"; 70 case SC_PM_RESET_REASON_MSI: 71 return "MSI reset"; 72 case SC_PM_RESET_REASON_UECC: 73 return "ECC reset"; 74 case SC_PM_RESET_REASON_SCFW_WDOG: 75 return "SCFW watchdog reset"; 76 case SC_PM_RESET_REASON_ROM_WDOG: 77 return "SCU ROM watchdog reset"; 78 case SC_PM_RESET_REASON_SECO: 79 return "SECO reset"; 80 case SC_PM_RESET_REASON_SCFW_FAULT: 81 return "SCFW fault reset"; 82 default: 83 return "Unknown reset"; 84 } 85} 86 87__weak void reset_cpu(void) 88{ 89} 90 91int arch_cpu_init(void) 92{ 93#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION) 94 spl_save_restore_data(); 95#endif 96 97#ifdef CONFIG_SPL_BUILD 98 struct pass_over_info_t *pass_over; 99 100 if (is_soc_rev(CHIP_REV_A)) { 101 pass_over = get_pass_over_info(); 102 if (pass_over && pass_over->g_ap_mu == 0) { 103 /* 104 * When ap_mu is 0, means the U-Boot booted 105 * from first container 106 */ 107 sc_misc_boot_status(-1, SC_MISC_BOOT_STATUS_SUCCESS); 108 } 109 } 110#endif 111 112 return 0; 113} 114 115static int imx8_init_mu(void) 116{ 117 struct udevice *devp; 118 int node, ret; 119 120 node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8-mu"); 121 122 ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp); 123 if (ret) { 124 printf("could not get scu %d\n", ret); 125 return ret; 126 } 127 128 if (is_imx8qm()) { 129 ret = sc_pm_set_resource_power_mode(-1, SC_R_SMMU, 130 SC_PM_PW_MODE_ON); 131 if (ret) 132 return ret; 133 } 134 135 return 0; 136} 137EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_F, imx8_init_mu); 138 139#if defined(CONFIG_ARCH_MISC_INIT) 140int arch_misc_init(void) 141{ 142 if (IS_ENABLED(CONFIG_FSL_CAAM)) { 143 struct udevice *dev; 144 int ret; 145 146 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); 147 if (ret) 148 printf("Failed to initialize caam_jr: %d\n", ret); 149 } 150 151 return 0; 152} 153#endif 154 155#ifdef CONFIG_IMX_BOOTAUX 156 157#ifdef CONFIG_IMX8QM 158int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) 159{ 160 sc_rsrc_t core_rsrc, mu_rsrc; 161 sc_faddr_t tcml_addr; 162 u32 tcml_size = SZ_128K; 163 ulong addr; 164 165 switch (core_id) { 166 case 0: 167 core_rsrc = SC_R_M4_0_PID0; 168 tcml_addr = 0x34FE0000; 169 mu_rsrc = SC_R_M4_0_MU_1A; 170 break; 171 case 1: 172 core_rsrc = SC_R_M4_1_PID0; 173 tcml_addr = 0x38FE0000; 174 mu_rsrc = SC_R_M4_1_MU_1A; 175 break; 176 default: 177 printf("Not support this core boot up, ID:%u\n", core_id); 178 return -EINVAL; 179 } 180 181 addr = (sc_faddr_t)boot_private_data; 182 183 if (addr >= tcml_addr && addr <= tcml_addr + tcml_size) { 184 printf("Wrong image address 0x%lx, should not in TCML\n", 185 addr); 186 return -EINVAL; 187 } 188 189 printf("Power on M4 and MU\n"); 190 191 if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) 192 return -EIO; 193 194 if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) 195 return -EIO; 196 197 printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr); 198 199 if (addr != tcml_addr) 200 memcpy((void *)tcml_addr, (void *)addr, tcml_size); 201 202 printf("Start M4 %u\n", core_id); 203 if (sc_pm_cpu_start(-1, core_rsrc, true, tcml_addr) != SC_ERR_NONE) 204 return -EIO; 205 206 printf("bootaux complete\n"); 207 return 0; 208} 209#endif 210 211#ifdef CONFIG_IMX8QXP 212int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) 213{ 214 sc_rsrc_t core_rsrc, mu_rsrc = SC_R_NONE; 215 sc_faddr_t aux_core_ram; 216 u32 size; 217 ulong addr; 218 219 switch (core_id) { 220 case 0: 221 core_rsrc = SC_R_M4_0_PID0; 222 aux_core_ram = 0x34FE0000; 223 mu_rsrc = SC_R_M4_0_MU_1A; 224 size = SZ_128K; 225 break; 226 case 1: 227 core_rsrc = SC_R_DSP; 228 aux_core_ram = 0x596f8000; 229 size = SZ_2K; 230 break; 231 default: 232 printf("Not support this core boot up, ID:%u\n", core_id); 233 return -EINVAL; 234 } 235 236 addr = (sc_faddr_t)boot_private_data; 237 238 if (addr >= aux_core_ram && addr <= aux_core_ram + size) { 239 printf("Wrong image address 0x%lx, should not in aux core ram\n", 240 addr); 241 return -EINVAL; 242 } 243 244 printf("Power on aux core %d\n", core_id); 245 246 if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) 247 return -EIO; 248 249 if (mu_rsrc != SC_R_NONE) { 250 if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) 251 return -EIO; 252 } 253 254 if (core_id == 1) { 255 struct power_domain pd; 256 257 if (sc_pm_clock_enable(-1, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) { 258 printf("Error enable clock\n"); 259 return -EIO; 260 } 261 262 if (!power_domain_lookup_name("audio_sai0", &pd)) { 263 if (power_domain_on(&pd)) { 264 printf("Error power on SAI0\n"); 265 return -EIO; 266 } 267 } 268 269 if (!power_domain_lookup_name("audio_ocram", &pd)) { 270 if (power_domain_on(&pd)) { 271 printf("Error power on HIFI RAM\n"); 272 return -EIO; 273 } 274 } 275 } 276 277 printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram); 278 if (core_id == 0) { 279 /* M4 use bin file */ 280 memcpy((void *)aux_core_ram, (void *)addr, size); 281 } else { 282 /* HIFI use elf file */ 283 if (!valid_elf_image(addr)) 284 return -1; 285 addr = load_elf_image_shdr(addr); 286 } 287 288 printf("Start %s\n", core_id == 0 ? "M4" : "HIFI"); 289 290 if (sc_pm_cpu_start(-1, core_rsrc, true, aux_core_ram) != SC_ERR_NONE) 291 return -EIO; 292 293 printf("bootaux complete\n"); 294 return 0; 295} 296#endif 297 298int arch_auxiliary_core_check_up(u32 core_id) 299{ 300 sc_rsrc_t core_rsrc; 301 sc_pm_power_mode_t power_mode; 302 303 switch (core_id) { 304 case 0: 305 core_rsrc = SC_R_M4_0_PID0; 306 break; 307#ifdef CONFIG_IMX8QM 308 case 1: 309 core_rsrc = SC_R_M4_1_PID0; 310 break; 311#endif 312 default: 313 printf("Not support this core, ID:%u\n", core_id); 314 return 0; 315 } 316 317 if (sc_pm_get_resource_power_mode(-1, core_rsrc, &power_mode) != SC_ERR_NONE) 318 return 0; 319 320 if (power_mode != SC_PM_PW_MODE_OFF) 321 return 1; 322 323 return 0; 324} 325#endif 326 327int print_bootinfo(void) 328{ 329 enum boot_device bt_dev = get_boot_device(); 330 331 puts("Boot: "); 332 switch (bt_dev) { 333 case SD1_BOOT: 334 puts("SD0\n"); 335 break; 336 case SD2_BOOT: 337 puts("SD1\n"); 338 break; 339 case SD3_BOOT: 340 puts("SD2\n"); 341 break; 342 case MMC1_BOOT: 343 puts("MMC0\n"); 344 break; 345 case MMC2_BOOT: 346 puts("MMC1\n"); 347 break; 348 case MMC3_BOOT: 349 puts("MMC2\n"); 350 break; 351 case FLEXSPI_BOOT: 352 puts("FLEXSPI\n"); 353 break; 354 case SATA_BOOT: 355 puts("SATA\n"); 356 break; 357 case NAND_BOOT: 358 puts("NAND\n"); 359 break; 360 case USB_BOOT: 361 puts("USB\n"); 362 break; 363 default: 364 printf("Unknown device %u\n", bt_dev); 365 break; 366 } 367 368 printf("Reset cause: %s\n", get_reset_cause()); 369 370 return 0; 371} 372 373enum boot_device get_boot_device(void) 374{ 375 enum boot_device boot_dev = SD1_BOOT; 376 377 sc_rsrc_t dev_rsrc; 378 379 sc_misc_get_boot_dev(-1, &dev_rsrc); 380 381 switch (dev_rsrc) { 382 case SC_R_SDHC_0: 383 boot_dev = MMC1_BOOT; 384 break; 385 case SC_R_SDHC_1: 386 boot_dev = SD2_BOOT; 387 break; 388 case SC_R_SDHC_2: 389 boot_dev = SD3_BOOT; 390 break; 391 case SC_R_NAND: 392 boot_dev = NAND_BOOT; 393 break; 394 case SC_R_FSPI_0: 395 boot_dev = FLEXSPI_BOOT; 396 break; 397 case SC_R_SATA_0: 398 boot_dev = SATA_BOOT; 399 break; 400 case SC_R_USB_0: 401 case SC_R_USB_1: 402 case SC_R_USB_2: 403 boot_dev = USB_BOOT; 404 break; 405 default: 406 break; 407 } 408 409 return boot_dev; 410} 411 412#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 413#define FUSE_UNIQUE_ID_WORD0 16 414#define FUSE_UNIQUE_ID_WORD1 17 415void get_board_serial(struct tag_serialnr *serialnr) 416{ 417 int err; 418 u32 val1 = 0, val2 = 0; 419 u32 word1, word2; 420 421 if (!serialnr) 422 return; 423 424 word1 = FUSE_UNIQUE_ID_WORD0; 425 word2 = FUSE_UNIQUE_ID_WORD1; 426 427 err = sc_misc_otp_fuse_read(-1, word1, &val1); 428 if (err) { 429 printf("%s fuse %d read error: %d\n", __func__, word1, err); 430 return; 431 } 432 433 err = sc_misc_otp_fuse_read(-1, word2, &val2); 434 if (err) { 435 printf("%s fuse %d read error: %d\n", __func__, word2, err); 436 return; 437 } 438 serialnr->low = val1; 439 serialnr->high = val2; 440} 441#endif /*CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG*/ 442 443#ifdef CONFIG_ENV_IS_IN_MMC 444__weak int board_mmc_get_env_dev(int devno) 445{ 446 return CONFIG_SYS_MMC_ENV_DEV; 447} 448 449int mmc_get_env_dev(void) 450{ 451 sc_rsrc_t dev_rsrc; 452 int devno; 453 454 sc_misc_get_boot_dev(-1, &dev_rsrc); 455 456 switch (dev_rsrc) { 457 case SC_R_SDHC_0: 458 devno = 0; 459 break; 460 case SC_R_SDHC_1: 461 devno = 1; 462 break; 463 case SC_R_SDHC_2: 464 devno = 2; 465 break; 466 default: 467 /* If not boot from sd/mmc, use default value */ 468 return CONFIG_SYS_MMC_ENV_DEV; 469 } 470 471 return board_mmc_get_env_dev(devno); 472} 473#endif 474 475#define MEMSTART_ALIGNMENT SZ_2M /* Align the memory start with 2MB */ 476 477static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start, 478 sc_faddr_t *addr_end) 479{ 480 sc_faddr_t start, end; 481 int ret; 482 bool owned; 483 484 owned = sc_rm_is_memreg_owned(-1, mr); 485 if (owned) { 486 ret = sc_rm_get_memreg_info(-1, mr, &start, &end); 487 if (ret) { 488 printf("Memreg get info failed, %d\n", ret); 489 return -EINVAL; 490 } 491 debug("0x%llx -- 0x%llx\n", start, end); 492 *addr_start = start; 493 *addr_end = end; 494 495 return 0; 496 } 497 498 return -EINVAL; 499} 500 501__weak void board_mem_get_layout(u64 *phys_sdram_1_start, 502 u64 *phys_sdram_1_size, 503 u64 *phys_sdram_2_start, 504 u64 *phys_sdram_2_size) 505{ 506 *phys_sdram_1_start = PHYS_SDRAM_1; 507 *phys_sdram_1_size = PHYS_SDRAM_1_SIZE; 508 *phys_sdram_2_start = PHYS_SDRAM_2; 509 *phys_sdram_2_size = PHYS_SDRAM_2_SIZE; 510} 511 512phys_size_t get_effective_memsize(void) 513{ 514 sc_rm_mr_t mr; 515 sc_faddr_t start, end, end1, start_aligned; 516 u64 phys_sdram_1_start, phys_sdram_1_size; 517 u64 phys_sdram_2_start, phys_sdram_2_size; 518 int err; 519 520 board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, 521 &phys_sdram_2_start, &phys_sdram_2_size); 522 523 524 end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; 525 for (mr = 0; mr < 64; mr++) { 526 err = get_owned_memreg(mr, &start, &end); 527 if (!err) { 528 start_aligned = roundup(start, MEMSTART_ALIGNMENT); 529 /* Too small memory region, not use it */ 530 if (start_aligned > end) 531 continue; 532 533 /* Find the memory region runs the U-Boot */ 534 if (start >= phys_sdram_1_start && start <= end1 && 535 (start <= CONFIG_TEXT_BASE && 536 end >= CONFIG_TEXT_BASE)) { 537 if ((end + 1) <= 538 ((sc_faddr_t)phys_sdram_1_start + 539 phys_sdram_1_size)) 540 return (end - phys_sdram_1_start + 1); 541 else 542 return phys_sdram_1_size; 543 } 544 } 545 } 546 547 return phys_sdram_1_size; 548} 549 550int dram_init(void) 551{ 552 sc_rm_mr_t mr; 553 sc_faddr_t start, end, end1, end2; 554 u64 phys_sdram_1_start, phys_sdram_1_size; 555 u64 phys_sdram_2_start, phys_sdram_2_size; 556 int err; 557 558 board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, 559 &phys_sdram_2_start, &phys_sdram_2_size); 560 561 end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; 562 end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; 563 for (mr = 0; mr < 64; mr++) { 564 err = get_owned_memreg(mr, &start, &end); 565 if (!err) { 566 start = roundup(start, MEMSTART_ALIGNMENT); 567 /* Too small memory region, not use it */ 568 if (start > end) 569 continue; 570 571 if (start >= phys_sdram_1_start && start <= end1) { 572 if ((end + 1) <= end1) 573 gd->ram_size += end - start + 1; 574 else 575 gd->ram_size += end1 - start; 576 } else if (start >= phys_sdram_2_start && 577 start <= end2) { 578 if ((end + 1) <= end2) 579 gd->ram_size += end - start + 1; 580 else 581 gd->ram_size += end2 - start; 582 } 583 } 584 } 585 586 /* If error, set to the default value */ 587 if (!gd->ram_size) { 588 gd->ram_size = phys_sdram_1_size; 589 gd->ram_size += phys_sdram_2_size; 590 } 591 return 0; 592} 593 594static void dram_bank_sort(int current_bank) 595{ 596 phys_addr_t start; 597 phys_size_t size; 598 599 while (current_bank > 0) { 600 if (gd->bd->bi_dram[current_bank - 1].start > 601 gd->bd->bi_dram[current_bank].start) { 602 start = gd->bd->bi_dram[current_bank - 1].start; 603 size = gd->bd->bi_dram[current_bank - 1].size; 604 605 gd->bd->bi_dram[current_bank - 1].start = 606 gd->bd->bi_dram[current_bank].start; 607 gd->bd->bi_dram[current_bank - 1].size = 608 gd->bd->bi_dram[current_bank].size; 609 610 gd->bd->bi_dram[current_bank].start = start; 611 gd->bd->bi_dram[current_bank].size = size; 612 } 613 current_bank--; 614 } 615} 616 617int dram_init_banksize(void) 618{ 619 sc_rm_mr_t mr; 620 sc_faddr_t start, end, end1, end2; 621 int i = 0; 622 u64 phys_sdram_1_start, phys_sdram_1_size; 623 u64 phys_sdram_2_start, phys_sdram_2_size; 624 int err; 625 626 board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, 627 &phys_sdram_2_start, &phys_sdram_2_size); 628 629 end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; 630 end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; 631 for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) { 632 err = get_owned_memreg(mr, &start, &end); 633 if (!err) { 634 start = roundup(start, MEMSTART_ALIGNMENT); 635 if (start > end) /* Small memory region, no use it */ 636 continue; 637 638 if (start >= phys_sdram_1_start && start <= end1) { 639 gd->bd->bi_dram[i].start = start; 640 641 if ((end + 1) <= end1) 642 gd->bd->bi_dram[i].size = 643 end - start + 1; 644 else 645 gd->bd->bi_dram[i].size = end1 - start; 646 647 dram_bank_sort(i); 648 i++; 649 } else if (start >= phys_sdram_2_start && start <= end2) { 650 gd->bd->bi_dram[i].start = start; 651 652 if ((end + 1) <= end2) 653 gd->bd->bi_dram[i].size = 654 end - start + 1; 655 else 656 gd->bd->bi_dram[i].size = end2 - start; 657 658 dram_bank_sort(i); 659 i++; 660 } 661 } 662 } 663 664 /* If error, set to the default value */ 665 if (!i) { 666 gd->bd->bi_dram[0].start = phys_sdram_1_start; 667 gd->bd->bi_dram[0].size = phys_sdram_1_size; 668 gd->bd->bi_dram[1].start = phys_sdram_2_start; 669 gd->bd->bi_dram[1].size = phys_sdram_2_size; 670 } 671 672 return 0; 673} 674 675static u64 get_block_attrs(sc_faddr_t addr_start) 676{ 677 u64 attr = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | 678 PTE_BLOCK_PXN | PTE_BLOCK_UXN; 679 u64 phys_sdram_1_start, phys_sdram_1_size; 680 u64 phys_sdram_2_start, phys_sdram_2_size; 681 682 board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, 683 &phys_sdram_2_start, &phys_sdram_2_size); 684 685 if ((addr_start >= phys_sdram_1_start && 686 addr_start <= ((sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size)) || 687 (addr_start >= phys_sdram_2_start && 688 addr_start <= ((sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size))) 689 return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE); 690 691 return attr; 692} 693 694static u64 get_block_size(sc_faddr_t addr_start, sc_faddr_t addr_end) 695{ 696 sc_faddr_t end1, end2; 697 u64 phys_sdram_1_start, phys_sdram_1_size; 698 u64 phys_sdram_2_start, phys_sdram_2_size; 699 700 board_mem_get_layout(&phys_sdram_1_start, &phys_sdram_1_size, 701 &phys_sdram_2_start, &phys_sdram_2_size); 702 703 704 end1 = (sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size; 705 end2 = (sc_faddr_t)phys_sdram_2_start + phys_sdram_2_size; 706 707 if (addr_start >= phys_sdram_1_start && addr_start <= end1) { 708 if ((addr_end + 1) > end1) 709 return end1 - addr_start; 710 } else if (addr_start >= phys_sdram_2_start && addr_start <= end2) { 711 if ((addr_end + 1) > end2) 712 return end2 - addr_start; 713 } 714 715 return (addr_end - addr_start + 1); 716} 717 718#define MAX_PTE_ENTRIES 512 719#define MAX_MEM_MAP_REGIONS 16 720 721static struct mm_region imx8_mem_map[MAX_MEM_MAP_REGIONS]; 722struct mm_region *mem_map = imx8_mem_map; 723 724void enable_caches(void) 725{ 726 sc_rm_mr_t mr; 727 sc_faddr_t start, end; 728 int err, i; 729 730 /* Create map for registers access from 0x1c000000 to 0x80000000*/ 731 imx8_mem_map[0].virt = 0x1c000000UL; 732 imx8_mem_map[0].phys = 0x1c000000UL; 733 imx8_mem_map[0].size = 0x64000000UL; 734 imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 735 PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; 736 737 i = 1; 738 for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) { 739 err = get_owned_memreg(mr, &start, &end); 740 if (!err) { 741 imx8_mem_map[i].virt = start; 742 imx8_mem_map[i].phys = start; 743 imx8_mem_map[i].size = get_block_size(start, end); 744 imx8_mem_map[i].attrs = get_block_attrs(start); 745 i++; 746 } 747 } 748 749 if (i < MAX_MEM_MAP_REGIONS) { 750 imx8_mem_map[i].size = 0; 751 imx8_mem_map[i].attrs = 0; 752 } else { 753 puts("Error, need more MEM MAP REGIONS reserved\n"); 754 icache_enable(); 755 return; 756 } 757 758 for (i = 0; i < MAX_MEM_MAP_REGIONS; i++) { 759 debug("[%d] vir = 0x%llx phys = 0x%llx size = 0x%llx attrs = 0x%llx\n", 760 i, imx8_mem_map[i].virt, imx8_mem_map[i].phys, 761 imx8_mem_map[i].size, imx8_mem_map[i].attrs); 762 } 763 764 icache_enable(); 765 dcache_enable(); 766} 767 768#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) 769u64 get_page_table_size(void) 770{ 771 u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64); 772 u64 size = 0; 773 774 /* 775 * For each memory region, the max table size: 776 * 2 level 3 tables + 2 level 2 tables + 1 level 1 table 777 */ 778 size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt; 779 780 /* 781 * We need to duplicate our page table once to have an emergency pt to 782 * resort to when splitting page tables later on 783 */ 784 size *= 2; 785 786 /* 787 * We may need to split page tables later on if dcache settings change, 788 * so reserve up to 4 (random pick) page tables for that. 789 */ 790 size += one_pt * 4; 791 792 return size; 793} 794#endif 795 796#if defined(CONFIG_IMX8QM) 797#define FUSE_MAC0_WORD0 452 798#define FUSE_MAC0_WORD1 453 799#define FUSE_MAC1_WORD0 454 800#define FUSE_MAC1_WORD1 455 801#elif defined(CONFIG_IMX8QXP) 802#define FUSE_MAC0_WORD0 708 803#define FUSE_MAC0_WORD1 709 804#define FUSE_MAC1_WORD0 710 805#define FUSE_MAC1_WORD1 711 806#endif 807 808void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) 809{ 810 u32 word[2], val[2] = {}; 811 int i, ret; 812 813 if (dev_id == 0) { 814 word[0] = FUSE_MAC0_WORD0; 815 word[1] = FUSE_MAC0_WORD1; 816 } else { 817 word[0] = FUSE_MAC1_WORD0; 818 word[1] = FUSE_MAC1_WORD1; 819 } 820 821 for (i = 0; i < 2; i++) { 822 ret = sc_misc_otp_fuse_read(-1, word[i], &val[i]); 823 if (ret < 0) 824 goto err; 825 } 826 827 mac[0] = val[0]; 828 mac[1] = val[0] >> 8; 829 mac[2] = val[0] >> 16; 830 mac[3] = val[0] >> 24; 831 mac[4] = val[1]; 832 mac[5] = val[1] >> 8; 833 834 debug("%s: MAC%d: %02x.%02x.%02x.%02x.%02x.%02x\n", 835 __func__, dev_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 836 return; 837err: 838 printf("%s: fuse %d, err: %d\n", __func__, word[i], ret); 839} 840 841u32 get_cpu_rev(void) 842{ 843 u32 id = 0, rev = 0; 844 int ret; 845 846 ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id); 847 if (ret) 848 return 0; 849 850 rev = (id >> 5) & 0xf; 851 id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */ 852 853 return (id << 12) | rev; 854} 855 856void board_boot_order(u32 *spl_boot_list) 857{ 858 spl_boot_list[0] = spl_boot_device(); 859 860 if (spl_boot_list[0] == BOOT_DEVICE_SPI) { 861 /* Check whether we own the flexspi0, if not, use NOR boot */ 862 if (!sc_rm_is_resource_owned(-1, SC_R_FSPI_0)) 863 spl_boot_list[0] = BOOT_DEVICE_NOR; 864 } 865} 866 867bool m4_parts_booted(void) 868{ 869 sc_rm_pt_t m4_parts[2]; 870 int err; 871 872 err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]); 873 if (err) { 874 printf("%s get resource [%d] owner error: %d\n", __func__, 875 SC_R_M4_0_PID0, err); 876 return false; 877 } 878 879 if (sc_pm_is_partition_started(-1, m4_parts[0])) 880 return true; 881 882 if (is_imx8qm()) { 883 err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]); 884 if (err) { 885 printf("%s get resource [%d] owner error: %d\n", 886 __func__, SC_R_M4_1_PID0, err); 887 return false; 888 } 889 890 if (sc_pm_is_partition_started(-1, m4_parts[1])) 891 return true; 892 } 893 894 return false; 895} 896