Skip to content
Snippets Groups Projects
Commit 58c8c096 authored by Tom Rini's avatar Tom Rini
Browse files

Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze

parents a6c13097 e0027f08
No related branches found
No related tags found
No related merge requests found
Showing
with 537 additions and 16 deletions
...@@ -47,5 +47,53 @@ config ZYNQMP_USB ...@@ -47,5 +47,53 @@ config ZYNQMP_USB
config SYS_MALLOC_F_LEN config SYS_MALLOC_F_LEN
default 0x600 default 0x600
config SPL_ZYNQMP_ALT_BOOTMODE_ENABLED
bool "Overwrite SPL bootmode"
depends on SPL
help
Overwrite bootmode selected via boot mode pins to tell SPL what should
be the next boot device.
config SPL_ZYNQMP_ALT_BOOTMODE
hex
default 0x0 if JTAG_MODE
default 0x1 if QSPI_MODE_24BIT
default 0x2 if QSPI_MODE_32BIT
default 0x3 if SD_MODE
default 0x4 if NAND_MODE
default 0x5 if SD_MODE1
default 0x6 if EMMC_MODE
default 0x7 if USB_MODE
choice
prompt "Boot mode"
depends on ZYNQMP_ALT_BOOTMODE_ENABLED
default JTAG
config JTAG_MODE
bool "JTAG_MODE"
config QSPI_MODE_24BIT
bool "QSPI_MODE_24BIT"
config QSPI_MODE_32BIT
bool "QSPI_MODE_32BIT"
config SD_MODE
bool "SD_MODE"
config SD_MODE1
bool "SD_MODE1"
config NAND_MODE
bool "NAND_MODE"
config EMMC_MODE
bool "EMMC_MODE"
config USB_MODE
bool "USB"
endchoice
endif endif
...@@ -35,10 +35,29 @@ void board_init_f(ulong dummy) ...@@ -35,10 +35,29 @@ void board_init_f(ulong dummy)
board_init_r(NULL, 0); board_init_r(NULL, 0);
} }
static void ps_mode_reset(ulong mode)
{
writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT,
&crlapb_base->boot_pin_ctrl);
udelay(5);
writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT |
mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT,
&crlapb_base->boot_pin_ctrl);
}
/*
* Set default PS_MODE1 which is used for USB ULPI phy reset
* Also other resets can be connected to this certain pin
*/
#ifndef MODE_RESET
# define MODE_RESET PS_MODE1
#endif
#ifdef CONFIG_SPL_BOARD_INIT #ifdef CONFIG_SPL_BOARD_INIT
void spl_board_init(void) void spl_board_init(void)
{ {
preloader_console_init(); preloader_console_init();
ps_mode_reset(MODE_RESET);
board_init(); board_init();
} }
#endif #endif
...@@ -48,6 +67,13 @@ u32 spl_boot_device(void) ...@@ -48,6 +67,13 @@ u32 spl_boot_device(void)
u32 reg = 0; u32 reg = 0;
u8 bootmode; u8 bootmode;
#if defined(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE_ENABLED)
/* Change default boot mode at run-time */
writel(BOOT_MODE_USE_ALT |
CONFIG_SPL_ZYNQMP_ALT_BOOTMODE << BOOT_MODE_ALT_SHIFT,
&crlapb_base->boot_mode);
#endif
reg = readl(&crlapb_base->boot_mode); reg = readl(&crlapb_base->boot_mode);
bootmode = reg & BOOT_MODES_MASK; bootmode = reg & BOOT_MODES_MASK;
...@@ -59,6 +85,10 @@ u32 spl_boot_device(void) ...@@ -59,6 +85,10 @@ u32 spl_boot_device(void)
case SD_MODE: case SD_MODE:
case SD_MODE1: case SD_MODE1:
return BOOT_DEVICE_MMC1; return BOOT_DEVICE_MMC1;
#endif
#ifdef CONFIG_SPL_DFU_SUPPORT
case USB_MODE:
return BOOT_DEVICE_DFU;
#endif #endif
default: default:
printf("Invalid Boot Mode:0x%x\n", bootmode); printf("Invalid Boot Mode:0x%x\n", bootmode);
......
...@@ -25,6 +25,13 @@ ...@@ -25,6 +25,13 @@
#define ZYNQMP_CRL_APB_BASEADDR 0xFF5E0000 #define ZYNQMP_CRL_APB_BASEADDR 0xFF5E0000
#define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000 #define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000
#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT 0
#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT 8
#define PS_MODE0 BIT(0)
#define PS_MODE1 BIT(1)
#define PS_MODE2 BIT(2)
#define PS_MODE3 BIT(3)
struct crlapb_regs { struct crlapb_regs {
u32 reserved0[36]; u32 reserved0[36];
...@@ -35,7 +42,9 @@ struct crlapb_regs { ...@@ -35,7 +42,9 @@ struct crlapb_regs {
u32 boot_mode; /* 0x200 */ u32 boot_mode; /* 0x200 */
u32 reserved3[14]; u32 reserved3[14];
u32 rst_lpd_top; /* 0x23C */ u32 rst_lpd_top; /* 0x23C */
u32 reserved4[26]; u32 reserved4[4];
u32 boot_pin_ctrl; /* 0x250 */
u32 reserved5[21];
}; };
#define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR) #define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR)
...@@ -69,7 +78,10 @@ struct iou_scntr_secure { ...@@ -69,7 +78,10 @@ struct iou_scntr_secure {
#define SD_MODE1 0x00000005 /* sd 1 */ #define SD_MODE1 0x00000005 /* sd 1 */
#define NAND_MODE 0x00000004 #define NAND_MODE 0x00000004
#define EMMC_MODE 0x00000006 #define EMMC_MODE 0x00000006
#define USB_MODE 0x00000007
#define JTAG_MODE 0x00000000 #define JTAG_MODE 0x00000000
#define BOOT_MODE_USE_ALT 0x100
#define BOOT_MODE_ALT_SHIFT 12
#define ZYNQMP_IOU_SLCR_BASEADDR 0xFF180000 #define ZYNQMP_IOU_SLCR_BASEADDR 0xFF180000
......
...@@ -28,6 +28,7 @@ enum { ...@@ -28,6 +28,7 @@ enum {
BOOT_DEVICE_SATA, BOOT_DEVICE_SATA,
BOOT_DEVICE_I2C, BOOT_DEVICE_I2C,
BOOT_DEVICE_BOARD, BOOT_DEVICE_BOARD,
BOOT_DEVICE_DFU,
BOOT_DEVICE_NONE BOOT_DEVICE_NONE
}; };
#endif #endif
......
...@@ -16,14 +16,114 @@ ...@@ -16,14 +16,114 @@
#include <asm/io.h> #include <asm/io.h>
#include <usb.h> #include <usb.h>
#include <dwc3-uboot.h> #include <dwc3-uboot.h>
#include <zynqmppl.h>
#include <i2c.h> #include <i2c.h>
#include <g_dnl.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
!defined(CONFIG_SPL_BUILD)
static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
static const struct {
uint32_t id;
char *name;
} zynqmp_devices[] = {
{
.id = 0x10,
.name = "3eg",
},
{
.id = 0x11,
.name = "2eg",
},
{
.id = 0x20,
.name = "5ev",
},
{
.id = 0x21,
.name = "4ev",
},
{
.id = 0x30,
.name = "7ev",
},
{
.id = 0x38,
.name = "9eg",
},
{
.id = 0x39,
.name = "6eg",
},
{
.id = 0x40,
.name = "11eg",
},
{
.id = 0x50,
.name = "15eg",
},
{
.id = 0x58,
.name = "19eg",
},
{
.id = 0x59,
.name = "17eg",
},
};
static int chip_id(void)
{
struct pt_regs regs;
regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
regs.regs[1] = 0;
regs.regs[2] = 0;
regs.regs[3] = 0;
smc_call(&regs);
return regs.regs[0];
}
static char *zynqmp_get_silicon_idcode_name(void)
{
uint32_t i, id;
id = chip_id();
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
if (zynqmp_devices[i].id == id)
return zynqmp_devices[i].name;
}
return "unknown";
}
#endif
#define ZYNQMP_VERSION_SIZE 9
int board_init(void) int board_init(void)
{ {
printf("EL Level:\tEL%d\n", current_el()); printf("EL Level:\tEL%d\n", current_el());
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
!defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
defined(CONFIG_SPL_BUILD))
if (current_el() != 3) {
static char version[ZYNQMP_VERSION_SIZE];
strncat(version, "xczu", ZYNQMP_VERSION_SIZE);
zynqmppl.name = strncat(version,
zynqmp_get_silicon_idcode_name(),
ZYNQMP_VERSION_SIZE);
printf("Chip ID:\t%s\n", zynqmppl.name);
fpga_init();
fpga_add(fpga_xilinx, &zynqmppl);
}
#endif
return 0; return 0;
} }
...@@ -228,6 +328,10 @@ int board_late_init(void) ...@@ -228,6 +328,10 @@ int board_late_init(void)
puts("Bootmode: "); puts("Bootmode: ");
switch (bootmode) { switch (bootmode) {
case USB_MODE:
puts("USB_MODE\n");
mode = "usb";
break;
case JTAG_MODE: case JTAG_MODE:
puts("JTAG_MODE\n"); puts("JTAG_MODE\n");
mode = "pxe dhcp"; mode = "pxe dhcp";
...@@ -283,22 +387,38 @@ int checkboard(void) ...@@ -283,22 +387,38 @@ int checkboard(void)
} }
#ifdef CONFIG_USB_DWC3 #ifdef CONFIG_USB_DWC3
static struct dwc3_device dwc3_device_data = { static struct dwc3_device dwc3_device_data0 = {
.maximum_speed = USB_SPEED_HIGH, .maximum_speed = USB_SPEED_HIGH,
.base = ZYNQMP_USB0_XHCI_BASEADDR, .base = ZYNQMP_USB0_XHCI_BASEADDR,
.dr_mode = USB_DR_MODE_PERIPHERAL, .dr_mode = USB_DR_MODE_PERIPHERAL,
.index = 0, .index = 0,
}; };
int usb_gadget_handle_interrupts(void) static struct dwc3_device dwc3_device_data1 = {
.maximum_speed = USB_SPEED_HIGH,
.base = ZYNQMP_USB1_XHCI_BASEADDR,
.dr_mode = USB_DR_MODE_PERIPHERAL,
.index = 1,
};
int usb_gadget_handle_interrupts(int index)
{ {
dwc3_uboot_handle_interrupt(0); dwc3_uboot_handle_interrupt(index);
return 0; return 0;
} }
int board_usb_init(int index, enum usb_init_type init) int board_usb_init(int index, enum usb_init_type init)
{ {
return dwc3_uboot_init(&dwc3_device_data); debug("%s: index %x\n", __func__, index);
switch (index) {
case 0:
return dwc3_uboot_init(&dwc3_device_data0);
case 1:
return dwc3_uboot_init(&dwc3_device_data1);
};
return -1;
} }
int board_usb_cleanup(int index, enum usb_init_type init) int board_usb_cleanup(int index, enum usb_init_type init)
......
...@@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000 ...@@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_ZYNQMP_USB=y CONFIG_ZYNQMP_USB=y
CONFIG_SYS_TEXT_BASE=0x8000000 CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep108" CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep108"
CONFIG_AHCI=y
CONFIG_FIT=y CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT=y
...@@ -46,6 +47,8 @@ CONFIG_NET_RANDOM_ETHADDR=y ...@@ -46,6 +47,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_BLK=y CONFIG_BLK=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y CONFIG_DM_I2C=y
CONFIG_SYS_I2C_CADENCE=y CONFIG_SYS_I2C_CADENCE=y
......
...@@ -38,6 +38,8 @@ CONFIG_NET_RANDOM_ETHADDR=y ...@@ -38,6 +38,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_BLK=y CONFIG_BLK=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y CONFIG_DM_I2C=y
CONFIG_SYS_I2C_CADENCE=y CONFIG_SYS_I2C_CADENCE=y
......
...@@ -41,6 +41,8 @@ CONFIG_NET_RANDOM_ETHADDR=y ...@@ -41,6 +41,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_BLK=y CONFIG_BLK=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y CONFIG_DM_I2C=y
CONFIG_SYS_I2C_CADENCE=y CONFIG_SYS_I2C_CADENCE=y
......
CONFIG_ARM=y CONFIG_ARM=y
CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm018_dc4"
CONFIG_ARCH_ZYNQMP=y CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm018 dc4" CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm018 dc4"
...@@ -34,6 +33,8 @@ CONFIG_NET_RANDOM_ETHADDR=y ...@@ -34,6 +33,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_BLK=y CONFIG_BLK=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y CONFIG_DM_I2C=y
CONFIG_SYS_I2C_CADENCE=y CONFIG_SYS_I2C_CADENCE=y
......
...@@ -33,6 +33,8 @@ CONFIG_OF_EMBED=y ...@@ -33,6 +33,8 @@ CONFIG_OF_EMBED=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_BLK=y CONFIG_BLK=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y CONFIG_DM_I2C=y
CONFIG_SYS_I2C_CADENCE=y CONFIG_SYS_I2C_CADENCE=y
......
...@@ -6,6 +6,7 @@ CONFIG_ZYNQMP_USB=y ...@@ -6,6 +6,7 @@ CONFIG_ZYNQMP_USB=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102" CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102"
CONFIG_SYS_TEXT_BASE=0x8000000 CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102" CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102"
CONFIG_AHCI=y
CONFIG_FIT=y CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT=y
...@@ -38,6 +39,8 @@ CONFIG_NET_RANDOM_ETHADDR=y ...@@ -38,6 +39,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_BLK=y CONFIG_BLK=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_DM_MMC_OPS=y CONFIG_DM_MMC_OPS=y
......
...@@ -6,6 +6,7 @@ CONFIG_ZYNQMP_USB=y ...@@ -6,6 +6,7 @@ CONFIG_ZYNQMP_USB=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102" CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102"
CONFIG_SYS_TEXT_BASE=0x8000000 CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB" CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
CONFIG_AHCI=y
CONFIG_FIT=y CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT=y
...@@ -38,6 +39,8 @@ CONFIG_NET_RANDOM_ETHADDR=y ...@@ -38,6 +39,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_BLK=y CONFIG_BLK=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_DM_MMC_OPS=y CONFIG_DM_MMC_OPS=y
......
...@@ -20,6 +20,8 @@ source "drivers/dfu/Kconfig" ...@@ -20,6 +20,8 @@ source "drivers/dfu/Kconfig"
source "drivers/dma/Kconfig" source "drivers/dma/Kconfig"
source "drivers/fpga/Kconfig"
source "drivers/gpio/Kconfig" source "drivers/gpio/Kconfig"
source "drivers/hwmon/Kconfig" source "drivers/hwmon/Kconfig"
......
menu "FPGA support"
config FPGA
bool
config FPGA_XILINX
bool "Enable Xilinx FPGA drivers"
select FPGA
help
Enable Xilinx FPGA specific functions which includes bitstream
(in BIT format), fpga and device validation.
config FPGA_ZYNQMPPL
bool "Enable Xilinx FPGA driver for ZynqMP"
depends on FPGA_XILINX
help
Enable FPGA driver for loading bitstream in BIT and BIN format
on Xilinx Zynq UltraScale+ (ZynqMP) device.
endmenu
...@@ -10,6 +10,7 @@ obj-$(CONFIG_FPGA_SPARTAN2) += spartan2.o ...@@ -10,6 +10,7 @@ obj-$(CONFIG_FPGA_SPARTAN2) += spartan2.o
obj-$(CONFIG_FPGA_SPARTAN3) += spartan3.o obj-$(CONFIG_FPGA_SPARTAN3) += spartan3.o
obj-$(CONFIG_FPGA_VIRTEX2) += virtex2.o obj-$(CONFIG_FPGA_VIRTEX2) += virtex2.o
obj-$(CONFIG_FPGA_ZYNQPL) += zynqpl.o obj-$(CONFIG_FPGA_ZYNQPL) += zynqpl.o
obj-$(CONFIG_FPGA_ZYNQMPPL) += zynqmppl.o
obj-$(CONFIG_FPGA_XILINX) += xilinx.o obj-$(CONFIG_FPGA_XILINX) += xilinx.o
obj-$(CONFIG_FPGA_LATTICE) += ivm_core.o lattice.o obj-$(CONFIG_FPGA_LATTICE) += ivm_core.o lattice.o
ifdef CONFIG_FPGA_ALTERA ifdef CONFIG_FPGA_ALTERA
......
...@@ -199,6 +199,9 @@ int xilinx_info(xilinx_desc *desc) ...@@ -199,6 +199,9 @@ int xilinx_info(xilinx_desc *desc)
case xilinx_zynq: case xilinx_zynq:
printf("Zynq PL\n"); printf("Zynq PL\n");
break; break;
case xilinx_zynqmp:
printf("ZynqMP PL\n");
break;
/* Add new family types here */ /* Add new family types here */
default: default:
printf ("Unknown family type, %d\n", desc->family); printf ("Unknown family type, %d\n", desc->family);
...@@ -227,6 +230,9 @@ int xilinx_info(xilinx_desc *desc) ...@@ -227,6 +230,9 @@ int xilinx_info(xilinx_desc *desc)
case devcfg: case devcfg:
printf("Device configuration interface (Zynq)\n"); printf("Device configuration interface (Zynq)\n");
break; break;
case csu_dma:
printf("csu_dma configuration interface (ZynqMP)\n");
break;
/* Add new interface types here */ /* Add new interface types here */
default: default:
printf ("Unsupported interface type, %d\n", desc->iface); printf ("Unsupported interface type, %d\n", desc->iface);
......
/*
* (C) Copyright 2015 - 2016, Xilinx, Inc,
* Michal Simek <michal.simek@xilinx.com>
* Siva Durga Prasad <siva.durga.paladugu@xilinx.com>
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <console.h>
#include <common.h>
#include <zynqmppl.h>
#include <linux/sizes.h>
#define DUMMY_WORD 0xffffffff
/* Xilinx binary format header */
static const u32 bin_format[] = {
DUMMY_WORD, /* Dummy words */
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
DUMMY_WORD,
0x000000bb, /* Sync word */
0x11220044, /* Sync word */
DUMMY_WORD,
DUMMY_WORD,
0xaa995566, /* Sync word */
};
#define SWAP_NO 1
#define SWAP_DONE 2
/*
* Load the whole word from unaligned buffer
* Keep in your mind that it is byte loading on little-endian system
*/
static u32 load_word(const void *buf, u32 swap)
{
u32 word = 0;
u8 *bitc = (u8 *)buf;
int p;
if (swap == SWAP_NO) {
for (p = 0; p < 4; p++) {
word <<= 8;
word |= bitc[p];
}
} else {
for (p = 3; p >= 0; p--) {
word <<= 8;
word |= bitc[p];
}
}
return word;
}
static u32 check_header(const void *buf)
{
u32 i, pattern;
int swap = SWAP_NO;
u32 *test = (u32 *)buf;
debug("%s: Let's check bitstream header\n", __func__);
/* Checking that passing bin is not a bitstream */
for (i = 0; i < ARRAY_SIZE(bin_format); i++) {
pattern = load_word(&test[i], swap);
/*
* Bitstreams in binary format are swapped
* compare to regular bistream.
* Do not swap dummy word but if swap is done assume
* that parsing buffer is binary format
*/
if ((__swab32(pattern) != DUMMY_WORD) &&
(__swab32(pattern) == bin_format[i])) {
swap = SWAP_DONE;
debug("%s: data swapped - let's swap\n", __func__);
}
debug("%s: %d/%px: pattern %x/%x bin_format\n", __func__, i,
&test[i], pattern, bin_format[i]);
}
debug("%s: Found bitstream header at %px %s swapinng\n", __func__,
buf, swap == SWAP_NO ? "without" : "with");
return swap;
}
static void *check_data(u8 *buf, size_t bsize, u32 *swap)
{
u32 word, p = 0; /* possition */
/* Because buf doesn't need to be aligned let's read it by chars */
for (p = 0; p < bsize; p++) {
word = load_word(&buf[p], SWAP_NO);
debug("%s: word %x %x/%px\n", __func__, word, p, &buf[p]);
/* Find the first bitstream dummy word */
if (word == DUMMY_WORD) {
debug("%s: Found dummy word at position %x/%px\n",
__func__, p, &buf[p]);
*swap = check_header(&buf[p]);
if (*swap) {
/* FIXME add full bitstream checking here */
return &buf[p];
}
}
/* Loop can be huge - support CTRL + C */
if (ctrlc())
return NULL;
}
return NULL;
}
static ulong zynqmp_align_dma_buffer(u32 *buf, u32 len, u32 swap)
{
u32 *new_buf;
u32 i;
if ((ulong)buf != ALIGN((ulong)buf, ARCH_DMA_MINALIGN)) {
new_buf = (u32 *)ALIGN((ulong)buf, ARCH_DMA_MINALIGN);
/*
* This might be dangerous but permits to flash if
* ARCH_DMA_MINALIGN is greater than header size
*/
if (new_buf > (u32 *)buf) {
debug("%s: Aligned buffer is after buffer start\n",
__func__);
new_buf -= ARCH_DMA_MINALIGN;
}
printf("%s: Align buffer at %px to %px(swap %d)\n", __func__,
buf, new_buf, swap);
for (i = 0; i < (len/4); i++)
new_buf[i] = load_word(&buf[i], swap);
buf = new_buf;
} else if (swap != SWAP_DONE) {
/* For bitstream which are aligned */
u32 *new_buf = (u32 *)buf;
printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__,
swap);
for (i = 0; i < (len/4); i++)
new_buf[i] = load_word(&buf[i], swap);
}
return (ulong)buf;
}
static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf,
size_t bsize, u32 blocksize, u32 *swap)
{
ulong *buf_start;
ulong diff;
buf_start = check_data((u8 *)buf, blocksize, swap);
if (!buf_start)
return FPGA_FAIL;
/* Check if data is postpone from start */
diff = (ulong)buf_start - (ulong)buf;
if (diff) {
printf("%s: Bitstream is not validated yet (diff %lx)\n",
__func__, diff);
return FPGA_FAIL;
}
if ((ulong)buf < SZ_1M) {
printf("%s: Bitstream has to be placed up to 1MB (%px)\n",
__func__, buf);
return FPGA_FAIL;
}
return 0;
}
static int invoke_smc(ulong id, ulong reg0, ulong reg1, ulong reg2)
{
struct pt_regs regs;
regs.regs[0] = id;
regs.regs[1] = reg0;
regs.regs[2] = reg1;
regs.regs[3] = reg2;
smc_call(&regs);
return regs.regs[0];
}
static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize,
bitstream_type bstype)
{
u32 swap;
ulong bin_buf, flags;
int ret;
if (zynqmp_validate_bitstream(desc, buf, bsize, bsize, &swap))
return FPGA_FAIL;
bin_buf = zynqmp_align_dma_buffer((u32 *)buf, bsize, swap);
debug("%s called!\n", __func__);
flush_dcache_range(bin_buf, bin_buf + bsize);
if (bsize % 4)
bsize = bsize / 4 + 1;
else
bsize = bsize / 4;
flags = (u32)bsize | ((u64)bstype << 32);
ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, bin_buf, flags, 0);
if (ret)
debug("PL FPGA LOAD fail\n");
return ret;
}
struct xilinx_fpga_op zynqmp_op = {
.load = zynqmp_load,
};
...@@ -92,7 +92,8 @@ static void zynq_spi_init_hw(struct zynq_spi_priv *priv) ...@@ -92,7 +92,8 @@ static void zynq_spi_init_hw(struct zynq_spi_priv *priv)
u32 confr; u32 confr;
/* Disable SPI */ /* Disable SPI */
writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, &regs->enr); confr = ZYNQ_SPI_ENR_SPI_EN_MASK;
writel(~confr, &regs->enr);
/* Disable Interrupts */ /* Disable Interrupts */
writel(ZYNQ_SPI_IXR_ALL_MASK, &regs->idr); writel(ZYNQ_SPI_IXR_ALL_MASK, &regs->idr);
...@@ -173,8 +174,10 @@ static int zynq_spi_release_bus(struct udevice *dev) ...@@ -173,8 +174,10 @@ static int zynq_spi_release_bus(struct udevice *dev)
struct udevice *bus = dev->parent; struct udevice *bus = dev->parent;
struct zynq_spi_priv *priv = dev_get_priv(bus); struct zynq_spi_priv *priv = dev_get_priv(bus);
struct zynq_spi_regs *regs = priv->regs; struct zynq_spi_regs *regs = priv->regs;
u32 confr;
writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, &regs->enr); confr = ZYNQ_SPI_ENR_SPI_EN_MASK;
writel(~confr, &regs->enr);
return 0; return 0;
} }
......
...@@ -75,7 +75,9 @@ ...@@ -75,7 +75,9 @@
/* Diff from config_distro_defaults.h */ /* Diff from config_distro_defaults.h */
#define CONFIG_SUPPORT_RAW_INITRD #define CONFIG_SUPPORT_RAW_INITRD
#if !defined(CONFIG_SPL_BUILD)
#define CONFIG_ENV_VARS_UBOOT_CONFIG #define CONFIG_ENV_VARS_UBOOT_CONFIG
#endif
#define CONFIG_AUTO_COMPLETE #define CONFIG_AUTO_COMPLETE
/* PXE */ /* PXE */
...@@ -108,7 +110,7 @@ ...@@ -108,7 +110,7 @@
#define CONFIG_SYS_LOAD_ADDR 0x8000000 #define CONFIG_SYS_LOAD_ADDR 0x8000000
#if defined(CONFIG_ZYNQMP_USB) #if defined(CONFIG_ZYNQMP_USB)
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
#define CONFIG_USB_XHCI_ZYNQMP #define CONFIG_USB_XHCI_ZYNQMP
...@@ -136,7 +138,6 @@ ...@@ -136,7 +138,6 @@
# define DFU_ALT_INFO # define DFU_ALT_INFO
#endif #endif
#define CONFIG_BOARD_LATE_INIT #define CONFIG_BOARD_LATE_INIT
/* Do not preserve environment */ /* Do not preserve environment */
...@@ -185,7 +186,6 @@ ...@@ -185,7 +186,6 @@
#endif #endif
#ifdef CONFIG_SATA_CEVA #ifdef CONFIG_SATA_CEVA
#define CONFIG_AHCI
#define CONFIG_LIBATA #define CONFIG_LIBATA
#define CONFIG_SCSI_AHCI #define CONFIG_SCSI_AHCI
#define CONFIG_SCSI_AHCI_PLAT #define CONFIG_SCSI_AHCI_PLAT
...@@ -247,13 +247,24 @@ ...@@ -247,13 +247,24 @@
DFU_ALT_INFO DFU_ALT_INFO
#endif #endif
/* SPL can't handle all huge variables - define just DFU */
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_DFU_SUPPORT)
#undef CONFIG_EXTRA_ENV_SETTINGS
# define CONFIG_EXTRA_ENV_SETTINGS \
"dfu_alt_info_ram=uboot.bin ram 0x8000000 0x1000000;" \
"atf-uboot.ub ram 0x10000000 0x1000000;" \
"Image ram 0x80000 0x3f80000;" \
"system.dtb ram 0x4000000 0x100000\0" \
"dfu_bufsiz=0x1000\0"
#endif
#define CONFIG_SPL_TEXT_BASE 0xfffc0000 #define CONFIG_SPL_TEXT_BASE 0xfffc0000
#define CONFIG_SPL_STACK 0xfffffffc #define CONFIG_SPL_STACK 0xfffffffc
#define CONFIG_SPL_MAX_SIZE 0x20000 #define CONFIG_SPL_MAX_SIZE 0x40000
/* Just random location in OCM */ /* Just random location in OCM */
#define CONFIG_SPL_BSS_START_ADDR 0x1000000 #define CONFIG_SPL_BSS_START_ADDR 0x0
#define CONFIG_SPL_BSS_MAX_SIZE 0x2000000 #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_FRAMEWORK
#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_BOARD_INIT
...@@ -265,7 +276,7 @@ ...@@ -265,7 +276,7 @@
#define CONFIG_SYS_SPL_ARGS_ADDR 0x8000000 #define CONFIG_SYS_SPL_ARGS_ADDR 0x8000000
/* ATF is my kernel image */ /* ATF is my kernel image */
#define CONFIG_SPL_FS_LOAD_KERNEL_NAME "atf.ub" #define CONFIG_SPL_FS_LOAD_KERNEL_NAME "atf-uboot.ub"
/* FIT load address for RAM boot */ /* FIT load address for RAM boot */
#define CONFIG_SPL_LOAD_FIT_ADDRESS 0x10000000 #define CONFIG_SPL_LOAD_FIT_ADDRESS 0x10000000
...@@ -279,4 +290,18 @@ ...@@ -279,4 +290,18 @@
# define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" # define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
#endif #endif
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_DFU_SUPPORT)
# undef CONFIG_CMD_BOOTD
# define CONFIG_SPL_ENV_SUPPORT
# define CONFIG_SPL_HASH_SUPPORT
# define CONFIG_ENV_MAX_ENTRIES 10
# define CONFIG_SYS_SPL_MALLOC_START 0x20000000
# define CONFIG_SYS_SPL_MALLOC_SIZE 0x10000000
#ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE
# error "Disable CONFIG_SPL_SYS_MALLOC_SIMPLE. Full malloc needs to be used"
#endif
#endif
#endif /* __XILINX_ZYNQMP_H */ #endif /* __XILINX_ZYNQMP_H */
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#define CONFIG_ZYNQ_SDHCI_MAX_FREQ 52000000 #define CONFIG_ZYNQ_SDHCI_MAX_FREQ 52000000
#define CONFIG_ZYNQ_SDHCI_MIN_FREQ (CONFIG_ZYNQ_SDHCI_MAX_FREQ << 9) #define CONFIG_ZYNQ_SDHCI_MIN_FREQ (CONFIG_ZYNQ_SDHCI_MAX_FREQ << 9)
#define CONFIG_ZYNQ_EEPROM #define CONFIG_ZYNQ_EEPROM
#define CONFIG_AHCI
#define CONFIG_SATA_CEVA #define CONFIG_SATA_CEVA
#define CONFIG_ZYNQMP_XHCI_LIST {ZYNQMP_USB0_XHCI_BASEADDR, \ #define CONFIG_ZYNQMP_XHCI_LIST {ZYNQMP_USB0_XHCI_BASEADDR, \
ZYNQMP_USB1_XHCI_BASEADDR} ZYNQMP_USB1_XHCI_BASEADDR}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment