xref: /openbmc/linux/drivers/spi/atmel-quadspi.c (revision 360823a09426347ea8f232b0b0b5156d0aed0302)
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