u-boot/board/xilinx/versal/board.c
Michal Simek d61728c8e8 xilinx: board: Read the whole eeprom not just offset
Starts to use new way how eeproms should be referenced.
Reference is done via nvmem alias nodes. When this new way is specified
code itself read the eeprom and decode xilinx legacy format and fill struct
xilinx_board_description. Then based on information present there board_*
variables are setup.
If variables are saved and content can't be changed information is just
shown on console.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
2020-10-27 08:13:32 +01:00

246 lines
5 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2014 - 2018 Xilinx, Inc.
* Michal Simek <michal.simek@xilinx.com>
*/
#include <common.h>
#include <cpu_func.h>
#include <env.h>
#include <fdtdec.h>
#include <init.h>
#include <log.h>
#include <malloc.h>
#include <time.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#include <dm/device.h>
#include <dm/uclass.h>
#include <versalpl.h>
#include "../common/board.h"
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_FPGA_VERSALPL)
static xilinx_desc versalpl = XILINX_VERSAL_DESC;
#endif
int board_init(void)
{
printf("EL Level:\tEL%d\n", current_el());
#if defined(CONFIG_FPGA_VERSALPL)
fpga_init();
fpga_add(fpga_xilinx, &versalpl);
#endif
if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
xilinx_read_eeprom();
return 0;
}
int board_early_init_r(void)
{
u32 val;
if (current_el() != 3)
return 0;
debug("iou_switch ctrl div0 %x\n",
readl(&crlapb_base->iou_switch_ctrl));
writel(IOU_SWITCH_CTRL_CLKACT_BIT |
(CONFIG_IOU_SWITCH_DIVISOR0 << IOU_SWITCH_CTRL_DIVISOR0_SHIFT),
&crlapb_base->iou_switch_ctrl);
/* Global timer init - Program time stamp reference clk */
val = readl(&crlapb_base->timestamp_ref_ctrl);
val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
writel(val, &crlapb_base->timestamp_ref_ctrl);
debug("ref ctrl 0x%x\n",
readl(&crlapb_base->timestamp_ref_ctrl));
/* Clear reset of timestamp reg */
writel(0, &crlapb_base->rst_timestamp);
/*
* Program freq register in System counter and
* enable system counter.
*/
writel(COUNTER_FREQUENCY,
&iou_scntr_secure->base_frequency_id_register);
debug("counter val 0x%x\n",
readl(&iou_scntr_secure->base_frequency_id_register));
writel(IOU_SCNTRS_CONTROL_EN,
&iou_scntr_secure->counter_control_register);
debug("scntrs control 0x%x\n",
readl(&iou_scntr_secure->counter_control_register));
debug("timer 0x%llx\n", get_ticks());
debug("timer 0x%llx\n", get_ticks());
return 0;
}
static u8 versal_get_bootmode(void)
{
u8 bootmode;
u32 reg = 0;
reg = readl(&crp_base->boot_mode_usr);
if (reg >> BOOT_MODE_ALT_SHIFT)
reg >>= BOOT_MODE_ALT_SHIFT;
bootmode = reg & BOOT_MODES_MASK;
return bootmode;
}
int board_late_init(void)
{
u8 bootmode;
struct udevice *dev;
int bootseq = -1;
int bootseq_len = 0;
int env_targets_len = 0;
const char *mode;
char *new_targets;
char *env_targets;
if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
debug("Saved variables - Skipping\n");
return 0;
}
if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
return 0;
bootmode = versal_get_bootmode();
puts("Bootmode: ");
switch (bootmode) {
case USB_MODE:
puts("USB_MODE\n");
mode = "dfu_usb";
break;
case JTAG_MODE:
puts("JTAG_MODE\n");
mode = "jtag pxe dhcp";
break;
case QSPI_MODE_24BIT:
puts("QSPI_MODE_24\n");
mode = "xspi0";
break;
case QSPI_MODE_32BIT:
puts("QSPI_MODE_32\n");
mode = "xspi0";
break;
case OSPI_MODE:
puts("OSPI_MODE\n");
mode = "xspi0";
break;
case EMMC_MODE:
puts("EMMC_MODE\n");
if (uclass_get_device_by_name(UCLASS_MMC,
"sdhci@f1050000", &dev)) {
puts("Boot from EMMC but without SD1 enabled!\n");
return -1;
}
debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
mode = "mmc";
bootseq = dev->seq;
break;
case SD_MODE:
puts("SD_MODE\n");
if (uclass_get_device_by_name(UCLASS_MMC,
"sdhci@f1040000", &dev)) {
puts("Boot from SD0 but without SD0 enabled!\n");
return -1;
}
debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
mode = "mmc";
bootseq = dev->seq;
break;
case SD1_LSHFT_MODE:
puts("LVL_SHFT_");
/* fall through */
case SD_MODE1:
puts("SD_MODE1\n");
if (uclass_get_device_by_name(UCLASS_MMC,
"sdhci@f1050000", &dev)) {
puts("Boot from SD1 but without SD1 enabled!\n");
return -1;
}
debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
mode = "mmc";
bootseq = dev->seq;
break;
default:
mode = "";
printf("Invalid Boot Mode:0x%x\n", bootmode);
break;
}
if (bootseq >= 0) {
bootseq_len = snprintf(NULL, 0, "%i", bootseq);
debug("Bootseq len: %x\n", bootseq_len);
}
/*
* One terminating char + one byte for space between mode
* and default boot_targets
*/
env_targets = env_get("boot_targets");
if (env_targets)
env_targets_len = strlen(env_targets);
new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
bootseq_len);
if (!new_targets)
return -ENOMEM;
if (bootseq >= 0)
sprintf(new_targets, "%s%x %s", mode, bootseq,
env_targets ? env_targets : "");
else
sprintf(new_targets, "%s %s", mode,
env_targets ? env_targets : "");
env_set("boot_targets", new_targets);
return board_late_init_xilinx();
}
int dram_init_banksize(void)
{
int ret;
ret = fdtdec_setup_memory_banksize();
if (ret)
return ret;
mem_map_fill();
return 0;
}
int dram_init(void)
{
if (fdtdec_setup_mem_size_base_lowest() != 0)
return -EINVAL;
return 0;
}
void reset_cpu(ulong addr)
{
}