Merge tag 'xilinx-for-v2021.01-v2' of https://gitlab.denx.de/u-boot/custodians/u...
authorTom Rini <trini@konsulko.com>
Thu, 29 Oct 2020 15:30:15 +0000 (11:30 -0400)
committerTom Rini <trini@konsulko.com>
Thu, 29 Oct 2020 15:30:15 +0000 (11:30 -0400)
Xilinx changes for v2021.01-v2

common:
- Add support for 64bit loadables from SPL

xilinx:
- Update documentation and record ownership
- Enable eeprom board detection based legacy and fru formats
- Add support for FRU format

microblaze:
- Optimize low level ASM code
- Enable SPI/I2C
- Enable distro boot

zynq:
- Add support for Zturn V5

zynqmp:
- Improve silicon detection code
- Enable several kconfig options
- Align DT with the latest state
- Enabling security commands
- Enable and support FPGA loading from SPL
- Optimize xilinx_pm_request() calling

versal:
- Some DTs/Kconfig/defconfig alignments
- Add binding header for clock and power

zynq-sdhci:
- Add support for tap delay programming

zynq-spi/zynq-qspi:
- Use clock framework for getting clocks

xilinx-spi:
- Fix some code issues (unused variables)

serial:
- Check return value from clock functions in pl01x

74 files changed:
MAINTAINERS
arch/arm/dts/Makefile
arch/arm/dts/versal-mini-emmc0.dts
arch/arm/dts/versal-mini-emmc1.dts
arch/arm/dts/zynq-zturn-common.dtsi [new file with mode: 0644]
arch/arm/dts/zynq-zturn-v5.dts [new file with mode: 0644]
arch/arm/dts/zynq-zturn.dts
arch/arm/dts/zynqmp-mini-qspi.dts
arch/arm/mach-zynq/spl.c
arch/arm/mach-zynqmp/include/mach/sys_proto.h
arch/arm/mach-zynqmp/spl.c
arch/microblaze/Kconfig
arch/microblaze/cpu/start.S
board/xilinx/Kconfig
board/xilinx/common/Makefile [new file with mode: 0644]
board/xilinx/common/board.c
board/xilinx/common/board.h
board/xilinx/common/fru.c [new file with mode: 0644]
board/xilinx/common/fru.h [new file with mode: 0644]
board/xilinx/common/fru_ops.c [new file with mode: 0644]
board/xilinx/microblaze-generic/microblaze-generic.c
board/xilinx/versal/Makefile
board/xilinx/versal/board.c
board/xilinx/zynq/Makefile
board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c [new file with mode: 0644]
board/xilinx/zynqmp/MAINTAINERS
board/xilinx/zynqmp/Makefile
board/xilinx/zynqmp/cmds.c
board/xilinx/zynqmp/tap_delays.c
board/xilinx/zynqmp/zynqmp.c
common/fdt_support.c
common/image-fit.c
common/spl/spl_atf.c
common/spl/spl_fit.c
common/spl/spl_opensbi.c
configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig
configs/microblaze-generic_defconfig
configs/syzygy_hub_defconfig
configs/xilinx_versal_mini_defconfig
configs/xilinx_versal_mini_emmc0_defconfig
configs/xilinx_versal_mini_emmc1_defconfig
configs/xilinx_versal_virt_defconfig
configs/xilinx_zynq_virt_defconfig
configs/xilinx_zynqmp_virt_defconfig
doc/board/xilinx/index.rst
doc/board/xilinx/xilinx.rst
doc/board/xilinx/zynq.rst
doc/board/xilinx/zynqmp-r5.rst [new file with mode: 0644]
doc/board/xilinx/zynqmp.rst [new file with mode: 0644]
doc/uImage.FIT/howto.txt
drivers/core/ofnode.c
drivers/firmware/firmware-zynqmp.c
drivers/mailbox/zynqmp-ipi.c
drivers/misc/Kconfig
drivers/mmc/sdhci.c
drivers/mmc/zynq_sdhci.c
drivers/mtd/spi/sf_internal.h
drivers/serial/serial_pl01x.c
drivers/spi/xilinx_spi.c
drivers/spi/zynq_qspi.c
drivers/spi/zynq_spi.c
include/configs/microblaze-generic.h
include/configs/xilinx_versal.h
include/configs/xilinx_versal_mini.h
include/configs/xilinx_zynqmp_mini.h
include/dm/ofnode.h
include/dt-bindings/clock/xlnx-versal-clk.h [new file with mode: 0644]
include/dt-bindings/power/xlnx-versal-power.h [new file with mode: 0644]
include/mmc.h
include/sdhci.h
include/u-boot/rsa-mod-exp.h
include/zynqmp_tap_delay.h
lib/rsa/rsa-mod-exp.c
test/dm/ofnode.c

index 857e236..1505e74 100644 (file)
@@ -546,6 +546,7 @@ M:  Michal Simek <monstr@monstr.eu>
 S:     Maintained
 T:     git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
 F:     arch/arm/mach-zynq/
+F:     doc/board/xilinx/
 F:     drivers/clk/clk_zynq.c
 F:     drivers/fpga/zynqpl.c
 F:     drivers/gpio/zynq_gpio.c
index d8b0a91..bd97604 100644 (file)
@@ -279,6 +279,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
        zynq-zc770-xm013.dtb \
        zynq-zed.dtb \
        zynq-zturn.dtb \
+       zynq-zturn-v5.dtb \
        zynq-zybo.dtb \
        zynq-zybo-z7.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += \
index 7826a28..6a6e746 100644 (file)
        #size-cells = <2>;
        model = "Xilinx Versal MINI eMMC0";
 
-       clk25: clk25 {
+       clk200: clk200 {
                compatible = "fixed-clock";
                #clock-cells = <0x0>;
-               clock-frequency = <25000000>;
+               clock-frequency = <200000000>;
        };
 
        dcc: dcc {
                sdhci0: sdhci@f1040000 {
                        compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
                        status = "okay";
+                       non-removable;
+                       disable-wp;
+                       bus-width = <8>;
                        reg = <0x0 0xf1040000 0x0 0x10000>;
                        clock-names = "clk_xin", "clk_ahb";
-                       clocks = <&clk25 &clk25>;
+                       clocks = <&clk200 &clk200>;
                        xlnx,device_id = <0>;
                        no-1-8-v;
                        xlnx,mio-bank = <0>;
index 2f28f85..c342e6b 100644 (file)
        #size-cells = <2>;
        model = "Xilinx Versal MINI eMMC1";
 
-       clk25: clk25 {
+       clk200: clk200 {
                compatible = "fixed-clock";
                #clock-cells = <0x0>;
-               clock-frequency = <25000000>;
+               clock-frequency = <200000000>;
        };
 
        dcc: dcc {
                sdhci1: sdhci@f1050000 {
                        compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
                        status = "okay";
+                       non-removable;
+                       disable-wp;
+                       bus-width = <8>;
                        reg = <0x0 0xf1050000 0x0 0x10000>;
                        clock-names = "clk_xin", "clk_ahb";
-                       clocks = <&clk25 &clk25>;
+                       clocks = <&clk200 &clk200>;
                        xlnx,device_id = <1>;
                        no-1-8-v;
                        xlnx,mio-bank = <0>;
diff --git a/arch/arm/dts/zynq-zturn-common.dtsi b/arch/arm/dts/zynq-zturn-common.dtsi
new file mode 100644 (file)
index 0000000..1d7af02
--- /dev/null
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Copyright (C) 2015 Andrea Merello <adnrea.merello@gmail.com>
+ *  Copyright (C) 2017 Alexander Graf <agraf@suse.de>
+ *
+ *  Based on zynq-zed.dts which is:
+ *  Copyright (C) 2011 - 2014 Xilinx
+ *  Copyright (C) 2012 National Instruments Corp.
+ *
+ */
+
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+       compatible = "xlnx,zynq-7000";
+
+       aliases {
+               ethernet0 = &gem0;
+               serial0 = &uart1;
+               serial1 = &uart0;
+               mmc0 = &sdhci0;
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x40000000>;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               usr-led1 {
+                       label = "usr-led1";
+                       gpios = <&gpio0 0x0 0x1>;
+                       default-state = "off";
+               };
+
+               usr-led2 {
+                       label = "usr-led2";
+                       gpios = <&gpio0 0x9 0x1>;
+                       default-state = "off";
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               autorepeat;
+               K1 {
+                       label = "K1";
+                       gpios = <&gpio0 0x32 0x1>;
+                       linux,code = <0x66>;
+                       wakeup-source;
+                       autorepeat;
+               };
+       };
+};
+
+&clkc {
+       ps-clk-frequency = <33333333>;
+};
+
+&qspi {
+       u-boot,dm-pre-reloc;
+       status = "okay";
+};
+
+&gem0 {
+       status = "okay";
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethernet_phy>;
+
+       ethernet_phy: ethernet-phy@0 {
+       };
+};
+
+&sdhci0 {
+       u-boot,dm-pre-reloc;
+       status = "okay";
+};
+
+&uart0 {
+       u-boot,dm-pre-reloc;
+       status = "okay";
+};
+
+&uart1 {
+       u-boot,dm-pre-reloc;
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&can0 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       stlm75@49 {
+               status = "okay";
+               compatible = "lm75";
+               reg = <0x49>;
+       };
+
+       accelerometer@53 {
+               compatible = "adi,adxl345", "adxl345", "adi,adxl34x", "adxl34x";
+               reg = <0x53>;
+               interrupt-parent = <&intc>;
+               interrupts = <0x0 0x1e 0x4>;
+       };
+};
diff --git a/arch/arm/dts/zynq-zturn-v5.dts b/arch/arm/dts/zynq-zturn-v5.dts
new file mode 100644 (file)
index 0000000..536632a
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/dts-v1/;
+/include/ "zynq-zturn-common.dtsi"
+
+/ {
+       model = "Zynq Z-Turn MYIR Board V5";
+       compatible = "myir,zynq-zturn-v5", "xlnx,zynq-7000";
+};
+
+&gem0 {
+       ethernet_phy: ethernet-phy@0 {
+               reg = <0x3>;
+       };
+};
index 600e8ee..620b24a 100644 (file)
 // SPDX-License-Identifier: GPL-2.0
-/*
- *  Copyright (C) 2015 Andrea Merello <adnrea.merello@gmail.com>
- *  Copyright (C) 2017 Alexander Graf <agraf@suse.de>
- *
- *  Based on zynq-zed.dts which is:
- *  Copyright (C) 2011 - 2014 Xilinx
- *  Copyright (C) 2012 National Instruments Corp.
- *
- */
 
 /dts-v1/;
-/include/ "zynq-7000.dtsi"
+/include/ "zynq-zturn-common.dtsi"
 
 / {
        model = "Zynq Z-Turn MYIR Board";
        compatible = "myir,zynq-zturn", "xlnx,zynq-7000";
-
-       aliases {
-               ethernet0 = &gem0;
-               serial0 = &uart1;
-               serial1 = &uart0;
-               mmc0 = &sdhci0;
-       };
-
-       memory@0 {
-               device_type = "memory";
-               reg = <0x0 0x40000000>;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       gpio-leds {
-               compatible = "gpio-leds";
-               usr-led1 {
-                       label = "usr-led1";
-                       gpios = <&gpio0 0x0 0x1>;
-                       default-state = "off";
-               };
-
-               usr-led2 {
-                       label = "usr-led2";
-                       gpios = <&gpio0 0x9 0x1>;
-                       default-state = "off";
-               };
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-               autorepeat;
-               K1 {
-                       label = "K1";
-                       gpios = <&gpio0 0x32 0x1>;
-                       linux,code = <0x66>;
-                       wakeup-source;
-                       autorepeat;
-               };
-       };
-};
-
-&clkc {
-       ps-clk-frequency = <33333333>;
-};
-
-&qspi {
-       u-boot,dm-pre-reloc;
-       status = "okay";
 };
 
 &gem0 {
-       status = "okay";
-       phy-mode = "rgmii-id";
-       phy-handle = <&ethernet_phy>;
-
        ethernet_phy: ethernet-phy@0 {
                reg = <0x0>;
        };
 };
-
-&sdhci0 {
-       u-boot,dm-pre-reloc;
-       status = "okay";
-};
-
-&uart0 {
-       u-boot,dm-pre-reloc;
-       status = "okay";
-};
-
-&uart1 {
-       u-boot,dm-pre-reloc;
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-       dr_mode = "host";
-};
-
-&can0 {
-       status = "okay";
-};
-
-&i2c0 {
-       status = "okay";
-       clock-frequency = <400000>;
-
-       stlm75@49 {
-               status = "okay";
-               compatible = "lm75";
-               reg = <0x49>;
-       };
-
-       accelerometer@53 {
-               compatible = "adi,adxl345", "adxl345", "adi,adxl34x", "adxl34x";
-               reg = <0x53>;
-               interrupt-parent = <&intc>;
-               interrupts = <0x0 0x1e 0x4>;
-       };
-};
index a76e640..9b4320f 100644 (file)
@@ -70,7 +70,7 @@
                reg = <0x0>;
                spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
-               spi-max-frequency = <108000000>;
+               spi-max-frequency = <40000000>;
        };
 };
 
index cb8cfd2..d09141c 100644 (file)
@@ -9,7 +9,6 @@
 #include <init.h>
 #include <log.h>
 #include <spl.h>
-#include <generated/dt.h>
 
 #include <asm/io.h>
 #include <asm/spl.h>
@@ -86,16 +85,3 @@ void spl_board_prepare_for_boot(void)
        ps7_post_config();
        debug("SPL bye\n");
 }
-
-#ifdef CONFIG_SPL_LOAD_FIT
-int board_fit_config_name_match(const char *name)
-{
-       /* Just empty function now - can't decide what to choose */
-       debug("%s: Check %s, default %s\n", __func__, name, DEVICE_TREE);
-
-       if (!strcmp(name, DEVICE_TREE))
-               return 0;
-
-       return -1;
-}
-#endif
index f2b3cea..1c12eac 100644 (file)
@@ -9,6 +9,16 @@
 
 #define ZYNQMP_CSU_SILICON_VER_MASK    0xF
 #define KEY_PTR_LEN    32
+#define IV_SIZE                12
+#define RSA_KEY_SIZE   512
+#define MODULUS_LEN    512
+#define PRIV_EXPO_LEN  512
+#define PUB_EXPO_LEN   4
+
+#define ZYNQMP_SHA3_INIT       1
+#define ZYNQMP_SHA3_UPDATE     2
+#define ZYNQMP_SHA3_FINAL      4
+#define ZYNQMP_SHA3_SIZE       48
 
 #define ZYNQMP_FPGA_BIT_AUTH_DDR       1
 #define ZYNQMP_FPGA_BIT_AUTH_OCM       2
index 9dd61e2..88386b2 100644 (file)
@@ -119,13 +119,3 @@ int spl_start_uboot(void)
        return 0;
 }
 #endif
-
-#ifdef CONFIG_SPL_LOAD_FIT
-int board_fit_config_name_match(const char *name)
-{
-       /* Just empty function now - can't decide what to choose */
-       debug("%s: %s\n", __func__, name);
-
-       return -1;
-}
-#endif
index ff6b3c7..99a17bc 100644 (file)
@@ -16,10 +16,14 @@ config TARGET_MICROBLAZE_GENERIC
        select OF_CONTROL
        select SUPPORT_SPL
        select SYSRESET
+       select DM_SPI
+       select DM_SPI_FLASH
+       select SPI
        imply CMD_DM
 
 endchoice
 
+source "board/xilinx/Kconfig"
 source "board/xilinx/microblaze-generic/Kconfig"
 
 endmenu
index cbec299..9479737 100644 (file)
        .text
        .global _start
 _start:
-       /*
-        * reserve registers:
-        * r10: Stores little/big endian offset for vectors
-        * r2: Stores imm opcode
-        * r3: Stores brai opcode
-        */
-
        mts     rmsr, r0        /* disable cache */
 
        addi    r8, r0, __end
        mts     rslr, r8
-       /* TODO: Redo this code to call board_init_f_*() */
+
 #if defined(CONFIG_SPL_BUILD)
        addi    r1, r0, CONFIG_SPL_STACK_ADDR
-       mts     rshr, r1
-       addi    r1, r1, -4      /* Decrement SP to top of memory */
-#else
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
-       addi    r1, r0, CONFIG_SYS_INIT_SP_OFFSET - CONFIG_VAL(SYS_MALLOC_F_LEN)
 #else
        addi    r1, r0, CONFIG_SYS_INIT_SP_OFFSET
 #endif
-       mts     rshr, r1
+
        addi    r1, r1, -4      /* Decrement SP to top of memory */
 
+       /* Call board_init_f_alloc_reserve with the current stack pointer as
+        * parameter. */
+       add     r5, r0, r1
+       bralid  r15, board_init_f_alloc_reserve
+       nop
+
+       /* board_init_f_alloc_reserve returns a pointer to the allocated area
+        * in r3. Set the new stack pointer below this area. */
+       add     r1, r0, r3
+       mts     rshr, r1
+       addi    r1, r1, -4
+
+       /* Call board_init_f_init_reserve with the address returned by
+        * board_init_f_alloc_reserve as parameter. */
+       add     r5, r0, r3
+       bralid  r15, board_init_f_init_reserve
+       nop
+
+#if !defined(CONFIG_SPL_BUILD)
+       /* Setup vectors with pre-relocation symbols */
+       or      r5, r0, r0
+       bralid  r15, __setup_exceptions
+       nop
+#endif
+
+       /* Flush cache before enable cache */
+       addik   r5, r0, 0
+       addik   r6, r0, XILINX_DCACHE_BYTE_SIZE
+       bralid  r15, flush_cache
+       nop
+
+       /* enable instruction and data cache */
+       mfs     r12, rmsr
+       ori     r12, r12, 0x1a0
+       mts     rmsr, r12
+
+clear_bss:
+       /* clear BSS segments */
+       addi    r5, r0, __bss_start
+       addi    r4, r0, __bss_end
+       cmp     r6, r5, r4
+       beqi    r6, 3f
+2:
+       swi     r0, r5, 0 /* write zero to loc */
+       addi    r5, r5, 4 /* increment to next loc */
+       cmp     r6, r5, r4 /* check if we have reach the end */
+       bnei    r6, 2b
+3:     /* jumping to board_init */
+#ifdef CONFIG_DEBUG_UART
+       bralid  r15, debug_uart_init
+       nop
+#endif
+#ifndef CONFIG_SPL_BUILD
+       or      r5, r0, r0      /* flags - empty */
+       brai    board_init_f
+#else
+       brai    board_init_r
+#endif
+1:     bri     1b
+
+#ifndef CONFIG_SPL_BUILD
+       .text
+       .ent    __setup_exceptions
+       .align  2
+/*
+ * Set up reset, interrupt, user exception and hardware exception vectors.
+ *
+ * Parameters:
+ * r5 - relocation offset (zero when setting up vectors before
+ *      relocation, and gd->reloc_off when setting up vectors after
+ *      relocation)
+ *    - the relocation offset is added to the _exception_handler,
+ *      _interrupt_handler and _hw_exception_handler symbols to reflect the
+ *      post-relocation memory addresses
+ *
+ * Reserve registers:
+ * r10: Stores little/big endian offset for vectors
+ * r2: Stores imm opcode
+ * r3: Stores brai opcode
+ */
+__setup_exceptions:
+       addik   r1, r1, -28
+       swi     r2, r1, 4
+       swi     r3, r1, 8
+       swi     r6, r1, 12
+       swi     r7, r1, 16
+       swi     r8, r1, 20
+       swi     r10, r1, 24
+
        /* Find-out if u-boot is running on BIG/LITTLE endian platform
         * There are some steps which is necessary to keep in mind:
         * 1. Setup offset value to r6
@@ -76,7 +153,7 @@ _start:
        swi     r2, r0, 0x8     /* user vector exception - imm opcode */
        swi     r3, r0, 0xC     /* user vector exception - brai opcode */
 
-       addik   r6, r0, _exception_handler
+       addik   r6, r5, _exception_handler
        sw      r6, r1, r0
        /*
         * BIG ENDIAN memory map for user exception
@@ -109,7 +186,7 @@ _start:
        swi     r2, r0, 0x10    /* interrupt - imm opcode */
        swi     r3, r0, 0x14    /* interrupt - brai opcode */
 
-       addik   r6, r0, _interrupt_handler
+       addik   r6, r5, _interrupt_handler
        sw      r6, r1, r0
        lhu     r7, r1, r10
        rsubi   r8, r10, 0x12
@@ -121,67 +198,26 @@ _start:
        swi     r2, r0, 0x20    /* hardware exception - imm opcode */
        swi     r3, r0, 0x24    /* hardware exception - brai opcode */
 
-       addik   r6, r0, _hw_exception_handler
+       addik   r6, r5, _hw_exception_handler
        sw      r6, r1, r0
        lhu     r7, r1, r10
        rsubi   r8, r10, 0x22
        sh      r7, r0, r8
        rsubi   r8, r10, 0x26
        sh      r6, r0, r8
-#endif /* CONFIG_SPL_BUILD */
-
-       /* Flush cache before enable cache */
-       addik   r5, r0, 0
-       addik   r6, r0, XILINX_DCACHE_BYTE_SIZE
-       bralid r15, flush_cache
-       nop
-
-       /* enable instruction and data cache */
-       mfs     r12, rmsr
-       ori     r12, r12, 0x1a0
-       mts     rmsr, r12
 
-       /* TODO: Redo this code to call board_init_f_*() */
-clear_bss:
-       /* clear BSS segments */
-       addi    r5, r0, __bss_start
-       addi    r4, r0, __bss_end
-       cmp     r6, r5, r4
-       beqi    r6, 3f
-2:
-       swi     r0, r5, 0 /* write zero to loc */
-       addi    r5, r5, 4 /* increment to next loc */
-       cmp     r6, r5, r4 /* check if we have reach the end */
-       bnei    r6, 2b
-3:     /* jumping to board_init */
-#ifdef CONFIG_DEBUG_UART
-       bralid  r15, debug_uart_init
-       nop
-#endif
-#ifndef CONFIG_SPL_BUILD
-       or      r5, r0, r0      /* flags - empty */
-       addi    r31, r0, _gd
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
-       addi    r6, r0, CONFIG_SYS_INIT_SP_OFFSET
-       swi     r6, r31, GD_MALLOC_BASE
-#endif
-       brai    board_init_f
-#else
-       addi    r31, r0, _gd
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
-       addi    r6, r0, CONFIG_SPL_STACK_ADDR
-       swi     r6, r31, GD_MALLOC_BASE
-#endif
-       brai    board_init_r
-#endif
-1:     bri     1b
+       lwi     r10, r1, 24
+       lwi     r8, r1, 20
+       lwi     r7, r1, 16
+       lwi     r6, r1, 12
+       lwi     r3, r1, 8
+       lwi     r2, r1, 4
+       addik   r1, r1, 28
 
- .section .bss
-.align 4
-_gd:
-         .space  GENERATED_GBL_DATA_SIZE
+       rtsd    r15, 8
+       or      r0, r0, r0
+       .end    __setup_exceptions
 
-#ifndef CONFIG_SPL_BUILD
 /*
  * Read 16bit little endian
  */
@@ -249,39 +285,10 @@ relocate_code:
        addi    r24, r0, CONFIG_SYS_TEXT_BASE /* Get reloc offset */
        rsub    r23, r24, r23 /* keep - this is already here gd->reloc_off */
 
-       addik   r6, r0, 0x2 /* BIG/LITTLE endian offset */
-       lwi     r7, r0, 0x28
-       swi     r6, r0, 0x28 /* used first unused MB vector */
-       lbui    r10, r0, 0x28 /* used first unused MB vector */
-       swi     r7, r0, 0x28
-
-#ifdef CONFIG_SYS_USR_EXCEP
-       addik   r6, r0, _exception_handler
-       addk    r6, r6, r23 /* add offset */
-       sw      r6, r1, r0
-       lhu     r7, r1, r10
-       rsubi   r8, r10, 0xa
-       sh      r7, r0, r8
-       rsubi   r8, r10, 0xe
-       sh      r6, r0, r8
-#endif
-       addik   r6, r0, _hw_exception_handler
-       addk    r6, r6, r23 /* add offset */
-       sw      r6, r1, r0
-       lhu     r7, r1, r10
-       rsubi   r8, r10, 0x22
-       sh      r7, r0, r8
-       rsubi   r8, r10, 0x26
-       sh      r6, r0, r8
-
-       addik   r6, r0, _interrupt_handler
-       addk    r6, r6, r23 /* add offset */
-       sw      r6, r1, r0
-       lhu     r7, r1, r10
-       rsubi   r8, r10, 0x12
-       sh      r7, r0, r8
-       rsubi   r8, r10, 0x16
-       sh      r6, r0, r8
+       /* Setup vectors with post-relocation symbols */
+       add     r5, r0, r23 /* load gd->reloc_off to r5 */
+       bralid  r15, __setup_exceptions
+       nop
 
        /* Check if GOT exist */
        addik   r21, r23, _got_start
index c80d0a8..64507b5 100644 (file)
@@ -50,9 +50,34 @@ config XILINX_OF_BOARD_DTB_ADDR
 
 config BOOT_SCRIPT_OFFSET
        hex "Boot script offset"
-       depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
-       default 0xFC0000 if ARCH_ZYNQ
+       depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || MICROBLAZE
+       default 0xFC0000 if ARCH_ZYNQ || MICROBLAZE
        default 0x3E80000 if ARCH_ZYNQMP
        default 0x7F80000 if ARCH_VERSAL
        help
-          Specifies distro boot script offset in NAND/NOR flash.
+          Specifies distro boot script offset in NAND/QSPI/NOR flash.
+
+config ZYNQ_MAC_IN_EEPROM
+       bool "Reading MAC address from EEPROM"
+       help
+         Enable this option if your MAC address is saved in eeprom and
+         xlnx,eeprom DT property in chosen node points to it.
+
+if ZYNQ_MAC_IN_EEPROM
+
+config ZYNQ_GEM_I2C_MAC_OFFSET
+       hex "Set the I2C MAC offset"
+       default 0x0
+       depends on DM_I2C
+       help
+         Set the MAC offset for i2C.
+
+endif
+
+config CMD_FRU
+       bool "FRU information for product"
+       help
+         This option enables FRU commands to capture and display FRU
+         information present in the device. The FRU Information is used
+         to primarily to provide "inventory" information about the boards
+         that the FRU Information Device is located on.
diff --git a/board/xilinx/common/Makefile b/board/xilinx/common/Makefile
new file mode 100644 (file)
index 0000000..2120284
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# (C) Copyright 2020 Xilinx, Inc.
+# Michal Simek <michal.simek@xilinx.com>
+#
+
+obj-y  += board.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_CMD_FRU) += fru.o fru_ops.o
+endif
index b0f60c4..cdc06a3 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2014 - 2019 Xilinx, Inc.
+ * (C) Copyright 2014 - 2020 Xilinx, Inc.
  * Michal Simek <michal.simek@xilinx.com>
  */
 
 #include <dm/uclass.h>
 #include <i2c.h>
 #include <linux/sizes.h>
+#include <malloc.h>
 #include "board.h"
+#include <dm.h>
+#include <i2c_eeprom.h>
+#include <net.h>
+#include <generated/dt.h>
+
+#include "fru.h"
 
 #if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
@@ -41,6 +48,277 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
 }
 #endif
 
+#define EEPROM_HEADER_MAGIC            0xdaaddeed
+#define EEPROM_HDR_MANUFACTURER_LEN    16
+#define EEPROM_HDR_NAME_LEN            16
+#define EEPROM_HDR_REV_LEN             8
+#define EEPROM_HDR_SERIAL_LEN          20
+#define EEPROM_HDR_NO_OF_MAC_ADDR      4
+#define EEPROM_HDR_ETH_ALEN            ETH_ALEN
+
+struct xilinx_board_description {
+       u32 header;
+       char manufacturer[EEPROM_HDR_MANUFACTURER_LEN + 1];
+       char name[EEPROM_HDR_NAME_LEN + 1];
+       char revision[EEPROM_HDR_REV_LEN + 1];
+       char serial[EEPROM_HDR_SERIAL_LEN + 1];
+       u8 mac_addr[EEPROM_HDR_NO_OF_MAC_ADDR][EEPROM_HDR_ETH_ALEN + 1];
+};
+
+static int highest_id = -1;
+static struct xilinx_board_description **board_info;
+
+#define XILINX_I2C_DETECTION_BITS      sizeof(struct fru_common_hdr)
+
+/* Variable which stores pointer to array which stores eeprom content */
+struct xilinx_legacy_format {
+       char board_sn[18]; /* 0x0 */
+       char unused0[14]; /* 0x12 */
+       char eth_mac[6]; /* 0x20 */
+       char unused1[170]; /* 0x26 */
+       char board_name[11]; /* 0xd0 */
+       char unused2[5]; /* 0xdc */
+       char board_revision[3]; /* 0xe0 */
+       char unused3[29]; /* 0xe3 */
+};
+
+static void xilinx_eeprom_legacy_cleanup(char *eeprom, int size)
+{
+       int i;
+       char byte;
+
+       for (i = 0; i < size; i++) {
+               byte = eeprom[i];
+
+               /* Remove all ffs and spaces */
+               if (byte == 0xff || byte == ' ')
+                       eeprom[i] = 0;
+
+               /* Convert strings to lower case */
+               if (byte >= 'A' && byte <= 'Z')
+                       eeprom[i] = byte + 'a' - 'A';
+       }
+}
+
+static int xilinx_read_eeprom_legacy(struct udevice *dev, char *name,
+                                    struct xilinx_board_description *desc)
+{
+       int ret, size;
+       struct xilinx_legacy_format *eeprom_content;
+       bool eth_valid = false;
+
+       size = sizeof(*eeprom_content);
+
+       eeprom_content = calloc(1, size);
+       if (!eeprom_content)
+               return -ENOMEM;
+
+       debug("%s: I2C EEPROM read pass data at %p\n", __func__,
+             eeprom_content);
+
+       ret = dm_i2c_read(dev, 0, (uchar *)eeprom_content, size);
+       if (ret) {
+               debug("%s: I2C EEPROM read failed\n", __func__);
+               free(eeprom_content);
+               return ret;
+       }
+
+       xilinx_eeprom_legacy_cleanup((char *)eeprom_content, size);
+
+       printf("Xilinx I2C Legacy format at %s:\n", name);
+       printf(" Board name:\t%s\n", eeprom_content->board_name);
+       printf(" Board rev:\t%s\n", eeprom_content->board_revision);
+       printf(" Board SN:\t%s\n", eeprom_content->board_sn);
+
+       eth_valid = is_valid_ethaddr((const u8 *)eeprom_content->eth_mac);
+       if (eth_valid)
+               printf(" Ethernet mac:\t%pM\n", eeprom_content->eth_mac);
+
+       /* Terminating \0 chars ensure end of string */
+       strcpy(desc->name, eeprom_content->board_name);
+       strcpy(desc->revision, eeprom_content->board_revision);
+       strcpy(desc->serial, eeprom_content->board_sn);
+       if (eth_valid)
+               memcpy(desc->mac_addr[0], eeprom_content->eth_mac, ETH_ALEN);
+
+       desc->header = EEPROM_HEADER_MAGIC;
+
+       free(eeprom_content);
+
+       return ret;
+}
+
+static bool xilinx_detect_legacy(u8 *buffer)
+{
+       int i;
+       char c;
+
+       for (i = 0; i < XILINX_I2C_DETECTION_BITS; i++) {
+               c = buffer[i];
+
+               if (c < '0' || c > '9')
+                       return false;
+       }
+
+       return true;
+}
+
+static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
+                                 struct xilinx_board_description *desc)
+{
+       int ret, eeprom_size;
+       u8 *fru_content;
+
+       /* FIXME this is shortcut - if eeprom type is wrong it will fail */
+       eeprom_size = i2c_eeprom_size(dev);
+
+       fru_content = calloc(1, eeprom_size);
+       if (!fru_content)
+               return -ENOMEM;
+
+       debug("%s: I2C EEPROM read pass data at %p\n", __func__,
+             fru_content);
+
+       ret = dm_i2c_read(dev, 0, (uchar *)fru_content,
+                         eeprom_size);
+       if (ret) {
+               debug("%s: I2C EEPROM read failed\n", __func__);
+               free(fru_content);
+               return ret;
+       }
+
+       printf("Xilinx I2C FRU format at %s:\n", name);
+       fru_capture((unsigned long)fru_content);
+       ret = fru_display(0);
+       if (ret) {
+               printf("FRU format decoding failed.\n");
+               return ret;
+       }
+
+       if (desc->header == EEPROM_HEADER_MAGIC) {
+               debug("Information already filled\n");
+               return -EINVAL;
+       }
+
+       /* It is clear that FRU was captured and structures were filled */
+       strncpy(desc->manufacturer, (char *)fru_data.brd.manufacturer_name,
+               sizeof(desc->manufacturer));
+       strncpy(desc->name, (char *)fru_data.brd.product_name,
+               sizeof(desc->name));
+       strncpy(desc->revision, (char *)fru_data.brd.rev,
+               sizeof(desc->revision));
+       strncpy(desc->serial, (char *)fru_data.brd.serial_number,
+               sizeof(desc->serial));
+       desc->header = EEPROM_HEADER_MAGIC;
+
+       return 0;
+}
+
+static bool xilinx_detect_fru(u8 *buffer)
+{
+       u8 checksum = 0;
+       int i;
+
+       checksum = fru_checksum((u8 *)buffer, sizeof(struct fru_common_hdr));
+       if (checksum) {
+               debug("%s Common header CRC FAIL\n", __func__);
+               return false;
+       }
+
+       bool all_zeros = true;
+       /* Checksum over all zeros is also zero that's why detect this case */
+       for (i = 0; i < sizeof(struct fru_common_hdr); i++) {
+               if (buffer[i] != 0)
+                       all_zeros = false;
+       }
+
+       if (all_zeros)
+               return false;
+
+       debug("%s Common header CRC PASS\n", __func__);
+       return true;
+}
+
+static int xilinx_read_eeprom_single(char *name,
+                                    struct xilinx_board_description *desc)
+{
+       int ret;
+       struct udevice *dev;
+       ofnode eeprom;
+       u8 buffer[XILINX_I2C_DETECTION_BITS];
+
+       eeprom = ofnode_get_aliases_node(name);
+       if (!ofnode_valid(eeprom))
+               return -ENODEV;
+
+       ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev);
+       if (ret)
+               return ret;
+
+       ret = dm_i2c_read(dev, 0, buffer, sizeof(buffer));
+       if (ret) {
+               debug("%s: I2C EEPROM read failed\n", __func__);
+               return ret;
+       }
+
+       debug("%s: i2c memory detected: %s\n", __func__, name);
+
+       if (CONFIG_IS_ENABLED(CMD_FRU) && xilinx_detect_fru(buffer))
+               return xilinx_read_eeprom_fru(dev, name, desc);
+
+       if (xilinx_detect_legacy(buffer))
+               return xilinx_read_eeprom_legacy(dev, name, desc);
+
+       return -ENODEV;
+}
+
+__maybe_unused int xilinx_read_eeprom(void)
+{
+       int id, ret;
+       char name_buf[8]; /* 8 bytes should be enough for nvmem+number */
+       struct xilinx_board_description *desc;
+
+       highest_id = dev_read_alias_highest_id("nvmem");
+       /* No nvmem aliases present */
+       if (highest_id < 0)
+               return -EINVAL;
+
+       board_info = calloc(1, sizeof(desc) * highest_id);
+       if (!board_info)
+               return -ENOMEM;
+
+       debug("%s: Highest ID %d, board_info %p\n", __func__,
+             highest_id, board_info);
+
+       for (id = 0; id <= highest_id; id++) {
+               snprintf(name_buf, sizeof(name_buf), "nvmem%d", id);
+
+               /* Alloc structure */
+               desc = board_info[id];
+               if (!desc) {
+                       desc = calloc(1, sizeof(*desc));
+                       if (!desc)
+                               return -ENOMEM;
+
+                       board_info[id] = desc;
+               }
+
+               /* Ignoring return value for supporting multiple chips */
+               ret = xilinx_read_eeprom_single(name_buf, desc);
+               if (ret) {
+                       free(desc);
+                       board_info[id] = NULL;
+               }
+       }
+
+       /*
+        * Consider to clean board_info structure when board/cards are not
+        * detected.
+        */
+
+       return 0;
+}
+
 #if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
 void *board_fdt_blob_setup(void)
 {
@@ -75,12 +353,36 @@ void *board_fdt_blob_setup(void)
 }
 #endif
 
+#if defined(CONFIG_BOARD_LATE_INIT)
+static int env_set_by_index(const char *name, int index, char *data)
+{
+       char var[32];
+
+       if (!index)
+               sprintf(var, "board_%s", name);
+       else
+               sprintf(var, "card%d_%s", index, name);
+
+       return env_set(var, data);
+}
+
 int board_late_init_xilinx(void)
 {
        u32 ret = 0;
+       int i, id, macid = 0;
+       struct xilinx_board_description *desc;
        phys_size_t bootm_size = gd->ram_size;
+       struct bd_info *bd = gd->bd;
+
+       if (!CONFIG_IS_ENABLED(MICROBLAZE) && bd->bi_dram[0].start) {
+               ulong scriptaddr;
 
-       if (CONFIG_IS_ENABLED(ARCH_ZYNQ))
+               scriptaddr = env_get_hex("scriptaddr", 0);
+               ret |= env_set_hex("scriptaddr",
+                                  bd->bi_dram[0].start + scriptaddr);
+       }
+
+       if (CONFIG_IS_ENABLED(ARCH_ZYNQ) || CONFIG_IS_ENABLED(MICROBLAZE))
                bootm_size = min(bootm_size, (phys_size_t)(SZ_512M + SZ_256M));
 
        ret |= env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
@@ -88,8 +390,49 @@ int board_late_init_xilinx(void)
        ret |= env_set_addr("bootm_low", (void *)gd->ram_base);
        ret |= env_set_addr("bootm_size", (void *)bootm_size);
 
+       for (id = 0; id <= highest_id; id++) {
+               desc = board_info[id];
+               if (desc && desc->header == EEPROM_HEADER_MAGIC) {
+                       if (desc->manufacturer[0])
+                               ret |= env_set_by_index("manufacturer", id,
+                                                       desc->manufacturer);
+                       if (desc->name[0])
+                               ret |= env_set_by_index("name", id,
+                                                       desc->name);
+                       if (desc->revision[0])
+                               ret |= env_set_by_index("rev", id,
+                                                       desc->revision);
+                       if (desc->serial[0])
+                               ret |= env_set_by_index("serial", id,
+                                                       desc->serial);
+
+                       if (!CONFIG_IS_ENABLED(NET))
+                               continue;
+
+                       for (i = 0; i < EEPROM_HDR_NO_OF_MAC_ADDR; i++) {
+                               if (!desc->mac_addr[i])
+                                       continue;
+
+                               if (is_valid_ethaddr((const u8 *)desc->mac_addr[i]))
+                                       ret |= eth_env_set_enetaddr_by_index("eth",
+                                                       macid++, desc->mac_addr[i]);
+                       }
+               }
+       }
+
        if (ret)
                printf("%s: Saving run time variables FAILED\n", __func__);
 
        return 0;
 }
+#endif
+
+int __maybe_unused board_fit_config_name_match(const char *name)
+{
+       debug("%s: Check %s, default %s\n", __func__, name, DEVICE_TREE);
+
+       if (!strcmp(name, DEVICE_TREE))
+               return 0;
+
+       return -1;
+}
index 180dfbc..69e6424 100644 (file)
@@ -9,4 +9,6 @@
 
 int board_late_init_xilinx(void);
 
+int xilinx_read_eeprom(void);
+
 #endif /* BOARD_XILINX_COMMON_BOARD_H */
diff --git a/board/xilinx/common/fru.c b/board/xilinx/common/fru.c
new file mode 100644 (file)
index 0000000..ccf4872
--- /dev/null
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2019 - 2020 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fdtdec.h>
+#include <malloc.h>
+
+#include "fru.h"
+
+static int do_fru_capture(struct cmd_tbl *cmdtp, int flag, int argc,
+                         char *const argv[])
+{
+       unsigned long addr;
+       char *endp;
+
+       if (argc < cmdtp->maxargs)
+               return CMD_RET_USAGE;
+
+       addr = simple_strtoul(argv[2], &endp, 16);
+       if (*argv[1] == 0 || *endp != 0)
+               return -1;
+
+       return fru_capture(addr);
+}
+
+static int do_fru_display(struct cmd_tbl *cmdtp, int flag, int argc,
+                         char *const argv[])
+{
+       fru_display(1);
+       return CMD_RET_SUCCESS;
+}
+
+static int do_fru_generate(struct cmd_tbl *cmdtp, int flag, int argc,
+                          char *const argv[])
+{
+       unsigned long addr;
+
+       if (argc < cmdtp->maxargs)
+               return CMD_RET_USAGE;
+
+       addr = simple_strtoul(argv[2], NULL, 16);
+
+       return fru_generate(addr, argv[3], argv[4], argv[5], argv[6], argv[7]);
+}
+
+static struct cmd_tbl cmd_fru_sub[] = {
+       U_BOOT_CMD_MKENT(capture, 3, 0, do_fru_capture, "", ""),
+       U_BOOT_CMD_MKENT(display, 2, 0, do_fru_display, "", ""),
+       U_BOOT_CMD_MKENT(board_gen, 8, 0, do_fru_generate, "", ""),
+};
+
+static int do_fru(struct cmd_tbl *cmdtp, int flag, int argc,
+                 char *const argv[])
+{
+       struct cmd_tbl *c;
+       int ret;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       c = find_cmd_tbl(argv[1], &cmd_fru_sub[0],
+                        ARRAY_SIZE(cmd_fru_sub));
+       if (!c)
+               return CMD_RET_USAGE;
+
+       ret = c->cmd(c, flag, argc, argv);
+
+       return cmd_process_error(c, ret);
+}
+
+/***************************************************/
+#ifdef CONFIG_SYS_LONGHELP
+static char fru_help_text[] =
+       "capture <addr> - Parse and capture FRU table present at address.\n"
+       "fru display - Displays content of FRU table that was captured using\n"
+       "              fru capture command\n"
+       "fru board_gen <addr> <manufacturer> <board name> <serial number>\n"
+       "              <part number> <revision> - Generate FRU format with\n"
+       "              board info area filled based on parameters. <addr> is\n"
+       "              pointing to place where FRU is generated.\n"
+       ;
+#endif
+
+U_BOOT_CMD(
+       fru, 8, 1, do_fru,
+       "FRU table info",
+       fru_help_text
+)
diff --git a/board/xilinx/common/fru.h b/board/xilinx/common/fru.h
new file mode 100644 (file)
index 0000000..a3e6520
--- /dev/null
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Xilinx, Inc.
+ * Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
+ */
+
+#ifndef __FRU_H
+#define __FRU_H
+
+struct fru_common_hdr {
+       u8 version;
+       u8 off_internal;
+       u8 off_chassis;
+       u8 off_board;
+       u8 off_product;
+       u8 off_multirec;
+       u8 pad;
+       u8 crc;
+};
+
+#define FRU_BOARD_MAX_LEN      32
+
+struct __packed fru_board_info_header {
+       u8 ver;
+       u8 len;
+       u8 lang_code;
+       u8 time[3];
+};
+
+struct __packed fru_board_info_member {
+       u8 type_len;
+       u8 *name;
+};
+
+struct fru_board_data {
+       u8 ver;
+       u8 len;
+       u8 lang_code;
+       u8 time[3];
+       u8 manufacturer_type_len;
+       u8 manufacturer_name[FRU_BOARD_MAX_LEN];
+       u8 product_name_type_len;
+       u8 product_name[FRU_BOARD_MAX_LEN];
+       u8 serial_number_type_len;
+       u8 serial_number[FRU_BOARD_MAX_LEN];
+       u8 part_number_type_len;
+       u8 part_number[FRU_BOARD_MAX_LEN];
+       u8 file_id_type_len;
+       u8 file_id[FRU_BOARD_MAX_LEN];
+       /* Xilinx custom fields */
+       u8 rev_type_len;
+       u8 rev[FRU_BOARD_MAX_LEN];
+};
+
+struct fru_table {
+       bool captured;
+       struct fru_common_hdr hdr;
+       struct fru_board_data brd;
+};
+
+#define FRU_TYPELEN_CODE_MASK  0xC0
+#define FRU_TYPELEN_LEN_MASK   0x3F
+#define FRU_COMMON_HDR_VER_MASK                0xF
+#define FRU_COMMON_HDR_LEN_MULTIPLIER  8
+#define FRU_LANG_CODE_ENGLISH          0
+#define FRU_LANG_CODE_ENGLISH_1                25
+#define FRU_TYPELEN_EOF                        0xC1
+
+/* This should be minimum of fields */
+#define FRU_BOARD_AREA_TOTAL_FIELDS    5
+#define FRU_TYPELEN_TYPE_SHIFT         6
+#define FRU_TYPELEN_TYPE_BINARY                0
+#define FRU_TYPELEN_TYPE_ASCII8                3
+
+int fru_display(int verbose);
+int fru_capture(unsigned long addr);
+int fru_generate(unsigned long addr, char *manufacturer, char *board_name,
+                char *serial_no, char *part_no, char *revision);
+u8 fru_checksum(u8 *addr, u8 len);
+
+extern struct fru_table fru_data;
+
+#endif /* FRU_H */
diff --git a/board/xilinx/common/fru_ops.c b/board/xilinx/common/fru_ops.c
new file mode 100644 (file)
index 0000000..fc3add7
--- /dev/null
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2019 - 2020 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#include "fru.h"
+
+struct fru_table fru_data __section(.data);
+
+static u16 fru_cal_area_len(u8 len)
+{
+       return len * FRU_COMMON_HDR_LEN_MULTIPLIER;
+}
+
+static u8 fru_version(u8 ver)
+{
+       return ver & FRU_COMMON_HDR_VER_MASK;
+}
+
+static int fru_check_language(u8 code)
+{
+       if (code != FRU_LANG_CODE_ENGLISH && code != FRU_LANG_CODE_ENGLISH_1) {
+               printf("FRU_ERROR: Only English Language is supported\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+u8 fru_checksum(u8 *addr, u8 len)
+{
+       u8 checksum = 0;
+
+       while (len--) {
+               checksum += *addr;
+               addr++;
+       }
+
+       return checksum;
+}
+
+static int fru_check_type_len(u8 type_len, u8 language, u8 *type)
+{
+       int len;
+
+       if (type_len == FRU_TYPELEN_EOF)
+               return -EINVAL;
+
+       *type = (type_len & FRU_TYPELEN_CODE_MASK) >> FRU_TYPELEN_TYPE_SHIFT;
+
+       len = type_len & FRU_TYPELEN_LEN_MASK;
+
+       return len;
+}
+
+/* Return len */
+static u8 fru_gen_type_len(u8 *addr, char *name)
+{
+       int len = strlen(name);
+       struct fru_board_info_member *member;
+
+       member = (struct fru_board_info_member *)addr;
+       member->type_len = FRU_TYPELEN_TYPE_ASCII8 << FRU_TYPELEN_TYPE_SHIFT;
+       member->type_len |= len;
+
+       debug("%lx/%lx: Add %s to 0x%lx (len 0x%x)\n", (ulong)addr,
+             (ulong)&member->type_len,  name, (ulong)&member->name, len);
+       memcpy(&member->name, name, len);
+
+       /* Add +1 for type_len parameter */
+       return 1 + len;
+}
+
+int fru_generate(unsigned long addr, char *manufacturer, char *board_name,
+                char *serial_no, char *part_no, char *revision)
+{
+       struct fru_common_hdr *header = (struct fru_common_hdr *)addr;
+       struct fru_board_info_header *board_info;
+       u8 *member;
+       u8 len, pad, modulo;
+
+       header->version = 1; /* Only version 1.0 is supported now */
+       header->off_internal = 0; /* not present */
+       header->off_chassis = 0; /* not present */
+       header->off_board = (sizeof(*header)) / 8; /* Starting offset 8 */
+       header->off_product = 0; /* not present */
+       header->off_multirec = 0; /* not present */
+       header->pad = 0;
+       /*
+        * This unsigned byte can be used to calculate a zero checksum
+        * for the data area following the header. I.e. the modulo 256 sum of
+        * the record data bytes plus the checksum byte equals zero.
+        */
+       header->crc = 0; /* Clear before calculation */
+       header->crc = 0 - fru_checksum((u8 *)header, sizeof(*header));
+
+       /* board info is just right after header */
+       board_info = (void *)((u8 *)header + sizeof(*header));
+
+       debug("header %lx, board_info %lx\n", (ulong)header, (ulong)board_info);
+
+       board_info->ver = 1; /* 1.0 spec */
+       board_info->lang_code = 0; /* English */
+       board_info->time[0] = 0; /* unspecified */
+       board_info->time[1] = 0; /* unspecified */
+       board_info->time[2] = 0; /* unspecified */
+
+       /* Member fields are just after board_info header */
+       member = (u8 *)board_info + sizeof(*board_info);
+
+       len = fru_gen_type_len(member, manufacturer); /* Board Manufacturer */
+       member += len;
+       len = fru_gen_type_len(member, board_name); /* Board Product name */
+       member += len;
+       len = fru_gen_type_len(member, serial_no); /* Board Serial number */
+       member += len;
+       len = fru_gen_type_len(member, part_no); /* Board part number */
+       member += len;
+       len = fru_gen_type_len(member, "U-Boot generator"); /* File ID */
+       member += len;
+       len = fru_gen_type_len(member, revision); /* Revision */
+       member += len;
+
+       *member++ = 0xc1; /* Indication of no more fields */
+
+       len = member - (u8 *)board_info; /* Find current length */
+       len += 1; /* Add checksum there too for calculation */
+
+       modulo = len % 8;
+
+       if (modulo) {
+               /* Do not fill last item which is checksum */
+               for (pad = 0; pad < 8 - modulo; pad++)
+                       *member++ = 0;
+
+               /* Increase structure size */
+               len += 8 - modulo;
+       }
+
+       board_info->len = len / 8; /* Size in multiples of 8 bytes */
+
+       *member = 0; /* Clear before calculation */
+       *member = 0 - fru_checksum((u8 *)board_info, len);
+
+       debug("checksum %x(addr %x)\n", *member, len);
+
+       env_set_hex("fru_addr", addr);
+       env_set_hex("filesize", (unsigned long)member - addr + 1);
+
+       return 0;
+}
+
+static int fru_parse_board(unsigned long addr)
+{
+       u8 i, type;
+       int len;
+       u8 *data, *term;
+
+       memcpy(&fru_data.brd.ver, (void *)addr, 6);
+       addr += 6;
+       data = (u8 *)&fru_data.brd.manufacturer_type_len;
+
+       for (i = 0; ; i++, data += FRU_BOARD_MAX_LEN) {
+               len = fru_check_type_len(*(u8 *)addr, fru_data.brd.lang_code,
+                                        &type);
+               /*
+                * Stop cature if it end of fields
+                */
+               if (len == -EINVAL)
+                       break;
+
+               /* This record type/len field */
+               *data++ = *(u8 *)addr;
+
+               /* Add offset to match data */
+               addr += 1;
+
+               /* If len is 0 it means empty field that's why skip writing */
+               if (!len)
+                       continue;
+
+               /* Record data field */
+               memcpy(data, (u8 *)addr, len);
+               term = data + (u8)len;
+               *term = 0;
+               addr += len;
+       }
+
+       if (i < FRU_BOARD_AREA_TOTAL_FIELDS) {
+               printf("Board area require minimum %d fields\n",
+                      FRU_BOARD_AREA_TOTAL_FIELDS);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int fru_capture(unsigned long addr)
+{
+       struct fru_common_hdr *hdr;
+       u8 checksum = 0;
+
+       checksum = fru_checksum((u8 *)addr, sizeof(struct fru_common_hdr));
+       if (checksum) {
+               printf("%s Common header CRC error\n", __func__);
+               return -EINVAL;
+       }
+
+       hdr = (struct fru_common_hdr *)addr;
+
+       memcpy((void *)&fru_data.hdr, (void *)hdr,
+              sizeof(struct fru_common_hdr));
+
+       fru_data.captured = true;
+
+       if (hdr->off_board) {
+               addr += fru_cal_area_len(hdr->off_board);
+               fru_parse_board(addr);
+       }
+
+       env_set_hex("fru_addr", addr);
+
+       return 0;
+}
+
+static int fru_display_board(struct fru_board_data *brd, int verbose)
+{
+       u32 time = 0;
+       u8 type;
+       int len;
+       u8 *data;
+       static const char * const typecode[] = {
+               "Binary/Unspecified",
+               "BCD plus",
+               "6-bit ASCII",
+               "8-bit ASCII",
+               "2-byte UNICODE"
+       };
+       static const char * const boardinfo[] = {
+               "Manufacturer Name",
+               "Product Name",
+               "Serial No",
+               "Part Number",
+               "File ID",
+               /* Xilinx spec */
+               "Revision Number",
+       };
+
+       if (verbose) {
+               printf("*****BOARD INFO*****\n");
+               printf("Version:%d\n", fru_version(brd->ver));
+               printf("Board Area Length:%d\n", fru_cal_area_len(brd->len));
+       }
+
+       if (fru_check_language(brd->lang_code))
+               return -EINVAL;
+
+       time = brd->time[2] << 16 | brd->time[1] << 8 |
+              brd->time[0];
+
+       if (verbose)
+               printf("Time in Minutes from 0:00hrs 1/1/96: %d\n", time);
+
+       data = (u8 *)&brd->manufacturer_type_len;
+
+       for (u8 i = 0; i < (sizeof(boardinfo) / sizeof(*boardinfo)); i++) {
+               len = fru_check_type_len(*data++, brd->lang_code,
+                                        &type);
+               if (len == -EINVAL) {
+                       printf("**** EOF for Board Area ****\n");
+                       break;
+               }
+
+               if (type <= FRU_TYPELEN_TYPE_ASCII8 &&
+                   (brd->lang_code == FRU_LANG_CODE_ENGLISH ||
+                    brd->lang_code == FRU_LANG_CODE_ENGLISH_1))
+                       debug("Type code: %s\n", typecode[type]);
+               else
+                       debug("Type code: %s\n", typecode[type + 1]);
+
+               if (!len) {
+                       debug("%s not found\n", boardinfo[i]);
+                       continue;
+               }
+
+               switch (type) {
+               case FRU_TYPELEN_TYPE_BINARY:
+                       debug("Length: %d\n", len);
+                       printf(" %s: 0x%x\n", boardinfo[i], *data);
+                       break;
+               case FRU_TYPELEN_TYPE_ASCII8:
+                       debug("Length: %d\n", len);
+                       printf(" %s: %s\n", boardinfo[i], data);
+                       break;
+               default:
+                       debug("Unsupported type %x\n", type);
+               }
+
+               data += FRU_BOARD_MAX_LEN;
+       }
+
+       return 0;
+}
+
+static void fru_display_common_hdr(struct fru_common_hdr *hdr, int verbose)
+{
+       if (!verbose)
+               return;
+
+       printf("*****COMMON HEADER*****\n");
+       printf("Version:%d\n", fru_version(hdr->version));
+       if (hdr->off_internal)
+               printf("Internal Use Area Offset:%d\n",
+                      fru_cal_area_len(hdr->off_internal));
+       else
+               printf("*** No Internal Area ***\n");
+
+       if (hdr->off_chassis)
+               printf("Chassis Info Area Offset:%d\n",
+                      fru_cal_area_len(hdr->off_chassis));
+       else
+               printf("*** No Chassis Info Area ***\n");
+
+       if (hdr->off_board)
+               printf("Board Area Offset:%d\n",
+                      fru_cal_area_len(hdr->off_board));
+       else
+               printf("*** No Board Area ***\n");
+
+       if (hdr->off_product)
+               printf("Product Info Area Offset:%d\n",
+                      fru_cal_area_len(hdr->off_product));
+       else
+               printf("*** No Product Info Area ***\n");
+
+       if (hdr->off_multirec)
+               printf("MultiRecord Area Offset:%d\n",
+                      fru_cal_area_len(hdr->off_multirec));
+       else
+               printf("*** No MultiRecord Area ***\n");
+}
+
+int fru_display(int verbose)
+{
+       if (!fru_data.captured) {
+               printf("FRU data not available please run fru parse\n");
+               return -EINVAL;
+       }
+
+       fru_display_common_hdr(&fru_data.hdr, verbose);
+
+       return fru_display_board(&fru_data.brd, verbose);
+}
index 4e569e9..e590999 100644 (file)
@@ -18,6 +18,7 @@
 #include <dm/lists.h>
 #include <fdtdec.h>
 #include <linux/sizes.h>
+#include "../common/board.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -36,7 +37,8 @@ int dram_init(void)
 
 int board_late_init(void)
 {
-       ulong max_size, lowmem_size;
+       ulong max_size;
+       u32 status = 0;
 
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYSRESET_MICROBLAZE)
        int ret;
@@ -55,12 +57,19 @@ int board_late_init(void)
        max_size = gd->start_addr_sp - CONFIG_STACK_SIZE;
        max_size = round_down(max_size, SZ_16M);
 
-       /* Linux default LOWMEM_SIZE is 0x30000000 = 768MB */
-       lowmem_size = gd->ram_base + 768 * 1024 * 1024;
+       status |= env_set_hex("scriptaddr", max_size + SZ_2M);
 
-       env_set_addr("initrd_high", (void *)min_t(ulong, max_size,
-                                                 lowmem_size));
-       env_set_addr("fdt_high", (void *)min_t(ulong, max_size, lowmem_size));
+       status |= env_set_hex("pxefile_addr_r", max_size + SZ_1M);
 
-       return 0;
+       status |= env_set_hex("kernel_addr_r", gd->ram_base + SZ_32M);
+
+       status |= env_set_hex("fdt_addr_r", gd->ram_base + SZ_32M - SZ_1M);
+
+       status |= env_set_hex("ramdisk_addr_r",
+                              gd->ram_base + SZ_32M + SZ_4M + SZ_2M);
+
+       if (status)
+               printf("%s: Saving run time variables FAILED\n", __func__);
+
+       return board_late_init_xilinx();
 }
index 90e0343..4a46ca0 100644 (file)
@@ -6,4 +6,3 @@
 
 obj-y  := board.o
 obj-$(CONFIG_CMD_VERSAL)       += cmds.o
-obj-y  += ../common/board.o
index a5ca4ca..912c114 100644 (file)
@@ -36,6 +36,9 @@ int board_init(void)
        fpga_add(fpga_xilinx, &versalpl);
 #endif
 
+       if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
+               xilinx_read_eeprom();
+
        return 0;
 }
 
index 096a7ac..8566171 100644 (file)
@@ -4,7 +4,6 @@
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
 obj-y  := board.o
-obj-y  += ../common/board.o
 
 ifneq ($(CONFIG_XILINX_PS_INIT_FILE),"")
 PS_INIT_FILE := $(shell cd $(srctree); readlink -f $(CONFIG_XILINX_PS_INIT_FILE))
diff --git a/board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c b/board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c
new file mode 100644 (file)
index 0000000..5d57386
--- /dev/null
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Xilinx, Inc.
+ */
+
+#include <asm/arch/ps7_init_gpl.h>
+
+static unsigned long ps7_pll_init_data[] = {
+       EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+       EMIT_MASKWRITE(0xF8000110, 0x003FFFF0U, 0x000FA220U),
+       EMIT_MASKWRITE(0xF8000100, 0x0007F000U, 0x00028000U),
+       EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000010U),
+       EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000001U),
+       EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000000U),
+       EMIT_MASKPOLL(0xF800010C, 0x00000001U),
+       EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000000U),
+       EMIT_MASKWRITE(0xF8000120, 0x1F003F30U, 0x1F000200U),
+       EMIT_MASKWRITE(0xF8000114, 0x003FFFF0U, 0x0012C220U),
+       EMIT_MASKWRITE(0xF8000104, 0x0007F000U, 0x00020000U),
+       EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000010U),
+       EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000001U),
+       EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000000U),
+       EMIT_MASKPOLL(0xF800010C, 0x00000002U),
+       EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000000U),
+       EMIT_MASKWRITE(0xF8000124, 0xFFF00003U, 0x0C200003U),
+       EMIT_MASKWRITE(0xF8000118, 0x003FFFF0U, 0x001452C0U),
+       EMIT_MASKWRITE(0xF8000108, 0x0007F000U, 0x0001E000U),
+       EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000010U),
+       EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000001U),
+       EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000000U),
+       EMIT_MASKPOLL(0xF800010C, 0x00000004U),
+       EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000000U),
+       EMIT_WRITE(0xF8000004, 0x0000767BU),
+       EMIT_EXIT(),
+};
+
+static unsigned long ps7_clock_init_data[] = {
+       EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+       EMIT_MASKWRITE(0xF8000128, 0x03F03F01U, 0x00700F01U),
+       EMIT_MASKWRITE(0xF8000138, 0x00000011U, 0x00000001U),
+       EMIT_MASKWRITE(0xF8000140, 0x03F03F71U, 0x00100801U),
+       EMIT_MASKWRITE(0xF800014C, 0x00003F31U, 0x00000501U),
+       EMIT_MASKWRITE(0xF8000150, 0x00003F33U, 0x00001401U),
+       EMIT_MASKWRITE(0xF8000154, 0x00003F33U, 0x00000A03U),
+       EMIT_MASKWRITE(0xF800015C, 0x03F03F33U, 0x00200501U),
+       EMIT_MASKWRITE(0xF8000160, 0x007F007FU, 0x00000000U),
+       EMIT_MASKWRITE(0xF8000168, 0x00003F31U, 0x00000501U),
+       EMIT_MASKWRITE(0xF8000170, 0x03F03F30U, 0x00200500U),
+       EMIT_MASKWRITE(0xF8000180, 0x03F03F30U, 0x00400500U),
+       EMIT_MASKWRITE(0xF80001C4, 0x00000001U, 0x00000001U),
+       EMIT_MASKWRITE(0xF800012C, 0x01FFCCCDU, 0x01FD044DU),
+       EMIT_WRITE(0xF8000004, 0x0000767BU),
+       EMIT_EXIT(),
+};
+
+static unsigned long ps7_ddr_init_data[] = {
+       EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000080U),
+       EMIT_MASKWRITE(0xF8006004, 0x0007FFFFU, 0x00001082U),
+       EMIT_MASKWRITE(0xF8006008, 0x03FFFFFFU, 0x03C0780FU),
+       EMIT_MASKWRITE(0xF800600C, 0x03FFFFFFU, 0x02001001U),
+       EMIT_MASKWRITE(0xF8006010, 0x03FFFFFFU, 0x00014001U),
+       EMIT_MASKWRITE(0xF8006014, 0x001FFFFFU, 0x0004285BU),
+       EMIT_MASKWRITE(0xF8006018, 0xF7FFFFFFU, 0x44E458D3U),
+       EMIT_MASKWRITE(0xF800601C, 0xFFFFFFFFU, 0x7282BCE5U),
+       EMIT_MASKWRITE(0xF8006020, 0x7FDFFFFCU, 0x270872D0U),
+       EMIT_MASKWRITE(0xF8006024, 0x0FFFFFC3U, 0x00000000U),
+       EMIT_MASKWRITE(0xF8006028, 0x00003FFFU, 0x00002007U),
+       EMIT_MASKWRITE(0xF800602C, 0xFFFFFFFFU, 0x00000008U),
+       EMIT_MASKWRITE(0xF8006030, 0xFFFFFFFFU, 0x00040B30U),
+       EMIT_MASKWRITE(0xF8006034, 0x13FF3FFFU, 0x000116D4U),
+       EMIT_MASKWRITE(0xF8006038, 0x00000003U, 0x00000000U),
+       EMIT_MASKWRITE(0xF800603C, 0x000FFFFFU, 0x00000777U),
+       EMIT_MASKWRITE(0xF8006040, 0xFFFFFFFFU, 0xFFF00000U),
+       EMIT_MASKWRITE(0xF8006044, 0x0FFFFFFFU, 0x0F666666U),
+       EMIT_MASKWRITE(0xF8006048, 0x0003F03FU, 0x0003C008U),
+       EMIT_MASKWRITE(0xF8006050, 0xFF0F8FFFU, 0x77010800U),
+       EMIT_MASKWRITE(0xF8006058, 0x00010000U, 0x00000000U),
+       EMIT_MASKWRITE(0xF800605C, 0x0000FFFFU, 0x00005003U),
+       EMIT_MASKWRITE(0xF8006060, 0x000017FFU, 0x0000003EU),
+       EMIT_MASKWRITE(0xF8006064, 0x00021FE0U, 0x00020000U),
+       EMIT_MASKWRITE(0xF8006068, 0x03FFFFFFU, 0x00284141U),
+       EMIT_MASKWRITE(0xF800606C, 0x0000FFFFU, 0x00001610U),
+       EMIT_MASKWRITE(0xF8006078, 0x03FFFFFFU, 0x00466111U),
+       EMIT_MASKWRITE(0xF800607C, 0x000FFFFFU, 0x00032222U),
+       EMIT_MASKWRITE(0xF80060A4, 0xFFFFFFFFU, 0x10200802U),
+       EMIT_MASKWRITE(0xF80060A8, 0x0FFFFFFFU, 0x0690CB73U),
+       EMIT_MASKWRITE(0xF80060AC, 0x000001FFU, 0x000001FEU),
+       EMIT_MASKWRITE(0xF80060B0, 0x1FFFFFFFU, 0x1CFFFFFFU),
+       EMIT_MASKWRITE(0xF80060B4, 0x00000200U, 0x00000200U),
+       EMIT_MASKWRITE(0xF80060B8, 0x01FFFFFFU, 0x00200066U),
+       EMIT_MASKWRITE(0xF80060C4, 0x00000003U, 0x00000000U),
+       EMIT_MASKWRITE(0xF80060C8, 0x000000FFU, 0x00000000U),
+       EMIT_MASKWRITE(0xF80060DC, 0x00000001U, 0x00000000U),
+       EMIT_MASKWRITE(0xF80060F0, 0x0000FFFFU, 0x00000000U),
+       EMIT_MASKWRITE(0xF80060F4, 0x0000000FU, 0x00000008U),
+       EMIT_MASKWRITE(0xF8006114, 0x000000FFU, 0x00000000U),
+       EMIT_MASKWRITE(0xF8006118, 0x7FFFFFCFU, 0x40000001U),
+       EMIT_MASKWRITE(0xF800611C, 0x7FFFFFCFU, 0x40000001U),
+       EMIT_MASKWRITE(0xF8006120, 0x7FFFFFCFU, 0x40000001U),
+       EMIT_MASKWRITE(0xF8006124, 0x7FFFFFCFU, 0x40000001U),
+       EMIT_MASKWRITE(0xF800612C, 0x000FFFFFU, 0x0002A81FU),
+       EMIT_MASKWRITE(0xF8006130, 0x000FFFFFU, 0x00029822U),
+       EMIT_MASKWRITE(0xF8006134, 0x000FFFFFU, 0x00026C10U),
+       EMIT_MASKWRITE(0xF8006138, 0x000FFFFFU, 0x00026013U),
+       EMIT_MASKWRITE(0xF8006140, 0x000FFFFFU, 0x00000035U),
+       EMIT_MASKWRITE(0xF8006144, 0x000FFFFFU, 0x00000035U),
+       EMIT_MASKWRITE(0xF8006148, 0x000FFFFFU, 0x00000035U),
+       EMIT_MASKWRITE(0xF800614C, 0x000FFFFFU, 0x00000035U),
+       EMIT_MASKWRITE(0xF8006154, 0x000FFFFFU, 0x0000009FU),
+       EMIT_MASKWRITE(0xF8006158, 0x000FFFFFU, 0x000000A2U),
+       EMIT_MASKWRITE(0xF800615C, 0x000FFFFFU, 0x00000090U),
+       EMIT_MASKWRITE(0xF8006160, 0x000FFFFFU, 0x00000093U),
+       EMIT_MASKWRITE(0xF8006168, 0x001FFFFFU, 0x000000FFU),
+       EMIT_MASKWRITE(0xF800616C, 0x001FFFFFU, 0x000000FBU),
+       EMIT_MASKWRITE(0xF8006170, 0x001FFFFFU, 0x000000F0U),
+       EMIT_MASKWRITE(0xF8006174, 0x001FFFFFU, 0x000000EDU),
+       EMIT_MASKWRITE(0xF800617C, 0x000FFFFFU, 0x000000DFU),
+       EMIT_MASKWRITE(0xF8006180, 0x000FFFFFU, 0x000000E2U),
+       EMIT_MASKWRITE(0xF8006184, 0x000FFFFFU, 0x000000D0U),
+       EMIT_MASKWRITE(0xF8006188, 0x000FFFFFU, 0x000000D3U),
+       EMIT_MASKWRITE(0xF8006190, 0x6FFFFEFEU, 0x00040080U),
+       EMIT_MASKWRITE(0xF8006194, 0x000FFFFFU, 0x0001FC82U),
+       EMIT_MASKWRITE(0xF8006204, 0xFFFFFFFFU, 0x00000000U),
+       EMIT_MASKWRITE(0xF8006208, 0x000703FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF800620C, 0x000703FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF8006210, 0x000703FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF8006214, 0x000703FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF8006218, 0x000F03FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF800621C, 0x000F03FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF8006220, 0x000F03FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF8006224, 0x000F03FFU, 0x000003FFU),
+       EMIT_MASKWRITE(0xF80062A8, 0x00000FF5U, 0x00000000U),
+       EMIT_MASKWRITE(0xF80062AC, 0xFFFFFFFFU, 0x00000000U),
+       EMIT_MASKWRITE(0xF80062B0, 0x003FFFFFU, 0x00005125U),
+       EMIT_MASKWRITE(0xF80062B4, 0x0003FFFFU, 0x000012A8U),
+       EMIT_MASKPOLL(0xF8000B74, 0x00002000U),
+       EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000081U),
+       EMIT_MASKPOLL(0xF8006054, 0x00000007U),
+       EMIT_EXIT(),
+};
+
+static unsigned long ps7_mio_init_data[] = {
+       EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+       EMIT_MASKWRITE(0xF8000B40, 0x00000FFFU, 0x00000600U),
+       EMIT_MASKWRITE(0xF8000B44, 0x00000FFFU, 0x00000600U),
+       EMIT_MASKWRITE(0xF8000B48, 0x00000FFFU, 0x00000672U),
+       EMIT_MASKWRITE(0xF8000B4C, 0x00000FFFU, 0x00000672U),
+       EMIT_MASKWRITE(0xF8000B50, 0x00000FFFU, 0x00000674U),
+       EMIT_MASKWRITE(0xF8000B54, 0x00000FFFU, 0x00000674U),
+       EMIT_MASKWRITE(0xF8000B58, 0x00000FFFU, 0x00000600U),
+       EMIT_MASKWRITE(0xF8000B5C, 0xFFFFFFFFU, 0x0018C61CU),
+       EMIT_MASKWRITE(0xF8000B60, 0xFFFFFFFFU, 0x00F9861CU),
+       EMIT_MASKWRITE(0xF8000B64, 0xFFFFFFFFU, 0x00F9861CU),
+       EMIT_MASKWRITE(0xF8000B68, 0xFFFFFFFFU, 0x00F9861CU),
+       EMIT_MASKWRITE(0xF8000B6C, 0x00007FFFU, 0x00000260U),
+       EMIT_MASKWRITE(0xF8000B70, 0x00000001U, 0x00000001U),
+       EMIT_MASKWRITE(0xF8000B70, 0x00000021U, 0x00000020U),
+       EMIT_MASKWRITE(0xF8000B70, 0x07FEFFFFU, 0x00000823U),
+       EMIT_MASKWRITE(0xF8000700, 0x00003FFFU, 0x00001600U),
+       EMIT_MASKWRITE(0xF8000704, 0x00003FFFU, 0x00000602U),
+       EMIT_MASKWRITE(0xF8000708, 0x00003FFFU, 0x00000602U),
+       EMIT_MASKWRITE(0xF800070C, 0x00003FFFU, 0x00000602U),
+       EMIT_MASKWRITE(0xF8000710, 0x00003FFFU, 0x00000602U),
+       EMIT_MASKWRITE(0xF8000714, 0x00003FFFU, 0x00000602U),
+       EMIT_MASKWRITE(0xF8000718, 0x00003FFFU, 0x00000602U),
+       EMIT_MASKWRITE(0xF800071C, 0x00003FFFU, 0x00000600U),
+       EMIT_MASKWRITE(0xF8000720, 0x00003FFFU, 0x00000602U),
+       EMIT_MASKWRITE(0xF8000724, 0x00003FFFU, 0x00000600U),
+       EMIT_MASKWRITE(0xF8000728, 0x00003FFFU, 0x000016E1U),
+       EMIT_MASKWRITE(0xF800072C, 0x00003FFFU, 0x000016E0U),
+       EMIT_MASKWRITE(0xF8000730, 0x00003FFFU, 0x00001640U),
+       EMIT_MASKWRITE(0xF8000734, 0x00003FFFU, 0x00001640U),
+       EMIT_MASKWRITE(0xF8000738, 0x00003FFFU, 0x00001621U),
+       EMIT_MASKWRITE(0xF800073C, 0x00003FFFU, 0x00001620U),
+       EMIT_MASKWRITE(0xF8000740, 0x00003FFFU, 0x00001202U),
+       EMIT_MASKWRITE(0xF8000744, 0x00003FFFU, 0x00001202U),
+       EMIT_MASKWRITE(0xF8000748, 0x00003FFFU, 0x00001202U),
+       EMIT_MASKWRITE(0xF800074C, 0x00003FFFU, 0x00001202U),
+       EMIT_MASKWRITE(0xF8000750, 0x00003FFFU, 0x00001202U),
+       EMIT_MASKWRITE(0xF8000754, 0x00003FFFU, 0x00001202U),
+       EMIT_MASKWRITE(0xF8000758, 0x00003FFFU, 0x00001203U),
+       EMIT_MASKWRITE(0xF800075C, 0x00003FFFU, 0x00001203U),
+       EMIT_MASKWRITE(0xF8000760, 0x00003FFFU, 0x00001203U),
+       EMIT_MASKWRITE(0xF8000764, 0x00003FFFU, 0x00001203U),
+       EMIT_MASKWRITE(0xF8000768, 0x00003FFFU, 0x00001203U),
+       EMIT_MASKWRITE(0xF800076C, 0x00003FFFU, 0x00001203U),
+       EMIT_MASKWRITE(0xF8000770, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF8000774, 0x00003FFFU, 0x00001205U),
+       EMIT_MASKWRITE(0xF8000778, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF800077C, 0x00003FFFU, 0x00001205U),
+       EMIT_MASKWRITE(0xF8000780, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF8000784, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF8000788, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF800078C, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF8000790, 0x00003FFFU, 0x00001205U),
+       EMIT_MASKWRITE(0xF8000794, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF8000798, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF800079C, 0x00003FFFU, 0x00001204U),
+       EMIT_MASKWRITE(0xF80007A0, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF80007A4, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF80007A8, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF80007AC, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF80007B0, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF80007B4, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF80007B8, 0x00003F01U, 0x00000201U),
+       EMIT_MASKWRITE(0xF80007BC, 0x00003F01U, 0x00000201U),
+       EMIT_MASKWRITE(0xF80007C0, 0x00003FFFU, 0x000012E0U),
+       EMIT_MASKWRITE(0xF80007C4, 0x00003FFFU, 0x000012E1U),
+       EMIT_MASKWRITE(0xF80007C8, 0x00003FFFU, 0x00000200U),
+       EMIT_MASKWRITE(0xF80007CC, 0x00003FFFU, 0x00000200U),
+       EMIT_MASKWRITE(0xF80007D0, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF80007D4, 0x00003FFFU, 0x00001280U),
+       EMIT_MASKWRITE(0xF8000830, 0x003F003FU, 0x002E002FU),
+       EMIT_WRITE(0xF8000004, 0x0000767BU),
+       EMIT_EXIT(),
+};
+
+static unsigned long ps7_peripherals_init_data[] = {
+       EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+       EMIT_MASKWRITE(0xF8000B48, 0x00000180U, 0x00000180U),
+       EMIT_MASKWRITE(0xF8000B4C, 0x00000180U, 0x00000180U),
+       EMIT_MASKWRITE(0xF8000B50, 0x00000180U, 0x00000180U),
+       EMIT_MASKWRITE(0xF8000B54, 0x00000180U, 0x00000180U),
+       EMIT_WRITE(0xF8000004, 0x0000767BU),
+       EMIT_MASKWRITE(0xE000D000, 0x00080000U, 0x00080000U),
+       EMIT_MASKWRITE(0xF8007000, 0x20000000U, 0x00000000U),
+       EMIT_MASKWRITE(0xE000A244, 0x003FFFFFU, 0x00080000U),
+       EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370008U),
+       EMIT_MASKWRITE(0xE000A248, 0x003FFFFFU, 0x00080000U),
+       EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370000U),
+       EMIT_MASKDELAY(0xF8F00200, 1),
+       EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370008U),
+       EMIT_EXIT(),
+};
+
+static unsigned long ps7_post_config_0[] = {
+       EMIT_WRITE(0xF8000008, 0x0000DF0DU),
+       EMIT_MASKWRITE(0xF8000900, 0x0000000FU, 0x0000000FU),
+       EMIT_MASKWRITE(0xF8000240, 0xFFFFFFFFU, 0x00000000U),
+       EMIT_WRITE(0xF8000004, 0x0000767BU),
+       EMIT_EXIT(),
+};
+
+int ps7_post_config(void)
+{
+       return ps7_config(ps7_post_config_0);
+}
+
+int ps7_init(void)
+{
+       int ret;
+
+       ret = ps7_config(ps7_mio_init_data);
+       if (ret != PS7_INIT_SUCCESS)
+               return ret;
+
+       ret = ps7_config(ps7_pll_init_data);
+       if (ret != PS7_INIT_SUCCESS)
+               return ret;
+
+       ret = ps7_config(ps7_clock_init_data);
+       if (ret != PS7_INIT_SUCCESS)
+               return ret;
+
+       ret = ps7_config(ps7_ddr_init_data);
+       if (ret != PS7_INIT_SUCCESS)
+               return ret;
+
+       ret = ps7_config(ps7_peripherals_init_data);
+       if (ret != PS7_INIT_SUCCESS)
+               return ret;
+       return PS7_INIT_SUCCESS;
+}
index 04fc7f3..9cd4f3f 100644 (file)
@@ -3,6 +3,7 @@ M:      Michal Simek <michal.simek@xilinx.com>
 S:     Maintained
 F:     arch/arm/dts/zynqmp-*
 F:     arch/arm/dts/avnet-ultra96*
+F:     board/xilinx/common/
 F:     board/xilinx/zynqmp/
 F:     include/configs/xilinx_zynqmp*
 F:     configs/xilinx_zynqmp*
index 398c6aa..7d8277c 100644 (file)
@@ -4,7 +4,6 @@
 # Michal Simek <michal.simek@xilinx.com>
 
 obj-y  := zynqmp.o
-obj-y  += ../common/board.o
 
 ifneq ($(CONFIG_XILINX_PS_INIT_FILE),"")
 PS_INIT_FILE := $(shell cd $(srctree); readlink -f $(CONFIG_XILINX_PS_INIT_FILE))
index c0d28a7..cf63ad9 100644 (file)
@@ -9,11 +9,22 @@
 #include <cpu_func.h>
 #include <env.h>
 #include <malloc.h>
+#include <memalign.h>
 #include <zynqmp_firmware.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
 
+struct aes {
+       u64 srcaddr;
+       u64 ivaddr;
+       u64 keyaddr;
+       u64 dstaddr;
+       u64 len;
+       u64 op;
+       u64 keysrc;
+};
+
 static int do_zynqmp_verify_secure(struct cmd_tbl *cmdtp, int flag, int argc,
                                   char *const argv[])
 {
@@ -107,6 +118,66 @@ static int do_zynqmp_mmio_write(struct cmd_tbl *cmdtp, int flag, int argc,
        return ret;
 }
 
+static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc,
+                        char * const argv[])
+{
+       ALLOC_CACHE_ALIGN_BUFFER(struct aes, aes, 1);
+       int ret;
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+
+       if (zynqmp_firmware_version() <= PMUFW_V1_0) {
+               puts("ERR: PMUFW v1.0 or less is detected\n");
+               puts("ERR: Encrypt/Decrypt feature is not supported\n");
+               puts("ERR: Please upgrade PMUFW\n");
+               return CMD_RET_FAILURE;
+       }
+
+       if (argc < cmdtp->maxargs - 1)
+               return CMD_RET_USAGE;
+
+       aes->srcaddr = simple_strtoul(argv[2], NULL, 16);
+       aes->ivaddr = simple_strtoul(argv[3], NULL, 16);
+       aes->len = simple_strtoul(argv[4], NULL, 16);
+       aes->op = simple_strtoul(argv[5], NULL, 16);
+       aes->keysrc = simple_strtoul(argv[6], NULL, 16);
+       aes->dstaddr = simple_strtoul(argv[7], NULL, 16);
+
+       flush_dcache_range((ulong)aes, (ulong)(aes) +
+                          roundup(sizeof(struct aes), ARCH_DMA_MINALIGN));
+
+       if (aes->srcaddr && aes->ivaddr && aes->dstaddr) {
+               flush_dcache_range(aes->srcaddr,
+                                  (aes->srcaddr +
+                                   roundup(aes->len, ARCH_DMA_MINALIGN)));
+               flush_dcache_range(aes->ivaddr,
+                                  (aes->ivaddr +
+                                   roundup(IV_SIZE, ARCH_DMA_MINALIGN)));
+               flush_dcache_range(aes->dstaddr,
+                                  (aes->dstaddr +
+                                   roundup(aes->len, ARCH_DMA_MINALIGN)));
+       }
+
+       if (aes->keysrc == 0) {
+               if (argc < cmdtp->maxargs)
+                       return CMD_RET_USAGE;
+
+               aes->keyaddr = simple_strtoul(argv[8], NULL, 16);
+               if (aes->keyaddr)
+                       flush_dcache_range(aes->keyaddr,
+                                          (aes->keyaddr +
+                                           roundup(KEY_PTR_LEN,
+                                                   ARCH_DMA_MINALIGN)));
+       }
+
+       ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes),
+                               lower_32_bits((ulong)aes), 0, 0, ret_payload);
+       if (ret || ret_payload[1])
+               printf("Failed: AES op status:0x%x, errcode:0x%x\n",
+                      ret, ret_payload[1]);
+
+       return ret;
+}
+
 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
 static int do_zynqmp_tcm_init(struct cmd_tbl *cmdtp, int flag, int argc,
                              char *const argv[])
@@ -148,11 +219,145 @@ static int do_zynqmp_pmufw(struct cmd_tbl *cmdtp, int flag, int argc,
        return 0;
 }
 
+static int do_zynqmp_rsa(struct cmd_tbl *cmdtp, int flag, int argc,
+                        char * const argv[])
+{
+       u64 srcaddr, mod, exp;
+       u32 srclen, rsaop, size, ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       if (argc != cmdtp->maxargs)
+               return CMD_RET_USAGE;
+
+       if (zynqmp_firmware_version() <= PMUFW_V1_0) {
+               puts("ERR: PMUFW v1.0 or less is detected\n");
+               puts("ERR: Encrypt/Decrypt feature is not supported\n");
+               puts("ERR: Please upgrade PMUFW\n");
+               return CMD_RET_FAILURE;
+       }
+
+       srcaddr = simple_strtoul(argv[2], NULL, 16);
+       srclen = simple_strtoul(argv[3], NULL, 16);
+       if (srclen != RSA_KEY_SIZE) {
+               puts("ERR: srclen should be equal to 0x200(512 bytes)\n");
+               return CMD_RET_USAGE;
+       }
+
+       mod = simple_strtoul(argv[4], NULL, 16);
+       exp = simple_strtoul(argv[5], NULL, 16);
+       rsaop = simple_strtoul(argv[6], NULL, 16);
+       if (!(rsaop == 0 || rsaop == 1)) {
+               puts("ERR: rsaop should be either 0 or 1\n");
+               return CMD_RET_USAGE;
+       }
+
+       memcpy((void *)srcaddr + srclen, (void *)mod, MODULUS_LEN);
+
+       /*
+        * For encryption we load public exponent (key size 4096-bits),
+        * for decryption we load private exponent (32-bits)
+        */
+       if (rsaop) {
+               memcpy((void *)srcaddr + srclen + MODULUS_LEN,
+                      (void *)exp, PUB_EXPO_LEN);
+               size = srclen + MODULUS_LEN + PUB_EXPO_LEN;
+       } else {
+               memcpy((void *)srcaddr + srclen + MODULUS_LEN,
+                      (void *)exp, PRIV_EXPO_LEN);
+               size = srclen + MODULUS_LEN + PRIV_EXPO_LEN;
+       }
+
+       flush_dcache_range((ulong)srcaddr,
+                          (ulong)(srcaddr) + roundup(size, ARCH_DMA_MINALIGN));
+
+       ret = xilinx_pm_request(PM_SECURE_RSA, upper_32_bits((ulong)srcaddr),
+                               lower_32_bits((ulong)srcaddr), srclen, rsaop,
+                               ret_payload);
+       if (ret || ret_payload[1]) {
+               printf("Failed: RSA status:0x%x, errcode:0x%x\n",
+                      ret, ret_payload[1]);
+               return CMD_RET_FAILURE;
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
+static int do_zynqmp_sha3(struct cmd_tbl *cmdtp, int flag,
+                         int argc, char * const argv[])
+{
+       u64 srcaddr, hashaddr;
+       u32 srclen, ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       if (argc > cmdtp->maxargs || argc < (cmdtp->maxargs - 1))
+               return CMD_RET_USAGE;
+
+       if (zynqmp_firmware_version() <= PMUFW_V1_0) {
+               puts("ERR: PMUFW v1.0 or less is detected\n");
+               puts("ERR: Encrypt/Decrypt feature is not supported\n");
+               puts("ERR: Please upgrade PMUFW\n");
+               return CMD_RET_FAILURE;
+       }
+
+       srcaddr = simple_strtoul(argv[2], NULL, 16);
+       srclen = simple_strtoul(argv[3], NULL, 16);
+
+       if (argc == 5) {
+               hashaddr = simple_strtoul(argv[4], NULL, 16);
+               flush_dcache_range(hashaddr,
+                                  hashaddr + roundup(ZYNQMP_SHA3_SIZE,
+                                                     ARCH_DMA_MINALIGN));
+       } else {
+               hashaddr = srcaddr;
+       }
+
+       /* Check srcaddr or srclen != 0 */
+       if (!srcaddr || !srclen) {
+               puts("ERR: srcaddr & srclen should not be 0\n");
+               return CMD_RET_USAGE;
+       }
+
+       flush_dcache_range(srcaddr,
+                          srcaddr + roundup(srclen, ARCH_DMA_MINALIGN));
+
+       ret = xilinx_pm_request(PM_SECURE_SHA, 0, 0, 0,
+                               ZYNQMP_SHA3_INIT, ret_payload);
+       if (ret || ret_payload[1]) {
+               printf("Failed: SHA INIT status:0x%x, errcode:0x%x\n",
+                      ret, ret_payload[1]);
+               return CMD_RET_FAILURE;
+       }
+
+       ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)srcaddr),
+                               lower_32_bits((ulong)srcaddr),
+                               srclen, ZYNQMP_SHA3_UPDATE, ret_payload);
+       if (ret || ret_payload[1]) {
+               printf("Failed: SHA UPDATE status:0x%x, errcode:0x%x\n",
+                      ret, ret_payload[1]);
+               return CMD_RET_FAILURE;
+       }
+
+       ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)hashaddr),
+                               lower_32_bits((ulong)hashaddr),
+                               ZYNQMP_SHA3_SIZE, ZYNQMP_SHA3_FINAL,
+                               ret_payload);
+       if (ret || ret_payload[1]) {
+               printf("Failed: SHA FINAL status:0x%x, errcode:0x%x\n",
+                      ret, ret_payload[1]);
+               return CMD_RET_FAILURE;
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
 static struct cmd_tbl cmd_zynqmp_sub[] = {
        U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
        U_BOOT_CMD_MKENT(pmufw, 4, 0, do_zynqmp_pmufw, "", ""),
        U_BOOT_CMD_MKENT(mmio_read, 3, 0, do_zynqmp_mmio_read, "", ""),
        U_BOOT_CMD_MKENT(mmio_write, 5, 0, do_zynqmp_mmio_write, "", ""),
+       U_BOOT_CMD_MKENT(aes, 9, 0, do_zynqmp_aes, "", ""),
+       U_BOOT_CMD_MKENT(rsa, 7, 0, do_zynqmp_rsa, "", ""),
+       U_BOOT_CMD_MKENT(sha3, 5, 0, do_zynqmp_sha3, "", ""),
 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
        U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
 #endif
@@ -196,6 +401,14 @@ static char zynqmp_help_text[] =
        "zynqmp mmio_read address - read from address\n"
        "zynqmp mmio_write address mask value - write value after masking to\n"
        "                                       address\n"
+       "zynqmp aes srcaddr ivaddr len aesop keysrc dstaddr [keyaddr] -\n"
+       "       Encrypts or decrypts blob of data at src address and puts it\n"
+       "       back to dstaddr using key and iv at keyaddr and ivaddr\n"
+       "       respectively. keysrc value specifies from which source key\n"
+       "       has to be used, it can be User/Device/PUF key. A value of 0\n"
+       "       for KUP(user key),1 for DeviceKey and 2 for PUF key. The\n"
+       "       aesop value specifies the operation which can be 0 for\n"
+       "       decrypt and 1 for encrypt operation\n"
 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
        "zynqmp tcminit mode - Initialize the TCM with zeros. TCM needs to be\n"
        "                      initialized before accessing to avoid ECC\n"
@@ -204,11 +417,24 @@ static char zynqmp_help_text[] =
        "                      lock(0)/split(1)\n"
 #endif
        "zynqmp pmufw address size - load PMU FW configuration object\n"
+       "zynqmp rsa srcaddr srclen mod exp rsaop -\n"
+       "       Performs RSA encryption and RSA decryption on blob of data\n"
+       "       at srcaddr and puts it back in srcaddr using modulus and\n"
+       "       public or private exponent\n"
+       "       srclen : must be key size(4096 bits)\n"
+       "       exp :   private key exponent for RSA decryption(4096 bits)\n"
+       "               public key exponent for RSA encryption(32 bits)\n"
+       "       rsaop : 0 for RSA Decryption, 1 for RSA Encryption\n"
+       "zynqmp sha3 srcaddr srclen [key_addr] -\n"
+       "       Generates sha3 hash value for data blob at srcaddr and puts\n"
+       "       48 bytes hash value into srcaddr\n"
+       "       Optional key_addr can be specified for saving sha3 hash value\n"
+       "       Note: srcaddr/srclen should not be 0\n"
        ;
 #endif
 
 U_BOOT_CMD(
-       zynqmp, 5, 1, do_zynqmp,
+       zynqmp, 9, 1, do_zynqmp,
        "ZynqMP sub-system",
        zynqmp_help_text
 )
index 5fde0ae..1cab25f 100644 (file)
@@ -6,8 +6,10 @@
  */
 
 #include <common.h>
+#include <zynqmp_tap_delay.h>
 #include <asm/arch/sys_proto.h>
 #include <linux/delay.h>
+#include <mmc.h>
 
 #define SD_DLL_CTRL                    0xFF180358
 #define SD_ITAP_DLY                    0xFF180314
 #define SD1_ITAPDLYENA_MASK            0x01000000
 #define SD1_ITAPDLYENA                 0x01000000
 #define SD0_ITAPDLYSEL_MASK            0x000000FF
-#define SD0_ITAPDLYSEL_HSD             0x00000015
-#define SD0_ITAPDLYSEL_SD_DDR50                0x0000003D
-#define SD0_ITAPDLYSEL_MMC_DDR50       0x00000012
-
 #define SD1_ITAPDLYSEL_MASK            0x00FF0000
-#define SD1_ITAPDLYSEL_HSD             0x00150000
-#define SD1_ITAPDLYSEL_SD_DDR50                0x003D0000
-#define SD1_ITAPDLYSEL_MMC_DDR50       0x00120000
-
 #define SD0_OTAPDLYSEL_MASK            0x0000003F
-#define SD0_OTAPDLYSEL_MMC_HSD         0x00000006
-#define SD0_OTAPDLYSEL_SD_HSD          0x00000005
-#define SD0_OTAPDLYSEL_SDR50           0x00000003
-#define SD0_OTAPDLYSEL_SDR104_B0       0x00000003
-#define SD0_OTAPDLYSEL_SDR104_B2       0x00000002
-#define SD0_OTAPDLYSEL_SD_DDR50                0x00000004
-#define SD0_OTAPDLYSEL_MMC_DDR50       0x00000006
-
 #define SD1_OTAPDLYSEL_MASK            0x003F0000
-#define SD1_OTAPDLYSEL_MMC_HSD         0x00060000
-#define SD1_OTAPDLYSEL_SD_HSD          0x00050000
-#define SD1_OTAPDLYSEL_SDR50           0x00030000
-#define SD1_OTAPDLYSEL_SDR104_B0       0x00030000
-#define SD1_OTAPDLYSEL_SDR104_B2       0x00020000
-#define SD1_OTAPDLYSEL_SD_DDR50                0x00040000
-#define SD1_OTAPDLYSEL_MMC_DDR50       0x00060000
-
-#define MMC_BANK2              0x2
-
-#define MMC_TIMING_UHS_SDR25           1
-#define MMC_TIMING_UHS_SDR50           2
-#define MMC_TIMING_UHS_SDR104          3
-#define MMC_TIMING_UHS_DDR50           4
-#define MMC_TIMING_MMC_HS200           5
-#define MMC_TIMING_SD_HS               6
-#define MMC_TIMING_MMC_DDR52           7
-#define MMC_TIMING_MMC_HS              8
 
 void zynqmp_dll_reset(u8 deviceid)
 {
@@ -82,149 +50,49 @@ void zynqmp_dll_reset(u8 deviceid)
                zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
 }
 
-static void arasan_zynqmp_tap_sdr104(u8 deviceid, u8 timing, u8 bank)
-{
-       if (deviceid == 0) {
-               /* Program OTAP */
-               if (bank == MMC_BANK2)
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
-                                         SD0_OTAPDLYSEL_SDR104_B2);
-               else
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
-                                         SD0_OTAPDLYSEL_SDR104_B0);
-       } else {
-               /* Program OTAP */
-               if (bank == MMC_BANK2)
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-                                         SD1_OTAPDLYSEL_SDR104_B2);
-               else
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-                                         SD1_OTAPDLYSEL_SDR104_B0);
-       }
-}
-
-static void arasan_zynqmp_tap_hs(u8 deviceid, u8 timing, u8 bank)
-{
-       if (deviceid == 0) {
-               /* Program ITAP */
-               zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
-                                 SD0_ITAPCHGWIN);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
-                                 SD0_ITAPDLYENA);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
-                                 SD0_ITAPDLYSEL_HSD);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
-               /* Program OTAP */
-               if (timing == MMC_TIMING_MMC_HS)
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
-                                         SD0_OTAPDLYSEL_MMC_HSD);
-               else
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
-                                         SD0_OTAPDLYSEL_SD_HSD);
-       } else {
-               /* Program ITAP */
-               zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
-                                 SD1_ITAPCHGWIN);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
-                                 SD1_ITAPDLYENA);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
-                                 SD1_ITAPDLYSEL_HSD);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
-               /* Program OTAP */
-               if (timing == MMC_TIMING_MMC_HS)
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-                                         SD1_OTAPDLYSEL_MMC_HSD);
-               else
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-                                         SD1_OTAPDLYSEL_SD_HSD);
-       }
-}
-
-static void arasan_zynqmp_tap_ddr50(u8 deviceid, u8 timing, u8 bank)
+void arasan_zynqmp_set_tapdelay(u8 deviceid, u32 itap_delay, u32 otap_delay)
 {
        if (deviceid == 0) {
+               zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
+                                 SD0_DLL_RST);
                /* Program ITAP */
-               zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
-                                 SD0_ITAPCHGWIN);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
-                                 SD0_ITAPDLYENA);
-               if (timing == MMC_TIMING_UHS_DDR50)
-                       zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
-                                         SD0_ITAPDLYSEL_SD_DDR50);
-               else
+               if (itap_delay) {
+                       zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
+                                         SD0_ITAPCHGWIN);
+                       zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
+                                         SD0_ITAPDLYENA);
                        zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
-                                         SD0_ITAPDLYSEL_MMC_DDR50);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
+                                         itap_delay);
+                       zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
+                                         0x0);
+               }
+
                /* Program OTAP */
-               if (timing == MMC_TIMING_UHS_DDR50)
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
-                                         SD0_OTAPDLYSEL_SD_DDR50);
-               else
+               if (otap_delay)
                        zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
-                                         SD0_OTAPDLYSEL_MMC_DDR50);
-       } else {
-               /* Program ITAP */
-               zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
-                                 SD1_ITAPCHGWIN);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
-                                 SD1_ITAPDLYENA);
-               if (timing == MMC_TIMING_UHS_DDR50)
-                       zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
-                                         SD1_ITAPDLYSEL_SD_DDR50);
-               else
-                       zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
-                                         SD1_ITAPDLYSEL_MMC_DDR50);
-               zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
-               /* Program OTAP */
-               if (timing == MMC_TIMING_UHS_DDR50)
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-                                         SD1_OTAPDLYSEL_SD_DDR50);
-               else
-                       zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-                                         SD1_OTAPDLYSEL_MMC_DDR50);
-       }
-}
+                                         otap_delay);
 
-static void arasan_zynqmp_tap_sdr50(u8 deviceid, u8 timing, u8 bank)
-{
-       if (deviceid == 0) {
-               /* Program OTAP */
-               zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
-                                 SD0_OTAPDLYSEL_SDR50);
+               zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
        } else {
-               /* Program OTAP */
-               zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-                                 SD1_OTAPDLYSEL_SDR50);
-       }
-}
-
-void arasan_zynqmp_set_tapdelay(u8 deviceid, u8 timing, u8 bank)
-{
-       if (deviceid == 0)
-               zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
-                                 SD0_DLL_RST);
-       else
                zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
                                  SD1_DLL_RST);
+               /* Program ITAP */
+               if (itap_delay) {
+                       zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
+                                         SD1_ITAPCHGWIN);
+                       zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
+                                         SD1_ITAPDLYENA);
+                       zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
+                                         (itap_delay << 16));
+                       zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
+                                         0x0);
+               }
 
-       switch (timing) {
-       case MMC_TIMING_UHS_SDR25:
-               arasan_zynqmp_tap_hs(deviceid, timing, bank);
-               break;
-       case MMC_TIMING_UHS_SDR50:
-               arasan_zynqmp_tap_sdr50(deviceid, timing, bank);
-               break;
-       case MMC_TIMING_UHS_SDR104:
-       case MMC_TIMING_MMC_HS200:
-               arasan_zynqmp_tap_sdr104(deviceid, timing, bank);
-               break;
-       case MMC_TIMING_UHS_DDR50:
-               arasan_zynqmp_tap_ddr50(deviceid, timing, bank);
-               break;
-       }
+               /* Program OTAP */
+               if (otap_delay)
+                       zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+                                         (otap_delay << 16));
 
-       if (deviceid == 0)
-               zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
-       else
                zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
+       }
 }
index 28f067a..731285a 100644 (file)
 #include "pm_cfg_obj.h"
 
 #define ZYNQMP_VERSION_SIZE    7
-#define EFUSE_VCU_DIS_MASK     0x100
-#define EFUSE_VCU_DIS_SHIFT    8
-#define EFUSE_GPU_DIS_MASK     0x20
-#define EFUSE_GPU_DIS_SHIFT    5
-#define IDCODE2_PL_INIT_MASK   0x200
-#define IDCODE2_PL_INIT_SHIFT  9
+#define EFUSE_VCU_DIS_MASK     0x100
+#define EFUSE_VCU_DIS_SHIFT    8
+#define EFUSE_GPU_DIS_MASK     0x20
+#define EFUSE_GPU_DIS_SHIFT    5
+#define IDCODE2_PL_INIT_MASK   0x200
+#define IDCODE2_PL_INIT_SHIFT  9
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -100,7 +100,7 @@ static const struct {
        {
                .id = 0x04738093,
                .device = 9,
-               .variants = ZYNQMP_VARIANT_EG,
+               .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
        },
        {
                .id = 0x04740093,
@@ -190,8 +190,13 @@ static char *zynqmp_get_silicon_idcode_name(void)
        u32 idcode, idcode2;
        char name[ZYNQMP_VERSION_SIZE];
        u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
 
-       xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
+       ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
+       if (ret) {
+               debug("%s: Getting chipid failed\n", __func__);
+               return "unknown";
+       }
 
        /*
         * Firmware returns:
@@ -204,7 +209,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
 
        idcode  = ret_payload[1];
        idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
-       debug("%s, IDCODE: 0x%0X, IDCODE2: 0x%0X\r\n", __func__, idcode,
+       debug("%s, IDCODE: 0x%0x, IDCODE2: 0x%0x\r\n", __func__, idcode,
              idcode2);
 
        for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
@@ -216,8 +221,10 @@ static char *zynqmp_get_silicon_idcode_name(void)
                return "unknown";
 
        /* Add device prefix to the name */
-       strncpy(name, "zu", ZYNQMP_VERSION_SIZE);
-       strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
+       ret = snprintf(name, ZYNQMP_VERSION_SIZE, "zu%d",
+                      zynqmp_devices[i].device);
+       if (ret < 0)
+               return "unknown";
 
        if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
                /* Devices with EV variant might be EG/CG/EV family */
@@ -321,6 +328,9 @@ int board_init(void)
        if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
                zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
                                                zynqmp_pm_cfg_obj_size);
+#else
+       if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
+               xilinx_read_eeprom();
 #endif
 
        printf("EL Level:\tEL%d\n", current_el());
index a565b47..5ae75df 100644 (file)
@@ -611,14 +611,9 @@ int fdt_record_loadable(void *blob, u32 index, const char *name,
        if (node < 0)
                return node;
 
-       /*
-        * We record these as 32bit entities, possibly truncating addresses.
-        * However, spl_fit.c is not 64bit safe either: i.e. we should not
-        * have an issue here.
-        */
-       fdt_setprop_u32(blob, node, "load-addr", load_addr);
+       fdt_setprop_u64(blob, node, "load", load_addr);
        if (entry_point != -1)
-               fdt_setprop_u32(blob, node, "entry-point", entry_point);
+               fdt_setprop_u64(blob, node, "entry", entry_point);
        fdt_setprop_u32(blob, node, "size", size);
        if (type)
                fdt_setprop_string(blob, node, "type", type);
index d54eff9..c82d4d8 100644 (file)
@@ -791,17 +791,18 @@ static int fit_image_get_address(const void *fit, int noffset, char *name,
                return -1;
        }
 
-       if (len > sizeof(ulong)) {
-               printf("Unsupported %s address size\n", name);
-               return -1;
-       }
-
        cell_len = len >> 2;
        /* Use load64 to avoid compiling warning for 32-bit target */
        while (cell_len--) {
                load64 = (load64 << 32) | uimage_to_cpu(*cell);
                cell++;
        }
+
+       if (len > sizeof(ulong) && (uint32_t)(load64 >> 32)) {
+               printf("Unsupported %s address size\n", name);
+               return -1;
+       }
+
        *load = (ulong)load64;
 
        return 0;
index b54b4f0..9bd25f6 100644 (file)
@@ -132,10 +132,11 @@ static int spl_fit_images_find(void *blob, int os)
 uintptr_t spl_fit_images_get_entry(void *blob, int node)
 {
        ulong  val;
+       int ret;
 
-       val = fdt_getprop_u32(blob, node, "entry-point");
-       if (val == FDT_ERROR)
-               val = fdt_getprop_u32(blob, node, "load-addr");
+       ret = fit_image_get_entry(blob, node, &val);
+       if (ret)
+               ret = fit_image_get_load(blob, node, &val);
 
        debug("%s: entry point 0x%lx\n", __func__, val);
        return val;
index fd6086a..f5109e8 100644 (file)
@@ -332,9 +332,15 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
        }
 
        if (image_info) {
+               ulong entry_point;
+
                image_info->load_addr = load_addr;
                image_info->size = length;
-               image_info->entry_point = fdt_getprop_u32(fit, node, "entry");
+
+               if (!fit_image_get_entry(fit, node, &entry_point))
+                       image_info->entry_point = entry_point;
+               else
+                       image_info->entry_point = FDT_ERROR;
        }
 
        return 0;
index 14f335f..41e0746 100644 (file)
@@ -61,11 +61,9 @@ void spl_invoke_opensbi(struct spl_image_info *spl_image)
        }
 
        /* Get U-Boot entry point */
-       uboot_entry = fdt_getprop_u32(spl_image->fdt_addr, uboot_node,
-                                     "entry-point");
-       if (uboot_entry == FDT_ERROR)
-               uboot_entry = fdt_getprop_u32(spl_image->fdt_addr, uboot_node,
-                                             "load-addr");
+       ret = fit_image_get_entry(spl_image->fdt_addr, uboot_node, &uboot_entry);
+       if (ret)
+               ret = fit_image_get_load(spl_image->fdt_addr, uboot_node, &uboot_entry);
 
        /* Prepare obensbi_info object */
        opensbi_info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE;
index 25282ba..2426179 100644 (file)
@@ -8,6 +8,8 @@ CONFIG_DEBUG_UART_BASE=0xff000000
 CONFIG_DEBUG_UART_CLOCK=100000000
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_ZYNQ_MAC_IN_EEPROM=y
+CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xfa
 CONFIG_DEFAULT_DEVICE_TREE="avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0"
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
@@ -42,7 +44,6 @@ CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_MISC=y
 CONFIG_I2C_EEPROM=y
-CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xfa
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
 CONFIG_SPI_FLASH_BAR=y
index bfbdb49..08c8885 100644 (file)
@@ -12,6 +12,7 @@ CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
 CONFIG_XILINX_MICROBLAZE0_USE_DIV=1
 CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=1
 CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic"
+CONFIG_DISTRO_DEFAULTS=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_BOOTDELAY=-1
@@ -21,13 +22,12 @@ CONFIG_USE_PREBOOT=y
 CONFIG_PREBOOT="echo U-BOOT for ${hostname};setenv preboot;echo"
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_OS_BASE=0x2c060000
-CONFIG_HUSH_PARSER=y
-# CONFIG_AUTO_COMPLETE is not set
 CONFIG_SYS_PROMPT="U-Boot-mONStR> "
 CONFIG_CMD_IMLS=y
 CONFIG_CMD_SPL=y
@@ -35,10 +35,7 @@ CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_SAVES=y
 # CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
 CONFIG_CMD_TFTPPUT=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_JFFS2=y
 CONFIG_SPL_OF_CONTROL=y
@@ -47,6 +44,7 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_SPL_DM=y
 CONFIG_XILINX_GPIO=y
+CONFIG_DM_I2C=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_MTD=y
@@ -56,6 +54,12 @@ CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_FLASH_CFI_MTD=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHY_ATHEROS=y
 CONFIG_PHY_BROADCOM=y
 CONFIG_PHY_DAVICOM=y
@@ -71,6 +75,7 @@ CONFIG_XILINX_AXIEMAC=y
 CONFIG_XILINX_EMACLITE=y
 CONFIG_SYS_NS16550=y
 CONFIG_XILINX_UARTLITE=y
+CONFIG_XILINX_SPI=y
 CONFIG_SYSRESET_GPIO=y
 CONFIG_SYSRESET_MICROBLAZE=y
 CONFIG_WDT=y
index 8f69006..276c476 100644 (file)
@@ -9,6 +9,8 @@ CONFIG_SPL_STACK_R_ADDR=0x200000
 CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0xe0000000
 CONFIG_DEBUG_UART_CLOCK=50000000
+CONFIG_ZYNQ_MAC_IN_EEPROM=y
+CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xFA
 CONFIG_DEFAULT_DEVICE_TREE="zynq-syzygy-hub"
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
@@ -40,7 +42,6 @@ CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQPL=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
-CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xFA
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
 CONFIG_PHY_MARVELL=y
index e72cef9..427268b 100644 (file)
@@ -7,7 +7,7 @@ CONFIG_NR_DRAM_BANKS=3
 CONFIG_ENV_SIZE=0x80
 CONFIG_SYS_MALLOC_LEN=0x2000
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
-CONFIG_COUNTER_FREQUENCY=2720000
+CONFIG_COUNTER_FREQUENCY=100000000
 # CONFIG_PSCI_RESET is not set
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini"
 # CONFIG_EXPERT is not set
index b5c3ae4..8837987 100644 (file)
@@ -6,7 +6,7 @@ CONFIG_SYS_TEXT_BASE=0x10000
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_ENV_SIZE=0x80
 CONFIG_SYS_MALLOC_LEN=0x80000
-CONFIG_COUNTER_FREQUENCY=2720000
+CONFIG_COUNTER_FREQUENCY=100000000
 # CONFIG_PSCI_RESET is not set
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini-emmc0"
 # CONFIG_EXPERT is not set
index 871f8cc..b07dc04 100644 (file)
@@ -6,7 +6,7 @@ CONFIG_SYS_TEXT_BASE=0x10000
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_ENV_SIZE=0x80
 CONFIG_SYS_MALLOC_LEN=0x80000
-CONFIG_COUNTER_FREQUENCY=2720000
+CONFIG_COUNTER_FREQUENCY=100000000
 # CONFIG_PSCI_RESET is not set
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini-emmc1"
 # CONFIG_EXPERT is not set
index 5175571..7291c51 100644 (file)
@@ -4,8 +4,9 @@ CONFIG_ARCH_VERSAL=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x100000
 CONFIG_DM_GPIO=y
+CONFIG_CMD_FRU=y
 CONFIG_DEFINE_TCM_OCM_MMAP=y
-CONFIG_COUNTER_FREQUENCY=62500000
+CONFIG_COUNTER_FREQUENCY=100000000
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
@@ -27,6 +28,7 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_MTD=y
+CONFIG_CMD_SF_TEST=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_CACHE=y
@@ -51,6 +53,7 @@ CONFIG_MISC=y
 CONFIG_I2C_EEPROM=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0x0
+CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
@@ -83,6 +86,7 @@ CONFIG_PL01X_SERIAL=y
 CONFIG_XILINX_UARTLITE=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_ZYNQ_SPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_DM_USB_GADGET=y
index b127945..da84c01 100644 (file)
@@ -6,6 +6,8 @@ CONFIG_SYS_SPI_U_BOOT_OFFS=0x100000
 CONFIG_DM_GPIO=y
 CONFIG_SPL_STACK_R_ADDR=0x200000
 CONFIG_SPL=y
+CONFIG_CMD_FRU=y
+CONFIG_CMD_ZYNQ_AES=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706"
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_SYS_CUSTOM_LDSCRIPT=y
@@ -40,6 +42,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_MTD=y
 CONFIG_CMD_NAND_LOCK_UNLOCK=y
+CONFIG_CMD_SF_TEST=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TFTPPUT=y
@@ -49,7 +52,7 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_MTDPARTS_SPREAD=y
 CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
 CONFIG_CMD_UBI=y
-CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0"
+CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zturn-v5 zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0"
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
@@ -88,6 +91,8 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHY_MARVELL=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_PHY_REALTEK=y
 CONFIG_PHY_XILINX=y
 CONFIG_MII=y
index 264b662..0c816de 100644 (file)
@@ -7,6 +7,9 @@ CONFIG_DM_GPIO=y
 CONFIG_SPL=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_ZYNQ_MAC_IN_EEPROM=y
+CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
+CONFIG_CMD_FRU=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC"
 CONFIG_AHCI=y
@@ -19,6 +22,7 @@ CONFIG_USE_PREBOOT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_SPL_FPGA=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
@@ -45,10 +49,12 @@ CONFIG_CMD_MTD=y
 CONFIG_CMD_NAND_LOCK_UNLOCK=y
 CONFIG_CMD_POWEROFF=y
 CONFIG_CMD_SDRAM=y
+CONFIG_CMD_SF_TEST=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_TIMER=y
 CONFIG_CMD_EXT4_WRITE=y
@@ -58,6 +64,7 @@ CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
 CONFIG_CMD_UBI=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_LIST="avnet-ultra96-rev1 zynqmp-a2197-revA zynqmp-e-a2197-00-revA zynqmp-g-a2197-00-revA zynqmp-m-a2197-01-revA zynqmp-m-a2197-02-revA zynqmp-m-a2197-03-revA zynqmp-p-a2197-00-revA zynqmp-zc1232-revA zynqmp-zc1254-revA zynqmp-zc1751-xm015-dc1 zynqmp-zc1751-xm016-dc2 zynqmp-zc1751-xm017-dc3 zynqmp-zc1751-xm018-dc4 zynqmp-zc1751-xm019-dc5 zynqmp-zcu100-revC zynqmp-zcu102-rev1.1 zynqmp-zcu102-rev1.0 zynqmp-zcu102-revA zynqmp-zcu102-revB zynqmp-zcu104-revA zynqmp-zcu104-revC zynqmp-zcu106-revA zynqmp-zcu111-revA zynqmp-zcu1275-revA zynqmp-zcu1275-revB zynqmp-zcu1285-revA zynqmp-zcu208-revA zynqmp-zcu216-revA zynqmp-topic-miamimp-xilinx-xdp-v1r1"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent interrupts iommus power-domains"
 CONFIG_ENV_IS_NOWHERE=y
 CONFIG_ENV_IS_IN_FAT=y
 CONFIG_ENV_IS_IN_NAND=y
@@ -88,7 +95,6 @@ CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_MISC=y
 CONFIG_I2C_EEPROM=y
-CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
 CONFIG_SYS_I2C_EEPROM_ADDR=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0x0
 CONFIG_SUPPORT_EMMC_BOOT=y
index 47f0929..2e31fe3 100644 (file)
@@ -8,3 +8,5 @@ Xilinx
 
    xilinx
    zynq
+   zynqmp
+   zynqmp-r5
index f6ea5db..8c9afb4 100644 (file)
@@ -10,18 +10,28 @@ kernel.
 
 * ata
        - Documentation/devicetree/bindings/ata/ahci-ceva.txt
+* clock
+       - Documentation/devicetree/bindings/clock/xlnx,zynqmp-clk.txt
+* firmware
+       - Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
+* fpga
+       - Documentation/devicetree/bindings/fpga/xlnx,zynqmp-pcap-fpga.txt
 * gpio
        - Documentation/devicetree/bindings/gpio/gpio-xilinx.txt
        - Documentation/devicetree/bindings/gpio/gpio-zynq.txt
 * i2c
-       - Documentation/devicetree/bindings/i2c/i2c-xiic.txt
-       - Documentation/devicetree/bindings/i2c/i2c-cadence.txt
+       - Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
+       - Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
 * mmc
-       - Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
+       - Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
 * net
        - Documentation/devicetree/bindings/net/macb.txt
        - Documentation/devicetree/bindings/net/xilinx_axienet.txt
        - Documentation/devicetree/bindings/net/xilinx_emaclite.txt
+* nvmem
+       - Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.txt
+* power
+       - Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
 * serial
        - Documentation/devicetree/bindings/serial/cdns,uart.txt
        - Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.txt
index f564434..438912f 100644 (file)
@@ -83,7 +83,7 @@ Mainline status
 ---------------
 
 - Added basic board configurations support.
-- Added zynq u-boot bsp code - arch/arm/cpu/armv7/zynq
+- Added zynq u-boot bsp code - arch/arm/mach-zynq
 - Added zynq boards named - zc70x, zed, microzed, zc770_xm010/xm011/xm012/xm013
 - Added zynq drivers:
 
@@ -99,11 +99,6 @@ Mainline status
 - Added basic FDT support for zynq boards
 - d-cache support for zynq_gem.c
 
-TODO
-----
-
-Add FDT support on individual drivers
-
 * [1] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC702-G.htm
 * [2] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC706-G.htm
 * [3] http://zedboard.org/product/zedboard
diff --git a/doc/board/xilinx/zynqmp-r5.rst b/doc/board/xilinx/zynqmp-r5.rst
new file mode 100644 (file)
index 0000000..2cd368b
--- /dev/null
@@ -0,0 +1,137 @@
+.. SPDX-License-Identifier: GPL-2.0
+..  (C) Copyright 2020 Xilinx, Inc.
+
+ZYNQMP-R5
+=========
+
+About this
+----------
+
+This document describes the information about Xilinx Zynq UltraScale+ MPSOC
+U-Boot Cortex R5 support.
+
+ZynqMP R5 boards
+----------------
+
+* zynqmp-r5 - U-Boot running on RPU Cortex-R5
+
+Building
+--------
+
+configure and build armv7 toolchain::
+
+   $ make xilinx_zynqmp_r5_defconfig
+   $ make
+
+Notes
+^^^^^
+
+Output fragment is u-boot.
+
+Loading
+-------
+
+ZynqMP R5 U-Boot was created for supporting loading OS on RPU. There are two
+ways how to start U-Boot on R5.
+
+Bootgen
+^^^^^^^
+
+The first way is to use Xilinx FSBL (First stage
+bootloader) to load u-boot and start it. The following bif can be used for boot
+image generation via Xilinx bootgen utility::
+
+
+  the_ROM_image:
+  {
+       [bootloader,destination_cpu=r5-0] fsbl_rpu.elf
+       [destination_cpu=r5-0]u-boot.elf
+  }
+
+Bootgen command for building boot.bin::
+
+  bootgen -image <bif>.bif -r -w -o i boot.bin
+
+
+U-Boot cpu command
+^^^^^^^^^^^^^^^^^^
+
+The second way to load U-Boot to Cortex R5 is from U-Boot running on A53 as is
+visible from the following log::
+
+  U-Boot SPL 2020.10-rc4-00090-g801b3d5c5757 (Sep 15 2020 - 14:07:24 +0200)
+  PMUFW:       v1.1
+  Loading new PMUFW cfg obj (2024 bytes)
+  EL Level:    EL3
+  Multiboot:   0
+  Trying to boot from MMC2
+  spl: could not initialize mmc. error: -19
+  Trying to boot from MMC1
+  spl_load_image_fat_os: error reading image u-boot.bin, err - -2
+  NOTICE:  ATF running on XCZU7EG/EV/silicon v4/RTL5.1 at 0xfffea000
+  NOTICE:  BL31: v2.2(release):v2.2-614-ged9dc512fb9c
+  NOTICE:  BL31: Built : 09:32:09, Mar 13 2020
+
+
+  U-Boot 2020.10-rc4-00090-g801b3d5c5757 (Sep 15 2020 - 14:07:24 +0200)
+
+  Model: ZynqMP ZCU104 RevC
+  Board: Xilinx ZynqMP
+  DRAM:  2 GiB
+  PMUFW:       v1.1
+  EL Level:    EL2
+  Chip ID:     zu7e
+  WDT:   Started with servicing (60s timeout)
+  NAND:  0 MiB
+  MMC:   mmc@ff170000: 0
+  Loading Environment from FAT... *** Warning - bad CRC, using default environment
+
+  In:    serial
+  Out:   serial
+  Err:   serial
+  Bootmode: LVL_SHFT_SD_MODE1
+  Reset reason:        SOFT
+  Net:
+  ZYNQ GEM: ff0e0000, mdio bus ff0e0000, phyaddr 12, interface rgmii-id
+  eth0: ethernet@ff0e0000
+  Hit any key to stop autoboot:  0
+  ZynqMP> setenv autoload no
+  ZynqMP> dhcp
+  BOOTP broadcast 1
+  DHCP client bound to address 192.168.0.167 (8 ms)
+  ZynqMP> tftpboot 20000000 192.168.0.105:u-boot-r5-2.elf
+  Using ethernet@ff0e0000 device
+  TFTP from server 192.168.0.105; our IP address is 192.168.0.167
+  Filename 'u-boot-r5-2.elf'.
+  Load address: 0x20000000
+  Loading: #################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        #################################################################
+        ################
+        376 KiB/s
+  done
+  Bytes transferred = 2075464 (1fab48 hex)
+  ZynqMP> setenv autostart no
+  ZynqMP> bootelf -p 20000000
+  ZynqMP> cpu 4 release 10000000 lockstep
+  Using TCM jump trampoline for address 0x10000000
+  R5 lockstep mode
+  ZynqMP>
+
+Then on second uart you can see U-Boot up and running on R5::
+
+  U-Boot 2020.10-rc4-00071-g7045622cc9ba (Sep 16 2020 - 13:38:53 +0200)
+
+  Model: Xilinx ZynqMP R5
+  DRAM:  512 MiB
+  MMC:
+  In:    serial@ff010000
+  Out:   serial@ff010000
+  Err:   serial@ff010000
+  Net:   No ethernet found.
+  ZynqMP r5>
+
+Please make sure MIO pins for uart are properly configured to see output.
diff --git a/doc/board/xilinx/zynqmp.rst b/doc/board/xilinx/zynqmp.rst
new file mode 100644 (file)
index 0000000..a035cff
--- /dev/null
@@ -0,0 +1,115 @@
+.. SPDX-License-Identifier: GPL-2.0
+..  (C) Copyright 2020 Xilinx, Inc.
+
+ZYNQMP
+======
+
+About this
+----------
+
+This document describes the information about Xilinx Zynq UltraScale+ MPSOC
+U-Boot support. Core support is available in arch/arm/mach-zynqmp folder.
+
+ZynqMP boards
+-------------
+
+* zcu100 (ultra96 v1), zcu102, zcu104, zcu106 - Evaluation boards
+* zc1232 - Characterization boards
+* zcu111, zcu208, zcu216 - RFSOC evaluation boards
+* zcu1254, zcu1275, zcu1285 - RFSOC characterization boards
+* a2197 - System Controller on Versal boards
+* mini - Mini U-Boot running out of OCM
+* zc1751 - Characterization Processor boards
+     - zc1751-xm015-dc1
+     - zc1751-xm016-dc2
+     - zc1751-xm017-dc3
+     - zc1751-xm018-dc4
+     - zc1751-xm019-dc5
+
+Building
+--------
+
+Configure and build for zcu102 board::
+
+   $ source arm64 toolchain
+   $ export DEVICE_TREE=zynqmp-zcu102-revA
+   $ make xilinx_zynqmp_virt_defconfig
+   $ make
+
+U-Boot SPL flow
+---------------
+
+For getting U-Boot SPL flow up and running it is necessary to do some additional
+steps because booting device requires external images which are not the part of
+U-Boot repository.
+
+PMU firmware
+^^^^^^^^^^^^
+The Platform Management Unit (PMU) RAM can be loaded with a firmware (PMU
+Firmware) at run-time and can be used to extend or customize the functionality
+of PMU. The PMU firmware is the part of boot image (boot.bin) and it is
+automatically loaded by BootROM. boot.bin can be directly generated by mkimage
+tool as the part of make. If you want to create boot.bin with PMU Firmware
+include please point CONFIG_PMUFW_INIT_FILE to PMU firmware binary. For example:::
+
+  CONFIG_PMUFW_INIT_FILE="<path>/pmu.bin"
+
+If you see below message you need to load PMU Firmware::
+
+  PMUFW is not found - Please load it!
+
+The second external blob is PMU Configuration object which is object which is
+passed from U-Boot SPL to PMU Firmware for initial system configuration. PMU
+configuration object is the part of U-Boot SPL image. For pointing to this
+object please use CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE symbol. For example:::
+
+  CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE="<path>/pmu_obj.bin"
+
+
+PMU configuration object
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Object can be obtain in several ways. The easiest way is to take pm_cfg_obj.c
+from SDK/Vitis design and build it:::
+
+  $ git clone https://github.com/Xilinx/embeddedsw.git
+  $ export EMBEDDED_SW=$PWD/embeddedsw
+  $ gcc -c pm_cfg_obj.c -I ${EMBEDDED_SW}/lib/bsp/standalone/src/common/ -I ${EMBEDDED_SW}/lib/sw_services/xilpm/src/zynqmp/client/common/
+  $ objcopy -O binary pm_cfg_obj.o pmu_obj.bin
+
+The second way is to use tools/zynqmp_pm_cfg_obj_convert.py. For more
+information about this tool please run it with -h parameter.
+
+The third way is to extract it from Xilinx FSBL elf file. Object is starting at
+XPm_ConfigObject symbol.
+
+
+Arm Trusted Firmware (ATF)
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+U-Boot itself can run from EL3 to EL1. Without ATF U-Boot runs in EL3. Boot flow
+is U-Boot SPL->U-Boot in EL3. When ATF is used U-Boot normally runs in EL2. Boot
+flow is U-Boot SPL->ATF->U-Boot in EL2. As the part of build process u-boot.itb
+is generated. When BL31 shell variable is present u-boot.itb is generated with
+ATF included. You can point to it by:::
+
+  $ export BL31=<path>/bl31.bin
+
+Flashing
+--------
+
+SD Card
+^^^^^^^
+
+To write an image that boots from a SD card first create a FAT32 partition
+and a FAT32 filesystem on the SD card::
+
+        sudo fdisk /dev/sdx
+        sudo mkfs.vfat -F 32 /dev/sdx1
+
+Mount the SD card and copy the SPL and U-Boot to the root directory of the
+SD card::
+
+        sudo mount -t vfat /dev/sdx1 /mnt
+        sudo cp spl/boot.bin /mnt
+        sudo cp u-boot.itb /mnt
index 8592719..019dda2 100644 (file)
@@ -66,6 +66,90 @@ can point to a script which generates this image source file during
 the build process. It gets passed a list of device tree files (taken from the
 CONFIG_OF_LIST symbol).
 
+The SPL also records to a DT all additional images (called loadables) which are
+loaded. The information about loadables locations is passed via the DT node with
+fit-images name.
+
+Loadables Example
+-----------------
+Consider the following case for an ARM64 platform where U-Boot runs in EL2
+started by ATF where SPL is loading U-Boot (as loadables) and ATF (as firmware).
+
+/dts-v1/;
+
+/ {
+       description = "Configuration to load ATF before U-Boot";
+
+       images {
+               uboot {
+                       description = "U-Boot (64-bit)";
+                       data = /incbin/("u-boot-nodtb.bin");
+                       type = "firmware";
+                       os = "u-boot";
+                       arch = "arm64";
+                       compression = "none";
+                       load = <0x8 0x8000000>;
+                       entry = <0x8 0x8000000>;
+                       hash {
+                               algo = "md5";
+                       };
+               };
+               atf {
+                       description = "ARM Trusted Firmware";
+                       data = /incbin/("bl31.bin");
+                       type = "firmware";
+                       os = "arm-trusted-firmware";
+                       arch = "arm64";
+                       compression = "none";
+                       load = <0xfffea000>;
+                       entry = <0xfffea000>;
+                       hash {
+                               algo = "md5";
+                       };
+               };
+               fdt_1 {
+                       description = "zynqmp-zcu102-revA";
+                       data = /incbin/("arch/arm/dts/zynqmp-zcu102-revA.dtb");
+                       type = "flat_dt";
+                       arch = "arm64";
+                       compression = "none";
+                       load = <0x100000>;
+                       hash {
+                               algo = "md5";
+                       };
+               };
+       };
+       configurations {
+               default = "config_1";
+
+               config_1 {
+                       description = "zynqmp-zcu102-revA";
+                       firmware = "atf";
+                       loadables = "uboot";
+                       fdt = "fdt_1";
+               };
+       };
+};
+
+In this case the SPL records via fit-images DT node the information about
+loadables U-Boot image.
+
+ZynqMP> fdt addr $fdtcontroladdr
+ZynqMP> fdt print /fit-images
+fit-images {
+       uboot {
+               os = "u-boot";
+               type = "firmware";
+               size = <0x001017c8>;
+               entry = <0x00000008 0x08000000>;
+               load = <0x00000008 0x08000000>;
+       };
+};
+
+As you can see entry and load properties are 64bit wide to support loading
+images above 4GB (in past entry and load properties where just 32bit).
+
+
 Example 1 -- old-style (non-FDT) kernel booting
 -----------------------------------------------
 
index 7d1b895..a68076b 100644 (file)
@@ -476,6 +476,28 @@ ofnode ofnode_get_chosen_node(const char *name)
        return ofnode_path(prop);
 }
 
+const void *ofnode_read_aliases_prop(const char *propname, int *sizep)
+{
+       ofnode node;
+
+       node = ofnode_path("/aliases");
+
+       return ofnode_read_prop(node, propname, sizep);
+}
+
+ofnode ofnode_get_aliases_node(const char *name)
+{
+       const char *prop;
+
+       prop = ofnode_read_aliases_prop(name, NULL);
+       if (!prop)
+               return ofnode_null();
+
+       debug("%s: node_path: %s\n", __func__, prop);
+
+       return ofnode_path(prop);
+}
+
 int ofnode_get_child_count(ofnode parent)
 {
        ofnode child;
index 7583f24..d4dc856 100644 (file)
@@ -165,6 +165,14 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
                 */
                u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
 
+               if (api_id == PM_FPGA_LOAD) {
+                       /* Swap addr_hi/low because of incompatibility */
+                       u32 temp = regs[1];
+
+                       regs[1] = regs[2];
+                       regs[2] = temp;
+               }
+
                ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT);
 #else
                return -EPERM;
index 9483ed9..847a036 100644 (file)
@@ -56,7 +56,7 @@ static int zynqmp_ipi_send(struct mbox_chan *chan, const void *data)
 
        /* Wait until observation bit is cleared */
        ret = wait_for_bit_le32(&ipi_int_apu->obs, IPI_BIT_MASK_PMU0, false,
-                               100, false);
+                               1000, false);
 
        debug("%s, send %ld bytes\n", __func__, msg->len);
        return ret;
index b67e906..29432ae 100644 (file)
@@ -376,13 +376,6 @@ config SPL_I2C_EEPROM
          This option is an SPL-variant of the I2C_EEPROM option.
          See the help of I2C_EEPROM for details.
 
-config ZYNQ_GEM_I2C_MAC_OFFSET
-       hex "Set the I2C MAC offset"
-       default 0x0
-       depends on DM_I2C
-       help
-         Set the MAC offset for i2C.
-
 if I2C_EEPROM
 
 config SYS_I2C_EEPROM_ADDR
index d549a26..0628934 100644 (file)
@@ -812,7 +812,8 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
                cfg->host_caps &= ~MMC_MODE_HS_52MHz;
        }
 
-       if (!(cfg->voltages & MMC_VDD_165_195))
+       if (!(cfg->voltages & MMC_VDD_165_195) ||
+           (host->quirks & SDHCI_QUIRK_NO_1_8_V))
                caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
                            SDHCI_SUPPORT_DDR50);
 
index 775c17b..147ecc0 100644 (file)
 #include <sdhci.h>
 #include <zynqmp_tap_delay.h>
 
+#define SDHCI_ARASAN_ITAPDLY_REGISTER   0xF0F8
+#define SDHCI_ARASAN_OTAPDLY_REGISTER   0xF0FC
+#define SDHCI_ITAPDLY_CHGWIN            0x200
+#define SDHCI_ITAPDLY_ENABLE            0x100
+#define SDHCI_OTAPDLY_ENABLE            0x40
+
+#define SDHCI_TUNING_LOOP_COUNT                40
+#define MMC_BANK2                      0x2
+
+struct arasan_sdhci_clk_data {
+       int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
+       int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
+};
+
 struct arasan_sdhci_plat {
        struct mmc_config cfg;
        struct mmc mmc;
@@ -26,29 +40,35 @@ struct arasan_sdhci_plat {
 
 struct arasan_sdhci_priv {
        struct sdhci_host *host;
+       struct arasan_sdhci_clk_data clk_data;
        u8 deviceid;
        u8 bank;
+       u8 no_1p8;
 };
 
-#if defined(CONFIG_ARCH_ZYNQMP)
-#define MMC_HS200_BUS_SPEED    5
+#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
+/* Default settings for ZynqMP Clock Phases */
+const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63,  0,   0, 183, 54,  0, 0};
+const u32 zynqmp_oclk_phases[] = {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0};
+
+/* Default settings for Versal Clock Phases */
+const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132, 0, 0, 162, 90, 0, 0};
+const u32 versal_oclk_phases[] = {0,  60, 48, 0, 48, 72, 90, 36, 60, 90, 0};
 
 static const u8 mode2timing[] = {
-       [MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
-       [MMC_HS] = HIGH_SPEED_BUS_SPEED,
-       [SD_HS] = HIGH_SPEED_BUS_SPEED,
-       [MMC_HS_52] = HIGH_SPEED_BUS_SPEED,
-       [MMC_DDR_52] = HIGH_SPEED_BUS_SPEED,
-       [UHS_SDR12] = UHS_SDR12_BUS_SPEED,
-       [UHS_SDR25] = UHS_SDR25_BUS_SPEED,
-       [UHS_SDR50] = UHS_SDR50_BUS_SPEED,
-       [UHS_DDR50] = UHS_DDR50_BUS_SPEED,
-       [UHS_SDR104] = UHS_SDR104_BUS_SPEED,
-       [MMC_HS_200] = MMC_HS200_BUS_SPEED,
+       [MMC_LEGACY] = MMC_TIMING_LEGACY,
+       [MMC_HS] = MMC_TIMING_MMC_HS,
+       [SD_HS] = MMC_TIMING_SD_HS,
+       [MMC_HS_52] = MMC_TIMING_UHS_SDR50,
+       [MMC_DDR_52] = MMC_TIMING_UHS_DDR50,
+       [UHS_SDR12] = MMC_TIMING_UHS_SDR12,
+       [UHS_SDR25] = MMC_TIMING_UHS_SDR25,
+       [UHS_SDR50] = MMC_TIMING_UHS_SDR50,
+       [UHS_DDR50] = MMC_TIMING_UHS_DDR50,
+       [UHS_SDR104] = MMC_TIMING_UHS_SDR104,
+       [MMC_HS_200] = MMC_TIMING_MMC_HS200,
 };
 
-#define SDHCI_TUNING_LOOP_COUNT        40
-
 static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
 {
        u16 clk;
@@ -156,17 +176,352 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
        return 0;
 }
 
+/**
+ * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
+ *
+ * Set the SD Output Clock Tap Delays for Output path
+ *
+ * @host:              Pointer to the sdhci_host structure.
+ * @degrees:           The clock phase shift between 0 - 359.
+ * Return: 0 on success and error value on error
+ */
+static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
+                                           int degrees)
+{
+       struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
+       struct mmc *mmc = (struct mmc *)host->mmc;
+       u8 tap_delay, tap_max = 0;
+       int ret;
+       int timing = mode2timing[mmc->selected_mode];
+
+       /*
+        * This is applicable for SDHCI_SPEC_300 and above
+        * ZynqMP does not set phase for <=25MHz clock.
+        * If degrees is zero, no need to do anything.
+        */
+       if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
+           timing == MMC_TIMING_LEGACY ||
+           timing == MMC_TIMING_UHS_SDR12 || !degrees)
+               return 0;
+
+       switch (timing) {
+       case MMC_TIMING_MMC_HS:
+       case MMC_TIMING_SD_HS:
+       case MMC_TIMING_UHS_SDR25:
+       case MMC_TIMING_UHS_DDR50:
+       case MMC_TIMING_MMC_DDR52:
+               /* For 50MHz clock, 30 Taps are available */
+               tap_max = 30;
+               break;
+       case MMC_TIMING_UHS_SDR50:
+               /* For 100MHz clock, 15 Taps are available */
+               tap_max = 15;
+               break;
+       case MMC_TIMING_UHS_SDR104:
+       case MMC_TIMING_MMC_HS200:
+               /* For 200MHz clock, 8 Taps are available */
+               tap_max = 8;
+       default:
+               break;
+       }
+
+       tap_delay = (degrees * tap_max) / 360;
+
+       arasan_zynqmp_set_tapdelay(priv->deviceid, 0, tap_delay);
+
+       return ret;
+}
+
+/**
+ * sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Clock Tap Delays
+ *
+ * Set the SD Input Clock Tap Delays for Input path
+ *
+ * @host:              Pointer to the sdhci_host structure.
+ * @degrees:           The clock phase shift between 0 - 359.
+ * Return: 0 on success and error value on error
+ */
+static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
+                                           int degrees)
+{
+       struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
+       struct mmc *mmc = (struct mmc *)host->mmc;
+       u8 tap_delay, tap_max = 0;
+       int ret;
+       int timing = mode2timing[mmc->selected_mode];
+
+       /*
+        * This is applicable for SDHCI_SPEC_300 and above
+        * ZynqMP does not set phase for <=25MHz clock.
+        * If degrees is zero, no need to do anything.
+        */
+       if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
+           timing == MMC_TIMING_LEGACY ||
+           timing == MMC_TIMING_UHS_SDR12 || !degrees)
+               return 0;
+
+       switch (timing) {
+       case MMC_TIMING_MMC_HS:
+       case MMC_TIMING_SD_HS:
+       case MMC_TIMING_UHS_SDR25:
+       case MMC_TIMING_UHS_DDR50:
+       case MMC_TIMING_MMC_DDR52:
+               /* For 50MHz clock, 120 Taps are available */
+               tap_max = 120;
+               break;
+       case MMC_TIMING_UHS_SDR50:
+               /* For 100MHz clock, 60 Taps are available */
+               tap_max = 60;
+               break;
+       case MMC_TIMING_UHS_SDR104:
+       case MMC_TIMING_MMC_HS200:
+               /* For 200MHz clock, 30 Taps are available */
+               tap_max = 30;
+       default:
+               break;
+       }
+
+       tap_delay = (degrees * tap_max) / 360;
+
+       arasan_zynqmp_set_tapdelay(priv->deviceid, tap_delay, 0);
+
+       return ret;
+}
+
+/**
+ * sdhci_versal_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
+ *
+ * Set the SD Output Clock Tap Delays for Output path
+ *
+ * @host:              Pointer to the sdhci_host structure.
+ * @degrees            The clock phase shift between 0 - 359.
+ * Return: 0 on success and error value on error
+ */
+static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host,
+                                           int degrees)
+{
+       struct mmc *mmc = (struct mmc *)host->mmc;
+       u8 tap_delay, tap_max = 0;
+       int ret;
+       int timing = mode2timing[mmc->selected_mode];
+
+       /*
+        * This is applicable for SDHCI_SPEC_300 and above
+        * Versal does not set phase for <=25MHz clock.
+        * If degrees is zero, no need to do anything.
+        */
+       if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
+           timing == MMC_TIMING_LEGACY ||
+           timing == MMC_TIMING_UHS_SDR12 || !degrees)
+               return 0;
+
+       switch (timing) {
+       case MMC_TIMING_MMC_HS:
+       case MMC_TIMING_SD_HS:
+       case MMC_TIMING_UHS_SDR25:
+       case MMC_TIMING_UHS_DDR50:
+       case MMC_TIMING_MMC_DDR52:
+               /* For 50MHz clock, 30 Taps are available */
+               tap_max = 30;
+               break;
+       case MMC_TIMING_UHS_SDR50:
+               /* For 100MHz clock, 15 Taps are available */
+               tap_max = 15;
+               break;
+       case MMC_TIMING_UHS_SDR104:
+       case MMC_TIMING_MMC_HS200:
+               /* For 200MHz clock, 8 Taps are available */
+               tap_max = 8;
+       default:
+               break;
+       }
+
+       tap_delay = (degrees * tap_max) / 360;
+
+       /* Set the Clock Phase */
+       if (tap_delay) {
+               u32 regval;
+
+               regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER);
+               regval |= SDHCI_OTAPDLY_ENABLE;
+               sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
+               regval |= tap_delay;
+               sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
+       }
+
+       return ret;
+}
+
+/**
+ * sdhci_versal_sampleclk_set_phase - Set the SD Input Clock Tap Delays
+ *
+ * Set the SD Input Clock Tap Delays for Input path
+ *
+ * @host:              Pointer to the sdhci_host structure.
+ * @degrees            The clock phase shift between 0 - 359.
+ * Return: 0 on success and error value on error
+ */
+static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,
+                                           int degrees)
+{
+       struct mmc *mmc = (struct mmc *)host->mmc;
+       u8 tap_delay, tap_max = 0;
+       int ret;
+       int timing = mode2timing[mmc->selected_mode];
+
+       /*
+        * This is applicable for SDHCI_SPEC_300 and above
+        * Versal does not set phase for <=25MHz clock.
+        * If degrees is zero, no need to do anything.
+        */
+       if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
+           timing == MMC_TIMING_LEGACY ||
+           timing == MMC_TIMING_UHS_SDR12 || !degrees)
+               return 0;
+
+       switch (timing) {
+       case MMC_TIMING_MMC_HS:
+       case MMC_TIMING_SD_HS:
+       case MMC_TIMING_UHS_SDR25:
+       case MMC_TIMING_UHS_DDR50:
+       case MMC_TIMING_MMC_DDR52:
+               /* For 50MHz clock, 120 Taps are available */
+               tap_max = 120;
+               break;
+       case MMC_TIMING_UHS_SDR50:
+               /* For 100MHz clock, 60 Taps are available */
+               tap_max = 60;
+               break;
+       case MMC_TIMING_UHS_SDR104:
+       case MMC_TIMING_MMC_HS200:
+               /* For 200MHz clock, 30 Taps are available */
+               tap_max = 30;
+       default:
+               break;
+       }
+
+       tap_delay = (degrees * tap_max) / 360;
+
+       /* Set the Clock Phase */
+       if (tap_delay) {
+               u32 regval;
+
+               regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER);
+               regval |= SDHCI_ITAPDLY_CHGWIN;
+               sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+               regval |= SDHCI_ITAPDLY_ENABLE;
+               sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+               regval |= tap_delay;
+               sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+               regval &= ~SDHCI_ITAPDLY_CHGWIN;
+               sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+       }
+
+       return ret;
+}
+
 static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
 {
        struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
+       struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
        struct mmc *mmc = (struct mmc *)host->mmc;
-       u8 uhsmode;
+       struct udevice *dev = mmc->dev;
+       u8 timing = mode2timing[mmc->selected_mode];
+       u32 iclk_phase = clk_data->clk_phase_in[timing];
+       u32 oclk_phase = clk_data->clk_phase_out[timing];
+
+       dev_dbg(dev, "%s, host:%s, mode:%d\n", __func__, host->name, timing);
+
+       if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) &&
+           device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
+               sdhci_zynqmp_sampleclk_set_phase(host, iclk_phase);
+               sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase);
+       } else if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
+                  device_is_compatible(dev, "xlnx,versal-8.9a")) {
+               sdhci_versal_sampleclk_set_phase(host, iclk_phase);
+               sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
+       }
+}
 
-       uhsmode = mode2timing[mmc->selected_mode];
+static void arasan_dt_read_clk_phase(struct udevice *dev, unsigned char timing,
+                                    const char *prop)
+{
+       struct arasan_sdhci_priv *priv = dev_get_priv(dev);
+       struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
+       u32 clk_phase[2] = {0};
+
+       /*
+        * Read Tap Delay values from DT, if the DT does not contain the
+        * Tap Values then use the pre-defined values
+        */
+       if (dev_read_u32_array(dev, prop, &clk_phase[0], 2)) {
+               dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n",
+                       prop, clk_data->clk_phase_in[timing],
+                       clk_data->clk_phase_out[timing]);
+               return;
+       }
 
-       if (uhsmode >= UHS_SDR25_BUS_SPEED)
-               arasan_zynqmp_set_tapdelay(priv->deviceid, uhsmode,
-                                          priv->bank);
+       /* The values read are Input and Output Clock Delays in order */
+       clk_data->clk_phase_in[timing] = clk_phase[0];
+       clk_data->clk_phase_out[timing] = clk_phase[1];
+}
+
+/**
+ * arasan_dt_parse_clk_phases - Read Tap Delay values from DT
+ *
+ * Called at initialization to parse the values of Tap Delays.
+ *
+ * @dev:                Pointer to our struct udevice.
+ */
+static void arasan_dt_parse_clk_phases(struct udevice *dev)
+{
+       struct arasan_sdhci_priv *priv = dev_get_priv(dev);
+       struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
+       int i;
+
+       if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) &&
+           device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
+               for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
+                       clk_data->clk_phase_in[i] = zynqmp_iclk_phases[i];
+                       clk_data->clk_phase_out[i] = zynqmp_oclk_phases[i];
+               }
+
+               if (priv->bank == MMC_BANK2) {
+                       clk_data->clk_phase_out[MMC_TIMING_UHS_SDR104] = 90;
+                       clk_data->clk_phase_out[MMC_TIMING_MMC_HS200] = 90;
+               }
+       }
+
+       if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
+           device_is_compatible(dev, "xlnx,versal-8.9a")) {
+               for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
+                       clk_data->clk_phase_in[i] = versal_iclk_phases[i];
+                       clk_data->clk_phase_out[i] = versal_oclk_phases[i];
+               }
+       }
+
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_LEGACY,
+                                "clk-phase-legacy");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS,
+                                "clk-phase-mmc-hs");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_SD_HS,
+                                "clk-phase-sd-hs");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR12,
+                                "clk-phase-uhs-sdr12");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR25,
+                                "clk-phase-uhs-sdr25");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR50,
+                                "clk-phase-uhs-sdr50");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR104,
+                                "clk-phase-uhs-sdr104");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_DDR50,
+                                "clk-phase-uhs-ddr50");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_DDR52,
+                                "clk-phase-mmc-ddr52");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS200,
+                                "clk-phase-mmc-hs200");
+       arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS400,
+                                "clk-phase-mmc-hs400");
 }
 
 static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
@@ -184,12 +539,10 @@ static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
        }
 
        if (mmc->selected_mode > SD_HS &&
-           mmc->selected_mode <= UHS_DDR50)
+           mmc->selected_mode <= MMC_HS_200)
                sdhci_set_uhs_timing(host);
 }
-#endif
 
-#if defined(CONFIG_ARCH_ZYNQMP)
 const struct sdhci_ops arasan_ops = {
        .platform_execute_tuning = &arasan_sdhci_execute_tuning,
        .set_delay = &arasan_sdhci_set_tapdelay,
@@ -236,6 +589,9 @@ static int arasan_sdhci_probe(struct udevice *dev)
        host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE;
 #endif
 
+       if (priv->no_1p8)
+               host->quirks |= SDHCI_QUIRK_NO_1_8_V;
+
        plat->cfg.f_max = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
 
        ret = mmc_of_parse(dev, &plat->cfg);
@@ -267,8 +623,9 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 
        priv->host->name = dev->name;
 
-#if defined(CONFIG_ARCH_ZYNQMP)
+#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
        priv->host->ops = &arasan_ops;
+       arasan_dt_parse_clk_phases(dev);
 #endif
 
        priv->host->ioaddr = (void *)dev_read_addr(dev);
@@ -277,6 +634,7 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 
        priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1);
        priv->bank = dev_read_u32_default(dev, "xlnx,mio-bank", 0);
+       priv->no_1p8 = dev_read_bool(dev, "no-1-8-v");
 
        return 0;
 }
index dabd40a..9ceff0e 100644 (file)
@@ -67,7 +67,7 @@ struct flash_info {
 #define SPI_NOR_SKIP_SFDP      BIT(13) /* Skip parsing of SFDP tables */
 #define USE_CLSR               BIT(14) /* use CLSR command */
 #define SPI_NOR_HAS_SST26LOCK  BIT(15) /* Flash supports lock/unlock via BPR */
-#define SPI_NOR_OCTAL_READ      BIT(16) /* Flash supports Octal Read */
+#define SPI_NOR_OCTAL_READ     BIT(16) /* Flash supports Octal Read */
 };
 
 extern const struct flash_info spi_nor_ids[];
index 2772c25..d9e35c6 100644 (file)
@@ -19,6 +19,7 @@
 #include <watchdog.h>
 #include <asm/io.h>
 #include <serial.h>
+#include <dm/device_compat.h>
 #include <dm/platform_data/serial_pl01x.h>
 #include <linux/compiler.h>
 #include "serial_pl01x_internal.h"
@@ -362,8 +363,18 @@ int pl01x_serial_ofdata_to_platdata(struct udevice *dev)
        plat->clock = dev_read_u32_default(dev, "clock", CONFIG_PL011_CLOCK);
        ret = clk_get_by_index(dev, 0, &clk);
        if (!ret) {
-               clk_enable(&clk);
+               ret = clk_enable(&clk);
+               if (ret && ret != -ENOSYS) {
+                       dev_err(dev, "failed to enable clock\n");
+                       return ret;
+               }
+
                plat->clock = clk_get_rate(&clk);
+               if (IS_ERR_VALUE(plat->clock)) {
+                       dev_err(dev, "failed to get rate\n");
+                       return plat->clock;
+               }
+               debug("%s: CLK %d\n", __func__, plat->clock);
        }
        plat->type = dev_get_driver_data(dev);
        plat->skip_init = dev_read_bool(dev, "skip-init");
index 348630f..47a5571 100644 (file)
@@ -214,7 +214,7 @@ static void xilinx_spi_startup_block(struct udevice *dev, unsigned int bytes,
        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
        const unsigned char *txp = dout;
        unsigned char *rxp = din;
-       u32 reg, count;
+       u32 reg;
        u32 txbytes = bytes;
        u32 rxbytes = bytes;
 
@@ -224,10 +224,10 @@ static void xilinx_spi_startup_block(struct udevice *dev, unsigned int bytes,
         * it sets txp to the initial value for the normal operation.
         */
        for ( ; priv->startup < 2; priv->startup++) {
-               count = xilinx_spi_fill_txfifo(bus, txp, txbytes);
+               xilinx_spi_fill_txfifo(bus, txp, txbytes);
                reg = readl(&regs->spicr) & ~SPICR_MASTER_INHIBIT;
                writel(reg, &regs->spicr);
-               count = xilinx_spi_read_rxfifo(bus, rxp, rxbytes);
+               xilinx_spi_read_rxfifo(bus, rxp, rxbytes);
                txp = din;
 
                if (priv->startup) {
@@ -251,7 +251,7 @@ static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen,
        unsigned char *rxp = din;
        u32 txbytes = bytes;
        u32 rxbytes = bytes;
-       u32 reg, count, timeout;
+       u32 reg, count;
        int ret;
 
        debug("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n",
index 3f39ef0..f2eddec 100644 (file)
@@ -6,8 +6,10 @@
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
 
+#include <clk.h>
 #include <common.h>
 #include <dm.h>
+#include <dm/device_compat.h>
 #include <log.h>
 #include <malloc.h>
 #include <spi.h>
@@ -105,17 +107,29 @@ static int zynq_qspi_ofdata_to_platdata(struct udevice *bus)
        plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
                                                              node, "reg");
 
-       /* FIXME: Use 166MHz as a suitable default */
-       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
-                                       166666666);
-       plat->speed_hz = plat->frequency / 2;
-
-       debug("%s: regs=%p max-frequency=%d\n", __func__,
-             plat->regs, plat->frequency);
-
        return 0;
 }
 
+/**
+ * zynq_qspi_init_hw - Initialize the hardware
+ * @priv:      Pointer to the zynq_qspi_priv structure
+ *
+ * The default settings of the QSPI controller's configurable parameters on
+ * reset are
+ *     - Master mode
+ *     - Baud rate divisor is set to 2
+ *     - Threshold value for TX FIFO not full interrupt is set to 1
+ *     - Flash memory interface mode enabled
+ *     - Size of the word to be transferred as 8 bit
+ * This function performs the following actions
+ *     - Disable and clear all the interrupts
+ *     - Enable manual slave select
+ *     - Enable auto start
+ *     - Deselect all the chip select lines
+ *     - Set the size of the word to be transferred as 32 bit
+ *     - Set the little endian mode of TX FIFO and
+ *     - Enable the QSPI controller
+ */
 static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
 {
        struct zynq_qspi_regs *regs = priv->regs;
@@ -159,19 +173,45 @@ static int zynq_qspi_probe(struct udevice *bus)
 {
        struct zynq_qspi_platdata *plat = dev_get_platdata(bus);
        struct zynq_qspi_priv *priv = dev_get_priv(bus);
+       struct clk clk;
+       unsigned long clock;
+       int ret;
 
        priv->regs = plat->regs;
        priv->fifo_depth = ZYNQ_QSPI_FIFO_DEPTH;
 
+       ret = clk_get_by_name(bus, "ref_clk", &clk);
+       if (ret < 0) {
+               dev_err(bus, "failed to get clock\n");
+               return ret;
+       }
+
+       clock = clk_get_rate(&clk);
+       if (IS_ERR_VALUE(clock)) {
+               dev_err(bus, "failed to get rate\n");
+               return clock;
+       }
+
+       ret = clk_enable(&clk);
+       if (ret && ret != -ENOSYS) {
+               dev_err(bus, "failed to enable clock\n");
+               return ret;
+       }
+
        /* init the zynq spi hw */
        zynq_qspi_init_hw(priv);
 
+       plat->frequency = clock;
+       plat->speed_hz = plat->frequency / 2;
+
+       debug("%s: max-frequency=%d\n", __func__, plat->speed_hz);
+
        return 0;
 }
 
-/*
+/**
  * zynq_qspi_read_data - Copy data to RX buffer
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi_priv structure
  * @data:      The 32 bit variable where data is stored
  * @size:      Number of bytes to be copied from data to RX buffer
  */
@@ -214,9 +254,9 @@ static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size)
                priv->bytes_to_receive = 0;
 }
 
-/*
+/**
  * zynq_qspi_write_data - Copy data from TX buffer
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi_priv structure
  * @data:      Pointer to the 32 bit variable where data is to be copied
  * @size:      Number of bytes to be copied from TX buffer to data
  */
@@ -263,6 +303,11 @@ static void zynq_qspi_write_data(struct  zynq_qspi_priv *priv,
                priv->bytes_to_transfer = 0;
 }
 
+/**
+ * zynq_qspi_chipselect - Select or deselect the chip select line
+ * @priv:      Pointer to the zynq_qspi_priv structure
+ * @is_on:     Select(1) or deselect (0) the chip select line
+ */
 static void zynq_qspi_chipselect(struct  zynq_qspi_priv *priv, int is_on)
 {
        u32 confr;
@@ -282,9 +327,10 @@ static void zynq_qspi_chipselect(struct  zynq_qspi_priv *priv, int is_on)
        writel(confr, &regs->cr);
 }
 
-/*
+/**
  * zynq_qspi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi_priv structure
+ * @size:      Number of bytes to be copied to fifo
  */
 static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
 {
@@ -322,9 +368,9 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
        }
 }
 
-/*
+/**
  * zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller
- * @zqspi:     Pointer to the zynq_qspi structure
+ * @priv:      Pointer to the zynq_qspi structure
  *
  * This function handles TX empty and Mode Fault interrupts only.
  * On TX empty interrupt this function reads the received data from RX FIFO and
@@ -410,11 +456,9 @@ static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv)
        return 0;
 }
 
-/*
+/**
  * zynq_qspi_start_transfer - Initiates the QSPI transfer
- * @qspi:      Pointer to the spi_device structure
- * @transfer:  Pointer to the spi_transfer structure which provide information
- *             about next transfer parameters
+ * @priv:      Pointer to the zynq_qspi_priv structure
  *
  * This function fills the TX FIFO, starts the QSPI transfer, and waits for the
  * transfer to be completed.
index 9923931..cb911c3 100644 (file)
@@ -8,10 +8,12 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dm/device_compat.h>
 #include <log.h>
 #include <malloc.h>
 #include <spi.h>
 #include <time.h>
+#include <clk.h>
 #include <asm/io.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
@@ -79,17 +81,10 @@ static int zynq_spi_ofdata_to_platdata(struct udevice *bus)
 
        plat->regs = dev_read_addr_ptr(bus);
 
-       /* FIXME: Use 250MHz as a suitable default */
-       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
-                                       250000000);
        plat->deactivate_delay_us = fdtdec_get_int(blob, node,
                                        "spi-deactivate-delay", 0);
        plat->activate_delay_us = fdtdec_get_int(blob, node,
                                                 "spi-activate-delay", 0);
-       plat->speed_hz = plat->frequency / 2;
-
-       debug("%s: regs=%p max-frequency=%d\n", __func__,
-             plat->regs, plat->frequency);
 
        return 0;
 }
@@ -128,13 +123,39 @@ static int zynq_spi_probe(struct udevice *bus)
 {
        struct zynq_spi_platdata *plat = dev_get_platdata(bus);
        struct zynq_spi_priv *priv = dev_get_priv(bus);
+       struct clk clk;
+       unsigned long clock;
+       int ret;
 
        priv->regs = plat->regs;
        priv->fifo_depth = ZYNQ_SPI_FIFO_DEPTH;
 
+       ret = clk_get_by_name(bus, "ref_clk", &clk);
+       if (ret < 0) {
+               dev_err(bus, "failed to get clock\n");
+               return ret;
+       }
+
+       clock = clk_get_rate(&clk);
+       if (IS_ERR_VALUE(clock)) {
+               dev_err(bus, "failed to get rate\n");
+               return clock;
+       }
+
+       ret = clk_enable(&clk);
+       if (ret && ret != -ENOSYS) {
+               dev_err(bus, "failed to enable clock\n");
+               return ret;
+       }
+
        /* init the zynq spi hw */
        zynq_spi_init_hw(priv);
 
+       plat->frequency = clock;
+       plat->speed_hz = plat->frequency / 2;
+
+       debug("%s: max-frequency=%d\n", __func__, plat->speed_hz);
+
        return 0;
 }
 
index 8ca0e83..2b41242 100644 (file)
 #define        CONFIG_SYS_LOAD_ADDR    0
 
 #define        CONFIG_HOSTNAME         "microblaze-generic"
-#define        CONFIG_BOOTCOMMAND      "base 0;tftp 11000000 image.img;bootm"
 
 /* architecture dependent code */
 #define        CONFIG_SYS_USR_EXCEP    /* user exception */
 
+#if defined(CONFIG_CMD_PXE) && defined(CONFIG_CMD_DHCP)
+#define BOOT_TARGET_DEVICES_PXE(func)  func(PXE, pxe, na)
+#else
+#define BOOT_TARGET_DEVICES_PXE(func)
+#endif
+
+#if defined(CONFIG_CMD_DHCP)
+#define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na)
+#else
+#define BOOT_TARGET_DEVICES_DHCP(func)
+#endif
+
+#if defined(CONFIG_SPI_FLASH)
+# define BOOT_TARGET_DEVICES_QSPI(func) func(QSPI, qspi, na)
+#else
+# define BOOT_TARGET_DEVICES_QSPI(func)
+#endif
+
+#define BOOTENV_DEV_QSPI(devtypeu, devtypel, instance) \
+       "bootcmd_qspi=sf probe 0 0 0 && " \
+       "sf read ${scriptaddr} ${script_offset_f} ${script_size_f} && " \
+       "echo QSPI: Trying to boot script at ${scriptaddr} && " \
+       "source ${scriptaddr}; echo QSPI: SCRIPT FAILED: continuing...;\0"
+
+#define BOOTENV_DEV_NAME_QSPI(devtypeu, devtypel, instance) \
+       "qspi "
+
+#define BOOT_TARGET_DEVICES_JTAG(func) func(JTAG, jtag, na)
+
+#define BOOTENV_DEV_JTAG(devtypeu, devtypel, instance) \
+       "bootcmd_jtag=echo JTAG: Trying to boot script at ${scriptaddr} && " \
+               "source ${scriptaddr}; echo JTAG: SCRIPT FAILED: continuing...;\0"
+
+#define BOOTENV_DEV_NAME_JTAG(devtypeu, devtypel, instance) \
+       "jtag "
+
+#define BOOT_TARGET_DEVICES(func) \
+       BOOT_TARGET_DEVICES_JTAG(func) \
+       BOOT_TARGET_DEVICES_QSPI(func)  \
+       BOOT_TARGET_DEVICES_DHCP(func) \
+       BOOT_TARGET_DEVICES_PXE(func)
+
+#include <config_distro_bootcmd.h>
+
 #ifndef CONFIG_EXTRA_ENV_SETTINGS
-#define        CONFIG_EXTRA_ENV_SETTINGS       "unlock=yes\0" \
-                                       "nor0=flash-0\0"\
-                                       "mtdparts=mtdparts=flash-0:"\
-                                       "256k(u-boot),256k(env),3m(kernel),"\
-                                       "1m(romfs),1m(cramfs),-(jffs2)\0"\
-                                       "nc=setenv stdout nc;"\
-                                       "setenv stdin nc\0" \
-                                       "serial=setenv stdout serial;"\
-                                       "setenv stdin serial\0"
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "unlock=yes\0"\
+       "nor0=flash-0\0"\
+       "mtdparts=mtdparts=flash-0:"\
+       "256k(u-boot),256k(env),3m(kernel),"\
+       "1m(romfs),1m(cramfs),-(jffs2)\0"\
+       "nc=setenv stdout nc;"\
+       "setenv stdin nc\0" \
+       "serial=setenv stdout serial;"\
+       "setenv stdin serial\0"\
+       "script_size_f=0x40000\0"\
+       BOOTENV
 #endif
 
 #if defined(CONFIG_XILINX_AXIEMAC)
 #define CONFIG_SYS_INIT_RAM_SIZE       0x100000
 
 # define CONFIG_SPL_STACK_ADDR         (CONFIG_SYS_INIT_RAM_ADDR + \
-                                        CONFIG_SYS_INIT_RAM_SIZE - \
-                                        CONFIG_SYS_MALLOC_F_LEN)
+                                        CONFIG_SYS_INIT_RAM_SIZE)
 
 /* Just for sure that there is a space for stack */
 #define CONFIG_SPL_STACK_SIZE          0x100
index 8b41632..f1d2594 100644 (file)
@@ -18,7 +18,6 @@
 #define GICD_BASE      0xF9000000
 #define GICR_BASE      0xF9080000
 
-
 #define CONFIG_SYS_INIT_SP_ADDR                CONFIG_SYS_TEXT_BASE
 
 /* Generic Timer Definitions - setup in EL3. Setup by ATF for other cases */
index 0b201a2..00c9718 100644 (file)
@@ -10,7 +10,6 @@
 #ifndef __CONFIG_VERSAL_MINI_H
 #define __CONFIG_VERSAL_MINI_H
 
-
 #define CONFIG_EXTRA_ENV_SETTINGS
 
 #include <configs/xilinx_versal.h>
index 3f57423..ef9c768 100644 (file)
@@ -10,7 +10,6 @@
 #ifndef __CONFIG_ZYNQMP_MINI_H
 #define __CONFIG_ZYNQMP_MINI_H
 
-
 #define CONFIG_EXTRA_ENV_SETTINGS
 
 #include <configs/xilinx_zynqmp.h>
index 4b7af37..ced7f6f 100644 (file)
@@ -605,6 +605,28 @@ const char *ofnode_read_chosen_string(const char *propname);
  */
 ofnode ofnode_get_chosen_node(const char *propname);
 
+/**
+ * ofnode_read_aliases_prop() - get the value of a aliases property
+ *
+ * This looks for a property within the /aliases node and returns its value
+ *
+ * @propname: Property name to look for
+ * @sizep: Returns size of property, or FDT_ERR_... error code if function
+ *     returns NULL
+ * @return property value if found, else NULL
+ */
+const void *ofnode_read_aliases_prop(const char *propname, int *sizep);
+
+/**
+ * ofnode_get_aliases_node() - get a referenced node from the aliases node
+ *
+ * This looks up a named property in the aliases node and uses that as a path to
+ * look up a code.
+ *
+ * @return the referenced node if present, else ofnode_null()
+ */
+ofnode ofnode_get_aliases_node(const char *propname);
+
 struct display_timing;
 /**
  * ofnode_decode_display_timing() - decode display timings
diff --git a/include/dt-bindings/clock/xlnx-versal-clk.h b/include/dt-bindings/clock/xlnx-versal-clk.h
new file mode 100644 (file)
index 0000000..264d634
--- /dev/null
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright (C) 2019 Xilinx Inc.
+ *
+ */
+
+#ifndef _DT_BINDINGS_CLK_VERSAL_H
+#define _DT_BINDINGS_CLK_VERSAL_H
+
+#define PMC_PLL                                        1
+#define APU_PLL                                        2
+#define RPU_PLL                                        3
+#define CPM_PLL                                        4
+#define NOC_PLL                                        5
+#define PLL_MAX                                        6
+#define PMC_PRESRC                             7
+#define PMC_POSTCLK                            8
+#define PMC_PLL_OUT                            9
+#define PPLL                                   10
+#define NOC_PRESRC                             11
+#define NOC_POSTCLK                            12
+#define NOC_PLL_OUT                            13
+#define NPLL                                   14
+#define APU_PRESRC                             15
+#define APU_POSTCLK                            16
+#define APU_PLL_OUT                            17
+#define APLL                                   18
+#define RPU_PRESRC                             19
+#define RPU_POSTCLK                            20
+#define RPU_PLL_OUT                            21
+#define RPLL                                   22
+#define CPM_PRESRC                             23
+#define CPM_POSTCLK                            24
+#define CPM_PLL_OUT                            25
+#define CPLL                                   26
+#define PPLL_TO_XPD                            27
+#define NPLL_TO_XPD                            28
+#define APLL_TO_XPD                            29
+#define RPLL_TO_XPD                            30
+#define EFUSE_REF                              31
+#define SYSMON_REF                             32
+#define IRO_SUSPEND_REF                                33
+#define USB_SUSPEND                            34
+#define SWITCH_TIMEOUT                         35
+#define RCLK_PMC                               36
+#define RCLK_LPD                               37
+#define WDT                                    38
+#define TTC0                                   39
+#define TTC1                                   40
+#define TTC2                                   41
+#define TTC3                                   42
+#define GEM_TSU                                        43
+#define GEM_TSU_LB                             44
+#define MUXED_IRO_DIV2                         45
+#define MUXED_IRO_DIV4                         46
+#define PSM_REF                                        47
+#define GEM0_RX                                        48
+#define GEM0_TX                                        49
+#define GEM1_RX                                        50
+#define GEM1_TX                                        51
+#define CPM_CORE_REF                           52
+#define CPM_LSBUS_REF                          53
+#define CPM_DBG_REF                            54
+#define CPM_AUX0_REF                           55
+#define CPM_AUX1_REF                           56
+#define QSPI_REF                               57
+#define OSPI_REF                               58
+#define SDIO0_REF                              59
+#define SDIO1_REF                              60
+#define PMC_LSBUS_REF                          61
+#define I2C_REF                                        62
+#define TEST_PATTERN_REF                       63
+#define DFT_OSC_REF                            64
+#define PMC_PL0_REF                            65
+#define PMC_PL1_REF                            66
+#define PMC_PL2_REF                            67
+#define PMC_PL3_REF                            68
+#define CFU_REF                                        69
+#define SPARE_REF                              70
+#define NPI_REF                                        71
+#define HSM0_REF                               72
+#define HSM1_REF                               73
+#define SD_DLL_REF                             74
+#define FPD_TOP_SWITCH                         75
+#define FPD_LSBUS                              76
+#define ACPU                                   77
+#define DBG_TRACE                              78
+#define DBG_FPD                                        79
+#define LPD_TOP_SWITCH                         80
+#define ADMA                                   81
+#define LPD_LSBUS                              82
+#define CPU_R5                                 83
+#define CPU_R5_CORE                            84
+#define CPU_R5_OCM                             85
+#define CPU_R5_OCM2                            86
+#define IOU_SWITCH                             87
+#define GEM0_REF                               88
+#define GEM1_REF                               89
+#define GEM_TSU_REF                            90
+#define USB0_BUS_REF                           91
+#define UART0_REF                              92
+#define UART1_REF                              93
+#define SPI0_REF                               94
+#define SPI1_REF                               95
+#define CAN0_REF                               96
+#define CAN1_REF                               97
+#define I2C0_REF                               98
+#define I2C1_REF                               99
+#define DBG_LPD                                        100
+#define TIMESTAMP_REF                          101
+#define DBG_TSTMP                              102
+#define CPM_TOPSW_REF                          103
+#define USB3_DUAL_REF                          104
+#define OUTCLK_MAX                             105
+#define REF_CLK                                        106
+#define PL_ALT_REF_CLK                         107
+#define MUXED_IRO                              108
+#define PL_EXT                                 109
+#define PL_LB                                  110
+#define MIO_50_OR_51                           111
+#define MIO_24_OR_25                           112
+
+#endif
diff --git a/include/dt-bindings/power/xlnx-versal-power.h b/include/dt-bindings/power/xlnx-versal-power.h
new file mode 100644 (file)
index 0000000..1b75175
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright (C) 2019 - 2020 Xilinx, Inc.
+ */
+
+#ifndef _DT_BINDINGS_VERSAL_POWER_H
+#define _DT_BINDINGS_VERSAL_POWER_H
+
+#define PM_DEV_USB_0                           (0x18224018U)
+#define PM_DEV_GEM_0                           (0x18224019U)
+#define PM_DEV_GEM_1                           (0x1822401aU)
+#define PM_DEV_SPI_0                           (0x1822401bU)
+#define PM_DEV_SPI_1                           (0x1822401cU)
+#define PM_DEV_I2C_0                           (0x1822401dU)
+#define PM_DEV_I2C_1                           (0x1822401eU)
+#define PM_DEV_CAN_FD_0                                (0x1822401fU)
+#define PM_DEV_CAN_FD_1                                (0x18224020U)
+#define PM_DEV_UART_0                          (0x18224021U)
+#define PM_DEV_UART_1                          (0x18224022U)
+#define PM_DEV_GPIO                            (0x18224023U)
+#define PM_DEV_TTC_0                           (0x18224024U)
+#define PM_DEV_TTC_1                           (0x18224025U)
+#define PM_DEV_TTC_2                           (0x18224026U)
+#define PM_DEV_TTC_3                           (0x18224027U)
+#define PM_DEV_SWDT_FPD                                (0x18224029U)
+#define PM_DEV_OSPI                            (0x1822402aU)
+#define PM_DEV_QSPI                            (0x1822402bU)
+#define PM_DEV_GPIO_PMC                                (0x1822402cU)
+#define PM_DEV_SDIO_0                          (0x1822402eU)
+#define PM_DEV_SDIO_1                          (0x1822402fU)
+#define PM_DEV_RTC                             (0x18224034U)
+#define PM_DEV_ADMA_0                          (0x18224035U)
+#define PM_DEV_ADMA_1                          (0x18224036U)
+#define PM_DEV_ADMA_2                          (0x18224037U)
+#define PM_DEV_ADMA_3                          (0x18224038U)
+#define PM_DEV_ADMA_4                          (0x18224039U)
+#define PM_DEV_ADMA_5                          (0x1822403aU)
+#define PM_DEV_ADMA_6                          (0x1822403bU)
+#define PM_DEV_ADMA_7                          (0x1822403cU)
+#define PM_DEV_AI                              (0x18224072U)
+
+#endif
index ac7b54f..1d377e0 100644 (file)
@@ -360,6 +360,19 @@ enum mmc_voltage {
 #define MMC_NUM_BOOT_PARTITION 2
 #define MMC_PART_RPMB           3       /* RPMB partition number */
 
+/* timing specification used */
+#define MMC_TIMING_LEGACY      0
+#define MMC_TIMING_MMC_HS      1
+#define MMC_TIMING_SD_HS       2
+#define MMC_TIMING_UHS_SDR12   3
+#define MMC_TIMING_UHS_SDR25   4
+#define MMC_TIMING_UHS_SDR50   5
+#define MMC_TIMING_UHS_SDR104  6
+#define MMC_TIMING_UHS_DDR50   7
+#define MMC_TIMING_MMC_DDR52   8
+#define MMC_TIMING_MMC_HS200   9
+#define MMC_TIMING_MMC_HS400   10
+
 /* Driver model support */
 
 /**
index f69d5f8..1fd20ec 100644 (file)
 #define SDHCI_QUIRK_BROKEN_HISPD_MODE  BIT(5)
 #define SDHCI_QUIRK_WAIT_SEND_CMD      (1 << 6)
 #define SDHCI_QUIRK_USE_WIDE8          (1 << 8)
+#define SDHCI_QUIRK_NO_1_8_V           (1 << 9)
 
 /* to make gcc happy */
 struct sdhci_host;
index 1da8af1..7b7c291 100644 (file)
@@ -66,7 +66,7 @@ int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
                struct key_prop *node, uint8_t *out);
 
 #if defined(CONFIG_CMD_ZYNQ_RSA)
-int zynq_pow_mod(u32 *keyptr, u32 *inout);
+int zynq_pow_mod(uint32_t *keyptr, uint32_t *inout);
 #endif
 
 /**
index b07e3e0..7b71343 100644 (file)
 
 #ifdef CONFIG_ARCH_ZYNQMP
 void zynqmp_dll_reset(u8 deviceid);
-void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank);
+void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay, u32 otap_delay);
 #else
 inline void zynqmp_dll_reset(u8 deviceid) {}
-inline void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank) {}
+inline void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay,
+                                      u32 otap_delay) {}
 #endif
 
 #endif
index 78c688d..74f9eb1 100644 (file)
@@ -321,7 +321,7 @@ int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
  *        pow_mod calculation required for zynq is bit different from
  *        pw_mod above here, hence defined zynq specific routine.
  */
-int zynq_pow_mod(u32 *keyptr, u32 *inout)
+int zynq_pow_mod(uint32_t *keyptr, uint32_t *inout)
 {
        u32 *result, *ptr;
        uint i;
index 01ac3c2..fb1ceb1 100644 (file)
@@ -207,6 +207,28 @@ static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_ofnode_read_chosen, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 
+static int dm_test_ofnode_read_aliases(struct unit_test_state *uts)
+{
+       const void *val;
+       ofnode node;
+       int size;
+
+       node = ofnode_get_aliases_node("eth3");
+       ut_assert(ofnode_valid(node));
+       ut_asserteq_str("sbe5", ofnode_get_name(node));
+
+       node = ofnode_get_aliases_node("unknown");
+       ut_assert(!ofnode_valid(node));
+
+       val = ofnode_read_aliases_prop("spi0", &size);
+       ut_assertnonnull(val);
+       ut_asserteq(7, size);
+       ut_asserteq_str("/spi@0", (const char *)val);
+
+       return 0;
+}
+DM_TEST(dm_test_ofnode_read_aliases, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
 static int dm_test_ofnode_get_child_count(struct unit_test_state *uts)
 {
        ofnode node, child_node;