uboot/board/xilinx/zynqmp/zynqmp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2014 - 2015 Xilinx, Inc.
   4 * Michal Simek <michal.simek@xilinx.com>
   5 */
   6
   7#include <common.h>
   8#include <command.h>
   9#include <cpu_func.h>
  10#include <debug_uart.h>
  11#include <dfu.h>
  12#include <env.h>
  13#include <env_internal.h>
  14#include <init.h>
  15#include <log.h>
  16#include <net.h>
  17#include <sata.h>
  18#include <ahci.h>
  19#include <scsi.h>
  20#include <soc.h>
  21#include <malloc.h>
  22#include <memalign.h>
  23#include <wdt.h>
  24#include <asm/arch/clk.h>
  25#include <asm/arch/hardware.h>
  26#include <asm/arch/sys_proto.h>
  27#include <asm/arch/psu_init_gpl.h>
  28#include <asm/cache.h>
  29#include <asm/global_data.h>
  30#include <asm/io.h>
  31#include <asm/ptrace.h>
  32#include <dm/device.h>
  33#include <dm/uclass.h>
  34#include <usb.h>
  35#include <dwc3-uboot.h>
  36#include <zynqmppl.h>
  37#include <zynqmp_firmware.h>
  38#include <g_dnl.h>
  39#include <linux/bitops.h>
  40#include <linux/delay.h>
  41#include <linux/sizes.h>
  42#include "../common/board.h"
  43
  44#include "pm_cfg_obj.h"
  45
  46DECLARE_GLOBAL_DATA_PTR;
  47
  48#if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
  49static xilinx_desc zynqmppl = {
  50        xilinx_zynqmp, csu_dma, 1, &zynqmp_op, 0, &zynqmp_op, NULL,
  51        ZYNQMP_FPGA_FLAGS
  52};
  53#endif
  54
  55int __maybe_unused psu_uboot_init(void)
  56{
  57        int ret;
  58
  59        ret = psu_init();
  60        if (ret)
  61                return ret;
  62
  63        /*
  64         * PS_SYSMON_ANALOG_BUS register determines mapping between SysMon
  65         * supply sense channel to SysMon supply registers inside the IP.
  66         * This register must be programmed to complete SysMon IP
  67         * configuration. The default register configuration after
  68         * power-up is incorrect. Hence, fix this by writing the
  69         * correct value - 0x3210.
  70         */
  71        writel(ZYNQMP_PS_SYSMON_ANALOG_BUS_VAL,
  72               ZYNQMP_AMS_PS_SYSMON_ANALOG_BUS);
  73
  74        /* Delay is required for clocks to be propagated */
  75        udelay(1000000);
  76        
  77        return 0;
  78}
  79
  80#if !defined(CONFIG_SPL_BUILD)
  81# if defined(CONFIG_DEBUG_UART_BOARD_INIT)
  82void board_debug_uart_init(void)
  83{
  84#  if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
  85        psu_uboot_init();
  86#  endif
  87}
  88# endif
  89
  90# if defined(CONFIG_BOARD_EARLY_INIT_F)
  91int board_early_init_f(void)
  92{
  93        int ret = 0;
  94#  if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) && !defined(CONFIG_DEBUG_UART_BOARD_INIT)
  95        ret = psu_uboot_init();
  96#  endif
  97        return ret;
  98}
  99# endif
 100#endif
 101
 102static int multi_boot(void)
 103{
 104        u32 multiboot = 0;
 105        int ret;
 106
 107        ret = zynqmp_mmio_read((ulong)&csu_base->multi_boot, &multiboot);
 108        if (ret)
 109                return -EINVAL;
 110
 111        return multiboot;
 112}
 113
 114#if defined(CONFIG_SPL_BUILD)
 115static void restore_jtag(void)
 116{
 117        if (current_el() != 3)
 118                return;
 119
 120        writel(CSU_JTAG_SEC_GATE_DISABLE, &csu_base->jtag_sec);
 121        writel(CSU_JTAG_DAP_ENABLE_DEBUG, &csu_base->jtag_dap_cfg);
 122        writel(CSU_JTAG_CHAIN_WR_SETUP, &csu_base->jtag_chain_status_wr);
 123        writel(CRLAPB_DBG_LPD_CTRL_SETUP_CLK, &crlapb_base->dbg_lpd_ctrl);
 124        writel(CRLAPB_RST_LPD_DBG_RESET, &crlapb_base->rst_lpd_dbg);
 125        writel(CSU_PCAP_PROG_RELEASE_PL, &csu_base->pcap_prog);
 126}
 127#endif
 128
 129static void print_secure_boot(void)
 130{
 131        u32 status = 0;
 132
 133        if (zynqmp_mmio_read((ulong)&csu_base->status, &status))
 134                return;
 135
 136        printf("Secure Boot:\t%sauthenticated, %sencrypted\n",
 137               status & ZYNQMP_CSU_STATUS_AUTHENTICATED ? "" : "not ",
 138               status & ZYNQMP_CSU_STATUS_ENCRYPTED ? "" : "not ");
 139}
 140
 141int board_init(void)
 142{
 143#if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
 144        struct udevice *soc;
 145        char name[SOC_MAX_STR_SIZE];
 146        int ret;
 147#endif
 148
 149#if defined(CONFIG_SPL_BUILD)
 150        /* Check *at build time* if the filename is an non-empty string */
 151        if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
 152                zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
 153                                                zynqmp_pm_cfg_obj_size);
 154#endif
 155
 156#if defined(CONFIG_ZYNQMP_FIRMWARE)
 157        struct udevice *dev;
 158
 159        uclass_get_device_by_name(UCLASS_FIRMWARE, "zynqmp-power", &dev);
 160        if (!dev)
 161                panic("PMU Firmware device not found - Enable it");
 162#endif
 163
 164#if defined(CONFIG_SPL_BUILD)
 165        printf("Silicon version:\t%d\n", zynqmp_get_silicon_version());
 166
 167        /* the CSU disables the JTAG interface when secure boot is enabled */
 168        if (CONFIG_IS_ENABLED(ZYNQMP_RESTORE_JTAG))
 169                restore_jtag();
 170#else
 171        if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
 172                xilinx_read_eeprom();
 173#endif
 174
 175        printf("EL Level:\tEL%d\n", current_el());
 176
 177#if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
 178        ret = soc_get(&soc);
 179        if (!ret) {
 180                ret = soc_get_machine(soc, name, sizeof(name));
 181                if (ret >= 0) {
 182                        zynqmppl.name = strdup(name);
 183                        fpga_init();
 184                        fpga_add(fpga_xilinx, &zynqmppl);
 185                }
 186        }
 187#endif
 188
 189        /* display secure boot information */
 190        print_secure_boot();
 191        if (current_el() == 3)
 192                printf("Multiboot:\t%d\n", multi_boot());
 193
 194        return 0;
 195}
 196
 197int board_early_init_r(void)
 198{
 199        u32 val;
 200
 201        if (current_el() != 3)
 202                return 0;
 203
 204        val = readl(&crlapb_base->timestamp_ref_ctrl);
 205        val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
 206
 207        if (!val) {
 208                val = readl(&crlapb_base->timestamp_ref_ctrl);
 209                val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
 210                writel(val, &crlapb_base->timestamp_ref_ctrl);
 211
 212                /* Program freq register in System counter */
 213                writel(zynqmp_get_system_timer_freq(),
 214                       &iou_scntr_secure->base_frequency_id_register);
 215                /* And enable system counter */
 216                writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
 217                       &iou_scntr_secure->counter_control_register);
 218        }
 219        return 0;
 220}
 221
 222unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
 223                         char *const argv[])
 224{
 225        int ret = 0;
 226
 227        if (current_el() > 1) {
 228                smp_kick_all_cpus();
 229                dcache_disable();
 230                armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
 231                                    ES_TO_AARCH64);
 232        } else {
 233                printf("FAIL: current EL is not above EL1\n");
 234                ret = EINVAL;
 235        }
 236        return ret;
 237}
 238
 239#if !defined(CFG_SYS_SDRAM_BASE) && !defined(CFG_SYS_SDRAM_SIZE)
 240int dram_init_banksize(void)
 241{
 242        int ret;
 243
 244        ret = fdtdec_setup_memory_banksize();
 245        if (ret)
 246                return ret;
 247
 248        mem_map_fill();
 249
 250        return 0;
 251}
 252
 253int dram_init(void)
 254{
 255        if (fdtdec_setup_mem_size_base() != 0)
 256                return -EINVAL;
 257
 258        return 0;
 259}
 260
 261#else
 262int dram_init_banksize(void)
 263{
 264        gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
 265        gd->bd->bi_dram[0].size = get_effective_memsize();
 266
 267        mem_map_fill();
 268
 269        return 0;
 270}
 271
 272int dram_init(void)
 273{
 274        gd->ram_size = get_ram_size((void *)CFG_SYS_SDRAM_BASE,
 275                                    CFG_SYS_SDRAM_SIZE);
 276
 277        return 0;
 278}
 279#endif
 280
 281#if !CONFIG_IS_ENABLED(SYSRESET)
 282void reset_cpu(void)
 283{
 284}
 285#endif
 286
 287static u8 __maybe_unused zynqmp_get_bootmode(void)
 288{
 289        u8 bootmode;
 290        u32 reg = 0;
 291        int ret;
 292
 293        ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, &reg);
 294        if (ret)
 295                return -EINVAL;
 296
 297        debug("HW boot mode: %x\n", reg & BOOT_MODES_MASK);
 298        debug("ALT boot mode: %x\n", reg >> BOOT_MODE_ALT_SHIFT);
 299
 300        if (reg >> BOOT_MODE_ALT_SHIFT)
 301                reg >>= BOOT_MODE_ALT_SHIFT;
 302
 303        bootmode = reg & BOOT_MODES_MASK;
 304
 305        return bootmode;
 306}
 307
 308#if defined(CONFIG_BOARD_LATE_INIT)
 309static const struct {
 310        u32 bit;
 311        const char *name;
 312} reset_reasons[] = {
 313        { RESET_REASON_DEBUG_SYS, "DEBUG" },
 314        { RESET_REASON_SOFT, "SOFT" },
 315        { RESET_REASON_SRST, "SRST" },
 316        { RESET_REASON_PSONLY, "PS-ONLY" },
 317        { RESET_REASON_PMU, "PMU" },
 318        { RESET_REASON_INTERNAL, "INTERNAL" },
 319        { RESET_REASON_EXTERNAL, "EXTERNAL" },
 320        {}
 321};
 322
 323static int reset_reason(void)
 324{
 325        u32 reg;
 326        int i, ret;
 327        const char *reason = NULL;
 328
 329        ret = zynqmp_mmio_read((ulong)&crlapb_base->reset_reason, &reg);
 330        if (ret)
 331                return -EINVAL;
 332
 333        puts("Reset reason:\t");
 334
 335        for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
 336                if (reg & reset_reasons[i].bit) {
 337                        reason = reset_reasons[i].name;
 338                        printf("%s ", reset_reasons[i].name);
 339                        break;
 340                }
 341        }
 342
 343        puts("\n");
 344
 345        env_set("reset_reason", reason);
 346
 347        return 0;
 348}
 349
 350static int set_fdtfile(void)
 351{
 352        char *compatible, *fdtfile;
 353        const char *suffix = ".dtb";
 354        const char *vendor = "xilinx/";
 355        int fdt_compat_len;
 356
 357        if (env_get("fdtfile"))
 358                return 0;
 359
 360        compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible",
 361                                         &fdt_compat_len);
 362        if (compatible && fdt_compat_len) {
 363                char *name;
 364
 365                debug("Compatible: %s\n", compatible);
 366
 367                name = strchr(compatible, ',');
 368                if (!name)
 369                        return -EINVAL;
 370
 371                name++;
 372
 373                fdtfile = calloc(1, strlen(vendor) + strlen(name) +
 374                                 strlen(suffix) + 1);
 375                if (!fdtfile)
 376                        return -ENOMEM;
 377
 378                sprintf(fdtfile, "%s%s%s", vendor, name, suffix);
 379
 380                env_set("fdtfile", fdtfile);
 381                free(fdtfile);
 382        }
 383
 384        return 0;
 385}
 386
 387int board_late_init(void)
 388{
 389        u8 bootmode;
 390        struct udevice *dev;
 391        int bootseq = -1;
 392        int bootseq_len = 0;
 393        int env_targets_len = 0;
 394        const char *mode;
 395        char *new_targets;
 396        char *env_targets;
 397        int ret, multiboot;
 398
 399#if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
 400        usb_ether_init();
 401#endif
 402
 403        if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
 404                debug("Saved variables - Skipping\n");
 405                return 0;
 406        }
 407
 408        if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG))
 409                return 0;
 410
 411        ret = set_fdtfile();
 412        if (ret)
 413                return ret;
 414
 415        multiboot = multi_boot();
 416        if (multiboot >= 0)
 417                env_set_hex("multiboot", multiboot);
 418
 419        bootmode = zynqmp_get_bootmode();
 420
 421        puts("Bootmode: ");
 422        switch (bootmode) {
 423        case USB_MODE:
 424                puts("USB_MODE\n");
 425                mode = "usb_dfu0 usb_dfu1";
 426                env_set("modeboot", "usb_dfu_spl");
 427                break;
 428        case JTAG_MODE:
 429                puts("JTAG_MODE\n");
 430                mode = "jtag pxe dhcp";
 431                env_set("modeboot", "jtagboot");
 432                break;
 433        case QSPI_MODE_24BIT:
 434        case QSPI_MODE_32BIT:
 435                mode = "qspi0";
 436                puts("QSPI_MODE\n");
 437                env_set("modeboot", "qspiboot");
 438                break;
 439        case EMMC_MODE:
 440                puts("EMMC_MODE\n");
 441                if (uclass_get_device_by_name(UCLASS_MMC,
 442                                              "mmc@ff160000", &dev) &&
 443                    uclass_get_device_by_name(UCLASS_MMC,
 444                                              "sdhci@ff160000", &dev)) {
 445                        puts("Boot from EMMC but without SD0 enabled!\n");
 446                        return -1;
 447                }
 448                debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
 449
 450                mode = "mmc";
 451                bootseq = dev_seq(dev);
 452                env_set("modeboot", "emmcboot");
 453                break;
 454        case SD_MODE:
 455                puts("SD_MODE\n");
 456                if (uclass_get_device_by_name(UCLASS_MMC,
 457                                              "mmc@ff160000", &dev) &&
 458                    uclass_get_device_by_name(UCLASS_MMC,
 459                                              "sdhci@ff160000", &dev)) {
 460                        puts("Boot from SD0 but without SD0 enabled!\n");
 461                        return -1;
 462                }
 463                debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
 464
 465                mode = "mmc";
 466                bootseq = dev_seq(dev);
 467                env_set("modeboot", "sdboot");
 468                break;
 469        case SD1_LSHFT_MODE:
 470                puts("LVL_SHFT_");
 471                fallthrough;
 472        case SD_MODE1:
 473                puts("SD_MODE1\n");
 474                if (uclass_get_device_by_name(UCLASS_MMC,
 475                                              "mmc@ff170000", &dev) &&
 476                    uclass_get_device_by_name(UCLASS_MMC,
 477                                              "sdhci@ff170000", &dev)) {
 478                        puts("Boot from SD1 but without SD1 enabled!\n");
 479                        return -1;
 480                }
 481                debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
 482
 483                mode = "mmc";
 484                bootseq = dev_seq(dev);
 485                env_set("modeboot", "sdboot");
 486                break;
 487        case NAND_MODE:
 488                puts("NAND_MODE\n");
 489                mode = "nand0";
 490                env_set("modeboot", "nandboot");
 491                break;
 492        default:
 493                mode = "";
 494                printf("Invalid Boot Mode:0x%x\n", bootmode);
 495                break;
 496        }
 497
 498        if (bootseq >= 0) {
 499                bootseq_len = snprintf(NULL, 0, "%i", bootseq);
 500                debug("Bootseq len: %x\n", bootseq_len);
 501                env_set_hex("bootseq", bootseq);
 502        }
 503
 504        /*
 505         * One terminating char + one byte for space between mode
 506         * and default boot_targets
 507         */
 508        env_targets = env_get("boot_targets");
 509        if (env_targets)
 510                env_targets_len = strlen(env_targets);
 511
 512        new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
 513                             bootseq_len);
 514        if (!new_targets)
 515                return -ENOMEM;
 516
 517        if (bootseq >= 0)
 518                sprintf(new_targets, "%s%x %s", mode, bootseq,
 519                        env_targets ? env_targets : "");
 520        else
 521                sprintf(new_targets, "%s %s", mode,
 522                        env_targets ? env_targets : "");
 523
 524        env_set("boot_targets", new_targets);
 525        free(new_targets);
 526
 527        reset_reason();
 528
 529        return board_late_init_xilinx();
 530}
 531#endif
 532
 533int checkboard(void)
 534{
 535        puts("Board: Xilinx ZynqMP\n");
 536        return 0;
 537}
 538
 539int mmc_get_env_dev(void)
 540{
 541        struct udevice *dev;
 542        int bootseq = 0;
 543
 544        switch (zynqmp_get_bootmode()) {
 545        case EMMC_MODE:
 546        case SD_MODE:
 547                if (uclass_get_device_by_name(UCLASS_MMC,
 548                                              "mmc@ff160000", &dev) &&
 549                    uclass_get_device_by_name(UCLASS_MMC,
 550                                              "sdhci@ff160000", &dev)) {
 551                        return -1;
 552                }
 553                bootseq = dev_seq(dev);
 554                break;
 555        case SD1_LSHFT_MODE:
 556        case SD_MODE1:
 557                if (uclass_get_device_by_name(UCLASS_MMC,
 558                                              "mmc@ff170000", &dev) &&
 559                    uclass_get_device_by_name(UCLASS_MMC,
 560                                              "sdhci@ff170000", &dev)) {
 561                        return -1;
 562                }
 563                bootseq = dev_seq(dev);
 564                break;
 565        default:
 566                break;
 567        }
 568
 569        debug("bootseq %d\n", bootseq);
 570
 571        return bootseq;
 572}
 573
 574enum env_location env_get_location(enum env_operation op, int prio)
 575{
 576        u32 bootmode = zynqmp_get_bootmode();
 577
 578        if (prio)
 579                return ENVL_UNKNOWN;
 580
 581        switch (bootmode) {
 582        case EMMC_MODE:
 583        case SD_MODE:
 584        case SD1_LSHFT_MODE:
 585        case SD_MODE1:
 586                if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
 587                        return ENVL_FAT;
 588                if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
 589                        return ENVL_EXT4;
 590                return ENVL_NOWHERE;
 591        case NAND_MODE:
 592                if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
 593                        return ENVL_NAND;
 594                if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI))
 595                        return ENVL_UBI;
 596                return ENVL_NOWHERE;
 597        case QSPI_MODE_24BIT:
 598        case QSPI_MODE_32BIT:
 599                if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
 600                        return ENVL_SPI_FLASH;
 601                return ENVL_NOWHERE;
 602        case JTAG_MODE:
 603        default:
 604                return ENVL_NOWHERE;
 605        }
 606}
 607
 608#if defined(CONFIG_SET_DFU_ALT_INFO)
 609
 610#define DFU_ALT_BUF_LEN         SZ_1K
 611
 612void set_dfu_alt_info(char *interface, char *devstr)
 613{
 614        int multiboot, bootseq = 0, len = 0;
 615
 616        ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
 617
 618        if (env_get("dfu_alt_info"))
 619                return;
 620
 621        memset(buf, 0, sizeof(buf));
 622
 623        multiboot = multi_boot();
 624        if (multiboot < 0)
 625                multiboot = 0;
 626
 627        multiboot = env_get_hex("multiboot", multiboot);
 628        debug("Multiboot: %d\n", multiboot);
 629
 630        switch (zynqmp_get_bootmode()) {
 631        case EMMC_MODE:
 632        case SD_MODE:
 633        case SD1_LSHFT_MODE:
 634        case SD_MODE1:
 635                bootseq = mmc_get_env_dev();
 636
 637                len += snprintf(buf + len, DFU_ALT_BUF_LEN, "mmc %d=boot",
 638                               bootseq);
 639
 640                if (multiboot)
 641                        len += snprintf(buf + len, DFU_ALT_BUF_LEN,
 642                                       "%04d", multiboot);
 643
 644                len += snprintf(buf + len, DFU_ALT_BUF_LEN, ".bin fat %d 1",
 645                               bootseq);
 646#if defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME)
 647                len += snprintf(buf + len, DFU_ALT_BUF_LEN, ";%s fat %d 1",
 648                               CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
 649#endif
 650                break;
 651        case QSPI_MODE_24BIT:
 652        case QSPI_MODE_32BIT:
 653                len += snprintf(buf + len, DFU_ALT_BUF_LEN,
 654                               "sf 0:0=boot.bin raw %x 0x1500000",
 655                               multiboot * SZ_32K);
 656#if defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME) && defined(CONFIG_SYS_SPI_U_BOOT_OFFS)
 657                len += snprintf(buf + len, DFU_ALT_BUF_LEN,
 658                               ";%s raw 0x%x 0x500000",
 659                               CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
 660                               CONFIG_SYS_SPI_U_BOOT_OFFS);
 661#endif
 662                break;
 663        default:
 664                return;
 665        }
 666
 667        env_set("dfu_alt_info", buf);
 668        puts("DFU alt info setting: done\n");
 669}
 670#endif
 671