*/
#include <common.h>
+#include <cpu_func.h>
+#include <debug_uart.h>
+#include <env.h>
+#include <init.h>
#include <sata.h>
#include <ahci.h>
#include <scsi.h>
#include <usb.h>
#include <dwc3-uboot.h>
#include <zynqmppl.h>
-#include <i2c.h>
+#include <zynqmp_firmware.h>
#include <g_dnl.h>
+#include <linux/sizes.h>
-DECLARE_GLOBAL_DATA_PTR;
+#include "pm_cfg_obj.h"
-#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
-static struct udevice *watchdog_dev;
-#endif
+DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
!defined(CONFIG_SPL_BUILD)
.id = 0x62,
.name = "29dr",
},
+ {
+ .id = 0x66,
+ .name = "39dr",
+ },
+ {
+ .id = 0x7b,
+ .name = "48dr",
+ },
+ {
+ .id = 0x7e,
+ .name = "49dr",
+ },
};
#endif
int board_early_init_f(void)
{
- int ret = 0;
-#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CLK_ZYNQMP)
- u32 pm_api_version;
+#if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
+ int ret;
- pm_api_version = zynqmp_pmufw_version();
- printf("PMUFW:\tv%d.%d\n",
- pm_api_version >> ZYNQMP_PM_VERSION_MAJOR_SHIFT,
- pm_api_version & ZYNQMP_PM_VERSION_MINOR_MASK);
+ ret = psu_init();
+ if (ret)
+ return ret;
- if (pm_api_version < ZYNQMP_PM_VERSION)
- panic("PMUFW version error. Expected: v%d.%d\n",
- ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR);
+ /* Delay is required for clocks to be propagated */
+ udelay(1000000);
#endif
-#if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
- ret = psu_init();
+#ifdef CONFIG_DEBUG_UART
+ /* Uart debug for sure */
+ debug_uart_init();
+ puts("Debug uart enabled\n"); /* or printch() */
#endif
-#if defined(CONFIG_WDT) && !defined(CONFIG_SPL_BUILD)
- /* bss is not cleared at time when watchdog_reset() is called */
- watchdog_dev = NULL;
-#endif
+ return 0;
+}
- return ret;
+static int multi_boot(void)
+{
+ u32 multiboot;
+
+ multiboot = readl(&csu_base->multi_boot);
+
+ printf("Multiboot:\t%x\n", multiboot);
+
+ return 0;
}
int board_init(void)
{
+#if defined(CONFIG_ZYNQMP_FIRMWARE)
+ struct udevice *dev;
+
+ uclass_get_device_by_name(UCLASS_FIRMWARE, "zynqmp-power", &dev);
+ if (!dev)
+ panic("PMU Firmware device not found - Enable it");
+#endif
+
+#if defined(CONFIG_SPL_BUILD)
+ /* Check *at build time* if the filename is an non-empty string */
+ if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
+ zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
+ zynqmp_pm_cfg_obj_size);
+#endif
+
printf("EL Level:\tEL%d\n", current_el());
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
}
#endif
-#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
- if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
- debug("Watchdog: Not found by seq!\n");
- if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
- puts("Watchdog: Not found!\n");
- return 0;
- }
- }
-
- wdt_start(watchdog_dev, 0, 0);
- puts("Watchdog: Started\n");
-#endif
+ if (current_el() == 3)
+ multi_boot();
return 0;
}
-#ifdef CONFIG_WATCHDOG
-/* Called by macro WATCHDOG_RESET */
-void watchdog_reset(void)
-{
-# if !defined(CONFIG_SPL_BUILD)
- static ulong next_reset;
- ulong now;
-
- if (!watchdog_dev)
- return;
-
- now = timer_get_us();
-
- /* Do not reset the watchdog too often */
- if (now > next_reset) {
- wdt_reset(watchdog_dev);
- next_reset = now + 1000;
- }
-# endif
-}
-#endif
-
int board_early_init_r(void)
{
u32 val;
return 0;
}
-int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
-{
-#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
- defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
- defined(CONFIG_ZYNQ_EEPROM_BUS)
- i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
-
- if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
- CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
- ethaddr, 6))
- printf("I2C EEPROM MAC address read failed\n");
-#endif
-
- return 0;
-}
-
unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
char * const argv[])
{
{
}
+#if defined(CONFIG_BOARD_LATE_INIT)
static const struct {
u32 bit;
const char *name;
{}
};
-static u32 reset_reason(void)
+static int reset_reason(void)
{
- u32 ret;
- int i;
+ u32 reg;
+ int i, ret;
const char *reason = NULL;
- ret = readl(&crlapb_base->reset_reason);
+ ret = zynqmp_mmio_read((ulong)&crlapb_base->reset_reason, ®);
+ if (ret)
+ return -EINVAL;
puts("Reset reason:\t");
for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
- if (ret & reset_reasons[i].bit) {
+ if (reg & reset_reasons[i].bit) {
reason = reset_reasons[i].name;
printf("%s ", reset_reasons[i].name);
break;
env_set("reset_reason", reason);
- writel(~0, &crlapb_base->reset_reason);
+ ret = zynqmp_mmio_write((ulong)&crlapb_base->reset_reason, ~0, ~0);
+ if (ret)
+ return -EINVAL;
return ret;
}
+static int set_fdtfile(void)
+{
+ char *compatible, *fdtfile;
+ const char *suffix = ".dtb";
+ const char *vendor = "xilinx/";
+
+ if (env_get("fdtfile"))
+ return 0;
+
+ compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
+ if (compatible) {
+ debug("Compatible: %s\n", compatible);
+
+ /* Discard vendor prefix */
+ strsep(&compatible, ",");
+
+ fdtfile = calloc(1, strlen(vendor) + strlen(compatible) +
+ strlen(suffix) + 1);
+ if (!fdtfile)
+ return -ENOMEM;
+
+ sprintf(fdtfile, "%s%s%s", vendor, compatible, suffix);
+
+ env_set("fdtfile", fdtfile);
+ free(fdtfile);
+ }
+
+ return 0;
+}
+
int board_late_init(void)
{
u32 reg = 0;
char *new_targets;
char *env_targets;
int ret;
+ ulong initrd_hi;
#if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
usb_ether_init();
return 0;
}
+ ret = set_fdtfile();
+ if (ret)
+ return ret;
+
ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, ®);
if (ret)
return -EINVAL;
break;
case JTAG_MODE:
puts("JTAG_MODE\n");
- mode = "pxe dhcp";
+ mode = "jtag pxe dhcp";
env_set("modeboot", "jtagboot");
break;
case QSPI_MODE_24BIT:
break;
case EMMC_MODE:
puts("EMMC_MODE\n");
- mode = "mmc0";
- env_set("modeboot", "emmcboot");
+ if (uclass_get_device_by_name(UCLASS_MMC,
+ "mmc@ff160000", &dev) &&
+ uclass_get_device_by_name(UCLASS_MMC,
+ "sdhci@ff160000", &dev)) {
+ puts("Boot from EMMC 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 SD_MODE:
puts("SD_MODE\n");
if (uclass_get_device_by_name(UCLASS_MMC,
+ "mmc@ff160000", &dev) &&
+ uclass_get_device_by_name(UCLASS_MMC,
"sdhci@ff160000", &dev)) {
puts("Boot from SD0 but without SD0 enabled!\n");
return -1;
case SD_MODE1:
puts("SD_MODE1\n");
if (uclass_get_device_by_name(UCLASS_MMC,
+ "mmc@ff170000", &dev) &&
+ uclass_get_device_by_name(UCLASS_MMC,
"sdhci@ff170000", &dev)) {
puts("Boot from SD1 but without SD1 enabled!\n");
return -1;
env_set("boot_targets", new_targets);
+ initrd_hi = gd->start_addr_sp - CONFIG_STACK_SIZE;
+ initrd_hi = round_down(initrd_hi, SZ_16M);
+ env_set_addr("initrd_high", (void *)initrd_hi);
+
+ env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
+
reset_reason();
return 0;
}
+#endif
int checkboard(void)
{