1cae417b2STudor Ambarus // SPDX-License-Identifier: GPL-2.0
20e6aae08SPiotr Bugalski /*
30e6aae08SPiotr Bugalski * Driver for Atmel QSPI Controller
40e6aae08SPiotr Bugalski *
50e6aae08SPiotr Bugalski * Copyright (C) 2015 Atmel Corporation
60e6aae08SPiotr Bugalski * Copyright (C) 2018 Cryptera A/S
70e6aae08SPiotr Bugalski *
80e6aae08SPiotr Bugalski * Author: Cyrille Pitchen <cyrille.pitchen@atmel.com>
90e6aae08SPiotr Bugalski * Author: Piotr Bugalski <bugalski.piotr@gmail.com>
100e6aae08SPiotr Bugalski *
110e6aae08SPiotr Bugalski * This driver is based on drivers/mtd/spi-nor/fsl-quadspi.c from Freescale.
120e6aae08SPiotr Bugalski */
130e6aae08SPiotr Bugalski
140e6aae08SPiotr Bugalski #include <linux/clk.h>
150e6aae08SPiotr Bugalski #include <linux/delay.h>
160e6aae08SPiotr Bugalski #include <linux/err.h>
170e6aae08SPiotr Bugalski #include <linux/interrupt.h>
180e6aae08SPiotr Bugalski #include <linux/io.h>
193ae012e9STudor Ambarus #include <linux/kernel.h>
203ae012e9STudor Ambarus #include <linux/module.h>
213ae012e9STudor Ambarus #include <linux/of.h>
222e5c8888STudor Ambarus #include <linux/of_platform.h>
233ae012e9STudor Ambarus #include <linux/platform_device.h>
244a2f83b7SClaudiu Beznea #include <linux/pm_runtime.h>
250e6aae08SPiotr Bugalski #include <linux/spi/spi-mem.h>
260e6aae08SPiotr Bugalski
270e6aae08SPiotr Bugalski /* QSPI register offsets */
280e6aae08SPiotr Bugalski #define QSPI_CR 0x0000 /* Control Register */
290e6aae08SPiotr Bugalski #define QSPI_MR 0x0004 /* Mode Register */
300e6aae08SPiotr Bugalski #define QSPI_RD 0x0008 /* Receive Data Register */
310e6aae08SPiotr Bugalski #define QSPI_TD 0x000c /* Transmit Data Register */
320e6aae08SPiotr Bugalski #define QSPI_SR 0x0010 /* Status Register */
330e6aae08SPiotr Bugalski #define QSPI_IER 0x0014 /* Interrupt Enable Register */
340e6aae08SPiotr Bugalski #define QSPI_IDR 0x0018 /* Interrupt Disable Register */
350e6aae08SPiotr Bugalski #define QSPI_IMR 0x001c /* Interrupt Mask Register */
360e6aae08SPiotr Bugalski #define QSPI_SCR 0x0020 /* Serial Clock Register */
370e6aae08SPiotr Bugalski
380e6aae08SPiotr Bugalski #define QSPI_IAR 0x0030 /* Instruction Address Register */
390e6aae08SPiotr Bugalski #define QSPI_ICR 0x0034 /* Instruction Code Register */
402e5c8888STudor Ambarus #define QSPI_WICR 0x0034 /* Write Instruction Code Register */
410e6aae08SPiotr Bugalski #define QSPI_IFR 0x0038 /* Instruction Frame Register */
422e5c8888STudor Ambarus #define QSPI_RICR 0x003C /* Read Instruction Code Register */
430e6aae08SPiotr Bugalski
440e6aae08SPiotr Bugalski #define QSPI_SMR 0x0040 /* Scrambling Mode Register */
450e6aae08SPiotr Bugalski #define QSPI_SKR 0x0044 /* Scrambling Key Register */
460e6aae08SPiotr Bugalski
470e6aae08SPiotr Bugalski #define QSPI_WPMR 0x00E4 /* Write Protection Mode Register */
480e6aae08SPiotr Bugalski #define QSPI_WPSR 0x00E8 /* Write Protection Status Register */
490e6aae08SPiotr Bugalski
500e6aae08SPiotr Bugalski #define QSPI_VERSION 0x00FC /* Version Register */
510e6aae08SPiotr Bugalski
520e6aae08SPiotr Bugalski
530e6aae08SPiotr Bugalski /* Bitfields in QSPI_CR (Control Register) */
540e6aae08SPiotr Bugalski #define QSPI_CR_QSPIEN BIT(0)
550e6aae08SPiotr Bugalski #define QSPI_CR_QSPIDIS BIT(1)
560e6aae08SPiotr Bugalski #define QSPI_CR_SWRST BIT(7)
570e6aae08SPiotr Bugalski #define QSPI_CR_LASTXFER BIT(24)
580e6aae08SPiotr Bugalski
590e6aae08SPiotr Bugalski /* Bitfields in QSPI_MR (Mode Register) */
600e6aae08SPiotr Bugalski #define QSPI_MR_SMM BIT(0)
610e6aae08SPiotr Bugalski #define QSPI_MR_LLB BIT(1)
620e6aae08SPiotr Bugalski #define QSPI_MR_WDRBT BIT(2)
630e6aae08SPiotr Bugalski #define QSPI_MR_SMRM BIT(3)
640e6aae08SPiotr Bugalski #define QSPI_MR_CSMODE_MASK GENMASK(5, 4)
650e6aae08SPiotr Bugalski #define QSPI_MR_CSMODE_NOT_RELOADED (0 << 4)
660e6aae08SPiotr Bugalski #define QSPI_MR_CSMODE_LASTXFER (1 << 4)
670e6aae08SPiotr Bugalski #define QSPI_MR_CSMODE_SYSTEMATICALLY (2 << 4)
680e6aae08SPiotr Bugalski #define QSPI_MR_NBBITS_MASK GENMASK(11, 8)
690e6aae08SPiotr Bugalski #define QSPI_MR_NBBITS(n) ((((n) - 8) << 8) & QSPI_MR_NBBITS_MASK)
700e6aae08SPiotr Bugalski #define QSPI_MR_DLYBCT_MASK GENMASK(23, 16)
710e6aae08SPiotr Bugalski #define QSPI_MR_DLYBCT(n) (((n) << 16) & QSPI_MR_DLYBCT_MASK)
720e6aae08SPiotr Bugalski #define QSPI_MR_DLYCS_MASK GENMASK(31, 24)
730e6aae08SPiotr Bugalski #define QSPI_MR_DLYCS(n) (((n) << 24) & QSPI_MR_DLYCS_MASK)
740e6aae08SPiotr Bugalski
750e6aae08SPiotr Bugalski /* Bitfields in QSPI_SR/QSPI_IER/QSPI_IDR/QSPI_IMR */
760e6aae08SPiotr Bugalski #define QSPI_SR_RDRF BIT(0)
770e6aae08SPiotr Bugalski #define QSPI_SR_TDRE BIT(1)
780e6aae08SPiotr Bugalski #define QSPI_SR_TXEMPTY BIT(2)
790e6aae08SPiotr Bugalski #define QSPI_SR_OVRES BIT(3)
800e6aae08SPiotr Bugalski #define QSPI_SR_CSR BIT(8)
810e6aae08SPiotr Bugalski #define QSPI_SR_CSS BIT(9)
820e6aae08SPiotr Bugalski #define QSPI_SR_INSTRE BIT(10)
830e6aae08SPiotr Bugalski #define QSPI_SR_QSPIENS BIT(24)
840e6aae08SPiotr Bugalski
850e6aae08SPiotr Bugalski #define QSPI_SR_CMD_COMPLETED (QSPI_SR_INSTRE | QSPI_SR_CSR)
860e6aae08SPiotr Bugalski
870e6aae08SPiotr Bugalski /* Bitfields in QSPI_SCR (Serial Clock Register) */
880e6aae08SPiotr Bugalski #define QSPI_SCR_CPOL BIT(0)
890e6aae08SPiotr Bugalski #define QSPI_SCR_CPHA BIT(1)
900e6aae08SPiotr Bugalski #define QSPI_SCR_SCBR_MASK GENMASK(15, 8)
910e6aae08SPiotr Bugalski #define QSPI_SCR_SCBR(n) (((n) << 8) & QSPI_SCR_SCBR_MASK)
920e6aae08SPiotr Bugalski #define QSPI_SCR_DLYBS_MASK GENMASK(23, 16)
930e6aae08SPiotr Bugalski #define QSPI_SCR_DLYBS(n) (((n) << 16) & QSPI_SCR_DLYBS_MASK)
940e6aae08SPiotr Bugalski
952e5c8888STudor Ambarus /* Bitfields in QSPI_ICR (Read/Write Instruction Code Register) */
960e6aae08SPiotr Bugalski #define QSPI_ICR_INST_MASK GENMASK(7, 0)
970e6aae08SPiotr Bugalski #define QSPI_ICR_INST(inst) (((inst) << 0) & QSPI_ICR_INST_MASK)
980e6aae08SPiotr Bugalski #define QSPI_ICR_OPT_MASK GENMASK(23, 16)
990e6aae08SPiotr Bugalski #define QSPI_ICR_OPT(opt) (((opt) << 16) & QSPI_ICR_OPT_MASK)
1000e6aae08SPiotr Bugalski
1010e6aae08SPiotr Bugalski /* Bitfields in QSPI_IFR (Instruction Frame Register) */
1020e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_MASK GENMASK(2, 0)
1030e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_SINGLE_BIT_SPI (0 << 0)
1040e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_DUAL_OUTPUT (1 << 0)
1050e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_QUAD_OUTPUT (2 << 0)
1060e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_DUAL_IO (3 << 0)
1070e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_QUAD_IO (4 << 0)
1080e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_DUAL_CMD (5 << 0)
1090e6aae08SPiotr Bugalski #define QSPI_IFR_WIDTH_QUAD_CMD (6 << 0)
1100e6aae08SPiotr Bugalski #define QSPI_IFR_INSTEN BIT(4)
1110e6aae08SPiotr Bugalski #define QSPI_IFR_ADDREN BIT(5)
1120e6aae08SPiotr Bugalski #define QSPI_IFR_OPTEN BIT(6)
1130e6aae08SPiotr Bugalski #define QSPI_IFR_DATAEN BIT(7)
1140e6aae08SPiotr Bugalski #define QSPI_IFR_OPTL_MASK GENMASK(9, 8)
1150e6aae08SPiotr Bugalski #define QSPI_IFR_OPTL_1BIT (0 << 8)
1160e6aae08SPiotr Bugalski #define QSPI_IFR_OPTL_2BIT (1 << 8)
1170e6aae08SPiotr Bugalski #define QSPI_IFR_OPTL_4BIT (2 << 8)
1180e6aae08SPiotr Bugalski #define QSPI_IFR_OPTL_8BIT (3 << 8)
1190e6aae08SPiotr Bugalski #define QSPI_IFR_ADDRL BIT(10)
120b456fd18STudor Ambarus #define QSPI_IFR_TFRTYP_MEM BIT(12)
121b456fd18STudor Ambarus #define QSPI_IFR_SAMA5D2_WRITE_TRSFR BIT(13)
1220e6aae08SPiotr Bugalski #define QSPI_IFR_CRM BIT(14)
1230e6aae08SPiotr Bugalski #define QSPI_IFR_NBDUM_MASK GENMASK(20, 16)
1240e6aae08SPiotr Bugalski #define QSPI_IFR_NBDUM(n) (((n) << 16) & QSPI_IFR_NBDUM_MASK)
1252e5c8888STudor Ambarus #define QSPI_IFR_APBTFRTYP_READ BIT(24) /* Defined in SAM9X60 */
1260e6aae08SPiotr Bugalski
1270e6aae08SPiotr Bugalski /* Bitfields in QSPI_SMR (Scrambling Mode Register) */
1280e6aae08SPiotr Bugalski #define QSPI_SMR_SCREN BIT(0)
1290e6aae08SPiotr Bugalski #define QSPI_SMR_RVDIS BIT(1)
1300e6aae08SPiotr Bugalski
1310e6aae08SPiotr Bugalski /* Bitfields in QSPI_WPMR (Write Protection Mode Register) */
1320e6aae08SPiotr Bugalski #define QSPI_WPMR_WPEN BIT(0)
1330e6aae08SPiotr Bugalski #define QSPI_WPMR_WPKEY_MASK GENMASK(31, 8)
1340e6aae08SPiotr Bugalski #define QSPI_WPMR_WPKEY(wpkey) (((wpkey) << 8) & QSPI_WPMR_WPKEY_MASK)
1350e6aae08SPiotr Bugalski
1360e6aae08SPiotr Bugalski /* Bitfields in QSPI_WPSR (Write Protection Status Register) */
1370e6aae08SPiotr Bugalski #define QSPI_WPSR_WPVS BIT(0)
1380e6aae08SPiotr Bugalski #define QSPI_WPSR_WPVSRC_MASK GENMASK(15, 8)
1390e6aae08SPiotr Bugalski #define QSPI_WPSR_WPVSRC(src) (((src) << 8) & QSPI_WPSR_WPVSRC)
1400e6aae08SPiotr Bugalski
14134e7a236SCsókás, Bence #define ATMEL_QSPI_TIMEOUT 1000 /* ms */
14234e7a236SCsókás, Bence
1432e5c8888STudor Ambarus struct atmel_qspi_caps {
1442e5c8888STudor Ambarus bool has_qspick;
1452e5c8888STudor Ambarus bool has_ricr;
1462e5c8888STudor Ambarus };
1470e6aae08SPiotr Bugalski
14834e7a236SCsókás, Bence struct atmel_qspi_ops;
14934e7a236SCsókás, Bence
1500e6aae08SPiotr Bugalski struct atmel_qspi {
1510e6aae08SPiotr Bugalski void __iomem *regs;
1520e6aae08SPiotr Bugalski void __iomem *mem;
153bd7905e2STudor Ambarus struct clk *pclk;
1542e5c8888STudor Ambarus struct clk *qspick;
1550e6aae08SPiotr Bugalski struct platform_device *pdev;
1562e5c8888STudor Ambarus const struct atmel_qspi_caps *caps;
15734e7a236SCsókás, Bence const struct atmel_qspi_ops *ops;
1588e093ea4STudor Ambarus resource_size_t mmap_size;
1590e6aae08SPiotr Bugalski u32 pending;
16034e7a236SCsókás, Bence u32 irq_mask;
1619958c8c3STudor Ambarus u32 mr;
162ab735611STudor Ambarus u32 scr;
1630e6aae08SPiotr Bugalski struct completion cmd_completion;
1640e6aae08SPiotr Bugalski };
1650e6aae08SPiotr Bugalski
16634e7a236SCsókás, Bence struct atmel_qspi_ops {
16734e7a236SCsókás, Bence int (*set_cfg)(struct atmel_qspi *aq, const struct spi_mem_op *op,
16834e7a236SCsókás, Bence u32 *offset);
16934e7a236SCsókás, Bence int (*transfer)(struct spi_mem *mem, const struct spi_mem_op *op,
17034e7a236SCsókás, Bence u32 offset);
17134e7a236SCsókás, Bence };
17234e7a236SCsókás, Bence
1731db6de22STudor Ambarus struct atmel_qspi_mode {
1740e6aae08SPiotr Bugalski u8 cmd_buswidth;
1750e6aae08SPiotr Bugalski u8 addr_buswidth;
1760e6aae08SPiotr Bugalski u8 data_buswidth;
1770e6aae08SPiotr Bugalski u32 config;
1780e6aae08SPiotr Bugalski };
1790e6aae08SPiotr Bugalski
1802e5c8888STudor Ambarus static const struct atmel_qspi_mode atmel_qspi_modes[] = {
1810e6aae08SPiotr Bugalski { 1, 1, 1, QSPI_IFR_WIDTH_SINGLE_BIT_SPI },
1820e6aae08SPiotr Bugalski { 1, 1, 2, QSPI_IFR_WIDTH_DUAL_OUTPUT },
1830e6aae08SPiotr Bugalski { 1, 1, 4, QSPI_IFR_WIDTH_QUAD_OUTPUT },
1840e6aae08SPiotr Bugalski { 1, 2, 2, QSPI_IFR_WIDTH_DUAL_IO },
1850e6aae08SPiotr Bugalski { 1, 4, 4, QSPI_IFR_WIDTH_QUAD_IO },
1860e6aae08SPiotr Bugalski { 2, 2, 2, QSPI_IFR_WIDTH_DUAL_CMD },
1870e6aae08SPiotr Bugalski { 4, 4, 4, QSPI_IFR_WIDTH_QUAD_CMD },
1880e6aae08SPiotr Bugalski };
1890e6aae08SPiotr Bugalski
190c528ecfbSTudor Ambarus #ifdef VERBOSE_DEBUG
atmel_qspi_reg_name(u32 offset,char * tmp,size_t sz)191c528ecfbSTudor Ambarus static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)
192c528ecfbSTudor Ambarus {
193c528ecfbSTudor Ambarus switch (offset) {
194c528ecfbSTudor Ambarus case QSPI_CR:
195c528ecfbSTudor Ambarus return "CR";
196c528ecfbSTudor Ambarus case QSPI_MR:
197c528ecfbSTudor Ambarus return "MR";
198c528ecfbSTudor Ambarus case QSPI_RD:
19941535cb1SCsókás, Bence return "RD";
200c528ecfbSTudor Ambarus case QSPI_TD:
201c528ecfbSTudor Ambarus return "TD";
202c528ecfbSTudor Ambarus case QSPI_SR:
203c528ecfbSTudor Ambarus return "SR";
204c528ecfbSTudor Ambarus case QSPI_IER:
205c528ecfbSTudor Ambarus return "IER";
206c528ecfbSTudor Ambarus case QSPI_IDR:
207c528ecfbSTudor Ambarus return "IDR";
208c528ecfbSTudor Ambarus case QSPI_IMR:
209c528ecfbSTudor Ambarus return "IMR";
210c528ecfbSTudor Ambarus case QSPI_SCR:
211c528ecfbSTudor Ambarus return "SCR";
212c528ecfbSTudor Ambarus case QSPI_IAR:
213c528ecfbSTudor Ambarus return "IAR";
214c528ecfbSTudor Ambarus case QSPI_ICR:
215c528ecfbSTudor Ambarus return "ICR/WICR";
216c528ecfbSTudor Ambarus case QSPI_IFR:
217c528ecfbSTudor Ambarus return "IFR";
218c528ecfbSTudor Ambarus case QSPI_RICR:
219c528ecfbSTudor Ambarus return "RICR";
220c528ecfbSTudor Ambarus case QSPI_SMR:
221c528ecfbSTudor Ambarus return "SMR";
222c528ecfbSTudor Ambarus case QSPI_SKR:
223c528ecfbSTudor Ambarus return "SKR";
224c528ecfbSTudor Ambarus case QSPI_WPMR:
225c528ecfbSTudor Ambarus return "WPMR";
226c528ecfbSTudor Ambarus case QSPI_WPSR:
227c528ecfbSTudor Ambarus return "WPSR";
228c528ecfbSTudor Ambarus case QSPI_VERSION:
229c528ecfbSTudor Ambarus return "VERSION";
230c528ecfbSTudor Ambarus default:
231c528ecfbSTudor Ambarus snprintf(tmp, sz, "0x%02x", offset);
232c528ecfbSTudor Ambarus break;
233c528ecfbSTudor Ambarus }
234c528ecfbSTudor Ambarus
235c528ecfbSTudor Ambarus return tmp;
236c528ecfbSTudor Ambarus }
237c528ecfbSTudor Ambarus #endif /* VERBOSE_DEBUG */
238c528ecfbSTudor Ambarus
atmel_qspi_read(struct atmel_qspi * aq,u32 offset)239c528ecfbSTudor Ambarus static u32 atmel_qspi_read(struct atmel_qspi *aq, u32 offset)
240c528ecfbSTudor Ambarus {
241c528ecfbSTudor Ambarus u32 value = readl_relaxed(aq->regs + offset);
242c528ecfbSTudor Ambarus
243c528ecfbSTudor Ambarus #ifdef VERBOSE_DEBUG
244c528ecfbSTudor Ambarus char tmp[8];
245c528ecfbSTudor Ambarus
246c528ecfbSTudor Ambarus dev_vdbg(&aq->pdev->dev, "read 0x%08x from %s\n", value,
247c528ecfbSTudor Ambarus atmel_qspi_reg_name(offset, tmp, sizeof(tmp)));
248c528ecfbSTudor Ambarus #endif /* VERBOSE_DEBUG */
249c528ecfbSTudor Ambarus
250c528ecfbSTudor Ambarus return value;
251c528ecfbSTudor Ambarus }
252c528ecfbSTudor Ambarus
atmel_qspi_write(u32 value,struct atmel_qspi * aq,u32 offset)253c528ecfbSTudor Ambarus static void atmel_qspi_write(u32 value, struct atmel_qspi *aq, u32 offset)
254c528ecfbSTudor Ambarus {
255c528ecfbSTudor Ambarus #ifdef VERBOSE_DEBUG
256c528ecfbSTudor Ambarus char tmp[8];
257c528ecfbSTudor Ambarus
258c528ecfbSTudor Ambarus dev_vdbg(&aq->pdev->dev, "write 0x%08x into %s\n", value,
259c528ecfbSTudor Ambarus atmel_qspi_reg_name(offset, tmp, sizeof(tmp)));
260c528ecfbSTudor Ambarus #endif /* VERBOSE_DEBUG */
261c528ecfbSTudor Ambarus
262c528ecfbSTudor Ambarus writel_relaxed(value, aq->regs + offset);
263c528ecfbSTudor Ambarus }
264c528ecfbSTudor Ambarus
atmel_qspi_is_compatible(const struct spi_mem_op * op,const struct atmel_qspi_mode * mode)2651db6de22STudor Ambarus static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op,
2661db6de22STudor Ambarus const struct atmel_qspi_mode *mode)
2670e6aae08SPiotr Bugalski {
2680e6aae08SPiotr Bugalski if (op->cmd.buswidth != mode->cmd_buswidth)
2690e6aae08SPiotr Bugalski return false;
2700e6aae08SPiotr Bugalski
2710e6aae08SPiotr Bugalski if (op->addr.nbytes && op->addr.buswidth != mode->addr_buswidth)
2720e6aae08SPiotr Bugalski return false;
2730e6aae08SPiotr Bugalski
2740e6aae08SPiotr Bugalski if (op->data.nbytes && op->data.buswidth != mode->data_buswidth)
2750e6aae08SPiotr Bugalski return false;
2760e6aae08SPiotr Bugalski
2770e6aae08SPiotr Bugalski return true;
2780e6aae08SPiotr Bugalski }
2790e6aae08SPiotr Bugalski
atmel_qspi_find_mode(const struct spi_mem_op * op)2801db6de22STudor Ambarus static int atmel_qspi_find_mode(const struct spi_mem_op *op)
2810e6aae08SPiotr Bugalski {
2820e6aae08SPiotr Bugalski u32 i;
2830e6aae08SPiotr Bugalski
2842e5c8888STudor Ambarus for (i = 0; i < ARRAY_SIZE(atmel_qspi_modes); i++)
2852e5c8888STudor Ambarus if (atmel_qspi_is_compatible(op, &atmel_qspi_modes[i]))
2860e6aae08SPiotr Bugalski return i;
2870e6aae08SPiotr Bugalski
2882aaa8dd0STudor Ambarus return -ENOTSUPP;
2890e6aae08SPiotr Bugalski }
2900e6aae08SPiotr Bugalski
atmel_qspi_supports_op(struct spi_mem * mem,const struct spi_mem_op * op)2910e6aae08SPiotr Bugalski static bool atmel_qspi_supports_op(struct spi_mem *mem,
2920e6aae08SPiotr Bugalski const struct spi_mem_op *op)
2930e6aae08SPiotr Bugalski {
2948c235cc2STudor Ambarus if (!spi_mem_default_supports_op(mem, op))
2958c235cc2STudor Ambarus return false;
2968c235cc2STudor Ambarus
2971db6de22STudor Ambarus if (atmel_qspi_find_mode(op) < 0)
2980e6aae08SPiotr Bugalski return false;
2990e6aae08SPiotr Bugalski
3000e6aae08SPiotr Bugalski /* special case not supported by hardware */
3010e6aae08SPiotr Bugalski if (op->addr.nbytes == 2 && op->cmd.buswidth != op->addr.buswidth &&
3020e6aae08SPiotr Bugalski op->dummy.nbytes == 0)
3030e6aae08SPiotr Bugalski return false;
3040e6aae08SPiotr Bugalski
3050e6aae08SPiotr Bugalski return true;
3060e6aae08SPiotr Bugalski }
3070e6aae08SPiotr Bugalski
atmel_qspi_set_cfg(struct atmel_qspi * aq,const struct spi_mem_op * op,u32 * offset)3082e5c8888STudor Ambarus static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
3092e5c8888STudor Ambarus const struct spi_mem_op *op, u32 *offset)
3100e6aae08SPiotr Bugalski {
3112e5c8888STudor Ambarus u32 iar, icr, ifr;
3120e6aae08SPiotr Bugalski u32 dummy_cycles = 0;
3132e5c8888STudor Ambarus int mode;
3140e6aae08SPiotr Bugalski
3150e6aae08SPiotr Bugalski iar = 0;
3160e6aae08SPiotr Bugalski icr = QSPI_ICR_INST(op->cmd.opcode);
3170e6aae08SPiotr Bugalski ifr = QSPI_IFR_INSTEN;
3180e6aae08SPiotr Bugalski
3191db6de22STudor Ambarus mode = atmel_qspi_find_mode(op);
3200e6aae08SPiotr Bugalski if (mode < 0)
3212aaa8dd0STudor Ambarus return mode;
3222e5c8888STudor Ambarus ifr |= atmel_qspi_modes[mode].config;
3230e6aae08SPiotr Bugalski
32409134c53SYoshitaka Ikeda if (op->dummy.nbytes)
3250e6aae08SPiotr Bugalski dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth;
3260e6aae08SPiotr Bugalski
3272e5c8888STudor Ambarus /*
3282e5c8888STudor Ambarus * The controller allows 24 and 32-bit addressing while NAND-flash
3292e5c8888STudor Ambarus * requires 16-bit long. Handling 8-bit long addresses is done using
3302e5c8888STudor Ambarus * the option field. For the 16-bit addresses, the workaround depends
3312e5c8888STudor Ambarus * of the number of requested dummy bits. If there are 8 or more dummy
3322e5c8888STudor Ambarus * cycles, the address is shifted and sent with the first dummy byte.
3332e5c8888STudor Ambarus * Otherwise opcode is disabled and the first byte of the address
3342e5c8888STudor Ambarus * contains the command opcode (works only if the opcode and address
3352e5c8888STudor Ambarus * use the same buswidth). The limitation is when the 16-bit address is
3362e5c8888STudor Ambarus * used without enough dummy cycles and the opcode is using a different
3372e5c8888STudor Ambarus * buswidth than the address.
3382e5c8888STudor Ambarus */
3390e6aae08SPiotr Bugalski if (op->addr.buswidth) {
3400e6aae08SPiotr Bugalski switch (op->addr.nbytes) {
3410e6aae08SPiotr Bugalski case 0:
3420e6aae08SPiotr Bugalski break;
3430e6aae08SPiotr Bugalski case 1:
3440e6aae08SPiotr Bugalski ifr |= QSPI_IFR_OPTEN | QSPI_IFR_OPTL_8BIT;
3450e6aae08SPiotr Bugalski icr |= QSPI_ICR_OPT(op->addr.val & 0xff);
3460e6aae08SPiotr Bugalski break;
3470e6aae08SPiotr Bugalski case 2:
3480e6aae08SPiotr Bugalski if (dummy_cycles < 8 / op->addr.buswidth) {
3490e6aae08SPiotr Bugalski ifr &= ~QSPI_IFR_INSTEN;
3500e6aae08SPiotr Bugalski ifr |= QSPI_IFR_ADDREN;
3510e6aae08SPiotr Bugalski iar = (op->cmd.opcode << 16) |
3520e6aae08SPiotr Bugalski (op->addr.val & 0xffff);
3530e6aae08SPiotr Bugalski } else {
3540e6aae08SPiotr Bugalski ifr |= QSPI_IFR_ADDREN;
3550e6aae08SPiotr Bugalski iar = (op->addr.val << 8) & 0xffffff;
3560e6aae08SPiotr Bugalski dummy_cycles -= 8 / op->addr.buswidth;
3570e6aae08SPiotr Bugalski }
3580e6aae08SPiotr Bugalski break;
3590e6aae08SPiotr Bugalski case 3:
3600e6aae08SPiotr Bugalski ifr |= QSPI_IFR_ADDREN;
3610e6aae08SPiotr Bugalski iar = op->addr.val & 0xffffff;
3620e6aae08SPiotr Bugalski break;
3630e6aae08SPiotr Bugalski case 4:
3640e6aae08SPiotr Bugalski ifr |= QSPI_IFR_ADDREN | QSPI_IFR_ADDRL;
3650e6aae08SPiotr Bugalski iar = op->addr.val & 0x7ffffff;
3660e6aae08SPiotr Bugalski break;
3670e6aae08SPiotr Bugalski default:
3680e6aae08SPiotr Bugalski return -ENOTSUPP;
3690e6aae08SPiotr Bugalski }
3700e6aae08SPiotr Bugalski }
3710e6aae08SPiotr Bugalski
3722e5c8888STudor Ambarus /* offset of the data access in the QSPI memory space */
3732e5c8888STudor Ambarus *offset = iar;
3742e5c8888STudor Ambarus
3750e6aae08SPiotr Bugalski /* Set number of dummy cycles */
3760e6aae08SPiotr Bugalski if (dummy_cycles)
3770e6aae08SPiotr Bugalski ifr |= QSPI_IFR_NBDUM(dummy_cycles);
3780e6aae08SPiotr Bugalski
379cac8c821STudor Ambarus /* Set data enable and data transfer type. */
380cac8c821STudor Ambarus if (op->data.nbytes) {
3810e6aae08SPiotr Bugalski ifr |= QSPI_IFR_DATAEN;
3820e6aae08SPiotr Bugalski
383cac8c821STudor Ambarus if (op->addr.nbytes)
384cac8c821STudor Ambarus ifr |= QSPI_IFR_TFRTYP_MEM;
385cac8c821STudor Ambarus }
386cac8c821STudor Ambarus
3872e5c8888STudor Ambarus /*
3882e5c8888STudor Ambarus * If the QSPI controller is set in regular SPI mode, set it in
3892e5c8888STudor Ambarus * Serial Memory Mode (SMM).
3902e5c8888STudor Ambarus */
391ecb8a79dSAlexander Dahl if (!(aq->mr & QSPI_MR_SMM)) {
392ecb8a79dSAlexander Dahl aq->mr |= QSPI_MR_SMM;
393646749b4SAlexander Dahl atmel_qspi_write(aq->mr, aq, QSPI_MR);
3942e5c8888STudor Ambarus }
3950e6aae08SPiotr Bugalski
3960e6aae08SPiotr Bugalski /* Clear pending interrupts */
397c528ecfbSTudor Ambarus (void)atmel_qspi_read(aq, QSPI_SR);
3980e6aae08SPiotr Bugalski
399d00364b6STudor Ambarus /* Set QSPI Instruction Frame registers. */
400d00364b6STudor Ambarus if (op->addr.nbytes && !op->data.nbytes)
401c528ecfbSTudor Ambarus atmel_qspi_write(iar, aq, QSPI_IAR);
402d00364b6STudor Ambarus
403d00364b6STudor Ambarus if (aq->caps->has_ricr) {
4042e5c8888STudor Ambarus if (op->data.dir == SPI_MEM_DATA_IN)
405c528ecfbSTudor Ambarus atmel_qspi_write(icr, aq, QSPI_RICR);
4062e5c8888STudor Ambarus else
407c528ecfbSTudor Ambarus atmel_qspi_write(icr, aq, QSPI_WICR);
4082e5c8888STudor Ambarus } else {
409cac8c821STudor Ambarus if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
4102e5c8888STudor Ambarus ifr |= QSPI_IFR_SAMA5D2_WRITE_TRSFR;
4112e5c8888STudor Ambarus
412c528ecfbSTudor Ambarus atmel_qspi_write(icr, aq, QSPI_ICR);
4132e5c8888STudor Ambarus }
4142e5c8888STudor Ambarus
415c066efb0STudor Ambarus atmel_qspi_write(ifr, aq, QSPI_IFR);
416c066efb0STudor Ambarus
4172e5c8888STudor Ambarus return 0;
4182e5c8888STudor Ambarus }
4192e5c8888STudor Ambarus
atmel_qspi_wait_for_completion(struct atmel_qspi * aq,u32 irq_mask)42034e7a236SCsókás, Bence static int atmel_qspi_wait_for_completion(struct atmel_qspi *aq, u32 irq_mask)
42134e7a236SCsókás, Bence {
42234e7a236SCsókás, Bence int err = 0;
42334e7a236SCsókás, Bence u32 sr;
42434e7a236SCsókás, Bence
42534e7a236SCsókás, Bence /* Poll INSTRuction End status */
42634e7a236SCsókás, Bence sr = atmel_qspi_read(aq, QSPI_SR);
42734e7a236SCsókás, Bence if ((sr & irq_mask) == irq_mask)
42834e7a236SCsókás, Bence return 0;
42934e7a236SCsókás, Bence
43034e7a236SCsókás, Bence /* Wait for INSTRuction End interrupt */
43134e7a236SCsókás, Bence reinit_completion(&aq->cmd_completion);
43234e7a236SCsókás, Bence aq->pending = sr & irq_mask;
43334e7a236SCsókás, Bence aq->irq_mask = irq_mask;
43434e7a236SCsókás, Bence atmel_qspi_write(irq_mask, aq, QSPI_IER);
43534e7a236SCsókás, Bence if (!wait_for_completion_timeout(&aq->cmd_completion,
43634e7a236SCsókás, Bence msecs_to_jiffies(ATMEL_QSPI_TIMEOUT)))
43734e7a236SCsókás, Bence err = -ETIMEDOUT;
43834e7a236SCsókás, Bence atmel_qspi_write(irq_mask, aq, QSPI_IDR);
43934e7a236SCsókás, Bence
44034e7a236SCsókás, Bence return err;
44134e7a236SCsókás, Bence }
44234e7a236SCsókás, Bence
atmel_qspi_transfer(struct spi_mem * mem,const struct spi_mem_op * op,u32 offset)44334e7a236SCsókás, Bence static int atmel_qspi_transfer(struct spi_mem *mem,
44434e7a236SCsókás, Bence const struct spi_mem_op *op, u32 offset)
4452e5c8888STudor Ambarus {
446ccbc6554SYang Yingliang struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller);
4470e6aae08SPiotr Bugalski
4480e6aae08SPiotr Bugalski /* Skip to the final steps if there is no data */
44934e7a236SCsókás, Bence if (!op->data.nbytes)
45034e7a236SCsókás, Bence return atmel_qspi_wait_for_completion(aq,
45134e7a236SCsókás, Bence QSPI_SR_CMD_COMPLETED);
45234e7a236SCsókás, Bence
4530e6aae08SPiotr Bugalski /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
454c528ecfbSTudor Ambarus (void)atmel_qspi_read(aq, QSPI_IFR);
4550e6aae08SPiotr Bugalski
4560e6aae08SPiotr Bugalski /* Send/Receive data */
457*b85a1561SBence Csókás if (op->data.dir == SPI_MEM_DATA_IN) {
458b780c3f3STudor Ambarus memcpy_fromio(op->data.buf.in, aq->mem + offset,
4592e5c8888STudor Ambarus op->data.nbytes);
460*b85a1561SBence Csókás
461*b85a1561SBence Csókás /* Synchronize AHB and APB accesses again */
462*b85a1561SBence Csókás rmb();
463*b85a1561SBence Csókás } else {
464b780c3f3STudor Ambarus memcpy_toio(aq->mem + offset, op->data.buf.out,
4652e5c8888STudor Ambarus op->data.nbytes);
4660e6aae08SPiotr Bugalski
467*b85a1561SBence Csókás /* Synchronize AHB and APB accesses again */
468*b85a1561SBence Csókás wmb();
469*b85a1561SBence Csókás }
470*b85a1561SBence Csókás
4710e6aae08SPiotr Bugalski /* Release the chip-select */
472c528ecfbSTudor Ambarus atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
47334e7a236SCsókás, Bence
47434e7a236SCsókás, Bence return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED);
4750e6aae08SPiotr Bugalski }
4760e6aae08SPiotr Bugalski
atmel_qspi_exec_op(struct spi_mem * mem,const struct spi_mem_op * op)47734e7a236SCsókás, Bence static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
47834e7a236SCsókás, Bence {
47934e7a236SCsókás, Bence struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller);
48034e7a236SCsókás, Bence u32 offset;
48134e7a236SCsókás, Bence int err;
48234e7a236SCsókás, Bence
48334e7a236SCsókás, Bence /*
48434e7a236SCsókás, Bence * Check if the address exceeds the MMIO window size. An improvement
48534e7a236SCsókás, Bence * would be to add support for regular SPI mode and fall back to it
48634e7a236SCsókás, Bence * when the flash memories overrun the controller's memory space.
48734e7a236SCsókás, Bence */
48834e7a236SCsókás, Bence if (op->addr.val + op->data.nbytes > aq->mmap_size)
48934e7a236SCsókás, Bence return -EOPNOTSUPP;
49034e7a236SCsókás, Bence
49134e7a236SCsókás, Bence if (op->addr.nbytes > 4)
49234e7a236SCsókás, Bence return -EOPNOTSUPP;
49334e7a236SCsókás, Bence
49434e7a236SCsókás, Bence err = pm_runtime_resume_and_get(&aq->pdev->dev);
49534e7a236SCsókás, Bence if (err < 0)
49634e7a236SCsókás, Bence return err;
49734e7a236SCsókás, Bence
49834e7a236SCsókás, Bence err = aq->ops->set_cfg(aq, op, &offset);
49934e7a236SCsókás, Bence if (err)
5004a2f83b7SClaudiu Beznea goto pm_runtime_put;
5010e6aae08SPiotr Bugalski
50234e7a236SCsókás, Bence err = aq->ops->transfer(mem, op, offset);
5030e6aae08SPiotr Bugalski
5044a2f83b7SClaudiu Beznea pm_runtime_put:
5054a2f83b7SClaudiu Beznea pm_runtime_mark_last_busy(&aq->pdev->dev);
5064a2f83b7SClaudiu Beznea pm_runtime_put_autosuspend(&aq->pdev->dev);
5070e6aae08SPiotr Bugalski return err;
5080e6aae08SPiotr Bugalski }
5090e6aae08SPiotr Bugalski
atmel_qspi_get_name(struct spi_mem * spimem)51055e3dacaSYueHaibing static const char *atmel_qspi_get_name(struct spi_mem *spimem)
5110e6aae08SPiotr Bugalski {
5120e6aae08SPiotr Bugalski return dev_name(spimem->spi->dev.parent);
5130e6aae08SPiotr Bugalski }
5140e6aae08SPiotr Bugalski
5150e6aae08SPiotr Bugalski static const struct spi_controller_mem_ops atmel_qspi_mem_ops = {
5160e6aae08SPiotr Bugalski .supports_op = atmel_qspi_supports_op,
5170e6aae08SPiotr Bugalski .exec_op = atmel_qspi_exec_op,
5180e6aae08SPiotr Bugalski .get_name = atmel_qspi_get_name
5190e6aae08SPiotr Bugalski };
5200e6aae08SPiotr Bugalski
atmel_qspi_setup(struct spi_device * spi)5210e6aae08SPiotr Bugalski static int atmel_qspi_setup(struct spi_device *spi)
5220e6aae08SPiotr Bugalski {
523ccbc6554SYang Yingliang struct spi_controller *ctrl = spi->controller;
5240e6aae08SPiotr Bugalski struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
5250e6aae08SPiotr Bugalski unsigned long src_rate;
526ab735611STudor Ambarus u32 scbr;
5274a2f83b7SClaudiu Beznea int ret;
5280e6aae08SPiotr Bugalski
5290e6aae08SPiotr Bugalski if (ctrl->busy)
5300e6aae08SPiotr Bugalski return -EBUSY;
5310e6aae08SPiotr Bugalski
5320e6aae08SPiotr Bugalski if (!spi->max_speed_hz)
5330e6aae08SPiotr Bugalski return -EINVAL;
5340e6aae08SPiotr Bugalski
535bd7905e2STudor Ambarus src_rate = clk_get_rate(aq->pclk);
5360e6aae08SPiotr Bugalski if (!src_rate)
5370e6aae08SPiotr Bugalski return -EINVAL;
5380e6aae08SPiotr Bugalski
5390e6aae08SPiotr Bugalski /* Compute the QSPI baudrate */
5400e6aae08SPiotr Bugalski scbr = DIV_ROUND_UP(src_rate, spi->max_speed_hz);
5410e6aae08SPiotr Bugalski if (scbr > 0)
5420e6aae08SPiotr Bugalski scbr--;
5430e6aae08SPiotr Bugalski
5444a2f83b7SClaudiu Beznea ret = pm_runtime_resume_and_get(ctrl->dev.parent);
5454a2f83b7SClaudiu Beznea if (ret < 0)
5464a2f83b7SClaudiu Beznea return ret;
5474a2f83b7SClaudiu Beznea
548ecb8a79dSAlexander Dahl aq->scr &= ~QSPI_SCR_SCBR_MASK;
549ecb8a79dSAlexander Dahl aq->scr |= QSPI_SCR_SCBR(scbr);
550c528ecfbSTudor Ambarus atmel_qspi_write(aq->scr, aq, QSPI_SCR);
5510e6aae08SPiotr Bugalski
5524a2f83b7SClaudiu Beznea pm_runtime_mark_last_busy(ctrl->dev.parent);
5534a2f83b7SClaudiu Beznea pm_runtime_put_autosuspend(ctrl->dev.parent);
5544a2f83b7SClaudiu Beznea
5550e6aae08SPiotr Bugalski return 0;
5560e6aae08SPiotr Bugalski }
5570e6aae08SPiotr Bugalski
atmel_qspi_set_cs_timing(struct spi_device * spi)558f732646dSTudor Ambarus static int atmel_qspi_set_cs_timing(struct spi_device *spi)
559f732646dSTudor Ambarus {
560ccbc6554SYang Yingliang struct spi_controller *ctrl = spi->controller;
561f732646dSTudor Ambarus struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
562f732646dSTudor Ambarus unsigned long clk_rate;
563f732646dSTudor Ambarus u32 cs_setup;
564f732646dSTudor Ambarus int delay;
565f732646dSTudor Ambarus int ret;
566f732646dSTudor Ambarus
567f732646dSTudor Ambarus delay = spi_delay_to_ns(&spi->cs_setup, NULL);
568f732646dSTudor Ambarus if (delay <= 0)
569f732646dSTudor Ambarus return delay;
570f732646dSTudor Ambarus
571f732646dSTudor Ambarus clk_rate = clk_get_rate(aq->pclk);
572f732646dSTudor Ambarus if (!clk_rate)
573f732646dSTudor Ambarus return -EINVAL;
574f732646dSTudor Ambarus
575f732646dSTudor Ambarus cs_setup = DIV_ROUND_UP((delay * DIV_ROUND_UP(clk_rate, 1000000)),
576f732646dSTudor Ambarus 1000);
577f732646dSTudor Ambarus
578f732646dSTudor Ambarus ret = pm_runtime_resume_and_get(ctrl->dev.parent);
579f732646dSTudor Ambarus if (ret < 0)
580f732646dSTudor Ambarus return ret;
581f732646dSTudor Ambarus
582ecb8a79dSAlexander Dahl aq->scr &= ~QSPI_SCR_DLYBS_MASK;
583f732646dSTudor Ambarus aq->scr |= QSPI_SCR_DLYBS(cs_setup);
584f732646dSTudor Ambarus atmel_qspi_write(aq->scr, aq, QSPI_SCR);
585f732646dSTudor Ambarus
586f732646dSTudor Ambarus pm_runtime_mark_last_busy(ctrl->dev.parent);
587f732646dSTudor Ambarus pm_runtime_put_autosuspend(ctrl->dev.parent);
588f732646dSTudor Ambarus
589f732646dSTudor Ambarus return 0;
590f732646dSTudor Ambarus }
591f732646dSTudor Ambarus
atmel_qspi_init(struct atmel_qspi * aq)5925b74e9a3STudor Ambarus static void atmel_qspi_init(struct atmel_qspi *aq)
5930e6aae08SPiotr Bugalski {
5940e6aae08SPiotr Bugalski /* Reset the QSPI controller */
595c528ecfbSTudor Ambarus atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
5960e6aae08SPiotr Bugalski
5979958c8c3STudor Ambarus /* Set the QSPI controller by default in Serial Memory Mode */
598ecb8a79dSAlexander Dahl aq->mr |= QSPI_MR_SMM;
599ecb8a79dSAlexander Dahl atmel_qspi_write(aq->mr, aq, QSPI_MR);
6009958c8c3STudor Ambarus
6010e6aae08SPiotr Bugalski /* Enable the QSPI controller */
602c528ecfbSTudor Ambarus atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
6030e6aae08SPiotr Bugalski }
6040e6aae08SPiotr Bugalski
atmel_qspi_interrupt(int irq,void * dev_id)6050e6aae08SPiotr Bugalski static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id)
6060e6aae08SPiotr Bugalski {
6079ce4c512STudor Ambarus struct atmel_qspi *aq = dev_id;
6080e6aae08SPiotr Bugalski u32 status, mask, pending;
6090e6aae08SPiotr Bugalski
610c528ecfbSTudor Ambarus status = atmel_qspi_read(aq, QSPI_SR);
611c528ecfbSTudor Ambarus mask = atmel_qspi_read(aq, QSPI_IMR);
6120e6aae08SPiotr Bugalski pending = status & mask;
6130e6aae08SPiotr Bugalski
6140e6aae08SPiotr Bugalski if (!pending)
6150e6aae08SPiotr Bugalski return IRQ_NONE;
6160e6aae08SPiotr Bugalski
6170e6aae08SPiotr Bugalski aq->pending |= pending;
61834e7a236SCsókás, Bence if ((aq->pending & aq->irq_mask) == aq->irq_mask)
6190e6aae08SPiotr Bugalski complete(&aq->cmd_completion);
6200e6aae08SPiotr Bugalski
6210e6aae08SPiotr Bugalski return IRQ_HANDLED;
6220e6aae08SPiotr Bugalski }
6230e6aae08SPiotr Bugalski
62434e7a236SCsókás, Bence static const struct atmel_qspi_ops atmel_qspi_ops = {
62534e7a236SCsókás, Bence .set_cfg = atmel_qspi_set_cfg,
62634e7a236SCsókás, Bence .transfer = atmel_qspi_transfer,
62734e7a236SCsókás, Bence };
62834e7a236SCsókás, Bence
atmel_qspi_probe(struct platform_device * pdev)6290e6aae08SPiotr Bugalski static int atmel_qspi_probe(struct platform_device *pdev)
6300e6aae08SPiotr Bugalski {
6310e6aae08SPiotr Bugalski struct spi_controller *ctrl;
6320e6aae08SPiotr Bugalski struct atmel_qspi *aq;
6330e6aae08SPiotr Bugalski struct resource *res;
6340e6aae08SPiotr Bugalski int irq, err = 0;
6350e6aae08SPiotr Bugalski
636ccbc6554SYang Yingliang ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*aq));
6370e6aae08SPiotr Bugalski if (!ctrl)
6380e6aae08SPiotr Bugalski return -ENOMEM;
6390e6aae08SPiotr Bugalski
6400e6aae08SPiotr Bugalski ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD;
6410e6aae08SPiotr Bugalski ctrl->setup = atmel_qspi_setup;
642f732646dSTudor Ambarus ctrl->set_cs_timing = atmel_qspi_set_cs_timing;
6430e6aae08SPiotr Bugalski ctrl->bus_num = -1;
6440e6aae08SPiotr Bugalski ctrl->mem_ops = &atmel_qspi_mem_ops;
6450e6aae08SPiotr Bugalski ctrl->num_chipselect = 1;
6460e6aae08SPiotr Bugalski ctrl->dev.of_node = pdev->dev.of_node;
6470e6aae08SPiotr Bugalski platform_set_drvdata(pdev, ctrl);
6480e6aae08SPiotr Bugalski
6490e6aae08SPiotr Bugalski aq = spi_controller_get_devdata(ctrl);
6500e6aae08SPiotr Bugalski
6510e6aae08SPiotr Bugalski init_completion(&aq->cmd_completion);
6520e6aae08SPiotr Bugalski aq->pdev = pdev;
65334e7a236SCsókás, Bence aq->ops = &atmel_qspi_ops;
6540e6aae08SPiotr Bugalski
6550e6aae08SPiotr Bugalski /* Map the registers */
6560e6aae08SPiotr Bugalski res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base");
6570e6aae08SPiotr Bugalski aq->regs = devm_ioremap_resource(&pdev->dev, res);
6580e6aae08SPiotr Bugalski if (IS_ERR(aq->regs)) {
6590e6aae08SPiotr Bugalski dev_err(&pdev->dev, "missing registers\n");
660c7b88456SLukas Wunner return PTR_ERR(aq->regs);
6610e6aae08SPiotr Bugalski }
6620e6aae08SPiotr Bugalski
6630e6aae08SPiotr Bugalski /* Map the AHB memory */
6640e6aae08SPiotr Bugalski res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mmap");
6650e6aae08SPiotr Bugalski aq->mem = devm_ioremap_resource(&pdev->dev, res);
6660e6aae08SPiotr Bugalski if (IS_ERR(aq->mem)) {
6670e6aae08SPiotr Bugalski dev_err(&pdev->dev, "missing AHB memory\n");
668c7b88456SLukas Wunner return PTR_ERR(aq->mem);
6690e6aae08SPiotr Bugalski }
6700e6aae08SPiotr Bugalski
6718e093ea4STudor Ambarus aq->mmap_size = resource_size(res);
6728e093ea4STudor Ambarus
6730e6aae08SPiotr Bugalski /* Get the peripheral clock */
674bd7905e2STudor Ambarus aq->pclk = devm_clk_get(&pdev->dev, "pclk");
675bd7905e2STudor Ambarus if (IS_ERR(aq->pclk))
676bd7905e2STudor Ambarus aq->pclk = devm_clk_get(&pdev->dev, NULL);
677bd7905e2STudor Ambarus
678bd7905e2STudor Ambarus if (IS_ERR(aq->pclk)) {
6790e6aae08SPiotr Bugalski dev_err(&pdev->dev, "missing peripheral clock\n");
680c7b88456SLukas Wunner return PTR_ERR(aq->pclk);
6810e6aae08SPiotr Bugalski }
6820e6aae08SPiotr Bugalski
6830e6aae08SPiotr Bugalski /* Enable the peripheral clock */
684bd7905e2STudor Ambarus err = clk_prepare_enable(aq->pclk);
6850e6aae08SPiotr Bugalski if (err) {
6860e6aae08SPiotr Bugalski dev_err(&pdev->dev, "failed to enable the peripheral clock\n");
687c7b88456SLukas Wunner return err;
6880e6aae08SPiotr Bugalski }
6890e6aae08SPiotr Bugalski
6902e5c8888STudor Ambarus aq->caps = of_device_get_match_data(&pdev->dev);
6912e5c8888STudor Ambarus if (!aq->caps) {
6922e5c8888STudor Ambarus dev_err(&pdev->dev, "Could not retrieve QSPI caps\n");
6932e5c8888STudor Ambarus err = -EINVAL;
6940e685017SLukas Wunner goto disable_pclk;
6952e5c8888STudor Ambarus }
6962e5c8888STudor Ambarus
6972e5c8888STudor Ambarus if (aq->caps->has_qspick) {
6982e5c8888STudor Ambarus /* Get the QSPI system clock */
6992e5c8888STudor Ambarus aq->qspick = devm_clk_get(&pdev->dev, "qspick");
7002e5c8888STudor Ambarus if (IS_ERR(aq->qspick)) {
7012e5c8888STudor Ambarus dev_err(&pdev->dev, "missing system clock\n");
7022e5c8888STudor Ambarus err = PTR_ERR(aq->qspick);
7032e5c8888STudor Ambarus goto disable_pclk;
7042e5c8888STudor Ambarus }
7052e5c8888STudor Ambarus
7062e5c8888STudor Ambarus /* Enable the QSPI system clock */
7072e5c8888STudor Ambarus err = clk_prepare_enable(aq->qspick);
7082e5c8888STudor Ambarus if (err) {
7092e5c8888STudor Ambarus dev_err(&pdev->dev,
7102e5c8888STudor Ambarus "failed to enable the QSPI system clock\n");
7112e5c8888STudor Ambarus goto disable_pclk;
7122e5c8888STudor Ambarus }
7132e5c8888STudor Ambarus }
7142e5c8888STudor Ambarus
7150e6aae08SPiotr Bugalski /* Request the IRQ */
7160e6aae08SPiotr Bugalski irq = platform_get_irq(pdev, 0);
7170e6aae08SPiotr Bugalski if (irq < 0) {
7180e6aae08SPiotr Bugalski err = irq;
7192e5c8888STudor Ambarus goto disable_qspick;
7200e6aae08SPiotr Bugalski }
7210e6aae08SPiotr Bugalski err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt,
7220e6aae08SPiotr Bugalski 0, dev_name(&pdev->dev), aq);
7230e6aae08SPiotr Bugalski if (err)
7242e5c8888STudor Ambarus goto disable_qspick;
7250e6aae08SPiotr Bugalski
7264a2f83b7SClaudiu Beznea pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
7274a2f83b7SClaudiu Beznea pm_runtime_use_autosuspend(&pdev->dev);
7284a2f83b7SClaudiu Beznea pm_runtime_set_active(&pdev->dev);
7294a2f83b7SClaudiu Beznea pm_runtime_enable(&pdev->dev);
7304a2f83b7SClaudiu Beznea pm_runtime_get_noresume(&pdev->dev);
7314a2f83b7SClaudiu Beznea
7325b74e9a3STudor Ambarus atmel_qspi_init(aq);
7330e6aae08SPiotr Bugalski
7340e6aae08SPiotr Bugalski err = spi_register_controller(ctrl);
7354a2f83b7SClaudiu Beznea if (err) {
7364a2f83b7SClaudiu Beznea pm_runtime_put_noidle(&pdev->dev);
7374a2f83b7SClaudiu Beznea pm_runtime_disable(&pdev->dev);
7384a2f83b7SClaudiu Beznea pm_runtime_set_suspended(&pdev->dev);
7394a2f83b7SClaudiu Beznea pm_runtime_dont_use_autosuspend(&pdev->dev);
7402e5c8888STudor Ambarus goto disable_qspick;
7414a2f83b7SClaudiu Beznea }
7424a2f83b7SClaudiu Beznea pm_runtime_mark_last_busy(&pdev->dev);
7434a2f83b7SClaudiu Beznea pm_runtime_put_autosuspend(&pdev->dev);
7440e6aae08SPiotr Bugalski
7450e6aae08SPiotr Bugalski return 0;
7460e6aae08SPiotr Bugalski
7472e5c8888STudor Ambarus disable_qspick:
7482e5c8888STudor Ambarus clk_disable_unprepare(aq->qspick);
749bd7905e2STudor Ambarus disable_pclk:
750bd7905e2STudor Ambarus clk_disable_unprepare(aq->pclk);
7510e6aae08SPiotr Bugalski
7520e6aae08SPiotr Bugalski return err;
7530e6aae08SPiotr Bugalski }
7540e6aae08SPiotr Bugalski
atmel_qspi_remove(struct platform_device * pdev)7554d70dd0aSUwe Kleine-König static void atmel_qspi_remove(struct platform_device *pdev)
7560e6aae08SPiotr Bugalski {
7570e6aae08SPiotr Bugalski struct spi_controller *ctrl = platform_get_drvdata(pdev);
7580e6aae08SPiotr Bugalski struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
7594a2f83b7SClaudiu Beznea int ret;
7604a2f83b7SClaudiu Beznea
7610e6aae08SPiotr Bugalski spi_unregister_controller(ctrl);
7629448bc1dSUwe Kleine-König
7639448bc1dSUwe Kleine-König ret = pm_runtime_get_sync(&pdev->dev);
7649448bc1dSUwe Kleine-König if (ret >= 0) {
765c528ecfbSTudor Ambarus atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
7669448bc1dSUwe Kleine-König clk_disable(aq->qspick);
7679448bc1dSUwe Kleine-König clk_disable(aq->pclk);
7689448bc1dSUwe Kleine-König } else {
7699448bc1dSUwe Kleine-König /*
7709448bc1dSUwe Kleine-König * atmel_qspi_runtime_{suspend,resume} just disable and enable
7719448bc1dSUwe Kleine-König * the two clks respectively. So after resume failed these are
7729448bc1dSUwe Kleine-König * off, and we skip hardware access and disabling these clks again.
7739448bc1dSUwe Kleine-König */
7749448bc1dSUwe Kleine-König dev_warn(&pdev->dev, "Failed to resume device on remove\n");
7759448bc1dSUwe Kleine-König }
7769448bc1dSUwe Kleine-König
7779448bc1dSUwe Kleine-König clk_unprepare(aq->qspick);
7789448bc1dSUwe Kleine-König clk_unprepare(aq->pclk);
7794a2f83b7SClaudiu Beznea
7804a2f83b7SClaudiu Beznea pm_runtime_disable(&pdev->dev);
7812016d585SJinjie Ruan pm_runtime_dont_use_autosuspend(&pdev->dev);
7824a2f83b7SClaudiu Beznea pm_runtime_put_noidle(&pdev->dev);
7830e6aae08SPiotr Bugalski }
7840e6aae08SPiotr Bugalski
atmel_qspi_suspend(struct device * dev)7850e6aae08SPiotr Bugalski static int __maybe_unused atmel_qspi_suspend(struct device *dev)
7860e6aae08SPiotr Bugalski {
787e5c27498SClaudiu Beznea struct spi_controller *ctrl = dev_get_drvdata(dev);
788e5c27498SClaudiu Beznea struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
7894a2f83b7SClaudiu Beznea int ret;
7904a2f83b7SClaudiu Beznea
7914a2f83b7SClaudiu Beznea ret = pm_runtime_resume_and_get(dev);
7924a2f83b7SClaudiu Beznea if (ret < 0)
7934a2f83b7SClaudiu Beznea return ret;
7940e6aae08SPiotr Bugalski
795df6978b7STudor Ambarus atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
7964a2f83b7SClaudiu Beznea
7974a2f83b7SClaudiu Beznea pm_runtime_mark_last_busy(dev);
7984a2f83b7SClaudiu Beznea pm_runtime_force_suspend(dev);
7994a2f83b7SClaudiu Beznea
8004a2f83b7SClaudiu Beznea clk_unprepare(aq->qspick);
8014a2f83b7SClaudiu Beznea clk_unprepare(aq->pclk);
8020e6aae08SPiotr Bugalski
8030e6aae08SPiotr Bugalski return 0;
8040e6aae08SPiotr Bugalski }
8050e6aae08SPiotr Bugalski
atmel_qspi_resume(struct device * dev)8060e6aae08SPiotr Bugalski static int __maybe_unused atmel_qspi_resume(struct device *dev)
8070e6aae08SPiotr Bugalski {
808e5c27498SClaudiu Beznea struct spi_controller *ctrl = dev_get_drvdata(dev);
809e5c27498SClaudiu Beznea struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
8104a2f83b7SClaudiu Beznea int ret;
8110e6aae08SPiotr Bugalski
812754b569bSChen Ni ret = clk_prepare(aq->pclk);
813754b569bSChen Ni if (ret)
814754b569bSChen Ni return ret;
815754b569bSChen Ni
816754b569bSChen Ni ret = clk_prepare(aq->qspick);
817754b569bSChen Ni if (ret) {
818754b569bSChen Ni clk_unprepare(aq->pclk);
819754b569bSChen Ni return ret;
820754b569bSChen Ni }
8214a2f83b7SClaudiu Beznea
8224a2f83b7SClaudiu Beznea ret = pm_runtime_force_resume(dev);
8234a2f83b7SClaudiu Beznea if (ret < 0)
8244a2f83b7SClaudiu Beznea return ret;
8250e6aae08SPiotr Bugalski
8265b74e9a3STudor Ambarus atmel_qspi_init(aq);
827ab735611STudor Ambarus
828c528ecfbSTudor Ambarus atmel_qspi_write(aq->scr, aq, QSPI_SCR);
829ab735611STudor Ambarus
8304a2f83b7SClaudiu Beznea pm_runtime_mark_last_busy(dev);
8314a2f83b7SClaudiu Beznea pm_runtime_put_autosuspend(dev);
8324a2f83b7SClaudiu Beznea
8335b74e9a3STudor Ambarus return 0;
8340e6aae08SPiotr Bugalski }
8350e6aae08SPiotr Bugalski
atmel_qspi_runtime_suspend(struct device * dev)8364a2f83b7SClaudiu Beznea static int __maybe_unused atmel_qspi_runtime_suspend(struct device *dev)
8374a2f83b7SClaudiu Beznea {
8384a2f83b7SClaudiu Beznea struct spi_controller *ctrl = dev_get_drvdata(dev);
8394a2f83b7SClaudiu Beznea struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
8404a2f83b7SClaudiu Beznea
8414a2f83b7SClaudiu Beznea clk_disable(aq->qspick);
8424a2f83b7SClaudiu Beznea clk_disable(aq->pclk);
8434a2f83b7SClaudiu Beznea
8444a2f83b7SClaudiu Beznea return 0;
8454a2f83b7SClaudiu Beznea }
8464a2f83b7SClaudiu Beznea
atmel_qspi_runtime_resume(struct device * dev)8474a2f83b7SClaudiu Beznea static int __maybe_unused atmel_qspi_runtime_resume(struct device *dev)
8484a2f83b7SClaudiu Beznea {
8494a2f83b7SClaudiu Beznea struct spi_controller *ctrl = dev_get_drvdata(dev);
8504a2f83b7SClaudiu Beznea struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
8514a2f83b7SClaudiu Beznea int ret;
8524a2f83b7SClaudiu Beznea
8534a2f83b7SClaudiu Beznea ret = clk_enable(aq->pclk);
8544a2f83b7SClaudiu Beznea if (ret)
8554a2f83b7SClaudiu Beznea return ret;
8564a2f83b7SClaudiu Beznea
857c18bbac3SUwe Kleine-König ret = clk_enable(aq->qspick);
858c18bbac3SUwe Kleine-König if (ret)
859c18bbac3SUwe Kleine-König clk_disable(aq->pclk);
860c18bbac3SUwe Kleine-König
861c18bbac3SUwe Kleine-König return ret;
8624a2f83b7SClaudiu Beznea }
8634a2f83b7SClaudiu Beznea
8644a2f83b7SClaudiu Beznea static const struct dev_pm_ops __maybe_unused atmel_qspi_pm_ops = {
8654a2f83b7SClaudiu Beznea SET_SYSTEM_SLEEP_PM_OPS(atmel_qspi_suspend, atmel_qspi_resume)
8664a2f83b7SClaudiu Beznea SET_RUNTIME_PM_OPS(atmel_qspi_runtime_suspend,
8674a2f83b7SClaudiu Beznea atmel_qspi_runtime_resume, NULL)
8684a2f83b7SClaudiu Beznea };
8690e6aae08SPiotr Bugalski
8702e5c8888STudor Ambarus static const struct atmel_qspi_caps atmel_sama5d2_qspi_caps = {};
8712e5c8888STudor Ambarus
8722e5c8888STudor Ambarus static const struct atmel_qspi_caps atmel_sam9x60_qspi_caps = {
8732e5c8888STudor Ambarus .has_qspick = true,
8742e5c8888STudor Ambarus .has_ricr = true,
8752e5c8888STudor Ambarus };
8762e5c8888STudor Ambarus
8770e6aae08SPiotr Bugalski static const struct of_device_id atmel_qspi_dt_ids[] = {
8782e5c8888STudor Ambarus {
8792e5c8888STudor Ambarus .compatible = "atmel,sama5d2-qspi",
8802e5c8888STudor Ambarus .data = &atmel_sama5d2_qspi_caps,
8812e5c8888STudor Ambarus },
8822e5c8888STudor Ambarus {
8832e5c8888STudor Ambarus .compatible = "microchip,sam9x60-qspi",
8842e5c8888STudor Ambarus .data = &atmel_sam9x60_qspi_caps,
8852e5c8888STudor Ambarus },
8860e6aae08SPiotr Bugalski { /* sentinel */ }
8870e6aae08SPiotr Bugalski };
8880e6aae08SPiotr Bugalski
8890e6aae08SPiotr Bugalski MODULE_DEVICE_TABLE(of, atmel_qspi_dt_ids);
8900e6aae08SPiotr Bugalski
8910e6aae08SPiotr Bugalski static struct platform_driver atmel_qspi_driver = {
8920e6aae08SPiotr Bugalski .driver = {
8930e6aae08SPiotr Bugalski .name = "atmel_qspi",
8940e6aae08SPiotr Bugalski .of_match_table = atmel_qspi_dt_ids,
895f11ec1ccSClaudiu Beznea .pm = pm_ptr(&atmel_qspi_pm_ops),
8960e6aae08SPiotr Bugalski },
8970e6aae08SPiotr Bugalski .probe = atmel_qspi_probe,
8984d70dd0aSUwe Kleine-König .remove_new = atmel_qspi_remove,
8990e6aae08SPiotr Bugalski };
9000e6aae08SPiotr Bugalski module_platform_driver(atmel_qspi_driver);
9010e6aae08SPiotr Bugalski
9020e6aae08SPiotr Bugalski MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@atmel.com>");
9030e6aae08SPiotr Bugalski MODULE_AUTHOR("Piotr Bugalski <bugalski.piotr@gmail.com");
9040e6aae08SPiotr Bugalski MODULE_DESCRIPTION("Atmel QSPI Controller driver");
9050e6aae08SPiotr Bugalski MODULE_LICENSE("GPL v2");
906