]> git.sur5r.net Git - u-boot/commitdiff
Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze
authorTom Rini <trini@konsulko.com>
Thu, 22 Sep 2016 15:36:23 +0000 (11:36 -0400)
committerTom Rini <trini@konsulko.com>
Thu, 22 Sep 2016 15:36:23 +0000 (11:36 -0400)
23 files changed:
arch/arm/cpu/armv8/zynqmp/Kconfig
arch/arm/cpu/armv8/zynqmp/spl.c
arch/arm/include/asm/arch-zynqmp/hardware.h
arch/arm/include/asm/spl.h
board/xilinx/zynqmp/zynqmp.c
configs/xilinx_zynqmp_ep_defconfig
configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
configs/xilinx_zynqmp_zcu102_defconfig
configs/xilinx_zynqmp_zcu102_revB_defconfig
drivers/Kconfig
drivers/fpga/Kconfig [new file with mode: 0644]
drivers/fpga/Makefile
drivers/fpga/xilinx.c
drivers/fpga/zynqmppl.c [new file with mode: 0644]
drivers/spi/zynq_spi.c
include/configs/xilinx_zynqmp.h
include/configs/xilinx_zynqmp_ep.h
include/configs/xilinx_zynqmp_zc1751_xm018_dc4.h [deleted file]
include/xilinx.h
include/zynqmppl.h [new file with mode: 0644]

index e7039919c701df8c8a66a52bdc3c0039e0964715..1eedb39aa5a864ca91462efd8c1c12b3c23343f6 100644 (file)
@@ -47,5 +47,53 @@ config ZYNQMP_USB
 config SYS_MALLOC_F_LEN
        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
index 867d2b25a88d67d86873f346a899f77f4fe2a0bb..04e190537d15c47e9b976fd1a1fb14c73c9da41c 100644 (file)
@@ -35,10 +35,29 @@ void board_init_f(ulong dummy)
        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
 void spl_board_init(void)
 {
        preloader_console_init();
+       ps_mode_reset(MODE_RESET);
        board_init();
 }
 #endif
@@ -48,6 +67,13 @@ u32 spl_boot_device(void)
        u32 reg = 0;
        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);
        bootmode = reg & BOOT_MODES_MASK;
 
@@ -59,6 +85,10 @@ u32 spl_boot_device(void)
        case SD_MODE:
        case SD_MODE1:
                return BOOT_DEVICE_MMC1;
+#endif
+#ifdef CONFIG_SPL_DFU_SUPPORT
+       case USB_MODE:
+               return BOOT_DEVICE_DFU;
 #endif
        default:
                printf("Invalid Boot Mode:0x%x\n", bootmode);
index 35964d603b386c16b6ab93a3c5d0ff038faf5cb0..456c1b0902e578c985dba3af3115873863102748 100644 (file)
 
 #define ZYNQMP_CRL_APB_BASEADDR        0xFF5E0000
 #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 {
        u32 reserved0[36];
@@ -35,7 +42,9 @@ struct crlapb_regs {
        u32 boot_mode; /* 0x200 */
        u32 reserved3[14];
        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)
@@ -69,7 +78,10 @@ struct iou_scntr_secure {
 #define SD_MODE1       0x00000005 /* sd 1 */
 #define NAND_MODE      0x00000004
 #define EMMC_MODE      0x00000006
+#define USB_MODE       0x00000007
 #define JTAG_MODE      0x00000000
+#define BOOT_MODE_USE_ALT      0x100
+#define BOOT_MODE_ALT_SHIFT    12
 
 #define ZYNQMP_IOU_SLCR_BASEADDR       0xFF180000
 
index 19c38f4083c2d78aef27d3ea1317a4dff741e217..6f312d6652aa36c958ba86198b902d650ab4fe14 100644 (file)
@@ -28,6 +28,7 @@ enum {
        BOOT_DEVICE_SATA,
        BOOT_DEVICE_I2C,
        BOOT_DEVICE_BOARD,
+       BOOT_DEVICE_DFU,
        BOOT_DEVICE_NONE
 };
 #endif
index 0c5d9979316f2cd0a8f4fa0f2d3204ecb063f3c0..566b5e8d2afa4915bb13b6754ef43b323a1240d5 100644 (file)
 #include <asm/io.h>
 #include <usb.h>
 #include <dwc3-uboot.h>
+#include <zynqmppl.h>
 #include <i2c.h>
+#include <g_dnl.h>
 
 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)
 {
        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;
 }
 
@@ -228,6 +328,10 @@ int board_late_init(void)
 
        puts("Bootmode: ");
        switch (bootmode) {
+       case USB_MODE:
+               puts("USB_MODE\n");
+               mode = "usb";
+               break;
        case JTAG_MODE:
                puts("JTAG_MODE\n");
                mode = "pxe dhcp";
@@ -283,22 +387,38 @@ int checkboard(void)
 }
 
 #ifdef CONFIG_USB_DWC3
-static struct dwc3_device dwc3_device_data = {
+static struct dwc3_device dwc3_device_data0 = {
        .maximum_speed = USB_SPEED_HIGH,
        .base = ZYNQMP_USB0_XHCI_BASEADDR,
        .dr_mode = USB_DR_MODE_PERIPHERAL,
        .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;
 }
 
 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)
index 196eb6974e1f361d6bb1fb0e5fe51384b37fa0df..bd8b906a649d0cde3f0ef0a34f1024b0f1dc0d03 100644 (file)
@@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_ZYNQMP_USB=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep108"
+CONFIG_AHCI=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
@@ -46,6 +47,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BLK=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
index a3fb226e9183400868d8de7e86cc9dfe4e8d00f2..6afacd2d91aac103c24e80dc5ef24e2f2a62d1be 100644 (file)
@@ -38,6 +38,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BLK=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
index aec4f9b3ee63b220729db9f523ce4a9453b57389..4068c28818e90313168a717713d560a32992c169 100644 (file)
@@ -41,6 +41,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BLK=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
index 0b2ebb1a54b06ce457b412d7833f9ecc905f0a2e..c717f043bbf3908d37708584121633c4ae9d5414 100644 (file)
@@ -1,5 +1,4 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm018_dc4"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm018 dc4"
@@ -34,6 +33,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BLK=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
index f570b2aa424a34f09b6745e2f23fc6061509df36..1a27bd06ab927686de35a16ed323c1d1fde43782 100644 (file)
@@ -33,6 +33,8 @@ CONFIG_OF_EMBED=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BLK=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
index 8fcb2fd3eed1db4ea0ecce1fee910737dfa65857..90b5ff6c7603bfb882a718f2479980d5c39e76b4 100644 (file)
@@ -6,6 +6,7 @@ CONFIG_ZYNQMP_USB=y
 CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102"
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102"
+CONFIG_AHCI=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
@@ -38,6 +39,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BLK=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC_OPS=y
index b7ba599a091577ca2cbd92314336e65d58ac003c..5a0d686931580d14cf7a62ff7938a7260f7966bc 100644 (file)
@@ -6,6 +6,7 @@ CONFIG_ZYNQMP_USB=y
 CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102"
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
+CONFIG_AHCI=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
@@ -38,6 +39,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BLK=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC_OPS=y
index 4f84469955529ab449af1021080421d5faad6487..4c555a0c1f0617fdcc4d53bd6e713f8784fe806f 100644 (file)
@@ -20,6 +20,8 @@ source "drivers/dfu/Kconfig"
 
 source "drivers/dma/Kconfig"
 
+source "drivers/fpga/Kconfig"
+
 source "drivers/gpio/Kconfig"
 
 source "drivers/hwmon/Kconfig"
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
new file mode 100644 (file)
index 0000000..f3f6bf7
--- /dev/null
@@ -0,0 +1,20 @@
+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
index fec3fecbdfbf0e8b06a37bf332f1237458f84240..777706f186dd0b8fb1913ccc0029d77d72be83d2 100644 (file)
@@ -10,6 +10,7 @@ obj-$(CONFIG_FPGA_SPARTAN2) += spartan2.o
 obj-$(CONFIG_FPGA_SPARTAN3) += spartan3.o
 obj-$(CONFIG_FPGA_VIRTEX2) += virtex2.o
 obj-$(CONFIG_FPGA_ZYNQPL) += zynqpl.o
+obj-$(CONFIG_FPGA_ZYNQMPPL) += zynqmppl.o
 obj-$(CONFIG_FPGA_XILINX) += xilinx.o
 obj-$(CONFIG_FPGA_LATTICE) += ivm_core.o lattice.o
 ifdef CONFIG_FPGA_ALTERA
index d459a2f7a572180954bdc34a82fcf39c32be868e..2cd0104d8b154b35f8c85de42e50028ad614d57a 100644 (file)
@@ -199,6 +199,9 @@ int xilinx_info(xilinx_desc *desc)
                case xilinx_zynq:
                        printf("Zynq PL\n");
                        break;
+               case xilinx_zynqmp:
+                       printf("ZynqMP PL\n");
+                       break;
                        /* Add new family types here */
                default:
                        printf ("Unknown family type, %d\n", desc->family);
@@ -227,6 +230,9 @@ int xilinx_info(xilinx_desc *desc)
                case devcfg:
                        printf("Device configuration interface (Zynq)\n");
                        break;
+               case csu_dma:
+                       printf("csu_dma configuration interface (ZynqMP)\n");
+                       break;
                        /* Add new interface types here */
                default:
                        printf ("Unsupported interface type, %d\n", desc->iface);
diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c
new file mode 100644 (file)
index 0000000..23039c3
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * (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,
+};
index 09ae1be7e9875ed4d6acd2d7d0eae810561fefdb..7a176a2cd6dd2d1d1ebd694e83968c63aa4f7e17 100644 (file)
@@ -92,7 +92,8 @@ static void zynq_spi_init_hw(struct zynq_spi_priv *priv)
        u32 confr;
 
        /* Disable SPI */
-       writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, &regs->enr);
+       confr = ZYNQ_SPI_ENR_SPI_EN_MASK;
+       writel(~confr, &regs->enr);
 
        /* Disable Interrupts */
        writel(ZYNQ_SPI_IXR_ALL_MASK, &regs->idr);
@@ -173,8 +174,10 @@ static int zynq_spi_release_bus(struct udevice *dev)
        struct udevice *bus = dev->parent;
        struct zynq_spi_priv *priv = dev_get_priv(bus);
        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;
 }
index c43ea19807412e3fc2fc4496aee5a7b45006fdc3..5ed8beb9c2fa2f98dc38e7d4325ddedf02caaeb4 100644 (file)
@@ -75,7 +75,9 @@
 
 /* Diff from config_distro_defaults.h */
 #define CONFIG_SUPPORT_RAW_INITRD
+#if !defined(CONFIG_SPL_BUILD)
 #define CONFIG_ENV_VARS_UBOOT_CONFIG
+#endif
 #define CONFIG_AUTO_COMPLETE
 
 /* PXE */
 #define CONFIG_SYS_LOAD_ADDR           0x8000000
 
 #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_USB_XHCI_ZYNQMP
 
 # define DFU_ALT_INFO
 #endif
 
-
 #define CONFIG_BOARD_LATE_INIT
 
 /* Do not preserve environment */
 #endif
 
 #ifdef CONFIG_SATA_CEVA
-#define CONFIG_AHCI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
        DFU_ALT_INFO
 #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_STACK               0xfffffffc
-#define CONFIG_SPL_MAX_SIZE            0x20000
+#define CONFIG_SPL_MAX_SIZE            0x40000
 
 /* Just random location in OCM */
-#define CONFIG_SPL_BSS_START_ADDR      0x1000000
-#define CONFIG_SPL_BSS_MAX_SIZE                0x2000000
+#define CONFIG_SPL_BSS_START_ADDR      0x0
+#define CONFIG_SPL_BSS_MAX_SIZE                0x80000
 
 #define CONFIG_SPL_FRAMEWORK
 #define CONFIG_SPL_BOARD_INIT
 #define CONFIG_SYS_SPL_ARGS_ADDR       0x8000000
 
 /* 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 */
 #define CONFIG_SPL_LOAD_FIT_ADDRESS    0x10000000
 # define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME       "u-boot.img"
 #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 */
index 44434aab7bf02d5fbfde7b92d13f8f7d78a2f5fc..8e4b96033b8c9b04b1f614fee1b2b1db31680073 100644 (file)
@@ -16,7 +16,6 @@
 #define CONFIG_ZYNQ_SDHCI_MAX_FREQ     52000000
 #define CONFIG_ZYNQ_SDHCI_MIN_FREQ     (CONFIG_ZYNQ_SDHCI_MAX_FREQ << 9)
 #define CONFIG_ZYNQ_EEPROM
-#define CONFIG_AHCI
 #define CONFIG_SATA_CEVA
 #define CONFIG_ZYNQMP_XHCI_LIST {ZYNQMP_USB0_XHCI_BASEADDR, \
                                 ZYNQMP_USB1_XHCI_BASEADDR}
diff --git a/include/configs/xilinx_zynqmp_zc1751_xm018_dc4.h b/include/configs/xilinx_zynqmp_zc1751_xm018_dc4.h
deleted file mode 100644 (file)
index 4866b61..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Configuration for Xilinx ZynqMP zc1751 XM018 DC4
- *
- * (C) Copyright 2015 Xilinx, Inc.
- * Michal Simek <michal.simek@xilinx.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef __CONFIG_ZYNQMP_ZC1751_XM018_DC4_H
-#define __CONFIG_ZYNQMP_ZC1751_XM018_DC4_H
-
-#include <configs/xilinx_zynqmp.h>
-
-#endif /* __CONFIG_ZYNQMP_ZC1751_XM018_DC4_H */
index aebcb3bfdf29d7f87e4701fd01387bfe8f95b34a..d2a2ea71e1211a4b8382c3ec29297e86b9288984 100644 (file)
@@ -21,6 +21,7 @@ typedef enum {                        /* typedef xilinx_iface */
        master_selectmap,       /* master SelectMap (virtex2)           */
        slave_selectmap,        /* slave SelectMap (virtex2)            */
        devcfg,                 /* devcfg interface (zynq) */
+       csu_dma,                /* csu_dma interface (zynqmp) */
        max_xilinx_iface_type   /* insert all new types before this */
 } xilinx_iface;                        /* end, typedef xilinx_iface */
 
@@ -31,6 +32,7 @@ typedef enum {                        /* typedef xilinx_family */
        xilinx_virtex2,         /* Virtex2 Family */
        xilinx_spartan3,        /* Spartan-III Family */
        xilinx_zynq,            /* Zynq Family */
+       xilinx_zynqmp,          /* ZynqMP Family */
        max_xilinx_type         /* insert all new types before this */
 } xilinx_family;               /* end, typedef xilinx_family */
 
diff --git a/include/zynqmppl.h b/include/zynqmppl.h
new file mode 100644 (file)
index 0000000..542ace9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2015 Xilinx, Inc,
+ * Michal Simek <michal.simek@xilinx.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef _ZYNQMPPL_H_
+#define _ZYNQMPPL_H_
+
+#include <xilinx.h>
+
+#define ZYNQMP_SIP_SVC_CSU_DMA_CHIPID          0xC2000018
+#define ZYNQMP_SIP_SVC_PM_FPGA_LOAD            0xC2000016
+#define ZYNQMP_FPGA_OP_INIT                    (1 << 0)
+#define ZYNQMP_FPGA_OP_LOAD                    (1 << 1)
+#define ZYNQMP_FPGA_OP_DONE                    (1 << 2)
+
+extern struct xilinx_fpga_op zynqmp_op;
+
+#define XILINX_ZYNQMP_DESC \
+{ xilinx_zynqmp, csu_dma, 1, &zynqmp_op, 0, &zynqmp_op }
+
+#endif /* _ZYNQMPPL_H_ */