146d0a991SJagan Teki /*
246d0a991SJagan Teki * (C) Copyright 2013 Xilinx, Inc.
346d0a991SJagan Teki * (C) Copyright 2015 Jagan Teki <jteki@openedev.com>
446d0a991SJagan Teki *
546d0a991SJagan Teki * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
646d0a991SJagan Teki *
746d0a991SJagan Teki * SPDX-License-Identifier: GPL-2.0+
846d0a991SJagan Teki */
946d0a991SJagan Teki
1046d0a991SJagan Teki #include <common.h>
1146d0a991SJagan Teki #include <dm.h>
1246d0a991SJagan Teki #include <malloc.h>
1346d0a991SJagan Teki #include <spi.h>
1446d0a991SJagan Teki #include <asm/io.h>
1546d0a991SJagan Teki
1646d0a991SJagan Teki DECLARE_GLOBAL_DATA_PTR;
1746d0a991SJagan Teki
1846d0a991SJagan Teki /* zynq qspi register bit masks ZYNQ_QSPI_<REG>_<BIT>_MASK */
19736b4df1SJagan Teki #define ZYNQ_QSPI_CR_IFMODE_MASK BIT(31) /* Flash intrface mode*/
20736b4df1SJagan Teki #define ZYNQ_QSPI_CR_MSA_MASK BIT(15) /* Manual start enb */
21736b4df1SJagan Teki #define ZYNQ_QSPI_CR_MCS_MASK BIT(14) /* Manual chip select */
22736b4df1SJagan Teki #define ZYNQ_QSPI_CR_PCS_MASK BIT(10) /* Peri chip select */
239cf2ffb3SJagan Teki #define ZYNQ_QSPI_CR_FW_MASK GENMASK(7, 6) /* FIFO width */
249cf2ffb3SJagan Teki #define ZYNQ_QSPI_CR_SS_MASK GENMASK(13, 10) /* Slave Select */
259cf2ffb3SJagan Teki #define ZYNQ_QSPI_CR_BAUD_MASK GENMASK(5, 3) /* Baud rate div */
26736b4df1SJagan Teki #define ZYNQ_QSPI_CR_CPHA_MASK BIT(2) /* Clock phase */
27736b4df1SJagan Teki #define ZYNQ_QSPI_CR_CPOL_MASK BIT(1) /* Clock polarity */
28736b4df1SJagan Teki #define ZYNQ_QSPI_CR_MSTREN_MASK BIT(0) /* Mode select */
29736b4df1SJagan Teki #define ZYNQ_QSPI_IXR_RXNEMPTY_MASK BIT(4) /* RX_FIFO_not_empty */
30736b4df1SJagan Teki #define ZYNQ_QSPI_IXR_TXOW_MASK BIT(2) /* TX_FIFO_not_full */
319cf2ffb3SJagan Teki #define ZYNQ_QSPI_IXR_ALL_MASK GENMASK(6, 0) /* All IXR bits */
32736b4df1SJagan Teki #define ZYNQ_QSPI_ENR_SPI_EN_MASK BIT(0) /* SPI Enable */
3304a44d36SNathan Rossi #define ZYNQ_QSPI_LQSPICFG_LQMODE_MASK BIT(31) /* Linear QSPI Mode */
3446d0a991SJagan Teki
3546d0a991SJagan Teki /* zynq qspi Transmit Data Register */
3646d0a991SJagan Teki #define ZYNQ_QSPI_TXD_00_00_OFFSET 0x1C /* Transmit 4-byte inst */
3746d0a991SJagan Teki #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80 /* Transmit 1-byte inst */
3846d0a991SJagan Teki #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84 /* Transmit 2-byte inst */
3946d0a991SJagan Teki #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88 /* Transmit 3-byte inst */
4046d0a991SJagan Teki
4146d0a991SJagan Teki #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1 /* Tx FIFO threshold level*/
4246d0a991SJagan Teki #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32 /* Rx FIFO threshold level */
4346d0a991SJagan Teki
4446d0a991SJagan Teki #define ZYNQ_QSPI_CR_BAUD_MAX 8 /* Baud rate divisor max val */
4546d0a991SJagan Teki #define ZYNQ_QSPI_CR_BAUD_SHIFT 3 /* Baud rate divisor shift */
4646d0a991SJagan Teki #define ZYNQ_QSPI_CR_SS_SHIFT 10 /* Slave select shift */
4746d0a991SJagan Teki
4846d0a991SJagan Teki #define ZYNQ_QSPI_FIFO_DEPTH 63
4946d0a991SJagan Teki #ifndef CONFIG_SYS_ZYNQ_QSPI_WAIT
5046d0a991SJagan Teki #define CONFIG_SYS_ZYNQ_QSPI_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
5146d0a991SJagan Teki #endif
5246d0a991SJagan Teki
5346d0a991SJagan Teki /* zynq qspi register set */
5446d0a991SJagan Teki struct zynq_qspi_regs {
5546d0a991SJagan Teki u32 cr; /* 0x00 */
5646d0a991SJagan Teki u32 isr; /* 0x04 */
5746d0a991SJagan Teki u32 ier; /* 0x08 */
5846d0a991SJagan Teki u32 idr; /* 0x0C */
5946d0a991SJagan Teki u32 imr; /* 0x10 */
6046d0a991SJagan Teki u32 enr; /* 0x14 */
6146d0a991SJagan Teki u32 dr; /* 0x18 */
6246d0a991SJagan Teki u32 txd0r; /* 0x1C */
6346d0a991SJagan Teki u32 drxr; /* 0x20 */
6446d0a991SJagan Teki u32 sicr; /* 0x24 */
6546d0a991SJagan Teki u32 txftr; /* 0x28 */
6646d0a991SJagan Teki u32 rxftr; /* 0x2C */
6746d0a991SJagan Teki u32 gpior; /* 0x30 */
6846d0a991SJagan Teki u32 reserved0[19];
6946d0a991SJagan Teki u32 txd1r; /* 0x80 */
7046d0a991SJagan Teki u32 txd2r; /* 0x84 */
7146d0a991SJagan Teki u32 txd3r; /* 0x88 */
7204a44d36SNathan Rossi u32 reserved1[5];
7304a44d36SNathan Rossi u32 lqspicfg; /* 0xA0 */
7404a44d36SNathan Rossi u32 lqspists; /* 0xA4 */
7546d0a991SJagan Teki };
7646d0a991SJagan Teki
7746d0a991SJagan Teki /* zynq qspi platform data */
7846d0a991SJagan Teki struct zynq_qspi_platdata {
7946d0a991SJagan Teki struct zynq_qspi_regs *regs;
8046d0a991SJagan Teki u32 frequency; /* input frequency */
8146d0a991SJagan Teki u32 speed_hz;
8246d0a991SJagan Teki };
8346d0a991SJagan Teki
8446d0a991SJagan Teki /* zynq qspi priv */
8546d0a991SJagan Teki struct zynq_qspi_priv {
8646d0a991SJagan Teki struct zynq_qspi_regs *regs;
8746d0a991SJagan Teki u8 cs;
8846d0a991SJagan Teki u8 mode;
8946d0a991SJagan Teki u8 fifo_depth;
9046d0a991SJagan Teki u32 freq; /* required frequency */
9146d0a991SJagan Teki const void *tx_buf;
9246d0a991SJagan Teki void *rx_buf;
9346d0a991SJagan Teki unsigned len;
9446d0a991SJagan Teki int bytes_to_transfer;
9546d0a991SJagan Teki int bytes_to_receive;
9646d0a991SJagan Teki unsigned int is_inst;
9746d0a991SJagan Teki unsigned cs_change:1;
9846d0a991SJagan Teki };
9946d0a991SJagan Teki
zynq_qspi_ofdata_to_platdata(struct udevice * bus)10046d0a991SJagan Teki static int zynq_qspi_ofdata_to_platdata(struct udevice *bus)
10146d0a991SJagan Teki {
10246d0a991SJagan Teki struct zynq_qspi_platdata *plat = bus->platdata;
10346d0a991SJagan Teki const void *blob = gd->fdt_blob;
104*e160f7d4SSimon Glass int node = dev_of_offset(bus);
10546d0a991SJagan Teki
10646d0a991SJagan Teki plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
10746d0a991SJagan Teki node, "reg");
10846d0a991SJagan Teki
10946d0a991SJagan Teki /* FIXME: Use 166MHz as a suitable default */
11046d0a991SJagan Teki plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
11146d0a991SJagan Teki 166666666);
11246d0a991SJagan Teki plat->speed_hz = plat->frequency / 2;
11346d0a991SJagan Teki
11446d0a991SJagan Teki debug("%s: regs=%p max-frequency=%d\n", __func__,
11546d0a991SJagan Teki plat->regs, plat->frequency);
11646d0a991SJagan Teki
11746d0a991SJagan Teki return 0;
11846d0a991SJagan Teki }
11946d0a991SJagan Teki
zynq_qspi_init_hw(struct zynq_qspi_priv * priv)12046d0a991SJagan Teki static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
12146d0a991SJagan Teki {
12246d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
12346d0a991SJagan Teki u32 confr;
12446d0a991SJagan Teki
12546d0a991SJagan Teki /* Disable QSPI */
12646d0a991SJagan Teki writel(~ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr);
12746d0a991SJagan Teki
12846d0a991SJagan Teki /* Disable Interrupts */
12946d0a991SJagan Teki writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->idr);
13046d0a991SJagan Teki
13146d0a991SJagan Teki /* Clear the TX and RX threshold reg */
13246d0a991SJagan Teki writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, ®s->txftr);
13346d0a991SJagan Teki writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, ®s->rxftr);
13446d0a991SJagan Teki
13546d0a991SJagan Teki /* Clear the RX FIFO */
13646d0a991SJagan Teki while (readl(®s->isr) & ZYNQ_QSPI_IXR_RXNEMPTY_MASK)
13746d0a991SJagan Teki readl(®s->drxr);
13846d0a991SJagan Teki
13946d0a991SJagan Teki /* Clear Interrupts */
14046d0a991SJagan Teki writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->isr);
14146d0a991SJagan Teki
14246d0a991SJagan Teki /* Manual slave select and Auto start */
14346d0a991SJagan Teki confr = readl(®s->cr);
14446d0a991SJagan Teki confr &= ~ZYNQ_QSPI_CR_MSA_MASK;
14546d0a991SJagan Teki confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
14646d0a991SJagan Teki ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
14746d0a991SJagan Teki ZYNQ_QSPI_CR_MSTREN_MASK;
14846d0a991SJagan Teki writel(confr, ®s->cr);
14946d0a991SJagan Teki
15004a44d36SNathan Rossi /* Disable the LQSPI feature */
15104a44d36SNathan Rossi confr = readl(®s->lqspicfg);
15204a44d36SNathan Rossi confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
15304a44d36SNathan Rossi writel(confr, ®s->lqspicfg);
15404a44d36SNathan Rossi
15546d0a991SJagan Teki /* Enable SPI */
15646d0a991SJagan Teki writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr);
15746d0a991SJagan Teki }
15846d0a991SJagan Teki
zynq_qspi_probe(struct udevice * bus)15946d0a991SJagan Teki static int zynq_qspi_probe(struct udevice *bus)
16046d0a991SJagan Teki {
16146d0a991SJagan Teki struct zynq_qspi_platdata *plat = dev_get_platdata(bus);
16246d0a991SJagan Teki struct zynq_qspi_priv *priv = dev_get_priv(bus);
16346d0a991SJagan Teki
16446d0a991SJagan Teki priv->regs = plat->regs;
16546d0a991SJagan Teki priv->fifo_depth = ZYNQ_QSPI_FIFO_DEPTH;
16646d0a991SJagan Teki
16746d0a991SJagan Teki /* init the zynq spi hw */
16846d0a991SJagan Teki zynq_qspi_init_hw(priv);
16946d0a991SJagan Teki
17046d0a991SJagan Teki return 0;
17146d0a991SJagan Teki }
17246d0a991SJagan Teki
17346d0a991SJagan Teki /*
17446d0a991SJagan Teki * zynq_qspi_read_data - Copy data to RX buffer
17546d0a991SJagan Teki * @zqspi: Pointer to the zynq_qspi structure
17646d0a991SJagan Teki * @data: The 32 bit variable where data is stored
17746d0a991SJagan Teki * @size: Number of bytes to be copied from data to RX buffer
17846d0a991SJagan Teki */
zynq_qspi_read_data(struct zynq_qspi_priv * priv,u32 data,u8 size)17946d0a991SJagan Teki static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size)
18046d0a991SJagan Teki {
18146d0a991SJagan Teki u8 byte3;
18246d0a991SJagan Teki
18346d0a991SJagan Teki debug("%s: data 0x%04x rx_buf addr: 0x%08x size %d\n", __func__ ,
18446d0a991SJagan Teki data, (unsigned)(priv->rx_buf), size);
18546d0a991SJagan Teki
18646d0a991SJagan Teki if (priv->rx_buf) {
18746d0a991SJagan Teki switch (size) {
18846d0a991SJagan Teki case 1:
18946d0a991SJagan Teki *((u8 *)priv->rx_buf) = data;
19046d0a991SJagan Teki priv->rx_buf += 1;
19146d0a991SJagan Teki break;
19246d0a991SJagan Teki case 2:
19346d0a991SJagan Teki *((u16 *)priv->rx_buf) = data;
19446d0a991SJagan Teki priv->rx_buf += 2;
19546d0a991SJagan Teki break;
19646d0a991SJagan Teki case 3:
19746d0a991SJagan Teki *((u16 *)priv->rx_buf) = data;
19846d0a991SJagan Teki priv->rx_buf += 2;
19946d0a991SJagan Teki byte3 = (u8)(data >> 16);
20046d0a991SJagan Teki *((u8 *)priv->rx_buf) = byte3;
20146d0a991SJagan Teki priv->rx_buf += 1;
20246d0a991SJagan Teki break;
20346d0a991SJagan Teki case 4:
20446d0a991SJagan Teki /* Can not assume word aligned buffer */
20546d0a991SJagan Teki memcpy(priv->rx_buf, &data, size);
20646d0a991SJagan Teki priv->rx_buf += 4;
20746d0a991SJagan Teki break;
20846d0a991SJagan Teki default:
20946d0a991SJagan Teki /* This will never execute */
21046d0a991SJagan Teki break;
21146d0a991SJagan Teki }
21246d0a991SJagan Teki }
21346d0a991SJagan Teki priv->bytes_to_receive -= size;
21446d0a991SJagan Teki if (priv->bytes_to_receive < 0)
21546d0a991SJagan Teki priv->bytes_to_receive = 0;
21646d0a991SJagan Teki }
21746d0a991SJagan Teki
21846d0a991SJagan Teki /*
21946d0a991SJagan Teki * zynq_qspi_write_data - Copy data from TX buffer
22046d0a991SJagan Teki * @zqspi: Pointer to the zynq_qspi structure
22146d0a991SJagan Teki * @data: Pointer to the 32 bit variable where data is to be copied
22246d0a991SJagan Teki * @size: Number of bytes to be copied from TX buffer to data
22346d0a991SJagan Teki */
zynq_qspi_write_data(struct zynq_qspi_priv * priv,u32 * data,u8 size)22446d0a991SJagan Teki static void zynq_qspi_write_data(struct zynq_qspi_priv *priv,
22546d0a991SJagan Teki u32 *data, u8 size)
22646d0a991SJagan Teki {
22746d0a991SJagan Teki if (priv->tx_buf) {
22846d0a991SJagan Teki switch (size) {
22946d0a991SJagan Teki case 1:
23046d0a991SJagan Teki *data = *((u8 *)priv->tx_buf);
23146d0a991SJagan Teki priv->tx_buf += 1;
23246d0a991SJagan Teki *data |= 0xFFFFFF00;
23346d0a991SJagan Teki break;
23446d0a991SJagan Teki case 2:
23546d0a991SJagan Teki *data = *((u16 *)priv->tx_buf);
23646d0a991SJagan Teki priv->tx_buf += 2;
23746d0a991SJagan Teki *data |= 0xFFFF0000;
23846d0a991SJagan Teki break;
23946d0a991SJagan Teki case 3:
24046d0a991SJagan Teki *data = *((u16 *)priv->tx_buf);
24146d0a991SJagan Teki priv->tx_buf += 2;
24246d0a991SJagan Teki *data |= (*((u8 *)priv->tx_buf) << 16);
24346d0a991SJagan Teki priv->tx_buf += 1;
24446d0a991SJagan Teki *data |= 0xFF000000;
24546d0a991SJagan Teki break;
24646d0a991SJagan Teki case 4:
24746d0a991SJagan Teki /* Can not assume word aligned buffer */
24846d0a991SJagan Teki memcpy(data, priv->tx_buf, size);
24946d0a991SJagan Teki priv->tx_buf += 4;
25046d0a991SJagan Teki break;
25146d0a991SJagan Teki default:
25246d0a991SJagan Teki /* This will never execute */
25346d0a991SJagan Teki break;
25446d0a991SJagan Teki }
25546d0a991SJagan Teki } else {
25646d0a991SJagan Teki *data = 0;
25746d0a991SJagan Teki }
25846d0a991SJagan Teki
25946d0a991SJagan Teki debug("%s: data 0x%08x tx_buf addr: 0x%08x size %d\n", __func__,
26046d0a991SJagan Teki *data, (u32)priv->tx_buf, size);
26146d0a991SJagan Teki
26246d0a991SJagan Teki priv->bytes_to_transfer -= size;
26346d0a991SJagan Teki if (priv->bytes_to_transfer < 0)
26446d0a991SJagan Teki priv->bytes_to_transfer = 0;
26546d0a991SJagan Teki }
26646d0a991SJagan Teki
zynq_qspi_chipselect(struct zynq_qspi_priv * priv,int is_on)26746d0a991SJagan Teki static void zynq_qspi_chipselect(struct zynq_qspi_priv *priv, int is_on)
26846d0a991SJagan Teki {
26946d0a991SJagan Teki u32 confr;
27046d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
27146d0a991SJagan Teki
27246d0a991SJagan Teki confr = readl(®s->cr);
27346d0a991SJagan Teki
27446d0a991SJagan Teki if (is_on) {
27546d0a991SJagan Teki /* Select the slave */
27646d0a991SJagan Teki confr &= ~ZYNQ_QSPI_CR_SS_MASK;
27746d0a991SJagan Teki confr |= (~(1 << priv->cs) << ZYNQ_QSPI_CR_SS_SHIFT) &
27846d0a991SJagan Teki ZYNQ_QSPI_CR_SS_MASK;
27946d0a991SJagan Teki } else
28046d0a991SJagan Teki /* Deselect the slave */
28146d0a991SJagan Teki confr |= ZYNQ_QSPI_CR_SS_MASK;
28246d0a991SJagan Teki
28346d0a991SJagan Teki writel(confr, ®s->cr);
28446d0a991SJagan Teki }
28546d0a991SJagan Teki
28646d0a991SJagan Teki /*
28746d0a991SJagan Teki * zynq_qspi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
28846d0a991SJagan Teki * @zqspi: Pointer to the zynq_qspi structure
28946d0a991SJagan Teki */
zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv * priv,u32 size)29046d0a991SJagan Teki static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
29146d0a991SJagan Teki {
29246d0a991SJagan Teki u32 data = 0;
29346d0a991SJagan Teki u32 fifocount = 0;
29446d0a991SJagan Teki unsigned len, offset;
29546d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
29646d0a991SJagan Teki static const unsigned offsets[4] = {
29746d0a991SJagan Teki ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
29846d0a991SJagan Teki ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
29946d0a991SJagan Teki
30046d0a991SJagan Teki while ((fifocount < size) &&
30146d0a991SJagan Teki (priv->bytes_to_transfer > 0)) {
30246d0a991SJagan Teki if (priv->bytes_to_transfer >= 4) {
30346d0a991SJagan Teki if (priv->tx_buf) {
30446d0a991SJagan Teki memcpy(&data, priv->tx_buf, 4);
30546d0a991SJagan Teki priv->tx_buf += 4;
30646d0a991SJagan Teki } else {
30746d0a991SJagan Teki data = 0;
30846d0a991SJagan Teki }
30946d0a991SJagan Teki writel(data, ®s->txd0r);
31046d0a991SJagan Teki priv->bytes_to_transfer -= 4;
31146d0a991SJagan Teki fifocount++;
31246d0a991SJagan Teki } else {
31346d0a991SJagan Teki /* Write TXD1, TXD2, TXD3 only if TxFIFO is empty. */
31446d0a991SJagan Teki if (!(readl(®s->isr)
31546d0a991SJagan Teki & ZYNQ_QSPI_IXR_TXOW_MASK) &&
31646d0a991SJagan Teki !priv->rx_buf)
31746d0a991SJagan Teki return;
31846d0a991SJagan Teki len = priv->bytes_to_transfer;
31946d0a991SJagan Teki zynq_qspi_write_data(priv, &data, len);
32046d0a991SJagan Teki offset = (priv->rx_buf) ? offsets[0] : offsets[len];
32146d0a991SJagan Teki writel(data, ®s->cr + (offset / 4));
32246d0a991SJagan Teki }
32346d0a991SJagan Teki }
32446d0a991SJagan Teki }
32546d0a991SJagan Teki
32646d0a991SJagan Teki /*
32746d0a991SJagan Teki * zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller
32846d0a991SJagan Teki * @zqspi: Pointer to the zynq_qspi structure
32946d0a991SJagan Teki *
33046d0a991SJagan Teki * This function handles TX empty and Mode Fault interrupts only.
33146d0a991SJagan Teki * On TX empty interrupt this function reads the received data from RX FIFO and
33246d0a991SJagan Teki * fills the TX FIFO if there is any data remaining to be transferred.
33346d0a991SJagan Teki * On Mode Fault interrupt this function indicates that transfer is completed,
33446d0a991SJagan Teki * the SPI subsystem will identify the error as the remaining bytes to be
33546d0a991SJagan Teki * transferred is non-zero.
33646d0a991SJagan Teki *
33746d0a991SJagan Teki * returns: 0 for poll timeout
33846d0a991SJagan Teki * 1 transfer operation complete
33946d0a991SJagan Teki */
zynq_qspi_irq_poll(struct zynq_qspi_priv * priv)34046d0a991SJagan Teki static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv)
34146d0a991SJagan Teki {
34246d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
34346d0a991SJagan Teki u32 rxindex = 0;
34446d0a991SJagan Teki u32 rxcount;
34546d0a991SJagan Teki u32 status, timeout;
34646d0a991SJagan Teki
34746d0a991SJagan Teki /* Poll until any of the interrupt status bits are set */
34846d0a991SJagan Teki timeout = get_timer(0);
34946d0a991SJagan Teki do {
35046d0a991SJagan Teki status = readl(®s->isr);
35146d0a991SJagan Teki } while ((status == 0) &&
35246d0a991SJagan Teki (get_timer(timeout) < CONFIG_SYS_ZYNQ_QSPI_WAIT));
35346d0a991SJagan Teki
35446d0a991SJagan Teki if (status == 0) {
35546d0a991SJagan Teki printf("zynq_qspi_irq_poll: Timeout!\n");
35646d0a991SJagan Teki return -ETIMEDOUT;
35746d0a991SJagan Teki }
35846d0a991SJagan Teki
35946d0a991SJagan Teki writel(status, ®s->isr);
36046d0a991SJagan Teki
36146d0a991SJagan Teki /* Disable all interrupts */
36246d0a991SJagan Teki writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->idr);
36346d0a991SJagan Teki if ((status & ZYNQ_QSPI_IXR_TXOW_MASK) ||
36446d0a991SJagan Teki (status & ZYNQ_QSPI_IXR_RXNEMPTY_MASK)) {
36546d0a991SJagan Teki /*
36646d0a991SJagan Teki * This bit is set when Tx FIFO has < THRESHOLD entries. We have
36746d0a991SJagan Teki * the THRESHOLD value set to 1, so this bit indicates Tx FIFO
36846d0a991SJagan Teki * is empty
36946d0a991SJagan Teki */
37046d0a991SJagan Teki rxcount = priv->bytes_to_receive - priv->bytes_to_transfer;
37146d0a991SJagan Teki rxcount = (rxcount % 4) ? ((rxcount/4)+1) : (rxcount/4);
37246d0a991SJagan Teki while ((rxindex < rxcount) &&
37346d0a991SJagan Teki (rxindex < ZYNQ_QSPI_RXFIFO_THRESHOLD)) {
37446d0a991SJagan Teki /* Read out the data from the RX FIFO */
37546d0a991SJagan Teki u32 data;
37646d0a991SJagan Teki data = readl(®s->drxr);
37746d0a991SJagan Teki
37846d0a991SJagan Teki if (priv->bytes_to_receive >= 4) {
37946d0a991SJagan Teki if (priv->rx_buf) {
38046d0a991SJagan Teki memcpy(priv->rx_buf, &data, 4);
38146d0a991SJagan Teki priv->rx_buf += 4;
38246d0a991SJagan Teki }
38346d0a991SJagan Teki priv->bytes_to_receive -= 4;
38446d0a991SJagan Teki } else {
38546d0a991SJagan Teki zynq_qspi_read_data(priv, data,
38646d0a991SJagan Teki priv->bytes_to_receive);
38746d0a991SJagan Teki }
38846d0a991SJagan Teki rxindex++;
38946d0a991SJagan Teki }
39046d0a991SJagan Teki
39146d0a991SJagan Teki if (priv->bytes_to_transfer) {
39246d0a991SJagan Teki /* There is more data to send */
39346d0a991SJagan Teki zynq_qspi_fill_tx_fifo(priv,
39446d0a991SJagan Teki ZYNQ_QSPI_RXFIFO_THRESHOLD);
39546d0a991SJagan Teki
39646d0a991SJagan Teki writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->ier);
39746d0a991SJagan Teki } else {
39846d0a991SJagan Teki /*
39946d0a991SJagan Teki * If transfer and receive is completed then only send
40046d0a991SJagan Teki * complete signal
40146d0a991SJagan Teki */
40246d0a991SJagan Teki if (!priv->bytes_to_receive) {
40346d0a991SJagan Teki /* return operation complete */
40446d0a991SJagan Teki writel(ZYNQ_QSPI_IXR_ALL_MASK,
40546d0a991SJagan Teki ®s->idr);
40646d0a991SJagan Teki return 1;
40746d0a991SJagan Teki }
40846d0a991SJagan Teki }
40946d0a991SJagan Teki }
41046d0a991SJagan Teki
41146d0a991SJagan Teki return 0;
41246d0a991SJagan Teki }
41346d0a991SJagan Teki
41446d0a991SJagan Teki /*
41546d0a991SJagan Teki * zynq_qspi_start_transfer - Initiates the QSPI transfer
41646d0a991SJagan Teki * @qspi: Pointer to the spi_device structure
41746d0a991SJagan Teki * @transfer: Pointer to the spi_transfer structure which provide information
41846d0a991SJagan Teki * about next transfer parameters
41946d0a991SJagan Teki *
42046d0a991SJagan Teki * This function fills the TX FIFO, starts the QSPI transfer, and waits for the
42146d0a991SJagan Teki * transfer to be completed.
42246d0a991SJagan Teki *
42346d0a991SJagan Teki * returns: Number of bytes transferred in the last transfer
42446d0a991SJagan Teki */
zynq_qspi_start_transfer(struct zynq_qspi_priv * priv)42546d0a991SJagan Teki static int zynq_qspi_start_transfer(struct zynq_qspi_priv *priv)
42646d0a991SJagan Teki {
42746d0a991SJagan Teki u32 data = 0;
42846d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
42946d0a991SJagan Teki
43046d0a991SJagan Teki debug("%s: qspi: 0x%08x transfer: 0x%08x len: %d\n", __func__,
43146d0a991SJagan Teki (u32)priv, (u32)priv, priv->len);
43246d0a991SJagan Teki
43346d0a991SJagan Teki priv->bytes_to_transfer = priv->len;
43446d0a991SJagan Teki priv->bytes_to_receive = priv->len;
43546d0a991SJagan Teki
43646d0a991SJagan Teki if (priv->len < 4)
43746d0a991SJagan Teki zynq_qspi_fill_tx_fifo(priv, priv->len);
43846d0a991SJagan Teki else
43946d0a991SJagan Teki zynq_qspi_fill_tx_fifo(priv, priv->fifo_depth);
44046d0a991SJagan Teki
44146d0a991SJagan Teki writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->ier);
44246d0a991SJagan Teki
44346d0a991SJagan Teki /* wait for completion */
44446d0a991SJagan Teki do {
44546d0a991SJagan Teki data = zynq_qspi_irq_poll(priv);
44646d0a991SJagan Teki } while (data == 0);
44746d0a991SJagan Teki
44846d0a991SJagan Teki return (priv->len) - (priv->bytes_to_transfer);
44946d0a991SJagan Teki }
45046d0a991SJagan Teki
zynq_qspi_transfer(struct zynq_qspi_priv * priv)45146d0a991SJagan Teki static int zynq_qspi_transfer(struct zynq_qspi_priv *priv)
45246d0a991SJagan Teki {
45346d0a991SJagan Teki unsigned cs_change = 1;
45446d0a991SJagan Teki int status = 0;
45546d0a991SJagan Teki
45646d0a991SJagan Teki while (1) {
45746d0a991SJagan Teki /* Select the chip if required */
45846d0a991SJagan Teki if (cs_change)
45946d0a991SJagan Teki zynq_qspi_chipselect(priv, 1);
46046d0a991SJagan Teki
46146d0a991SJagan Teki cs_change = priv->cs_change;
46246d0a991SJagan Teki
46346d0a991SJagan Teki if (!priv->tx_buf && !priv->rx_buf && priv->len) {
46446d0a991SJagan Teki status = -1;
46546d0a991SJagan Teki break;
46646d0a991SJagan Teki }
46746d0a991SJagan Teki
46846d0a991SJagan Teki /* Request the transfer */
46946d0a991SJagan Teki if (priv->len) {
47046d0a991SJagan Teki status = zynq_qspi_start_transfer(priv);
47146d0a991SJagan Teki priv->is_inst = 0;
47246d0a991SJagan Teki }
47346d0a991SJagan Teki
47446d0a991SJagan Teki if (status != priv->len) {
47546d0a991SJagan Teki if (status > 0)
47646d0a991SJagan Teki status = -EMSGSIZE;
47746d0a991SJagan Teki debug("zynq_qspi_transfer:%d len:%d\n",
47846d0a991SJagan Teki status, priv->len);
47946d0a991SJagan Teki break;
48046d0a991SJagan Teki }
48146d0a991SJagan Teki status = 0;
48246d0a991SJagan Teki
48346d0a991SJagan Teki if (cs_change)
48446d0a991SJagan Teki /* Deselect the chip */
48546d0a991SJagan Teki zynq_qspi_chipselect(priv, 0);
48646d0a991SJagan Teki
48746d0a991SJagan Teki break;
48846d0a991SJagan Teki }
48946d0a991SJagan Teki
49046d0a991SJagan Teki return 0;
49146d0a991SJagan Teki }
49246d0a991SJagan Teki
zynq_qspi_claim_bus(struct udevice * dev)49346d0a991SJagan Teki static int zynq_qspi_claim_bus(struct udevice *dev)
49446d0a991SJagan Teki {
49546d0a991SJagan Teki struct udevice *bus = dev->parent;
49646d0a991SJagan Teki struct zynq_qspi_priv *priv = dev_get_priv(bus);
49746d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
49846d0a991SJagan Teki
49946d0a991SJagan Teki writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr);
50046d0a991SJagan Teki
50146d0a991SJagan Teki return 0;
50246d0a991SJagan Teki }
50346d0a991SJagan Teki
zynq_qspi_release_bus(struct udevice * dev)50446d0a991SJagan Teki static int zynq_qspi_release_bus(struct udevice *dev)
50546d0a991SJagan Teki {
50646d0a991SJagan Teki struct udevice *bus = dev->parent;
50746d0a991SJagan Teki struct zynq_qspi_priv *priv = dev_get_priv(bus);
50846d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
50946d0a991SJagan Teki
51046d0a991SJagan Teki writel(~ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr);
51146d0a991SJagan Teki
51246d0a991SJagan Teki return 0;
51346d0a991SJagan Teki }
51446d0a991SJagan Teki
zynq_qspi_xfer(struct udevice * dev,unsigned int bitlen,const void * dout,void * din,unsigned long flags)51546d0a991SJagan Teki static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen,
51646d0a991SJagan Teki const void *dout, void *din, unsigned long flags)
51746d0a991SJagan Teki {
51846d0a991SJagan Teki struct udevice *bus = dev->parent;
51946d0a991SJagan Teki struct zynq_qspi_priv *priv = dev_get_priv(bus);
52046d0a991SJagan Teki struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
52146d0a991SJagan Teki
52246d0a991SJagan Teki priv->cs = slave_plat->cs;
52346d0a991SJagan Teki priv->tx_buf = dout;
52446d0a991SJagan Teki priv->rx_buf = din;
52546d0a991SJagan Teki priv->len = bitlen / 8;
52646d0a991SJagan Teki
527e5e0d68fSJagan Teki debug("zynq_qspi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
52846d0a991SJagan Teki bus->seq, slave_plat->cs, bitlen, priv->len, flags);
52946d0a991SJagan Teki
53046d0a991SJagan Teki /*
53146d0a991SJagan Teki * Festering sore.
53246d0a991SJagan Teki * Assume that the beginning of a transfer with bits to
53346d0a991SJagan Teki * transmit must contain a device command.
53446d0a991SJagan Teki */
53546d0a991SJagan Teki if (dout && flags & SPI_XFER_BEGIN)
53646d0a991SJagan Teki priv->is_inst = 1;
53746d0a991SJagan Teki else
53846d0a991SJagan Teki priv->is_inst = 0;
53946d0a991SJagan Teki
54046d0a991SJagan Teki if (flags & SPI_XFER_END)
54146d0a991SJagan Teki priv->cs_change = 1;
54246d0a991SJagan Teki else
54346d0a991SJagan Teki priv->cs_change = 0;
54446d0a991SJagan Teki
54546d0a991SJagan Teki zynq_qspi_transfer(priv);
54646d0a991SJagan Teki
54746d0a991SJagan Teki return 0;
54846d0a991SJagan Teki }
54946d0a991SJagan Teki
zynq_qspi_set_speed(struct udevice * bus,uint speed)55046d0a991SJagan Teki static int zynq_qspi_set_speed(struct udevice *bus, uint speed)
55146d0a991SJagan Teki {
55246d0a991SJagan Teki struct zynq_qspi_platdata *plat = bus->platdata;
55346d0a991SJagan Teki struct zynq_qspi_priv *priv = dev_get_priv(bus);
55446d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
55546d0a991SJagan Teki uint32_t confr;
55646d0a991SJagan Teki u8 baud_rate_val = 0;
55746d0a991SJagan Teki
55846d0a991SJagan Teki if (speed > plat->frequency)
55946d0a991SJagan Teki speed = plat->frequency;
56046d0a991SJagan Teki
56146d0a991SJagan Teki /* Set the clock frequency */
56246d0a991SJagan Teki confr = readl(®s->cr);
56346d0a991SJagan Teki if (speed == 0) {
56446d0a991SJagan Teki /* Set baudrate x8, if the freq is 0 */
56546d0a991SJagan Teki baud_rate_val = 0x2;
56646d0a991SJagan Teki } else if (plat->speed_hz != speed) {
56746d0a991SJagan Teki while ((baud_rate_val < ZYNQ_QSPI_CR_BAUD_MAX) &&
56846d0a991SJagan Teki ((plat->frequency /
56946d0a991SJagan Teki (2 << baud_rate_val)) > speed))
57046d0a991SJagan Teki baud_rate_val++;
57146d0a991SJagan Teki
57246d0a991SJagan Teki plat->speed_hz = speed / (2 << baud_rate_val);
57346d0a991SJagan Teki }
57446d0a991SJagan Teki confr &= ~ZYNQ_QSPI_CR_BAUD_MASK;
57546d0a991SJagan Teki confr |= (baud_rate_val << ZYNQ_QSPI_CR_BAUD_SHIFT);
57646d0a991SJagan Teki
57746d0a991SJagan Teki writel(confr, ®s->cr);
57846d0a991SJagan Teki priv->freq = speed;
57946d0a991SJagan Teki
580e5e0d68fSJagan Teki debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
58146d0a991SJagan Teki
58246d0a991SJagan Teki return 0;
58346d0a991SJagan Teki }
58446d0a991SJagan Teki
zynq_qspi_set_mode(struct udevice * bus,uint mode)58546d0a991SJagan Teki static int zynq_qspi_set_mode(struct udevice *bus, uint mode)
58646d0a991SJagan Teki {
58746d0a991SJagan Teki struct zynq_qspi_priv *priv = dev_get_priv(bus);
58846d0a991SJagan Teki struct zynq_qspi_regs *regs = priv->regs;
58946d0a991SJagan Teki uint32_t confr;
59046d0a991SJagan Teki
59146d0a991SJagan Teki /* Set the SPI Clock phase and polarities */
59246d0a991SJagan Teki confr = readl(®s->cr);
59346d0a991SJagan Teki confr &= ~(ZYNQ_QSPI_CR_CPHA_MASK | ZYNQ_QSPI_CR_CPOL_MASK);
59446d0a991SJagan Teki
5952775e918SJagan Teki if (mode & SPI_CPHA)
59646d0a991SJagan Teki confr |= ZYNQ_QSPI_CR_CPHA_MASK;
5972775e918SJagan Teki if (mode & SPI_CPOL)
59846d0a991SJagan Teki confr |= ZYNQ_QSPI_CR_CPOL_MASK;
59946d0a991SJagan Teki
60046d0a991SJagan Teki writel(confr, ®s->cr);
60146d0a991SJagan Teki priv->mode = mode;
60246d0a991SJagan Teki
603e5e0d68fSJagan Teki debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
60446d0a991SJagan Teki
60546d0a991SJagan Teki return 0;
60646d0a991SJagan Teki }
60746d0a991SJagan Teki
60846d0a991SJagan Teki static const struct dm_spi_ops zynq_qspi_ops = {
60946d0a991SJagan Teki .claim_bus = zynq_qspi_claim_bus,
61046d0a991SJagan Teki .release_bus = zynq_qspi_release_bus,
61146d0a991SJagan Teki .xfer = zynq_qspi_xfer,
61246d0a991SJagan Teki .set_speed = zynq_qspi_set_speed,
61346d0a991SJagan Teki .set_mode = zynq_qspi_set_mode,
61446d0a991SJagan Teki };
61546d0a991SJagan Teki
61646d0a991SJagan Teki static const struct udevice_id zynq_qspi_ids[] = {
61746d0a991SJagan Teki { .compatible = "xlnx,zynq-qspi-1.0" },
61846d0a991SJagan Teki { }
61946d0a991SJagan Teki };
62046d0a991SJagan Teki
62146d0a991SJagan Teki U_BOOT_DRIVER(zynq_qspi) = {
62246d0a991SJagan Teki .name = "zynq_qspi",
62346d0a991SJagan Teki .id = UCLASS_SPI,
62446d0a991SJagan Teki .of_match = zynq_qspi_ids,
62546d0a991SJagan Teki .ops = &zynq_qspi_ops,
62646d0a991SJagan Teki .ofdata_to_platdata = zynq_qspi_ofdata_to_platdata,
62746d0a991SJagan Teki .platdata_auto_alloc_size = sizeof(struct zynq_qspi_platdata),
62846d0a991SJagan Teki .priv_auto_alloc_size = sizeof(struct zynq_qspi_priv),
62946d0a991SJagan Teki .probe = zynq_qspi_probe,
63046d0a991SJagan Teki };
631