2 * (C) Copyright 2013 Inc.
4 * Xilinx Zynq PS SPI controller driver (master mode only)
6 * SPDX-License-Identifier: GPL-2.0+
14 #include <asm/arch/hardware.h>
16 /* zynq spi register bit masks ZYNQ_SPI_<REG>_<BIT>_MASK */
17 #define ZYNQ_SPI_CR_MSA_MASK (1 << 15) /* Manual start enb */
18 #define ZYNQ_SPI_CR_MCS_MASK (1 << 14) /* Manual chip select */
19 #define ZYNQ_SPI_CR_CS_MASK (0xF << 10) /* Chip select */
20 #define ZYNQ_SPI_CR_BRD_MASK (0x7 << 3) /* Baud rate div */
21 #define ZYNQ_SPI_CR_CPHA_MASK (1 << 2) /* Clock phase */
22 #define ZYNQ_SPI_CR_CPOL_MASK (1 << 1) /* Clock polarity */
23 #define ZYNQ_SPI_CR_MSTREN_MASK (1 << 0) /* Mode select */
24 #define ZYNQ_SPI_IXR_RXNEMPTY_MASK (1 << 4) /* RX_FIFO_not_empty */
25 #define ZYNQ_SPI_IXR_TXOW_MASK (1 << 2) /* TX_FIFO_not_full */
26 #define ZYNQ_SPI_IXR_ALL_MASK 0x7F /* All IXR bits */
27 #define ZYNQ_SPI_ENR_SPI_EN_MASK (1 << 0) /* SPI Enable */
29 #define ZYNQ_SPI_FIFO_DEPTH 128
30 #ifndef CONFIG_SYS_ZYNQ_SPI_WAIT
31 #define CONFIG_SYS_ZYNQ_SPI_WAIT (CONFIG_SYS_HZ/100) /* 10 ms */
34 /* zynq spi register set */
35 struct zynq_spi_regs
{
48 struct zynq_spi_slave
{
49 struct spi_slave slave
;
50 struct zynq_spi_regs
*base
;
58 static inline struct zynq_spi_slave
*to_zynq_spi_slave(struct spi_slave
*slave
)
60 return container_of(slave
, struct zynq_spi_slave
, slave
);
63 static inline struct zynq_spi_regs
*get_zynq_spi_base(int dev
)
66 return (struct zynq_spi_regs
*)ZYNQ_SPI_BASEADDR1
;
68 return (struct zynq_spi_regs
*)ZYNQ_SPI_BASEADDR0
;
71 static void zynq_spi_init_hw(struct zynq_spi_slave
*zslave
)
76 writel(~ZYNQ_SPI_ENR_SPI_EN_MASK
, &zslave
->base
->enr
);
78 /* Disable Interrupts */
79 writel(ZYNQ_SPI_IXR_ALL_MASK
, &zslave
->base
->idr
);
82 while (readl(&zslave
->base
->isr
) &
83 ZYNQ_SPI_IXR_RXNEMPTY_MASK
)
84 readl(&zslave
->base
->rxdr
);
86 /* Clear Interrupts */
87 writel(ZYNQ_SPI_IXR_ALL_MASK
, &zslave
->base
->isr
);
89 /* Manual slave select and Auto start */
90 confr
= ZYNQ_SPI_CR_MCS_MASK
| ZYNQ_SPI_CR_CS_MASK
|
91 ZYNQ_SPI_CR_MSTREN_MASK
;
92 confr
&= ~ZYNQ_SPI_CR_MSA_MASK
;
93 writel(confr
, &zslave
->base
->cr
);
96 writel(ZYNQ_SPI_ENR_SPI_EN_MASK
, &zslave
->base
->enr
);
99 int spi_cs_is_valid(unsigned int bus
, unsigned int cs
)
101 /* 2 bus with 3 chipselect */
102 return bus
< 2 && cs
< 3;
105 void spi_cs_activate(struct spi_slave
*slave
)
107 struct zynq_spi_slave
*zslave
= to_zynq_spi_slave(slave
);
110 debug("spi_cs_activate: 0x%08x\n", (u32
)slave
);
112 clrbits_le32(&zslave
->base
->cr
, ZYNQ_SPI_CR_CS_MASK
);
113 cr
= readl(&zslave
->base
->cr
);
115 * CS cal logic: CS[13:10]
120 cr
|= (~(0x1 << slave
->cs
) << 10) & ZYNQ_SPI_CR_CS_MASK
;
121 writel(cr
, &zslave
->base
->cr
);
124 void spi_cs_deactivate(struct spi_slave
*slave
)
126 struct zynq_spi_slave
*zslave
= to_zynq_spi_slave(slave
);
128 debug("spi_cs_deactivate: 0x%08x\n", (u32
)slave
);
130 setbits_le32(&zslave
->base
->cr
, ZYNQ_SPI_CR_CS_MASK
);
138 struct spi_slave
*spi_setup_slave(unsigned int bus
, unsigned int cs
,
139 unsigned int max_hz
, unsigned int mode
)
141 struct zynq_spi_slave
*zslave
;
143 if (!spi_cs_is_valid(bus
, cs
))
146 zslave
= spi_alloc_slave(struct zynq_spi_slave
, bus
, cs
);
148 printf("SPI_error: Fail to allocate zynq_spi_slave\n");
152 zslave
->base
= get_zynq_spi_base(bus
);
154 zslave
->fifo_depth
= ZYNQ_SPI_FIFO_DEPTH
;
155 zslave
->input_hz
= 166666700;
156 zslave
->speed_hz
= zslave
->input_hz
/ 2;
157 zslave
->req_hz
= max_hz
;
159 /* init the zynq spi hw */
160 zynq_spi_init_hw(zslave
);
162 return &zslave
->slave
;
165 void spi_free_slave(struct spi_slave
*slave
)
167 struct zynq_spi_slave
*zslave
= to_zynq_spi_slave(slave
);
169 debug("spi_free_slave: 0x%08x\n", (u32
)slave
);
173 int spi_claim_bus(struct spi_slave
*slave
)
175 struct zynq_spi_slave
*zslave
= to_zynq_spi_slave(slave
);
177 u8 baud_rate_val
= 0;
179 writel(~ZYNQ_SPI_ENR_SPI_EN_MASK
, &zslave
->base
->enr
);
181 /* Set the SPI Clock phase and polarities */
182 confr
= readl(&zslave
->base
->cr
);
183 confr
&= ~(ZYNQ_SPI_CR_CPHA_MASK
| ZYNQ_SPI_CR_CPOL_MASK
);
184 if (zslave
->mode
& SPI_CPHA
)
185 confr
|= ZYNQ_SPI_CR_CPHA_MASK
;
186 if (zslave
->mode
& SPI_CPOL
)
187 confr
|= ZYNQ_SPI_CR_CPOL_MASK
;
189 /* Set the clock frequency */
190 if (zslave
->req_hz
== 0) {
191 /* Set baudrate x8, if the req_hz is 0 */
193 } else if (zslave
->speed_hz
!= zslave
->req_hz
) {
194 while ((baud_rate_val
< 8) &&
196 (2 << baud_rate_val
)) > zslave
->req_hz
))
198 zslave
->speed_hz
= zslave
->req_hz
/ (2 << baud_rate_val
);
200 confr
&= ~ZYNQ_SPI_CR_BRD_MASK
;
201 confr
|= (baud_rate_val
<< 3);
202 writel(confr
, &zslave
->base
->cr
);
204 writel(ZYNQ_SPI_ENR_SPI_EN_MASK
, &zslave
->base
->enr
);
209 void spi_release_bus(struct spi_slave
*slave
)
211 struct zynq_spi_slave
*zslave
= to_zynq_spi_slave(slave
);
213 debug("spi_release_bus: 0x%08x\n", (u32
)slave
);
214 writel(~ZYNQ_SPI_ENR_SPI_EN_MASK
, &zslave
->base
->enr
);
217 int spi_xfer(struct spi_slave
*slave
, unsigned int bitlen
, const void *dout
,
218 void *din
, unsigned long flags
)
220 struct zynq_spi_slave
*zslave
= to_zynq_spi_slave(slave
);
221 u32 len
= bitlen
/ 8;
222 u32 tx_len
= len
, rx_len
= len
, tx_tvl
;
223 const u8
*tx_buf
= dout
;
224 u8
*rx_buf
= din
, buf
;
227 debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
228 slave
->bus
, slave
->cs
, bitlen
, len
, flags
);
234 debug("spi_xfer: Non byte aligned SPI transfer\n");
238 if (flags
& SPI_XFER_BEGIN
)
239 spi_cs_activate(slave
);
242 /* Write the data into TX FIFO - tx threshold is fifo_depth */
244 while ((tx_tvl
< zslave
->fifo_depth
) && tx_len
) {
249 writel(buf
, &zslave
->base
->txdr
);
254 /* Check TX FIFO completion */
256 status
= readl(&zslave
->base
->isr
);
257 while (!(status
& ZYNQ_SPI_IXR_TXOW_MASK
)) {
258 if (get_timer(ts
) > CONFIG_SYS_ZYNQ_SPI_WAIT
) {
259 printf("spi_xfer: Timeout! TX FIFO not full\n");
262 status
= readl(&zslave
->base
->isr
);
265 /* Read the data from RX FIFO */
266 status
= readl(&zslave
->base
->isr
);
267 while (status
& ZYNQ_SPI_IXR_RXNEMPTY_MASK
) {
268 buf
= readl(&zslave
->base
->rxdr
);
271 status
= readl(&zslave
->base
->isr
);
276 if (flags
& SPI_XFER_END
)
277 spi_cs_deactivate(slave
);