uboot/arch/arm/mach-imx/imx8ulp/soc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2021 NXP
   4 */
   5
   6#include <asm/io.h>
   7#include <asm/arch/clock.h>
   8#include <asm/arch/imx-regs.h>
   9#include <asm/arch/sys_proto.h>
  10#include <asm/armv8/mmu.h>
  11#include <asm/mach-imx/boot_mode.h>
  12#include <asm/global_data.h>
  13#include <efi_loader.h>
  14#include <spl.h>
  15#include <asm/arch/rdc.h>
  16#include <asm/arch/s400_api.h>
  17#include <asm/arch/mu_hal.h>
  18#include <cpu_func.h>
  19#include <asm/setup.h>
  20#include <dm.h>
  21#include <dm/device-internal.h>
  22#include <dm/lists.h>
  23#include <dm/uclass.h>
  24#include <dm/device.h>
  25#include <dm/uclass-internal.h>
  26
  27DECLARE_GLOBAL_DATA_PTR;
  28
  29struct rom_api *g_rom_api = (struct rom_api *)0x1980;
  30
  31enum boot_device get_boot_device(void)
  32{
  33        volatile gd_t *pgd = gd;
  34        int ret;
  35        u32 boot;
  36        u16 boot_type;
  37        u8 boot_instance;
  38        enum boot_device boot_dev = SD1_BOOT;
  39
  40        ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
  41                                          ((uintptr_t)&boot) ^ QUERY_BT_DEV);
  42        set_gd(pgd);
  43
  44        if (ret != ROM_API_OKAY) {
  45                puts("ROMAPI: failure at query_boot_info\n");
  46                return -1;
  47        }
  48
  49        boot_type = boot >> 16;
  50        boot_instance = (boot >> 8) & 0xff;
  51
  52        switch (boot_type) {
  53        case BT_DEV_TYPE_SD:
  54                boot_dev = boot_instance + SD1_BOOT;
  55                break;
  56        case BT_DEV_TYPE_MMC:
  57                boot_dev = boot_instance + MMC1_BOOT;
  58                break;
  59        case BT_DEV_TYPE_NAND:
  60                boot_dev = NAND_BOOT;
  61                break;
  62        case BT_DEV_TYPE_FLEXSPINOR:
  63                boot_dev = QSPI_BOOT;
  64                break;
  65        case BT_DEV_TYPE_USB:
  66                boot_dev = USB_BOOT;
  67                break;
  68        default:
  69                break;
  70        }
  71
  72        return boot_dev;
  73}
  74
  75bool is_usb_boot(void)
  76{
  77        return get_boot_device() == USB_BOOT;
  78}
  79
  80#ifdef CONFIG_ENV_IS_IN_MMC
  81__weak int board_mmc_get_env_dev(int devno)
  82{
  83        return devno;
  84}
  85
  86int mmc_get_env_dev(void)
  87{
  88        volatile gd_t *pgd = gd;
  89        int ret;
  90        u32 boot;
  91        u16 boot_type;
  92        u8 boot_instance;
  93
  94        ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
  95                                          ((uintptr_t)&boot) ^ QUERY_BT_DEV);
  96        set_gd(pgd);
  97
  98        if (ret != ROM_API_OKAY) {
  99                puts("ROMAPI: failure at query_boot_info\n");
 100                return CONFIG_SYS_MMC_ENV_DEV;
 101        }
 102
 103        boot_type = boot >> 16;
 104        boot_instance = (boot >> 8) & 0xff;
 105
 106        /* If not boot from sd/mmc, use default value */
 107        if (boot_type != BOOT_TYPE_SD && boot_type != BOOT_TYPE_MMC)
 108                return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV);
 109
 110        return board_mmc_get_env_dev(boot_instance);
 111}
 112#endif
 113
 114u32 get_cpu_rev(void)
 115{
 116        return (MXC_CPU_IMX8ULP << 12) | CHIP_REV_1_0;
 117}
 118
 119enum bt_mode get_boot_mode(void)
 120{
 121        u32 bt0_cfg = 0;
 122
 123        bt0_cfg = readl(SIM_SEC_BASE_ADDR + 0x24);
 124        bt0_cfg &= (BT0CFG_LPBOOT_MASK | BT0CFG_DUALBOOT_MASK);
 125
 126        if (!(bt0_cfg & BT0CFG_LPBOOT_MASK)) {
 127                /* No low power boot */
 128                if (bt0_cfg & BT0CFG_DUALBOOT_MASK)
 129                        return DUAL_BOOT;
 130                else
 131                        return SINGLE_BOOT;
 132        }
 133
 134        return LOW_POWER_BOOT;
 135}
 136
 137#define CMC_SRS_TAMPER                    BIT(31)
 138#define CMC_SRS_SECURITY                  BIT(30)
 139#define CMC_SRS_TZWDG                     BIT(29)
 140#define CMC_SRS_JTAG_RST                  BIT(28)
 141#define CMC_SRS_CORE1                     BIT(16)
 142#define CMC_SRS_LOCKUP                    BIT(15)
 143#define CMC_SRS_SW                        BIT(14)
 144#define CMC_SRS_WDG                       BIT(13)
 145#define CMC_SRS_PIN_RESET                 BIT(8)
 146#define CMC_SRS_WARM                      BIT(4)
 147#define CMC_SRS_HVD                       BIT(3)
 148#define CMC_SRS_LVD                       BIT(2)
 149#define CMC_SRS_POR                       BIT(1)
 150#define CMC_SRS_WUP                       BIT(0)
 151
 152static char *get_reset_cause(char *ret)
 153{
 154        u32 cause1, cause = 0, srs = 0;
 155        void __iomem *reg_ssrs = (void __iomem *)(CMC1_BASE_ADDR + 0x88);
 156        void __iomem *reg_srs = (void __iomem *)(CMC1_BASE_ADDR + 0x80);
 157
 158        if (!ret)
 159                return "null";
 160
 161        srs = readl(reg_srs);
 162        cause1 = readl(reg_ssrs);
 163
 164        cause = srs & (CMC_SRS_POR | CMC_SRS_WUP | CMC_SRS_WARM);
 165
 166        switch (cause) {
 167        case CMC_SRS_POR:
 168                sprintf(ret, "%s", "POR");
 169                break;
 170        case CMC_SRS_WUP:
 171                sprintf(ret, "%s", "WUP");
 172                break;
 173        case CMC_SRS_WARM:
 174                cause = srs & (CMC_SRS_WDG | CMC_SRS_SW |
 175                        CMC_SRS_JTAG_RST);
 176                switch (cause) {
 177                case CMC_SRS_WDG:
 178                        sprintf(ret, "%s", "WARM-WDG");
 179                        break;
 180                case CMC_SRS_SW:
 181                        sprintf(ret, "%s", "WARM-SW");
 182                        break;
 183                case CMC_SRS_JTAG_RST:
 184                        sprintf(ret, "%s", "WARM-JTAG");
 185                        break;
 186                default:
 187                        sprintf(ret, "%s", "WARM-UNKN");
 188                        break;
 189                }
 190                break;
 191        default:
 192                sprintf(ret, "%s-%X", "UNKN", srs);
 193                break;
 194        }
 195
 196        debug("[%X] SRS[%X] %X - ", cause1, srs, srs ^ cause1);
 197        return ret;
 198}
 199
 200#if defined(CONFIG_DISPLAY_CPUINFO)
 201const char *get_imx_type(u32 imxtype)
 202{
 203        return "8ULP";
 204}
 205
 206int print_cpuinfo(void)
 207{
 208        u32 cpurev;
 209        char cause[18];
 210
 211        cpurev = get_cpu_rev();
 212
 213        printf("CPU:   Freescale i.MX%s rev%d.%d at %d MHz\n",
 214               get_imx_type((cpurev & 0xFF000) >> 12),
 215               (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0,
 216               mxc_get_clock(MXC_ARM_CLK) / 1000000);
 217
 218        printf("Reset cause: %s\n", get_reset_cause(cause));
 219
 220        printf("Boot mode: ");
 221        switch (get_boot_mode()) {
 222        case LOW_POWER_BOOT:
 223                printf("Low power boot\n");
 224                break;
 225        case DUAL_BOOT:
 226                printf("Dual boot\n");
 227                break;
 228        case SINGLE_BOOT:
 229        default:
 230                printf("Single boot\n");
 231                break;
 232        }
 233
 234        return 0;
 235}
 236#endif
 237
 238#define UNLOCK_WORD0 0xC520 /* 1st unlock word */
 239#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
 240#define REFRESH_WORD0 0xA602 /* 1st refresh word */
 241#define REFRESH_WORD1 0xB480 /* 2nd refresh word */
 242
 243static void disable_wdog(void __iomem *wdog_base)
 244{
 245        u32 val_cs = readl(wdog_base + 0x00);
 246
 247        if (!(val_cs & 0x80))
 248                return;
 249
 250        dmb();
 251        __raw_writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */
 252        __raw_writel(REFRESH_WORD1, (wdog_base + 0x04));
 253        dmb();
 254
 255        if (!(val_cs & 800)) {
 256                dmb();
 257                __raw_writel(UNLOCK_WORD0, (wdog_base + 0x04));
 258                __raw_writel(UNLOCK_WORD1, (wdog_base + 0x04));
 259                dmb();
 260
 261                while (!(readl(wdog_base + 0x00) & 0x800))
 262                        ;
 263        }
 264        writel(0x0, (wdog_base + 0x0C)); /* Set WIN to 0 */
 265        writel(0x400, (wdog_base + 0x08)); /* Set timeout to default 0x400 */
 266        writel(0x120, (wdog_base + 0x00)); /* Disable it and set update */
 267
 268        while (!(readl(wdog_base + 0x00) & 0x400))
 269                ;
 270}
 271
 272void init_wdog(void)
 273{
 274        disable_wdog((void __iomem *)WDG3_RBASE);
 275}
 276
 277static struct mm_region imx8ulp_arm64_mem_map[] = {
 278        {
 279                /* ROM */
 280                .virt = 0x0,
 281                .phys = 0x0,
 282                .size = 0x40000UL,
 283                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 284                         PTE_BLOCK_OUTER_SHARE
 285        },
 286        {
 287                /* FLEXSPI0 */
 288                .virt = 0x04000000,
 289                .phys = 0x04000000,
 290                .size = 0x08000000UL,
 291                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 292                         PTE_BLOCK_NON_SHARE |
 293                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 294        },
 295        {
 296                /* SSRAM (align with 2M) */
 297                .virt = 0x1FE00000UL,
 298                .phys = 0x1FE00000UL,
 299                .size = 0x400000UL,
 300                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 301                         PTE_BLOCK_OUTER_SHARE |
 302                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 303        }, {
 304                /* SRAM1 (align with 2M) */
 305                .virt = 0x21000000UL,
 306                .phys = 0x21000000UL,
 307                .size = 0x200000UL,
 308                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 309                         PTE_BLOCK_OUTER_SHARE |
 310                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 311        }, {
 312                /* SRAM0 (align with 2M) */
 313                .virt = 0x22000000UL,
 314                .phys = 0x22000000UL,
 315                .size = 0x200000UL,
 316                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 317                         PTE_BLOCK_OUTER_SHARE |
 318                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 319        }, {
 320                /* Peripherals */
 321                .virt = 0x27000000UL,
 322                .phys = 0x27000000UL,
 323                .size = 0x3000000UL,
 324                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 325                         PTE_BLOCK_NON_SHARE |
 326                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 327        }, {
 328                /* Peripherals */
 329                .virt = 0x2D000000UL,
 330                .phys = 0x2D000000UL,
 331                .size = 0x1600000UL,
 332                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 333                         PTE_BLOCK_NON_SHARE |
 334                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 335        }, {
 336                /* FLEXSPI1-2 */
 337                .virt = 0x40000000UL,
 338                .phys = 0x40000000UL,
 339                .size = 0x40000000UL,
 340                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 341                         PTE_BLOCK_NON_SHARE |
 342                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 343        }, {
 344                /* DRAM1 */
 345                .virt = 0x80000000UL,
 346                .phys = 0x80000000UL,
 347                .size = PHYS_SDRAM_SIZE,
 348                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 349                         PTE_BLOCK_OUTER_SHARE
 350        }, {
 351                /*
 352                 * empty entrie to split table entry 5
 353                 * if needed when TEEs are used
 354                 */
 355                0,
 356        }, {
 357                /* List terminator */
 358                0,
 359        }
 360};
 361
 362struct mm_region *mem_map = imx8ulp_arm64_mem_map;
 363
 364/* simplify the page table size to enhance boot speed */
 365#define MAX_PTE_ENTRIES         512
 366#define MAX_MEM_MAP_REGIONS     16
 367u64 get_page_table_size(void)
 368{
 369        u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
 370        u64 size = 0;
 371
 372        /*
 373         * For each memory region, the max table size:
 374         * 2 level 3 tables + 2 level 2 tables + 1 level 1 table
 375         */
 376        size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt;
 377
 378        /*
 379         * We need to duplicate our page table once to have an emergency pt to
 380         * resort to when splitting page tables later on
 381         */
 382        size *= 2;
 383
 384        /*
 385         * We may need to split page tables later on if dcache settings change,
 386         * so reserve up to 4 (random pick) page tables for that.
 387         */
 388        size += one_pt * 4;
 389
 390        return size;
 391}
 392
 393void enable_caches(void)
 394{
 395        /* TODO: add TEE memmap region */
 396
 397        icache_enable();
 398        dcache_enable();
 399}
 400
 401int dram_init(void)
 402{
 403        gd->ram_size = PHYS_SDRAM_SIZE;
 404
 405        return 0;
 406}
 407
 408#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 409void get_board_serial(struct tag_serialnr *serialnr)
 410{
 411        u32 uid[4];
 412        u32 res;
 413        int ret;
 414
 415        ret = ahab_read_common_fuse(1, uid, 4, &res);
 416        if (ret)
 417                printf("ahab read fuse failed %d, 0x%x\n", ret, res);
 418        else
 419                printf("UID 0x%x,0x%x,0x%x,0x%x\n", uid[0], uid[1], uid[2], uid[3]);
 420
 421        serialnr->low = uid[0];
 422        serialnr->high = uid[3];
 423}
 424#endif
 425
 426static void set_core0_reset_vector(u32 entry)
 427{
 428        /* Update SIM1 DGO8 for reset vector base */
 429        writel(entry, SIM1_BASE_ADDR + 0x5c);
 430
 431        /* set update bit */
 432        setbits_le32(SIM1_BASE_ADDR + 0x8, 0x1 << 24);
 433
 434        /* polling the ack */
 435        while ((readl(SIM1_BASE_ADDR + 0x8) & (0x1 << 26)) == 0)
 436                ;
 437
 438        /* clear the update */
 439        clrbits_le32(SIM1_BASE_ADDR + 0x8, (0x1 << 24));
 440
 441        /* clear the ack by set 1 */
 442        setbits_le32(SIM1_BASE_ADDR + 0x8, (0x1 << 26));
 443}
 444
 445static int trdc_set_access(void)
 446{
 447        /*
 448         * TRDC mgr + 4 MBC + 2 MRC.
 449         * S400 should already configure when release RDC
 450         * A35 only map non-secure region for pbridge0 and 1, set sec_access to false
 451         */
 452        trdc_mbc_set_access(2, 7, 0, 49, false);
 453        trdc_mbc_set_access(2, 7, 0, 50, false);
 454        trdc_mbc_set_access(2, 7, 0, 51, false);
 455        trdc_mbc_set_access(2, 7, 0, 52, false);
 456        trdc_mbc_set_access(2, 7, 0, 53, false);
 457        trdc_mbc_set_access(2, 7, 0, 54, false);
 458
 459        /* CGC0: PBridge0 slot 47 */
 460        trdc_mbc_set_access(2, 7, 0, 47, false);
 461
 462        /* Iomuxc0: : PBridge1 slot 33 */
 463        trdc_mbc_set_access(2, 7, 1, 33, false);
 464
 465        return 0;
 466}
 467
 468int arch_cpu_init(void)
 469{
 470        if (IS_ENABLED(CONFIG_SPL_BUILD)) {
 471                /* Disable wdog */
 472                init_wdog();
 473
 474                if (get_boot_mode() == SINGLE_BOOT) {
 475                        release_rdc(RDC_TRDC);
 476                        trdc_set_access();
 477                        /* LPAV to APD */
 478                        setbits_le32(0x2802B044, BIT(7));
 479                        /* GPU 2D/3D to APD */
 480                        setbits_le32(0x2802B04C, BIT(1) | BIT(2));
 481                        /* DCNANO and MIPI_DSI to APD */
 482                        setbits_le32(0x2802B04C, BIT(1) | BIT(2) | BIT(3) | BIT(4));
 483                }
 484
 485                /* release xrdc, then allow A35 to write SRAM2 */
 486                release_rdc(RDC_XRDC);
 487                xrdc_mrc_region_set_access(2, CONFIG_SPL_TEXT_BASE, 0xE00);
 488
 489                clock_init();
 490        } else {
 491                /* reconfigure core0 reset vector to ROM */
 492                set_core0_reset_vector(0x1000);
 493        }
 494
 495        return 0;
 496}
 497
 498int arch_cpu_init_dm(void)
 499{
 500        struct udevice *devp;
 501        int node, ret;
 502
 503        node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8ulp-mu");
 504
 505        ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp);
 506        if (ret) {
 507                printf("could not get S400 mu %d\n", ret);
 508                return ret;
 509        }
 510
 511        return 0;
 512}
 513
 514#if defined(CONFIG_SPL_BUILD)
 515__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 516{
 517        debug("image entry point: 0x%lx\n", spl_image->entry_point);
 518
 519        set_core0_reset_vector((u32)spl_image->entry_point);
 520
 521        /* Enable the 512KB cache */
 522        setbits_le32(SIM1_BASE_ADDR + 0x30, (0x1 << 4));
 523
 524        /* reset core */
 525        setbits_le32(SIM1_BASE_ADDR + 0x30, (0x1 << 16));
 526
 527        while (1)
 528                ;
 529}
 530#endif
 531
 532void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 533{
 534        memset(mac, 0, 6);
 535}
 536
 537int (*card_emmc_is_boot_part_en)(void) = (void *)0x67cc;
 538u32 spl_arch_boot_image_offset(u32 image_offset, u32 rom_bt_dev)
 539{
 540        /* Hard code for eMMC image_offset on 8ULP ROM, need fix by ROM, temp workaround */
 541        if (((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_MMC && card_emmc_is_boot_part_en())
 542                image_offset = 0;
 543
 544        return image_offset;
 545}
 546