blob: c11736d96f33438e5b26128791a4de56fd792bd8 [file] [log] [blame]
Thomas Gleixner59899842019-05-20 19:08:04 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05302/*
3 * Xilinx Zynq UltraScale+ MPSoC Quad-SPI (QSPI) controller driver
4 * (master mode only)
5 *
6 * Copyright (C) 2009 - 2015 Xilinx, Inc.
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05307 */
8
9#include <linux/clk.h>
10#include <linux/delay.h>
11#include <linux/dma-mapping.h>
12#include <linux/dmaengine.h>
Olof Johanssonab7b7c72019-04-29 09:15:14 -070013#include <linux/firmware/xlnx-zynqmp.h>
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +053014#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <linux/module.h>
17#include <linux/of_irq.h>
18#include <linux/of_address.h>
19#include <linux/platform_device.h>
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +053020#include <linux/pm_runtime.h>
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +053021#include <linux/spi/spi.h>
22#include <linux/spinlock.h>
23#include <linux/workqueue.h>
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +020024#include <linux/spi/spi-mem.h>
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +053025
26/* Generic QSPI register offsets */
27#define GQSPI_CONFIG_OFST 0x00000100
28#define GQSPI_ISR_OFST 0x00000104
29#define GQSPI_IDR_OFST 0x0000010C
30#define GQSPI_IER_OFST 0x00000108
31#define GQSPI_IMASK_OFST 0x00000110
32#define GQSPI_EN_OFST 0x00000114
33#define GQSPI_TXD_OFST 0x0000011C
34#define GQSPI_RXD_OFST 0x00000120
35#define GQSPI_TX_THRESHOLD_OFST 0x00000128
36#define GQSPI_RX_THRESHOLD_OFST 0x0000012C
37#define GQSPI_LPBK_DLY_ADJ_OFST 0x00000138
38#define GQSPI_GEN_FIFO_OFST 0x00000140
39#define GQSPI_SEL_OFST 0x00000144
40#define GQSPI_GF_THRESHOLD_OFST 0x00000150
41#define GQSPI_FIFO_CTRL_OFST 0x0000014C
42#define GQSPI_QSPIDMA_DST_CTRL_OFST 0x0000080C
43#define GQSPI_QSPIDMA_DST_SIZE_OFST 0x00000804
44#define GQSPI_QSPIDMA_DST_STS_OFST 0x00000808
45#define GQSPI_QSPIDMA_DST_I_STS_OFST 0x00000814
46#define GQSPI_QSPIDMA_DST_I_EN_OFST 0x00000818
47#define GQSPI_QSPIDMA_DST_I_DIS_OFST 0x0000081C
48#define GQSPI_QSPIDMA_DST_I_MASK_OFST 0x00000820
49#define GQSPI_QSPIDMA_DST_ADDR_OFST 0x00000800
50#define GQSPI_QSPIDMA_DST_ADDR_MSB_OFST 0x00000828
Naga Sureshkumar Rellifae7b3c2022-10-11 11:50:38 +053051#define GQSPI_DATA_DLY_ADJ_OFST 0x000001F8
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +053052
53/* GQSPI register bit masks */
54#define GQSPI_SEL_MASK 0x00000001
55#define GQSPI_EN_MASK 0x00000001
56#define GQSPI_LPBK_DLY_ADJ_USE_LPBK_MASK 0x00000020
57#define GQSPI_ISR_WR_TO_CLR_MASK 0x00000002
58#define GQSPI_IDR_ALL_MASK 0x00000FBE
59#define GQSPI_CFG_MODE_EN_MASK 0xC0000000
60#define GQSPI_CFG_GEN_FIFO_START_MODE_MASK 0x20000000
61#define GQSPI_CFG_ENDIAN_MASK 0x04000000
62#define GQSPI_CFG_EN_POLL_TO_MASK 0x00100000
63#define GQSPI_CFG_WP_HOLD_MASK 0x00080000
64#define GQSPI_CFG_BAUD_RATE_DIV_MASK 0x00000038
65#define GQSPI_CFG_CLK_PHA_MASK 0x00000004
66#define GQSPI_CFG_CLK_POL_MASK 0x00000002
67#define GQSPI_CFG_START_GEN_FIFO_MASK 0x10000000
68#define GQSPI_GENFIFO_IMM_DATA_MASK 0x000000FF
69#define GQSPI_GENFIFO_DATA_XFER 0x00000100
70#define GQSPI_GENFIFO_EXP 0x00000200
71#define GQSPI_GENFIFO_MODE_SPI 0x00000400
72#define GQSPI_GENFIFO_MODE_DUALSPI 0x00000800
73#define GQSPI_GENFIFO_MODE_QUADSPI 0x00000C00
74#define GQSPI_GENFIFO_MODE_MASK 0x00000C00
75#define GQSPI_GENFIFO_CS_LOWER 0x00001000
76#define GQSPI_GENFIFO_CS_UPPER 0x00002000
77#define GQSPI_GENFIFO_BUS_LOWER 0x00004000
78#define GQSPI_GENFIFO_BUS_UPPER 0x00008000
79#define GQSPI_GENFIFO_BUS_BOTH 0x0000C000
80#define GQSPI_GENFIFO_BUS_MASK 0x0000C000
81#define GQSPI_GENFIFO_TX 0x00010000
82#define GQSPI_GENFIFO_RX 0x00020000
83#define GQSPI_GENFIFO_STRIPE 0x00040000
84#define GQSPI_GENFIFO_POLL 0x00080000
85#define GQSPI_GENFIFO_EXP_START 0x00000100
86#define GQSPI_FIFO_CTRL_RST_RX_FIFO_MASK 0x00000004
87#define GQSPI_FIFO_CTRL_RST_TX_FIFO_MASK 0x00000002
88#define GQSPI_FIFO_CTRL_RST_GEN_FIFO_MASK 0x00000001
89#define GQSPI_ISR_RXEMPTY_MASK 0x00000800
90#define GQSPI_ISR_GENFIFOFULL_MASK 0x00000400
91#define GQSPI_ISR_GENFIFONOT_FULL_MASK 0x00000200
92#define GQSPI_ISR_TXEMPTY_MASK 0x00000100
93#define GQSPI_ISR_GENFIFOEMPTY_MASK 0x00000080
94#define GQSPI_ISR_RXFULL_MASK 0x00000020
95#define GQSPI_ISR_RXNEMPTY_MASK 0x00000010
96#define GQSPI_ISR_TXFULL_MASK 0x00000008
97#define GQSPI_ISR_TXNOT_FULL_MASK 0x00000004
98#define GQSPI_ISR_POLL_TIME_EXPIRE_MASK 0x00000002
99#define GQSPI_IER_TXNOT_FULL_MASK 0x00000004
100#define GQSPI_IER_RXEMPTY_MASK 0x00000800
101#define GQSPI_IER_POLL_TIME_EXPIRE_MASK 0x00000002
102#define GQSPI_IER_RXNEMPTY_MASK 0x00000010
103#define GQSPI_IER_GENFIFOEMPTY_MASK 0x00000080
104#define GQSPI_IER_TXEMPTY_MASK 0x00000100
105#define GQSPI_QSPIDMA_DST_INTR_ALL_MASK 0x000000FE
106#define GQSPI_QSPIDMA_DST_STS_WTC 0x0000E000
107#define GQSPI_CFG_MODE_EN_DMA_MASK 0x80000000
108#define GQSPI_ISR_IDR_MASK 0x00000994
109#define GQSPI_QSPIDMA_DST_I_EN_DONE_MASK 0x00000002
110#define GQSPI_QSPIDMA_DST_I_STS_DONE_MASK 0x00000002
111#define GQSPI_IRQ_MASK 0x00000980
112
113#define GQSPI_CFG_BAUD_RATE_DIV_SHIFT 3
114#define GQSPI_GENFIFO_CS_SETUP 0x4
115#define GQSPI_GENFIFO_CS_HOLD 0x3
116#define GQSPI_TXD_DEPTH 64
117#define GQSPI_RX_FIFO_THRESHOLD 32
118#define GQSPI_RX_FIFO_FILL (GQSPI_RX_FIFO_THRESHOLD * 4)
119#define GQSPI_TX_FIFO_THRESHOLD_RESET_VAL 32
120#define GQSPI_TX_FIFO_FILL (GQSPI_TXD_DEPTH -\
121 GQSPI_TX_FIFO_THRESHOLD_RESET_VAL)
122#define GQSPI_GEN_FIFO_THRESHOLD_RESET_VAL 0X10
123#define GQSPI_QSPIDMA_DST_CTRL_RESET_VAL 0x803FFA00
124#define GQSPI_SELECT_FLASH_CS_LOWER 0x1
125#define GQSPI_SELECT_FLASH_CS_UPPER 0x2
126#define GQSPI_SELECT_FLASH_CS_BOTH 0x3
127#define GQSPI_SELECT_FLASH_BUS_LOWER 0x1
128#define GQSPI_SELECT_FLASH_BUS_UPPER 0x2
129#define GQSPI_SELECT_FLASH_BUS_BOTH 0x3
130#define GQSPI_BAUD_DIV_MAX 7 /* Baud rate divisor maximum */
131#define GQSPI_BAUD_DIV_SHIFT 2 /* Baud rate divisor shift */
132#define GQSPI_SELECT_MODE_SPI 0x1
133#define GQSPI_SELECT_MODE_DUALSPI 0x2
134#define GQSPI_SELECT_MODE_QUADSPI 0x4
135#define GQSPI_DMA_UNALIGN 0x3
136#define GQSPI_DEFAULT_NUM_CS 1 /* Default number of chip selects */
137
Amit Kumar Mahapatradd9c2322022-05-12 20:28:20 +0530138#define GQSPI_MAX_NUM_CS 2 /* Maximum number of chip selects */
139
Naga Sureshkumar Rellifae7b3c2022-10-11 11:50:38 +0530140#define GQSPI_USE_DATA_DLY 0x1
141#define GQSPI_USE_DATA_DLY_SHIFT 31
142#define GQSPI_DATA_DLY_ADJ_VALUE 0x2
143#define GQSPI_DATA_DLY_ADJ_SHIFT 28
144
145#define GQSPI_FREQ_37_5MHZ 37500000
146#define GQSPI_FREQ_40MHZ 40000000
147#define GQSPI_FREQ_100MHZ 100000000
148#define GQSPI_FREQ_150MHZ 150000000
149
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530150#define SPI_AUTOSUSPEND_TIMEOUT 3000
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530151enum mode_type {GQSPI_MODE_IO, GQSPI_MODE_DMA};
152
153/**
154 * struct zynqmp_qspi - Defines qspi driver instance
Amit Kumar Mahapatrab3b95302022-10-11 11:50:34 +0530155 * @ctlr: Pointer to the spi controller information
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530156 * @regs: Virtual address of the QSPI controller registers
157 * @refclk: Pointer to the peripheral clock
158 * @pclk: Pointer to the APB clock
159 * @irq: IRQ number
160 * @dev: Pointer to struct device
161 * @txbuf: Pointer to the TX buffer
162 * @rxbuf: Pointer to the RX buffer
163 * @bytes_to_transfer: Number of bytes left to transfer
164 * @bytes_to_receive: Number of bytes left to receive
165 * @genfifocs: Used for chip select
166 * @genfifobus: Used to select the upper or lower bus
167 * @dma_rx_bytes: Remaining bytes to receive by DMA mode
168 * @dma_addr: DMA address after mapping the kernel buffer
169 * @genfifoentry: Used for storing the genfifoentry instruction.
170 * @mode: Defines the mode in which QSPI is operating
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200171 * @data_completion: completion structure
Amit Kumar Mahapatrab3b95302022-10-11 11:50:34 +0530172 * @op_lock: Operational lock
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530173 * @speed_hz: Current SPI bus clock speed in hz
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530174 */
175struct zynqmp_qspi {
Quanyang Wang799f9232021-04-16 08:46:49 +0800176 struct spi_controller *ctlr;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530177 void __iomem *regs;
178 struct clk *refclk;
179 struct clk *pclk;
180 int irq;
181 struct device *dev;
182 const void *txbuf;
183 void *rxbuf;
184 int bytes_to_transfer;
185 int bytes_to_receive;
186 u32 genfifocs;
187 u32 genfifobus;
188 u32 dma_rx_bytes;
189 dma_addr_t dma_addr;
190 u32 genfifoentry;
191 enum mode_type mode;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200192 struct completion data_completion;
Quanyang Wanga0f65be2021-04-08 12:02:21 +0800193 struct mutex op_lock;
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530194 u32 speed_hz;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530195};
196
197/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200198 * zynqmp_gqspi_read - For GQSPI controller read operation
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530199 * @xqspi: Pointer to the zynqmp_qspi structure
200 * @offset: Offset from where to read
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200201 * Return: Value at the offset
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530202 */
203static u32 zynqmp_gqspi_read(struct zynqmp_qspi *xqspi, u32 offset)
204{
205 return readl_relaxed(xqspi->regs + offset);
206}
207
208/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200209 * zynqmp_gqspi_write - For GQSPI controller write operation
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530210 * @xqspi: Pointer to the zynqmp_qspi structure
211 * @offset: Offset where to write
212 * @val: Value to be written
213 */
214static inline void zynqmp_gqspi_write(struct zynqmp_qspi *xqspi, u32 offset,
215 u32 val)
216{
217 writel_relaxed(val, (xqspi->regs + offset));
218}
219
220/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200221 * zynqmp_gqspi_selectslave - For selection of slave device
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530222 * @instanceptr: Pointer to the zynqmp_qspi structure
Lee Jones4b42b0b2020-07-17 14:54:20 +0100223 * @slavecs: For chip select
224 * @slavebus: To check which bus is selected- upper or lower
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530225 */
226static void zynqmp_gqspi_selectslave(struct zynqmp_qspi *instanceptr,
227 u8 slavecs, u8 slavebus)
228{
229 /*
230 * Bus and CS lines selected here will be updated in the instance and
231 * used for subsequent GENFIFO entries during transfer.
232 */
233
234 /* Choose slave select line */
235 switch (slavecs) {
236 case GQSPI_SELECT_FLASH_CS_BOTH:
237 instanceptr->genfifocs = GQSPI_GENFIFO_CS_LOWER |
238 GQSPI_GENFIFO_CS_UPPER;
Dan Carpenter861a4812015-06-24 17:31:33 +0300239 break;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530240 case GQSPI_SELECT_FLASH_CS_UPPER:
241 instanceptr->genfifocs = GQSPI_GENFIFO_CS_UPPER;
242 break;
243 case GQSPI_SELECT_FLASH_CS_LOWER:
244 instanceptr->genfifocs = GQSPI_GENFIFO_CS_LOWER;
245 break;
246 default:
247 dev_warn(instanceptr->dev, "Invalid slave select\n");
248 }
249
250 /* Choose the bus */
251 switch (slavebus) {
252 case GQSPI_SELECT_FLASH_BUS_BOTH:
253 instanceptr->genfifobus = GQSPI_GENFIFO_BUS_LOWER |
254 GQSPI_GENFIFO_BUS_UPPER;
255 break;
256 case GQSPI_SELECT_FLASH_BUS_UPPER:
257 instanceptr->genfifobus = GQSPI_GENFIFO_BUS_UPPER;
258 break;
259 case GQSPI_SELECT_FLASH_BUS_LOWER:
260 instanceptr->genfifobus = GQSPI_GENFIFO_BUS_LOWER;
261 break;
262 default:
263 dev_warn(instanceptr->dev, "Invalid slave bus\n");
264 }
265}
266
267/**
Naga Sureshkumar Rellifae7b3c2022-10-11 11:50:38 +0530268 * zynqmp_qspi_set_tapdelay: To configure qspi tap delays
269 * @xqspi: Pointer to the zynqmp_qspi structure
270 * @baudrateval: Buadrate to configure
271 */
272static void zynqmp_qspi_set_tapdelay(struct zynqmp_qspi *xqspi, u32 baudrateval)
273{
274 u32 lpbkdlyadj = 0, datadlyadj = 0, clk_rate;
275 u32 reqhz = 0;
276
277 clk_rate = clk_get_rate(xqspi->refclk);
278 reqhz = (clk_rate / (GQSPI_BAUD_DIV_SHIFT << baudrateval));
279
280 if (reqhz <= GQSPI_FREQ_40MHZ) {
281 zynqmp_pm_set_tapdelay_bypass(PM_TAPDELAY_QSPI,
282 PM_TAPDELAY_BYPASS_ENABLE);
283 } else if (reqhz <= GQSPI_FREQ_100MHZ) {
284 zynqmp_pm_set_tapdelay_bypass(PM_TAPDELAY_QSPI,
285 PM_TAPDELAY_BYPASS_ENABLE);
286 lpbkdlyadj |= (GQSPI_LPBK_DLY_ADJ_USE_LPBK_MASK);
287 datadlyadj |= ((GQSPI_USE_DATA_DLY <<
288 GQSPI_USE_DATA_DLY_SHIFT) |
289 (GQSPI_DATA_DLY_ADJ_VALUE <<
290 GQSPI_DATA_DLY_ADJ_SHIFT));
291 } else if (reqhz <= GQSPI_FREQ_150MHZ) {
292 lpbkdlyadj |= GQSPI_LPBK_DLY_ADJ_USE_LPBK_MASK;
293 }
294 zynqmp_gqspi_write(xqspi, GQSPI_LPBK_DLY_ADJ_OFST, lpbkdlyadj);
295 zynqmp_gqspi_write(xqspi, GQSPI_DATA_DLY_ADJ_OFST, datadlyadj);
296}
297
298/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200299 * zynqmp_qspi_init_hw - Initialize the hardware
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530300 * @xqspi: Pointer to the zynqmp_qspi structure
301 *
302 * The default settings of the QSPI controller's configurable parameters on
303 * reset are
304 * - Master mode
305 * - TX threshold set to 1
306 * - RX threshold set to 1
307 * - Flash memory interface mode enabled
308 * This function performs the following actions
309 * - Disable and clear all the interrupts
310 * - Enable manual slave select
311 * - Enable manual start
312 * - Deselect all the chip select lines
Amit Kumar Mahapatra22742b82022-10-11 11:50:35 +0530313 * - Set the little endian mode of TX FIFO
314 * - Set clock phase
315 * - Set clock polarity and
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530316 * - Enable the QSPI controller
317 */
318static void zynqmp_qspi_init_hw(struct zynqmp_qspi *xqspi)
319{
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530320 u32 config_reg, baud_rate_val = 0;
321 ulong clk_rate;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530322
323 /* Select the GQSPI mode */
324 zynqmp_gqspi_write(xqspi, GQSPI_SEL_OFST, GQSPI_SEL_MASK);
325 /* Clear and disable interrupts */
326 zynqmp_gqspi_write(xqspi, GQSPI_ISR_OFST,
327 zynqmp_gqspi_read(xqspi, GQSPI_ISR_OFST) |
328 GQSPI_ISR_WR_TO_CLR_MASK);
329 /* Clear the DMA STS */
330 zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_I_STS_OFST,
331 zynqmp_gqspi_read(xqspi,
332 GQSPI_QSPIDMA_DST_I_STS_OFST));
333 zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_STS_OFST,
334 zynqmp_gqspi_read(xqspi,
335 GQSPI_QSPIDMA_DST_STS_OFST) |
336 GQSPI_QSPIDMA_DST_STS_WTC);
337 zynqmp_gqspi_write(xqspi, GQSPI_IDR_OFST, GQSPI_IDR_ALL_MASK);
338 zynqmp_gqspi_write(xqspi,
339 GQSPI_QSPIDMA_DST_I_DIS_OFST,
340 GQSPI_QSPIDMA_DST_INTR_ALL_MASK);
341 /* Disable the GQSPI */
342 zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
343 config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST);
344 config_reg &= ~GQSPI_CFG_MODE_EN_MASK;
345 /* Manual start */
346 config_reg |= GQSPI_CFG_GEN_FIFO_START_MODE_MASK;
347 /* Little endian by default */
348 config_reg &= ~GQSPI_CFG_ENDIAN_MASK;
349 /* Disable poll time out */
350 config_reg &= ~GQSPI_CFG_EN_POLL_TO_MASK;
351 /* Set hold bit */
352 config_reg |= GQSPI_CFG_WP_HOLD_MASK;
353 /* Clear pre-scalar by default */
354 config_reg &= ~GQSPI_CFG_BAUD_RATE_DIV_MASK;
Amit Kumar Mahapatra22742b82022-10-11 11:50:35 +0530355 /* Set CPHA */
356 if (xqspi->ctlr->mode_bits & SPI_CPHA)
357 config_reg |= GQSPI_CFG_CLK_PHA_MASK;
358 else
359 config_reg &= ~GQSPI_CFG_CLK_PHA_MASK;
360 /* Set CPOL */
361 if (xqspi->ctlr->mode_bits & SPI_CPOL)
362 config_reg |= GQSPI_CFG_CLK_POL_MASK;
363 else
364 config_reg &= ~GQSPI_CFG_CLK_POL_MASK;
365
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530366 /* Set the clock frequency */
367 clk_rate = clk_get_rate(xqspi->refclk);
368 while ((baud_rate_val < GQSPI_BAUD_DIV_MAX) &&
369 (clk_rate /
370 (GQSPI_BAUD_DIV_SHIFT << baud_rate_val)) > xqspi->speed_hz)
371 baud_rate_val++;
372
373 config_reg &= ~GQSPI_CFG_BAUD_RATE_DIV_MASK;
374 config_reg |= (baud_rate_val << GQSPI_CFG_BAUD_RATE_DIV_SHIFT);
375
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530376 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg);
377
Naga Sureshkumar Rellifae7b3c2022-10-11 11:50:38 +0530378 /* Set the tapdelay for clock frequency */
379 zynqmp_qspi_set_tapdelay(xqspi, baud_rate_val);
380
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530381 /* Clear the TX and RX FIFO */
382 zynqmp_gqspi_write(xqspi, GQSPI_FIFO_CTRL_OFST,
383 GQSPI_FIFO_CTRL_RST_RX_FIFO_MASK |
384 GQSPI_FIFO_CTRL_RST_TX_FIFO_MASK |
385 GQSPI_FIFO_CTRL_RST_GEN_FIFO_MASK);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530386 /* Reset thresholds */
387 zynqmp_gqspi_write(xqspi, GQSPI_TX_THRESHOLD_OFST,
388 GQSPI_TX_FIFO_THRESHOLD_RESET_VAL);
389 zynqmp_gqspi_write(xqspi, GQSPI_RX_THRESHOLD_OFST,
390 GQSPI_RX_FIFO_THRESHOLD);
391 zynqmp_gqspi_write(xqspi, GQSPI_GF_THRESHOLD_OFST,
392 GQSPI_GEN_FIFO_THRESHOLD_RESET_VAL);
393 zynqmp_gqspi_selectslave(xqspi,
394 GQSPI_SELECT_FLASH_CS_LOWER,
395 GQSPI_SELECT_FLASH_BUS_LOWER);
396 /* Initialize DMA */
397 zynqmp_gqspi_write(xqspi,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200398 GQSPI_QSPIDMA_DST_CTRL_OFST,
399 GQSPI_QSPIDMA_DST_CTRL_RESET_VAL);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530400
401 /* Enable the GQSPI */
402 zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, GQSPI_EN_MASK);
403}
404
405/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200406 * zynqmp_qspi_copy_read_data - Copy data to RX buffer
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530407 * @xqspi: Pointer to the zynqmp_qspi structure
408 * @data: The variable where data is stored
409 * @size: Number of bytes to be copied from data to RX buffer
410 */
411static void zynqmp_qspi_copy_read_data(struct zynqmp_qspi *xqspi,
412 ulong data, u8 size)
413{
414 memcpy(xqspi->rxbuf, &data, size);
415 xqspi->rxbuf += size;
416 xqspi->bytes_to_receive -= size;
417}
418
419/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200420 * zynqmp_qspi_chipselect - Select or deselect the chip select line
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530421 * @qspi: Pointer to the spi_device structure
422 * @is_high: Select(0) or deselect (1) the chip select line
423 */
424static void zynqmp_qspi_chipselect(struct spi_device *qspi, bool is_high)
425{
426 struct zynqmp_qspi *xqspi = spi_master_get_devdata(qspi->master);
427 ulong timeout;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200428 u32 genfifoentry = 0, statusreg;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530429
430 genfifoentry |= GQSPI_GENFIFO_MODE_SPI;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530431
432 if (!is_high) {
Amit Kumar Mahapatradd9c2322022-05-12 20:28:20 +0530433 if (!qspi->chip_select) {
434 xqspi->genfifobus = GQSPI_GENFIFO_BUS_LOWER;
435 xqspi->genfifocs = GQSPI_GENFIFO_CS_LOWER;
436 } else {
437 xqspi->genfifobus = GQSPI_GENFIFO_BUS_UPPER;
438 xqspi->genfifocs = GQSPI_GENFIFO_CS_UPPER;
439 }
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200440 genfifoentry |= xqspi->genfifobus;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530441 genfifoentry |= xqspi->genfifocs;
442 genfifoentry |= GQSPI_GENFIFO_CS_SETUP;
443 } else {
444 genfifoentry |= GQSPI_GENFIFO_CS_HOLD;
445 }
446
447 zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, genfifoentry);
448
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530449 /* Manually start the generic FIFO command */
450 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200451 zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST) |
452 GQSPI_CFG_START_GEN_FIFO_MASK);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530453
454 timeout = jiffies + msecs_to_jiffies(1000);
455
456 /* Wait until the generic FIFO command is empty */
457 do {
458 statusreg = zynqmp_gqspi_read(xqspi, GQSPI_ISR_OFST);
459
460 if ((statusreg & GQSPI_ISR_GENFIFOEMPTY_MASK) &&
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200461 (statusreg & GQSPI_ISR_TXEMPTY_MASK))
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530462 break;
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200463 cpu_relax();
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530464 } while (!time_after_eq(jiffies, timeout));
465
466 if (time_after_eq(jiffies, timeout))
467 dev_err(xqspi->dev, "Chip select timed out\n");
468}
469
470/**
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200471 * zynqmp_qspi_selectspimode - Selects SPI mode - x1 or x2 or x4.
472 * @xqspi: xqspi is a pointer to the GQSPI instance
473 * @spimode: spimode - SPI or DUAL or QUAD.
474 * Return: Mask to set desired SPI mode in GENFIFO entry.
475 */
476static inline u32 zynqmp_qspi_selectspimode(struct zynqmp_qspi *xqspi,
477 u8 spimode)
478{
479 u32 mask = 0;
480
481 switch (spimode) {
482 case GQSPI_SELECT_MODE_DUALSPI:
483 mask = GQSPI_GENFIFO_MODE_DUALSPI;
484 break;
485 case GQSPI_SELECT_MODE_QUADSPI:
486 mask = GQSPI_GENFIFO_MODE_QUADSPI;
487 break;
488 case GQSPI_SELECT_MODE_SPI:
489 mask = GQSPI_GENFIFO_MODE_SPI;
490 break;
491 default:
492 dev_warn(xqspi->dev, "Invalid SPI mode\n");
493 }
494
495 return mask;
496}
497
498/**
499 * zynqmp_qspi_config_op - Configure QSPI controller for specified
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530500 * transfer
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200501 * @xqspi: Pointer to the zynqmp_qspi structure
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530502 * @qspi: Pointer to the spi_device structure
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530503 *
504 * Sets the operational mode of QSPI controller for the next QSPI transfer and
505 * sets the requested clock frequency.
506 *
507 * Return: Always 0
508 *
509 * Note:
510 * If the requested frequency is not an exact match with what can be
511 * obtained using the pre-scalar value, the driver sets the clock
512 * frequency which is lower than the requested frequency (maximum lower)
513 * for the transfer.
514 *
515 * If the requested frequency is higher or lower than that is supported
516 * by the QSPI controller the driver will set the highest or lowest
517 * frequency supported by controller.
518 */
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200519static int zynqmp_qspi_config_op(struct zynqmp_qspi *xqspi,
520 struct spi_device *qspi)
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530521{
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530522 ulong clk_rate;
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530523 u32 config_reg, req_speed_hz, baud_rate_val = 0;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530524
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530525 req_speed_hz = qspi->max_speed_hz;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530526
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530527 if (xqspi->speed_hz != req_speed_hz) {
528 xqspi->speed_hz = req_speed_hz;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530529
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530530 /* Set the clock frequency */
531 /* If req_speed_hz == 0, default to lowest speed */
532 clk_rate = clk_get_rate(xqspi->refclk);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530533
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530534 while ((baud_rate_val < GQSPI_BAUD_DIV_MAX) &&
535 (clk_rate /
536 (GQSPI_BAUD_DIV_SHIFT << baud_rate_val)) >
537 req_speed_hz)
538 baud_rate_val++;
539
540 config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST);
541
542 config_reg &= ~GQSPI_CFG_BAUD_RATE_DIV_MASK;
543 config_reg |= (baud_rate_val << GQSPI_CFG_BAUD_RATE_DIV_SHIFT);
544 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg);
Naga Sureshkumar Rellifae7b3c2022-10-11 11:50:38 +0530545 zynqmp_qspi_set_tapdelay(xqspi, baud_rate_val);
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +0530546 }
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530547 return 0;
548}
549
550/**
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200551 * zynqmp_qspi_setup_op - Configure the QSPI controller
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530552 * @qspi: Pointer to the spi_device structure
553 *
554 * Sets the operational mode of QSPI controller for the next QSPI transfer,
555 * baud rate and divisor value to setup the requested qspi clock.
556 *
557 * Return: 0 on success; error value otherwise.
558 */
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200559static int zynqmp_qspi_setup_op(struct spi_device *qspi)
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530560{
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200561 struct spi_controller *ctlr = qspi->master;
562 struct zynqmp_qspi *xqspi = spi_controller_get_devdata(ctlr);
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200563
564 if (ctlr->busy)
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530565 return -EBUSY;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200566
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200567 zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, GQSPI_EN_MASK);
568
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530569 return 0;
570}
571
572/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200573 * zynqmp_qspi_filltxfifo - Fills the TX FIFO as long as there is room in
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530574 * the FIFO or the bytes required to be
575 * transmitted.
576 * @xqspi: Pointer to the zynqmp_qspi structure
577 * @size: Number of bytes to be copied from TX buffer to TX FIFO
578 */
579static void zynqmp_qspi_filltxfifo(struct zynqmp_qspi *xqspi, int size)
580{
581 u32 count = 0, intermediate;
582
Quanyang Wang8ad07d72021-04-08 12:02:22 +0800583 while ((xqspi->bytes_to_transfer > 0) && (count < size) && (xqspi->txbuf)) {
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530584 if (xqspi->bytes_to_transfer >= 4) {
Amit Kumar Mahapatra2530b3d2021-04-16 08:46:50 +0800585 memcpy(&intermediate, xqspi->txbuf, 4);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530586 xqspi->txbuf += 4;
587 xqspi->bytes_to_transfer -= 4;
Amit Kumar Mahapatra2530b3d2021-04-16 08:46:50 +0800588 count += 4;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530589 } else {
Amit Kumar Mahapatra2530b3d2021-04-16 08:46:50 +0800590 memcpy(&intermediate, xqspi->txbuf,
591 xqspi->bytes_to_transfer);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530592 xqspi->txbuf += xqspi->bytes_to_transfer;
593 xqspi->bytes_to_transfer = 0;
Amit Kumar Mahapatra2530b3d2021-04-16 08:46:50 +0800594 count += xqspi->bytes_to_transfer;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530595 }
Amit Kumar Mahapatra2530b3d2021-04-16 08:46:50 +0800596 zynqmp_gqspi_write(xqspi, GQSPI_TXD_OFST, intermediate);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530597 }
598}
599
600/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200601 * zynqmp_qspi_readrxfifo - Fills the RX FIFO as long as there is room in
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530602 * the FIFO.
603 * @xqspi: Pointer to the zynqmp_qspi structure
604 * @size: Number of bytes to be copied from RX buffer to RX FIFO
605 */
606static void zynqmp_qspi_readrxfifo(struct zynqmp_qspi *xqspi, u32 size)
607{
608 ulong data;
609 int count = 0;
610
611 while ((count < size) && (xqspi->bytes_to_receive > 0)) {
612 if (xqspi->bytes_to_receive >= 4) {
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200613 (*(u32 *)xqspi->rxbuf) =
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530614 zynqmp_gqspi_read(xqspi, GQSPI_RXD_OFST);
615 xqspi->rxbuf += 4;
616 xqspi->bytes_to_receive -= 4;
617 count += 4;
618 } else {
619 data = zynqmp_gqspi_read(xqspi, GQSPI_RXD_OFST);
620 count += xqspi->bytes_to_receive;
621 zynqmp_qspi_copy_read_data(xqspi, data,
622 xqspi->bytes_to_receive);
623 xqspi->bytes_to_receive = 0;
624 }
625 }
626}
627
628/**
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200629 * zynqmp_qspi_fillgenfifo - Fills the GENFIFO.
630 * @xqspi: Pointer to the zynqmp_qspi structure
631 * @nbits: Transfer/Receive buswidth.
632 * @genfifoentry: Variable in which GENFIFO mask is saved
633 */
634static void zynqmp_qspi_fillgenfifo(struct zynqmp_qspi *xqspi, u8 nbits,
635 u32 genfifoentry)
636{
637 u32 transfer_len = 0;
638
639 if (xqspi->txbuf) {
640 genfifoentry &= ~GQSPI_GENFIFO_RX;
641 genfifoentry |= GQSPI_GENFIFO_DATA_XFER;
642 genfifoentry |= GQSPI_GENFIFO_TX;
643 transfer_len = xqspi->bytes_to_transfer;
Quanyang Wang8ad07d72021-04-08 12:02:22 +0800644 } else if (xqspi->rxbuf) {
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200645 genfifoentry &= ~GQSPI_GENFIFO_TX;
646 genfifoentry |= GQSPI_GENFIFO_DATA_XFER;
647 genfifoentry |= GQSPI_GENFIFO_RX;
648 if (xqspi->mode == GQSPI_MODE_DMA)
649 transfer_len = xqspi->dma_rx_bytes;
650 else
651 transfer_len = xqspi->bytes_to_receive;
Quanyang Wang8ad07d72021-04-08 12:02:22 +0800652 } else {
653 /* Sending dummy circles here */
654 genfifoentry &= ~(GQSPI_GENFIFO_TX | GQSPI_GENFIFO_RX);
655 genfifoentry |= GQSPI_GENFIFO_DATA_XFER;
656 transfer_len = xqspi->bytes_to_transfer;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200657 }
658 genfifoentry |= zynqmp_qspi_selectspimode(xqspi, nbits);
659 xqspi->genfifoentry = genfifoentry;
660
661 if ((transfer_len) < GQSPI_GENFIFO_IMM_DATA_MASK) {
662 genfifoentry &= ~GQSPI_GENFIFO_IMM_DATA_MASK;
663 genfifoentry |= transfer_len;
664 zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, genfifoentry);
665 } else {
666 int tempcount = transfer_len;
667 u32 exponent = 8; /* 2^8 = 256 */
668 u8 imm_data = tempcount & 0xFF;
669
670 tempcount &= ~(tempcount & 0xFF);
671 /* Immediate entry */
672 if (tempcount != 0) {
673 /* Exponent entries */
674 genfifoentry |= GQSPI_GENFIFO_EXP;
675 while (tempcount != 0) {
676 if (tempcount & GQSPI_GENFIFO_EXP_START) {
677 genfifoentry &=
678 ~GQSPI_GENFIFO_IMM_DATA_MASK;
679 genfifoentry |= exponent;
680 zynqmp_gqspi_write(xqspi,
681 GQSPI_GEN_FIFO_OFST,
682 genfifoentry);
683 }
684 tempcount = tempcount >> 1;
685 exponent++;
686 }
687 }
688 if (imm_data != 0) {
689 genfifoentry &= ~GQSPI_GENFIFO_EXP;
690 genfifoentry &= ~GQSPI_GENFIFO_IMM_DATA_MASK;
691 genfifoentry |= (u8)(imm_data & 0xFF);
692 zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST,
693 genfifoentry);
694 }
695 }
696 if (xqspi->mode == GQSPI_MODE_IO && xqspi->rxbuf) {
697 /* Dummy generic FIFO entry */
698 zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, 0x0);
699 }
700}
701
702/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200703 * zynqmp_process_dma_irq - Handler for DMA done interrupt of QSPI
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530704 * controller
705 * @xqspi: zynqmp_qspi instance pointer
706 *
707 * This function handles DMA interrupt only.
708 */
709static void zynqmp_process_dma_irq(struct zynqmp_qspi *xqspi)
710{
711 u32 config_reg, genfifoentry;
712
713 dma_unmap_single(xqspi->dev, xqspi->dma_addr,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200714 xqspi->dma_rx_bytes, DMA_FROM_DEVICE);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530715 xqspi->rxbuf += xqspi->dma_rx_bytes;
716 xqspi->bytes_to_receive -= xqspi->dma_rx_bytes;
717 xqspi->dma_rx_bytes = 0;
718
719 /* Disabling the DMA interrupts */
720 zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_I_DIS_OFST,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200721 GQSPI_QSPIDMA_DST_I_EN_DONE_MASK);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530722
723 if (xqspi->bytes_to_receive > 0) {
724 /* Switch to IO mode,for remaining bytes to receive */
725 config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST);
726 config_reg &= ~GQSPI_CFG_MODE_EN_MASK;
727 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg);
728
729 /* Initiate the transfer of remaining bytes */
730 genfifoentry = xqspi->genfifoentry;
731 genfifoentry |= xqspi->bytes_to_receive;
732 zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, genfifoentry);
733
734 /* Dummy generic FIFO entry */
735 zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, 0x0);
736
737 /* Manual start */
738 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200739 (zynqmp_gqspi_read(xqspi,
740 GQSPI_CONFIG_OFST) |
741 GQSPI_CFG_START_GEN_FIFO_MASK));
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530742
743 /* Enable the RX interrupts for IO mode */
744 zynqmp_gqspi_write(xqspi, GQSPI_IER_OFST,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200745 GQSPI_IER_GENFIFOEMPTY_MASK |
746 GQSPI_IER_RXNEMPTY_MASK |
747 GQSPI_IER_RXEMPTY_MASK);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530748 }
749}
750
751/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200752 * zynqmp_qspi_irq - Interrupt service routine of the QSPI controller
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530753 * @irq: IRQ number
754 * @dev_id: Pointer to the xqspi structure
755 *
756 * This function handles TX empty only.
757 * On TX empty interrupt this function reads the received data from RX FIFO
758 * and fills the TX FIFO if there is any data remaining to be transferred.
759 *
760 * Return: IRQ_HANDLED when interrupt is handled
761 * IRQ_NONE otherwise.
762 */
763static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id)
764{
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200765 struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_id;
766 irqreturn_t ret = IRQ_NONE;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530767 u32 status, mask, dma_status = 0;
768
769 status = zynqmp_gqspi_read(xqspi, GQSPI_ISR_OFST);
770 zynqmp_gqspi_write(xqspi, GQSPI_ISR_OFST, status);
771 mask = (status & ~(zynqmp_gqspi_read(xqspi, GQSPI_IMASK_OFST)));
772
773 /* Read and clear DMA status */
774 if (xqspi->mode == GQSPI_MODE_DMA) {
775 dma_status =
776 zynqmp_gqspi_read(xqspi, GQSPI_QSPIDMA_DST_I_STS_OFST);
777 zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_I_STS_OFST,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200778 dma_status);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530779 }
780
781 if (mask & GQSPI_ISR_TXNOT_FULL_MASK) {
782 zynqmp_qspi_filltxfifo(xqspi, GQSPI_TX_FIFO_FILL);
783 ret = IRQ_HANDLED;
784 }
785
786 if (dma_status & GQSPI_QSPIDMA_DST_I_STS_DONE_MASK) {
787 zynqmp_process_dma_irq(xqspi);
788 ret = IRQ_HANDLED;
789 } else if (!(mask & GQSPI_IER_RXEMPTY_MASK) &&
790 (mask & GQSPI_IER_GENFIFOEMPTY_MASK)) {
791 zynqmp_qspi_readrxfifo(xqspi, GQSPI_RX_FIFO_FILL);
792 ret = IRQ_HANDLED;
793 }
794
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200795 if (xqspi->bytes_to_receive == 0 && xqspi->bytes_to_transfer == 0 &&
796 ((status & GQSPI_IRQ_MASK) == GQSPI_IRQ_MASK)) {
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530797 zynqmp_gqspi_write(xqspi, GQSPI_IDR_OFST, GQSPI_ISR_IDR_MASK);
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200798 complete(&xqspi->data_completion);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530799 ret = IRQ_HANDLED;
800 }
801 return ret;
802}
803
804/**
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200805 * zynqmp_qspi_setuprxdma - This function sets up the RX DMA operation
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530806 * @xqspi: xqspi is a pointer to the GQSPI instance.
Amit Kumar Mahapatrab3b95302022-10-11 11:50:34 +0530807 *
808 * Return: 0 on success; error value otherwise.
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530809 */
Quanyang Wang126bdb62021-04-16 08:46:52 +0800810static int zynqmp_qspi_setuprxdma(struct zynqmp_qspi *xqspi)
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530811{
812 u32 rx_bytes, rx_rem, config_reg;
813 dma_addr_t addr;
814 u64 dma_align = (u64)(uintptr_t)xqspi->rxbuf;
815
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200816 if (xqspi->bytes_to_receive < 8 ||
817 ((dma_align & GQSPI_DMA_UNALIGN) != 0x0)) {
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530818 /* Setting to IO mode */
819 config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST);
820 config_reg &= ~GQSPI_CFG_MODE_EN_MASK;
821 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg);
822 xqspi->mode = GQSPI_MODE_IO;
823 xqspi->dma_rx_bytes = 0;
Quanyang Wang126bdb62021-04-16 08:46:52 +0800824 return 0;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530825 }
826
827 rx_rem = xqspi->bytes_to_receive % 4;
828 rx_bytes = (xqspi->bytes_to_receive - rx_rem);
829
830 addr = dma_map_single(xqspi->dev, (void *)xqspi->rxbuf,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200831 rx_bytes, DMA_FROM_DEVICE);
Quanyang Wang126bdb62021-04-16 08:46:52 +0800832 if (dma_mapping_error(xqspi->dev, addr)) {
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530833 dev_err(xqspi->dev, "ERR:rxdma:memory not mapped\n");
Quanyang Wang126bdb62021-04-16 08:46:52 +0800834 return -ENOMEM;
835 }
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530836
837 xqspi->dma_rx_bytes = rx_bytes;
838 xqspi->dma_addr = addr;
839 zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_ADDR_OFST,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200840 (u32)(addr & 0xffffffff));
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530841 addr = ((addr >> 16) >> 16);
842 zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_ADDR_MSB_OFST,
Amit Kumar Mahapatraf09a4332020-09-24 09:11:19 +0200843 ((u32)addr) & 0xfff);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530844
845 /* Enabling the DMA mode */
846 config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST);
847 config_reg &= ~GQSPI_CFG_MODE_EN_MASK;
848 config_reg |= GQSPI_CFG_MODE_EN_DMA_MASK;
849 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg);
850
851 /* Switch to DMA mode */
852 xqspi->mode = GQSPI_MODE_DMA;
853
854 /* Write the number of bytes to transfer */
855 zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_SIZE_OFST, rx_bytes);
Quanyang Wang126bdb62021-04-16 08:46:52 +0800856
857 return 0;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530858}
859
860/**
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200861 * zynqmp_qspi_write_op - This function sets up the GENFIFO entries,
862 * TX FIFO, and fills the TX FIFO with as many
863 * bytes as possible.
864 * @xqspi: Pointer to the GQSPI instance.
865 * @tx_nbits: Transfer buswidth.
866 * @genfifoentry: Variable in which GENFIFO mask is returned
867 * to calling function
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530868 */
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200869static void zynqmp_qspi_write_op(struct zynqmp_qspi *xqspi, u8 tx_nbits,
870 u32 genfifoentry)
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530871{
872 u32 config_reg;
873
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200874 zynqmp_qspi_fillgenfifo(xqspi, tx_nbits, genfifoentry);
875 zynqmp_qspi_filltxfifo(xqspi, GQSPI_TXD_DEPTH);
876 if (xqspi->mode == GQSPI_MODE_DMA) {
877 config_reg = zynqmp_gqspi_read(xqspi,
878 GQSPI_CONFIG_OFST);
879 config_reg &= ~GQSPI_CFG_MODE_EN_MASK;
880 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
881 config_reg);
882 xqspi->mode = GQSPI_MODE_IO;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530883 }
884}
885
886/**
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200887 * zynqmp_qspi_read_op - This function sets up the GENFIFO entries and
888 * RX DMA operation.
889 * @xqspi: xqspi is a pointer to the GQSPI instance.
890 * @rx_nbits: Receive buswidth.
891 * @genfifoentry: genfifoentry is pointer to the variable in which
892 * GENFIFO mask is returned to calling function
Amit Kumar Mahapatrab3b95302022-10-11 11:50:34 +0530893 *
894 * Return: 0 on success; error value otherwise.
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530895 */
Quanyang Wang126bdb62021-04-16 08:46:52 +0800896static int zynqmp_qspi_read_op(struct zynqmp_qspi *xqspi, u8 rx_nbits,
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200897 u32 genfifoentry)
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530898{
Quanyang Wang126bdb62021-04-16 08:46:52 +0800899 int ret;
900
901 ret = zynqmp_qspi_setuprxdma(xqspi);
902 if (ret)
903 return ret;
Quanyang Wang41d31092021-04-08 12:02:23 +0800904 zynqmp_qspi_fillgenfifo(xqspi, rx_nbits, genfifoentry);
Quanyang Wang126bdb62021-04-16 08:46:52 +0800905
906 return 0;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530907}
908
909/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200910 * zynqmp_qspi_suspend - Suspend method for the QSPI driver
Lee Jones4b42b0b2020-07-17 14:54:20 +0100911 * @dev: Address of the platform_device structure
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530912 *
913 * This function stops the QSPI driver queue and disables the QSPI controller
914 *
915 * Return: Always 0
916 */
917static int __maybe_unused zynqmp_qspi_suspend(struct device *dev)
918{
Quanyang Wang799f9232021-04-16 08:46:49 +0800919 struct zynqmp_qspi *xqspi = dev_get_drvdata(dev);
920 struct spi_controller *ctlr = xqspi->ctlr;
921 int ret;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530922
Quanyang Wang799f9232021-04-16 08:46:49 +0800923 ret = spi_controller_suspend(ctlr);
924 if (ret)
925 return ret;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530926
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200927 zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530928
929 return 0;
930}
931
932/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +0200933 * zynqmp_qspi_resume - Resume method for the QSPI driver
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530934 * @dev: Address of the platform_device structure
935 *
936 * The function starts the QSPI driver queue and initializes the QSPI
937 * controller
938 *
939 * Return: 0 on success; error value otherwise
940 */
941static int __maybe_unused zynqmp_qspi_resume(struct device *dev)
942{
Quanyang Wang799f9232021-04-16 08:46:49 +0800943 struct zynqmp_qspi *xqspi = dev_get_drvdata(dev);
944 struct spi_controller *ctlr = xqspi->ctlr;
945
946 zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, GQSPI_EN_MASK);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530947
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +0200948 spi_controller_resume(ctlr);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +0530949
950 return 0;
951}
952
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530953/**
954 * zynqmp_runtime_suspend - Runtime suspend method for the SPI driver
955 * @dev: Address of the platform_device structure
956 *
957 * This function disables the clocks
958 *
959 * Return: Always 0
960 */
961static int __maybe_unused zynqmp_runtime_suspend(struct device *dev)
962{
Quanyang Wang799f9232021-04-16 08:46:49 +0800963 struct zynqmp_qspi *xqspi = dev_get_drvdata(dev);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530964
Quanyang Wangc6bdae02021-04-16 08:46:48 +0800965 clk_disable_unprepare(xqspi->refclk);
966 clk_disable_unprepare(xqspi->pclk);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530967
968 return 0;
969}
970
971/**
972 * zynqmp_runtime_resume - Runtime resume method for the SPI driver
973 * @dev: Address of the platform_device structure
974 *
975 * This function enables the clocks
976 *
977 * Return: 0 on success and error value on error
978 */
979static int __maybe_unused zynqmp_runtime_resume(struct device *dev)
980{
Quanyang Wang799f9232021-04-16 08:46:49 +0800981 struct zynqmp_qspi *xqspi = dev_get_drvdata(dev);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530982 int ret;
983
Quanyang Wangc6bdae02021-04-16 08:46:48 +0800984 ret = clk_prepare_enable(xqspi->pclk);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530985 if (ret) {
986 dev_err(dev, "Cannot enable APB clock.\n");
987 return ret;
988 }
989
Quanyang Wangc6bdae02021-04-16 08:46:48 +0800990 ret = clk_prepare_enable(xqspi->refclk);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530991 if (ret) {
992 dev_err(dev, "Cannot enable device clock.\n");
Quanyang Wangc6bdae02021-04-16 08:46:48 +0800993 clk_disable_unprepare(xqspi->pclk);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +0530994 return ret;
995 }
996
997 return 0;
998}
999
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001000/**
1001 * zynqmp_qspi_exec_op() - Initiates the QSPI transfer
1002 * @mem: The SPI memory
1003 * @op: The memory operation to execute
1004 *
1005 * Executes a memory operation.
1006 *
1007 * This function first selects the chip and starts the memory operation.
1008 *
1009 * Return: 0 in case of success, a negative error code otherwise.
1010 */
1011static int zynqmp_qspi_exec_op(struct spi_mem *mem,
1012 const struct spi_mem_op *op)
1013{
1014 struct zynqmp_qspi *xqspi = spi_controller_get_devdata
1015 (mem->spi->master);
1016 int err = 0, i;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001017 u32 genfifoentry = 0;
Quanyang Wanga2c5bed2021-04-16 08:46:51 +08001018 u16 opcode = op->cmd.opcode;
1019 u64 opaddr;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001020
1021 dev_dbg(xqspi->dev, "cmd:%#x mode:%d.%d.%d.%d\n",
1022 op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
1023 op->dummy.buswidth, op->data.buswidth);
1024
Quanyang Wanga0f65be2021-04-08 12:02:21 +08001025 mutex_lock(&xqspi->op_lock);
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001026 zynqmp_qspi_config_op(xqspi, mem->spi);
1027 zynqmp_qspi_chipselect(mem->spi, false);
1028 genfifoentry |= xqspi->genfifocs;
1029 genfifoentry |= xqspi->genfifobus;
1030
1031 if (op->cmd.opcode) {
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001032 reinit_completion(&xqspi->data_completion);
Quanyang Wanga2c5bed2021-04-16 08:46:51 +08001033 xqspi->txbuf = &opcode;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001034 xqspi->rxbuf = NULL;
1035 xqspi->bytes_to_transfer = op->cmd.nbytes;
1036 xqspi->bytes_to_receive = 0;
1037 zynqmp_qspi_write_op(xqspi, op->cmd.buswidth, genfifoentry);
1038 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
1039 zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST) |
1040 GQSPI_CFG_START_GEN_FIFO_MASK);
1041 zynqmp_gqspi_write(xqspi, GQSPI_IER_OFST,
1042 GQSPI_IER_GENFIFOEMPTY_MASK |
1043 GQSPI_IER_TXNOT_FULL_MASK);
Quanyang Wanga16bff62021-04-08 12:02:20 +08001044 if (!wait_for_completion_timeout
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001045 (&xqspi->data_completion, msecs_to_jiffies(1000))) {
1046 err = -ETIMEDOUT;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001047 goto return_err;
1048 }
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001049 }
1050
1051 if (op->addr.nbytes) {
Quanyang Wanga2c5bed2021-04-16 08:46:51 +08001052 xqspi->txbuf = &opaddr;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001053 for (i = 0; i < op->addr.nbytes; i++) {
1054 *(((u8 *)xqspi->txbuf) + i) = op->addr.val >>
1055 (8 * (op->addr.nbytes - i - 1));
1056 }
1057
1058 reinit_completion(&xqspi->data_completion);
1059 xqspi->rxbuf = NULL;
1060 xqspi->bytes_to_transfer = op->addr.nbytes;
1061 xqspi->bytes_to_receive = 0;
1062 zynqmp_qspi_write_op(xqspi, op->addr.buswidth, genfifoentry);
1063 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
1064 zynqmp_gqspi_read(xqspi,
1065 GQSPI_CONFIG_OFST) |
1066 GQSPI_CFG_START_GEN_FIFO_MASK);
1067 zynqmp_gqspi_write(xqspi, GQSPI_IER_OFST,
1068 GQSPI_IER_TXEMPTY_MASK |
1069 GQSPI_IER_GENFIFOEMPTY_MASK |
1070 GQSPI_IER_TXNOT_FULL_MASK);
Quanyang Wanga16bff62021-04-08 12:02:20 +08001071 if (!wait_for_completion_timeout
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001072 (&xqspi->data_completion, msecs_to_jiffies(1000))) {
1073 err = -ETIMEDOUT;
1074 goto return_err;
1075 }
1076 }
1077
1078 if (op->dummy.nbytes) {
Quanyang Wang8ad07d72021-04-08 12:02:22 +08001079 xqspi->txbuf = NULL;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001080 xqspi->rxbuf = NULL;
Quanyang Wang8ad07d72021-04-08 12:02:22 +08001081 /*
1082 * xqspi->bytes_to_transfer here represents the dummy circles
1083 * which need to be sent.
1084 */
1085 xqspi->bytes_to_transfer = op->dummy.nbytes * 8 / op->dummy.buswidth;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001086 xqspi->bytes_to_receive = 0;
Quanyang Wang8ad07d72021-04-08 12:02:22 +08001087 /*
1088 * Using op->data.buswidth instead of op->dummy.buswidth here because
1089 * we need to use it to configure the correct SPI mode.
1090 */
1091 zynqmp_qspi_write_op(xqspi, op->data.buswidth,
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001092 genfifoentry);
1093 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
1094 zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST) |
1095 GQSPI_CFG_START_GEN_FIFO_MASK);
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001096 }
1097
1098 if (op->data.nbytes) {
1099 reinit_completion(&xqspi->data_completion);
1100 if (op->data.dir == SPI_MEM_DATA_OUT) {
1101 xqspi->txbuf = (u8 *)op->data.buf.out;
1102 xqspi->rxbuf = NULL;
1103 xqspi->bytes_to_transfer = op->data.nbytes;
1104 xqspi->bytes_to_receive = 0;
1105 zynqmp_qspi_write_op(xqspi, op->data.buswidth,
1106 genfifoentry);
1107 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
1108 zynqmp_gqspi_read
1109 (xqspi, GQSPI_CONFIG_OFST) |
1110 GQSPI_CFG_START_GEN_FIFO_MASK);
1111 zynqmp_gqspi_write(xqspi, GQSPI_IER_OFST,
1112 GQSPI_IER_TXEMPTY_MASK |
1113 GQSPI_IER_GENFIFOEMPTY_MASK |
1114 GQSPI_IER_TXNOT_FULL_MASK);
1115 } else {
1116 xqspi->txbuf = NULL;
1117 xqspi->rxbuf = (u8 *)op->data.buf.in;
1118 xqspi->bytes_to_receive = op->data.nbytes;
1119 xqspi->bytes_to_transfer = 0;
Quanyang Wang126bdb62021-04-16 08:46:52 +08001120 err = zynqmp_qspi_read_op(xqspi, op->data.buswidth,
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001121 genfifoentry);
Quanyang Wang126bdb62021-04-16 08:46:52 +08001122 if (err)
1123 goto return_err;
1124
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001125 zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
1126 zynqmp_gqspi_read
1127 (xqspi, GQSPI_CONFIG_OFST) |
1128 GQSPI_CFG_START_GEN_FIFO_MASK);
1129 if (xqspi->mode == GQSPI_MODE_DMA) {
1130 zynqmp_gqspi_write
1131 (xqspi, GQSPI_QSPIDMA_DST_I_EN_OFST,
1132 GQSPI_QSPIDMA_DST_I_EN_DONE_MASK);
1133 } else {
1134 zynqmp_gqspi_write(xqspi, GQSPI_IER_OFST,
1135 GQSPI_IER_GENFIFOEMPTY_MASK |
1136 GQSPI_IER_RXNEMPTY_MASK |
1137 GQSPI_IER_RXEMPTY_MASK);
1138 }
1139 }
Quanyang Wanga16bff62021-04-08 12:02:20 +08001140 if (!wait_for_completion_timeout
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001141 (&xqspi->data_completion, msecs_to_jiffies(1000)))
1142 err = -ETIMEDOUT;
1143 }
1144
1145return_err:
1146
1147 zynqmp_qspi_chipselect(mem->spi, true);
Quanyang Wanga0f65be2021-04-08 12:02:21 +08001148 mutex_unlock(&xqspi->op_lock);
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001149
1150 return err;
1151}
1152
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +05301153static const struct dev_pm_ops zynqmp_qspi_dev_pm_ops = {
1154 SET_RUNTIME_PM_OPS(zynqmp_runtime_suspend,
1155 zynqmp_runtime_resume, NULL)
1156 SET_SYSTEM_SLEEP_PM_OPS(zynqmp_qspi_suspend, zynqmp_qspi_resume)
1157};
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301158
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001159static const struct spi_controller_mem_ops zynqmp_qspi_mem_ops = {
1160 .exec_op = zynqmp_qspi_exec_op,
1161};
1162
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301163/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +02001164 * zynqmp_qspi_probe - Probe method for the QSPI driver
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301165 * @pdev: Pointer to the platform_device structure
1166 *
1167 * This function initializes the driver data structures and the hardware.
1168 *
1169 * Return: 0 on success; error value otherwise
1170 */
1171static int zynqmp_qspi_probe(struct platform_device *pdev)
1172{
1173 int ret = 0;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001174 struct spi_controller *ctlr;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301175 struct zynqmp_qspi *xqspi;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301176 struct device *dev = &pdev->dev;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001177 struct device_node *np = dev->of_node;
Amit Kumar Mahapatradd9c2322022-05-12 20:28:20 +05301178 u32 num_cs;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301179
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001180 ctlr = spi_alloc_master(&pdev->dev, sizeof(*xqspi));
1181 if (!ctlr)
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301182 return -ENOMEM;
1183
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001184 xqspi = spi_controller_get_devdata(ctlr);
1185 xqspi->dev = dev;
Quanyang Wang799f9232021-04-16 08:46:49 +08001186 xqspi->ctlr = ctlr;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001187 platform_set_drvdata(pdev, xqspi);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301188
YueHaibing214d1ed2019-09-04 21:59:16 +08001189 xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301190 if (IS_ERR(xqspi->regs)) {
1191 ret = PTR_ERR(xqspi->regs);
1192 goto remove_master;
1193 }
1194
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301195 xqspi->pclk = devm_clk_get(&pdev->dev, "pclk");
1196 if (IS_ERR(xqspi->pclk)) {
1197 dev_err(dev, "pclk clock not found.\n");
1198 ret = PTR_ERR(xqspi->pclk);
1199 goto remove_master;
1200 }
1201
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301202 xqspi->refclk = devm_clk_get(&pdev->dev, "ref_clk");
1203 if (IS_ERR(xqspi->refclk)) {
1204 dev_err(dev, "ref_clk clock not found.\n");
1205 ret = PTR_ERR(xqspi->refclk);
Quanyang Wangc6bdae02021-04-16 08:46:48 +08001206 goto remove_master;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301207 }
1208
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001209 ret = clk_prepare_enable(xqspi->pclk);
1210 if (ret) {
1211 dev_err(dev, "Unable to enable APB clock.\n");
1212 goto remove_master;
1213 }
1214
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301215 ret = clk_prepare_enable(xqspi->refclk);
1216 if (ret) {
1217 dev_err(dev, "Unable to enable device clock.\n");
1218 goto clk_dis_pclk;
1219 }
1220
Quanyang Wangc6bdae02021-04-16 08:46:48 +08001221 init_completion(&xqspi->data_completion);
1222
Quanyang Wanga0f65be2021-04-08 12:02:21 +08001223 mutex_init(&xqspi->op_lock);
1224
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +05301225 pm_runtime_use_autosuspend(&pdev->dev);
1226 pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
1227 pm_runtime_set_active(&pdev->dev);
1228 pm_runtime_enable(&pdev->dev);
Dinghao Liu58eaa7b2021-04-15 15:46:44 +08001229
1230 ret = pm_runtime_get_sync(&pdev->dev);
1231 if (ret < 0) {
1232 dev_err(&pdev->dev, "Failed to pm_runtime_get_sync: %d\n", ret);
1233 goto clk_dis_all;
1234 }
1235
Amit Kumar Mahapatra22742b82022-10-11 11:50:35 +05301236 ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD |
1237 SPI_TX_DUAL | SPI_TX_QUAD;
Amit Kumar Mahapatra21764a42022-10-11 11:50:36 +05301238 ctlr->max_speed_hz = clk_get_rate(xqspi->refclk) / 2;
1239 xqspi->speed_hz = ctlr->max_speed_hz;
Amit Kumar Mahapatra22742b82022-10-11 11:50:35 +05301240
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301241 /* QSPI controller initializations */
1242 zynqmp_qspi_init_hw(xqspi);
1243
1244 xqspi->irq = platform_get_irq(pdev, 0);
1245 if (xqspi->irq <= 0) {
1246 ret = -ENXIO;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301247 goto clk_dis_all;
1248 }
1249 ret = devm_request_irq(&pdev->dev, xqspi->irq, zynqmp_qspi_irq,
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001250 0, pdev->name, xqspi);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301251 if (ret != 0) {
1252 ret = -ENXIO;
1253 dev_err(dev, "request_irq failed\n");
1254 goto clk_dis_all;
1255 }
1256
Jiasheng Jiang13262fc2022-03-02 17:20:51 +08001257 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(44));
1258 if (ret)
1259 goto clk_dis_all;
1260
Amit Kumar Mahapatradd9c2322022-05-12 20:28:20 +05301261 ret = of_property_read_u32(np, "num-cs", &num_cs);
1262 if (ret < 0) {
1263 ctlr->num_chipselect = GQSPI_DEFAULT_NUM_CS;
1264 } else if (num_cs > GQSPI_MAX_NUM_CS) {
1265 ret = -EINVAL;
1266 dev_err(&pdev->dev, "only %d chip selects are available\n",
1267 GQSPI_MAX_NUM_CS);
1268 goto clk_dis_all;
1269 } else {
1270 ctlr->num_chipselect = num_cs;
1271 }
1272
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001273 ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001274 ctlr->mem_ops = &zynqmp_qspi_mem_ops;
1275 ctlr->setup = zynqmp_qspi_setup_op;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001276 ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001277 ctlr->dev.of_node = np;
Dinghao Liu58eaa7b2021-04-15 15:46:44 +08001278 ctlr->auto_runtime_pm = true;
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301279
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001280 ret = devm_spi_register_controller(&pdev->dev, ctlr);
1281 if (ret) {
1282 dev_err(&pdev->dev, "spi_register_controller failed\n");
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301283 goto clk_dis_all;
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001284 }
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301285
Dinghao Liu58eaa7b2021-04-15 15:46:44 +08001286 pm_runtime_mark_last_busy(&pdev->dev);
1287 pm_runtime_put_autosuspend(&pdev->dev);
1288
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301289 return 0;
1290
1291clk_dis_all:
Dinghao Liu58eaa7b2021-04-15 15:46:44 +08001292 pm_runtime_put_sync(&pdev->dev);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +05301293 pm_runtime_set_suspended(&pdev->dev);
1294 pm_runtime_disable(&pdev->dev);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301295 clk_disable_unprepare(xqspi->refclk);
1296clk_dis_pclk:
1297 clk_disable_unprepare(xqspi->pclk);
1298remove_master:
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001299 spi_controller_put(ctlr);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301300
1301 return ret;
1302}
1303
1304/**
Amit Kumar Mahapatra91af6eb2020-09-24 09:11:17 +02001305 * zynqmp_qspi_remove - Remove method for the QSPI driver
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301306 * @pdev: Pointer to the platform_device structure
1307 *
1308 * This function is called if a device is physically removed from the system or
1309 * if the driver module is being unloaded. It frees all resources allocated to
1310 * the device.
1311 *
1312 * Return: 0 Always
1313 */
1314static int zynqmp_qspi_remove(struct platform_device *pdev)
1315{
Amit Kumar Mahapatra1c263722020-09-24 09:11:18 +02001316 struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301317
1318 zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
1319 clk_disable_unprepare(xqspi->refclk);
1320 clk_disable_unprepare(xqspi->pclk);
Naga Sureshkumar Relli9e3a0002018-03-26 18:34:20 +05301321 pm_runtime_set_suspended(&pdev->dev);
1322 pm_runtime_disable(&pdev->dev);
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301323
Ranjit Waghmodedfe11a12015-06-10 16:08:21 +05301324 return 0;
1325}
1326
1327static const struct of_device_id zynqmp_qspi_of_match[] = {
1328 { .compatible = "xlnx,zynqmp-qspi-1.0", },
1329 { /* End of table */ }
1330};
1331
1332MODULE_DEVICE_TABLE(of, zynqmp_qspi_of_match);
1333
1334static struct platform_driver zynqmp_qspi_driver = {
1335 .probe = zynqmp_qspi_probe,
1336 .remove = zynqmp_qspi_remove,
1337 .driver = {
1338 .name = "zynqmp-qspi",
1339 .of_match_table = zynqmp_qspi_of_match,
1340 .pm = &zynqmp_qspi_dev_pm_ops,
1341 },
1342};
1343
1344module_platform_driver(zynqmp_qspi_driver);
1345
1346MODULE_AUTHOR("Xilinx, Inc.");
1347MODULE_DESCRIPTION("Xilinx Zynqmp QSPI driver");
1348MODULE_LICENSE("GPL");