blob: 2963f48bb028d5cf7c84e2d10afc711bb08fb1f3 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Jagan Teki7fbea8a2015-08-17 18:38:06 +05302/*
3 * (C) Copyright 2013 Xilinx, Inc.
4 * (C) Copyright 2015 Jagan Teki <jteki@openedev.com>
5 *
6 * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
Jagan Teki7fbea8a2015-08-17 18:38:06 +05307 */
8
T Karthik Reddyb1f0d3d2020-02-04 05:47:45 -07009#include <clk.h>
Jagan Teki7fbea8a2015-08-17 18:38:06 +053010#include <common.h>
11#include <dm.h>
T Karthik Reddyb1f0d3d2020-02-04 05:47:45 -070012#include <dm/device_compat.h>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Jagan Teki7fbea8a2015-08-17 18:38:06 +053014#include <malloc.h>
15#include <spi.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060016#include <asm/global_data.h>
Jagan Teki7fbea8a2015-08-17 18:38:06 +053017#include <asm/io.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060018#include <linux/bitops.h>
Jagan Teki7fbea8a2015-08-17 18:38:06 +053019
20DECLARE_GLOBAL_DATA_PTR;
21
22/* zynq qspi register bit masks ZYNQ_QSPI_<REG>_<BIT>_MASK */
Jagan Tekif94b3f72015-10-22 20:40:16 +053023#define ZYNQ_QSPI_CR_IFMODE_MASK BIT(31) /* Flash intrface mode*/
24#define ZYNQ_QSPI_CR_MSA_MASK BIT(15) /* Manual start enb */
25#define ZYNQ_QSPI_CR_MCS_MASK BIT(14) /* Manual chip select */
26#define ZYNQ_QSPI_CR_PCS_MASK BIT(10) /* Peri chip select */
Jagan Tekie1af6ae2015-10-22 21:06:37 +053027#define ZYNQ_QSPI_CR_FW_MASK GENMASK(7, 6) /* FIFO width */
28#define ZYNQ_QSPI_CR_SS_MASK GENMASK(13, 10) /* Slave Select */
29#define ZYNQ_QSPI_CR_BAUD_MASK GENMASK(5, 3) /* Baud rate div */
Jagan Tekif94b3f72015-10-22 20:40:16 +053030#define ZYNQ_QSPI_CR_CPHA_MASK BIT(2) /* Clock phase */
31#define ZYNQ_QSPI_CR_CPOL_MASK BIT(1) /* Clock polarity */
32#define ZYNQ_QSPI_CR_MSTREN_MASK BIT(0) /* Mode select */
33#define ZYNQ_QSPI_IXR_RXNEMPTY_MASK BIT(4) /* RX_FIFO_not_empty */
34#define ZYNQ_QSPI_IXR_TXOW_MASK BIT(2) /* TX_FIFO_not_full */
Jagan Tekie1af6ae2015-10-22 21:06:37 +053035#define ZYNQ_QSPI_IXR_ALL_MASK GENMASK(6, 0) /* All IXR bits */
Jagan Tekif94b3f72015-10-22 20:40:16 +053036#define ZYNQ_QSPI_ENR_SPI_EN_MASK BIT(0) /* SPI Enable */
Nathan Rossib1150782015-12-09 00:44:40 +100037#define ZYNQ_QSPI_LQSPICFG_LQMODE_MASK BIT(31) /* Linear QSPI Mode */
Jagan Teki7fbea8a2015-08-17 18:38:06 +053038
39/* zynq qspi Transmit Data Register */
40#define ZYNQ_QSPI_TXD_00_00_OFFSET 0x1C /* Transmit 4-byte inst */
41#define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80 /* Transmit 1-byte inst */
42#define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84 /* Transmit 2-byte inst */
43#define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88 /* Transmit 3-byte inst */
44
45#define ZYNQ_QSPI_TXFIFO_THRESHOLD 1 /* Tx FIFO threshold level*/
46#define ZYNQ_QSPI_RXFIFO_THRESHOLD 32 /* Rx FIFO threshold level */
47
48#define ZYNQ_QSPI_CR_BAUD_MAX 8 /* Baud rate divisor max val */
49#define ZYNQ_QSPI_CR_BAUD_SHIFT 3 /* Baud rate divisor shift */
50#define ZYNQ_QSPI_CR_SS_SHIFT 10 /* Slave select shift */
51
Siva Durga Prasad Paladugu4495fd62022-01-30 22:22:39 -070052#define ZYNQ_QSPI_MAX_BAUD_RATE 0x7
53#define ZYNQ_QSPI_DEFAULT_BAUD_RATE 0x2
54
Jagan Teki7fbea8a2015-08-17 18:38:06 +053055#define ZYNQ_QSPI_FIFO_DEPTH 63
Ashok Reddy Somacaecfe62020-05-18 01:11:00 -060056#define ZYNQ_QSPI_WAIT (CONFIG_SYS_HZ / 100) /* 10 ms */
Jagan Teki7fbea8a2015-08-17 18:38:06 +053057
58/* zynq qspi register set */
59struct zynq_qspi_regs {
60 u32 cr; /* 0x00 */
61 u32 isr; /* 0x04 */
62 u32 ier; /* 0x08 */
63 u32 idr; /* 0x0C */
64 u32 imr; /* 0x10 */
65 u32 enr; /* 0x14 */
66 u32 dr; /* 0x18 */
67 u32 txd0r; /* 0x1C */
68 u32 drxr; /* 0x20 */
69 u32 sicr; /* 0x24 */
70 u32 txftr; /* 0x28 */
71 u32 rxftr; /* 0x2C */
72 u32 gpior; /* 0x30 */
73 u32 reserved0[19];
74 u32 txd1r; /* 0x80 */
75 u32 txd2r; /* 0x84 */
76 u32 txd3r; /* 0x88 */
Nathan Rossib1150782015-12-09 00:44:40 +100077 u32 reserved1[5];
78 u32 lqspicfg; /* 0xA0 */
79 u32 lqspists; /* 0xA4 */
Jagan Teki7fbea8a2015-08-17 18:38:06 +053080};
81
82/* zynq qspi platform data */
Simon Glassb75b15b2020-12-03 16:55:23 -070083struct zynq_qspi_plat {
Jagan Teki7fbea8a2015-08-17 18:38:06 +053084 struct zynq_qspi_regs *regs;
85 u32 frequency; /* input frequency */
86 u32 speed_hz;
87};
88
89/* zynq qspi priv */
90struct zynq_qspi_priv {
91 struct zynq_qspi_regs *regs;
92 u8 cs;
93 u8 mode;
94 u8 fifo_depth;
95 u32 freq; /* required frequency */
96 const void *tx_buf;
97 void *rx_buf;
98 unsigned len;
99 int bytes_to_transfer;
100 int bytes_to_receive;
101 unsigned int is_inst;
102 unsigned cs_change:1;
103};
104
Simon Glassaad29ae2020-12-03 16:55:21 -0700105static int zynq_qspi_of_to_plat(struct udevice *bus)
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530106{
Simon Glass95588622020-12-22 19:30:28 -0700107 struct zynq_qspi_plat *plat = dev_get_plat(bus);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530108 const void *blob = gd->fdt_blob;
Simon Glassdd79d6e2017-01-17 16:52:55 -0700109 int node = dev_of_offset(bus);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530110
111 plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
112 node, "reg");
113
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530114 return 0;
115}
116
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700117/**
118 * zynq_qspi_init_hw - Initialize the hardware
119 * @priv: Pointer to the zynq_qspi_priv structure
120 *
121 * The default settings of the QSPI controller's configurable parameters on
122 * reset are
123 * - Master mode
124 * - Baud rate divisor is set to 2
125 * - Threshold value for TX FIFO not full interrupt is set to 1
126 * - Flash memory interface mode enabled
127 * - Size of the word to be transferred as 8 bit
128 * This function performs the following actions
129 * - Disable and clear all the interrupts
130 * - Enable manual slave select
131 * - Enable auto start
132 * - Deselect all the chip select lines
133 * - Set the size of the word to be transferred as 32 bit
134 * - Set the little endian mode of TX FIFO and
135 * - Enable the QSPI controller
136 */
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530137static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
138{
139 struct zynq_qspi_regs *regs = priv->regs;
140 u32 confr;
141
142 /* Disable QSPI */
143 writel(~ZYNQ_QSPI_ENR_SPI_EN_MASK, &regs->enr);
144
145 /* Disable Interrupts */
146 writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->idr);
147
148 /* Clear the TX and RX threshold reg */
149 writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, &regs->txftr);
150 writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, &regs->rxftr);
151
152 /* Clear the RX FIFO */
153 while (readl(&regs->isr) & ZYNQ_QSPI_IXR_RXNEMPTY_MASK)
154 readl(&regs->drxr);
155
156 /* Clear Interrupts */
157 writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->isr);
158
159 /* Manual slave select and Auto start */
160 confr = readl(&regs->cr);
161 confr &= ~ZYNQ_QSPI_CR_MSA_MASK;
162 confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
163 ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
164 ZYNQ_QSPI_CR_MSTREN_MASK;
165 writel(confr, &regs->cr);
166
Nathan Rossib1150782015-12-09 00:44:40 +1000167 /* Disable the LQSPI feature */
168 confr = readl(&regs->lqspicfg);
169 confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
170 writel(confr, &regs->lqspicfg);
171
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530172 /* Enable SPI */
173 writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, &regs->enr);
174}
175
176static int zynq_qspi_probe(struct udevice *bus)
177{
Simon Glassb75b15b2020-12-03 16:55:23 -0700178 struct zynq_qspi_plat *plat = dev_get_plat(bus);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530179 struct zynq_qspi_priv *priv = dev_get_priv(bus);
T Karthik Reddyb1f0d3d2020-02-04 05:47:45 -0700180 struct clk clk;
181 unsigned long clock;
182 int ret;
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530183
184 priv->regs = plat->regs;
185 priv->fifo_depth = ZYNQ_QSPI_FIFO_DEPTH;
186
T Karthik Reddyb1f0d3d2020-02-04 05:47:45 -0700187 ret = clk_get_by_name(bus, "ref_clk", &clk);
188 if (ret < 0) {
189 dev_err(bus, "failed to get clock\n");
190 return ret;
191 }
192
193 clock = clk_get_rate(&clk);
194 if (IS_ERR_VALUE(clock)) {
195 dev_err(bus, "failed to get rate\n");
196 return clock;
197 }
198
199 ret = clk_enable(&clk);
Michal Simek41710952021-02-09 15:28:15 +0100200 if (ret) {
T Karthik Reddyb1f0d3d2020-02-04 05:47:45 -0700201 dev_err(bus, "failed to enable clock\n");
202 return ret;
203 }
204
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530205 /* init the zynq spi hw */
206 zynq_qspi_init_hw(priv);
207
T Karthik Reddyb1f0d3d2020-02-04 05:47:45 -0700208 plat->frequency = clock;
209 plat->speed_hz = plat->frequency / 2;
210
211 debug("%s: max-frequency=%d\n", __func__, plat->speed_hz);
212
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530213 return 0;
214}
215
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700216/**
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530217 * zynq_qspi_read_data - Copy data to RX buffer
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700218 * @priv: Pointer to the zynq_qspi_priv structure
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530219 * @data: The 32 bit variable where data is stored
220 * @size: Number of bytes to be copied from data to RX buffer
221 */
222static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size)
223{
224 u8 byte3;
225
226 debug("%s: data 0x%04x rx_buf addr: 0x%08x size %d\n", __func__ ,
227 data, (unsigned)(priv->rx_buf), size);
228
229 if (priv->rx_buf) {
230 switch (size) {
231 case 1:
232 *((u8 *)priv->rx_buf) = data;
233 priv->rx_buf += 1;
234 break;
235 case 2:
Siva Durga Prasad Paladugu99844ac2022-01-30 22:22:37 -0700236 *((u8 *)priv->rx_buf) = data;
237 priv->rx_buf += 1;
238 *((u8 *)priv->rx_buf) = (u8)(data >> 8);
239 priv->rx_buf += 1;
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530240 break;
241 case 3:
Siva Durga Prasad Paladugu99844ac2022-01-30 22:22:37 -0700242 *((u8 *)priv->rx_buf) = data;
243 priv->rx_buf += 1;
244 *((u8 *)priv->rx_buf) = (u8)(data >> 8);
245 priv->rx_buf += 1;
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530246 byte3 = (u8)(data >> 16);
247 *((u8 *)priv->rx_buf) = byte3;
248 priv->rx_buf += 1;
249 break;
250 case 4:
251 /* Can not assume word aligned buffer */
252 memcpy(priv->rx_buf, &data, size);
253 priv->rx_buf += 4;
254 break;
255 default:
256 /* This will never execute */
257 break;
258 }
259 }
260 priv->bytes_to_receive -= size;
261 if (priv->bytes_to_receive < 0)
262 priv->bytes_to_receive = 0;
263}
264
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700265/**
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530266 * zynq_qspi_write_data - Copy data from TX buffer
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700267 * @priv: Pointer to the zynq_qspi_priv structure
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530268 * @data: Pointer to the 32 bit variable where data is to be copied
269 * @size: Number of bytes to be copied from TX buffer to data
270 */
271static void zynq_qspi_write_data(struct zynq_qspi_priv *priv,
272 u32 *data, u8 size)
273{
274 if (priv->tx_buf) {
275 switch (size) {
276 case 1:
277 *data = *((u8 *)priv->tx_buf);
278 priv->tx_buf += 1;
279 *data |= 0xFFFFFF00;
280 break;
281 case 2:
Siva Durga Prasad Paladugu5ff1e242022-01-30 22:22:38 -0700282 *data = *((u8 *)priv->tx_buf);
283 priv->tx_buf += 1;
284 *data |= (*((u8 *)priv->tx_buf) << 8);
285 priv->tx_buf += 1;
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530286 *data |= 0xFFFF0000;
287 break;
288 case 3:
Siva Durga Prasad Paladugu5ff1e242022-01-30 22:22:38 -0700289 *data = *((u8 *)priv->tx_buf);
290 priv->tx_buf += 1;
291 *data |= (*((u8 *)priv->tx_buf) << 8);
292 priv->tx_buf += 1;
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530293 *data |= (*((u8 *)priv->tx_buf) << 16);
294 priv->tx_buf += 1;
295 *data |= 0xFF000000;
296 break;
297 case 4:
298 /* Can not assume word aligned buffer */
299 memcpy(data, priv->tx_buf, size);
300 priv->tx_buf += 4;
301 break;
302 default:
303 /* This will never execute */
304 break;
305 }
306 } else {
307 *data = 0;
308 }
309
310 debug("%s: data 0x%08x tx_buf addr: 0x%08x size %d\n", __func__,
311 *data, (u32)priv->tx_buf, size);
312
313 priv->bytes_to_transfer -= size;
314 if (priv->bytes_to_transfer < 0)
315 priv->bytes_to_transfer = 0;
316}
317
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700318/**
319 * zynq_qspi_chipselect - Select or deselect the chip select line
320 * @priv: Pointer to the zynq_qspi_priv structure
321 * @is_on: Select(1) or deselect (0) the chip select line
322 */
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530323static void zynq_qspi_chipselect(struct zynq_qspi_priv *priv, int is_on)
324{
325 u32 confr;
326 struct zynq_qspi_regs *regs = priv->regs;
327
328 confr = readl(&regs->cr);
329
330 if (is_on) {
331 /* Select the slave */
332 confr &= ~ZYNQ_QSPI_CR_SS_MASK;
333 confr |= (~(1 << priv->cs) << ZYNQ_QSPI_CR_SS_SHIFT) &
334 ZYNQ_QSPI_CR_SS_MASK;
335 } else
336 /* Deselect the slave */
337 confr |= ZYNQ_QSPI_CR_SS_MASK;
338
339 writel(confr, &regs->cr);
340}
341
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700342/**
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530343 * zynq_qspi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700344 * @priv: Pointer to the zynq_qspi_priv structure
345 * @size: Number of bytes to be copied to fifo
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530346 */
347static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
348{
349 u32 data = 0;
350 u32 fifocount = 0;
351 unsigned len, offset;
352 struct zynq_qspi_regs *regs = priv->regs;
353 static const unsigned offsets[4] = {
354 ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
355 ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
356
357 while ((fifocount < size) &&
358 (priv->bytes_to_transfer > 0)) {
359 if (priv->bytes_to_transfer >= 4) {
360 if (priv->tx_buf) {
361 memcpy(&data, priv->tx_buf, 4);
362 priv->tx_buf += 4;
363 } else {
364 data = 0;
365 }
366 writel(data, &regs->txd0r);
367 priv->bytes_to_transfer -= 4;
368 fifocount++;
369 } else {
370 /* Write TXD1, TXD2, TXD3 only if TxFIFO is empty. */
371 if (!(readl(&regs->isr)
372 & ZYNQ_QSPI_IXR_TXOW_MASK) &&
373 !priv->rx_buf)
374 return;
375 len = priv->bytes_to_transfer;
376 zynq_qspi_write_data(priv, &data, len);
377 offset = (priv->rx_buf) ? offsets[0] : offsets[len];
378 writel(data, &regs->cr + (offset / 4));
379 }
380 }
381}
382
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700383/**
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530384 * zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700385 * @priv: Pointer to the zynq_qspi structure
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530386 *
387 * This function handles TX empty and Mode Fault interrupts only.
388 * On TX empty interrupt this function reads the received data from RX FIFO and
389 * fills the TX FIFO if there is any data remaining to be transferred.
390 * On Mode Fault interrupt this function indicates that transfer is completed,
391 * the SPI subsystem will identify the error as the remaining bytes to be
392 * transferred is non-zero.
393 *
394 * returns: 0 for poll timeout
395 * 1 transfer operation complete
396 */
397static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv)
398{
399 struct zynq_qspi_regs *regs = priv->regs;
400 u32 rxindex = 0;
401 u32 rxcount;
402 u32 status, timeout;
403
404 /* Poll until any of the interrupt status bits are set */
405 timeout = get_timer(0);
406 do {
407 status = readl(&regs->isr);
408 } while ((status == 0) &&
Ashok Reddy Somacaecfe62020-05-18 01:11:00 -0600409 (get_timer(timeout) < ZYNQ_QSPI_WAIT));
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530410
411 if (status == 0) {
412 printf("zynq_qspi_irq_poll: Timeout!\n");
413 return -ETIMEDOUT;
414 }
415
416 writel(status, &regs->isr);
417
418 /* Disable all interrupts */
419 writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->idr);
420 if ((status & ZYNQ_QSPI_IXR_TXOW_MASK) ||
421 (status & ZYNQ_QSPI_IXR_RXNEMPTY_MASK)) {
422 /*
423 * This bit is set when Tx FIFO has < THRESHOLD entries. We have
424 * the THRESHOLD value set to 1, so this bit indicates Tx FIFO
425 * is empty
426 */
427 rxcount = priv->bytes_to_receive - priv->bytes_to_transfer;
428 rxcount = (rxcount % 4) ? ((rxcount/4)+1) : (rxcount/4);
429 while ((rxindex < rxcount) &&
430 (rxindex < ZYNQ_QSPI_RXFIFO_THRESHOLD)) {
431 /* Read out the data from the RX FIFO */
432 u32 data;
433 data = readl(&regs->drxr);
434
435 if (priv->bytes_to_receive >= 4) {
436 if (priv->rx_buf) {
437 memcpy(priv->rx_buf, &data, 4);
438 priv->rx_buf += 4;
439 }
440 priv->bytes_to_receive -= 4;
441 } else {
442 zynq_qspi_read_data(priv, data,
443 priv->bytes_to_receive);
444 }
445 rxindex++;
446 }
447
448 if (priv->bytes_to_transfer) {
449 /* There is more data to send */
450 zynq_qspi_fill_tx_fifo(priv,
451 ZYNQ_QSPI_RXFIFO_THRESHOLD);
452
453 writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->ier);
454 } else {
455 /*
456 * If transfer and receive is completed then only send
457 * complete signal
458 */
459 if (!priv->bytes_to_receive) {
460 /* return operation complete */
461 writel(ZYNQ_QSPI_IXR_ALL_MASK,
462 &regs->idr);
463 return 1;
464 }
465 }
466 }
467
468 return 0;
469}
470
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700471/**
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530472 * zynq_qspi_start_transfer - Initiates the QSPI transfer
Ashok Reddy Soma27e770a2020-01-28 07:39:04 -0700473 * @priv: Pointer to the zynq_qspi_priv structure
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530474 *
475 * This function fills the TX FIFO, starts the QSPI transfer, and waits for the
476 * transfer to be completed.
477 *
478 * returns: Number of bytes transferred in the last transfer
479 */
480static int zynq_qspi_start_transfer(struct zynq_qspi_priv *priv)
481{
482 u32 data = 0;
483 struct zynq_qspi_regs *regs = priv->regs;
484
485 debug("%s: qspi: 0x%08x transfer: 0x%08x len: %d\n", __func__,
486 (u32)priv, (u32)priv, priv->len);
487
488 priv->bytes_to_transfer = priv->len;
489 priv->bytes_to_receive = priv->len;
490
491 if (priv->len < 4)
492 zynq_qspi_fill_tx_fifo(priv, priv->len);
493 else
494 zynq_qspi_fill_tx_fifo(priv, priv->fifo_depth);
495
496 writel(ZYNQ_QSPI_IXR_ALL_MASK, &regs->ier);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530497
498 /* wait for completion */
499 do {
500 data = zynq_qspi_irq_poll(priv);
501 } while (data == 0);
502
503 return (priv->len) - (priv->bytes_to_transfer);
504}
505
506static int zynq_qspi_transfer(struct zynq_qspi_priv *priv)
507{
508 unsigned cs_change = 1;
509 int status = 0;
510
511 while (1) {
512 /* Select the chip if required */
513 if (cs_change)
514 zynq_qspi_chipselect(priv, 1);
515
516 cs_change = priv->cs_change;
517
518 if (!priv->tx_buf && !priv->rx_buf && priv->len) {
519 status = -1;
520 break;
521 }
522
523 /* Request the transfer */
524 if (priv->len) {
525 status = zynq_qspi_start_transfer(priv);
526 priv->is_inst = 0;
527 }
528
529 if (status != priv->len) {
530 if (status > 0)
531 status = -EMSGSIZE;
532 debug("zynq_qspi_transfer:%d len:%d\n",
533 status, priv->len);
534 break;
535 }
536 status = 0;
537
538 if (cs_change)
539 /* Deselect the chip */
540 zynq_qspi_chipselect(priv, 0);
541
542 break;
543 }
544
Vipul Kumar72cf0c92018-06-25 14:13:57 +0530545 return status;
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530546}
547
548static int zynq_qspi_claim_bus(struct udevice *dev)
549{
550 struct udevice *bus = dev->parent;
551 struct zynq_qspi_priv *priv = dev_get_priv(bus);
552 struct zynq_qspi_regs *regs = priv->regs;
553
554 writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, &regs->enr);
555
556 return 0;
557}
558
559static int zynq_qspi_release_bus(struct udevice *dev)
560{
561 struct udevice *bus = dev->parent;
562 struct zynq_qspi_priv *priv = dev_get_priv(bus);
563 struct zynq_qspi_regs *regs = priv->regs;
564
565 writel(~ZYNQ_QSPI_ENR_SPI_EN_MASK, &regs->enr);
566
567 return 0;
568}
569
570static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen,
571 const void *dout, void *din, unsigned long flags)
572{
573 struct udevice *bus = dev->parent;
574 struct zynq_qspi_priv *priv = dev_get_priv(bus);
Simon Glassb75b15b2020-12-03 16:55:23 -0700575 struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530576
577 priv->cs = slave_plat->cs;
578 priv->tx_buf = dout;
579 priv->rx_buf = din;
580 priv->len = bitlen / 8;
581
Jagan Tekicc7ae3d2015-10-25 09:31:54 +0530582 debug("zynq_qspi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
Simon Glass75e534b2020-12-16 21:20:07 -0700583 dev_seq(bus), slave_plat->cs, bitlen, priv->len, flags);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530584
585 /*
586 * Festering sore.
587 * Assume that the beginning of a transfer with bits to
588 * transmit must contain a device command.
589 */
590 if (dout && flags & SPI_XFER_BEGIN)
591 priv->is_inst = 1;
592 else
593 priv->is_inst = 0;
594
595 if (flags & SPI_XFER_END)
596 priv->cs_change = 1;
597 else
598 priv->cs_change = 0;
599
600 zynq_qspi_transfer(priv);
601
602 return 0;
603}
604
605static int zynq_qspi_set_speed(struct udevice *bus, uint speed)
606{
Simon Glass95588622020-12-22 19:30:28 -0700607 struct zynq_qspi_plat *plat = dev_get_plat(bus);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530608 struct zynq_qspi_priv *priv = dev_get_priv(bus);
609 struct zynq_qspi_regs *regs = priv->regs;
610 uint32_t confr;
611 u8 baud_rate_val = 0;
612
613 if (speed > plat->frequency)
614 speed = plat->frequency;
615
616 /* Set the clock frequency */
617 confr = readl(&regs->cr);
618 if (speed == 0) {
619 /* Set baudrate x8, if the freq is 0 */
620 baud_rate_val = 0x2;
621 } else if (plat->speed_hz != speed) {
622 while ((baud_rate_val < ZYNQ_QSPI_CR_BAUD_MAX) &&
623 ((plat->frequency /
624 (2 << baud_rate_val)) > speed))
625 baud_rate_val++;
626
Siva Durga Prasad Paladugu4495fd62022-01-30 22:22:39 -0700627 if (baud_rate_val > ZYNQ_QSPI_MAX_BAUD_RATE)
628 baud_rate_val = ZYNQ_QSPI_DEFAULT_BAUD_RATE;
629
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530630 plat->speed_hz = speed / (2 << baud_rate_val);
631 }
632 confr &= ~ZYNQ_QSPI_CR_BAUD_MASK;
633 confr |= (baud_rate_val << ZYNQ_QSPI_CR_BAUD_SHIFT);
634
635 writel(confr, &regs->cr);
636 priv->freq = speed;
637
Jagan Tekicc7ae3d2015-10-25 09:31:54 +0530638 debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530639
640 return 0;
641}
642
643static int zynq_qspi_set_mode(struct udevice *bus, uint mode)
644{
645 struct zynq_qspi_priv *priv = dev_get_priv(bus);
646 struct zynq_qspi_regs *regs = priv->regs;
647 uint32_t confr;
648
649 /* Set the SPI Clock phase and polarities */
650 confr = readl(&regs->cr);
651 confr &= ~(ZYNQ_QSPI_CR_CPHA_MASK | ZYNQ_QSPI_CR_CPOL_MASK);
652
Jagan Tekic27f1c12015-09-08 01:39:44 +0530653 if (mode & SPI_CPHA)
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530654 confr |= ZYNQ_QSPI_CR_CPHA_MASK;
Jagan Tekic27f1c12015-09-08 01:39:44 +0530655 if (mode & SPI_CPOL)
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530656 confr |= ZYNQ_QSPI_CR_CPOL_MASK;
657
658 writel(confr, &regs->cr);
659 priv->mode = mode;
660
Jagan Tekicc7ae3d2015-10-25 09:31:54 +0530661 debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530662
663 return 0;
664}
665
666static const struct dm_spi_ops zynq_qspi_ops = {
667 .claim_bus = zynq_qspi_claim_bus,
668 .release_bus = zynq_qspi_release_bus,
669 .xfer = zynq_qspi_xfer,
670 .set_speed = zynq_qspi_set_speed,
671 .set_mode = zynq_qspi_set_mode,
672};
673
674static const struct udevice_id zynq_qspi_ids[] = {
675 { .compatible = "xlnx,zynq-qspi-1.0" },
676 { }
677};
678
679U_BOOT_DRIVER(zynq_qspi) = {
680 .name = "zynq_qspi",
681 .id = UCLASS_SPI,
682 .of_match = zynq_qspi_ids,
683 .ops = &zynq_qspi_ops,
Simon Glassaad29ae2020-12-03 16:55:21 -0700684 .of_to_plat = zynq_qspi_of_to_plat,
Simon Glassb75b15b2020-12-03 16:55:23 -0700685 .plat_auto = sizeof(struct zynq_qspi_plat),
Simon Glass8a2b47f2020-12-03 16:55:17 -0700686 .priv_auto = sizeof(struct zynq_qspi_priv),
Jagan Teki7fbea8a2015-08-17 18:38:06 +0530687 .probe = zynq_qspi_probe,
688};