From: Siva Durga Prasad Paladugu Date: Mon, 3 Aug 2015 10:53:15 +0000 (+0530) Subject: spi: zynq_qspi: Move the zynq qspi driver to driver model X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=81ec69066b270c62a6468662314728cc8b7008f9;p=thirdparty%2Fu-boot.git spi: zynq_qspi: Move the zynq qspi driver to driver model Changes for the zynq qspi driver to support the SPI driver model framework. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- diff --git a/configs/zynq_afx_qspi_RSA_defconfig b/configs/zynq_afx_qspi_RSA_defconfig index 1aee4769161..c6aa8e9ab63 100644 --- a/configs/zynq_afx_qspi_RSA_defconfig +++ b/configs/zynq_afx_qspi_RSA_defconfig @@ -9,3 +9,5 @@ CONFIG_SYS_EXTRA_OPTIONS="AFX_QSPI" # CONFIG_CMD_IMLS is not set CONFIG_CMD_ZYNQ_RSA=y CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_afx_qspi_defconfig b/configs/zynq_afx_qspi_defconfig index 7d9d4cfcbd9..c367d490d02 100644 --- a/configs/zynq_afx_qspi_defconfig +++ b/configs/zynq_afx_qspi_defconfig @@ -5,3 +5,5 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-afx-qspi" CONFIG_SYS_EXTRA_OPTIONS="AFX_QSPI" # CONFIG_CMD_IMLS is not set CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig index 3957a671c7d..70c65c0fd7d 100644 --- a/configs/zynq_cse_qspi_defconfig +++ b/configs/zynq_cse_qspi_defconfig @@ -7,3 +7,5 @@ CONFIG_SYS_EXTRA_OPTIONS="CSE_QSPI" # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_GO is not set CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig index 936eec27f55..b435dfb3330 100644 --- a/configs/zynq_zc702_defconfig +++ b/configs/zynq_zc702_defconfig @@ -8,6 +8,7 @@ CONFIG_FIT=y 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_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_zc706_defconfig b/configs/zynq_zc706_defconfig index db11e6fe5b2..af9bc6192db 100644 --- a/configs/zynq_zc706_defconfig +++ b/configs/zynq_zc706_defconfig @@ -11,3 +11,5 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_zc70x_RSA_defconfig b/configs/zynq_zc70x_RSA_defconfig index 25813d2a1e0..35ff12b3db6 100644 --- a/configs/zynq_zc70x_RSA_defconfig +++ b/configs/zynq_zc70x_RSA_defconfig @@ -12,3 +12,5 @@ CONFIG_FIT_SIGNATURE=y # 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 --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig index abb02b1349f..571facf1f84 100644 --- a/configs/zynq_zc70x_defconfig +++ b/configs/zynq_zc70x_defconfig @@ -11,3 +11,5 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_zc770_xm010_RSA_defconfig b/configs/zynq_zc770_xm010_RSA_defconfig index db64432ddbb..dd02d8cf4f2 100644 --- a/configs/zynq_zc770_xm010_RSA_defconfig +++ b/configs/zynq_zc770_xm010_RSA_defconfig @@ -13,3 +13,5 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010" # 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 --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index 52511a759ae..e2f37fbe26c 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -13,3 +13,4 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010" # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_zc770_xm013_RSA_defconfig b/configs/zynq_zc770_xm013_RSA_defconfig index 6dbe02a894c..8f65f717db4 100644 --- a/configs/zynq_zc770_xm013_RSA_defconfig +++ b/configs/zynq_zc770_xm013_RSA_defconfig @@ -13,3 +13,5 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013" # 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 --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig index 8f10d325a50..bb7e10ed4b0 100644 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@ -12,3 +12,5 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013" # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/zynq_zed_RSA_defconfig b/configs/zynq_zed_RSA_defconfig index 4fe5df94ca9..d0c2949f601 100644 --- a/configs/zynq_zed_RSA_defconfig +++ b/configs/zynq_zed_RSA_defconfig @@ -12,3 +12,5 @@ CONFIG_FIT_SIGNATURE=y # 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 --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index 44885a17fe3..e575096c355 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -11,3 +11,5 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_OF_EMBED=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index aee898770b8..de9d752a5b6 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #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_BAUD_DIV_MASK (0x7 << 3) /* Baud rate div */ #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 */ @@ -120,44 +122,42 @@ struct zynq_qspi_regs { u32 midr; /* 0xFC */ }; -#define zynq_qspi_base ((struct zynq_qspi_regs *)ZYNQ_QSPI_BASEADDR) -struct zynq_qspi { - u32 input_clk_hz; +struct zynq_qspi_platdata { + struct zynq_qspi_regs *regs; + u32 frequency; /* input frequency */ u32 speed_hz; +// u32 is_dual; +}; + +struct zynq_qspi_priv { + struct zynq_qspi_regs *regs; + u8 mode; + u32 freq; const void *txbuf; void *rxbuf; + unsigned len; int bytes_to_transfer; int bytes_to_receive; unsigned int is_inst; unsigned int is_dual; - unsigned int is_dio; - unsigned int u_page; + unsigned int is_dio; + unsigned int u_page; + unsigned cs_change:1; }; -struct spi_device { - struct zynq_qspi master; - u32 max_speed_hz; - u8 chip_select; - u8 mode; - u8 bits_per_word; -}; +static int zynq_qspi_ofdata_to_platdata(struct udevice *bus) +{ + struct zynq_qspi_platdata *plat = bus->platdata; -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; -}; + debug("%s\n", __func__); + plat->regs = (struct zynq_qspi_regs *)ZYNQ_QSPI_BASEADDR; -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) + plat->frequency = 166666666; + plat->speed_hz = plat->frequency / 2; + + return 0; +} /* * zynq_qspi_init_hw - Initialize the hardware @@ -180,66 +180,222 @@ struct zynq_qspi_slave { * - 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) +static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv) { u32 config_reg; + struct zynq_qspi_regs *regs = priv->regs; - writel(~ZYNQ_QSPI_ENABLE_ENABLE_MASK, &zynq_qspi_base->enbr); - writel(0x7F, &zynq_qspi_base->idisr); + writel(~ZYNQ_QSPI_ENABLE_ENABLE_MASK, ®s->enbr); + writel(0x7F, ®s->idisr); /* Disable linear mode as the boot loader may have used it */ - writel(0x0, &zynq_qspi_base->lcr); + writel(0x0, ®s->lcr); /* Clear the TX and RX threshold reg */ - writel(0x1, &zynq_qspi_base->txftr); - writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, &zynq_qspi_base->rxftr); + writel(0x1, ®s->txftr); + writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, ®s->rxftr); /* Clear the RX FIFO */ - while (readl(&zynq_qspi_base->isr) & ZYNQ_QSPI_IXR_RXNEMTY_MASK) - readl(&zynq_qspi_base->drxr); + while (readl(®s->isr) & ZYNQ_QSPI_IXR_RXNEMTY_MASK) + readl(®s->drxr); + + debug("%s is_dual:0x%x, is_dio:0x%x\n", __func__, priv->is_dual, priv->is_dio); - writel(0x7F, &zynq_qspi_base->isr); - config_reg = readl(&zynq_qspi_base->confr); + writel(0x7F, ®s->isr); + config_reg = readl(®s->confr); config_reg &= ~ZYNQ_QSPI_CONFIG_MSA_MASK; 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) + if (priv->is_dual == SF_DUAL_STACKED_FLASH) config_reg |= 0x10; - writel(config_reg, &zynq_qspi_base->confr); + writel(config_reg, ®s->confr); - if (is_dual == SF_DUAL_PARALLEL_FLASH) { - if (is_dio == SF_DUALIO_FLASH) + if (priv->is_dual == SF_DUAL_PARALLEL_FLASH) { + if (priv->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); + ®s->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) + ®s->lcr); + } else if (priv->is_dual == SF_DUAL_STACKED_FLASH) { + if (priv->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); + ®s->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); + ®s->lcr); } - writel(ZYNQ_QSPI_ENABLE_ENABLE_MASK, &zynq_qspi_base->enbr); + writel(ZYNQ_QSPI_ENABLE_ENABLE_MASK, ®s->enbr); +} + +/* + * 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 void zynq_qspi_check_is_dual_flash(struct zynq_qspi_priv *priv) +{ + int lower_mio = 0, upper_mio = 0, upper_mio_cs1 = 0; + + priv->is_dual = -1; + priv->is_dio = 0; + lower_mio = zynq_slcr_get_mio_pin_status("qspi0"); + if (lower_mio == ZYNQ_QSPI_MIO_NUM_QSPI0) { + priv->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"); + priv->is_dio = SF_DUALIO_FLASH; + priv->is_dual = SF_SINGLE_FLASH; + } + } + + if (priv->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)) + priv->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)) + priv->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"); + priv->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"); + priv->is_dual = SF_DUAL_PARALLEL_FLASH; + } + } +} + +static int zynq_qspi_child_pre_probe(struct udevice *bus) +{ + struct spi_slave *slave = dev_get_parentdata(bus); + struct zynq_qspi_priv *priv = dev_get_priv(bus->parent); + + slave->option = priv->is_dual; + slave->dio = priv->is_dio; + slave->op_mode_rx = SPI_OPM_RX_QOF; + slave->op_mode_tx = SPI_OPM_TX_QPP; + + return 0; +} + +static int zynq_qspi_probe(struct udevice *bus) +{ + struct zynq_qspi_platdata *plat = dev_get_platdata(bus); + struct zynq_qspi_priv *priv = dev_get_priv(bus); + + debug("zynq_qspi_probe: bus:%p, priv:%p \n", bus, priv); + + priv->regs = plat->regs; + zynq_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 */ + zynq_qspi_init_hw(priv); + + return 0; +} + +static int zynq_qspi_set_speed(struct udevice *bus, uint speed) +{ + struct zynq_qspi_platdata *plat = bus->platdata; + struct zynq_qspi_priv *priv = dev_get_priv(bus); + struct zynq_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 &= ~ZYNQ_QSPI_CONFIG_BAUD_DIV_MASK; + confr |= (baud_rate_val << 3); + + writel(confr, ®s->confr); + priv->freq = speed; + + debug("zynq_spi_set_speed: regs=%p, mode=%d\n", priv->regs, priv->freq); + + return 0; +} + +static int zynq_qspi_set_mode(struct udevice *bus, uint mode) +{ + struct zynq_qspi_priv *priv = dev_get_priv(bus); + struct zynq_qspi_regs *regs = priv->regs; + uint32_t confr; + + debug("%s\n", __func__); + /* Set the SPI Clock phase and polarities */ + confr = readl(®s->confr); + confr &= ~(ZYNQ_QSPI_CONFIG_CPHA_MASK | ZYNQ_QSPI_CONFIG_CPOL_MASK); + + if (priv->mode & SPI_CPHA) + confr |= ZYNQ_QSPI_CONFIG_CPHA_MASK; + if (priv->mode & SPI_CPOL) + confr |= ZYNQ_QSPI_CONFIG_CPOL_MASK; + + writel(confr, ®s->confr); + priv->mode = mode; + + debug("zynq_spi_set_mode: regs=%p, mode=%d\n", priv->regs, priv->mode); + + return 0; } /* @@ -248,43 +404,43 @@ static void zynq_qspi_init_hw(int is_dual, int is_dio, unsigned int cs) * @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) +static void zynq_qspi_copy_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size) { u8 byte3; debug("%s: data 0x%04x rxbuf addr: 0x%08x size %d\n", __func__ , - data, (unsigned)(zqspi->rxbuf), size); + data, (unsigned)(priv->rxbuf), size); - if (zqspi->rxbuf) { + if (priv->rxbuf) { switch (size) { case 1: - *((u8 *)zqspi->rxbuf) = data; - zqspi->rxbuf += 1; + *((u8 *)priv->rxbuf) = data; + priv->rxbuf += 1; break; case 2: - *((u16 *)zqspi->rxbuf) = data; - zqspi->rxbuf += 2; + *((u16 *)priv->rxbuf) = data; + priv->rxbuf += 2; break; case 3: - *((u16 *)zqspi->rxbuf) = data; - zqspi->rxbuf += 2; + *((u16 *)priv->rxbuf) = data; + priv->rxbuf += 2; byte3 = (u8)(data >> 16); - *((u8 *)zqspi->rxbuf) = byte3; - zqspi->rxbuf += 1; + *((u8 *)priv->rxbuf) = byte3; + priv->rxbuf += 1; break; case 4: /* Can not assume word aligned buffer */ - memcpy(zqspi->rxbuf, &data, size); - zqspi->rxbuf += 4; + memcpy(priv->rxbuf, &data, size); + priv->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; + priv->bytes_to_receive -= size; + if (priv->bytes_to_receive < 0) + priv->bytes_to_receive = 0; } /* @@ -293,32 +449,32 @@ static void zynq_qspi_copy_read_data(struct zynq_qspi *zqspi, u32 data, u8 size) * @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, +static void zynq_qspi_copy_write_data(struct zynq_qspi_priv *priv, u32 *data, u8 size) { - if (zqspi->txbuf) { + if (priv->txbuf) { switch (size) { case 1: - *data = *((u8 *)zqspi->txbuf); - zqspi->txbuf += 1; + *data = *((u8 *)priv->txbuf); + priv->txbuf += 1; *data |= 0xFFFFFF00; break; case 2: - *data = *((u16 *)zqspi->txbuf); - zqspi->txbuf += 2; + *data = *((u16 *)priv->txbuf); + priv->txbuf += 2; *data |= 0xFFFF0000; break; case 3: - *data = *((u16 *)zqspi->txbuf); - zqspi->txbuf += 2; - *data |= (*((u8 *)zqspi->txbuf) << 16); - zqspi->txbuf += 1; + *data = *((u16 *)priv->txbuf); + priv->txbuf += 2; + *data |= (*((u8 *)priv->txbuf) << 16); + priv->txbuf += 1; *data |= 0xFF000000; break; case 4: /* Can not assume word aligned buffer */ - memcpy(data, zqspi->txbuf, size); - zqspi->txbuf += 4; + memcpy(data, priv->txbuf, size); + priv->txbuf += 4; break; default: /* This will never execute */ @@ -329,11 +485,11 @@ static void zynq_qspi_copy_write_data(struct zynq_qspi *zqspi, } debug("%s: data 0x%08x txbuf addr: 0x%08x size %d\n", __func__, - *data, (u32)zqspi->txbuf, size); + *data, (u32)priv->txbuf, size); - zqspi->bytes_to_transfer -= size; - if (zqspi->bytes_to_transfer < 0) - zqspi->bytes_to_transfer = 0; + priv->bytes_to_transfer -= size; + if (priv->bytes_to_transfer < 0) + priv->bytes_to_transfer = 0; } /* @@ -341,134 +497,63 @@ static void zynq_qspi_copy_write_data(struct zynq_qspi *zqspi, * @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) +static void zynq_qspi_chipselect(struct zynq_qspi_priv *priv, int is_on) { u32 config_reg; + struct zynq_qspi_regs *regs = priv->regs; debug("%s: is_on: %d\n", __func__, is_on); - config_reg = readl(&zynq_qspi_base->confr); + config_reg = readl(®s->confr); if (is_on) { /* Select the slave */ config_reg &= ~ZYNQ_QSPI_CONFIG_SSCTRL_MASK; - config_reg |= (((~(0x0001 << qspi->chip_select)) << 10) & + config_reg |= (((~(0x0001 << 0)) << 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; + writel(config_reg, ®s->confr); } /* * 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) +static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size) { u32 data = 0; u32 fifocount = 0; unsigned len, offset; + struct zynq_qspi_regs *regs = priv->regs; 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; + (priv->bytes_to_transfer > 0)) { + if (priv->bytes_to_transfer >= 4) { + if (priv->txbuf) { + memcpy(&data, priv->txbuf, 4); + priv->txbuf += 4; } else { data = 0; } - writel(data, &zynq_qspi_base->txd0r); - zqspi->bytes_to_transfer -= 4; + writel(data, ®s->txd0r); + priv->bytes_to_transfer -= 4; fifocount++; } else { /* Write TXD1, TXD2, TXD3 only if TxFIFO is empty. */ - if (!(readl(&zynq_qspi_base->isr) + if (!(readl(®s->isr) & ZYNQ_QSPI_IXR_TXNFULL_MASK) && - !zqspi->rxbuf) + !priv->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)); + len = priv->bytes_to_transfer; + zynq_qspi_copy_write_data(priv, &data, len); + offset = (priv->rxbuf) ? offsets[0] : offsets[len]; + writel(data, ®s->confr + (offset / 4)); } } } @@ -487,31 +572,32 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi *zqspi, u32 size) * returns: 0 for poll timeout * 1 transfer operation complete */ -static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi) +static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv) { int max_loop; u32 intr_status; u32 rxindex = 0; u32 rxcount; + struct zynq_qspi_regs *regs = priv->regs; - debug("%s: zqspi: 0x%08x\n", __func__, (u32)zqspi); + debug("%s: zqspi: 0x%08x\n", __func__, (u32)priv); /* Poll until any of the interrupt status bits are set */ max_loop = 0; do { - intr_status = readl(&zynq_qspi_base->isr); + intr_status = readl(®s->isr); max_loop++; } while ((intr_status == 0) && (max_loop < 100000)); if (intr_status == 0) { - printf("%s: Timeout\n", __func__); + debug("%s: Timeout\n", __func__); return 0; } - writel(intr_status, &zynq_qspi_base->isr); + writel(intr_status, ®s->isr); /* Disable all interrupts */ - writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->idisr); + writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->idisr); if ((intr_status & ZYNQ_QSPI_IXR_TXNFULL_MASK) || (intr_status & ZYNQ_QSPI_IXR_RXNEMTY_MASK)) { /* @@ -519,42 +605,42 @@ static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi) * the THRESHOLD value set to 1, so this bit indicates Tx FIFO * is empty */ - rxcount = zqspi->bytes_to_receive - zqspi->bytes_to_transfer; + rxcount = priv->bytes_to_receive - priv->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); + data = readl(®s->drxr); - if (zqspi->bytes_to_receive >= 4) { - if (zqspi->rxbuf) { - memcpy(zqspi->rxbuf, &data, 4); - zqspi->rxbuf += 4; + if (priv->bytes_to_receive >= 4) { + if (priv->rxbuf) { + memcpy(priv->rxbuf, &data, 4); + priv->rxbuf += 4; } - zqspi->bytes_to_receive -= 4; + priv->bytes_to_receive -= 4; } else { - zynq_qspi_copy_read_data(zqspi, data, - zqspi->bytes_to_receive); + zynq_qspi_copy_read_data(priv, data, + priv->bytes_to_receive); } rxindex++; } - if (zqspi->bytes_to_transfer) { + if (priv->bytes_to_transfer) { /* There is more data to send */ - zynq_qspi_fill_tx_fifo(zqspi, + zynq_qspi_fill_tx_fifo(priv, ZYNQ_QSPI_RXFIFO_THRESHOLD); - writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->ier); + writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->ier); } else { /* * If transfer and receive is completed then only send * complete signal */ - if (!zqspi->bytes_to_receive) { + if (!priv->bytes_to_receive) { /* return operation complete */ writel(ZYNQ_QSPI_IXR_ALL_MASK, - &zynq_qspi_base->idisr); + ®s->idisr); return 1; } } @@ -574,30 +660,27 @@ static int zynq_qspi_irq_poll(struct zynq_qspi *zqspi) * * returns: Number of bytes transferred in the last transfer */ -static int zynq_qspi_start_transfer(struct spi_device *qspi, - struct spi_transfer *transfer) +static int zynq_qspi_start_transfer(struct zynq_qspi_priv *priv) { - struct zynq_qspi *zqspi = &qspi->master; static u8 current_u_page; u32 data = 0; + struct zynq_qspi_regs *regs = priv->regs; debug("%s: qspi: 0x%08x transfer: 0x%08x len: %d\n", __func__, - (u32)qspi, (u32)transfer, transfer->len); + (u32)priv, (u32)priv, priv->len); - zqspi->txbuf = transfer->tx_buf; - zqspi->rxbuf = transfer->rx_buf; - zqspi->bytes_to_transfer = transfer->len; - zqspi->bytes_to_receive = transfer->len; + priv->bytes_to_transfer = priv->len; + priv->bytes_to_receive = priv->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) + if (priv->is_inst && (priv->is_dual == SF_DUAL_STACKED_FLASH) && + (current_u_page != priv->u_page)) { + if (priv->u_page) { + if (priv->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); + ®s->lcr); else /* Configure two memories on shared bus * by enabling upper mem @@ -606,13 +689,13 @@ static int zynq_qspi_start_transfer(struct spi_device *qspi, ZYNQ_QSPI_LCFG_U_PAGE | (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) | ZYNQ_QSPI_FR_QOUT_CODE), - &zynq_qspi_base->lcr); + ®s->lcr); } else { - if (zqspi->is_dio == SF_DUALIO_FLASH) + if (priv->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); + ®s->lcr); else /* Configure two memories on shared bus * by enabling lower mem @@ -620,252 +703,109 @@ static int zynq_qspi_start_transfer(struct spi_device *qspi, writel((ZYNQ_QSPI_LCFG_TWO_MEM_MASK | (1 << ZYNQ_QSPI_LCFG_DUMMY_SHIFT) | ZYNQ_QSPI_FR_QOUT_CODE), - &zynq_qspi_base->lcr); + ®s->lcr); } - current_u_page = zqspi->u_page; + current_u_page = priv->u_page; } - if (transfer->len < 4) - zynq_qspi_fill_tx_fifo(zqspi, transfer->len); + if (priv->len < 4) + zynq_qspi_fill_tx_fifo(priv, priv->len); else - zynq_qspi_fill_tx_fifo(zqspi, ZYNQ_QSPI_FIFO_DEPTH); + zynq_qspi_fill_tx_fifo(priv, ZYNQ_QSPI_FIFO_DEPTH); - writel(ZYNQ_QSPI_IXR_ALL_MASK, &zynq_qspi_base->ier); + writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->ier); /* Start the transfer by enabling manual start bit */ /* wait for completion */ do { - data = zynq_qspi_irq_poll(zqspi); + data = zynq_qspi_irq_poll(priv); } while (data == 0); - return (transfer->len) - (zqspi->bytes_to_transfer); + return (priv->len) - (priv->bytes_to_transfer); } -static int zynq_qspi_transfer(struct spi_device *qspi, - struct spi_transfer *transfer) +static int zynq_qspi_transfer(struct zynq_qspi_priv *priv) { - 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); + zynq_qspi_chipselect(priv, 1); - cs_change = transfer->cs_change; + cs_change = priv->cs_change; - if (!transfer->tx_buf && !transfer->rx_buf && transfer->len) { + if (!priv->txbuf && !priv->rxbuf && priv->len) { status = -1; break; } /* Request the transfer */ - if (transfer->len) { - status = zynq_qspi_start_transfer(qspi, transfer); - zqspi->is_inst = 0; + if (priv->len) { + status = zynq_qspi_start_transfer(priv); + priv->is_inst = 0; } - if (status != transfer->len) { + if (status != priv->len) { if (status > 0) status = -EMSGSIZE; + debug("zynq_qspi_transfer:%d len:%d\n", status, priv->len); break; } status = 0; - if (transfer->delay_usecs) - udelay(transfer->delay_usecs); - if (cs_change) /* Deselect the chip */ - zynq_qspi_chipselect(qspi, 0); + zynq_qspi_chipselect(priv, 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) +static int zynq_qspi_claim_bus(struct udevice *dev) { - int is_dual = -1; - int lower_mio = 0, upper_mio = 0, upper_mio_cs1 = 0; + struct udevice *bus = dev->parent; + struct zynq_qspi_priv *priv = dev_get_priv(bus); + struct zynq_qspi_regs *regs = priv->regs; - 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 int 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); + writel(ZYNQ_QSPI_ENABLE_ENABLE_MASK, ®s->enbr); - 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 %d 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; + return 0; } -void spi_free_slave(struct spi_slave *slave) +static int zynq_qspi_release_bus(struct udevice *dev) { - struct zynq_qspi_slave *qspi; - - debug("%s: slave: 0x%08x\n", __func__, (u32)slave); + struct udevice *bus = dev->parent; + struct zynq_qspi_priv *priv = dev_get_priv(bus); + struct zynq_qspi_regs *regs = priv->regs; - qspi = to_zynq_qspi_slave(slave); - free(qspi); -} + debug("%s\n", __func__); + writel(~ZYNQ_QSPI_ENABLE_ENABLE_MASK, ®s->enbr); -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, +static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { - struct zynq_qspi_slave *qspi; - struct spi_transfer transfer; + struct udevice *bus = dev->parent; + struct zynq_qspi_priv *priv = dev_get_priv(bus); + debug("%s", __func__); debug("%s: slave: 0x%08x bitlen: %d dout: 0x%08x ", __func__, - (u32)slave, bitlen, (u32)dout); + (u32)priv, 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; + priv->txbuf = dout; + priv->rxbuf = din; + priv->len = bitlen / 8; /* * Festering sore. @@ -873,25 +813,46 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, * transmit must contain a device command. */ if (dout && flags & SPI_XFER_BEGIN) - qspi->qspi.master.is_inst = 1; + priv->is_inst = 1; else - qspi->qspi.master.is_inst = 0; + priv->is_inst = 0; if (flags & SPI_XFER_END) - transfer.cs_change = 1; + priv->cs_change = 1; else - transfer.cs_change = 0; + priv->cs_change = 0; if (flags & SPI_XFER_U_PAGE) - qspi->qspi.master.u_page = 1; + priv->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; + priv->u_page = 0; - zynq_qspi_transfer(&qspi->qspi, &transfer); + zynq_qspi_transfer(priv); return 0; } + +static const struct dm_spi_ops zynq_qspi_ops = { + .claim_bus = zynq_qspi_claim_bus, + .release_bus = zynq_qspi_release_bus, + .xfer = zynq_qspi_xfer, + .set_speed = zynq_qspi_set_speed, + .set_mode = zynq_qspi_set_mode, +}; + +static const struct udevice_id zynq_qspi_ids[] = { + { .compatible = "xlnx,zynq-qspi-1.0" }, + { } +}; + +U_BOOT_DRIVER(zynq_qspi) = { + .name = "zynq_qspi", + .id = UCLASS_SPI, + .of_match = zynq_qspi_ids, + .ops = &zynq_qspi_ops, + .ofdata_to_platdata = zynq_qspi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct zynq_qspi_platdata), + .priv_auto_alloc_size = sizeof(struct zynq_qspi_priv), + .probe = zynq_qspi_probe, + .child_pre_probe = zynq_qspi_child_pre_probe, +}; diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index d311f475cf6..3a7bfd32c60 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -177,11 +177,9 @@ # define CONFIG_CMD_FS_GENERIC #endif -#undef CONFIG_ZYNQ_QSPI /* Temporary solution till DM is added */ /* QSPI */ #ifdef CONFIG_ZYNQ_QSPI # define CONFIG_SF_DEFAULT_SPEED 30000000 -# define CONFIG_SPI_FLASH_BAR # define CONFIG_SPI_FLASH_SPANSION # define CONFIG_SPI_FLASH_STMICRO # define CONFIG_SPI_FLASH_WINBOND @@ -519,12 +517,14 @@ #define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 0 /* qspi mode is working fine */ +#if 0 #ifdef CONFIG_ZYNQ_QSPI #define CONFIG_SPL_SPI_SUPPORT #define CONFIG_SPL_SPI_LOAD #define CONFIG_SPL_SPI_FLASH_SUPPORT #define CONFIG_SYS_SPI_U_BOOT_OFFS 0x100000 #endif +#endif #ifdef DEBUG #define CONFIG_SPL_RAM_DEVICE