]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
Merge tag 'v2015.01' into master
authorMichal Simek <michal.simek@xilinx.com>
Tue, 13 Jan 2015 09:19:59 +0000 (10:19 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 21 Jan 2015 08:43:36 +0000 (09:43 +0100)
Add AFX/CSE board support - Kconfig entry, defconfigs
Add RSA Kconfig entry and targets for it
Add zc770-xm011 and zynq-cc108 DTBs from the Linux kernel
Sync zynq-7000.dtsi with the Linux kernel.
Use spl_load_image_fat for bitstream loading in SPL.
Disable CONFIG_OF_CONTROL for all zynq boards.

Nand:
- Fix zynq_nand_read_subpage_raw parameters.
- Remove nand.h from sys_proto.h and move it zynq_nand.c
- Do not call nand_release(). Removed by:
  "mtd, ubi, ubifs: resync with Linux-3.14"
  (sha1: ff94bc40af3481d47546595ba73c136de6af6929)

QSPI:
- spi_flash_params has been moved from spi_flash.h
  to sf_internal.h - fix zynq_qspi.c driver to reflect this.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
64 files changed:
1  2 
Makefile
README
arch/arm/cpu/armv7/zynq/Kconfig
arch/arm/cpu/armv7/zynq/cpu.c
arch/arm/cpu/armv7/zynq/ddrc.c
arch/arm/cpu/armv7/zynq/spl.c
arch/arm/dts/Makefile
arch/arm/dts/zynq-7000.dtsi
arch/arm/dts/zynq-cc108.dts
arch/arm/dts/zynq-zc770-xm011.dts
arch/arm/lib/bootm-fdt.c
arch/arm/lib/bootm.c
common/Kconfig
common/Makefile
common/main.c
common/spl/spl_mmc.c
configs/zynq_afx_nand_RSA_defconfig
configs/zynq_afx_nand_defconfig
configs/zynq_afx_nor_RSA_defconfig
configs/zynq_afx_nor_defconfig
configs/zynq_afx_qspi_RSA_defconfig
configs/zynq_afx_qspi_defconfig
configs/zynq_cc108_defconfig
configs/zynq_cse_nand_defconfig
configs/zynq_cse_nor_defconfig
configs/zynq_cse_qspi_defconfig
configs/zynq_microzed_defconfig
configs/zynq_zc70x_RSA_defconfig
configs/zynq_zc70x_defconfig
configs/zynq_zc770_xm010_RSA_defconfig
configs/zynq_zc770_xm010_defconfig
configs/zynq_zc770_xm011_RSA_defconfig
configs/zynq_zc770_xm011_defconfig
configs/zynq_zc770_xm012_RSA_defconfig
configs/zynq_zc770_xm012_defconfig
configs/zynq_zc770_xm013_RSA_defconfig
configs/zynq_zc770_xm013_defconfig
configs/zynq_zed_RSA_defconfig
configs/zynq_zed_defconfig
configs/zynq_zybo_defconfig
drivers/fpga/zynqpl.c
drivers/mtd/cfi_flash.c
drivers/mtd/nand/Makefile
drivers/mtd/nand/zynq_nand.c
drivers/mtd/spi/sf_ops.c
drivers/mtd/spi/sf_probe.c
drivers/net/Makefile
drivers/spi/Makefile
drivers/spi/zynq_qspi.c
drivers/usb/gadget/ci_udc.c
drivers/usb/gadget/f_thor.c
fs/fat/fat.c
include/configs/microblaze-generic.h
include/configs/zynq-common.h
include/configs/zynq_cse.h
include/configs/zynq_zc70x.h
include/configs/zynq_zc770.h
include/configs/zynq_zed.h
include/netdev.h
include/spi.h
include/spi_flash.h
include/u-boot/rsa.h
lib/rsa/rsa-verify.c
scripts/Makefile.spl

diff --cc Makefile
index 12ea1a526028ebb39a1cec8274d659146ed8aea1,36a9a283b051527df532d16c5f4dd69c9be3556c..3d1cad8fb4dd70d9381edcdc88818eff98e6a412
mode 100755,100644..100755
+++ b/Makefile
@@@ -738,12 -743,11 +743,17 @@@ endi
  endif
  endif
  
 +ifneq ($(CONFIG_ZYNQ),)
 +ifeq ($(CONFIG_SPL),y)
 +ALL-y += boot.bin
 +endif
 +endif
 +
+ # Add optional build target if defined in board/cpu/soc headers
+ ifneq ($(CONFIG_BUILD_TARGET),)
+ ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
+ endif
  LDFLAGS_u-boot += $(LDFLAGS_FINAL)
  ifneq ($(CONFIG_SYS_TEXT_BASE),)
  LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
diff --cc README
Simple merge
index 0000000000000000000000000000000000000000,3a52535ce0010d3ef7855e56a1d302fa2d5880ca..2482bbb068c9019f3fbf4bebd3e02245ddfcdabe
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,39 +1,47 @@@
+ if ZYNQ
+ choice
+       prompt "Xilinx Zynq board select"
+ config TARGET_ZYNQ_ZED
+       bool "Zynq ZedBoard"
+ config TARGET_ZYNQ_MICROZED
+       bool "Zynq MicroZed"
+ config TARGET_ZYNQ_ZC70X
+       bool "Zynq ZC702/ZC706 Board"
+ config TARGET_ZYNQ_ZC770
+       bool "Zynq ZC770 Board"
+ config TARGET_ZYNQ_ZYBO
+       bool "Zynq Zybo Board"
++config TARGET_ZYNQ_AFX
++      bool "Zynq AFX Board"
++
++config TARGET_ZYNQ_CSE
++      bool "Zynq CSE Board"
++
+ endchoice
+ config SYS_BOARD
+       default "zynq"
+ config SYS_VENDOR
+       default "xilinx"
+ config SYS_SOC
+       default "zynq"
+ config SYS_CONFIG_NAME
+       default "zynq_zed" if TARGET_ZYNQ_ZED
+       default "zynq_microzed" if TARGET_ZYNQ_MICROZED
+       default "zynq_zc70x" if TARGET_ZYNQ_ZC70X
+       default "zynq_zc770" if TARGET_ZYNQ_ZC770
+       default "zynq_zybo" if TARGET_ZYNQ_ZYBO
++      default "zynq_cse" if TARGET_ZYNQ_CSE
++      default "zynq_afx" if TARGET_ZYNQ_AFX
+ endif
Simple merge
index 90ce4ff31867ab80f99f8f7a75df15a0acf1974c,d74f8dbbc45dfb9f6440ea38fa44552404f436ef..5b20accbcb172d7e0e40dc7c92933f5123e1485a
@@@ -40,9 -40,8 +40,10 @@@ void zynq_ddrc_init(void
                 * first stage bootloader. To get ECC to work all memory has
                 * been initialized by writing any value.
                 */
+               /* cppcheck-suppress nullPointer */
                memset((void *)0, 0, 1 * 1024 * 1024);
 +
 +              gd->ram_size /= 2;
        } else {
                puts("ECC disabled ");
        }
Simple merge
index 6e2e313829c161613b1a9c26a8ea82e813d50ad8,fac16cc384d37d578ee58085121d619c431a85a1..5b4900455a504920e424a97f474bf8969b54c416
@@@ -28,8 -42,9 +42,11 @@@ dtb-$(CONFIG_ARCH_UNIPHIER) += 
  dtb-$(CONFIG_ZYNQ) += zynq-zc702.dtb \
        zynq-zc706.dtb \
        zynq-zed.dtb \
+       zynq-zybo.dtb \
        zynq-microzed.dtb \
++      zynq-cc108.dtb \
        zynq-zc770-xm010.dtb \
++      zynq-zc770-xm011.dtb \
        zynq-zc770-xm012.dtb \
        zynq-zc770-xm013.dtb
  dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb
index 2d076f194e06035946f528a639a62a45fa3a648f,2d076f194e06035946f528a639a62a45fa3a648f..3c3ae7a709482f34995d072151fa19f9920badf3
@@@ -1,10 -1,10 +1,7 @@@
  /*
-- * Xilinx Zynq 7000 DTSI
-- * Describes the hardware common to all Zynq 7000-based boards.
++ * Copyright (C) 2011 - 2015 Xilinx, Inc.
   *
-- * Copyright (C) 2013 Xilinx, Inc.
-- *
-- * SPDX-License-Identifier:   GPL-2.0+
++ * SPDX-License-Identifier:    GPL-2.0+
   */
  /include/ "skeleton.dtsi"
  
                        reg = <0>;
                        clocks = <&clkc 3>;
                        clock-latency = <1000>;
++                      cpu0-supply = <&regulator_vccpint>;
                        operating-points = <
                                /* kHz    uV */
                                666667  1000000
                                333334  1000000
--                              222223  1000000
                        >;
                };
  
                reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
        };
  
--      amba {
++      regulator_vccpint: fixedregulator@0 {
++              compatible = "regulator-fixed";
++              regulator-name = "VCCPINT";
++              regulator-min-microvolt = <1000000>;
++              regulator-max-microvolt = <1000000>;
++              regulator-boot-on;
++              regulator-always-on;
++      };
++
++      amba: amba {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
                interrupt-parent = <&intc>;
                ranges;
  
--              i2c0: zynq-i2c@e0004000 {
++              adc: adc@f8007100 {
++                      compatible = "xlnx,zynq-xadc-1.00.a";
++                      reg = <0xf8007100 0x20>;
++                      interrupts = <0 7 4>;
++                      interrupt-parent = <&intc>;
++                      clocks = <&clkc 12>;
++              };
++
++              can0: can@e0008000 {
++                      compatible = "xlnx,zynq-can-1.0";
++                      status = "disabled";
++                      clocks = <&clkc 19>, <&clkc 36>;
++                      clock-names = "can_clk", "pclk";
++                      reg = <0xe0008000 0x1000>;
++                      interrupts = <0 28 4>;
++                      interrupt-parent = <&intc>;
++                      tx-fifo-depth = <0x40>;
++                      rx-fifo-depth = <0x40>;
++              };
++
++              can1: can@e0009000 {
++                      compatible = "xlnx,zynq-can-1.0";
++                      status = "disabled";
++                      clocks = <&clkc 20>, <&clkc 37>;
++                      clock-names = "can_clk", "pclk";
++                      reg = <0xe0009000 0x1000>;
++                      interrupts = <0 51 4>;
++                      interrupt-parent = <&intc>;
++                      tx-fifo-depth = <0x40>;
++                      rx-fifo-depth = <0x40>;
++              };
++
++              gpio0: gpio@e000a000 {
++                      compatible = "xlnx,zynq-gpio-1.0";
++                      #gpio-cells = <2>;
++                      clocks = <&clkc 42>;
++                      gpio-controller;
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 20 4>;
++                      reg = <0xe000a000 0x1000>;
++              };
++
++              i2c0: i2c@e0004000 {
                        compatible = "cdns,i2c-r1p10";
                        status = "disabled";
                        clocks = <&clkc 38>;
                        #size-cells = <0>;
                };
  
--              i2c1: zynq-i2c@e0005000 {
++              i2c1: i2c@e0005000 {
                        compatible = "cdns,i2c-r1p10";
                        status = "disabled";
                        clocks = <&clkc 39>;
                intc: interrupt-controller@f8f01000 {
                        compatible = "arm,cortex-a9-gic";
                        #interrupt-cells = <3>;
--                      #address-cells = <1>;
                        interrupt-controller;
                        reg = <0xF8F01000 0x1000>,
                              <0xF8F00100 0x100>;
                };
  
--              L2: cache-controller {
++              L2: cache-controller@f8f02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0xF8F02000 0x1000>;
                        arm,data-latency = <3 2 2>;
                        cache-level = <2>;
                };
  
--              uart0: uart@e0000000 {
--                      compatible = "xlnx,xuartps";
++              mc0: memory-controller@f8006000 {
++                      compatible = "xlnx,zynq-ddrc-a05";
++                      reg = <0xf8006000 0x1000>;
++                      xlnx,has-ecc = <0x0>;
++              };
++
++              ocmc: ocmc@f800c000 {
++                      compatible = "xlnx,zynq-ocmc-1.0";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 3 4>;
++                      reg = <0xf800c000 0x1000>;
++              };
++
++              uart0: serial@e0000000 {
++                      compatible = "xlnx,xuartps", "cdns,uart-r1p8";
                        status = "disabled";
                        clocks = <&clkc 23>, <&clkc 40>;
--                      clock-names = "ref_clk", "aper_clk";
++                      clock-names = "uart_clk", "pclk";
                        reg = <0xE0000000 0x1000>;
                        interrupts = <0 27 4>;
                };
  
--              uart1: uart@e0001000 {
--                      compatible = "xlnx,xuartps";
++              uart1: serial@e0001000 {
++                      compatible = "xlnx,xuartps", "cdns,uart-r1p8";
                        status = "disabled";
                        clocks = <&clkc 24>, <&clkc 41>;
--                      clock-names = "ref_clk", "aper_clk";
++                      clock-names = "uart_clk", "pclk";
                        reg = <0xE0001000 0x1000>;
                        interrupts = <0 50 4>;
                };
  
++              spi0: spi@e0006000 {
++                      compatible = "xlnx,zynq-spi-r1p6";
++                      reg = <0xe0006000 0x1000>;
++                      status = "disabled";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 26 4>;
++                      clocks = <&clkc 25>, <&clkc 34>;
++                      clock-names = "ref_clk", "pclk";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              spi1: spi@e0007000 {
++                      compatible = "xlnx,zynq-spi-r1p6";
++                      reg = <0xe0007000 0x1000>;
++                      status = "disabled";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 49 4>;
++                      clocks = <&clkc 26>, <&clkc 35>;
++                      clock-names = "ref_clk", "pclk";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              qspi: spi@e000d000 {
++                      clock-names = "ref_clk", "pclk";
++                      clocks = <&clkc 10>, <&clkc 43>;
++                      compatible = "xlnx,zynq-qspi-1.0";
++                      status = "disabled";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 19 4>;
++                      reg = <0xe000d000 0x1000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              smcc: memory-controller@e000e000 {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++                      status = "disabled";
++                      clock-names = "memclk", "aclk";
++                      clocks = <&clkc 11>, <&clkc 44>;
++                      compatible = "arm,pl353-smc-r2p1";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 18 4>;
++                      ranges ;
++                      reg = <0xe000e000 0x1000>;
++                      nand0: flash@e1000000 {
++                              status = "disabled";
++                              compatible = "arm,pl353-nand-r2p1";
++                              reg = <0xe1000000 0x1000000>;
++                              #address-cells = <0x1>;
++                              #size-cells = <0x1>;
++                      };
++                      nor0: flash@e2000000 {
++                              status = "disabled";
++                              compatible = "cfi-flash";
++                              reg = <0xe2000000 0x1000>;
++                              #address-cells = <1>;
++                              #size-cells = <1>;
++                      };
++              };
++
                gem0: ethernet@e000b000 {
--                      compatible = "cdns,gem";
--                      reg = <0xe000b000 0x4000>;
++                      compatible = "xlnx,ps7-ethernet-1.00.a";
++                      reg = <0xe000b000 0x1000>;
                        status = "disabled";
                        interrupts = <0 22 4>;
--                      clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
--                      clock-names = "pclk", "hclk", "tx_clk";
++                      clocks = <&clkc 13>, <&clkc 30>;
++                      clock-names = "ref_clk", "aper_clk";
++                      local-mac-address = [00 0a 35 00 00 00];
++                      xlnx,has-mdio = <0x1>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
                };
  
                gem1: ethernet@e000c000 {
--                      compatible = "cdns,gem";
--                      reg = <0xe000c000 0x4000>;
++                      compatible = "xlnx,ps7-ethernet-1.00.a";
++                      reg = <0xe000c000 0x1000>;
                        status = "disabled";
                        interrupts = <0 45 4>;
--                      clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>;
--                      clock-names = "pclk", "hclk", "tx_clk";
++                      clocks = <&clkc 14>, <&clkc 31>;
++                      clock-names = "ref_clk", "aper_clk";
++                      local-mac-address = [00 0a 35 00 00 00];
++                      xlnx,has-mdio = <0x1>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
                };
  
--              sdhci0: ps7-sdhci@e0100000 {
++              sdhci0: sdhci@e0100000 {
                        compatible = "arasan,sdhci-8.9a";
                        status = "disabled";
                        clock-names = "clk_xin", "clk_ahb";
                        interrupt-parent = <&intc>;
                        interrupts = <0 24 4>;
                        reg = <0xe0100000 0x1000>;
--              } ;
++              };
  
--              sdhci1: ps7-sdhci@e0101000 {
++              sdhci1: sdhci@e0101000 {
                        compatible = "arasan,sdhci-8.9a";
                        status = "disabled";
                        clock-names = "clk_xin", "clk_ahb";
                        interrupt-parent = <&intc>;
                        interrupts = <0 47 4>;
                        reg = <0xe0101000 0x1000>;
--              } ;
++              };
  
                slcr: slcr@f8000000 {
                        #address-cells = <1>;
                                #clock-cells = <1>;
                                compatible = "xlnx,ps7-clkc";
                                ps-clk-frequency = <33333333>;
--                              fclk-enable = <0>;
++                              fclk-enable = <0xf>;
                                clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
                                                "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
                                                "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
                        };
                };
  
++              dmac_s: dmac@f8003000 {
++                      compatible = "arm,pl330", "arm,primecell";
++                      reg = <0xf8003000 0x1000>;
++                      interrupt-parent = <&intc>;
++                      interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
++                              "dma4", "dma5", "dma6", "dma7";
++                      interrupts = <0 13 4>,
++                                   <0 14 4>, <0 15 4>,
++                                   <0 16 4>, <0 17 4>,
++                                   <0 40 4>, <0 41 4>,
++                                   <0 42 4>, <0 43 4>;
++                      #dma-cells = <1>;
++                      #dma-channels = <8>;
++                      #dma-requests = <4>;
++                      clocks = <&clkc 27>;
++                      clock-names = "apb_pclk";
++              };
++
++              devcfg: devcfg@f8007000 {
++                      clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
++                      clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
++                      compatible = "xlnx,zynq-devcfg-1.0";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 8 4>;
++                      reg = <0xf8007000 0x100>;
++              };
++
                global_timer: timer@f8f00200 {
                        compatible = "arm,cortex-a9-global-timer";
                        reg = <0xf8f00200 0x20>;
                        clocks = <&clkc 4>;
                };
  
--              ttc0: ttc0@f8001000 {
++              ttc0: timer@f8001000 {
                        interrupt-parent = <&intc>;
--                      interrupts = < 0 10 4 0 11 4 0 12 4 >;
++                      interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
                        compatible = "cdns,ttc";
                        clocks = <&clkc 6>;
                        reg = <0xF8001000 0x1000>;
                };
  
--              ttc1: ttc1@f8002000 {
++              ttc1: timer@f8002000 {
                        interrupt-parent = <&intc>;
--                      interrupts = < 0 37 4 0 38 4 0 39 4 >;
++                      interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
                        compatible = "cdns,ttc";
                        clocks = <&clkc 6>;
                        reg = <0xF8002000 0x1000>;
                };
--              scutimer: scutimer@f8f00600 {
++
++              scutimer: timer@f8f00600 {
                        interrupt-parent = <&intc>;
--                      interrupts = < 1 13 0x301 >;
++                      interrupts = <1 13 0x301>;
                        compatible = "arm,cortex-a9-twd-timer";
--                      reg = < 0xf8f00600 0x20 >;
++                      reg = <0xf8f00600 0x20>;
                        clocks = <&clkc 4>;
--              } ;
++              };
++
++              watchdog0: watchdog@f8005000 {
++                      clocks = <&clkc 45>;
++                      compatible = "xlnx,zynq-wdt-r1p2";
++                      device_type = "watchdog";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 9 1>;
++                      reg = <0xf8005000 0x1000>;
++                      reset = <0>;
++                      timeout-sec = <10>;
++              };
++
++              usb0: usb@e0002000 {
++                      clocks = <&clkc 28>;
++                      compatible = "xlnx,ps7-usb-1.00.a", "xlnx,zynq-usb-1.00.a";
++                      status = "disabled";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 21 4>;
++                      reg = <0xe0002000 0x1000>;
++              };
++
++              usb1: usb@e0003000 {
++                      clocks = <&clkc 29>;
++                      compatible = "xlnx,ps7-usb-1.00.a", "xlnx,zynq-usb-1.00.a";
++                      status = "disabled";
++                      interrupt-parent = <&intc>;
++                      interrupts = <0 44 4>;
++                      reg = <0xe0003000 0x1000>;
++              };
        };
  };
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..eb5da525c61e5db3739b103ee3152defa9ebc1eb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,109 @@@
++/*
++ * Device Tree Generator version: 1.1
++ *
++ * (C) Copyright 2007-2013 Xilinx, Inc.
++ * (C) Copyright 2007-2013 Michal Simek
++ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
++ *
++ * Michal SIMEK <monstr@monstr.eu>
++ *
++ * CAUTION: This file is automatically generated by libgen.
++ * Version: Xilinx EDK 14.7 EDK_P.20131013
++ *
++ */
++/dts-v1/;
++/include/ "zynq-7000.dtsi"
++
++/ {
++      compatible = "xlnx,zynq-cc108", "xlnx,zynq-7000";
++      model = "Xilinx Zynq";
++
++      aliases {
++              ethernet0 = &gem0;
++              serial0 = &uart1;
++              spi0 = &qspi;
++      };
++
++      chosen {
++              bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
++              linux,stdout-path = "/amba/serial@e0001000";
++      };
++
++      memory@0 {
++              device_type = "memory";
++              reg = <0x0 0x20000000>;
++      };
++};
++
++&qspi {
++      status = "okay";
++      is-dual = <0>;
++      num-cs = <1>;
++      flash@0 { /* 16 MB */
++              compatible = "n25q128a11";
++              reg = <0x0>;
++              spi-max-frequency = <50000000>;
++              spi-tx-bus-width = <1>;
++              spi-rx-bus-width = <4>;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              partition@0 {
++                      label = "qspi-fsbl-uboot-bs";
++                      reg = <0x0 0x400000>; /* 4MB */
++              };
++              partition@0x400000 {
++                      label = "qspi-linux";
++                      reg = <0x400000 0x400000>; /* 4MB */
++              };
++              partition@0x800000 {
++                      label = "qspi-rootfs";
++                      reg = <0x800000 0x400000>; /* 4MB */
++              };
++              partition@0xc00000 {
++                      label = "qspi-devicetree";
++                      reg = <0xc00000 0x100000>; /* 1MB */
++              };
++              partition@0xd00000 {
++                      label = "qspi-scratch";
++                      reg = <0xd00000 0x200000>; /* 2MB */
++              };
++              partition@0xf00000 {
++                      label = "qspi-uboot-env";
++                      reg = <0xf00000 0x100000>; /* 1MB */
++              };
++      };
++};
++
++&usb0 {
++      status = "okay";
++      dr_mode = "peripheral";
++      phy_type = "ulpi";
++      usb-reset = <&gpio0 9 0>;
++};
++
++&usb1 {
++      status = "okay";
++      dr_mode = "host";
++      phy_type = "ulpi";
++};
++
++
++&gem0 {
++      status = "okay";
++      phy-mode = "rgmii-id";
++      phy-handle = <&phy0>;
++
++      phy0: phy@1 {
++              reg = <1>;
++      };
++};
++
++&sdhci1 {
++      status = "okay";
++      broken-cd ;
++      wp-inverted ;
++};
++
++&uart1 {
++      status = "okay";
++};
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0f1a5fc64521cedfcf040594de2754ae188ed57a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,108 @@@
++/*
++ * Device Tree Generator version: 1.1
++ *
++ * (C) Copyright 2007-2013 Xilinx, Inc.
++ * (C) Copyright 2007-2013 Michal Simek
++ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
++ *
++ * Michal SIMEK <monstr@monstr.eu>
++ *
++ * CAUTION: This file is automatically generated by libgen.
++ * Version: Xilinx EDK 14.5 EDK_P.58f
++ *
++ */
++/dts-v1/;
++/include/ "zynq-7000.dtsi"
++
++/ {
++      compatible = "xlnx,zynq-zc770-xm011", "xlnx,zynq-7000";
++      model = "Xilinx Zynq";
++
++      aliases {
++              i2c0 = &i2c1;
++              serial0 = &uart1;
++              spi0 = &spi0;
++      };
++
++      chosen {
++              bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
++              linux,stdout-path = "/amba/serial@e0001000";
++      };
++
++      memory@0 {
++              device_type = "memory";
++              reg = <0x0 0x40000000>;
++      };
++};
++
++&smcc {
++      status = "okay";
++      arm,addr25 = <0x0>;
++      arm,nor-chip-sel0 = <0x0>;
++      arm,nor-chip-sel1 = <0x0>;
++      arm,sram-chip-sel0 = <0x0>;
++      arm,sram-chip-sel1 = <0x0>;
++};
++
++&nand0 {
++      status = "okay";
++      arm,nand-cycle-t0 = <0x4>;
++      arm,nand-cycle-t1 = <0x4>;
++      arm,nand-cycle-t2 = <0x1>;
++      arm,nand-cycle-t3 = <0x2>;
++      arm,nand-cycle-t4 = <0x2>;
++      arm,nand-cycle-t5 = <0x2>;
++      arm,nand-cycle-t6 = <0x4>;
++
++      partition@nand-fsbl-uboot {
++              label = "nand-fsbl-uboot";
++              reg = <0x0 0x100000>;
++      };
++      partition@nand-linux {
++              label = "nand-linux";
++              reg = <0x100000 0x500000>;
++      };
++      partition@nand-device-tree {
++              label = "nand-device-tree";
++              reg = <0x600000 0x20000>;
++      };
++      partition@nand-rootfs {
++              label = "nand-rootfs";
++              reg = <0x620000 0x5E0000>;
++      };
++      partition@nand-bitstream {
++              label = "nand-bitstream";
++              reg = <0xC00000 0x400000>;
++      };
++};
++
++&spi0 {
++      status = "okay";
++      num-cs = <4>;
++      is-decoded-cs = <0>;
++};
++
++&usb1 {
++      status = "okay";
++      dr_mode = "host";
++      phy_type = "ulpi";
++};
++
++
++&can0 {
++      status = "okay";
++};
++
++&i2c1 {
++      status = "okay";
++      clock-frequency = <400000>;
++
++      m24c02_eeprom@52 {
++              compatible = "at,24c02";
++              reg = <0x52>;
++      };
++};
++
++&uart1 {
++      status = "okay";
++};
index 9f9ebb070946ce8ae0415271e3cda91dbe441ff2,d4f1578e9e96fcdbd1434b5c5e663339844ada83..3a2c440abbdef0752cd02f790fb635e96aa6ef0b
  
  DECLARE_GLOBAL_DATA_PTR;
  
- int arch_fixup_memory_node(void *blob)
+ int arch_fixup_fdt(void *blob)
  {
 -      bd_t *bd = gd->bd;
 -      int bank, ret;
 -      u64 start[CONFIG_NR_DRAM_BANKS];
 -      u64 size[CONFIG_NR_DRAM_BANKS];
 -
 -      for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
 -              start[bank] = bd->bi_dram[bank].start;
 -              size[bank] = bd->bi_dram[bank].size;
 -      }
 -
 -      ret = fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
 -#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
 -      if (ret)
 -              return ret;
 -
 -      ret = armv7_update_dt(blob);
 -#endif
 -      return ret;
 +      return 0;
  }
index 8c33345e02b27ff516104d9fbd18772901aa18cb,0c1298a31e733c3e528f7d49a70088f27deece86..9fc0cb7a5e12765ce3c048a2945a855665ae5191
@@@ -238,10 -231,32 +231,29 @@@ static void boot_prep_linux(bootm_heade
                }
                setup_board_tags(&params);
                setup_end_tag(gd->bd);
 -      } else {
 -              printf("FDT and ATAGS support not compiled in - hanging\n");
 -              hang();
        }
-       do_nonsec_virt_switch();
  }
  
+ #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
+ bool armv7_boot_nonsec(void)
+ {
+       char *s = getenv("bootm_boot_mode");
+ #ifdef CONFIG_ARMV7_BOOT_SEC_DEFAULT
+       bool nonsec = false;
+ #else
+       bool nonsec = true;
+ #endif
+       if (s && !strcmp(s, "sec"))
+               nonsec = false;
+       if (s && !strcmp(s, "nonsec"))
+               nonsec = true;
+       return nonsec;
+ }
+ #endif
  /* Subcommand: GO */
  static void boot_jump_linux(bootm_headers_t *images, int flag)
  {
diff --cc common/Kconfig
index 0000000000000000000000000000000000000000,fd84fa08bd3efc2569ac4200684f26abca5ac205..5f99e18bcb2f4acd5e59a31aa7046a7613b46bf2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,316 +1,321 @@@
+ menu "Command line interface"
+       depends on !SPL_BUILD
+ config HUSH_PARSER
+       bool "Use hush shell"
+       select SYS_HUSH_PARSER
+       help
+         This option enables the "hush" shell (from Busybox) as command line
+         interpreter, thus enabling powerful command line syntax like
+         if...then...else...fi conditionals or `&&' and '||'
+         constructs ("shell scripts").
+         If disabled, you get the old, much simpler behaviour with a somewhat
+         smaller memory footprint.
+ config SYS_HUSH_PARSER
+       bool
+       help
+         Backward compatibility.
+ comment "Commands"
+ menu "Info commands"
+ config CMD_BDI
+       bool "bdinfo"
+       help
+         Print board info
+ config CMD_CONSOLE
+       bool "coninfo"
+       help
+         Print console devices and information.
+ config CMD_LICENSE
+       bool "license"
+       help
+         Print GPL license text
+ endmenu
+ menu "Boot commands"
+ config CMD_BOOTD
+       bool "bootd"
+       help
+         Run the command stored in the environment "bootcmd", i.e.
+         "bootd" does the same thing as "run bootcmd".
+ config CMD_BOOTM
+       bool "bootm"
+       default y
+       help
+         Boot an application image from the memory.
+ config CMD_GO
+       bool "go"
+       default y
+       help
+         Start an application at a given address.
+ config CMD_RUN
+       bool "run"
+       help
+         Run the command in the given environment variable.
+ config CMD_IMI
+       bool "iminfo"
+       help
+         Print header information for application image.
+ config CMD_IMLS
+       bool "imls"
+       help
+         List all images found in flash
+ config CMD_XIMG
+       bool "imxtract"
+       help
+         Extract a part of a multi-image.
+ endmenu
+ menu "Environment commands"
+ config CMD_EXPORTENV
+       bool "env export"
+       default y
+       help
+         Export environments.
+ config CMD_IMPORTENV
+       bool "env import"
+       default y
+       help
+         Import environments.
+ config CMD_EDITENV
+       bool "editenv"
+       help
+         Edit environment variable.
+ config CMD_SAVEENV
+       bool "saveenv"
+       help
+         Run the command in the given environment variable.
+ endmenu
+ menu "Memory commands"
+ config CMD_MEMORY
+       bool "md, mm, nm, mw, cp, cmp, base, loop"
+       help
+         Memeory commands.
+           md - memory display
+           mm - memory modify (auto-incrementing address)
+           nm - memory modify (constant address)
+           mw - memory write (fill)
+           cp - memory copy
+           cmp - memory compare
+           base - print or set address offset
+           loop - initinite loop on address range
+ config CMD_CRC32
+       bool "crc32"
+       default y
+       help
+         Compute CRC32.
+ config LOOPW
+       bool "loopw"
+       help
+         Infinite write loop on address range
+ config CMD_MEMTEST
+       bool "crc32"
+       help
+         Simple RAM read/write test.
+ config CMD_MX_CYCLIC
+       bool "mdc, mwc"
+       help
+         mdc - memory display cyclic
+         mwc - memory write cyclic
+ config CMD_MEMINFO
+       bool "meminfo"
+       help
+         Display memory information.
+ endmenu
+ menu "Device access commands"
+ config CMD_LOADB
+       bool "loadb"
+       help
+         Load a binary file over serial line.
+ config CMD_LOADS
+       bool "loads"
+       help
+         Load an S-Record file over serial line
+ config CMD_FLASH
+       bool "flinfo, erase, protect"
+       help
+         NOR flash support.
+           flinfo - print FLASH memory information
+           erase - FLASH memory
+           protect - enable or disable FLASH write protection
+ config CMD_NAND
+       bool "nand"
+       help
+         NAND support.
+ config CMD_SPI
+       bool "sspi"
+       help
+         SPI utility command.
+ config CMD_I2C
+       bool "i2c"
+       help
+         I2C support.
+ config CMD_USB
+       bool "usb"
+       help
+         USB support.
+ config CMD_FPGA
+       bool "fpga"
+       help
+         FPGA support.
+ endmenu
+ menu "Shell scripting commands"
+ config CMD_ECHO
+       bool "echo"
+       help
+         Echo args to console
+ config CMD_ITEST
+       bool "itest"
+       help
+         Return true/false on integer compare.
+ config CMD_SOURCE
+       bool "source"
+       help
+         Run script from memory
+ endmenu
+ menu "Network commands"
+ config CMD_NET
+       bool "bootp, tftpboot"
+       help
+         Network commands.
+         bootp - boot image via network using BOOTP/TFTP protocol
+         tftpboot - boot image via network using TFTP protocol
+ config CMD_TFTPPUT
+       bool "tftp put"
+       help
+         TFTP put command, for uploading files to a server
+ config CMD_TFTPSRV
+       bool "tftpsrv"
+       help
+         Act as a TFTP server and boot the first received file
+ config CMD_RARP
+       bool "rarpboot"
+       help
+         Boot image via network using RARP/TFTP protocol
+ config CMD_DHCP
+       bool "dhcp"
+       help
+         Boot image via network using DHCP/TFTP protocol
+ config CMD_NFS
+       bool "nfs"
+       help
+         Boot image via network using NFS protocol.
+ config CMD_PING
+       bool "ping"
+       help
+         Send ICMP ECHO_REQUEST to network host
+ config CMD_CDP
+       bool "cdp"
+       help
+         Perform CDP network configuration
+ config CMD_SNTP
+       bool "sntp"
+       help
+         Synchronize RTC via network
+ config CMD_DNS
+       bool "dns"
+       help
+         Lookup the IP of a hostname
+ config CMD_DNS
+       bool "dns"
+       help
+         Lookup the IP of a hostname
+ config CMD_LINK_LOCAL
+       bool "linklocal"
+       help
+         Acquire a network IP address using the link-local protocol
+ endmenu
+ menu "Misc commands"
+ config CMD_TIME
+       bool "time"
+       help
+         Run commands and summarize execution time.
+ # TODO: rename to CMD_SLEEP
+ config CMD_MISC
+       bool "sleep"
+       help
+         Delay execution for some time
+ config CMD_TIMER
+       bool "timer"
+       help
+         Access the system timer.
+ config CMD_SETGETDCR
+       bool "getdcr, setdcr, getidcr, setidcr"
+       depends on 4xx
+       help
+         getdcr - Get an AMCC PPC 4xx DCR's value
+         setdcr - Set an AMCC PPC 4xx DCR's value
+         getidcr - Get a register value via indirect DCR addressing
+         setidcr - Set a register value via indirect DCR addressing
++config CMD_ZYNQ_RSA
++      bool "Zynq RSA"
++      help
++        Verifies the authenticated and encrypted zynq images.
++
+ endmenu
+ endmenu
diff --cc common/Makefile
Simple merge
diff --cc common/main.c
Simple merge
index f86ba680c2a1663002b646c2f02a4cb1b3b151af,c2e596be69bc4310790de1160ddaef40f8c02759..0dc94f755ae710d81dbf351f045b6cde2f1d7ecc
@@@ -71,35 -85,6 +88,35 @@@ static int mmc_load_image_raw_os(struc
  }
  #endif
  
-       /* FIXME = standard file size + header desc_xilinx->size + 0x6c */
-       err = file_fat_read(CONFIG_SPL_FPGA_LOAD_ARGS_NAME,
-                           (void *)CONFIG_SPL_FPGA_LOAD_ADDR,
-                           0);
-       if (err <= 0) {
 +#ifdef CONFIG_SPL_FPGA_SUPPORT
 +static int mmc_load_fpga_image_fat(struct mmc *mmc)
 +{
 +      int err;
 +      int devnum = 0;
 +      const fpga_desc *const desc = fpga_get_desc(devnum);
 +      xilinx_desc *desc_xilinx = desc->devdesc;
 +
-       return fpga_loadbitstream(devnum, (char *)CONFIG_SPL_FPGA_LOAD_ADDR,
++      err = spl_load_image_fat(&mmc->block_dev,
++                                      CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
++                                      CONFIG_SPL_FPGA_LOAD_ARGS_NAME);
++
++      if (err) {
 +#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 +              printf("spl: error reading image %s, err - %d\n",
 +                     CONFIG_SPL_FPGA_LOAD_ARGS_NAME, err);
 +#endif
 +              return -1;
 +      }
 +#ifdef CONFIG_SPL_FPGA_BIT
-       return fpga_load(devnum, (const void *)CONFIG_SPL_FPGA_LOAD_ADDR,
++      return fpga_loadbitstream(devnum, (char *)spl_image.load_addr,
 +                                desc_xilinx->size, BIT_FULL);
 +#else
++      return fpga_load(devnum, (const void *)spl_image.load_addr,
 +                       desc_xilinx->size, BIT_FULL);
 +#endif
 +}
 +#endif
 +
  void spl_mmc_load_image(void)
  {
        struct mmc *mmc;
  #ifdef CONFIG_SPL_OS_BOOT
                if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
  #endif
-               err = mmc_load_image_raw(mmc,
+ #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
+               err = mmc_load_image_raw_partition(mmc,
+                       CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
+ #else
+               err = mmc_load_image_raw_sector(mmc,
                        CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+ #endif
+ #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
+       }
+       if (err || boot_mode == MMCSD_MODE_FS) {
+               debug("boot mode - FS\n");
  #ifdef CONFIG_SPL_FAT_SUPPORT
-       } else if (boot_mode == MMCSD_MODE_FAT) {
-               debug("boot mode - FAT\n");
 +
 +#ifdef CONFIG_SPL_FPGA_SUPPORT
 +              mmc_load_fpga_image_fat(mmc);
 +#endif
 +
  #ifdef CONFIG_SPL_OS_BOOT
                if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev,
-                                                               CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION))
+                                                               CONFIG_SYS_MMCSD_FS_BOOT_PARTITION))
  #endif
                err = spl_load_image_fat(&mmc->block_dev,
-                                       CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION,
-                                       CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
+                                       CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
+                                       CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+               if(err)
+ #endif /* CONFIG_SPL_FAT_SUPPORT */
+               {
+ #ifdef CONFIG_SPL_EXT_SUPPORT
+ #ifdef CONFIG_SPL_OS_BOOT
+               if (spl_start_uboot() || spl_load_image_ext_os(&mmc->block_dev,
+                                                               CONFIG_SYS_MMCSD_FS_BOOT_PARTITION))
  #endif
+               err = spl_load_image_ext(&mmc->block_dev,
+                                       CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
+                                       CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+ #endif /* CONFIG_SPL_EXT_SUPPORT */
+               }
+ #endif /* defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) */
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
        } else if (boot_mode == MMCSD_MODE_EMMCBOOT) {
                /*
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..632a2734d80cad66856dd0fb4dba6a0998690221
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="AFX_NAND"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_AFX=y
++CONFIG_OF_CONTROL=n
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8880484efb2c3b3dee6ac032cfbdf7e4f90fccd7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="AFX_NAND"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_AFX=y
++CONFIG_OF_CONTROL=n
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..281cbecb365155372b023105efecc5276878331f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="AFX_NOR"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_AFX=y
++CONFIG_OF_CONTROL=n
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e16e3d2819e2a0e01d4fd86f01fa3986c86a6f40
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="AFX_NOR"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_AFX=y
++CONFIG_OF_CONTROL=n
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..adf07de766ef9079f6002ce0c821c3d4aa0580d0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="AFX_QSPI"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_AFX=y
++CONFIG_OF_CONTROL=n
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..12c3a76f15dc9cdec867fbaac45fa688e8326d52
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="AFX_QSPI"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_AFX=y
++CONFIG_OF_CONTROL=n
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bf4e23e021cc4b2585493ee93e57c623ce7ac037
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++CONFIG_SPL=y
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_CC108=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-cc108"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0379cd931f836c24edc991b43ad29e94e0ef6898
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="CSE_NAND"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_CSE=y
++CONFIG_CMD_BOOTM=n
++CONFIG_CMD_GO=n
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4aeffcaf6423603c90884ea6a49c9916f7117d9c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="CSE_NOR"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_CSE=y
++CONFIG_CMD_BOOTM=n
++CONFIG_CMD_GO=n
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6b3e23c6e2a59bb74617257bcd1217287802154f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="CSE_QSPI"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_CSE=y
++CONFIG_CMD_BOOTM=n
++CONFIG_CMD_GO=n
index 0000000000000000000000000000000000000000,9588849bb5c0f7c78694fc90a52fb46daed1286f..f9ae4a2fa22dc5e703b2a8ee7c796428d3bda3fc
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,6 +1,6 @@@
 -CONFIG_OF_CONTROL=y
+ CONFIG_SPL=y
+ +S:CONFIG_ARM=y
+ +S:CONFIG_ZYNQ=y
+ +S:CONFIG_TARGET_ZYNQ_MICROZED=y
++CONFIG_OF_CONTROL=n
+ CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..630a7d5dde23deb1672c8254fe38bd6cac52840e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=y
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_ZC70X=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,cf507308e95d209540ad5442df87abdb01632549..9902ea4dc9045fe45258c19213dd92ee65f88e27
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,6 +1,6 @@@
 -CONFIG_OF_CONTROL=y
+ CONFIG_SPL=y
+ +S:CONFIG_ARM=y
+ +S:CONFIG_ZYNQ=y
+ +S:CONFIG_TARGET_ZYNQ_ZC70X=y
++CONFIG_OF_CONTROL=n
+ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..011ab4d6c2e3d5d0b2be321f036316d7a0b6719d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_ZC770=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,8bb405d1808907756610f7ebd8ade97227615ec9..0c66fc3375cd14fac78d4d86bc48ecb7973372ad
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,7 +1,7 @@@
 -CONFIG_SPL=y
++CONFIG_SPL=n
+ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
+ +S:CONFIG_ARM=y
+ +S:CONFIG_ZYNQ=y
+ +S:CONFIG_TARGET_ZYNQ_ZC770=y
 -CONFIG_OF_CONTROL=y
++CONFIG_OF_CONTROL=n
+ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f1292be3c8a7125a79f319e4caba95300c5a862b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM011"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_ZC770=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm011"
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..744288095a511dbdb5ca4d333a3ec38679c3e378
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM011"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_ZC770=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm011"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f1a8cb77e4249c95490eead6f2d80a79c83d714e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_ZC770=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,0ba5da589e95db553b682393db5348fdcdf00ceb..a2c5b3a26c1c902a47b765e7f474bb88746bb12c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,7 +1,7 @@@
 -CONFIG_SPL=y
++CONFIG_SPL=n
+ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012"
+ +S:CONFIG_ARM=y
+ +S:CONFIG_ZYNQ=y
+ +S:CONFIG_TARGET_ZYNQ_ZC770=y
 -CONFIG_OF_CONTROL=y
++CONFIG_OF_CONTROL=n
+ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..01a67d573082da1761f7eb37c93c94ee559b2dc0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++CONFIG_SPL=n
++CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_ZC770=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,13f8112a1b627139c8fc980370759c8cd0d0f36a..0fb5f74e1669fc72f76828ff7d48d3776c34dbed
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,7 +1,7 @@@
 -CONFIG_SPL=y
++CONFIG_SPL=n
+ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
+ +S:CONFIG_ARM=y
+ +S:CONFIG_ZYNQ=y
+ +S:CONFIG_TARGET_ZYNQ_ZC770=y
 -CONFIG_OF_CONTROL=y
++CONFIG_OF_CONTROL=n
+ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..feca419707f38d0cc084dd464a042a698c45040e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++CONFIG_SPL=y
+++S:CONFIG_ARM=y
+++S:CONFIG_ZYNQ=y
+++S:CONFIG_TARGET_ZYNQ_ZED=y
++CONFIG_OF_CONTROL=n
++CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
++CONFIG_CMD_ZYNQ_RSA=y
index 0000000000000000000000000000000000000000,eb057fae35c738332163e8693997c8667376124a..8ff24843594983979f15eedd9bcbea52d1696022
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,6 +1,6 @@@
 -CONFIG_OF_CONTROL=y
+ CONFIG_SPL=y
+ +S:CONFIG_ARM=y
+ +S:CONFIG_ZYNQ=y
+ +S:CONFIG_TARGET_ZYNQ_ZED=y
++CONFIG_OF_CONTROL=n
+ CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
index 0000000000000000000000000000000000000000,12311cd83b5011f35ff2b69737ad24c7b1fb9f9f..9ccfc52d54053afd1092b4c00ceb00c4ea135eeb
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,6 +1,6 @@@
 -CONFIG_OF_CONTROL=y
+ CONFIG_SPL=y
+ +S:CONFIG_ARM=y
+ +S:CONFIG_ZYNQ=y
+ +S:CONFIG_TARGET_ZYNQ_ZYBO=y
++CONFIG_OF_CONTROL=n
+ CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
Simple merge
Simple merge
Simple merge
index 75ead1f3c43cbbf0f87c595ebffda75b320b6323,0000000000000000000000000000000000000000..5caea3d7c1e7f3822ad2f7ddb6039424072a5a6b
mode 100644,000000..100644
--- /dev/null
@@@ -1,1252 -1,0 +1,1252 @@@
-                                   struct nand_chip *chip, u32 data_offs,
-                                   u32 readlen, u8 *buf)
 +/*
 + * Xilinx Zynq NAND Flash Controller Driver
 + * This driver is based on plat_nand.c and mxc_nand.c drivers
 + *
 + * Copyright (C) 2009 - 2013 Xilinx, Inc.
 + *
 + * SPDX-License-Identifier:   GPL-2.0+
 + */
 +
 +#include <common.h>
 +#include <malloc.h>
 +#include <asm/io.h>
 +#include <asm/errno.h>
++#include <nand.h>
 +#include <linux/mtd/mtd.h>
 +#include <linux/mtd/nand.h>
 +#include <linux/mtd/partitions.h>
 +#include <linux/mtd/nand_ecc.h>
 +#include <asm/arch/hardware.h>
 +#include <asm/arch/sys_proto.h>
 +
 +/* The NAND flash driver defines */
 +#define ZYNQ_NAND_CMD_PHASE   1       /* End command valid in command phase */
 +#define ZYNQ_NAND_DATA_PHASE  2       /* End command valid in data phase */
 +#define ZYNQ_NAND_ECC_SIZE    512     /* Size of data for ECC operation */
 +
 +/* Flash memory controller operating parameters */
 +#define ZYNQ_NAND_CLR_CONFIG  ((0x1 << 1)  |  /* Disable interrupt */ \
 +                              (0x1 << 4)   |  /* Clear interrupt */ \
 +                              (0x1 << 6))     /* Disable ECC interrupt */
 +
 +/* Assuming 50MHz clock (20ns cycle time) and 3V operation */
 +#define ZYNQ_NAND_SET_CYCLES  ((0x2 << 20) |  /* t_rr from nand_cycles */ \
 +                              (0x2 << 17)  |  /* t_ar from nand_cycles */ \
 +                              (0x1 << 14)  |  /* t_clr from nand_cycles */ \
 +                              (0x3 << 11)  |  /* t_wp from nand_cycles */ \
 +                              (0x2 << 8)   |  /* t_rea from nand_cycles */ \
 +                              (0x5 << 4)   |  /* t_wc from nand_cycles */ \
 +                              (0x5 << 0))     /* t_rc from nand_cycles */
 +
 +#define ZYNQ_NAND_SET_OPMODE  0x0
 +
 +#define ZYNQ_NAND_DIRECT_CMD  ((0x4 << 23) |  /* Chip 0 from interface 1 */ \
 +                              (0x2 << 21))    /* UpdateRegs operation */
 +
 +#define ZYNQ_NAND_ECC_CONFIG  ((0x1 << 2)  |  /* ECC available on APB */ \
 +                              (0x1 << 4)   |  /* ECC read at end of page */ \
 +                              (0x0 << 5))     /* No Jumping */
 +
 +#define ZYNQ_NAND_ECC_CMD1    ((0x80)      |  /* Write command */ \
 +                              (0x00 << 8)  |  /* Read command */ \
 +                              (0x30 << 16) |  /* Read End command */ \
 +                              (0x1 << 24))    /* Read End command calid */
 +
 +#define ZYNQ_NAND_ECC_CMD2    ((0x85)      |  /* Write col change cmd */ \
 +                              (0x05 << 8)  |  /* Read col change cmd */ \
 +                              (0xE0 << 16) |  /* Read col change end cmd */ \
 +                              (0x1 << 24))    /* Read col change
 +                                                      end cmd valid */
 +/* AXI Address definitions */
 +#define START_CMD_SHIFT               3
 +#define END_CMD_SHIFT         11
 +#define END_CMD_VALID_SHIFT   20
 +#define ADDR_CYCLES_SHIFT     21
 +#define CLEAR_CS_SHIFT                21
 +#define ECC_LAST_SHIFT                10
 +#define COMMAND_PHASE         (0 << 19)
 +#define DATA_PHASE            (1 << 19)
 +
 +#define ZYNQ_NAND_ECC_LAST    (1 << ECC_LAST_SHIFT)   /* Set ECC_Last */
 +#define ZYNQ_NAND_CLEAR_CS    (1 << CLEAR_CS_SHIFT)   /* Clear chip select */
 +
 +/* ECC block registers bit position and bit mask */
 +#define ZYNQ_NAND_ECC_BUSY    (1 << 6)        /* ECC block is busy */
 +#define ZYNQ_NAND_ECC_MASK    0x00FFFFFF      /* ECC value mask */
 +
 +/* NAND MIO buswidth count*/
 +#define ZYNQ_NAND_MIO_NUM_NAND_8BIT   13
 +#define ZYNQ_NAND_MIO_NUM_NAND_16BIT  8
 +
 +/* NAND buswidth */
 +enum zynq_nand_bus_width {
 +      NAND_BW_UNKNOWN = -1,
 +      NAND_BW_8BIT,
 +      NAND_BW_16BIT,
 +};
 +
 +/* SMC register set */
 +struct zynq_nand_smc_regs {
 +      u32 csr;                /* 0x00 */
 +      u32 reserved0[2];
 +      u32 cfr;                /* 0x0C */
 +      u32 dcr;                /* 0x10 */
 +      u32 scr;                /* 0x14 */
 +      u32 sor;                /* 0x18 */
 +      u32 reserved1[249];
 +      u32 esr;                /* 0x400 */
 +      u32 emcr;               /* 0x404 */
 +      u32 emcmd1r;    /* 0x408 */
 +      u32 emcmd2r;    /* 0x40C */
 +      u32 reserved2[2];
 +      u32 eval0r;             /* 0x418 */
 +};
 +
 +#define zynq_nand_smc_base    ((struct zynq_nand_smc_regs *)ZYNQ_SMC_BASEADDR)
 +
 +/*
 + * struct zynq_nand_command_format - Defines NAND flash command format
 + * @start_cmd:                First cycle command (Start command)
 + * @end_cmd:          Second cycle command (Last command)
 + * @addr_cycles:      Number of address cycles required to send the address
 + * @end_cmd_valid:    The second cycle command is valid for cmd or data phase
 + */
 +struct zynq_nand_command_format {
 +      int start_cmd;
 +      int end_cmd;
 +      u8 addr_cycles;
 +      u8 end_cmd_valid;
 +};
 +
 +/*
 + * struct zynq_nand_info - Defines the NAND flash driver instance
 + * @parts:            Pointer to the mtd_partition structure
 + * @nand_base:                Virtual address of the NAND flash device
 + * @end_cmd_pending:  End command is pending
 + * @end_cmd:          End command
 + */
 +struct zynq_nand_info {
 +#ifdef CONFIG_MTD_PARTITIONS
 +      struct mtd_partition    *parts;
 +#endif
 +      void __iomem            *nand_base;
 +      unsigned long           end_cmd_pending;
 +      unsigned long           end_cmd;
 +};
 +
 +#define ONDIE_ECC_FEATURE_ADDR        0x90
 +
 +/*  The NAND flash operations command format */
 +static const struct zynq_nand_command_format zynq_nand_commands[] = {
 +      {NAND_CMD_READ0, NAND_CMD_READSTART, 5, ZYNQ_NAND_CMD_PHASE},
 +      {NAND_CMD_RNDOUT, NAND_CMD_RNDOUTSTART, 2, ZYNQ_NAND_CMD_PHASE},
 +      {NAND_CMD_READID, NAND_CMD_NONE, 1, NAND_CMD_NONE},
 +      {NAND_CMD_STATUS, NAND_CMD_NONE, 0, NAND_CMD_NONE},
 +      {NAND_CMD_SEQIN, NAND_CMD_PAGEPROG, 5, ZYNQ_NAND_DATA_PHASE},
 +      {NAND_CMD_RNDIN, NAND_CMD_NONE, 2, NAND_CMD_NONE},
 +      {NAND_CMD_ERASE1, NAND_CMD_ERASE2, 3, ZYNQ_NAND_CMD_PHASE},
 +      {NAND_CMD_RESET, NAND_CMD_NONE, 0, NAND_CMD_NONE},
 +      {NAND_CMD_PARAM, NAND_CMD_NONE, 1, NAND_CMD_NONE},
 +      {NAND_CMD_GET_FEATURES, NAND_CMD_NONE, 1, NAND_CMD_NONE},
 +      {NAND_CMD_SET_FEATURES, NAND_CMD_NONE, 1, NAND_CMD_NONE},
 +      {NAND_CMD_NONE, NAND_CMD_NONE, 0, 0},
 +      /* Add all the flash commands supported by the flash device and Linux
 +       * The cache program command is not supported by driver because driver
 +       * cant differentiate between page program and cached page program from
 +       * start command, these commands can be differentiated through end
 +       * command, which doesn't fit in to the driver design. The cache program
 +       * command is not supported by NAND subsystem also, look at 1612 line
 +       * number (in nand_write_page function) of nand_base.c file.
 +       * {NAND_CMD_SEQIN, NAND_CMD_CACHEDPROG, 5, ZYNQ_NAND_YES}
 +       */
 +};
 +
 +/* Define default oob placement schemes for large and small page devices */
 +static struct nand_ecclayout nand_oob_16 = {
 +      .eccbytes = 3,
 +      .eccpos = {13, 14, 15},
 +      .oobfree = {
 +              { .offset = 0, .length = 12 }
 +      }
 +};
 +
 +static struct nand_ecclayout nand_oob_64 = {
 +      .eccbytes = 12,
 +      .eccpos = {
 +                 52, 53, 54, 55, 56, 57,
 +                 58, 59, 60, 61, 62, 63},
 +      .oobfree = {
 +              { .offset = 2, .length = 50 }
 +      }
 +};
 +
 +static struct nand_ecclayout ondie_nand_oob_64 = {
 +      .eccbytes = 32,
 +
 +      .eccpos = {
 +              8, 9, 10, 11, 12, 13, 14, 15,
 +              24, 25, 26, 27, 28, 29, 30, 31,
 +              40, 41, 42, 43, 44, 45, 46, 47,
 +              56, 57, 58, 59, 60, 61, 62, 63
 +      },
 +
 +      .oobfree = {
 +              { .offset = 4, .length = 4 },
 +              { .offset = 20, .length = 4 },
 +              { .offset = 36, .length = 4 },
 +              { .offset = 52, .length = 4 }
 +      }
 +};
 +
 +/* Generic flash bbt decriptors */
 +static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
 +static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
 +
 +static struct nand_bbt_descr bbt_main_descr = {
 +      .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
 +              NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
 +      .offs = 4,
 +      .len = 4,
 +      .veroffs = 20,
 +      .maxblocks = 4,
 +      .pattern = bbt_pattern
 +};
 +
 +static struct nand_bbt_descr bbt_mirror_descr = {
 +      .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
 +              NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
 +      .offs = 4,
 +      .len = 4,
 +      .veroffs = 20,
 +      .maxblocks = 4,
 +      .pattern = mirror_pattern
 +};
 +
 +/*
 + * zynq_nand_waitfor_ecc_completion - Wait for ECC completion
 + *
 + * returns: status for command completion, -1 for Timeout
 + */
 +static int zynq_nand_waitfor_ecc_completion(void)
 +{
 +      unsigned long timeout;
 +      u32 status;
 +
 +      /* Wait max 10ms */
 +      timeout = 10;
 +      status = readl(&zynq_nand_smc_base->esr);
 +      while (status & ZYNQ_NAND_ECC_BUSY) {
 +              status = readl(&zynq_nand_smc_base->esr);
 +              if (timeout == 0)
 +                      return -1;
 +              timeout--;
 +              udelay(1);
 +      }
 +
 +      return status;
 +}
 +
 +/*
 + * zynq_nand_init_nand_flash - Initialize NAND controller
 + * @option:   Device property flags
 + *
 + * This function initializes the NAND flash interface on the NAND controller.
 + *
 + * returns:   0 on success or error value on failure
 + */
 +static int zynq_nand_init_nand_flash(int option)
 +{
 +      u32 status;
 +
 +      /* disable interrupts */
 +      writel(ZYNQ_NAND_CLR_CONFIG, &zynq_nand_smc_base->cfr);
 +      /* Initialize the NAND interface by setting cycles and operation mode */
 +      writel(ZYNQ_NAND_SET_CYCLES, &zynq_nand_smc_base->scr);
 +      if (option & NAND_BUSWIDTH_16)
 +              writel((ZYNQ_NAND_SET_OPMODE | 0x1), &zynq_nand_smc_base->sor);
 +      else
 +              writel(ZYNQ_NAND_SET_OPMODE, &zynq_nand_smc_base->sor);
 +
 +      writel(ZYNQ_NAND_DIRECT_CMD, &zynq_nand_smc_base->dcr);
 +
 +      /* Wait till the ECC operation is complete */
 +      status = zynq_nand_waitfor_ecc_completion();
 +      if (status < 0) {
 +              printf("%s: Timeout\n", __func__);
 +              return status;
 +      }
 +
 +      /* Set the command1 and command2 register */
 +      writel(ZYNQ_NAND_ECC_CMD1, &zynq_nand_smc_base->emcmd1r);
 +      writel(ZYNQ_NAND_ECC_CMD2, &zynq_nand_smc_base->emcmd2r);
 +
 +      return 0;
 +}
 +
 +/*
 + * zynq_nand_calculate_hwecc - Calculate Hardware ECC
 + * @mtd:      Pointer to the mtd_info structure
 + * @data:     Pointer to the page data
 + * @ecc_code: Pointer to the ECC buffer where ECC data needs to be stored
 + *
 + * This function retrieves the Hardware ECC data from the controller and returns
 + * ECC data back to the MTD subsystem.
 + *
 + * returns:   0 on success or error value on failure
 + */
 +static int zynq_nand_calculate_hwecc(struct mtd_info *mtd, const u8 *data,
 +              u8 *ecc_code)
 +{
 +      u32 ecc_value = 0;
 +      u8 ecc_reg, ecc_byte;
 +      u32 ecc_status;
 +
 +      /* Wait till the ECC operation is complete */
 +      ecc_status = zynq_nand_waitfor_ecc_completion();
 +      if (ecc_status < 0) {
 +              printf("%s: Timeout\n", __func__);
 +              return ecc_status;
 +      }
 +
 +      for (ecc_reg = 0; ecc_reg < 4; ecc_reg++) {
 +              /* Read ECC value for each block */
 +              ecc_value = readl(&zynq_nand_smc_base->eval0r + ecc_reg);
 +              ecc_status = (ecc_value >> 24) & 0xFF;
 +              /* ECC value valid */
 +              if (ecc_status & 0x40) {
 +                      for (ecc_byte = 0; ecc_byte < 3; ecc_byte++) {
 +                              /* Copy ECC bytes to MTD buffer */
 +                              *ecc_code = ecc_value & 0xFF;
 +                              ecc_value = ecc_value >> 8;
 +                              ecc_code++;
 +                      }
 +              } else {
 +                      debug("%s: ecc status failed\n", __func__);
 +              }
 +      }
 +      return 0;
 +}
 +
 +/*
 + * onehot - onehot function
 + * @value:    value to check for onehot
 + *
 + * This function checks whether a value is onehot or not.
 + * onehot is if and only if onebit is set.
 + *
 + */
 +static int onehot(unsigned short value)
 +{
 +      return ((value & (value-1)) == 0);
 +}
 +
 +/*
 + * zynq_nand_correct_data - ECC correction function
 + * @mtd:      Pointer to the mtd_info structure
 + * @buf:      Pointer to the page data
 + * @read_ecc: Pointer to the ECC value read from spare data area
 + * @calc_ecc: Pointer to the calculated ECC value
 + *
 + * This function corrects the ECC single bit errors & detects 2-bit errors.
 + *
 + * returns:   0 if no ECC errors found
 + *            1 if single bit error found and corrected.
 + *            -1 if multiple ECC errors found.
 + */
 +static int zynq_nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
 +                      unsigned char *read_ecc, unsigned char *calc_ecc)
 +{
 +      unsigned char bit_addr;
 +      unsigned int byte_addr;
 +      unsigned short ecc_odd, ecc_even;
 +      unsigned short read_ecc_lower, read_ecc_upper;
 +      unsigned short calc_ecc_lower, calc_ecc_upper;
 +
 +      read_ecc_lower = (read_ecc[0] | (read_ecc[1] << 8)) & 0xfff;
 +      read_ecc_upper = ((read_ecc[1] >> 4) | (read_ecc[2] << 4)) & 0xfff;
 +
 +      calc_ecc_lower = (calc_ecc[0] | (calc_ecc[1] << 8)) & 0xfff;
 +      calc_ecc_upper = ((calc_ecc[1] >> 4) | (calc_ecc[2] << 4)) & 0xfff;
 +
 +      ecc_odd = read_ecc_lower ^ calc_ecc_lower;
 +      ecc_even = read_ecc_upper ^ calc_ecc_upper;
 +
 +      if ((ecc_odd == 0) && (ecc_even == 0))
 +              return 0;       /* no error */
 +      else if (ecc_odd == (~ecc_even & 0xfff)) {
 +              /* bits [11:3] of error code is byte offset */
 +              byte_addr = (ecc_odd >> 3) & 0x1ff;
 +              /* bits [2:0] of error code is bit offset */
 +              bit_addr = ecc_odd & 0x7;
 +              /* Toggling error bit */
 +              buf[byte_addr] ^= (1 << bit_addr);
 +              return 1;
 +      } else if (onehot(ecc_odd | ecc_even) == 1) {
 +              return 1; /* one error in parity */
 +      } else {
 +              return -1; /* Uncorrectable error */
 +      }
 +}
 +
 +/*
 + * zynq_nand_read_oob - [REPLACABLE] the most common OOB data read function
 + * @mtd:      mtd info structure
 + * @chip:     nand chip info structure
 + * @page:     page number to read
 + * @sndcmd:   flag whether to issue read command or not
 + */
 +static int zynq_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 +                      int page)
 +{
 +      unsigned long data_width = 4;
 +      unsigned long data_phase_addr = 0;
 +      u8 *p;
 +
 +      chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
 +
 +      p = chip->oob_poi;
 +      chip->read_buf(mtd, p, (mtd->oobsize - data_width));
 +      p += (mtd->oobsize - data_width);
 +
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_R;
 +      data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
 +      chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
 +      chip->read_buf(mtd, p, data_width);
 +
 +      return 0;
 +}
 +
 +/*
 + * zynq_nand_write_oob - [REPLACABLE] the most common OOB data write function
 + * @mtd:      mtd info structure
 + * @chip:     nand chip info structure
 + * @page:     page number to write
 + */
 +static int zynq_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 +                           int page)
 +{
 +      int status = 0;
 +      const u8 *buf = chip->oob_poi;
 +      unsigned long data_width = 4;
 +      unsigned long data_phase_addr = 0;
 +
 +      chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
 +
 +      chip->write_buf(mtd, buf, (mtd->oobsize - data_width));
 +      buf += (mtd->oobsize - data_width);
 +
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_W;
 +      data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
 +      data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
 +      chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
 +      chip->write_buf(mtd, buf, data_width);
 +
 +      /* Send command to program the OOB data */
 +      chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 +      status = chip->waitfunc(mtd, chip);
 +
 +      return status & NAND_STATUS_FAIL ? -EIO : 0;
 +}
 +
 +/*
 + * zynq_nand_read_page_raw - [Intern] read raw page data without ecc
 + * @mtd:        mtd info structure
 + * @chip:       nand chip info structure
 + * @buf:        buffer to store read data
 + * @oob_required: must write chip->oob_poi to OOB
 + * @page:       page number to read
 + */
 +static int zynq_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 +                                 u8 *buf,  int oob_required, int page)
 +{
 +      unsigned long data_width = 4;
 +      unsigned long data_phase_addr = 0;
 +      u8 *p;
 +
 +      chip->read_buf(mtd, buf, mtd->writesize);
 +
 +      p = chip->oob_poi;
 +      chip->read_buf(mtd, p, (mtd->oobsize - data_width));
 +      p += (mtd->oobsize - data_width);
 +
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_R;
 +      data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
 +      chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
 +
 +      chip->read_buf(mtd, p, data_width);
 +      return 0;
 +}
 +
 +static int zynq_nand_read_page_raw_nooob(struct mtd_info *mtd,
 +              struct nand_chip *chip, u8 *buf, int oob_required, int page)
 +{
 +      chip->read_buf(mtd, buf, mtd->writesize);
 +      return 0;
 +}
 +
 +static int zynq_nand_read_subpage_raw(struct mtd_info *mtd,
-       if (data_offs != 0) {
-               chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_offs, -1);
-               buf += data_offs;
++                                  struct nand_chip *chip, uint32_t offs,
++                                  uint32_t len, uint8_t *buf, int page)
 +{
-       chip->read_buf(mtd, buf, readlen);
++      if (offs != 0) {
++              chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offs, -1);
++              buf += offs;
 +      }
 +
-       nand_release(mtd);
++      chip->read_buf(mtd, buf, len);
 +      return 0;
 +}
 +
 +/*
 + * zynq_nand_write_page_raw - [Intern] raw page write function
 + * @mtd:        mtd info structure
 + * @chip:       nand chip info structure
 + * @buf:        data buffer
 + * @oob_required: must write chip->oob_poi to OOB
 + */
 +static int zynq_nand_write_page_raw(struct mtd_info *mtd,
 +      struct nand_chip *chip, const u8 *buf, int oob_required)
 +{
 +      unsigned long data_width = 4;
 +      unsigned long data_phase_addr = 0;
 +      u8 *p;
 +
 +      chip->write_buf(mtd, buf, mtd->writesize);
 +
 +      p = chip->oob_poi;
 +      chip->write_buf(mtd, p, (mtd->oobsize - data_width));
 +      p += (mtd->oobsize - data_width);
 +
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_W;
 +      data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
 +      data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
 +      chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
 +
 +      chip->write_buf(mtd, p, data_width);
 +
 +      return 0;
 +}
 +
 +/*
 + * nand_write_page_hwecc - Hardware ECC based page write function
 + * @mtd:      Pointer to the mtd info structure
 + * @chip:     Pointer to the NAND chip info structure
 + * @buf:      Pointer to the data buffer
 + * @oob_required: must write chip->oob_poi to OOB
 + *
 + * This functions writes data and hardware generated ECC values in to the page.
 + */
 +static int zynq_nand_write_page_hwecc(struct mtd_info *mtd,
 +      struct nand_chip *chip, const u8 *buf, int oob_required)
 +{
 +      int i, eccsize = chip->ecc.size;
 +      int eccsteps = chip->ecc.steps;
 +      u8 *ecc_calc = chip->buffers->ecccalc;
 +      const u8 *p = buf;
 +      u32 *eccpos = chip->ecc.layout->eccpos;
 +      unsigned long data_phase_addr = 0;
 +      unsigned long data_width = 4;
 +      u8 *oob_ptr;
 +
 +      for (; (eccsteps - 1); eccsteps--) {
 +              chip->write_buf(mtd, p, eccsize);
 +              p += eccsize;
 +      }
 +      chip->write_buf(mtd, p, (eccsize - data_width));
 +      p += (eccsize - data_width);
 +
 +      /* Set ECC Last bit to 1 */
 +      data_phase_addr = (unsigned long) chip->IO_ADDR_W;
 +      data_phase_addr |= ZYNQ_NAND_ECC_LAST;
 +      chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
 +      chip->write_buf(mtd, p, data_width);
 +
 +      /* Wait for ECC to be calculated and read the error values */
 +      p = buf;
 +      chip->ecc.calculate(mtd, p, &ecc_calc[0]);
 +
 +      for (i = 0; i < chip->ecc.total; i++)
 +              chip->oob_poi[eccpos[i]] = ~(ecc_calc[i]);
 +
 +      /* Clear ECC last bit */
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_W;
 +      data_phase_addr &= ~ZYNQ_NAND_ECC_LAST;
 +      chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
 +
 +      /* Write the spare area with ECC bytes */
 +      oob_ptr = chip->oob_poi;
 +      chip->write_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
 +
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_W;
 +      data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
 +      data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
 +      chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
 +      oob_ptr += (mtd->oobsize - data_width);
 +      chip->write_buf(mtd, oob_ptr, data_width);
 +
 +      return 0;
 +}
 +
 +/*
 + * zynq_nand_write_page_swecc - [REPLACABLE] software ecc based page
 + * write function
 + * @mtd:      mtd info structure
 + * @chip:     nand chip info structure
 + * @buf:      data buffer
 + * @oob_required: must write chip->oob_poi to OOB
 + */
 +static int zynq_nand_write_page_swecc(struct mtd_info *mtd,
 +      struct nand_chip *chip, const u8 *buf, int oob_required)
 +{
 +      int i, eccsize = chip->ecc.size;
 +      int eccbytes = chip->ecc.bytes;
 +      int eccsteps = chip->ecc.steps;
 +      u8 *ecc_calc = chip->buffers->ecccalc;
 +      const u8 *p = buf;
 +      u32 *eccpos = chip->ecc.layout->eccpos;
 +
 +      /* Software ecc calculation */
 +      for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 +              chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 +
 +      for (i = 0; i < chip->ecc.total; i++)
 +              chip->oob_poi[eccpos[i]] = ecc_calc[i];
 +
 +      return chip->ecc.write_page_raw(mtd, chip, buf, 1);
 +}
 +
 +/*
 + * nand_read_page_hwecc - Hardware ECC based page read function
 + * @mtd:      Pointer to the mtd info structure
 + * @chip:     Pointer to the NAND chip info structure
 + * @buf:      Pointer to the buffer to store read data
 + * @oob_required: must write chip->oob_poi to OOB
 + * @page:     page number to read
 + *
 + * This functions reads data and checks the data integrity by comparing hardware
 + * generated ECC values and read ECC values from spare area.
 + *
 + * returns:   0 always and updates ECC operation status in to MTD structure
 + */
 +static int zynq_nand_read_page_hwecc(struct mtd_info *mtd,
 +      struct nand_chip *chip, u8 *buf, int oob_required, int page)
 +{
 +      int i, stat, eccsize = chip->ecc.size;
 +      int eccbytes = chip->ecc.bytes;
 +      int eccsteps = chip->ecc.steps;
 +      u8 *p = buf;
 +      u8 *ecc_calc = chip->buffers->ecccalc;
 +      u8 *ecc_code = chip->buffers->ecccode;
 +      u32 *eccpos = chip->ecc.layout->eccpos;
 +      unsigned long data_phase_addr = 0;
 +      unsigned long data_width = 4;
 +      u8 *oob_ptr;
 +
 +      for (; (eccsteps - 1); eccsteps--) {
 +              chip->read_buf(mtd, p, eccsize);
 +              p += eccsize;
 +      }
 +      chip->read_buf(mtd, p, (eccsize - data_width));
 +      p += (eccsize - data_width);
 +
 +      /* Set ECC Last bit to 1 */
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_R;
 +      data_phase_addr |= ZYNQ_NAND_ECC_LAST;
 +      chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
 +      chip->read_buf(mtd, p, data_width);
 +
 +      /* Read the calculated ECC value */
 +      p = buf;
 +      chip->ecc.calculate(mtd, p, &ecc_calc[0]);
 +
 +      /* Clear ECC last bit */
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_R;
 +      data_phase_addr &= ~ZYNQ_NAND_ECC_LAST;
 +      chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
 +
 +      /* Read the stored ECC value */
 +      oob_ptr = chip->oob_poi;
 +      chip->read_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
 +
 +      /* de-assert chip select */
 +      data_phase_addr = (unsigned long)chip->IO_ADDR_R;
 +      data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
 +      chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
 +
 +      oob_ptr += (mtd->oobsize - data_width);
 +      chip->read_buf(mtd, oob_ptr, data_width);
 +
 +      for (i = 0; i < chip->ecc.total; i++)
 +              ecc_code[i] = ~(chip->oob_poi[eccpos[i]]);
 +
 +      eccsteps = chip->ecc.steps;
 +      p = buf;
 +
 +      /* Check ECC error for all blocks and correct if it is correctable */
 +      for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 +              stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
 +              if (stat < 0)
 +                      mtd->ecc_stats.failed++;
 +              else
 +                      mtd->ecc_stats.corrected += stat;
 +      }
 +      return 0;
 +}
 +
 +/*
 + * zynq_nand_read_page_swecc - [REPLACABLE] software ecc based page
 + * read function
 + * @mtd:      mtd info structure
 + * @chip:     nand chip info structure
 + * @buf:      buffer to store read data
 + * @page:     page number to read
 + */
 +static int zynq_nand_read_page_swecc(struct mtd_info *mtd,
 +      struct nand_chip *chip, u8 *buf, int oob_required,  int page)
 +{
 +      int i, eccsize = chip->ecc.size;
 +      int eccbytes = chip->ecc.bytes;
 +      int eccsteps = chip->ecc.steps;
 +      u8 *p = buf;
 +      u8 *ecc_calc = chip->buffers->ecccalc;
 +      u8 *ecc_code = chip->buffers->ecccode;
 +      u32 *eccpos = chip->ecc.layout->eccpos;
 +
 +      chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
 +
 +      for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 +              chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 +
 +      for (i = 0; i < chip->ecc.total; i++)
 +              ecc_code[i] = chip->oob_poi[eccpos[i]];
 +
 +      eccsteps = chip->ecc.steps;
 +      p = buf;
 +
 +      for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 +              int stat;
 +
 +              stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
 +              if (stat < 0)
 +                      mtd->ecc_stats.failed++;
 +              else
 +                      mtd->ecc_stats.corrected += stat;
 +      }
 +      return 0;
 +}
 +
 +/*
 + * zynq_nand_select_chip - Select the flash device
 + * @mtd:      Pointer to the mtd_info structure
 + * @chip:     Chip number to be selected
 + *
 + * This function is empty as the NAND controller handles chip select line
 + * internally based on the chip address passed in command and data phase.
 + */
 +static void zynq_nand_select_chip(struct mtd_info *mtd, int chip)
 +{
 +      return;
 +}
 +
 +/*
 + * zynq_nand_cmd_function - Send command to NAND device
 + * @mtd:      Pointer to the mtd_info structure
 + * @command:  The command to be sent to the flash device
 + * @column:   The column address for this command, -1 if none
 + * @page_addr:        The page address for this command, -1 if none
 + */
 +static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
 +                               int column, int page_addr)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      const struct zynq_nand_command_format *curr_cmd = NULL;
 +      struct zynq_nand_info *xnand;
 +      void *cmd_addr;
 +      unsigned long cmd_data = 0;
 +      unsigned long cmd_phase_addr = 0;
 +      unsigned long data_phase_addr = 0;
 +      unsigned long end_cmd = 0;
 +      unsigned long end_cmd_valid = 0;
 +      unsigned long i;
 +
 +      xnand = (struct zynq_nand_info *)chip->priv;
 +      if (xnand->end_cmd_pending) {
 +              /* Check for end command if this command request is same as the
 +               * pending command then return
 +               */
 +              if (xnand->end_cmd == command) {
 +                      xnand->end_cmd = 0;
 +                      xnand->end_cmd_pending = 0;
 +                      return;
 +              }
 +      }
 +
 +      /* Emulate NAND_CMD_READOOB for large page device */
 +      if ((mtd->writesize > ZYNQ_NAND_ECC_SIZE) &&
 +          (command == NAND_CMD_READOOB)) {
 +              column += mtd->writesize;
 +              command = NAND_CMD_READ0;
 +      }
 +
 +      /* Get the command format */
 +      for (i = 0; (zynq_nand_commands[i].start_cmd != NAND_CMD_NONE ||
 +              zynq_nand_commands[i].end_cmd != NAND_CMD_NONE); i++) {
 +              if (command == zynq_nand_commands[i].start_cmd)
 +                      curr_cmd = &zynq_nand_commands[i];
 +      }
 +      if (curr_cmd == NULL)
 +              return;
 +
 +      /* Clear interrupt */
 +      writel((1 << 4), &zynq_nand_smc_base->cfr);
 +
 +      /* Get the command phase address */
 +      if (curr_cmd->end_cmd_valid == ZYNQ_NAND_CMD_PHASE)
 +              end_cmd_valid = 1;
 +
 +      if (curr_cmd->end_cmd == NAND_CMD_NONE)
 +              end_cmd = 0x0;
 +      else
 +              end_cmd = curr_cmd->end_cmd;
 +
 +      cmd_phase_addr = (unsigned long)xnand->nand_base        |
 +                      (curr_cmd->addr_cycles << ADDR_CYCLES_SHIFT)    |
 +                      (end_cmd_valid << END_CMD_VALID_SHIFT)          |
 +                      (COMMAND_PHASE)                                 |
 +                      (end_cmd << END_CMD_SHIFT)                      |
 +                      (curr_cmd->start_cmd << START_CMD_SHIFT);
 +
 +      cmd_addr = (void __iomem *)cmd_phase_addr;
 +
 +      /* Get the data phase address */
 +      end_cmd_valid = 0;
 +
 +      data_phase_addr = (unsigned long)xnand->nand_base       |
 +                      (0x0 << CLEAR_CS_SHIFT)                         |
 +                      (end_cmd_valid << END_CMD_VALID_SHIFT)          |
 +                      (DATA_PHASE)                                    |
 +                      (end_cmd << END_CMD_SHIFT)                      |
 +                      (0x0 << ECC_LAST_SHIFT);
 +
 +      chip->IO_ADDR_R = (void  __iomem *)data_phase_addr;
 +      chip->IO_ADDR_W = chip->IO_ADDR_R;
 +
 +      /* Command phase AXI Read & Write */
 +      if (column != -1 && page_addr != -1) {
 +              /* Adjust columns for 16 bit bus width */
 +              if (chip->options & NAND_BUSWIDTH_16)
 +                      column >>= 1;
 +              cmd_data = column;
 +              if (mtd->writesize > ZYNQ_NAND_ECC_SIZE) {
 +                      cmd_data |= page_addr << 16;
 +                      /* Another address cycle for devices > 128MiB */
 +                      if (chip->chipsize > (128 << 20)) {
 +                              writel(cmd_data, cmd_addr);
 +                              cmd_data = (page_addr >> 16);
 +                      }
 +              } else {
 +                      cmd_data |= page_addr << 8;
 +              }
 +      }
 +      /* Erase */
 +      else if (page_addr != -1)
 +              cmd_data = page_addr;
 +      /* Change read/write column, read id etc */
 +      else if (column != -1) {
 +              /* Adjust columns for 16 bit bus width */
 +              if ((chip->options & NAND_BUSWIDTH_16) &&
 +                  ((command == NAND_CMD_READ0) ||
 +                   (command == NAND_CMD_SEQIN) ||
 +                   (command == NAND_CMD_RNDOUT) ||
 +                   (command == NAND_CMD_RNDIN)))
 +                      column >>= 1;
 +              cmd_data = column;
 +      } else
 +              ;
 +
 +      writel(cmd_data, cmd_addr);
 +
 +      if (curr_cmd->end_cmd_valid) {
 +              xnand->end_cmd = curr_cmd->end_cmd;
 +              xnand->end_cmd_pending = 1;
 +      }
 +
 +      ndelay(100);
 +
 +      if ((command == NAND_CMD_READ0) ||
 +          (command == NAND_CMD_RESET) ||
 +          (command == NAND_CMD_PARAM) ||
 +          (command == NAND_CMD_GET_FEATURES)) {
 +              while (!chip->dev_ready(mtd))
 +                              ;
 +              return;
 +      }
 +}
 +
 +/*
 + * zynq_nand_read_buf - read chip data into buffer
 + * @mtd:        MTD device structure
 + * @buf:        buffer to store date
 + * @len:        number of bytes to read
 + */
 +static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      const u32 *nand = chip->IO_ADDR_R;
 +
 +      /* Make sure that buf is 32 bit aligned */
 +      if (((int)buf & 0x3) != 0) {
 +              if (((int)buf & 0x1) != 0) {
 +                      if (len) {
 +                              *buf = readb(nand);
 +                              buf += 1;
 +                              len--;
 +                      }
 +              }
 +
 +              if (((int)buf & 0x3) != 0) {
 +                      if (len >= 2) {
 +                              *(u16 *)buf = readw(nand);
 +                              buf += 2;
 +                              len -= 2;
 +                      }
 +              }
 +      }
 +
 +      /* copy aligned data */
 +      while (len >= 4) {
 +              *(u32 *)buf = readl(nand);
 +              buf += 4;
 +              len -= 4;
 +      }
 +
 +      /* mop up any remaining bytes */
 +      if (len) {
 +              if (len >= 2) {
 +                      *(u16 *)buf = readw(nand);
 +                      buf += 2;
 +                      len -= 2;
 +              }
 +
 +              if (len)
 +                      *buf = readb(nand);
 +      }
 +}
 +
 +/*
 + * zynq_nand_write_buf - write buffer to chip
 + * @mtd:        MTD device structure
 + * @buf:        data buffer
 + * @len:        number of bytes to write
 + */
 +static void zynq_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      const u32 *nand = chip->IO_ADDR_W;
 +
 +      /* Make sure that buf is 32 bit aligned */
 +      if (((int)buf & 0x3) != 0) {
 +              if (((int)buf & 0x1) != 0) {
 +                      if (len) {
 +                              writeb(*buf, nand);
 +                              buf += 1;
 +                              len--;
 +                      }
 +              }
 +
 +              if (((int)buf & 0x3) != 0) {
 +                      if (len >= 2) {
 +                              writew(*(u16 *)buf, nand);
 +                              buf += 2;
 +                              len -= 2;
 +                      }
 +              }
 +      }
 +
 +      /* copy aligned data */
 +      while (len >= 4) {
 +              writel(*(u32 *)buf, nand);
 +              buf += 4;
 +              len -= 4;
 +      }
 +
 +      /* mop up any remaining bytes */
 +      if (len) {
 +              if (len >= 2) {
 +                      writew(*(u16 *)buf, nand);
 +                      buf += 2;
 +                      len -= 2;
 +              }
 +
 +              if (len)
 +                      writeb(*buf, nand);
 +      }
 +}
 +
 +/*
 + * zynq_nand_device_ready - Check device ready/busy line
 + * @mtd:      Pointer to the mtd_info structure
 + *
 + * returns:   0 on busy or 1 on ready state
 + */
 +static int zynq_nand_device_ready(struct mtd_info *mtd)
 +{
 +      /* Check the raw_int_status1 bit */
 +      if ((readl(&zynq_nand_smc_base->csr)) & 0x40) {
 +              /* Clear the interrupt condition */
 +              writel((1 << 4), &zynq_nand_smc_base->cfr);
 +              return 1;
 +      }
 +      return 0;
 +}
 +
 +/*
 + * zynq_nand_check_is_16bit_bw_flash - checking for 16 or 8 bit buswidth nand
 + *
 + * This function will check nand buswidth whether it supports 16 or 8 bit
 + * based on the MIO configuration done by FSBL.
 + *
 + * User needs to correctly configure the MIO's based on the
 + * buswidth supported by the nand flash which is present on the board.
 + *
 + * function will return -1, if there is no MIO configuration for
 + * nand flash.
 + */
 +static int zynq_nand_check_is_16bit_bw_flash(void)
 +{
 +      int is_16bit_bw = NAND_BW_UNKNOWN;
 +      int mio_num_8bit = 0, mio_num_16bit = 0;
 +
 +      mio_num_8bit = zynq_slcr_get_mio_pin_status("nand8");
 +      if (mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT)
 +              is_16bit_bw = NAND_BW_8BIT;
 +
 +      mio_num_16bit = zynq_slcr_get_mio_pin_status("nand16");
 +      if ((mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT) &&
 +          (mio_num_16bit == ZYNQ_NAND_MIO_NUM_NAND_16BIT))
 +              is_16bit_bw = NAND_BW_16BIT;
 +
 +      return is_16bit_bw;
 +}
 +
 +static int zynq_nand_init(struct nand_chip *nand_chip, int devnum)
 +{
 +      struct zynq_nand_info *xnand;
 +      struct mtd_info *mtd;
 +      unsigned long ecc_page_size;
 +      int err = -1;
 +      u8 maf_id, dev_id, i;
 +      u8 get_feature[4];
 +      u8 set_feature[4] = {0x08, 0x00, 0x00, 0x00};
 +      unsigned long ecc_cfg;
 +      int ondie_ecc_enabled = 0;
 +      int is_16bit_bw;
 +
 +      xnand = calloc(1, sizeof(struct zynq_nand_info));
 +      if (!xnand) {
 +              printf("%s: failed to allocate\n", __func__);
 +              goto free;
 +      }
 +
 +      xnand->nand_base = (void *)ZYNQ_NAND_BASEADDR;
 +      mtd = &nand_info[0];
 +
 +      nand_chip->priv = xnand;
 +      mtd->priv = nand_chip;
 +
 +      /* Set address of NAND IO lines */
 +      nand_chip->IO_ADDR_R = xnand->nand_base;
 +      nand_chip->IO_ADDR_W = xnand->nand_base;
 +
 +      /* Set the driver entry points for MTD */
 +      nand_chip->cmdfunc = zynq_nand_cmd_function;
 +      nand_chip->dev_ready = zynq_nand_device_ready;
 +      nand_chip->select_chip = zynq_nand_select_chip;
 +
 +      /* If we don't set this delay driver sets 20us by default */
 +      nand_chip->chip_delay = 30;
 +
 +      /* Buffer read/write routines */
 +      nand_chip->read_buf = zynq_nand_read_buf;
 +      nand_chip->write_buf = zynq_nand_write_buf;
 +
 +      /* Check the NAND buswidth */
 +      /* FIXME this will be changed by using NAND_BUSWIDTH_AUTO */
 +      is_16bit_bw = zynq_nand_check_is_16bit_bw_flash();
 +      if (is_16bit_bw == NAND_BW_UNKNOWN) {
 +              printf("%s: Unable detect NAND based on MIO settings\n",
 +                     __func__);
 +              goto free;
 +      } else if (is_16bit_bw == NAND_BW_16BIT) {
 +              nand_chip->options = NAND_BUSWIDTH_16;
 +      }
 +      nand_chip->bbt_options = NAND_BBT_USE_FLASH;
 +
 +      /* Initialize the NAND flash interface on NAND controller */
 +      if (zynq_nand_init_nand_flash(nand_chip->options) < 0) {
 +              printf("%s: nand flash init failed\n", __func__);
 +              goto free;
 +      }
 +
 +      /* first scan to find the device and get the page size */
 +      if (nand_scan_ident(mtd, 1, NULL)) {
 +              printf("%s: nand_scan_ident failed\n", __func__);
 +              goto fail;
 +      }
 +
 +      /* Send the command for reading device ID */
 +      nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
 +      nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 +
 +      /* Read manufacturer and device IDs */
 +      maf_id = nand_chip->read_byte(mtd);
 +      dev_id = nand_chip->read_byte(mtd);
 +
 +      if ((maf_id == 0x2c) && ((dev_id == 0xf1) ||
 +                               (dev_id == 0xa1) || (dev_id == 0xb1) ||
 +                               (dev_id == 0xaa) || (dev_id == 0xba) ||
 +                               (dev_id == 0xda) || (dev_id == 0xca) ||
 +                               (dev_id == 0xac) || (dev_id == 0xbc) ||
 +                               (dev_id == 0xdc) || (dev_id == 0xcc) ||
 +                               (dev_id == 0xa3) || (dev_id == 0xb3) ||
 +                               (dev_id == 0xd3) || (dev_id == 0xc3))) {
 +              nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES,
 +                                              ONDIE_ECC_FEATURE_ADDR, -1);
 +
 +              for (i = 0; i < 4; i++)
 +                      writeb(set_feature[i], nand_chip->IO_ADDR_W);
 +
 +              /* wait for 1us after writing data with SET_FEATURES command */
 +              ndelay(1000);
 +
 +              nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
 +                                              ONDIE_ECC_FEATURE_ADDR, -1);
 +              nand_chip->read_buf(mtd, get_feature, 4);
 +
 +              if (get_feature[0] & 0x08) {
 +                      debug("%s: OnDie ECC flash\n", __func__);
 +                      ondie_ecc_enabled = 1;
 +              } else {
 +                      printf("%s: Unable to detect OnDie ECC\n", __func__);
 +              }
 +      }
 +
 +      if (ondie_ecc_enabled) {
 +              /* bypass the controller ECC block */
 +              ecc_cfg = readl(&zynq_nand_smc_base->emcr);
 +              ecc_cfg &= ~0xc;
 +              writel(ecc_cfg, &zynq_nand_smc_base->emcr);
 +
 +              /* The software ECC routines won't work
 +               * with the SMC controller
 +               */
 +              nand_chip->ecc.mode = NAND_ECC_HW;
 +              nand_chip->ecc.strength = 1;
 +              nand_chip->ecc.read_page = zynq_nand_read_page_raw_nooob;
 +              nand_chip->ecc.read_subpage = zynq_nand_read_subpage_raw;
 +              nand_chip->ecc.write_page = zynq_nand_write_page_raw;
 +              nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
 +              nand_chip->ecc.write_page_raw = zynq_nand_write_page_raw;
 +              nand_chip->ecc.read_oob = zynq_nand_read_oob;
 +              nand_chip->ecc.write_oob = zynq_nand_write_oob;
 +              nand_chip->ecc.size = mtd->writesize;
 +              nand_chip->ecc.bytes = 0;
 +
 +              /* NAND with on-die ECC supports subpage reads */
 +              nand_chip->options |= NAND_SUBPAGE_READ;
 +
 +              /* On-Die ECC spare bytes offset 8 is used for ECC codes */
 +              if (ondie_ecc_enabled) {
 +                      nand_chip->ecc.layout = &ondie_nand_oob_64;
 +                      /* Use the BBT pattern descriptors */
 +                      nand_chip->bbt_td = &bbt_main_descr;
 +                      nand_chip->bbt_md = &bbt_mirror_descr;
 +              }
 +      } else {
 +              /* Hardware ECC generates 3 bytes ECC code for each 512 bytes */
 +              nand_chip->ecc.mode = NAND_ECC_HW;
 +              nand_chip->ecc.strength = 1;
 +              nand_chip->ecc.size = ZYNQ_NAND_ECC_SIZE;
 +              nand_chip->ecc.bytes = 3;
 +              nand_chip->ecc.calculate = zynq_nand_calculate_hwecc;
 +              nand_chip->ecc.correct = zynq_nand_correct_data;
 +              nand_chip->ecc.hwctl = NULL;
 +              nand_chip->ecc.read_page = zynq_nand_read_page_hwecc;
 +              nand_chip->ecc.write_page = zynq_nand_write_page_hwecc;
 +              nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
 +              nand_chip->ecc.write_page_raw = zynq_nand_write_page_raw;
 +              nand_chip->ecc.read_oob = zynq_nand_read_oob;
 +              nand_chip->ecc.write_oob = zynq_nand_write_oob;
 +
 +              switch (mtd->writesize) {
 +              case 512:
 +                      ecc_page_size = 0x1;
 +                      /* Set the ECC memory config register */
 +                      writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
 +                             &zynq_nand_smc_base->emcr);
 +                      break;
 +              case 1024:
 +                      ecc_page_size = 0x2;
 +                      /* Set the ECC memory config register */
 +                      writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
 +                             &zynq_nand_smc_base->emcr);
 +                      break;
 +              case 2048:
 +                      ecc_page_size = 0x3;
 +                      /* Set the ECC memory config register */
 +                      writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
 +                             &zynq_nand_smc_base->emcr);
 +                      break;
 +              default:
 +                      /* The software ECC routines won't work with
 +                       * the SMC controller
 +                       */
 +                      nand_chip->ecc.mode = NAND_ECC_HW;
 +                      nand_chip->ecc.calculate = nand_calculate_ecc;
 +                      nand_chip->ecc.correct = nand_correct_data;
 +                      nand_chip->ecc.read_page = zynq_nand_read_page_swecc;
 +                      /* nand_chip->ecc.read_subpage = nand_read_subpage; */
 +                      nand_chip->ecc.write_page = zynq_nand_write_page_swecc;
 +                      nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
 +                      nand_chip->ecc.write_page_raw =
 +                                              zynq_nand_write_page_raw;
 +                      nand_chip->ecc.read_oob = zynq_nand_read_oob;
 +                      nand_chip->ecc.write_oob = zynq_nand_write_oob;
 +                      nand_chip->ecc.size = 256;
 +                      nand_chip->ecc.bytes = 3;
 +                      break;
 +              }
 +
 +              if (mtd->oobsize == 16)
 +                      nand_chip->ecc.layout = &nand_oob_16;
 +              else if (mtd->oobsize == 64)
 +                      nand_chip->ecc.layout = &nand_oob_64;
 +              else
 +                      ;
 +      }
 +
 +      /* second phase scan */
 +      if (nand_scan_tail(mtd)) {
 +              printf("%s: nand_scan_tailfailed\n", __func__);
 +              goto fail;
 +      }
 +
 +      if (nand_register(devnum))
 +              goto fail;
 +
 +      return 0;
 +fail:
 +free:
 +      kfree(xnand);
 +      return err;
 +}
 +
 +static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 +
 +void board_nand_init(void)
 +{
 +      struct nand_chip *nand = &nand_chip[0];
 +
 +      if (zynq_nand_init(nand, 0))
 +              puts("ZYNQ NAND init failed\n");
 +}
Simple merge
Simple merge
Simple merge
Simple merge
index 215b26f6c9783708bc89f113aad692217264e42e,0000000000000000000000000000000000000000..d52abcc9a678d67f7f718d848f5fe6ba4fae0562
mode 100644,000000..100644
--- /dev/null
@@@ -1,895 -1,0 +1,896 @@@
 +/*
 + * (C) Copyright 2011 - 2013 Xilinx
 + *
 + * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
 + *
 + * SPDX-License-Identifier:   GPL-2.0+
 + */
 +
 +#include <common.h>
 +#include <malloc.h>
 +#include <ubi_uboot.h>
 +#include <spi.h>
 +#include <spi_flash.h>
 +#include <asm/io.h>
 +#include <asm/arch/hardware.h>
 +#include <asm/arch/sys_proto.h>
 +#include <asm/arch/clk.h>
++#include "../mtd/spi/sf_internal.h"
 +
 +/* QSPI Transmit Data Register */
 +#define ZYNQ_QSPI_TXD_00_00_OFFSET    0x1C /* Transmit 4-byte inst, WO */
 +#define ZYNQ_QSPI_TXD_00_01_OFFSET    0x80 /* Transmit 1-byte inst, WO */
 +#define ZYNQ_QSPI_TXD_00_10_OFFSET    0x84 /* Transmit 2-byte inst, WO */
 +#define ZYNQ_QSPI_TXD_00_11_OFFSET    0x88 /* Transmit 3-byte inst, WO */
 +
 +/*
 + * QSPI Configuration Register bit Masks
 + *
 + * This register contains various control bits that effect the operation
 + * of the QSPI controller
 + */
 +#define ZYNQ_QSPI_CONFIG_IFMODE_MASK  (1 << 31)  /* Flash intrface mode*/
 +#define ZYNQ_QSPI_CONFIG_MSA_MASK     (1 << 15)  /* Manual start enb */
 +#define ZYNQ_QSPI_CONFIG_MCS_MASK     (1 << 14)  /* Manual chip select */
 +#define ZYNQ_QSPI_CONFIG_PCS_MASK     (1 << 10)  /* Peri chip select */
 +#define ZYNQ_QSPI_CONFIG_FW_MASK      (0x3 << 6) /* FIFO width */
 +#define ZYNQ_QSPI_CONFIG_MSTREN_MASK  (1 << 0)   /* Mode select */
 +#define ZYNQ_QSPI_CONFIG_MANSRT_MASK  0x00010000 /* Manual TX Start */
 +#define ZYNQ_QSPI_CONFIG_CPHA_MASK    0x00000004 /* Clock Phase Control */
 +#define ZYNQ_QSPI_CONFIG_CPOL_MASK    0x00000002 /* Clock Polarity Control */
 +#define ZYNQ_QSPI_CONFIG_SSCTRL_MASK  0x00003C00 /* Slave Select Mask */
 +/*
 + * QSPI Interrupt Registers bit Masks
 + *
 + * All the four interrupt registers (Status/Mask/Enable/Disable) have the same
 + * bit definitions.
 + */
 +#define ZYNQ_QSPI_IXR_TXNFULL_MASK    0x00000004 /* QSPI TX FIFO Overflow */
 +#define ZYNQ_QSPI_IXR_TXFULL_MASK     0x00000008 /* QSPI TX FIFO is full */
 +#define ZYNQ_QSPI_IXR_RXNEMTY_MASK    0x00000010 /* QSPI RX FIFO Not Empty */
 +#define ZYNQ_QSPI_IXR_ALL_MASK                (ZYNQ_QSPI_IXR_TXNFULL_MASK | \
 +                                      ZYNQ_QSPI_IXR_RXNEMTY_MASK)
 +
 +/*
 + * QSPI Enable Register bit Masks
 + *
 + * This register is used to enable or disable the QSPI controller
 + */
 +#define ZYNQ_QSPI_ENABLE_ENABLE_MASK  0x00000001 /* QSPI Enable Bit Mask */
 +
 +/*
 + * QSPI Linear Configuration Register
 + *
 + * It is named Linear Configuration but it controls other modes when not in
 + * linear mode also.
 + */
 +#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK   0x40000000 /* QSPI Enable Bit Mask */
 +#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK   0x20000000 /* QSPI Enable Bit Mask */
 +#define ZYNQ_QSPI_LCFG_U_PAGE         0x10000000 /* QSPI Upper memory set */
 +
 +#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT    8
 +
 +#define ZYNQ_QSPI_FR_QOUT_CODE        0x6B    /* read instruction code */
 +#define ZYNQ_QSPI_FR_DUALIO_CODE      0xBB
 +
 +/*
 + * The modebits configurable by the driver to make the SPI support different
 + * data formats
 + */
 +#define MODEBITS                      (SPI_CPOL | SPI_CPHA)
 +
 +/* Definitions for the status of queue */
 +#define ZYNQ_QSPI_QUEUE_STOPPED               0
 +#define ZYNQ_QSPI_QUEUE_RUNNING               1
 +#define ZYNQ_QSPI_RXFIFO_THRESHOLD    32
 +#define ZYNQ_QSPI_FIFO_DEPTH          63
 +
 +/* QSPI MIO's count for different connection topologies */
 +#define ZYNQ_QSPI_MIO_NUM_QSPI0               6
 +#define ZYNQ_QSPI_MIO_NUM_QSPI1               5
 +#define ZYNQ_QSPI_MIO_NUM_QSPI1_CS    1
 +
 +/* QSPI MIO's count for different connection topologies */
 +#define ZYNQ_QSPI_MIO_NUM_QSPI0_DIO   4
 +#define ZYNQ_QSPI_MIO_NUM_QSPI1_DIO   3
 +#define ZYNQ_QSPI_MIO_NUM_QSPI1_CS_DIO        1
 +
 +/* QSPI register offsets */
 +struct zynq_qspi_regs {
 +      u32 confr;      /* 0x00 */
 +      u32 isr;        /* 0x04 */
 +      u32 ier;        /* 0x08 */
 +      u32 idisr;      /* 0x0C */
 +      u32 imaskr;     /* 0x10 */
 +      u32 enbr;       /* 0x14 */
 +      u32 dr;         /* 0x18 */
 +      u32 txd0r;      /* 0x1C */
 +      u32 drxr;       /* 0x20 */
 +      u32 sicr;       /* 0x24 */
 +      u32 txftr;      /* 0x28 */
 +      u32 rxftr;      /* 0x2C */
 +      u32 gpior;      /* 0x30 */
 +      u32 reserved0[19];
 +      u32 txd1r;      /* 0x80 */
 +      u32 txd2r;      /* 0x84 */
 +      u32 txd3r;      /* 0x88 */
 +      u32 reserved1[5];
 +      u32 lcr;        /* 0xA0 */
 +      u32 reserved2[22];
 +      u32 midr;       /* 0xFC */
 +};
 +
 +#define zynq_qspi_base ((struct zynq_qspi_regs *)ZYNQ_QSPI_BASEADDR)
 +
 +struct zynq_qspi {
 +      u32 input_clk_hz;
 +      u32 speed_hz;
 +      const void *txbuf;
 +      void *rxbuf;
 +      int bytes_to_transfer;
 +      int bytes_to_receive;
 +      unsigned int is_inst;
 +      unsigned int is_dual;
 +      unsigned int is_dio;
 +      unsigned int u_page;
 +};
 +
 +struct spi_device {
 +      struct zynq_qspi master;
 +      u32 max_speed_hz;
 +      u8 chip_select;
 +      u8 mode;
 +      u8 bits_per_word;
 +};
 +
 +struct spi_transfer {
 +      const void *tx_buf;
 +      void *rx_buf;
 +      unsigned len;
 +      unsigned cs_change:1;
 +      u8 bits_per_word;
 +      u16 delay_usecs;
 +      u32 speed_hz;
 +};
 +
 +struct zynq_qspi_slave {
 +      struct spi_slave slave;
 +      struct spi_device qspi;
 +};
 +#define to_zynq_qspi_slave(s) container_of(s, struct zynq_qspi_slave, slave)
 +
 +/*
 + * zynq_qspi_init_hw - Initialize the hardware
 + * @is_dual:          Indicates whether dual memories are used
 + * @cs:                       Indicates which chip select is used in dual stacked
 + *
 + * 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 manual 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(int is_dual, int is_dio, unsigned int cs)
 +{
 +      u32 config_reg;
 +
 +      writel(~ZYNQ_QSPI_ENABLE_ENABLE_MASK, &zynq_qspi_base->enbr);
 +      writel(0x7F, &zynq_qspi_base->idisr);
 +
 +      /* Disable linear mode as the boot loader may have used it */
 +      writel(0x0, &zynq_qspi_base->lcr);
 +
 +      /* Clear the TX and RX threshold reg */
 +      writel(0x1, &zynq_qspi_base->txftr);
 +      writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, &zynq_qspi_base->rxftr);
 +
 +      /* Clear the RX FIFO */
 +      while (readl(&zynq_qspi_base->isr) & ZYNQ_QSPI_IXR_RXNEMTY_MASK)
 +              readl(&zynq_qspi_base->drxr);
 +
 +      writel(0x7F, &zynq_qspi_base->isr);
 +      config_reg = readl(&zynq_qspi_base->confr);
 +      config_reg |= ZYNQ_QSPI_CONFIG_IFMODE_MASK |
 +              ZYNQ_QSPI_CONFIG_MCS_MASK | ZYNQ_QSPI_CONFIG_PCS_MASK |
 +              ZYNQ_QSPI_CONFIG_FW_MASK | ZYNQ_QSPI_CONFIG_MSTREN_MASK;
 +      if (is_dual == SF_DUAL_STACKED_FLASH)
 +              config_reg |= 0x10;
 +      writel(config_reg, &zynq_qspi_base->confr);
 +
 +      if (is_dual == SF_DUAL_PARALLEL_FLASH) {
 +              if (is_dio == SF_DUALIO_FLASH)
 +                      /* Enable two memories on seperate buses */
 +                      writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                              ZYNQ_QSPI_LCFG_SEP_BUS_MASK |
 +                              (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                              ZYNQ_QSPI_FR_DUALIO_CODE),
 +                              &zynq_qspi_base->lcr);
 +              else
 +                      /* Enable two memories on seperate buses */
 +                      writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                              ZYNQ_QSPI_LCFG_SEP_BUS_MASK |
 +                              (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                              ZYNQ_QSPI_FR_QOUT_CODE),
 +                              &zynq_qspi_base->lcr);
 +      } else if (is_dual == SF_DUAL_STACKED_FLASH) {
 +              if (is_dio == SF_DUALIO_FLASH)
 +                      /* Configure two memories on shared bus
 +                       * by enabling lower mem */
 +                      writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                              (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                              ZYNQ_QSPI_FR_DUALIO_CODE),
 +                              &zynq_qspi_base->lcr);
 +              else
 +                      /* Configure two memories on shared bus
 +                       * by enabling lower mem */
 +                      writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                              (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                              ZYNQ_QSPI_FR_QOUT_CODE),
 +                              &zynq_qspi_base->lcr);
 +      }
 +      writel(ZYNQ_QSPI_ENABLE_ENABLE_MASK, &zynq_qspi_base->enbr);
 +}
 +
 +/*
 + * zynq_qspi_copy_read_data - Copy data to RX buffer
 + * @zqspi:    Pointer to the zynq_qspi structure
 + * @data:     The 32 bit variable where data is stored
 + * @size:     Number of bytes to be copied from data to RX buffer
 + */
 +static void zynq_qspi_copy_read_data(struct zynq_qspi *zqspi, u32 data, u8 size)
 +{
 +      u8 byte3;
 +
 +      debug("%s: data 0x%04x rxbuf addr: 0x%08x size %d\n", __func__ ,
 +            data, (unsigned)(zqspi->rxbuf), size);
 +
 +      if (zqspi->rxbuf) {
 +              switch (size) {
 +              case 1:
 +                      *((u8 *)zqspi->rxbuf) = data;
 +                      zqspi->rxbuf += 1;
 +                      break;
 +              case 2:
 +                      *((u16 *)zqspi->rxbuf) = data;
 +                      zqspi->rxbuf += 2;
 +                      break;
 +              case 3:
 +                      *((u16 *)zqspi->rxbuf) = data;
 +                      zqspi->rxbuf += 2;
 +                      byte3 = (u8)(data >> 16);
 +                      *((u8 *)zqspi->rxbuf) = byte3;
 +                      zqspi->rxbuf += 1;
 +                      break;
 +              case 4:
 +                      /* Can not assume word aligned buffer */
 +                      memcpy(zqspi->rxbuf, &data, size);
 +                      zqspi->rxbuf += 4;
 +                      break;
 +              default:
 +                      /* This will never execute */
 +                      break;
 +              }
 +      }
 +      zqspi->bytes_to_receive -= size;
 +      if (zqspi->bytes_to_receive < 0)
 +              zqspi->bytes_to_receive = 0;
 +}
 +
 +/*
 + * zynq_qspi_copy_write_data - Copy data from TX buffer
 + * @zqspi:    Pointer to the zynq_qspi 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
 + */
 +static void zynq_qspi_copy_write_data(struct zynq_qspi *zqspi,
 +              u32 *data, u8 size)
 +{
 +      if (zqspi->txbuf) {
 +              switch (size) {
 +              case 1:
 +                      *data = *((u8 *)zqspi->txbuf);
 +                      zqspi->txbuf += 1;
 +                      *data |= 0xFFFFFF00;
 +                      break;
 +              case 2:
 +                      *data = *((u16 *)zqspi->txbuf);
 +                      zqspi->txbuf += 2;
 +                      *data |= 0xFFFF0000;
 +                      break;
 +              case 3:
 +                      *data = *((u16 *)zqspi->txbuf);
 +                      zqspi->txbuf += 2;
 +                      *data |= (*((u8 *)zqspi->txbuf) << 16);
 +                      zqspi->txbuf += 1;
 +                      *data |= 0xFF000000;
 +                      break;
 +              case 4:
 +                      /* Can not assume word aligned buffer */
 +                      memcpy(data, zqspi->txbuf, size);
 +                      zqspi->txbuf += 4;
 +                      break;
 +              default:
 +                      /* This will never execute */
 +                      break;
 +              }
 +      } else {
 +              *data = 0;
 +      }
 +
 +      debug("%s: data 0x%08x txbuf addr: 0x%08x size %d\n", __func__,
 +            *data, (u32)zqspi->txbuf, size);
 +
 +      zqspi->bytes_to_transfer -= size;
 +      if (zqspi->bytes_to_transfer < 0)
 +              zqspi->bytes_to_transfer = 0;
 +}
 +
 +/*
 + * zynq_qspi_chipselect - Select or deselect the chip select line
 + * @qspi:     Pointer to the spi_device structure
 + * @is_on:    Select(1) or deselect (0) the chip select line
 + */
 +static void zynq_qspi_chipselect(struct spi_device *qspi, int is_on)
 +{
 +      u32 config_reg;
 +
 +      debug("%s: is_on: %d\n", __func__, is_on);
 +
 +      config_reg = readl(&zynq_qspi_base->confr);
 +
 +      if (is_on) {
 +              /* Select the slave */
 +              config_reg &= ~ZYNQ_QSPI_CONFIG_SSCTRL_MASK;
 +              config_reg |= (((~(0x0001 << qspi->chip_select)) << 10) &
 +                              ZYNQ_QSPI_CONFIG_SSCTRL_MASK);
 +      } else
 +              /* Deselect the slave */
 +              config_reg |= ZYNQ_QSPI_CONFIG_SSCTRL_MASK;
 +
 +      writel(config_reg, &zynq_qspi_base->confr);
 +}
 +
 +/*
 + * zynq_qspi_setup_transfer - Configure QSPI controller for specified transfer
 + * @qspi:     Pointer to the spi_device structure
 + * @transfer: Pointer to the spi_transfer structure which provides information
 + *            about next transfer setup parameters
 + *
 + * Sets the operational mode of QSPI controller for the next QSPI transfer and
 + * sets the requested clock frequency.
 + *
 + * returns:   0 on success and -1 on invalid input parameter
 + *
 + * Note: If the requested frequency is not an exact match with what can be
 + * obtained using the prescalar value, the driver sets the clock frequency which
 + * is lower than the requested frequency (maximum lower) for the transfer. If
 + * the requested frequency is higher or lower than that is supported by the QSPI
 + * controller the driver will set the highest or lowest frequency supported by
 + * controller.
 + */
 +static int zynq_qspi_setup_transfer(struct spi_device *qspi,
 +              struct spi_transfer *transfer)
 +{
 +      struct zynq_qspi *zqspi = &qspi->master;
 +      u8 bits_per_word;
 +      u32 config_reg;
 +      u32 req_hz;
 +      u32 baud_rate_val = 0;
 +
 +      debug("%s: qspi: 0x%08x transfer: 0x%08x\n", __func__,
 +            (u32)qspi, (u32)transfer);
 +
 +      bits_per_word = (transfer) ?
 +                      transfer->bits_per_word : qspi->bits_per_word;
 +      req_hz = (transfer) ? transfer->speed_hz : qspi->max_speed_hz;
 +
 +      if (qspi->mode & ~MODEBITS) {
 +              printf("%s: Unsupported mode bits %x\n",
 +                     __func__, qspi->mode & ~MODEBITS);
 +              return -1;
 +      }
 +
 +      if (bits_per_word != 32)
 +              bits_per_word = 32;
 +
 +      config_reg = readl(&zynq_qspi_base->confr);
 +
 +      /* Set the QSPI clock phase and clock polarity */
 +      config_reg &= (~ZYNQ_QSPI_CONFIG_CPHA_MASK) &
 +                              (~ZYNQ_QSPI_CONFIG_CPOL_MASK);
 +      if (qspi->mode & SPI_CPHA)
 +              config_reg |= ZYNQ_QSPI_CONFIG_CPHA_MASK;
 +      if (qspi->mode & SPI_CPOL)
 +              config_reg |= ZYNQ_QSPI_CONFIG_CPOL_MASK;
 +
 +      /* Set the clock frequency */
 +      if (zqspi->speed_hz != req_hz) {
 +              baud_rate_val = 0;
 +              while ((baud_rate_val < 7) &&
 +                      (zqspi->input_clk_hz / (2 << baud_rate_val)) > req_hz) {
 +                              baud_rate_val++;
 +              }
 +              config_reg &= 0xFFFFFFC7;
 +              config_reg |= (baud_rate_val << 3);
 +              zqspi->speed_hz = req_hz;
 +      }
 +
 +      writel(config_reg, &zynq_qspi_base->confr);
 +
 +      debug("%s: mode %d, %u bits/w, %u clock speed\n", __func__,
 +            qspi->mode & MODEBITS, qspi->bits_per_word, zqspi->speed_hz);
 +
 +      return 0;
 +}
 +
 +/*
 + * zynq_qspi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
 + * @zqspi:    Pointer to the zynq_qspi structure
 + */
 +static void zynq_qspi_fill_tx_fifo(struct zynq_qspi *zqspi, u32 size)
 +{
 +      u32 data = 0;
 +      u32 fifocount = 0;
 +      unsigned len, offset;
 +      static const unsigned offsets[4] = {
 +              ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
 +              ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
 +
 +      while ((fifocount < size) &&
 +                      (zqspi->bytes_to_transfer > 0)) {
 +              if (zqspi->bytes_to_transfer >= 4) {
 +                      if (zqspi->txbuf) {
 +                              memcpy(&data, zqspi->txbuf, 4);
 +                              zqspi->txbuf += 4;
 +                      } else {
 +                              data = 0;
 +                      }
 +                      writel(data, &zynq_qspi_base->txd0r);
 +                      zqspi->bytes_to_transfer -= 4;
 +                      fifocount++;
 +              } else {
 +                      /* Write TXD1, TXD2, TXD3 only if TxFIFO is empty. */
 +                      if (!(readl(&zynq_qspi_base->isr)
 +                                      & ZYNQ_QSPI_IXR_TXNFULL_MASK) &&
 +                                      !zqspi->rxbuf)
 +                              return;
 +                      len = zqspi->bytes_to_transfer;
 +                      zynq_qspi_copy_write_data(zqspi, &data, len);
 +                      offset = (zqspi->rxbuf) ? offsets[0] : offsets[len];
 +                      writel(data, &zynq_qspi_base->confr + (offset / 4));
 +              }
 +      }
 +}
 +
 +/*
 + * zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller
 + * @zqspi:    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
 + * fills the TX FIFO if there is any data remaining to be transferred.
 + * On Mode Fault interrupt this function indicates that transfer is completed,
 + * the SPI subsystem will identify the error as the remaining bytes to be
 + * transferred is non-zero.
 + *
 + * returns:   0 for poll timeout
 + *            1 transfer operation complete
 + */
 +static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi)
 +{
 +      int max_loop;
 +      u32 intr_status;
 +      u32 rxindex = 0;
 +      u32 rxcount;
 +
 +      debug("%s: zqspi: 0x%08x\n", __func__, (u32)zqspi);
 +
 +      /* Poll until any of the interrupt status bits are set */
 +      max_loop = 0;
 +      do {
 +              intr_status = readl(&zynq_qspi_base->isr);
 +              max_loop++;
 +      } while ((intr_status == 0) && (max_loop < 100000));
 +
 +      if (intr_status == 0) {
 +              printf("%s: Timeout\n", __func__);
 +              return 0;
 +      }
 +
 +      writel(intr_status, &zynq_qspi_base->isr);
 +
 +      /* Disable all interrupts */
 +      writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->idisr);
 +      if ((intr_status & ZYNQ_QSPI_IXR_TXNFULL_MASK) ||
 +          (intr_status & ZYNQ_QSPI_IXR_RXNEMTY_MASK)) {
 +              /*
 +               * This bit is set when Tx FIFO has < THRESHOLD entries. We have
 +               * the THRESHOLD value set to 1, so this bit indicates Tx FIFO
 +               * is empty
 +               */
 +              rxcount = zqspi->bytes_to_receive - zqspi->bytes_to_transfer;
 +              rxcount = (rxcount % 4) ? ((rxcount/4)+1) : (rxcount/4);
 +              while ((rxindex < rxcount) &&
 +                              (rxindex < ZYNQ_QSPI_RXFIFO_THRESHOLD)) {
 +                      /* Read out the data from the RX FIFO */
 +                      u32 data;
 +                      data = readl(&zynq_qspi_base->drxr);
 +
 +                      if (zqspi->bytes_to_receive >= 4) {
 +                              if (zqspi->rxbuf) {
 +                                      memcpy(zqspi->rxbuf, &data, 4);
 +                                      zqspi->rxbuf += 4;
 +                              }
 +                              zqspi->bytes_to_receive -= 4;
 +                      } else {
 +                              zynq_qspi_copy_read_data(zqspi, data,
 +                                      zqspi->bytes_to_receive);
 +                      }
 +                      rxindex++;
 +              }
 +
 +              if (zqspi->bytes_to_transfer) {
 +                      /* There is more data to send */
 +                      zynq_qspi_fill_tx_fifo(zqspi,
 +                                             ZYNQ_QSPI_RXFIFO_THRESHOLD);
 +
 +                      writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->ier);
 +              } else {
 +                      /*
 +                       * If transfer and receive is completed then only send
 +                       * complete signal
 +                       */
 +                      if (!zqspi->bytes_to_receive) {
 +                              /* return operation complete */
 +                              writel(ZYNQ_QSPI_IXR_ALL_MASK,
 +                                     &zynq_qspi_base->idisr);
 +                              return 1;
 +                      }
 +              }
 +      }
 +
 +      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
 + *
 + * This function fills the TX FIFO, starts the QSPI transfer, and waits for the
 + * transfer to be completed.
 + *
 + * returns:   Number of bytes transferred in the last transfer
 + */
 +static int zynq_qspi_start_transfer(struct spi_device *qspi,
 +                      struct spi_transfer *transfer)
 +{
 +      struct zynq_qspi *zqspi = &qspi->master;
 +      static u8 current_u_page;
 +      u32 data = 0;
 +
 +      debug("%s: qspi: 0x%08x transfer: 0x%08x len: %d\n", __func__,
 +            (u32)qspi, (u32)transfer, transfer->len);
 +
 +      zqspi->txbuf = transfer->tx_buf;
 +      zqspi->rxbuf = transfer->rx_buf;
 +      zqspi->bytes_to_transfer = transfer->len;
 +      zqspi->bytes_to_receive = transfer->len;
 +
 +      if (zqspi->is_inst && (zqspi->is_dual == SF_DUAL_STACKED_FLASH) &&
 +          (current_u_page != zqspi->u_page)) {
 +              if (zqspi->u_page) {
 +                      if (zqspi->is_dio == SF_DUALIO_FLASH)
 +                              writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                                      ZYNQ_QSPI_LCFG_U_PAGE |
 +                                      (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                                      ZYNQ_QSPI_FR_DUALIO_CODE),
 +                                      &zynq_qspi_base->lcr);
 +                      else
 +                              /* Configure two memories on shared bus
 +                               * by enabling upper mem
 +                               */
 +                              writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                                      ZYNQ_QSPI_LCFG_U_PAGE |
 +                                      (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                                      ZYNQ_QSPI_FR_QOUT_CODE),
 +                                      &zynq_qspi_base->lcr);
 +              } else {
 +                      if (zqspi->is_dio == SF_DUALIO_FLASH)
 +                              writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                                      (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                                      ZYNQ_QSPI_FR_DUALIO_CODE),
 +                                      &zynq_qspi_base->lcr);
 +                      else
 +                              /* Configure two memories on shared bus
 +                               * by enabling lower mem
 +                               */
 +                              writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK |
 +                                      (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) |
 +                                      ZYNQ_QSPI_FR_QOUT_CODE),
 +                                      &zynq_qspi_base->lcr);
 +              }
 +              current_u_page = zqspi->u_page;
 +      }
 +
 +      if (transfer->len < 4)
 +              zynq_qspi_fill_tx_fifo(zqspi, transfer->len);
 +      else
 +              zynq_qspi_fill_tx_fifo(zqspi, ZYNQ_QSPI_FIFO_DEPTH);
 +
 +      writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->ier);
 +      /* Start the transfer by enabling manual start bit */
 +
 +      /* wait for completion */
 +      do {
 +              data = zynq_qspi_irq_poll(zqspi);
 +      } while (data == 0);
 +
 +      return (transfer->len) - (zqspi->bytes_to_transfer);
 +}
 +
 +static int zynq_qspi_transfer(struct spi_device *qspi,
 +              struct spi_transfer *transfer)
 +{
 +      struct zynq_qspi *zqspi = &qspi->master;
 +      unsigned cs_change = 1;
 +      int status = 0;
 +
 +      debug("%s\n", __func__);
 +
 +      while (1) {
 +              if (transfer->bits_per_word || transfer->speed_hz) {
 +                      status = zynq_qspi_setup_transfer(qspi, transfer);
 +                      if (status < 0)
 +                              break;
 +              }
 +
 +              /* Select the chip if required */
 +              if (cs_change)
 +                      zynq_qspi_chipselect(qspi, 1);
 +
 +              cs_change = transfer->cs_change;
 +
 +              if (!transfer->tx_buf && !transfer->rx_buf && transfer->len) {
 +                      status = -1;
 +                      break;
 +              }
 +
 +              /* Request the transfer */
 +              if (transfer->len) {
 +                      status = zynq_qspi_start_transfer(qspi, transfer);
 +                      zqspi->is_inst = 0;
 +              }
 +
 +              if (status != transfer->len) {
 +                      if (status > 0)
 +                              status = -EMSGSIZE;
 +                      break;
 +              }
 +              status = 0;
 +
 +              if (transfer->delay_usecs)
 +                      udelay(transfer->delay_usecs);
 +
 +              if (cs_change)
 +                      /* Deselect the chip */
 +                      zynq_qspi_chipselect(qspi, 0);
 +
 +              break;
 +      }
 +
 +      zynq_qspi_setup_transfer(qspi, NULL);
 +
 +      return 0;
 +}
 +
 +/*
 + * zynq_qspi_check_is_dual_flash - checking for dual or single qspi
 + *
 + * This function will check the type of the flash whether it supports
 + * single or dual qspi based on the MIO configuration done by FSBL.
 + *
 + * User needs to correctly configure the MIO's based on the
 + * number of qspi flashes present on the board.
 + *
 + * function will return -1, if there is no MIO configuration for
 + * qspi flash.
 + */
 +static int zynq_qspi_check_is_dual_flash(int *is_dio)
 +{
 +      int is_dual = -1;
 +      int lower_mio = 0, upper_mio = 0, upper_mio_cs1 = 0;
 +
 +      lower_mio = zynq_slcr_get_mio_pin_status("qspi0");
 +      if (lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) {
 +              is_dual = SF_SINGLE_FLASH;
 +      } else {
 +              lower_mio = zynq_slcr_get_mio_pin_status("qspi0_dio");
 +              if (lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) {
 +                      debug("QSPI in Single 2-bit\n");
 +                      *is_dio = SF_DUALIO_FLASH;
 +                      is_dual = SF_SINGLE_FLASH;
 +              }
 +      }
 +
 +      if (*is_dio != SF_DUALIO_FLASH) {
 +              upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs");
 +              if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) &&
 +                  (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS))
 +                      is_dual = SF_DUAL_STACKED_FLASH;
 +
 +              upper_mio = zynq_slcr_get_mio_pin_status("qspi1");
 +              if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) &&
 +                  (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS) &&
 +                  (upper_mio == ZYNQ_QSPI_MIO_NUM_QSPI1))
 +                      is_dual = SF_DUAL_PARALLEL_FLASH;
 +      } else {
 +              upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs_dio");
 +              if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) &&
 +                  (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS_DIO)) {
 +                      debug("QSPI in DualStacked 2-bit\n");
 +                      is_dual = SF_DUAL_STACKED_FLASH;
 +              }
 +              upper_mio = zynq_slcr_get_mio_pin_status("qspi1_dio");
 +              if ((lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0_DIO) &&
 +                  (upper_mio_cs1 == ZYNQ_QSPI_MIO_NUM_QSPI1_CS_DIO) &&
 +                  (upper_mio == ZYNQ_QSPI_MIO_NUM_QSPI1_DIO)) {
 +                      debug("QSPI in DualParallel 2-bit\n");
 +                      is_dual = SF_DUAL_PARALLEL_FLASH;
 +              }
 +      }
 +
 +      return is_dual;
 +}
 +
 +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 +{
 +      /* 1 bus with 2 chipselect */
 +      return bus == 0 && cs < 2;
 +}
 +
 +void spi_cs_activate(struct spi_slave *slave)
 +{
 +      debug("%s: slave 0x%08x\n", __func__, (unsigned)slave);
 +}
 +
 +void spi_cs_deactivate(struct spi_slave *slave)
 +{
 +      debug("%s: slave 0x%08x\n", __func__, (unsigned)slave);
 +}
 +
 +void spi_init()
 +{
 +      debug("%s\n", __func__);
 +}
 +
 +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 +              unsigned int max_hz, unsigned int mode)
 +{
 +      int is_dual;
 +      int is_dio = 0;
 +      unsigned long lqspi_frequency;
 +      struct zynq_qspi_slave *qspi;
 +
 +      debug("%s: bus: %d cs: %d max_hz: %d mode: %d\n",
 +            __func__, bus, cs, max_hz, mode);
 +
 +      if (!spi_cs_is_valid(bus, cs))
 +              return NULL;
 +
 +      is_dual = zynq_qspi_check_is_dual_flash(&is_dio);
 +
 +      if (is_dual == -1) {
 +              printf("%s: No QSPI device detected based on MIO settings\n",
 +                     __func__);
 +              return NULL;
 +      }
 +
 +      zynq_qspi_init_hw(is_dual, is_dio, cs);
 +
 +      qspi = spi_alloc_slave(struct zynq_qspi_slave, bus, cs);
 +      if (!qspi) {
 +              printf("%s: Fail to allocate zynq_qspi_slave\n", __func__);
 +              return NULL;
 +      }
 +
 +      lqspi_frequency = zynq_clk_get_rate(lqspi_clk);
 +      if (!lqspi_frequency) {
 +              debug("Defaulting to 200000000 Hz qspi clk");
 +              qspi->qspi.master.input_clk_hz = 200000000;
 +      } else {
 +              qspi->qspi.master.input_clk_hz = lqspi_frequency;
 +              debug("Qspi clk frequency set to %ld Hz\n", lqspi_frequency);
 +      }
 +
 +      qspi->slave.option = is_dual;
 +      qspi->slave.dio = is_dio;
 +      qspi->slave.op_mode_rx = SPI_OPM_RX_QOF;
 +      qspi->slave.op_mode_tx = SPI_OPM_TX_QPP;
 +      lqspi_frequency = qspi->qspi.master.input_clk_hz / 2;
 +      qspi->qspi.max_speed_hz = min(max_hz, lqspi_frequency);
 +      qspi->qspi.master.is_dio = is_dio;
 +      qspi->qspi.master.is_dual = is_dual;
 +      qspi->qspi.mode = mode;
 +      qspi->qspi.chip_select = 0;
 +      qspi->qspi.bits_per_word = 32;
 +      zynq_qspi_setup_transfer(&qspi->qspi, NULL);
 +
 +      return &qspi->slave;
 +}
 +
 +void spi_free_slave(struct spi_slave *slave)
 +{
 +      struct zynq_qspi_slave *qspi;
 +
 +      debug("%s: slave: 0x%08x\n", __func__, (u32)slave);
 +
 +      qspi = to_zynq_qspi_slave(slave);
 +      free(qspi);
 +}
 +
 +int spi_claim_bus(struct spi_slave *slave)
 +{
 +      debug("%s: slave: 0x%08x\n", __func__, (u32)slave);
 +      return 0;
 +}
 +
 +void spi_release_bus(struct spi_slave *slave)
 +{
 +      debug("%s: slave: 0x%08x\n", __func__, (u32)slave);
 +}
 +
 +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
 +              void *din, unsigned long flags)
 +{
 +      struct zynq_qspi_slave *qspi;
 +      struct spi_transfer transfer;
 +
 +      debug("%s: slave: 0x%08x bitlen: %d dout: 0x%08x ", __func__,
 +            (u32)slave, bitlen, (u32)dout);
 +      debug("din: 0x%08x flags: 0x%lx\n", (u32)din, flags);
 +
 +      qspi = (struct zynq_qspi_slave *)slave;
 +      transfer.tx_buf = dout;
 +      transfer.rx_buf = din;
 +      transfer.len = bitlen / 8;
 +
 +      /*
 +       * Festering sore.
 +       * Assume that the beginning of a transfer with bits to
 +       * transmit must contain a device command.
 +       */
 +      if (dout && flags & SPI_XFER_BEGIN)
 +              qspi->qspi.master.is_inst = 1;
 +      else
 +              qspi->qspi.master.is_inst = 0;
 +
 +      if (flags & SPI_XFER_END)
 +              transfer.cs_change = 1;
 +      else
 +              transfer.cs_change = 0;
 +
 +      if (flags & SPI_XFER_U_PAGE)
 +              qspi->qspi.master.u_page = 1;
 +      else
 +              qspi->qspi.master.u_page = 0;
 +
 +      transfer.delay_usecs = 0;
 +      transfer.bits_per_word = 32;
 +      transfer.speed_hz = qspi->qspi.max_speed_hz;
 +
 +      zynq_qspi_transfer(&qspi->qspi, &transfer);
 +
 +      return 0;
 +}
Simple merge
Simple merge
diff --cc fs/fat/fat.c
index 0206b14d5f8ae4f94aae63e6d065c7d3026e0b97,bccc3e3ed8fd0929c7f1adf33b2125178be75ccb..e22df5405cad52ca1225f1d5d6e09d95f2f86619
@@@ -317,23 -317,15 +317,22 @@@ get_cluster(fsdata *mydata, __u32 clust
  /*
   * Read at most 'maxsize' bytes from 'pos' in the file associated with 'dentptr'
   * into 'buffer'.
-  * Return the number of bytes read or -1 on fatal errors.
+  * Update the number of bytes read in *gotsize or return -1 on fatal errors.
   */
 +#ifndef CONFIG_ZYNQ_OCM
 +#if defined(CONFIG_ZYNQ) && defined(CONFIG_SPL_BUILD)
 +__section(.ddr)
 +#endif
  __u8 get_contents_vfatname_block[MAX_CLUSTSIZE]
        __aligned(ARCH_DMA_MINALIGN);
 +#else
 +__u8 *get_contents_vfatname_block = (__u8 *)FAT_BUFF_PTR_OCM;
 +#endif
  
- static long
- get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos,
-            __u8 *buffer, unsigned long maxsize)
+ static int get_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos,
+                       __u8 *buffer, loff_t maxsize, loff_t *gotsize)
  {
-       unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
+       loff_t filesize = FAT2CPU32(dentptr->size);
        unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
        __u32 curclust = START(dentptr);
        __u32 endclust, newclust;
@@@ -819,17 -803,11 +819,16 @@@ exit
        return ret;
  }
  
 +#ifndef CONFIG_ZYNQ_OCM
 +#if defined(CONFIG_ZYNQ) && defined(CONFIG_SPL_BUILD)
 +__section(.ddr)
 +#endif
  __u8 do_fat_read_at_block[MAX_CLUSTSIZE]
        __aligned(ARCH_DMA_MINALIGN);
 +#endif
  
- long
- do_fat_read_at(const char *filename, unsigned long pos, void *buffer,
-              unsigned long maxsize, int dols, int dogetsize)
+ int do_fat_read_at(const char *filename, loff_t pos, void *buffer,
+                  loff_t maxsize, int dols, int dogetsize, loff_t *size)
  {
        char fnamecopy[2048];
        boot_sector bs;
        __u32 cursect;
        int idx, isdir = 0;
        int files = 0, dirs = 0;
-       long ret = -1;
+       int ret = -1;
        int firsttime;
        __u32 root_cluster = 0;
+       __u32 read_blk;
        int rootdir_size = 0;
-       int j;
 +#ifdef CONFIG_ZYNQ_OCM
 +      __u8 do_fat_read_at_block[MAX_CLUSTSIZE]
 +               __aligned(ARCH_DMA_MINALIGN);
 +#endif
+       int buffer_blk_cnt;
+       int do_read;
+       __u8 *dir_ptr;
  
        if (read_bootsectandvi(&bs, &volinfo, &mydata->fatsize)) {
                debug("Error: reading boot sector\n");
index 88eee5f46049225e1d9f1de9cecf8b0ec69ca2a9,bb070600021b4a7da9728aaaafd3c9ba132ddf5c..7680d307a51c43e763c31441bf7b4fe73fe805a0
  
  #include "../board/xilinx/microblaze-generic/xparameters.h"
  
- #define       CONFIG_MICROBLAZE       1       /* MicroBlaze CPU */
 -/* MicroBlaze CPU */
  #define       MICROBLAZE_V5           1
  
 -/* linear and spi flash memory */
 -#ifdef XILINX_FLASH_START
 -#define       FLASH
 -#undef        SPIFLASH
 -#undef        RAMENV  /* hold environment in flash */
 -#else
 -#ifdef XILINX_SPI_FLASH_BASEADDR
 -#undef        FLASH
 -#define       SPIFLASH
 -#undef        RAMENV  /* hold environment in flash */
 -#else
 -#undef        FLASH
 -#undef        SPIFLASH
 -#define       RAMENV  /* hold environment in RAM */
 -#endif
 +/* Memory test handling */
 +#define       CONFIG_SYS_MEMTEST_START        CONFIG_SYS_SDRAM_BASE
 +#define       CONFIG_SYS_MEMTEST_END          (CONFIG_SYS_SDRAM_BASE + 0x1000)
 +
 +/* global pointer */
 +/* start of global data */
 +#define       CONFIG_SYS_GBL_DATA_OFFSET      (CONFIG_SYS_SDRAM_SIZE - GENERATED_GBL_DATA_SIZE)
 +
 +/* monitor code */
 +#define       SIZE                    0x40000
 +#define       CONFIG_SYS_MONITOR_LEN          SIZE
 +#define       CONFIG_SYS_MONITOR_BASE  (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET - CONFIG_SYS_MONITOR_LEN - GENERATED_BD_INFO_SIZE)
 +
 +#define       CONFIG_SYS_MONITOR_END          (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
 +#define       CONFIG_SYS_MALLOC_LEN           SIZE
 +#define       CONFIG_SYS_MALLOC_BASE          (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN)
 +
 +/* stack */
 +#define       CONFIG_SYS_INIT_SP_OFFSET       CONFIG_SYS_MALLOC_BASE
 +
 +#define   CONFIG_SYS_BOOTMAPSZ        (1 << 31) /* Initial Memory map for Linux */
 +
 +#undef CONFIG_PHYLIB
 +#define CONFIG_LMB            1
 +
 +/* Default cache size if not specified */
 +#ifndef XILINX_DCACHE_BYTE_SIZE
 +# define XILINX_DCACHE_BYTE_SIZE      32768
  #endif
  
 -/* uart */
 +
 +/* The following table includes the supported baudrates */
 +#define CONFIG_SYS_BAUDRATE_TABLE  \
 +      {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
 +
 +/* use serial multi for all serial devices */
 +#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
 +
  #ifdef XILINX_UARTLITE_BASEADDR
  # define CONFIG_XILINX_UARTLITE
 -# define CONFIG_SERIAL_BASE   XILINX_UARTLITE_BASEADDR
 -# define CONFIG_BAUDRATE      XILINX_UARTLITE_BAUDRATE
 -# define CONFIG_SYS_BAUDRATE_TABLE    { CONFIG_BAUDRATE }
 -# define CONSOLE_ARG  "console=console=ttyUL0,115200\0"
 -#elif XILINX_UART16550_BASEADDR
 -# define CONFIG_SYS_NS16550           1
 +# if defined(XILINX_UARTLITE_BAUDRATE)
 +#  define CONFIG_BAUDRATE     XILINX_UARTLITE_BAUDRATE
 +# endif
 +#endif
 +
 +#if XILINX_UART16550_BASEADDR
 +# define CONFIG_SYS_NS16550   1
  # define CONFIG_SYS_NS16550_SERIAL
 +# define CONFIG_SYS_NS16550_COM1      ((XILINX_UART16550_BASEADDR & ~0xF) + 0x1000)
 +# define CONFIG_SYS_NS16550_CLK               XILINX_UART16550_CLOCK_HZ
 +
  # if defined(__MICROBLAZEEL__)
  #  define CONFIG_SYS_NS16550_REG_SIZE -4
  # else
index 67083c10795952808b6cbc823ee21bdd199eadb7,87b4fffeb9fb262143edaae2599220c04255a959..30e9dc8dae36618daf61f852afda7f517c146c20
  #define CONFIG_FIT_VERBOSE    1 /* enable fit_format_{error,warning}() */
  #define CONFIG_IMAGE_FORMAT_LEGACY /* enable also legacy image format */
  
 -/* RSA support */
 -#define CONFIG_FIT_SIGNATURE
 -#define CONFIG_RSA
 -
+ /* FDT support */
+ #define CONFIG_DISPLAY_BOARDINFO_LATE
  /* Extend size of kernel image for uncompression */
  #define CONFIG_SYS_BOOTM_LEN  (60 * 1024 * 1024)
  
  /* Commands */
  #include <config_cmd_default.h>
  
 -#define CONFIG_CMD_PING
 -#define CONFIG_CMD_DHCP
 -#define CONFIG_CMD_MII
 -#define CONFIG_CMD_TFTPPUT
 +#ifdef CONFIG_SYS_ENET
 +# define CONFIG_CMD_PING
 +# define CONFIG_CMD_DHCP
 +# define CONFIG_CMD_MII
 +# define CONFIG_CMD_TFTPPUT
 +#else
 +# undef CONFIG_CMD_NET
 +# undef CONFIG_CMD_NFS
 +#endif
 +
 +#if defined(CONFIG_CMD_ZYNQ_RSA)
 +#define CONFIG_RSA
 +#define CONFIG_SHA256
 +#define CONFIG_CMD_ZYNQ_AES
 +#endif
 +
 +#define CONFIG_CMD_BOOTZ
 +#undef CONFIG_BOOTM_NETBSD
 +
 +#define CONFIG_SYS_HZ                 1000
 +
 +/* For development/debugging */
 +#ifdef DEBUG
 +# define CONFIG_CMD_REGINFO
 +# define CONFIG_PANIC_HANG
 +#endif
  
  /* SPL part */
- #define CONFIG_SPL
  #define CONFIG_CMD_SPL
  #define CONFIG_SPL_FRAMEWORK
  #define CONFIG_SPL_LIBCOMMON_SUPPORT
  
  /* Address in RAM where the parameters must be copied by SPL. */
  #define CONFIG_SYS_SPL_ARGS_ADDR      0x10000000
 +#define CONFIG_SYS_SPI_ARGS_OFFS      0 /* FIXME */
 +#define CONFIG_SYS_SPI_ARGS_SIZE      0 /* FIXME */
  
- #define CONFIG_SPL_FAT_LOAD_ARGS_NAME         "system.dtb"
- #define CONFIG_SPL_FAT_LOAD_KERNEL_NAME               "uImage"
+ #define CONFIG_SPL_FS_LOAD_ARGS_NAME          "system.dtb"
+ #define CONFIG_SPL_FS_LOAD_KERNEL_NAME                "uImage"
  
  /* Not using MMC raw mode - just for compilation purpose */
  #define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 0
  #define CONFIG_SPL_SPI_SUPPORT
  #define CONFIG_SPL_SPI_LOAD
  #define CONFIG_SPL_SPI_FLASH_SUPPORT
- #define CONFIG_SPL_SPI_BUS    0
- #define CONFIG_SYS_SPI_U_BOOT_OFFS    0x80000
- #define CONFIG_SPL_SPI_CS     0
+ #define CONFIG_SYS_SPI_U_BOOT_OFFS    0x100000
  #endif
  
 +#ifdef DEBUG
 +#define CONFIG_SPL_RAM_DEVICE
 +#define CONFIG_SPL_NET_SUPPORT
 +#define CONFIG_SPL_ETH_SUPPORT
 +#define CONFIG_SPL_ENV_SUPPORT
 +#define CONFIG_SPL_ETH_DEVICE "Gem.e000b000"
 +#endif
 +
  /* for booting directly linux */
  #define CONFIG_SPL_OS_BOOT
 +#define CONFIG_SYS_SPI_KERNEL_OFFS    0 /* FIXME */
  
  /* SP location before relocation, must use scratch RAM */
  #define CONFIG_SPL_TEXT_BASE  0x0
index 16d77936b31a17c44d577c4c7184d1dbfca35b66,0000000000000000000000000000000000000000..db2da7470673cea19b79b060100c1802d1460868
mode 100644,000000..100644
--- /dev/null
@@@ -1,81 -1,0 +1,79 @@@
- #undef CONFIG_CMD_GO
- #undef CONFIG_CMD_BOOTM
 +/*
 + * (C) Copyright 2013 Xilinx.
 + *
 + * Configuration settings for the Xilinx Zynq CSE board.
 + * See zynq-common.h for Zynq common configs
 + *
 + * SPDX-License-Identifier:     GPL-2.0+
 + */
 +
 +#ifndef __CONFIG_ZYNQ_CSE_H
 +#define __CONFIG_ZYNQ_CSE_H
 +
 +#define CONFIG_SYS_NO_FLASH
 +#define CONFIG_ZYNQ_DCC
 +#define _CONFIG_CMD_DEFAULT_H
 +#define CONFIG_SKIP_LOWLEVEL_INIT
 +#define CONFIG_ENV_IS_NOWHERE
 +#define CONFIG_SYS_DCACHE_OFF
 +
 +#if defined(CONFIG_CSE_QSPI)
 +# define CONFIG_ZYNQ_QSPI
 +
 +#elif defined(CONFIG_CSE_NAND)
 +# define CONFIG_NAND_ZYNQ
 +
 +#elif defined(CONFIG_CSE_NOR)
 +#undef CONFIG_SYS_NO_FLASH
 +
 +#endif
 +
 +#include <configs/zynq-common.h>
 +
 +/* Undef unneeded configs */
 +#undef CONFIG_SYS_SDRAM_BASE
 +#undef CONFIG_OF_LIBFDT
 +#undef CONFIG_EXTRA_ENV_SETTINGS
 +#undef CONFIG_BOARD_LATE_INIT
 +#undef CONFIG_FPGA
 +#undef CONFIG_FPGA_XILINX
 +#undef CONFIG_FPGA_ZYNQPL
 +#undef CONFIG_CMD_FPGA
 +#undef CONFIG_FIT
 +#undef CONFIG_FIT_VERBOSE
 +#undef CONFIG_CMD_BOOTZ
 +#undef CONFIG_BOOTCOMMAND
 +#undef CONFIG_SYS_HUSH_PARSER
 +#undef CONFIG_SYS_PROMPT_HUSH_PS2
 +#undef CONFIG_BOOTDELAY
 +#undef CONFIG_SYS_MALLOC_LEN
 +#undef CONFIG_ENV_SIZE
 +#undef CONFIG_CMDLINE_EDITING
 +#undef CONFIG_AUTO_COMPLETE
 +#undef CONFIG_ZLIB
 +#undef CONFIG_GZIP
 +#undef CONFIG_CMD_SPL
 +
 +/* Define needed configs */
 +#define CONFIG_CMD_MEMORY
 +#define CONFIG_BOOTDELAY      -1 /* -1 to Disable autoboot */
 +#define CONFIG_SYS_MALLOC_LEN 0x4000
 +
 +#if defined(CONFIG_CSE_QSPI)
 +# define CONFIG_SYS_SDRAM_SIZE                (256 * 1024)
 +# define CONFIG_SYS_SDRAM_BASE                0xFFFD0000
 +# define CONFIG_ENV_SIZE              1400
 +
 +#elif defined(CONFIG_CSE_NAND)
 +# define CONFIG_SYS_SDRAM_SIZE                (4 * 1024 * 1024)
 +# define CONFIG_SYS_SDRAM_BASE                0
 +# define CONFIG_ENV_SIZE              0x10000
 +
 +#elif defined(CONFIG_CSE_NOR)
 +# define CONFIG_SYS_SDRAM_SIZE                (256 * 1024)
 +# define CONFIG_SYS_SDRAM_BASE                0xFFFD0000
 +# define CONFIG_ENV_SIZE              1400
 +
 +#endif
 +
 +#endif /* __CONFIG_ZYNQ_CSE_H */
Simple merge
index d17217c7e2c3e710b93b09caf6608dd1d6faf1c9,16b904743f1e97f5487f850f81f6c0383a40c724..1aac1cf150223c19dded4722f34c2024b2da64e8
  # define CONFIG_ZYNQ_GEM0
  # define CONFIG_ZYNQ_GEM_PHY_ADDR0    7
  # define CONFIG_ZYNQ_SDHCI0
 -# define CONFIG_ZYNQ_SPI
 +# define CONFIG_ZYNQ_QSPI
- # define CONFIG_DEFAULT_DEVICE_TREE   zynq-zc770-xm010
 +
 +#elif defined(CONFIG_ZC770_XM011)
 +# define CONFIG_ZYNQ_SERIAL_UART1
 +# define CONFIG_NAND_ZYNQ
- # define CONFIG_DEFAULT_DEVICE_TREE   zynq-zc770-xm011
  
  #elif defined(CONFIG_ZC770_XM012)
  # define CONFIG_ZYNQ_SERIAL_UART1
@@@ -36,8 -29,6 +33,7 @@@
  # define CONFIG_ZYNQ_SERIAL_UART0
  # define CONFIG_ZYNQ_GEM1
  # define CONFIG_ZYNQ_GEM_PHY_ADDR1    7
- # define CONFIG_DEFAULT_DEVICE_TREE   zynq-zc770-xm013
 +# define CONFIG_ZYNQ_QSPI
  
  #else
  # define CONFIG_ZYNQ_SERIAL_UART0
index 832e7a0f53d64d764955ee1c6b1fcf4d48e2c1db,946de953e4a755a0dd65f1d225142ff8f3310ab0..224c7cd7c84de7e2054d28001692ce78fc3794ed
  
  #define CONFIG_ZYNQ_USB
  #define CONFIG_ZYNQ_SDHCI0
 +#define CONFIG_ZYNQ_QSPI
 +
  #define CONFIG_ZYNQ_BOOT_FREEBSD
- #define CONFIG_DEFAULT_DEVICE_TREE    zynq-zed
  
  #include <configs/zynq-common.h>
  
Simple merge
diff --cc include/spi.h
Simple merge
index 7b64957103dfd173e31aa456b1d5b684974b465a,5913b39e268ee30598de449d03447a8205c80dae..a8b5da203a70bd2e6d270ebdb41bf65382be97ec
  #ifndef _SPI_FLASH_H_
  #define _SPI_FLASH_H_
  
- #include <spi.h>
+ #include <dm.h>       /* Because we dereference struct udevice here */
  #include <linux/types.h>
- #include <linux/compiler.h>
- /* sf param flags */
- #define SECT_4K               1 << 1
- #define SECT_32K      1 << 2
- #define E_FSR         1 << 3
- #define WR_QPP                1 << 4
- /* Enum list - Full read commands */
- enum spi_read_cmds {
-       ARRAY_SLOW = 1 << 0,
-       DUAL_OUTPUT_FAST = 1 << 1,
-       DUAL_IO_FAST = 1 << 2,
-       QUAD_OUTPUT_FAST = 1 << 3,
-       QUAD_IO_FAST = 1 << 4,
- };
- #define RD_EXTN               ARRAY_SLOW | DUAL_OUTPUT_FAST | DUAL_IO_FAST
- #define RD_FULL               RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST
- /* Dual SPI flash memories */
- enum spi_dual_flash {
-       SF_SINGLE_FLASH = 0,
-       SF_DUAL_STACKED_FLASH = 1 << 0,
-       SF_DUAL_PARALLEL_FLASH = 1 << 1,
- };
  
- /**
-  * struct spi_flash_params - SPI/QSPI flash device params structure
-  *
-  * @name:             Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
-  * @jedec:            Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
-  * @ext_jedec:                Device ext_jedec ID
-  * @sector_size:      Sector size of this device
-  * @nr_sectors:               No.of sectors on this device
-  * @e_rd_cmd:         Enum list for read commands
-  * @flags:            Important param, for flash specific behaviour
-  */
- struct spi_flash_params {
-       const char *name;
-       u32 jedec;
-       u16 ext_jedec;
-       u32 sector_size;
-       u32 nr_sectors;
-       u8 e_rd_cmd;
-       u16 flags;
- };
 +#define SF_DUALIO_FLASH       1
 +
+ #ifndef CONFIG_SF_DEFAULT_SPEED
+ # define CONFIG_SF_DEFAULT_SPEED      1000000
+ #endif
+ #ifndef CONFIG_SF_DEFAULT_MODE
+ # define CONFIG_SF_DEFAULT_MODE               SPI_MODE_3
+ #endif
+ #ifndef CONFIG_SF_DEFAULT_CS
+ # define CONFIG_SF_DEFAULT_CS         0
+ #endif
+ #ifndef CONFIG_SF_DEFAULT_BUS
+ # define CONFIG_SF_DEFAULT_BUS                0
+ #endif
  
extern const struct spi_flash_params spi_flash_params_table[];
struct spi_slave;
  
  /**
   * struct spi_flash - SPI flash structure
Simple merge
index fd26bde621e49560df348d2881d8a7fda7f3b58a,4ef19b66f4b12588f2bbe0a978500a0718177336..aac25ad5b574535e8431e6ed8dca51c442282147
@@@ -121,7 -124,49 +124,49 @@@ static void montgomery_mul(const struc
        for (i = 0; i < key->len; ++i)
                montgomery_mul_add_step(key, result, a[i], b);
  }
 -
 +#if IMAGE_ENABLE_VERIFY
+ /**
+  * num_pub_exponent_bits() - Number of bits in the public exponent
+  *
+  * @key:      RSA key
+  * @num_bits: Storage for the number of public exponent bits
+  */
+ static int num_public_exponent_bits(const struct rsa_public_key *key,
+               int *num_bits)
+ {
+       uint64_t exponent;
+       int exponent_bits;
+       const uint max_bits = (sizeof(exponent) * 8);
+       exponent = key->exponent;
+       exponent_bits = 0;
+       if (!exponent) {
+               *num_bits = exponent_bits;
+               return 0;
+       }
+       for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits)
+               if (!(exponent >>= 1)) {
+                       *num_bits = exponent_bits;
+                       return 0;
+               }
+       return -EINVAL;
+ }
+ /**
+  * is_public_exponent_bit_set() - Check if a bit in the public exponent is set
+  *
+  * @key:      RSA key
+  * @pos:      The bit position to check
+  */
+ static int is_public_exponent_bit_set(const struct rsa_public_key *key,
+               int pos)
+ {
+       return key->exponent & (1ULL << pos);
+ }
  /**
   * pow_mod() - in-place public exponentiation
   *
Simple merge