uboot/arch/arm/mach-imx/imx8m/soc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2017-2019, 2021 NXP
   4 *
   5 * Peng Fan <peng.fan@nxp.com>
   6 */
   7
   8#include <common.h>
   9#include <cpu_func.h>
  10#include <event.h>
  11#include <init.h>
  12#include <log.h>
  13#include <asm/arch/imx-regs.h>
  14#include <asm/global_data.h>
  15#include <asm/io.h>
  16#include <asm/arch/clock.h>
  17#include <asm/arch/sys_proto.h>
  18#include <asm/mach-imx/hab.h>
  19#include <asm/mach-imx/boot_mode.h>
  20#include <asm/mach-imx/syscounter.h>
  21#include <asm/ptrace.h>
  22#include <asm/armv8/mmu.h>
  23#include <dm/uclass.h>
  24#include <dm/device.h>
  25#include <efi_loader.h>
  26#include <env.h>
  27#include <env_internal.h>
  28#include <errno.h>
  29#include <fdt_support.h>
  30#include <fsl_wdog.h>
  31#include <imx_sip.h>
  32#include <linux/bitops.h>
  33
  34DECLARE_GLOBAL_DATA_PTR;
  35
  36#if defined(CONFIG_IMX_HAB)
  37struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
  38        .bank = 1,
  39        .word = 3,
  40};
  41#endif
  42
  43int timer_init(void)
  44{
  45#ifdef CONFIG_SPL_BUILD
  46        struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR;
  47        unsigned long freq = readl(&sctr->cntfid0);
  48
  49        /* Update with accurate clock frequency */
  50        asm volatile("msr cntfrq_el0, %0" : : "r" (freq) : "memory");
  51
  52        clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1,
  53                        SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG);
  54#endif
  55
  56        gd->arch.tbl = 0;
  57        gd->arch.tbu = 0;
  58
  59        return 0;
  60}
  61
  62void enable_tzc380(void)
  63{
  64        struct iomuxc_gpr_base_regs *gpr =
  65                (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
  66
  67        /* Enable TZASC and lock setting */
  68        setbits_le32(&gpr->gpr[10], GPR_TZASC_EN);
  69        setbits_le32(&gpr->gpr[10], GPR_TZASC_EN_LOCK);
  70
  71        /*
  72         * According to TRM, TZASC_ID_SWAP_BYPASS should be set in
  73         * order to avoid AXI Bus errors when GPU is in use
  74         */
  75        setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS);
  76
  77        /*
  78         * imx8mn and imx8mp implements the lock bit for
  79         * TZASC_ID_SWAP_BYPASS, enable it to lock settings
  80         */
  81        setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS_LOCK);
  82
  83        /*
  84         * set Region 0 attribute to allow secure and non-secure
  85         * read/write permission. Found some masters like usb dwc3
  86         * controllers can't work with secure memory.
  87         */
  88        writel(0xf0000000, TZASC_BASE_ADDR + 0x108);
  89}
  90
  91void set_wdog_reset(struct wdog_regs *wdog)
  92{
  93        /*
  94         * Output WDOG_B signal to reset external pmic or POR_B decided by
  95         * the board design. Without external reset, the peripherals/DDR/
  96         * PMIC are not reset, that may cause system working abnormal.
  97         * WDZST bit is write-once only bit. Align this bit in kernel,
  98         * otherwise kernel code will have no chance to set this bit.
  99         */
 100        setbits_le16(&wdog->wcr, WDOG_WDT_MASK | WDOG_WDZST_MASK);
 101}
 102
 103static struct mm_region imx8m_mem_map[] = {
 104        {
 105                /* ROM */
 106                .virt = 0x0UL,
 107                .phys = 0x0UL,
 108                .size = 0x100000UL,
 109                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 110                         PTE_BLOCK_OUTER_SHARE
 111        }, {
 112                /* CAAM */
 113                .virt = 0x100000UL,
 114                .phys = 0x100000UL,
 115                .size = 0x8000UL,
 116                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 117                         PTE_BLOCK_NON_SHARE |
 118                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 119        }, {
 120                /* OCRAM_S */
 121                .virt = 0x180000UL,
 122                .phys = 0x180000UL,
 123                .size = 0x8000UL,
 124                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 125                         PTE_BLOCK_OUTER_SHARE
 126        }, {
 127                /* TCM */
 128                .virt = 0x7C0000UL,
 129                .phys = 0x7C0000UL,
 130                .size = 0x80000UL,
 131                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 132                         PTE_BLOCK_NON_SHARE |
 133                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 134        }, {
 135                /* OCRAM */
 136                .virt = 0x900000UL,
 137                .phys = 0x900000UL,
 138                .size = 0x200000UL,
 139                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 140                         PTE_BLOCK_OUTER_SHARE
 141        }, {
 142                /* AIPS */
 143                .virt = 0xB00000UL,
 144                .phys = 0xB00000UL,
 145                .size = 0x3f500000UL,
 146                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 147                         PTE_BLOCK_NON_SHARE |
 148                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
 149        }, {
 150                /* DRAM1 */
 151                .virt = 0x40000000UL,
 152                .phys = 0x40000000UL,
 153                .size = PHYS_SDRAM_SIZE,
 154                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 155                         PTE_BLOCK_OUTER_SHARE
 156#ifdef PHYS_SDRAM_2_SIZE
 157        }, {
 158                /* DRAM2 */
 159                .virt = 0x100000000UL,
 160                .phys = 0x100000000UL,
 161                .size = PHYS_SDRAM_2_SIZE,
 162                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 163                         PTE_BLOCK_OUTER_SHARE
 164#endif
 165        }, {
 166                /* empty entrie to split table entry 5 if needed when TEEs are used */
 167                0,
 168        }, {
 169                /* List terminator */
 170                0,
 171        }
 172};
 173
 174struct mm_region *mem_map = imx8m_mem_map;
 175
 176static unsigned int imx8m_find_dram_entry_in_mem_map(void)
 177{
 178        int i;
 179
 180        for (i = 0; i < ARRAY_SIZE(imx8m_mem_map); i++)
 181                if (imx8m_mem_map[i].phys == CONFIG_SYS_SDRAM_BASE)
 182                        return i;
 183
 184        hang(); /* Entry not found, this must never happen. */
 185}
 186
 187void enable_caches(void)
 188{
 189        /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch
 190         * If OPTEE does not run, still update the MMU table according to dram banks structure
 191         * to set correct dram size from board_phys_sdram_size
 192         */
 193        int i = 0;
 194        /*
 195         * please make sure that entry initial value matches
 196         * imx8m_mem_map for DRAM1
 197         */
 198        int entry = imx8m_find_dram_entry_in_mem_map();
 199        u64 attrs = imx8m_mem_map[entry].attrs;
 200
 201        while (i < CONFIG_NR_DRAM_BANKS &&
 202               entry < ARRAY_SIZE(imx8m_mem_map)) {
 203                if (gd->bd->bi_dram[i].start == 0)
 204                        break;
 205                imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start;
 206                imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start;
 207                imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size;
 208                imx8m_mem_map[entry].attrs = attrs;
 209                debug("Added memory mapping (%d): %llx %llx\n", entry,
 210                      imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size);
 211                i++; entry++;
 212        }
 213
 214        icache_enable();
 215        dcache_enable();
 216}
 217
 218__weak int board_phys_sdram_size(phys_size_t *size)
 219{
 220        if (!size)
 221                return -EINVAL;
 222
 223        *size = PHYS_SDRAM_SIZE;
 224
 225#ifdef PHYS_SDRAM_2_SIZE
 226        *size += PHYS_SDRAM_2_SIZE;
 227#endif
 228        return 0;
 229}
 230
 231int dram_init(void)
 232{
 233        phys_size_t sdram_size;
 234        int ret;
 235
 236        ret = board_phys_sdram_size(&sdram_size);
 237        if (ret)
 238                return ret;
 239
 240        /* rom_pointer[1] contains the size of TEE occupies */
 241        if (rom_pointer[1])
 242                gd->ram_size = sdram_size - rom_pointer[1];
 243        else
 244                gd->ram_size = sdram_size;
 245
 246        return 0;
 247}
 248
 249int dram_init_banksize(void)
 250{
 251        int bank = 0;
 252        int ret;
 253        phys_size_t sdram_size;
 254        phys_size_t sdram_b1_size, sdram_b2_size;
 255
 256        ret = board_phys_sdram_size(&sdram_size);
 257        if (ret)
 258                return ret;
 259
 260        /* Bank 1 can't cross over 4GB space */
 261        if (sdram_size > 0xc0000000) {
 262                sdram_b1_size = 0xc0000000;
 263                sdram_b2_size = sdram_size - 0xc0000000;
 264        } else {
 265                sdram_b1_size = sdram_size;
 266                sdram_b2_size = 0;
 267        }
 268
 269        gd->bd->bi_dram[bank].start = PHYS_SDRAM;
 270        if (rom_pointer[1]) {
 271                phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
 272                phys_size_t optee_size = (size_t)rom_pointer[1];
 273
 274                gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
 275                if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) {
 276                        if (++bank >= CONFIG_NR_DRAM_BANKS) {
 277                                puts("CONFIG_NR_DRAM_BANKS is not enough\n");
 278                                return -1;
 279                        }
 280
 281                        gd->bd->bi_dram[bank].start = optee_start + optee_size;
 282                        gd->bd->bi_dram[bank].size = PHYS_SDRAM +
 283                                sdram_b1_size - gd->bd->bi_dram[bank].start;
 284                }
 285        } else {
 286                gd->bd->bi_dram[bank].size = sdram_b1_size;
 287        }
 288
 289        if (sdram_b2_size) {
 290                if (++bank >= CONFIG_NR_DRAM_BANKS) {
 291                        puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
 292                        return -1;
 293                }
 294                gd->bd->bi_dram[bank].start = 0x100000000UL;
 295                gd->bd->bi_dram[bank].size = sdram_b2_size;
 296        }
 297
 298        return 0;
 299}
 300
 301phys_size_t get_effective_memsize(void)
 302{
 303        int ret;
 304        phys_size_t sdram_size;
 305        phys_size_t sdram_b1_size;
 306        ret = board_phys_sdram_size(&sdram_size);
 307        if (!ret) {
 308                /* Bank 1 can't cross over 4GB space */
 309                if (sdram_size > 0xc0000000) {
 310                        sdram_b1_size = 0xc0000000;
 311                } else {
 312                        sdram_b1_size = sdram_size;
 313                }
 314
 315                if (rom_pointer[1]) {
 316                        /* We will relocate u-boot to Top of dram1. Tee position has two cases:
 317                         * 1. At the top of dram1,  Then return the size removed optee size.
 318                         * 2. In the middle of dram1, return the size of dram1.
 319                         */
 320                        if ((rom_pointer[0] + rom_pointer[1]) == (PHYS_SDRAM + sdram_b1_size))
 321                                return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
 322                }
 323
 324                return sdram_b1_size;
 325        } else {
 326                return PHYS_SDRAM_SIZE;
 327        }
 328}
 329
 330ulong board_get_usable_ram_top(ulong total_size)
 331{
 332        ulong top_addr;
 333
 334        /*
 335         * Some IPs have their accessible address space restricted by
 336         * the interconnect. Let's make sure U-Boot only ever uses the
 337         * space below the 4G address boundary (which is 3GiB big),
 338         * even when the effective available memory is bigger.
 339         */
 340        top_addr = clamp_val((u64)PHYS_SDRAM + gd->ram_size, 0, 0xffffffff);
 341
 342        /*
 343         * rom_pointer[0] stores the TEE memory start address.
 344         * rom_pointer[1] stores the size TEE uses.
 345         * We need to reserve the memory region for TEE.
 346         */
 347        if (rom_pointer[0] && rom_pointer[1] && top_addr > rom_pointer[0])
 348                top_addr = rom_pointer[0];
 349
 350        return top_addr;
 351}
 352
 353static u32 get_cpu_variant_type(u32 type)
 354{
 355        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 356        struct fuse_bank *bank = &ocotp->bank[1];
 357        struct fuse_bank1_regs *fuse =
 358                (struct fuse_bank1_regs *)bank->fuse_regs;
 359
 360        u32 value = readl(&fuse->tester4);
 361
 362        if (type == MXC_CPU_IMX8MQ) {
 363                if ((value & 0x3) == 0x2)
 364                        return MXC_CPU_IMX8MD;
 365                else if (value & 0x200000)
 366                        return MXC_CPU_IMX8MQL;
 367
 368        } else if (type == MXC_CPU_IMX8MM) {
 369                switch (value & 0x3) {
 370                case 2:
 371                        if (value & 0x1c0000)
 372                                return MXC_CPU_IMX8MMDL;
 373                        else
 374                                return MXC_CPU_IMX8MMD;
 375                case 3:
 376                        if (value & 0x1c0000)
 377                                return MXC_CPU_IMX8MMSL;
 378                        else
 379                                return MXC_CPU_IMX8MMS;
 380                default:
 381                        if (value & 0x1c0000)
 382                                return MXC_CPU_IMX8MML;
 383                        break;
 384                }
 385        } else if (type == MXC_CPU_IMX8MN) {
 386                switch (value & 0x3) {
 387                case 2:
 388                        if (value & 0x1000000) {
 389                                if (value & 0x10000000)  /* MIPI DSI */
 390                                        return MXC_CPU_IMX8MNUD;
 391                                else
 392                                        return MXC_CPU_IMX8MNDL;
 393                        } else {
 394                                return MXC_CPU_IMX8MND;
 395                        }
 396                case 3:
 397                        if (value & 0x1000000) {
 398                                if (value & 0x10000000)  /* MIPI DSI */
 399                                        return MXC_CPU_IMX8MNUS;
 400                                else
 401                                        return MXC_CPU_IMX8MNSL;
 402                        } else {
 403                                return MXC_CPU_IMX8MNS;
 404                        }
 405                default:
 406                        if (value & 0x1000000) {
 407                                if (value & 0x10000000)  /* MIPI DSI */
 408                                        return MXC_CPU_IMX8MNUQ;
 409                                else
 410                                        return MXC_CPU_IMX8MNL;
 411                        }
 412                        break;
 413                }
 414        } else if (type == MXC_CPU_IMX8MP) {
 415                u32 value0 = readl(&fuse->tester3);
 416                u32 flag = 0;
 417
 418                if ((value0 & 0xc0000) == 0x80000)
 419                        return MXC_CPU_IMX8MPD;
 420
 421                        /* vpu disabled */
 422                if ((value0 & 0x43000000) == 0x43000000)
 423                        flag = 1;
 424
 425                /* npu disabled*/
 426                if ((value & 0x8) == 0x8)
 427                        flag |= BIT(1);
 428
 429                /* isp disabled */
 430                if ((value & 0x3) == 0x3)
 431                        flag |= BIT(2);
 432
 433                /* gpu disabled */
 434                if ((value & 0xc0) == 0xc0)
 435                        flag |= BIT(3);
 436
 437                /* lvds disabled */
 438                if ((value & 0x180000) == 0x180000)
 439                        flag |= BIT(4);
 440
 441                /* mipi dsi disabled */
 442                if ((value & 0x60000) == 0x60000)
 443                        flag |= BIT(5);
 444
 445                switch (flag) {
 446                case 0x3f:
 447                        return MXC_CPU_IMX8MPUL;
 448                case 7:
 449                        return MXC_CPU_IMX8MPL;
 450                case 2:
 451                        return MXC_CPU_IMX8MP6;
 452                default:
 453                        break;
 454                }
 455
 456        }
 457
 458        return type;
 459}
 460
 461u32 get_cpu_rev(void)
 462{
 463        struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
 464        u32 reg = readl(&ana_pll->digprog);
 465        u32 type = (reg >> 16) & 0xff;
 466        u32 major_low = (reg >> 8) & 0xff;
 467        u32 rom_version;
 468
 469        reg &= 0xff;
 470
 471        /* iMX8MP */
 472        if (major_low == 0x43) {
 473                type = get_cpu_variant_type(MXC_CPU_IMX8MP);
 474        } else if (major_low == 0x42) {
 475                /* iMX8MN */
 476                type = get_cpu_variant_type(MXC_CPU_IMX8MN);
 477        } else if (major_low == 0x41) {
 478                type = get_cpu_variant_type(MXC_CPU_IMX8MM);
 479        } else {
 480                if (reg == CHIP_REV_1_0) {
 481                        /*
 482                         * For B0 chip, the DIGPROG is not updated,
 483                         * it is still TO1.0. we have to check ROM
 484                         * version or OCOTP_READ_FUSE_DATA.
 485                         * 0xff0055aa is magic number for B1.
 486                         */
 487                        if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) {
 488                                /*
 489                                 * B2 uses same DIGPROG and OCOTP_READ_FUSE_DATA value with B1,
 490                                 * so have to check ROM to distinguish them
 491                                 */
 492                                rom_version = readl((void __iomem *)ROM_VERSION_B0);
 493                                rom_version &= 0xff;
 494                                if (rom_version == CHIP_REV_2_2)
 495                                        reg = CHIP_REV_2_2;
 496                                else
 497                                        reg = CHIP_REV_2_1;
 498                        } else {
 499                                rom_version =
 500                                        readl((void __iomem *)ROM_VERSION_A0);
 501                                if (rom_version != CHIP_REV_1_0) {
 502                                        rom_version = readl((void __iomem *)ROM_VERSION_B0);
 503                                        rom_version &= 0xff;
 504                                        if (rom_version == CHIP_REV_2_0)
 505                                                reg = CHIP_REV_2_0;
 506                                }
 507                        }
 508                }
 509
 510                type = get_cpu_variant_type(type);
 511        }
 512
 513        return (type << 12) | reg;
 514}
 515
 516static void imx_set_wdog_powerdown(bool enable)
 517{
 518        struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
 519        struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR;
 520        struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR;
 521
 522        /* Write to the PDE (Power Down Enable) bit */
 523        writew(enable, &wdog1->wmcr);
 524        writew(enable, &wdog2->wmcr);
 525        writew(enable, &wdog3->wmcr);
 526}
 527
 528static int imx8m_check_clock(void *ctx, struct event *event)
 529{
 530        struct udevice *dev;
 531        int ret;
 532
 533        if (CONFIG_IS_ENABLED(CLK)) {
 534                ret = uclass_get_device_by_name(UCLASS_CLK,
 535                                                "clock-controller@30380000",
 536                                                &dev);
 537                if (ret < 0) {
 538                        printf("Failed to find clock node. Check device tree\n");
 539                        return ret;
 540                }
 541        }
 542
 543        return 0;
 544}
 545EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock);
 546
 547int arch_cpu_init(void)
 548{
 549        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 550
 551#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
 552        icache_enable();
 553#endif
 554
 555        /*
 556         * ROM might disable clock for SCTR,
 557         * enable the clock before timer_init.
 558         */
 559        if (IS_ENABLED(CONFIG_SPL_BUILD))
 560                clock_enable(CCGR_SCTR, 1);
 561        /*
 562         * Init timer at very early state, because sscg pll setting
 563         * will use it
 564         */
 565        timer_init();
 566
 567        if (IS_ENABLED(CONFIG_SPL_BUILD)) {
 568                clock_init();
 569                imx_set_wdog_powerdown(false);
 570
 571                if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() ||
 572                    is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() ||
 573                    is_imx8mnsl() || is_imx8mpd() || is_imx8mnud() || is_imx8mnus()) {
 574                        /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */
 575                        struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840);
 576                        struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880);
 577                        struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0);
 578                        struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR;
 579
 580                        writel(0x1, &pgc_core2->pgcr);
 581                        writel(0x1, &pgc_core3->pgcr);
 582                        if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) {
 583                                writel(0x1, &pgc_core1->pgcr);
 584                                writel(0xE, &gpc->cpu_pgc_dn_trg);
 585                        } else {
 586                                writel(0xC, &gpc->cpu_pgc_dn_trg);
 587                        }
 588                }
 589        }
 590
 591        if (is_imx8mq()) {
 592                clock_enable(CCGR_OCOTP, 1);
 593                if (readl(&ocotp->ctrl) & 0x200)
 594                        writel(0x200, &ocotp->ctrl_clr);
 595        }
 596
 597        return 0;
 598}
 599
 600#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
 601struct rom_api *g_rom_api = (struct rom_api *)0x980;
 602
 603enum boot_device get_boot_device(void)
 604{
 605        volatile gd_t *pgd = gd;
 606        int ret;
 607        u32 boot;
 608        u16 boot_type;
 609        u8 boot_instance;
 610        enum boot_device boot_dev = SD1_BOOT;
 611
 612        ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
 613                                          ((uintptr_t)&boot) ^ QUERY_BT_DEV);
 614        set_gd(pgd);
 615
 616        if (ret != ROM_API_OKAY) {
 617                puts("ROMAPI: failure at query_boot_info\n");
 618                return -1;
 619        }
 620
 621        boot_type = boot >> 16;
 622        boot_instance = (boot >> 8) & 0xff;
 623
 624        switch (boot_type) {
 625        case BT_DEV_TYPE_SD:
 626                boot_dev = boot_instance + SD1_BOOT;
 627                break;
 628        case BT_DEV_TYPE_MMC:
 629                boot_dev = boot_instance + MMC1_BOOT;
 630                break;
 631        case BT_DEV_TYPE_NAND:
 632                boot_dev = NAND_BOOT;
 633                break;
 634        case BT_DEV_TYPE_FLEXSPINOR:
 635                boot_dev = QSPI_BOOT;
 636                break;
 637        case BT_DEV_TYPE_SPI_NOR:
 638                boot_dev = SPI_NOR_BOOT;
 639                break;
 640        case BT_DEV_TYPE_USB:
 641                boot_dev = USB_BOOT;
 642                break;
 643        default:
 644                break;
 645        }
 646
 647        return boot_dev;
 648}
 649#endif
 650
 651#if defined(CONFIG_IMX8M)
 652#include <spl.h>
 653int spl_mmc_emmc_boot_partition(struct mmc *mmc)
 654{
 655        u32 *rom_log_addr = (u32 *)0x9e0;
 656        u32 *rom_log;
 657        u8 event_id;
 658        int i, part;
 659
 660        part = default_spl_mmc_emmc_boot_partition(mmc);
 661
 662        /* If the ROM event log pointer is not valid. */
 663        if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xb00000 ||
 664            *rom_log_addr & 0x3)
 665                return part;
 666
 667        /* Parse the ROM event ID version 2 log */
 668        rom_log = (u32 *)(uintptr_t)(*rom_log_addr);
 669        for (i = 0; i < 128; i++) {
 670                event_id = rom_log[i] >> 24;
 671                switch (event_id) {
 672                case 0x00: /* End of list */
 673                        return part;
 674                /* Log entries with 1 parameter, skip 1 */
 675                case 0x80: /* Start to perform the device initialization */
 676                case 0x81: /* The boot device initialization completes */
 677                case 0x8f: /* The boot device initialization fails */
 678                case 0x90: /* Start to read data from boot device */
 679                case 0x91: /* Reading data from boot device completes */
 680                case 0x9f: /* Reading data from boot device fails */
 681                        i += 1;
 682                        continue;
 683                /* Log entries with 2 parameters, skip 2 */
 684                case 0xa0: /* Image authentication result */
 685                case 0xc0: /* Jump to the boot image soon */
 686                        i += 2;
 687                        continue;
 688                /* Boot from the secondary boot image */
 689                case 0x51:
 690                        /*
 691                         * Swap the eMMC boot partitions in case there was a
 692                         * fallback event (i.e. primary image was corrupted
 693                         * and that corruption was recognized by the BootROM),
 694                         * so the SPL loads the rest of the U-Boot from the
 695                         * correct eMMC boot partition, since the BootROM
 696                         * leaves the boot partition set to the corrupted one.
 697                         */
 698                        if (part == 1)
 699                                part = 2;
 700                        else if (part == 2)
 701                                part = 1;
 702                        continue;
 703                default:
 704                        continue;
 705                }
 706        }
 707
 708        return part;
 709}
 710#endif
 711
 712bool is_usb_boot(void)
 713{
 714        return get_boot_device() == USB_BOOT;
 715}
 716
 717#ifdef CONFIG_OF_SYSTEM_SETUP
 718bool check_fdt_new_path(void *blob)
 719{
 720        const char *soc_path = "/soc@0";
 721        int nodeoff;
 722
 723        nodeoff = fdt_path_offset(blob, soc_path);
 724        if (nodeoff < 0)
 725                return false;
 726
 727        return true;
 728}
 729
 730static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
 731{
 732        int i = 0;
 733        int rc;
 734        int nodeoff;
 735        const char *status = "disabled";
 736
 737        for (i = 0; i < size_array; i++) {
 738                nodeoff = fdt_path_offset(blob, nodes_path[i]);
 739                if (nodeoff < 0)
 740                        continue; /* Not found, skip it */
 741
 742                printf("Found %s node\n", nodes_path[i]);
 743
 744add_status:
 745                rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
 746                if (rc) {
 747                        if (rc == -FDT_ERR_NOSPACE) {
 748                                rc = fdt_increase_size(blob, 512);
 749                                if (!rc)
 750                                        goto add_status;
 751                        }
 752                        printf("Unable to update property %s:%s, err=%s\n",
 753                               nodes_path[i], "status", fdt_strerror(rc));
 754                } else {
 755                        printf("Modify %s:%s disabled\n",
 756                               nodes_path[i], "status");
 757                }
 758        }
 759
 760        return 0;
 761}
 762
 763#ifdef CONFIG_IMX8MQ
 764bool check_dcss_fused(void)
 765{
 766        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 767        struct fuse_bank *bank = &ocotp->bank[1];
 768        struct fuse_bank1_regs *fuse =
 769                (struct fuse_bank1_regs *)bank->fuse_regs;
 770        u32 value = readl(&fuse->tester4);
 771
 772        if (value & 0x4000000)
 773                return true;
 774
 775        return false;
 776}
 777
 778static int disable_mipi_dsi_nodes(void *blob)
 779{
 780        static const char * const nodes_path[] = {
 781                "/mipi_dsi@30A00000",
 782                "/mipi_dsi_bridge@30A00000",
 783                "/dsi_phy@30A00300",
 784                "/soc@0/bus@30800000/mipi_dsi@30a00000",
 785                "/soc@0/bus@30800000/dphy@30a00300",
 786                "/soc@0/bus@30800000/mipi-dsi@30a00000",
 787        };
 788
 789        return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
 790}
 791
 792static int disable_dcss_nodes(void *blob)
 793{
 794        static const char * const nodes_path[] = {
 795                "/dcss@0x32e00000",
 796                "/dcss@32e00000",
 797                "/hdmi@32c00000",
 798                "/hdmi_cec@32c33800",
 799                "/hdmi_drm@32c00000",
 800                "/display-subsystem",
 801                "/sound-hdmi",
 802                "/sound-hdmi-arc",
 803                "/soc@0/bus@32c00000/display-controller@32e00000",
 804                "/soc@0/bus@32c00000/hdmi@32c00000",
 805        };
 806
 807        return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
 808}
 809
 810static int check_mipi_dsi_nodes(void *blob)
 811{
 812        static const char * const lcdif_path[] = {
 813                "/lcdif@30320000",
 814                "/soc@0/bus@30000000/lcdif@30320000",
 815                "/soc@0/bus@30000000/lcd-controller@30320000"
 816        };
 817        static const char * const mipi_dsi_path[] = {
 818                "/mipi_dsi@30A00000",
 819                "/soc@0/bus@30800000/mipi_dsi@30a00000"
 820        };
 821        static const char * const lcdif_ep_path[] = {
 822                "/lcdif@30320000/port@0/mipi-dsi-endpoint",
 823                "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint",
 824                "/soc@0/bus@30000000/lcd-controller@30320000/port@0/endpoint"
 825        };
 826        static const char * const mipi_dsi_ep_path[] = {
 827                "/mipi_dsi@30A00000/port@1/endpoint",
 828                "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint",
 829                "/soc@0/bus@30800000/mipi-dsi@30a00000/ports/port@0/endpoint@0"
 830        };
 831
 832        int lookup_node;
 833        int nodeoff;
 834        bool new_path = check_fdt_new_path(blob);
 835        int i = new_path ? 1 : 0;
 836
 837        nodeoff = fdt_path_offset(blob, lcdif_path[i]);
 838        if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
 839                /*
 840                 * If can't find lcdif node or lcdif node is disabled,
 841                 * then disable all mipi dsi, since they only can input
 842                 * from DCSS
 843                 */
 844                return disable_mipi_dsi_nodes(blob);
 845        }
 846
 847        nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
 848        if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
 849                return 0;
 850
 851        nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
 852        if (nodeoff < 0) {
 853                /*
 854                 * If can't find lcdif endpoint, then disable all mipi dsi,
 855                 * since they only can input from DCSS
 856                 */
 857                return disable_mipi_dsi_nodes(blob);
 858        }
 859
 860        lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
 861        nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
 862
 863        if (nodeoff > 0 && nodeoff == lookup_node)
 864                return 0;
 865
 866        return disable_mipi_dsi_nodes(blob);
 867}
 868#endif
 869
 870int disable_vpu_nodes(void *blob)
 871{
 872        static const char * const nodes_path_8mq[] = {
 873                "/vpu@38300000",
 874                "/soc@0/vpu@38300000"
 875        };
 876
 877        static const char * const nodes_path_8mm[] = {
 878                "/vpu_g1@38300000",
 879                "/vpu_g2@38310000",
 880                "/vpu_h1@38320000"
 881        };
 882
 883        static const char * const nodes_path_8mp[] = {
 884                "/vpu_g1@38300000",
 885                "/vpu_g2@38310000",
 886                "/vpu_vc8000e@38320000"
 887        };
 888
 889        if (is_imx8mq())
 890                return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
 891        else if (is_imx8mm())
 892                return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
 893        else if (is_imx8mp())
 894                return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
 895        else
 896                return -EPERM;
 897}
 898
 899#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
 900static int low_drive_gpu_freq(void *blob)
 901{
 902        static const char *nodes_path_8mn[] = {
 903                "/gpu@38000000",
 904                "/soc@0/gpu@38000000"
 905        };
 906
 907        int nodeoff, cnt, i;
 908        u32 assignedclks[7];
 909
 910        nodeoff = fdt_path_offset(blob, nodes_path_8mn[0]);
 911        if (nodeoff < 0)
 912                return nodeoff;
 913
 914        cnt = fdtdec_get_int_array_count(blob, nodeoff, "assigned-clock-rates", assignedclks, 7);
 915        if (cnt < 0)
 916                return cnt;
 917
 918        if (cnt != 7)
 919                printf("Warning: %s, assigned-clock-rates count %d\n", nodes_path_8mn[0], cnt);
 920
 921        assignedclks[cnt - 1] = 200000000;
 922        assignedclks[cnt - 2] = 200000000;
 923
 924        for (i = 0; i < cnt; i++) {
 925                debug("<%u>, ", assignedclks[i]);
 926                assignedclks[i] = cpu_to_fdt32(assignedclks[i]);
 927        }
 928        debug("\n");
 929
 930        return fdt_setprop(blob, nodeoff, "assigned-clock-rates", &assignedclks, sizeof(assignedclks));
 931}
 932#endif
 933
 934static bool check_remote_endpoint(void *blob, const char *ep1, const char *ep2)
 935{
 936        int lookup_node;
 937        int nodeoff;
 938
 939        nodeoff = fdt_path_offset(blob, ep1);
 940        if (nodeoff) {
 941                lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
 942                nodeoff = fdt_path_offset(blob, ep2);
 943
 944                if (nodeoff > 0 && nodeoff == lookup_node)
 945                        return true;
 946        }
 947
 948        return false;
 949}
 950
 951int disable_dsi_lcdif_nodes(void *blob)
 952{
 953        int ret;
 954
 955        static const char * const dsi_path_8mp[] = {
 956                "/soc@0/bus@32c00000/mipi_dsi@32e60000"
 957        };
 958
 959        static const char * const lcdif_path_8mp[] = {
 960                "/soc@0/bus@32c00000/lcd-controller@32e80000"
 961        };
 962
 963        static const char * const lcdif_ep_path_8mp[] = {
 964                "/soc@0/bus@32c00000/lcd-controller@32e80000/port@0/endpoint"
 965        };
 966        static const char * const dsi_ep_path_8mp[] = {
 967                "/soc@0/bus@32c00000/mipi_dsi@32e60000/port@0/endpoint"
 968        };
 969
 970        ret = disable_fdt_nodes(blob, dsi_path_8mp, ARRAY_SIZE(dsi_path_8mp));
 971        if (ret)
 972                return ret;
 973
 974        if (check_remote_endpoint(blob, dsi_ep_path_8mp[0], lcdif_ep_path_8mp[0])) {
 975                /* Disable lcdif node */
 976                return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
 977        }
 978
 979        return 0;
 980}
 981
 982int disable_lvds_lcdif_nodes(void *blob)
 983{
 984        int ret, i;
 985
 986        static const char * const ldb_path_8mp[] = {
 987                "/soc@0/bus@32c00000/ldb@32ec005c",
 988                "/soc@0/bus@32c00000/phy@32ec0128"
 989        };
 990
 991        static const char * const lcdif_path_8mp[] = {
 992                "/soc@0/bus@32c00000/lcd-controller@32e90000"
 993        };
 994
 995        static const char * const lcdif_ep_path_8mp[] = {
 996                "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@0",
 997                "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@1"
 998        };
 999        static const char * const ldb_ep_path_8mp[] = {
1000                "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@0/port@0/endpoint",
1001                "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@1/port@0/endpoint"
1002        };
1003
1004        ret = disable_fdt_nodes(blob, ldb_path_8mp, ARRAY_SIZE(ldb_path_8mp));
1005        if (ret)
1006                return ret;
1007
1008        for (i = 0; i < ARRAY_SIZE(ldb_ep_path_8mp); i++) {
1009                if (check_remote_endpoint(blob, ldb_ep_path_8mp[i], lcdif_ep_path_8mp[i])) {
1010                        /* Disable lcdif node */
1011                        return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
1012                }
1013        }
1014
1015        return 0;
1016}
1017
1018int disable_gpu_nodes(void *blob)
1019{
1020        static const char * const nodes_path_8mn[] = {
1021                "/gpu@38000000",
1022                "/soc@/gpu@38000000"
1023        };
1024
1025        static const char * const nodes_path_8mp[] = {
1026                "/gpu3d@38000000",
1027                "/gpu2d@38008000"
1028        };
1029
1030        if (is_imx8mp())
1031                return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1032        else
1033                return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
1034}
1035
1036int disable_npu_nodes(void *blob)
1037{
1038        static const char * const nodes_path_8mp[] = {
1039                "/vipsi@38500000"
1040        };
1041
1042        return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1043}
1044
1045int disable_isp_nodes(void *blob)
1046{
1047        static const char * const nodes_path_8mp[] = {
1048                "/soc@0/bus@32c00000/camera/isp@32e10000",
1049                "/soc@0/bus@32c00000/camera/isp@32e20000"
1050        };
1051
1052        return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1053}
1054
1055int disable_dsp_nodes(void *blob)
1056{
1057        static const char * const nodes_path_8mp[] = {
1058                "/dsp@3b6e8000"
1059        };
1060
1061        return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1062}
1063
1064static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores)
1065{
1066        static const char * const thermal_path[] = {
1067                "/thermal-zones/cpu-thermal/cooling-maps/map0"
1068        };
1069
1070        int nodeoff, cnt, i, ret, j;
1071        u32 cooling_dev[12];
1072
1073        for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
1074                nodeoff = fdt_path_offset(blob, thermal_path[i]);
1075                if (nodeoff < 0)
1076                        continue; /* Not found, skip it */
1077
1078                cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12);
1079                if (cnt < 0)
1080                        continue;
1081
1082                if (cnt != 12)
1083                        printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt);
1084
1085                for (j = 0; j < cnt; j++)
1086                        cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
1087
1088                ret = fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev,
1089                                  sizeof(u32) * (12 - disabled_cores * 3));
1090                if (ret < 0) {
1091                        printf("Warning: %s, cooling-device setprop failed %d\n",
1092                               thermal_path[i], ret);
1093                        continue;
1094                }
1095
1096                printf("Update node %s, cooling-device prop\n", thermal_path[i]);
1097        }
1098}
1099
1100static void disable_pmu_cpu_nodes(void *blob, u32 disabled_cores)
1101{
1102        static const char * const pmu_path[] = {
1103                "/pmu"
1104        };
1105
1106        int nodeoff, cnt, i, ret, j;
1107        u32 irq_affinity[4];
1108
1109        for (i = 0; i < ARRAY_SIZE(pmu_path); i++) {
1110                nodeoff = fdt_path_offset(blob, pmu_path[i]);
1111                if (nodeoff < 0)
1112                        continue; /* Not found, skip it */
1113
1114                cnt = fdtdec_get_int_array_count(blob, nodeoff, "interrupt-affinity",
1115                                                 irq_affinity, 4);
1116                if (cnt < 0)
1117                        continue;
1118
1119                if (cnt != 4)
1120                        printf("Warning: %s, interrupt-affinity count %d\n", pmu_path[i], cnt);
1121
1122                for (j = 0; j < cnt; j++)
1123                        irq_affinity[j] = cpu_to_fdt32(irq_affinity[j]);
1124
1125                ret = fdt_setprop(blob, nodeoff, "interrupt-affinity", &irq_affinity,
1126                                 sizeof(u32) * (4 - disabled_cores));
1127                if (ret < 0) {
1128                        printf("Warning: %s, interrupt-affinity setprop failed %d\n",
1129                               pmu_path[i], ret);
1130                        continue;
1131                }
1132
1133                printf("Update node %s, interrupt-affinity prop\n", pmu_path[i]);
1134        }
1135}
1136
1137static int disable_cpu_nodes(void *blob, u32 disabled_cores)
1138{
1139        static const char * const nodes_path[] = {
1140                "/cpus/cpu@1",
1141                "/cpus/cpu@2",
1142                "/cpus/cpu@3",
1143        };
1144        u32 i = 0;
1145        int rc;
1146        int nodeoff;
1147
1148        if (disabled_cores > 3)
1149                return -EINVAL;
1150
1151        i = 3 - disabled_cores;
1152
1153        for (; i < 3; i++) {
1154                nodeoff = fdt_path_offset(blob, nodes_path[i]);
1155                if (nodeoff < 0)
1156                        continue; /* Not found, skip it */
1157
1158                debug("Found %s node\n", nodes_path[i]);
1159
1160                rc = fdt_del_node(blob, nodeoff);
1161                if (rc < 0) {
1162                        printf("Unable to delete node %s, err=%s\n",
1163                               nodes_path[i], fdt_strerror(rc));
1164                } else {
1165                        printf("Delete node %s\n", nodes_path[i]);
1166                }
1167        }
1168
1169        disable_thermal_cpu_nodes(blob, disabled_cores);
1170        disable_pmu_cpu_nodes(blob, disabled_cores);
1171
1172        return 0;
1173}
1174
1175static int cleanup_nodes_for_efi(void *blob)
1176{
1177        static const char * const path[][2] = {
1178                { "/soc@0/bus@32c00000/usb@32e40000", "extcon" },
1179                { "/soc@0/bus@32c00000/usb@32e50000", "extcon" },
1180                { "/soc@0/bus@30800000/ethernet@30be0000", "phy-reset-gpios" },
1181                { "/soc@0/bus@30800000/ethernet@30bf0000", "phy-reset-gpios" }
1182        };
1183        int nodeoff, i, rc;
1184
1185        for (i = 0; i < ARRAY_SIZE(path); i++) {
1186                nodeoff = fdt_path_offset(blob, path[i][0]);
1187                if (nodeoff < 0)
1188                        continue; /* Not found, skip it */
1189                debug("Found %s node\n", path[i][0]);
1190
1191                rc = fdt_delprop(blob, nodeoff, path[i][1]);
1192                if (rc == -FDT_ERR_NOTFOUND)
1193                        continue;
1194                if (rc) {
1195                        printf("Unable to update property %s:%s, err=%s\n",
1196                               path[i][0], path[i][1], fdt_strerror(rc));
1197                        return rc;
1198                }
1199
1200                printf("Remove %s:%s\n", path[i][0], path[i][1]);
1201        }
1202
1203        return 0;
1204}
1205
1206static int fixup_thermal_trips(void *blob, const char *name)
1207{
1208        int minc, maxc;
1209        int node, trip;
1210
1211        node = fdt_path_offset(blob, "/thermal-zones");
1212        if (node < 0)
1213                return node;
1214
1215        node = fdt_subnode_offset(blob, node, name);
1216        if (node < 0)
1217                return node;
1218
1219        node = fdt_subnode_offset(blob, node, "trips");
1220        if (node < 0)
1221                return node;
1222
1223        get_cpu_temp_grade(&minc, &maxc);
1224
1225        fdt_for_each_subnode(trip, blob, node) {
1226                const char *type;
1227                int temp, ret;
1228
1229                type = fdt_getprop(blob, trip, "type", NULL);
1230                if (!type)
1231                        continue;
1232
1233                temp = 0;
1234                if (!strcmp(type, "critical"))
1235                        temp = 1000 * maxc;
1236                else if (!strcmp(type, "passive"))
1237                        temp = 1000 * (maxc - 10);
1238                if (temp) {
1239                        ret = fdt_setprop_u32(blob, trip, "temperature", temp);
1240                        if (ret)
1241                                return ret;
1242                }
1243        }
1244
1245        return 0;
1246}
1247
1248int ft_system_setup(void *blob, struct bd_info *bd)
1249{
1250#ifdef CONFIG_IMX8MQ
1251        int i = 0;
1252        int rc;
1253        int nodeoff;
1254
1255        if (get_boot_device() == USB_BOOT) {
1256                disable_dcss_nodes(blob);
1257
1258                bool new_path = check_fdt_new_path(blob);
1259                int v = new_path ? 1 : 0;
1260                static const char * const usb_dwc3_path[] = {
1261                        "/usb@38100000/dwc3",
1262                        "/soc@0/usb@38100000"
1263                };
1264
1265                nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
1266                if (nodeoff >= 0) {
1267                        const char *speed = "high-speed";
1268
1269                        printf("Found %s node\n", usb_dwc3_path[v]);
1270
1271usb_modify_speed:
1272
1273                        rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
1274                        if (rc) {
1275                                if (rc == -FDT_ERR_NOSPACE) {
1276                                        rc = fdt_increase_size(blob, 512);
1277                                        if (!rc)
1278                                                goto usb_modify_speed;
1279                                }
1280                                printf("Unable to set property %s:%s, err=%s\n",
1281                                       usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
1282                        } else {
1283                                printf("Modify %s:%s = %s\n",
1284                                       usb_dwc3_path[v], "maximum-speed", speed);
1285                        }
1286                } else {
1287                        printf("Can't found %s node\n", usb_dwc3_path[v]);
1288                }
1289        }
1290
1291        /* Disable the CPU idle for A0 chip since the HW does not support it */
1292        if (is_soc_rev(CHIP_REV_1_0)) {
1293                static const char * const nodes_path[] = {
1294                        "/cpus/cpu@0",
1295                        "/cpus/cpu@1",
1296                        "/cpus/cpu@2",
1297                        "/cpus/cpu@3",
1298                };
1299
1300                for (i = 0; i < ARRAY_SIZE(nodes_path); i++) {
1301                        nodeoff = fdt_path_offset(blob, nodes_path[i]);
1302                        if (nodeoff < 0)
1303                                continue; /* Not found, skip it */
1304
1305                        debug("Found %s node\n", nodes_path[i]);
1306
1307                        rc = fdt_delprop(blob, nodeoff, "cpu-idle-states");
1308                        if (rc == -FDT_ERR_NOTFOUND)
1309                                continue;
1310                        if (rc) {
1311                                printf("Unable to update property %s:%s, err=%s\n",
1312                                       nodes_path[i], "status", fdt_strerror(rc));
1313                                return rc;
1314                        }
1315
1316                        debug("Remove %s:%s\n", nodes_path[i],
1317                               "cpu-idle-states");
1318                }
1319        }
1320
1321        if (is_imx8mql()) {
1322                disable_vpu_nodes(blob);
1323                if (check_dcss_fused()) {
1324                        printf("DCSS is fused\n");
1325                        disable_dcss_nodes(blob);
1326                        check_mipi_dsi_nodes(blob);
1327                }
1328        }
1329
1330        if (is_imx8md())
1331                disable_cpu_nodes(blob, 2);
1332
1333#elif defined(CONFIG_IMX8MM)
1334        if (is_imx8mml() || is_imx8mmdl() ||  is_imx8mmsl())
1335                disable_vpu_nodes(blob);
1336
1337        if (is_imx8mmd() || is_imx8mmdl())
1338                disable_cpu_nodes(blob, 2);
1339        else if (is_imx8mms() || is_imx8mmsl())
1340                disable_cpu_nodes(blob, 3);
1341
1342#elif defined(CONFIG_IMX8MN)
1343        if (is_imx8mnl() || is_imx8mndl() ||  is_imx8mnsl())
1344                disable_gpu_nodes(blob);
1345#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
1346        else {
1347                int ldm_gpu = low_drive_gpu_freq(blob);
1348
1349                if (ldm_gpu < 0)
1350                        printf("Update GPU node assigned-clock-rates failed\n");
1351                else
1352                        printf("Update GPU node assigned-clock-rates ok\n");
1353        }
1354#endif
1355
1356        if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud())
1357                disable_cpu_nodes(blob, 2);
1358        else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus())
1359                disable_cpu_nodes(blob, 3);
1360
1361#elif defined(CONFIG_IMX8MP)
1362        if (is_imx8mpul()) {
1363                /* Disable GPU */
1364                disable_gpu_nodes(blob);
1365
1366                /* Disable DSI */
1367                disable_dsi_lcdif_nodes(blob);
1368
1369                /* Disable LVDS */
1370                disable_lvds_lcdif_nodes(blob);
1371        }
1372
1373        if (is_imx8mpul() || is_imx8mpl())
1374                disable_vpu_nodes(blob);
1375
1376        if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
1377                disable_npu_nodes(blob);
1378
1379        if (is_imx8mpul() || is_imx8mpl())
1380                disable_isp_nodes(blob);
1381
1382        if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
1383                disable_dsp_nodes(blob);
1384
1385        if (is_imx8mpd())
1386                disable_cpu_nodes(blob, 2);
1387#endif
1388
1389        cleanup_nodes_for_efi(blob);
1390
1391        if (fixup_thermal_trips(blob, "cpu-thermal"))
1392                printf("Failed to update cpu-thermal trip(s)");
1393        if (IS_ENABLED(CONFIG_IMX8MP) &&
1394            fixup_thermal_trips(blob, "soc-thermal"))
1395                printf("Failed to update soc-thermal trip(s)");
1396
1397        return 0;
1398}
1399#endif
1400
1401#ifdef CONFIG_OF_BOARD_FIXUP
1402#ifndef CONFIG_SPL_BUILD
1403int board_fix_fdt(void *fdt)
1404{
1405        if (is_imx8mpul()) {
1406                int i = 0;
1407                int nodeoff, ret;
1408                const char *status = "disabled";
1409                static const char * const dsi_nodes[] = {
1410                        "/soc@0/bus@32c00000/mipi_dsi@32e60000",
1411                        "/soc@0/bus@32c00000/lcd-controller@32e80000",
1412                        "/dsi-host"
1413                };
1414
1415                for (i = 0; i < ARRAY_SIZE(dsi_nodes); i++) {
1416                        nodeoff = fdt_path_offset(fdt, dsi_nodes[i]);
1417                        if (nodeoff > 0) {
1418set_status:
1419                                ret = fdt_setprop(fdt, nodeoff, "status", status,
1420                                                  strlen(status) + 1);
1421                                if (ret == -FDT_ERR_NOSPACE) {
1422                                        ret = fdt_increase_size(fdt, 512);
1423                                        if (!ret)
1424                                                goto set_status;
1425                                }
1426                        }
1427                }
1428        }
1429
1430        return 0;
1431}
1432#endif
1433#endif
1434
1435#if !CONFIG_IS_ENABLED(SYSRESET)
1436void reset_cpu(void)
1437{
1438        struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
1439
1440        /* Clear WDA to trigger WDOG_B immediately */
1441        writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr);
1442
1443        while (1) {
1444                /*
1445                 * spin for .5 seconds before reset
1446                 */
1447        }
1448}
1449#endif
1450
1451#if defined(CONFIG_ARCH_MISC_INIT)
1452int arch_misc_init(void)
1453{
1454        if (IS_ENABLED(CONFIG_FSL_CAAM)) {
1455                struct udevice *dev;
1456                int ret;
1457
1458                ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
1459                if (ret)
1460                        printf("Failed to initialize caam_jr: %d\n", ret);
1461        }
1462
1463        return 0;
1464}
1465#endif
1466
1467void imx_tmu_arch_init(void *reg_base)
1468{
1469        if (is_imx8mm() || is_imx8mn()) {
1470                /* Load TCALIV and TASR from fuses */
1471                struct ocotp_regs *ocotp =
1472                        (struct ocotp_regs *)OCOTP_BASE_ADDR;
1473                struct fuse_bank *bank = &ocotp->bank[3];
1474                struct fuse_bank3_regs *fuse =
1475                        (struct fuse_bank3_regs *)bank->fuse_regs;
1476
1477                u32 tca_rt, tca_hr, tca_en;
1478                u32 buf_vref, buf_slope;
1479
1480                tca_rt = fuse->ana0 & 0xFF;
1481                tca_hr = (fuse->ana0 & 0xFF00) >> 8;
1482                tca_en = (fuse->ana0 & 0x2000000) >> 25;
1483
1484                buf_vref = (fuse->ana0 & 0x1F00000) >> 20;
1485                buf_slope = (fuse->ana0 & 0xF0000) >> 16;
1486
1487                writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1488                writel((tca_en << 31) | (tca_hr << 16) | tca_rt,
1489                       (ulong)reg_base + 0x30);
1490        }
1491#ifdef CONFIG_IMX8MP
1492        /* Load TCALIV0/1/m40 and TRIM from fuses */
1493        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
1494        struct fuse_bank *bank = &ocotp->bank[38];
1495        struct fuse_bank38_regs *fuse =
1496                (struct fuse_bank38_regs *)bank->fuse_regs;
1497        struct fuse_bank *bank2 = &ocotp->bank[39];
1498        struct fuse_bank39_regs *fuse2 =
1499                (struct fuse_bank39_regs *)bank2->fuse_regs;
1500        u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr;
1501        u32 reg;
1502        u32 tca40[2], tca25[2], tca105[2];
1503
1504        /* For blank sample */
1505        if (!fuse->ana_trim2 && !fuse->ana_trim3 &&
1506            !fuse->ana_trim4 && !fuse2->ana_trim5) {
1507                /* Use a default 25C binary codes */
1508                tca25[0] = 1596;
1509                tca25[1] = 1596;
1510                writel(tca25[0], (ulong)reg_base + 0x30);
1511                writel(tca25[1], (ulong)reg_base + 0x34);
1512                return;
1513        }
1514
1515        buf_vref = (fuse->ana_trim2 & 0xc0) >> 6;
1516        buf_slope = (fuse->ana_trim2 & 0xF00) >> 8;
1517        bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12;
1518        bgr = (fuse->ana_trim2 & 0xF0000) >> 16;
1519        vlsb = (fuse->ana_trim2 & 0xF00000) >> 20;
1520        writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1521
1522        reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | (1 << 7);
1523        writel(reg, (ulong)reg_base + 0x3c);
1524
1525        tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16;
1526        tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28;
1527        tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4);
1528        tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8;
1529        tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20;
1530        tca25[1] = fuse2->ana_trim5 & 0xFFF;
1531        tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12;
1532
1533        /* use 25c for 1p calibration */
1534        writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30);
1535        writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34);
1536        writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
1537#endif
1538}
1539
1540#if defined(CONFIG_SPL_BUILD)
1541#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
1542bool serror_need_skip = true;
1543
1544void do_error(struct pt_regs *pt_regs)
1545{
1546        /*
1547         * If stack is still in ROM reserved OCRAM not switch to SPL,
1548         * it is the ROM SError
1549         */
1550        ulong sp;
1551
1552        asm volatile("mov %0, sp" : "=r"(sp) : );
1553
1554        if (serror_need_skip && sp < 0x910000 && sp >= 0x900000) {
1555                /* Check for ERR050342, imx8mq HDCP enabled parts */
1556                if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
1557                        serror_need_skip = false;
1558                        return; /* Do nothing skip the SError in ROM */
1559                }
1560
1561                /* Check for ERR050350, field return mode for imx8mq, mm and mn */
1562                if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
1563                        serror_need_skip = false;
1564                        return; /* Do nothing skip the SError in ROM */
1565                }
1566        }
1567
1568        efi_restore_gd();
1569        printf("\"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
1570        show_regs(pt_regs);
1571        panic("Resetting CPU ...\n");
1572}
1573#endif
1574#endif
1575
1576#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
1577enum env_location arch_env_get_location(enum env_operation op, int prio)
1578{
1579        enum boot_device dev = get_boot_device();
1580
1581        if (prio)
1582                return ENVL_UNKNOWN;
1583
1584        switch (dev) {
1585        case USB_BOOT:
1586                if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
1587                        return ENVL_SPI_FLASH;
1588                if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
1589                        return ENVL_NAND;
1590                if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
1591                        return ENVL_MMC;
1592                if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE))
1593                        return ENVL_NOWHERE;
1594                return ENVL_UNKNOWN;
1595        case QSPI_BOOT:
1596        case SPI_NOR_BOOT:
1597                if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
1598                        return ENVL_SPI_FLASH;
1599                return ENVL_NOWHERE;
1600        case NAND_BOOT:
1601                if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
1602                        return ENVL_NAND;
1603                return ENVL_NOWHERE;
1604        case SD1_BOOT:
1605        case SD2_BOOT:
1606        case SD3_BOOT:
1607        case MMC1_BOOT:
1608        case MMC2_BOOT:
1609        case MMC3_BOOT:
1610                if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
1611                        return ENVL_MMC;
1612                else if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
1613                        return ENVL_EXT4;
1614                else if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
1615                        return ENVL_FAT;
1616                return ENVL_NOWHERE;
1617        default:
1618                return ENVL_NOWHERE;
1619        }
1620}
1621
1622#endif
1623
1624#ifdef CONFIG_IMX_BOOTAUX
1625const struct rproc_att hostmap[] = {
1626        /* aux core , host core,  size */
1627        { 0x00000000, 0x007e0000, 0x00020000 },
1628        /* OCRAM_S */
1629        { 0x00180000, 0x00180000, 0x00008000 },
1630        /* OCRAM */
1631        { 0x00900000, 0x00900000, 0x00020000 },
1632        /* OCRAM */
1633        { 0x00920000, 0x00920000, 0x00020000 },
1634        /* QSPI Code - alias */
1635        { 0x08000000, 0x08000000, 0x08000000 },
1636        /* DDR (Code) - alias */
1637        { 0x10000000, 0x80000000, 0x0FFE0000 },
1638        /* TCML */
1639        { 0x1FFE0000, 0x007E0000, 0x00040000 },
1640        /* OCRAM_S */
1641        { 0x20180000, 0x00180000, 0x00008000 },
1642        /* OCRAM */
1643        { 0x20200000, 0x00900000, 0x00040000 },
1644        /* DDR (Data) */
1645        { 0x40000000, 0x40000000, 0x80000000 },
1646        { /* sentinel */ }
1647};
1648#endif
1649