uboot/arch/arm/mach-socfpga/spl_a10.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *  Copyright (C) 2012-2021 Altera Corporation <www.altera.com>
   4 */
   5
   6#include <common.h>
   7#include <cpu_func.h>
   8#include <hang.h>
   9#include <init.h>
  10#include <asm/global_data.h>
  11#include <asm/io.h>
  12#include <asm/pl310.h>
  13#include <asm/u-boot.h>
  14#include <asm/utils.h>
  15#include <image.h>
  16#include <asm/arch/reset_manager.h>
  17#include <spl.h>
  18#include <asm/arch/system_manager.h>
  19#include <asm/arch/freeze_controller.h>
  20#include <asm/arch/clock_manager.h>
  21#include <asm/arch/scan_manager.h>
  22#include <asm/arch/sdram.h>
  23#include <asm/arch/scu.h>
  24#include <asm/arch/misc.h>
  25#include <asm/arch/nic301.h>
  26#include <asm/sections.h>
  27#include <fdtdec.h>
  28#include <watchdog.h>
  29#include <asm/arch/pinmux.h>
  30#include <asm/arch/fpga_manager.h>
  31#include <mmc.h>
  32#include <memalign.h>
  33#include <linux/delay.h>
  34
  35#define FPGA_BUFSIZ     16 * 1024
  36#define FSBL_IMAGE_IS_VALID     0x49535756
  37
  38#define FSBL_IMAGE_IS_INVALID   0x0
  39#define BOOTROM_CONFIGURES_IO_PINMUX    0x3
  40
  41DECLARE_GLOBAL_DATA_PTR;
  42
  43#define BOOTROM_SHARED_MEM_SIZE         0x800   /* 2KB */
  44#define BOOTROM_SHARED_MEM_ADDR         (CONFIG_SYS_INIT_RAM_ADDR + \
  45                                         SOCFPGA_PHYS_OCRAM_SIZE - \
  46                                         BOOTROM_SHARED_MEM_SIZE)
  47#define RST_STATUS_SHARED_ADDR          (BOOTROM_SHARED_MEM_ADDR + 0x438)
  48static u32 rst_mgr_status __section(".data");
  49
  50/*
  51 * Bootrom will clear the status register in reset manager and stores the
  52 * reset status value in shared memory. Bootrom stores shared data at last
  53 * 2KB of onchip RAM.
  54 * This function save reset status provided by BootROM to rst_mgr_status.
  55 * More information about reset status register value can be found in reset
  56 * manager register description.
  57 * When running in debugger without Bootrom, r0 to r3 are random values.
  58 * So, skip save the value when r0 is not BootROM shared data address.
  59 *
  60 * r0 - Contains the pointer to the shared memory block. The shared
  61 *      memory block is located in the top 2 KB of on-chip RAM.
  62 * r1 - contains the length of the shared memory.
  63 * r2 - unused and set to 0x0.
  64 * r3 - points to the version block.
  65 */
  66void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
  67                      unsigned long r3)
  68{
  69        if (r0 == BOOTROM_SHARED_MEM_ADDR)
  70                rst_mgr_status = readl(RST_STATUS_SHARED_ADDR);
  71
  72        save_boot_params_ret();
  73}
  74
  75u32 spl_boot_device(void)
  76{
  77        const u32 bsel = readl(socfpga_get_sysmgr_addr() + SYSMGR_A10_BOOTINFO);
  78
  79        switch (SYSMGR_GET_BOOTINFO_BSEL(bsel)) {
  80        case 0x1:       /* FPGA (HPS2FPGA Bridge) */
  81                return BOOT_DEVICE_RAM;
  82        case 0x2:       /* NAND Flash (1.8V) */
  83        case 0x3:       /* NAND Flash (3.0V) */
  84                socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
  85                return BOOT_DEVICE_NAND;
  86        case 0x4:       /* SD/MMC External Transceiver (1.8V) */
  87        case 0x5:       /* SD/MMC Internal Transceiver (3.0V) */
  88                socfpga_per_reset(SOCFPGA_RESET(SDMMC), 0);
  89                socfpga_per_reset(SOCFPGA_RESET(DMA), 0);
  90                return BOOT_DEVICE_MMC1;
  91        case 0x6:       /* QSPI Flash (1.8V) */
  92        case 0x7:       /* QSPI Flash (3.0V) */
  93                socfpga_per_reset(SOCFPGA_RESET(QSPI), 0);
  94                return BOOT_DEVICE_SPI;
  95        default:
  96                printf("Invalid boot device (bsel=%08x)!\n", bsel);
  97                hang();
  98        }
  99}
 100
 101#ifdef CONFIG_SPL_MMC
 102u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
 103{
 104#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
 105        return MMCSD_MODE_FS;
 106#else
 107        return MMCSD_MODE_RAW;
 108#endif
 109}
 110#endif
 111
 112void spl_board_init(void)
 113{
 114        int ret;
 115
 116        ALLOC_CACHE_ALIGN_BUFFER(char, buf, FPGA_BUFSIZ);
 117
 118        /* enable console uart printing */
 119        preloader_console_init();
 120        WATCHDOG_RESET();
 121
 122        arch_early_init_r();
 123
 124        /* If the full FPGA is already loaded, ie.from EPCQ, config fpga pins */
 125        if (is_fpgamgr_user_mode()) {
 126                ret = config_pins(gd->fdt_blob, "shared");
 127                if (ret)
 128                        return;
 129
 130                ret = config_pins(gd->fdt_blob, "fpga");
 131                if (ret)
 132                        return;
 133        } else if (!is_fpgamgr_early_user_mode()) {
 134                /* Program IOSSM(early IO release) or full FPGA */
 135                fpgamgr_program(buf, FPGA_BUFSIZ, 0);
 136
 137                /* Skipping double program for combined RBF */
 138                if (!is_fpgamgr_user_mode()) {
 139                        /*
 140                         * Expect FPGA entered early user mode, so
 141                         * the flag is set to re-program IOSSM
 142                         */
 143                        force_periph_program(true);
 144
 145                        /* Re-program IOSSM to stabilize IO system */
 146                        fpgamgr_program(buf, FPGA_BUFSIZ, 0);
 147
 148                        force_periph_program(false);
 149                }
 150        }
 151
 152        /* If the IOSSM/full FPGA is already loaded, start DDR */
 153        if (is_fpgamgr_early_user_mode() || is_fpgamgr_user_mode()) {
 154                if (!is_regular_boot_valid()) {
 155                        /*
 156                         * Ensure all signals in stable state before triggering
 157                         * warm reset. This value is recommended from stress
 158                         * test.
 159                         */
 160                        mdelay(10);
 161
 162#if IS_ENABLED(CONFIG_CADENCE_QSPI)
 163                        /*
 164                         * Trigger software reset to QSPI flash.
 165                         * On some boards, the QSPI flash reset may not be
 166                         * connected to the HPS warm reset.
 167                         */
 168                        qspi_flash_software_reset();
 169#endif
 170
 171                        ret = readl(socfpga_get_rstmgr_addr() +
 172                                    RSTMGR_A10_SYSWARMMASK);
 173                        /*
 174                         * Masking s2f & FPGA manager module reset from warm
 175                         * reset
 176                         */
 177                        writel(ret & (~(ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK |
 178                               ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK)),
 179                               socfpga_get_rstmgr_addr() +
 180                               RSTMGR_A10_SYSWARMMASK);
 181
 182                        /*
 183                         * BootROM will configure both IO and pin mux after a
 184                         * warm reset
 185                         */
 186                        ret = readl(socfpga_get_sysmgr_addr() +
 187                                    SYSMGR_A10_ROMCODE_CTRL);
 188                        writel(ret | BOOTROM_CONFIGURES_IO_PINMUX,
 189                               socfpga_get_sysmgr_addr() +
 190                               SYSMGR_A10_ROMCODE_CTRL);
 191
 192                        /*
 193                         * Up to here, image is considered valid and should be
 194                         * set as valid before warm reset is triggered
 195                         */
 196                        writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() +
 197                               SYSMGR_A10_ROMCODE_INITSWSTATE);
 198
 199                        /*
 200                         * Set this flag to scratch register, so that a proper
 201                         * boot progress before / after warm reset can be
 202                         * tracked by FSBL
 203                         */
 204                        set_regular_boot(true);
 205
 206                        WATCHDOG_RESET();
 207
 208                        reset_cpu();
 209                }
 210
 211                /*
 212                 * Reset this flag to scratch register, so that a proper
 213                 * boot progress before / after warm reset can be
 214                 * tracked by FSBL
 215                 */
 216                set_regular_boot(false);
 217
 218                ret = readl(socfpga_get_rstmgr_addr() +
 219                            RSTMGR_A10_SYSWARMMASK);
 220
 221                /*
 222                 * Unmasking s2f & FPGA manager module reset from warm
 223                 * reset
 224                 */
 225                writel(ret | ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK |
 226                        ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK,
 227                        socfpga_get_rstmgr_addr() + RSTMGR_A10_SYSWARMMASK);
 228
 229                /*
 230                 * Up to here, MPFE hang workaround is considered done and
 231                 * should be reset as invalid until FSBL successfully loading
 232                 * SSBL, and prepare jumping to SSBL, then only setting as
 233                 * valid
 234                 */
 235                writel(FSBL_IMAGE_IS_INVALID, socfpga_get_sysmgr_addr() +
 236                       SYSMGR_A10_ROMCODE_INITSWSTATE);
 237
 238                ddr_calibration_sequence();
 239        }
 240
 241        if (!is_fpgamgr_user_mode())
 242                fpgamgr_program(buf, FPGA_BUFSIZ, 0);
 243}
 244
 245void board_init_f(ulong dummy)
 246{
 247        if (spl_early_init())
 248                hang();
 249
 250        socfpga_get_managers_addr();
 251
 252        dcache_disable();
 253
 254        socfpga_init_security_policies();
 255        socfpga_sdram_remap_zero();
 256        socfpga_pl310_clear();
 257
 258        /* Assert reset to all except L4WD0 and L4TIMER0 */
 259        socfpga_per_reset_all();
 260        socfpga_watchdog_disable();
 261
 262        /* Configure the clock based on handoff */
 263        cm_basic_init(gd->fdt_blob);
 264
 265#ifdef CONFIG_HW_WATCHDOG
 266        /* release osc1 watchdog timer 0 from reset */
 267        socfpga_reset_deassert_osc1wd0();
 268
 269        /* reconfigure and enable the watchdog */
 270        hw_watchdog_init();
 271        WATCHDOG_RESET();
 272#endif /* CONFIG_HW_WATCHDOG */
 273
 274        config_dedicated_pins(gd->fdt_blob);
 275        WATCHDOG_RESET();
 276}
 277
 278/* board specific function prior loading SSBL / U-Boot proper */
 279void spl_board_prepare_for_boot(void)
 280{
 281        writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() +
 282               SYSMGR_A10_ROMCODE_INITSWSTATE);
 283}
 284