From: Michal Simek Date: Mon, 7 Dec 2015 10:22:14 +0000 (+0100) Subject: Merge tag 'v2015.10' into xilinx/master X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c599e302d8ac66841dbd6e4722f7d96353a12d38;p=thirdparty%2Fu-boot.git Merge tag 'v2015.10' into xilinx/master Prepare v2015.10 - Fix defconfig - Fix qspi support for cc108 - Enable NET_RANDOM_ETHADDR for mainline boards - Fix USB GADGET and LTHOR macros Signed-off-by: Michal Simek --- c599e302d8ac66841dbd6e4722f7d96353a12d38 diff --cc Makefile index 843e81a082f,fd060241042..b2c70d4393f mode 100755,100644..100755 --- a/Makefile +++ b/Makefile diff --cc arch/arm/dts/Makefile index 20a43b4e000,65b42308f2c..bc730c637db --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@@ -55,13 -60,7 +67,13 @@@ dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.d zynq-zc770-xm011.dtb \ zynq-zc770-xm012.dtb \ zynq-zc770-xm013.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-ep108.dtb \ + zynqmp-zcu102.dtb \ + zynqmp-zc1751-xm015-dc1.dtb \ + zynqmp-zc1751-xm016-dc2.dtb \ + zynqmp-zc1751-xm019-dc5.dtb \ + zynqmp-mini-qspi.dtb - dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb + dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb am335x-evm.dtb dtb-$(CONFIG_ARCH_SOCFPGA) += \ socfpga_arria5_socdk.dtb \ diff --cc common/board_f.c index 53661e33cb9,613332e1dc3..6757d7acde9 --- a/common/board_f.c +++ b/common/board_f.c @@@ -652,8 -655,10 +655,10 @@@ static int setup_dram_config(void return 0; } -static int reloc_fdt(void) +static int __maybe_unused reloc_fdt(void) { + if (gd->flags & GD_FLG_SKIP_RELOC) + return 0; if (gd->new_fdt) { memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size); gd->fdt_blob = gd->new_fdt; diff --cc configs/xilinx_zynqmp_ep_defconfig index 19316540b24,770c797ffd8..e27beb18e1d --- a/configs/xilinx_zynqmp_ep_defconfig +++ b/configs/xilinx_zynqmp_ep_defconfig @@@ -1,16 -1,22 +1,22 @@@ CONFIG_ARM=y CONFIG_ARCH_ZYNQMP=y - CONFIG_ZYNQMP_QSPI=y - CONFIG_NAND_ARASAN=y CONFIG_ZYNQMP_USB=y CONFIG_SYS_TEXT_BASE=0x8000000 -CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep" +CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep108" - CONFIG_FIT=y - CONFIG_FIT_VERBOSE=y + CONFIG_SYS_PROMPT="ZynqMP> " + # CONFIG_CMD_CONSOLE is not set # CONFIG_CMD_IMLS is not set - # CONFIG_CMD_FLASH is not set + # CONFIG_CMD_XIMG is not set + # CONFIG_CMD_EDITENV is not set + # CONFIG_CMD_ENV_EXISTS is not set + # CONFIG_CMD_LOADB is not set + # CONFIG_CMD_LOADS is not set + # CONFIG_CMD_FPGA is not set + # CONFIG_CMD_ITEST is not set + # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TFTPPUT=y CONFIG_CMD_DHCP=y + # CONFIG_CMD_NFS is not set CONFIG_CMD_PING=y CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y diff --cc configs/zynq_cc108_defconfig index badc792058e,00000000000..3c4ace3be49 mode 100644,000000..100644 --- a/configs/zynq_cc108_defconfig +++ b/configs/zynq_cc108_defconfig @@@ -1,7 -1,0 +1,9 @@@ +CONFIG_ARM=y +CONFIG_ARCH_ZYNQ=y +CONFIG_TARGET_ZYNQ_CC108=y +CONFIG_DEFAULT_DEVICE_TREE="zynq-cc108" +CONFIG_SPL=y +# CONFIG_CMD_IMLS is not set +CONFIG_OF_EMBED=y ++CONFIG_SPI_FLASH=y ++CONFIG_SPI_FLASH_BAR=y diff --cc configs/zynq_cse_qspi_defconfig index fb8cdd6073e,00000000000..14b90292da5 mode 100644,000000..100644 --- a/configs/zynq_cse_qspi_defconfig +++ b/configs/zynq_cse_qspi_defconfig @@@ -1,35 -1,0 +1,35 @@@ +CONFIG_ARM=y +CONFIG_ARCH_ZYNQ=y +CONFIG_TARGET_ZYNQ_CSE=y +CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-qspi" +CONFIG_SYS_EXTRA_OPTIONS="CSE_QSPI" ++# CONFIG_CMD_BDI is not set ++# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_GO is not set - # CONFIG_CMD_BDI is not set - # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_RUN is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_SAVEENV is not set +# CONFIG_CMD_ENV_EXISTS is not set +# CONFIG_CMD_CRC32 is not set +# CONFIG_CMD_DM is not set +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_CMD_ECHO is not set +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SOURCE is not set +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NET is not set +# CONFIG_CMD_NFS is not set +# CONFIG_CMD_MISC is not set +CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --cc configs/zynq_zc702_defconfig index b435dfb3330,8a388f36d21..13b2ac93f82 --- a/configs/zynq_zc702_defconfig +++ b/configs/zynq_zc702_defconfig @@@ -8,7 -7,7 +7,8 @@@ CONFIG_FIT= CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_IMLS is not set -# CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y + CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --cc configs/zynq_zc706_defconfig index af9bc6192db,f1009eebd30..2e61341f348 --- a/configs/zynq_zc706_defconfig +++ b/configs/zynq_zc706_defconfig @@@ -11,5 -11,4 +11,6 @@@ CONFIG_FIT_SIGNATURE= # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y + CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --cc configs/zynq_zc770_xm010_RSA_defconfig index dd02d8cf4f2,00000000000..4942ad44476 mode 100644,000000..100644 --- a/configs/zynq_zc770_xm010_RSA_defconfig +++ b/configs/zynq_zc770_xm010_RSA_defconfig @@@ -1,17 -1,0 +1,17 @@@ +CONFIG_ARM=y +CONFIG_ARCH_ZYNQ=y ++# CONFIG_SYS_MALLOC_F is not set +CONFIG_TARGET_ZYNQ_ZC770=y +CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010" - # CONFIG_SYS_MALLOC_F is not set +CONFIG_SPL=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y +CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010" +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_ZYNQ_RSA=y +CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --cc configs/zynq_zc770_xm010_defconfig index 5136b172b0c,cafbb0991c5..480fe32aff2 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@@ -12,6 -12,5 +12,7 @@@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010 # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y + CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_ZYNQ_SPI=y diff --cc configs/zynq_zc770_xm012_RSA_defconfig index b5fb79c4267,00000000000..28ebbe8f983 mode 100644,000000..100644 --- a/configs/zynq_zc770_xm012_RSA_defconfig +++ b/configs/zynq_zc770_xm012_RSA_defconfig @@@ -1,14 -1,0 +1,14 @@@ +CONFIG_ARM=y +CONFIG_ARCH_ZYNQ=y ++# CONFIG_SYS_MALLOC_F is not set +CONFIG_TARGET_ZYNQ_ZC770=y +CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012" - # CONFIG_SYS_MALLOC_F is not set +CONFIG_SPL=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y +CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012" +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_ZYNQ_RSA=y +CONFIG_OF_EMBED=y diff --cc configs/zynq_zc770_xm012_defconfig index c7e3307dde1,9a440097f48..e0af6bebc29 --- a/configs/zynq_zc770_xm012_defconfig +++ b/configs/zynq_zc770_xm012_defconfig @@@ -8,6 -8,6 +8,7 @@@ CONFIG_FIT= CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012" +# CONFIG_CMD_IMLS is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y + CONFIG_NET_RANDOM_ETHADDR=y diff --cc configs/zynq_zc770_xm013_RSA_defconfig index 8f65f717db4,00000000000..482b110cdaf mode 100644,000000..100644 --- a/configs/zynq_zc770_xm013_RSA_defconfig +++ b/configs/zynq_zc770_xm013_RSA_defconfig @@@ -1,17 -1,0 +1,17 @@@ +CONFIG_ARM=y +CONFIG_ARCH_ZYNQ=y ++# CONFIG_SYS_MALLOC_F is not set +CONFIG_TARGET_ZYNQ_ZC770=y +CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013" - # CONFIG_SYS_MALLOC_F is not set +CONFIG_SPL=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y +CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013" +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_ZYNQ_RSA=y +CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --cc configs/zynq_zc770_xm013_defconfig index bb7e10ed4b0,95e32a525c4..80dd25d2071 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@@ -12,5 -12,4 +12,6 @@@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013 # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y + CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --cc configs/zynq_zed_RSA_defconfig index d0c2949f601,6465040698a..d704c85378c --- a/configs/zynq_zed_RSA_defconfig +++ b/configs/zynq_zed_RSA_defconfig @@@ -1,8 -1,8 +1,8 @@@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y + # CONFIG_SYS_MALLOC_F is not set -CONFIG_TARGET_ZYNQ_ZC70X=y -CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" +CONFIG_TARGET_ZYNQ_ZED=y +CONFIG_DEFAULT_DEVICE_TREE="zynq-zed" - # CONFIG_SYS_MALLOC_F is not set CONFIG_SPL=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --cc configs/zynq_zed_defconfig index e575096c355,43520d0fff6..4f5eb30c3cf --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@@ -11,5 -11,4 +11,6 @@@ CONFIG_FIT_SIGNATURE= # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y + CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --cc drivers/net/phy/ti.c index 2b60a1ba3ec,00000000000..a3956304d09 mode 100644,000000..100644 --- a/drivers/net/phy/ti.c +++ b/drivers/net/phy/ti.c @@@ -1,208 -1,0 +1,205 @@@ +/* + * TI PHY drivers + * + * SPDX-License-Identifier: GPL-2.0 + * + */ +#include +#include + +/* TI DP83867 */ +#define DP83867_DEVADDR 0x1f + +#define MII_DP83867_PHYCTRL 0x10 +#define MII_DP83867_MICR 0x12 +#define DP83867_CTRL 0x1f + +/* Extended Registers */ +#define DP83867_RGMIICTL 0x0032 +#define DP83867_RGMIIDCTL 0x0086 + - /* FIXME this is consolidated in the latest U-Boot version */ - #define BIT(x) (1UL << (x)) - +#define DP83867_SW_RESET (1 << 15) +#define DP83867_SW_RESTART (1 << 14) + +/* MICR Interrupt bits */ +#define MII_DP83867_MICR_AN_ERR_INT_EN BIT(15) +#define MII_DP83867_MICR_SPEED_CHNG_INT_EN BIT(14) +#define MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN BIT(13) +#define MII_DP83867_MICR_PAGE_RXD_INT_EN BIT(12) +#define MII_DP83867_MICR_AUTONEG_COMP_INT_EN BIT(11) +#define MII_DP83867_MICR_LINK_STS_CHNG_INT_EN BIT(10) +#define MII_DP83867_MICR_FALSE_CARRIER_INT_EN BIT(8) +#define MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4) +#define MII_DP83867_MICR_WOL_INT_EN BIT(3) +#define MII_DP83867_MICR_XGMII_ERR_INT_EN BIT(2) +#define MII_DP83867_MICR_POL_CHNG_INT_EN BIT(1) +#define MII_DP83867_MICR_JABBER_INT_EN BIT(0) + +/* RGMIICTL bits */ +#define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1) +#define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0) + +/* PHY CTRL bits */ +#define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14 +#define DP83867_MDI_CROSSOVER 5 +#define DP83867_MDI_CROSSOVER_AUTO 0b10 + +/* RGMIIDCTL bits */ +#define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4 + +#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */ +#define MII_MMD_DATA 0x0e /* MMD Access Data Register */ + +/* MMD Access Control register fields */ +#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/ +#define MII_MMD_CTRL_ADDR 0x0000 /* Address */ +#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */ +#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */ +#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */ + +/* FIXME: These indirect PHY writes should go into common code. */ + +/** + * phy_read_mmd_indirect - reads data from the MMD registers + * @phydev: The PHY device bus + * @prtad: MMD Address + * @devad: MMD DEVAD + * @addr: PHY address on the MII bus + * + * Description: it reads data from the MMD registers (clause 22 to access to + * clause 45) of the specified phy address. + * To read these register we have: + * 1) Write reg 13 // DEVAD + * 2) Write reg 14 // MMD Address + * 3) Write reg 13 // MMD Data Command for MMD DEVAD + * 3) Read reg 14 // Read MMD data + */ +int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, + int devad, int addr) +{ + int value = -1; + + /* Write the desired MMD Devad */ + phy_write(phydev, addr, MII_MMD_CTRL, devad); + + /* Write the desired MMD register address */ + phy_write(phydev, addr, MII_MMD_DATA, prtad); + + /* Select the Function : DATA with no post increment */ + phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); + + /* Read the content of the MMD's selected register */ + value = phy_read(phydev, addr, MII_MMD_DATA); + return value; +} + +/** + * phy_write_mmd_indirect - writes data to the MMD registers + * @phydev: The PHY device + * @prtad: MMD Address + * @devad: MMD DEVAD + * @addr: PHY address on the MII bus + * @data: data to write in the MMD register + * + * Description: Write data from the MMD registers of the specified + * phy address. + * To write these register we have: + * 1) Write reg 13 // DEVAD + * 2) Write reg 14 // MMD Address + * 3) Write reg 13 // MMD Data Command for MMD DEVAD + * 3) Write reg 14 // Write MMD data + */ +void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, + int devad, int addr, u32 data) +{ + /* Write the desired MMD Devad */ + phy_write(phydev, addr, MII_MMD_CTRL, devad); + + /* Write the desired MMD register address */ + phy_write(phydev, addr, MII_MMD_DATA, prtad); + + /* Select the Function : DATA with no post increment */ + phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); + + /* Write the data into MMD's selected register */ + phy_write(phydev, addr, MII_MMD_DATA, data); +} + +/** + * phy_interface_is_rgmii - Convenience function for testing if a PHY interface + * is RGMII (all variants) + * @phydev: the phy_device struct + */ +static inline bool phy_interface_is_rgmii(struct phy_device *phydev) +{ + return phydev->interface >= PHY_INTERFACE_MODE_RGMII && + phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID; +} + +/* User setting - can be taken from DTS */ +#define RX_ID_DELAY 8 +#define TX_ID_DELAY 0xa +#define FIFO_DEPTH 1 + +static int dp83867_config(struct phy_device *phydev) +{ + unsigned int val, delay; + int ret; + + /* Restart the PHY. */ + val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL); + phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL, + val | DP83867_SW_RESTART); + + if (phy_interface_is_rgmii(phydev)) { + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL, + (DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) | + (FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT)); + if (ret) + return ret; + } + + if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && + (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { + val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, + DP83867_DEVADDR, phydev->addr); + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + val |= (DP83867_RGMII_TX_CLK_DELAY_EN | + DP83867_RGMII_RX_CLK_DELAY_EN); + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + val |= DP83867_RGMII_TX_CLK_DELAY_EN; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + val |= DP83867_RGMII_RX_CLK_DELAY_EN; + + phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, + DP83867_DEVADDR, phydev->addr, val); + + delay = (RX_ID_DELAY | + (TX_ID_DELAY << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); + + phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL, + DP83867_DEVADDR, phydev->addr, delay); + } + + genphy_config_aneg(phydev); + return 0; +} + +static struct phy_driver DP83867_driver = { + .name = "TI DP83867", + .uid = 0x2000a231, + .mask = 0xfffffff0, + .features = PHY_GBIT_FEATURES, + .config = &dp83867_config, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +int phy_ti_init(void) +{ + phy_register(&DP83867_driver); + return 0; +} diff --cc drivers/spi/zynqmp_qspi.c index bca107b9f09,00000000000..ca1be911025 mode 100644,000000..100644 --- a/drivers/spi/zynqmp_qspi.c +++ b/drivers/spi/zynqmp_qspi.c @@@ -1,762 -1,0 +1,763 @@@ +/* + * (C) Copyright 2014 - 2015 Xilinx + * + * Xilinx ZynqMP Quad-SPI(QSPI) controller driver (master mode only) + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include ++#include +#include +#include +#include +#include +#include +#include +#include +#include "../mtd/spi/sf_internal.h" + +#define ZYNQMP_QSPI_GFIFO_STRT_MODE_MASK (1 << 29) +#define ZYNQMP_QSPI_CONFIG_MODE_EN_MASK (3 << 30) +#define ZYNQMP_QSPI_CONFIG_DMA_MODE (2 << 30) +#define ZYNQMP_QSPI_CONFIG_CPHA_MASK (1 << 2) +#define ZYNQMP_QSPI_CONFIG_CPOL_MASK (1 << 1) + +/* QSPI MIO's count for different connection topologies */ +#define ZYNQMP_QSPI_MIO_NUM_QSPI0 6 +#define ZYNQMP_QSPI_MIO_NUM_QSPI1 5 +#define ZYNQMP_QSPI_MIO_NUM_QSPI1_CS 1 + +/* + * QSPI Interrupt Registers bit Masks + * + * All the four interrupt registers (Status/Mask/Enable/Disable) have the same + * bit definitions. + */ +#define ZYNQMP_QSPI_IXR_TXNFULL_MASK 0x00000004 /* QSPI TX FIFO Overflow */ +#define ZYNQMP_QSPI_IXR_TXFULL_MASK 0x00000008 /* QSPI TX FIFO is full */ +#define ZYNQMP_QSPI_IXR_RXNEMTY_MASK 0x00000010 /* QSPI RX FIFO Not Empty */ +#define ZYNQMP_QSPI_IXR_GFEMTY_MASK 0x00000080 /* QSPI Generic FIFO Empty */ +#define ZYNQMP_QSPI_IXR_ALL_MASK (ZYNQMP_QSPI_IXR_TXNFULL_MASK | \ + ZYNQMP_QSPI_IXR_RXNEMTY_MASK) + +/* + * QSPI Enable Register bit Masks + * + * This register is used to enable or disable the QSPI controller + */ +#define ZYNQMP_QSPI_ENABLE_ENABLE_MASK 0x00000001 /* QSPI Enable Bit Mask */ + +#define ZYNQMP_QSPI_GFIFO_LOW_BUS (1 << 14) +#define ZYNQMP_QSPI_GFIFO_CS_LOWER (1 << 12) +#define ZYNQMP_QSPI_GFIFO_UP_BUS (1 << 15) +#define ZYNQMP_QSPI_GFIFO_CS_UPPER (1 << 13) +#define ZYNQMP_QSPI_SPI_MODE_QSPI (3 << 10) +#define ZYNQMP_QSPI_SPI_MODE_SPI (1 << 10) +#define ZYNQMP_QSPI_IMD_DATA_CS_ASSERT 5 +#define ZYNQMP_QSPI_IMD_DATA_CS_DEASSERT 5 +#define ZYNQMP_QSPI_GFIFO_TX (1 << 16) +#define ZYNQMP_QSPI_GFIFO_RX (1 << 17) +#define ZYNQMP_QSPI_GFIFO_STRIPE_MASK (1 << 18) +#define ZYNQMP_QSPI_GFIFO_IMD_MASK 0xFF +#define ZYNQMP_QSPI_GFIFO_EXP_MASK (1 << 9) +#define ZYNQMP_QSPI_GFIFO_DATA_XFR_MASK (1 << 8) +#define ZYNQMP_QSPI_STRT_GEN_FIFO (1 << 28) +#define ZYNQMP_QSPI_GEN_FIFO_STRT_MOD (1 << 29) +#define ZYNQMP_QSPI_GFIFO_WP_HOLD (1 << 19) +#define ZYNQMP_QSPI_BAUD_DIV_MASK (7 << 3) +#define ZYNQMP_QSPI_DFLT_BAUD_RATE_DIV (1 << 3) +#define ZYNQMP_QSPI_GFIFO_ALL_INT_MASK 0xFBE +#define ZYNQMP_QSPI_DMA_DST_I_STS_DONE (1 << 1) +#define ZYNQMP_QSPI_DMA_DST_I_STS_MASK 0xFE +#define MODEBITS 0x6 + +#define QUAD_OUT_READ_CMD 0x6B +#define QUAD_PAGE_PROGRAM_CMD 0x32 + +#define ZYNQMP_QSPI_GFIFO_SELECT (1 << 0) + +#define ZYNQMP_QSPI_FIFO_THRESHOLD 1 + +#define SPI_XFER_ON_BOTH 0 +#define SPI_XFER_ON_LOWER 1 +#define SPI_XFER_ON_UPPER 2 + +#define ZYNQMP_QSPI_DMA_ALIGN 0x4 + +/* QSPI register offsets */ +struct zynqmp_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; /* 0x34 */ + u32 lpbkdly; /* 0x38 */ + u32 reserved1; /* 0x3C */ + u32 genfifo; /* 0x40 */ + u32 gqspisel; /* 0x44 */ + u32 reserved2; /* 0x48 */ + u32 gqfifoctrl; /* 0x4C */ + u32 gqfthr; /* 0x50 */ + u32 gqpollcfg; /* 0x54 */ + u32 gqpollto; /* 0x58 */ + u32 gqxfersts; /* 0x5C */ + u32 gqfifosnap; /* 0x60 */ + u32 gqrxcpy; /* 0x64 */ +}; + +struct zynqmp_qspi_dma_regs { + u32 dmadst; /* 0x00 */ + u32 dmasize; /* 0x04 */ + u32 dmasts; /* 0x08 */ + u32 dmactrl; /* 0x0C */ + u32 reserved0; /* 0x10 */ + u32 dmaisr; /* 0x14 */ + u32 dmaier; /* 0x18 */ + u32 dmaidr; /* 0x1C */ + u32 dmaimr; /* 0x20 */ + u32 dmactrl2; /* 0x24 */ + u32 dmadstmsb; /* 0x28 */ +}; + +struct zynqmp_qspi_platdata { + struct zynqmp_qspi_regs *regs; + struct zynqmp_qspi_dma_regs *dma_regs; + u32 frequency; + u32 speed_hz; +}; + +struct zynqmp_qspi_priv { + struct zynqmp_qspi_regs *regs; + struct zynqmp_qspi_dma_regs *dma_regs; + u8 mode; + u32 freq; + const void *tx_buf; + void *rx_buf; + unsigned len; + int bytes_to_transfer; + int bytes_to_receive; + unsigned int is_inst; + unsigned int is_dual; + unsigned int u_page; + unsigned int bus; + unsigned int stripe; + unsigned cs_change:1; +}; + +static u8 last_cmd; + +static int zynqmp_qspi_ofdata_to_platdata(struct udevice *bus) +{ + struct zynqmp_qspi_platdata *plat = bus->platdata; + + debug("%s\n", __func__); + plat->regs = (struct zynqmp_qspi_regs *)(ZYNQMP_QSPI_BASEADDR + 0x100); + plat->dma_regs = (struct zynqmp_qspi_dma_regs *)(ZYNQMP_QSPI_BASEADDR + + 0x800); + plat->frequency = 166666666; + plat->speed_hz = plat->frequency / 2; + + return 0; +} + +static void zynqmp_qspi_init_hw(struct zynqmp_qspi_priv *priv) +{ + u32 config_reg; + struct zynqmp_qspi_regs *regs = priv->regs; + + writel(ZYNQMP_QSPI_GFIFO_SELECT, ®s->gqspisel); + writel(ZYNQMP_QSPI_GFIFO_ALL_INT_MASK, ®s->idisr); + writel(ZYNQMP_QSPI_FIFO_THRESHOLD, ®s->txftr); + writel(ZYNQMP_QSPI_FIFO_THRESHOLD, ®s->rxftr); + writel(ZYNQMP_QSPI_GFIFO_ALL_INT_MASK, ®s->isr); + + config_reg = readl(®s->confr); + config_reg &= ~(ZYNQMP_QSPI_GFIFO_STRT_MODE_MASK | + ZYNQMP_QSPI_CONFIG_MODE_EN_MASK); + config_reg |= ZYNQMP_QSPI_CONFIG_DMA_MODE | + ZYNQMP_QSPI_GFIFO_WP_HOLD | + ZYNQMP_QSPI_DFLT_BAUD_RATE_DIV; + writel(config_reg, ®s->confr); + + writel(ZYNQMP_QSPI_ENABLE_ENABLE_MASK, ®s->enbr); +} + +static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv *priv) +{ + u32 gqspi_fifo_reg = 0; + + if (priv->is_dual == SF_DUAL_PARALLEL_FLASH) { + if (priv->bus == SPI_XFER_ON_BOTH) + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_LOW_BUS | + ZYNQMP_QSPI_GFIFO_UP_BUS | + ZYNQMP_QSPI_GFIFO_CS_UPPER | + ZYNQMP_QSPI_GFIFO_CS_LOWER; + else if (priv->bus == SPI_XFER_ON_LOWER) + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_LOW_BUS | + ZYNQMP_QSPI_GFIFO_CS_UPPER | + ZYNQMP_QSPI_GFIFO_CS_LOWER; + else if (priv->bus == SPI_XFER_ON_UPPER) + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_UP_BUS | + ZYNQMP_QSPI_GFIFO_CS_LOWER | + ZYNQMP_QSPI_GFIFO_CS_UPPER; + else + debug("Wrong Bus selection:0x%x\n", priv->bus); + } else { + if (priv->u_page) + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_LOW_BUS | + ZYNQMP_QSPI_GFIFO_CS_UPPER; + else + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_LOW_BUS | + ZYNQMP_QSPI_GFIFO_CS_LOWER; + } + return gqspi_fifo_reg; +} + +static void zynqmp_qspi_fill_gen_fifo(struct zynqmp_qspi_priv *priv, + u32 gqspi_fifo_reg) +{ + struct zynqmp_qspi_regs *regs = priv->regs; + u32 reg; + + do { + reg = readl(®s->isr); + } while (!(reg & ZYNQMP_QSPI_IXR_GFEMTY_MASK)); + + writel(gqspi_fifo_reg, ®s->genfifo); +} + +static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv *priv, int is_on) +{ + u32 gqspi_fifo_reg = 0; + + if (is_on) { + gqspi_fifo_reg = zynqmp_qspi_bus_select(priv); + gqspi_fifo_reg |= ZYNQMP_QSPI_SPI_MODE_SPI | + ZYNQMP_QSPI_IMD_DATA_CS_ASSERT; + } else { + if (priv->is_dual == SF_DUAL_PARALLEL_FLASH) + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_UP_BUS | + ZYNQMP_QSPI_GFIFO_LOW_BUS; + else if (priv->u_page) + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_UP_BUS; + else + gqspi_fifo_reg = ZYNQMP_QSPI_GFIFO_LOW_BUS; + gqspi_fifo_reg |= ZYNQMP_QSPI_IMD_DATA_CS_DEASSERT; + } + + debug("GFIFO_CMD_CS: 0x%x\n", gqspi_fifo_reg); + + zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg); +} + +static int zynqmp_qspi_set_speed(struct udevice *bus, uint speed) +{ + struct zynqmp_qspi_platdata *plat = bus->platdata; + struct zynqmp_qspi_priv *priv = dev_get_priv(bus); + struct zynqmp_qspi_regs *regs = priv->regs; + uint32_t confr; + u8 baud_rate_val = 0; + + debug("%s\n", __func__); + if (speed > plat->frequency) + speed = plat->frequency; + + /* Set the clock frequency */ + confr = readl(®s->confr); + if (speed == 0) { + /* Set baudrate x8, if the freq is 0 */ + baud_rate_val = 0x2; + } else if (plat->speed_hz != speed) { + while ((baud_rate_val < 8) && + ((plat->frequency / + (2 << baud_rate_val)) > speed)) + baud_rate_val++; + + plat->speed_hz = speed / (2 << baud_rate_val); + } + confr &= ~ZYNQMP_QSPI_BAUD_DIV_MASK; + confr |= (baud_rate_val << 3); + writel(confr, ®s->confr); + + priv->freq = speed; + + debug("regs=%p, mode=%d\n", priv->regs, priv->freq); + + return 0; +} + +static int zynqmp_qspi_child_pre_probe(struct udevice *bus) +{ + struct spi_slave *slave = dev_get_parentdata(bus); + struct zynqmp_qspi_priv *priv = dev_get_priv(bus->parent); + + slave->option = priv->is_dual; + slave->op_mode_rx = SPI_OPM_RX_QOF; + slave->op_mode_tx = SPI_OPM_TX_QPP; + slave->bytemode = SPI_4BYTE_MODE; + + return 0; +} + +static void zynqmp_qspi_check_is_dual_flash(struct zynqmp_qspi_priv *priv) +{ + int lower_mio = 0, upper_mio = 0, upper_mio_cs1 = 0; + + lower_mio = zynq_slcr_get_mio_pin_status("qspi0"); + if (lower_mio == ZYNQMP_QSPI_MIO_NUM_QSPI0) + priv->is_dual = SF_SINGLE_FLASH; + + upper_mio_cs1 = zynq_slcr_get_mio_pin_status("qspi1_cs"); + if ((lower_mio == ZYNQMP_QSPI_MIO_NUM_QSPI0) && + (upper_mio_cs1 == ZYNQMP_QSPI_MIO_NUM_QSPI1_CS)) + priv->is_dual = SF_DUAL_STACKED_FLASH; + + upper_mio = zynq_slcr_get_mio_pin_status("qspi1"); + if ((lower_mio == ZYNQMP_QSPI_MIO_NUM_QSPI0) && + (upper_mio_cs1 == ZYNQMP_QSPI_MIO_NUM_QSPI1_CS) && + (upper_mio == ZYNQMP_QSPI_MIO_NUM_QSPI1)) + priv->is_dual = SF_DUAL_PARALLEL_FLASH; +} + +static int zynqmp_qspi_probe(struct udevice *bus) +{ + struct zynqmp_qspi_platdata *plat = dev_get_platdata(bus); + struct zynqmp_qspi_priv *priv = dev_get_priv(bus); + + debug("zynqmp_qspi_probe: bus:%p, priv:%p \n", bus, priv); + + priv->regs = plat->regs; + priv->dma_regs = plat->dma_regs; + zynqmp_qspi_check_is_dual_flash(priv); + + if (priv->is_dual == -1) { + debug("%s: No QSPI device detected based on MIO settings\n", + __func__); + return -1; + } + + /* init the zynq spi hw */ + zynqmp_qspi_init_hw(priv); + + return 0; +} + +static int zynqmp_qspi_set_mode(struct udevice *bus, uint mode) +{ + struct zynqmp_qspi_priv *priv = dev_get_priv(bus); + struct zynqmp_qspi_regs *regs = priv->regs; + uint32_t confr; + + debug("%s\n", __func__); + /* Set the SPI Clock phase and polarities */ + confr = readl(®s->confr); + confr &= ~(ZYNQMP_QSPI_CONFIG_CPHA_MASK | + ZYNQMP_QSPI_CONFIG_CPOL_MASK); + + if (priv->mode & SPI_CPHA) + confr |= ZYNQMP_QSPI_CONFIG_CPHA_MASK; + if (priv->mode & SPI_CPOL) + confr |= ZYNQMP_QSPI_CONFIG_CPOL_MASK; + + //writel(confr, ®s->confr); + priv->mode = mode; + + debug("regs=%p, mode=%d\n", priv->regs, priv->mode); + + return 0; +} + + +static int zynqmp_qspi_fill_tx_fifo(struct zynqmp_qspi_priv *priv, u32 size) +{ + u32 data; + u32 timeout = 10000000; + struct zynqmp_qspi_regs *regs = priv->regs; + u32 *buf = (u32 *)priv->tx_buf; + + debug("TxFIFO: 0x%x, size: 0x%x\n", readl(®s->isr), + size); + + while (size && timeout) { + if (readl(®s->isr) & + ZYNQMP_QSPI_IXR_TXNFULL_MASK) { + if (size >= 4) { + writel(*buf, ®s->txd0r); + buf++; + size -= 4; + } else { + switch (size) { + case 1: + data = *((u8 *)buf); + buf += 1; + data |= 0xFFFFFF00; + break; + case 2: + data = *((u16 *)buf); + buf += 2; + data |= 0xFFFF0000; + break; + case 3: + data = *((u16 *)buf); + buf += 2; + data |= (*((u8 *)buf) << 16); + buf += 1; + data |= 0xFF000000; + break; + } + writel(data, ®s->txd0r); + size = 0; + } + } else { + timeout--; + } + } + if (!timeout) { + debug("zynqmp_qspi_fill_tx_fifo: Timeout\n"); + return -1; + } + + return 0; +} + +static void zynqmp_qspi_genfifo_cmd(struct zynqmp_qspi_priv *priv) +{ + u8 command = 1; + u32 gen_fifo_cmd; + u32 bytecount = 0; + + while (priv->len) { + gen_fifo_cmd = zynqmp_qspi_bus_select(priv); + gen_fifo_cmd |= ZYNQMP_QSPI_GFIFO_TX; + + if (command) { + command = 0; + last_cmd = *(u8 *)priv->tx_buf; + } + + gen_fifo_cmd |= ZYNQMP_QSPI_SPI_MODE_SPI; + gen_fifo_cmd |= *(u8 *)priv->tx_buf; + bytecount++; + priv->len--; + priv->tx_buf = (u8 *)priv->tx_buf + 1; + + debug("GFIFO_CMD_Cmd = 0x%x\n", gen_fifo_cmd); + + zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + } +} + +static u32 zynqmp_qspi_calc_exp(struct zynqmp_qspi_priv *priv, + u32 *gen_fifo_cmd) +{ + u32 expval = 8; + u32 len; + + while (1) { + if (priv->len > 255) { + if (priv->len & (1 << expval)) { + *gen_fifo_cmd &= ~ZYNQMP_QSPI_GFIFO_IMD_MASK; + *gen_fifo_cmd |= ZYNQMP_QSPI_GFIFO_EXP_MASK; + *gen_fifo_cmd |= expval; + priv->len -= (1 << expval); + return expval; + } + expval++; + } else { + *gen_fifo_cmd &= ~(ZYNQMP_QSPI_GFIFO_IMD_MASK | + ZYNQMP_QSPI_GFIFO_EXP_MASK); + *gen_fifo_cmd |= (u8)priv->len; + len = (u8)priv->len; + priv->len = 0; + return len; + } + } +} + +static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv) +{ + u32 gen_fifo_cmd; + u32 len; + int ret = 0; + + gen_fifo_cmd = zynqmp_qspi_bus_select(priv); + gen_fifo_cmd |= ZYNQMP_QSPI_GFIFO_TX | + ZYNQMP_QSPI_GFIFO_DATA_XFR_MASK; + + if (priv->stripe) + gen_fifo_cmd |= ZYNQMP_QSPI_GFIFO_STRIPE_MASK; + + if (last_cmd == QUAD_PAGE_PROGRAM_CMD) + gen_fifo_cmd |= ZYNQMP_QSPI_SPI_MODE_QSPI; + else + gen_fifo_cmd |= ZYNQMP_QSPI_SPI_MODE_SPI; + + while (priv->len) { + len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); + zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + + debug("GFIFO_CMD_TX:0x%x\n", gen_fifo_cmd); + + if (gen_fifo_cmd & ZYNQMP_QSPI_GFIFO_EXP_MASK) + ret = zynqmp_qspi_fill_tx_fifo(priv, + 1 << len); + else + ret = zynqmp_qspi_fill_tx_fifo(priv, + len); + + if (ret) + return ret; + } + return ret; +} + +static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, + u32 gen_fifo_cmd, u32 *buf) +{ + u32 addr; + u32 size, len; + u32 timeout = 10000000; + u32 actuallen = priv->len; + struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs; + + writel((unsigned long)buf, &dma_regs->dmadst); + writel(roundup(priv->len, 4), &dma_regs->dmasize); + writel(ZYNQMP_QSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); + addr = (unsigned long)buf; + size = roundup(priv->len, ARCH_DMA_MINALIGN); + flush_dcache_range(addr, addr+size); + + while (priv->len) { + len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); + if (!(gen_fifo_cmd & ZYNQMP_QSPI_GFIFO_EXP_MASK) && + (len % 4)) { + gen_fifo_cmd &= ~(0xFF); + gen_fifo_cmd |= (len/4 + 1) * 4; + } + zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + + debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd); + } + + while (timeout) { + if (readl(&dma_regs->dmaisr) & + ZYNQMP_QSPI_DMA_DST_I_STS_DONE) { + writel(ZYNQMP_QSPI_DMA_DST_I_STS_DONE, + &dma_regs->dmaisr); + break; + } + timeout--; + } + + debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", + (unsigned long)buf, (unsigned long)priv->rx_buf, *buf, + actuallen); + if (!timeout) { + debug("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr)); + return -1; + } + + if (buf != priv->rx_buf) + memcpy(priv->rx_buf, buf, actuallen); + + return 0; +} + +static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv) +{ + u32 gen_fifo_cmd; + u32 *buf; + u32 actuallen = priv->len; + + gen_fifo_cmd = zynqmp_qspi_bus_select(priv); + gen_fifo_cmd |= ZYNQMP_QSPI_GFIFO_RX | + ZYNQMP_QSPI_GFIFO_DATA_XFR_MASK; + + if (last_cmd == QUAD_OUT_READ_CMD) + gen_fifo_cmd |= ZYNQMP_QSPI_SPI_MODE_QSPI; + else + gen_fifo_cmd |= ZYNQMP_QSPI_SPI_MODE_SPI; + + if (priv->stripe) + gen_fifo_cmd |= ZYNQMP_QSPI_GFIFO_STRIPE_MASK; + + /* + * Check if receive buffer is aligned to 4 byte and length + * is multiples of four byte as we are using dma to receive. + */ + if (!((unsigned long)priv->rx_buf & (ZYNQMP_QSPI_DMA_ALIGN - 1)) && + !(actuallen % ZYNQMP_QSPI_DMA_ALIGN)) { + buf = (u32 *)priv->rx_buf; + return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); + } + + ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, + ZYNQMP_QSPI_DMA_ALIGN)); + buf = (u32 *)tmp; + return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); +} + +static int zynqmp_qspi_start_transfer(struct zynqmp_qspi_priv *priv) +{ + int ret = 0; + + if (priv->is_inst) { + if (priv->tx_buf) + zynqmp_qspi_genfifo_cmd(priv); + else + ret = -1; + } else { + if (priv->tx_buf) + ret = zynqmp_qspi_genfifo_fill_tx(priv); + else if (priv->rx_buf) + ret = zynqmp_qspi_genfifo_fill_rx(priv); + else + ret = -1; + } + return ret; +} + +static int zynqmp_qspi_transfer(struct zynqmp_qspi_priv *priv) +{ + static unsigned cs_change = 1; + int status = 0; + + debug("%s\n", __func__); + + while (1) { + /* Select the chip if required */ + if (cs_change) + zynqmp_qspi_chipselect(priv, 1); + + cs_change = priv->cs_change; + + if (!priv->tx_buf && !priv->rx_buf && priv->len) { + status = -1; + break; + } + + /* Request the transfer */ + if (priv->len) { + status = zynqmp_qspi_start_transfer(priv); + priv->is_inst = 0; + if (status < 0) + break; + } + + if (cs_change) + /* Deselect the chip */ + zynqmp_qspi_chipselect(priv, 0); + break; + } + + return status; +} + +static int zynqmp_qspi_claim_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct zynqmp_qspi_priv *priv = dev_get_priv(bus); + struct zynqmp_qspi_regs *regs = priv->regs; + + debug("%s\n", __func__); + writel(ZYNQMP_QSPI_ENABLE_ENABLE_MASK, ®s->enbr); + + return 0; +} + +static int zynqmp_qspi_release_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct zynqmp_qspi_priv *priv = dev_get_priv(bus); + struct zynqmp_qspi_regs *regs = priv->regs; + + debug("%s\n", __func__); + writel(~ZYNQMP_QSPI_ENABLE_ENABLE_MASK, ®s->enbr); + + return 0; +} + +int zynqmp_qspi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct udevice *bus = dev->parent; + struct zynqmp_qspi_priv *priv = dev_get_priv(bus); + + debug("%s: priv: 0x%08lx bitlen: %d dout: 0x%08lx ", __func__, + (unsigned long)priv, bitlen, (unsigned long)dout); + debug("din: 0x%08lx flags: 0x%lx\n", (unsigned long)din, flags); + + priv->tx_buf = dout; + priv->rx_buf = din; + priv->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) + priv->is_inst = 1; + else + priv->is_inst = 0; + + if (flags & SPI_XFER_END) + priv->cs_change = 1; + else + priv->cs_change = 0; + + if (flags & SPI_XFER_U_PAGE) + priv->u_page = 1; + else + priv->u_page = 0; + + priv->stripe = 0; + priv->bus = 0; + + if (priv->is_dual == SF_DUAL_PARALLEL_FLASH) { + if (flags & SPI_XFER_MASK) + priv->bus = (flags & SPI_XFER_MASK) >> 8; + if (flags & SPI_XFER_STRIPE) + priv->stripe = 1; + } + + zynqmp_qspi_transfer(priv); + + return 0; +} + +static const struct dm_spi_ops zynqmp_qspi_ops = { + .claim_bus = zynqmp_qspi_claim_bus, + .release_bus = zynqmp_qspi_release_bus, + .xfer = zynqmp_qspi_xfer, + .set_speed = zynqmp_qspi_set_speed, + .set_mode = zynqmp_qspi_set_mode, +}; + +static const struct udevice_id zynqmp_qspi_ids[] = { + { .compatible = "xlnx,zynqmp-qspi-1.0" }, + { } +}; + +U_BOOT_DRIVER(zynqmp_qspi) = { + .name = "zynqmp_qspi", + .id = UCLASS_SPI, + .of_match = zynqmp_qspi_ids, + .ops = &zynqmp_qspi_ops, + .ofdata_to_platdata = zynqmp_qspi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct zynqmp_qspi_platdata), + .priv_auto_alloc_size = sizeof(struct zynqmp_qspi_priv), + .probe = zynqmp_qspi_probe, + .child_pre_probe = zynqmp_qspi_child_pre_probe, +}; diff --cc include/configs/xilinx_zynqmp.h index d0f65e12364,da87188e84a..d53aa08cbb8 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@@ -142,38 -109,31 +142,39 @@@ #define CONFIG_SYS_LOAD_ADDR 0x8000000 #if defined(CONFIG_ZYNQMP_USB) -#define CONFIG_USB_DWC3 -#define CONFIG_USB_DWC3_GADGET - -#define CONFIG_USB_GADGET -#define CONFIG_USB_GADGET_DOWNLOAD -#define CONFIG_USB_GADGET_DUALSPEED -#define CONFIG_USB_GADGET_VBUS_DRAW 2 -#define CONFIG_USBDOWNLOAD_GADGET -#define CONFIG_SYS_DFU_DATA_BUF_SIZE 0x1800000 -#define DFU_DEFAULT_POLL_TIMEOUT 300 -#define CONFIG_USB_FUNCTION_DFU -#define CONFIG_DFU_RAM -#define CONFIG_G_DNL_VENDOR_NUM 0x03FD -#define CONFIG_G_DNL_PRODUCT_NUM 0x0300 -#define CONFIG_G_DNL_MANUFACTURER "Xilinx" -#define CONFIG_USB_CABLE_CHECK -#define CONFIG_CMD_DFU -#define CONFIG_CMD_THOR_DOWNLOAD -#define CONFIG_USB_FUNCTION_THOR -#define CONFIG_THOR_RESET_OFF -#define DFU_ALT_INFO_RAM \ +# define CONFIG_USB_XHCI_DWC3 +# define CONFIG_USB_XHCI +# define CONFIG_USB_MAX_CONTROLLER_COUNT 1 +# define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 +# define CONFIG_CMD_USB +# define CONFIG_USB_STORAGE +# define CONFIG_USB_XHCI_ZYNQMP + +# define CONFIG_USB_DWC3 +# define CONFIG_USB_DWC3_GADGET + +# define CONFIG_USB_GADGET +# define CONFIG_USB_GADGET_DUALSPEED +# define CONFIG_USB_GADGET_VBUS_DRAW 2 - # define CONFIG_USBDOWNLOAD_GADGET ++# define CONFIG_USB_GADGET_DOWNLOAD +# define CONFIG_SYS_DFU_DATA_BUF_SIZE 0x1800000 +# define DFU_DEFAULT_POLL_TIMEOUT 300 +# define CONFIG_DFU_FUNCTION +# define CONFIG_DFU_RAM +# define CONFIG_G_DNL_VENDOR_NUM 0x03FD +# define CONFIG_G_DNL_PRODUCT_NUM 0x0300 +# define CONFIG_G_DNL_MANUFACTURER "Xilinx" +# define CONFIG_USB_CABLE_CHECK +# define CONFIG_CMD_DFU +# define CONFIG_CMD_THOR_DOWNLOAD - # define CONFIG_THOR_FUNCTION +# define CONFIG_THOR_RESET_OFF ++# define CONFIG_USB_FUNCTION_DFU ++# define CONFIG_USB_FUNCTION_THOR +# define DFU_ALT_INFO_RAM \ "dfu_ram_info=" \ - "set dfu_alt_info " \ - "Image ram 0x200000 0x1800000\\\\;" \ - "system.dtb ram 0x7000000 0x40000\0" \ + "setenv dfu_alt_info " \ + "Image ram $kernel_addr $kernel_size\\\\;" \ + "system.dtb ram $fdt_addr $fdt_size\0" \ "dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \ "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" diff --cc include/configs/zynq-common.h index f55eed03131,e7ab50ad24c..7a9ac56802f --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@@ -135,8 -123,7 +135,8 @@@ # define CONFIG_USB_CABLE_CHECK # define CONFIG_CMD_DFU # define CONFIG_CMD_THOR_DOWNLOAD - # define CONFIG_THOR_FUNCTION +# define CONFIG_THOR_RESET_OFF + # define CONFIG_USB_FUNCTION_THOR # define DFU_ALT_INFO_RAM \ "dfu_ram_info=" \ "set dfu_alt_info " \ diff --cc include/configs/zynq_zc770.h index 1aac1cf1502,7a1b8729e5b..309f14e9a0f --- a/include/configs/zynq_zc770.h +++ b/include/configs/zynq_zc770.h @@@ -19,12 -19,11 +19,15 @@@ # define CONFIG_ZYNQ_GEM0 # define CONFIG_ZYNQ_GEM_PHY_ADDR0 7 # define CONFIG_ZYNQ_SDHCI0 -# define CONFIG_ZYNQ_SPI +# define CONFIG_ZYNQ_QSPI + +#elif defined(CONFIG_ZC770_XM011) +# define CONFIG_ZYNQ_SERIAL_UART1 +# define CONFIG_NAND_ZYNQ + #elif defined(CONFIG_ZC770_XM011) + # define CONFIG_ZYNQ_SERIAL_UART1 + #elif defined(CONFIG_ZC770_XM012) # define CONFIG_ZYNQ_SERIAL_UART1 # undef CONFIG_SYS_NO_FLASH diff --cc scripts/Makefile.spl index 08623f36c91,58442f150d8..e8ce88c6a18 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@@ -54,35 -54,11 +54,12 @@@ libs-$(HAVE_VENDOR_COMMON_LIB) += board libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/ libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/ - libs-$(CONFIG_SPL_DM) += drivers/core/ - libs-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/ - libs-$(CONFIG_SPL_GPIO_SUPPORT) += drivers/gpio/ - libs-$(CONFIG_SPL_MMC_SUPPORT) += drivers/mmc/ - libs-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += drivers/ddr/fsl/ - libs-$(CONFIG_SYS_MVEBU_DDR) += drivers/ddr/mvebu/ - libs-$(CONFIG_SPL_SERIAL_SUPPORT) += drivers/serial/ - libs-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += drivers/mtd/spi/ - libs-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/ + libs-y += drivers/ libs-y += fs/ +libs-$(CONFIG_SPL_FPGA_SUPPORT) += drivers/fpga/ libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/ - libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/ drivers/power/pmic/ - libs-$(CONFIG_SPL_MTD_SUPPORT) += drivers/mtd/ - libs-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/ - libs-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += drivers/misc/ - libs-$(CONFIG_SPL_ONENAND_SUPPORT) += drivers/mtd/onenand/ - libs-$(CONFIG_SPL_DMA_SUPPORT) += drivers/dma/ libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/ libs-$(CONFIG_SPL_NET_SUPPORT) += net/ - libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/ - libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/ - libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/net/phy/ - libs-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/ - libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/ - libs-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/ - libs-$(CONFIG_SPL_USB_HOST_SUPPORT) += drivers/usb/host/ - libs-$(CONFIG_OMAP_USB_PHY) += drivers/usb/phy/ - libs-$(CONFIG_SPL_SATA_SUPPORT) += drivers/block/ head-y := $(addprefix $(obj)/,$(head-y)) libs-y := $(addprefix $(obj)/,$(libs-y))