blob: 8a69b2caa7923025df95c3012fa1c97e93a729ad [file] [log] [blame]
Huang Shijiee46ecda2014-02-24 18:37:42 +08001/*
2 * Freescale QuadSPI driver.
3 *
4 * Copyright (C) 2013 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/interrupt.h>
14#include <linux/errno.h>
15#include <linux/platform_device.h>
16#include <linux/sched.h>
17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/timer.h>
24#include <linux/jiffies.h>
25#include <linux/completion.h>
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/partitions.h>
28#include <linux/mtd/spi-nor.h>
Han Xu392d39c2015-05-13 14:40:57 -050029#include <linux/mutex.h>
Huang Shijiee46ecda2014-02-24 18:37:42 +080030
Han Xu80d37722015-08-04 10:25:29 -050031/* Controller needs driver to swap endian */
32#define QUADSPI_QUIRK_SWAP_ENDIAN (1 << 0)
33/* Controller needs 4x internal clock */
34#define QUADSPI_QUIRK_4X_INT_CLK (1 << 1)
Frank Lid371cbf2015-08-04 10:25:35 -050035/*
36 * TKT253890, Controller needs driver to fill txfifo till 16 byte to
37 * trigger data transfer even though extern data will not transferred.
38 */
39#define QUADSPI_QUIRK_TKT253890 (1 << 2)
Han Xu80d37722015-08-04 10:25:29 -050040
Huang Shijiee46ecda2014-02-24 18:37:42 +080041/* The registers */
42#define QUADSPI_MCR 0x00
43#define QUADSPI_MCR_RESERVED_SHIFT 16
44#define QUADSPI_MCR_RESERVED_MASK (0xF << QUADSPI_MCR_RESERVED_SHIFT)
45#define QUADSPI_MCR_MDIS_SHIFT 14
46#define QUADSPI_MCR_MDIS_MASK (1 << QUADSPI_MCR_MDIS_SHIFT)
47#define QUADSPI_MCR_CLR_TXF_SHIFT 11
48#define QUADSPI_MCR_CLR_TXF_MASK (1 << QUADSPI_MCR_CLR_TXF_SHIFT)
49#define QUADSPI_MCR_CLR_RXF_SHIFT 10
50#define QUADSPI_MCR_CLR_RXF_MASK (1 << QUADSPI_MCR_CLR_RXF_SHIFT)
51#define QUADSPI_MCR_DDR_EN_SHIFT 7
52#define QUADSPI_MCR_DDR_EN_MASK (1 << QUADSPI_MCR_DDR_EN_SHIFT)
53#define QUADSPI_MCR_END_CFG_SHIFT 2
54#define QUADSPI_MCR_END_CFG_MASK (3 << QUADSPI_MCR_END_CFG_SHIFT)
55#define QUADSPI_MCR_SWRSTHD_SHIFT 1
56#define QUADSPI_MCR_SWRSTHD_MASK (1 << QUADSPI_MCR_SWRSTHD_SHIFT)
57#define QUADSPI_MCR_SWRSTSD_SHIFT 0
58#define QUADSPI_MCR_SWRSTSD_MASK (1 << QUADSPI_MCR_SWRSTSD_SHIFT)
59
60#define QUADSPI_IPCR 0x08
61#define QUADSPI_IPCR_SEQID_SHIFT 24
62#define QUADSPI_IPCR_SEQID_MASK (0xF << QUADSPI_IPCR_SEQID_SHIFT)
63
64#define QUADSPI_BUF0CR 0x10
65#define QUADSPI_BUF1CR 0x14
66#define QUADSPI_BUF2CR 0x18
67#define QUADSPI_BUFXCR_INVALID_MSTRID 0xe
68
69#define QUADSPI_BUF3CR 0x1c
70#define QUADSPI_BUF3CR_ALLMST_SHIFT 31
Allen Xu4e898ce2015-01-14 00:28:56 +080071#define QUADSPI_BUF3CR_ALLMST_MASK (1 << QUADSPI_BUF3CR_ALLMST_SHIFT)
72#define QUADSPI_BUF3CR_ADATSZ_SHIFT 8
73#define QUADSPI_BUF3CR_ADATSZ_MASK (0xFF << QUADSPI_BUF3CR_ADATSZ_SHIFT)
Huang Shijiee46ecda2014-02-24 18:37:42 +080074
75#define QUADSPI_BFGENCR 0x20
76#define QUADSPI_BFGENCR_PAR_EN_SHIFT 16
77#define QUADSPI_BFGENCR_PAR_EN_MASK (1 << (QUADSPI_BFGENCR_PAR_EN_SHIFT))
78#define QUADSPI_BFGENCR_SEQID_SHIFT 12
79#define QUADSPI_BFGENCR_SEQID_MASK (0xF << QUADSPI_BFGENCR_SEQID_SHIFT)
80
81#define QUADSPI_BUF0IND 0x30
82#define QUADSPI_BUF1IND 0x34
83#define QUADSPI_BUF2IND 0x38
84#define QUADSPI_SFAR 0x100
85
86#define QUADSPI_SMPR 0x108
87#define QUADSPI_SMPR_DDRSMP_SHIFT 16
88#define QUADSPI_SMPR_DDRSMP_MASK (7 << QUADSPI_SMPR_DDRSMP_SHIFT)
89#define QUADSPI_SMPR_FSDLY_SHIFT 6
90#define QUADSPI_SMPR_FSDLY_MASK (1 << QUADSPI_SMPR_FSDLY_SHIFT)
91#define QUADSPI_SMPR_FSPHS_SHIFT 5
92#define QUADSPI_SMPR_FSPHS_MASK (1 << QUADSPI_SMPR_FSPHS_SHIFT)
93#define QUADSPI_SMPR_HSENA_SHIFT 0
94#define QUADSPI_SMPR_HSENA_MASK (1 << QUADSPI_SMPR_HSENA_SHIFT)
95
96#define QUADSPI_RBSR 0x10c
97#define QUADSPI_RBSR_RDBFL_SHIFT 8
98#define QUADSPI_RBSR_RDBFL_MASK (0x3F << QUADSPI_RBSR_RDBFL_SHIFT)
99
100#define QUADSPI_RBCT 0x110
101#define QUADSPI_RBCT_WMRK_MASK 0x1F
102#define QUADSPI_RBCT_RXBRD_SHIFT 8
103#define QUADSPI_RBCT_RXBRD_USEIPS (0x1 << QUADSPI_RBCT_RXBRD_SHIFT)
104
105#define QUADSPI_TBSR 0x150
106#define QUADSPI_TBDR 0x154
107#define QUADSPI_SR 0x15c
108#define QUADSPI_SR_IP_ACC_SHIFT 1
109#define QUADSPI_SR_IP_ACC_MASK (0x1 << QUADSPI_SR_IP_ACC_SHIFT)
110#define QUADSPI_SR_AHB_ACC_SHIFT 2
111#define QUADSPI_SR_AHB_ACC_MASK (0x1 << QUADSPI_SR_AHB_ACC_SHIFT)
112
113#define QUADSPI_FR 0x160
114#define QUADSPI_FR_TFF_MASK 0x1
115
116#define QUADSPI_SFA1AD 0x180
117#define QUADSPI_SFA2AD 0x184
118#define QUADSPI_SFB1AD 0x188
119#define QUADSPI_SFB2AD 0x18c
120#define QUADSPI_RBDR 0x200
121
122#define QUADSPI_LUTKEY 0x300
123#define QUADSPI_LUTKEY_VALUE 0x5AF05AF0
124
125#define QUADSPI_LCKCR 0x304
126#define QUADSPI_LCKER_LOCK 0x1
127#define QUADSPI_LCKER_UNLOCK 0x2
128
129#define QUADSPI_RSER 0x164
130#define QUADSPI_RSER_TFIE (0x1 << 0)
131
132#define QUADSPI_LUT_BASE 0x310
133
134/*
135 * The definition of the LUT register shows below:
136 *
137 * ---------------------------------------------------
138 * | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 |
139 * ---------------------------------------------------
140 */
141#define OPRND0_SHIFT 0
142#define PAD0_SHIFT 8
143#define INSTR0_SHIFT 10
144#define OPRND1_SHIFT 16
145
146/* Instruction set for the LUT register. */
147#define LUT_STOP 0
148#define LUT_CMD 1
149#define LUT_ADDR 2
150#define LUT_DUMMY 3
151#define LUT_MODE 4
152#define LUT_MODE2 5
153#define LUT_MODE4 6
154#define LUT_READ 7
155#define LUT_WRITE 8
156#define LUT_JMP_ON_CS 9
157#define LUT_ADDR_DDR 10
158#define LUT_MODE_DDR 11
159#define LUT_MODE2_DDR 12
160#define LUT_MODE4_DDR 13
161#define LUT_READ_DDR 14
162#define LUT_WRITE_DDR 15
163#define LUT_DATA_LEARN 16
164
165/*
166 * The PAD definitions for LUT register.
167 *
168 * The pad stands for the lines number of IO[0:3].
169 * For example, the Quad read need four IO lines, so you should
170 * set LUT_PAD4 which means we use four IO lines.
171 */
172#define LUT_PAD1 0
173#define LUT_PAD2 1
174#define LUT_PAD4 2
175
176/* Oprands for the LUT register. */
177#define ADDR24BIT 0x18
178#define ADDR32BIT 0x20
179
180/* Macros for constructing the LUT register. */
181#define LUT0(ins, pad, opr) \
182 (((opr) << OPRND0_SHIFT) | ((LUT_##pad) << PAD0_SHIFT) | \
183 ((LUT_##ins) << INSTR0_SHIFT))
184
185#define LUT1(ins, pad, opr) (LUT0(ins, pad, opr) << OPRND1_SHIFT)
186
187/* other macros for LUT register. */
188#define QUADSPI_LUT(x) (QUADSPI_LUT_BASE + (x) * 4)
189#define QUADSPI_LUT_NUM 64
190
191/* SEQID -- we can have 16 seqids at most. */
192#define SEQID_QUAD_READ 0
193#define SEQID_WREN 1
194#define SEQID_WRDI 2
195#define SEQID_RDSR 3
196#define SEQID_SE 4
197#define SEQID_CHIP_ERASE 5
198#define SEQID_PP 6
199#define SEQID_RDID 7
200#define SEQID_WRSR 8
201#define SEQID_RDCR 9
202#define SEQID_EN4B 10
203#define SEQID_BRWR 11
204
Han Xu49bd7062015-08-04 10:25:22 -0500205#define QUADSPI_MIN_IOMAP SZ_4M
206
Huang Shijiee46ecda2014-02-24 18:37:42 +0800207enum fsl_qspi_devtype {
208 FSL_QUADSPI_VYBRID,
209 FSL_QUADSPI_IMX6SX,
Frank Lid371cbf2015-08-04 10:25:35 -0500210 FSL_QUADSPI_IMX7D,
Frank Li74a081d12015-08-04 10:25:47 -0500211 FSL_QUADSPI_IMX6UL,
Huang Shijiee46ecda2014-02-24 18:37:42 +0800212};
213
214struct fsl_qspi_devtype_data {
215 enum fsl_qspi_devtype devtype;
216 int rxfifo;
217 int txfifo;
Allen Xu4e898ce2015-01-14 00:28:56 +0800218 int ahb_buf_size;
Han Xu80d37722015-08-04 10:25:29 -0500219 int driver_data;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800220};
221
222static struct fsl_qspi_devtype_data vybrid_data = {
223 .devtype = FSL_QUADSPI_VYBRID,
224 .rxfifo = 128,
Allen Xu4e898ce2015-01-14 00:28:56 +0800225 .txfifo = 64,
Han Xu80d37722015-08-04 10:25:29 -0500226 .ahb_buf_size = 1024,
227 .driver_data = QUADSPI_QUIRK_SWAP_ENDIAN,
Huang Shijiee46ecda2014-02-24 18:37:42 +0800228};
229
230static struct fsl_qspi_devtype_data imx6sx_data = {
231 .devtype = FSL_QUADSPI_IMX6SX,
232 .rxfifo = 128,
Allen Xu4e898ce2015-01-14 00:28:56 +0800233 .txfifo = 512,
Han Xu80d37722015-08-04 10:25:29 -0500234 .ahb_buf_size = 1024,
235 .driver_data = QUADSPI_QUIRK_4X_INT_CLK,
Huang Shijiee46ecda2014-02-24 18:37:42 +0800236};
237
Frank Lid371cbf2015-08-04 10:25:35 -0500238static struct fsl_qspi_devtype_data imx7d_data = {
239 .devtype = FSL_QUADSPI_IMX7D,
240 .rxfifo = 512,
241 .txfifo = 512,
242 .ahb_buf_size = 1024,
243 .driver_data = QUADSPI_QUIRK_TKT253890
244 | QUADSPI_QUIRK_4X_INT_CLK,
245};
246
Frank Li74a081d12015-08-04 10:25:47 -0500247static struct fsl_qspi_devtype_data imx6ul_data = {
248 .devtype = FSL_QUADSPI_IMX6UL,
249 .rxfifo = 128,
250 .txfifo = 512,
251 .ahb_buf_size = 1024,
252 .driver_data = QUADSPI_QUIRK_TKT253890
253 | QUADSPI_QUIRK_4X_INT_CLK,
254};
255
Huang Shijiee46ecda2014-02-24 18:37:42 +0800256#define FSL_QSPI_MAX_CHIP 4
257struct fsl_qspi {
258 struct mtd_info mtd[FSL_QSPI_MAX_CHIP];
259 struct spi_nor nor[FSL_QSPI_MAX_CHIP];
260 void __iomem *iobase;
Han Xu49bd7062015-08-04 10:25:22 -0500261 void __iomem *ahb_addr;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800262 u32 memmap_phy;
Han Xu49bd7062015-08-04 10:25:22 -0500263 u32 memmap_offs;
264 u32 memmap_len;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800265 struct clk *clk, *clk_en;
266 struct device *dev;
267 struct completion c;
268 struct fsl_qspi_devtype_data *devtype_data;
269 u32 nor_size;
270 u32 nor_num;
271 u32 clk_rate;
272 unsigned int chip_base_addr; /* We may support two chips. */
Fabio Estevamcfe4af32015-01-13 20:14:15 -0200273 bool has_second_chip;
Han Xu392d39c2015-05-13 14:40:57 -0500274 struct mutex lock;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800275};
276
Han Xu80d37722015-08-04 10:25:29 -0500277static inline int needs_swap_endian(struct fsl_qspi *q)
Huang Shijiee46ecda2014-02-24 18:37:42 +0800278{
Han Xu80d37722015-08-04 10:25:29 -0500279 return q->devtype_data->driver_data & QUADSPI_QUIRK_SWAP_ENDIAN;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800280}
281
Han Xu80d37722015-08-04 10:25:29 -0500282static inline int needs_4x_clock(struct fsl_qspi *q)
Huang Shijiee46ecda2014-02-24 18:37:42 +0800283{
Han Xu80d37722015-08-04 10:25:29 -0500284 return q->devtype_data->driver_data & QUADSPI_QUIRK_4X_INT_CLK;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800285}
286
Frank Lid371cbf2015-08-04 10:25:35 -0500287static inline int needs_fill_txfifo(struct fsl_qspi *q)
288{
289 return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT253890;
290}
291
Huang Shijiee46ecda2014-02-24 18:37:42 +0800292/*
293 * An IC bug makes us to re-arrange the 32-bit data.
294 * The following chips, such as IMX6SLX, have fixed this bug.
295 */
296static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a)
297{
Han Xu80d37722015-08-04 10:25:29 -0500298 return needs_swap_endian(q) ? __swab32(a) : a;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800299}
300
301static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
302{
303 writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
304 writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
305}
306
307static inline void fsl_qspi_lock_lut(struct fsl_qspi *q)
308{
309 writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
310 writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
311}
312
313static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
314{
315 struct fsl_qspi *q = dev_id;
316 u32 reg;
317
318 /* clear interrupt */
319 reg = readl(q->iobase + QUADSPI_FR);
320 writel(reg, q->iobase + QUADSPI_FR);
321
322 if (reg & QUADSPI_FR_TFF_MASK)
323 complete(&q->c);
324
325 dev_dbg(q->dev, "QUADSPI_FR : 0x%.8x:0x%.8x\n", q->chip_base_addr, reg);
326 return IRQ_HANDLED;
327}
328
329static void fsl_qspi_init_lut(struct fsl_qspi *q)
330{
Brian Norrisa965d042014-04-10 15:49:38 -0700331 void __iomem *base = q->iobase;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800332 int rxfifo = q->devtype_data->rxfifo;
333 u32 lut_base;
334 u8 cmd, addrlen, dummy;
335 int i;
336
337 fsl_qspi_unlock_lut(q);
338
339 /* Clear all the LUT table */
340 for (i = 0; i < QUADSPI_LUT_NUM; i++)
341 writel(0, base + QUADSPI_LUT_BASE + i * 4);
342
343 /* Quad Read */
344 lut_base = SEQID_QUAD_READ * 4;
345
346 if (q->nor_size <= SZ_16M) {
Brian Norris58b89a12014-04-08 19:16:49 -0700347 cmd = SPINOR_OP_READ_1_1_4;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800348 addrlen = ADDR24BIT;
349 dummy = 8;
350 } else {
351 /* use the 4-byte address */
Brian Norris58b89a12014-04-08 19:16:49 -0700352 cmd = SPINOR_OP_READ_1_1_4;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800353 addrlen = ADDR32BIT;
354 dummy = 8;
355 }
356
357 writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
358 base + QUADSPI_LUT(lut_base));
359 writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
360 base + QUADSPI_LUT(lut_base + 1));
361
362 /* Write enable */
363 lut_base = SEQID_WREN * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700364 writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
Huang Shijiee46ecda2014-02-24 18:37:42 +0800365
366 /* Page Program */
367 lut_base = SEQID_PP * 4;
368
369 if (q->nor_size <= SZ_16M) {
Brian Norrisb02e7f32014-04-08 18:15:31 -0700370 cmd = SPINOR_OP_PP;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800371 addrlen = ADDR24BIT;
372 } else {
373 /* use the 4-byte address */
Brian Norrisb02e7f32014-04-08 18:15:31 -0700374 cmd = SPINOR_OP_PP;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800375 addrlen = ADDR32BIT;
376 }
377
378 writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
379 base + QUADSPI_LUT(lut_base));
380 writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
381
382 /* Read Status */
383 lut_base = SEQID_RDSR * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700384 writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
Huang Shijiee46ecda2014-02-24 18:37:42 +0800385 base + QUADSPI_LUT(lut_base));
386
387 /* Erase a sector */
388 lut_base = SEQID_SE * 4;
389
390 if (q->nor_size <= SZ_16M) {
Brian Norrisb02e7f32014-04-08 18:15:31 -0700391 cmd = SPINOR_OP_SE;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800392 addrlen = ADDR24BIT;
393 } else {
394 /* use the 4-byte address */
Brian Norrisb02e7f32014-04-08 18:15:31 -0700395 cmd = SPINOR_OP_SE;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800396 addrlen = ADDR32BIT;
397 }
398
399 writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
400 base + QUADSPI_LUT(lut_base));
401
402 /* Erase the whole chip */
403 lut_base = SEQID_CHIP_ERASE * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700404 writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
Huang Shijiee46ecda2014-02-24 18:37:42 +0800405 base + QUADSPI_LUT(lut_base));
406
407 /* READ ID */
408 lut_base = SEQID_RDID * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700409 writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
Huang Shijiee46ecda2014-02-24 18:37:42 +0800410 base + QUADSPI_LUT(lut_base));
411
412 /* Write Register */
413 lut_base = SEQID_WRSR * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700414 writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
Huang Shijiee46ecda2014-02-24 18:37:42 +0800415 base + QUADSPI_LUT(lut_base));
416
417 /* Read Configuration Register */
418 lut_base = SEQID_RDCR * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700419 writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
Huang Shijiee46ecda2014-02-24 18:37:42 +0800420 base + QUADSPI_LUT(lut_base));
421
422 /* Write disable */
423 lut_base = SEQID_WRDI * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700424 writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base));
Huang Shijiee46ecda2014-02-24 18:37:42 +0800425
426 /* Enter 4 Byte Mode (Micron) */
427 lut_base = SEQID_EN4B * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700428 writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base));
Huang Shijiee46ecda2014-02-24 18:37:42 +0800429
430 /* Enter 4 Byte Mode (Spansion) */
431 lut_base = SEQID_BRWR * 4;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700432 writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base));
Huang Shijiee46ecda2014-02-24 18:37:42 +0800433
434 fsl_qspi_lock_lut(q);
435}
436
437/* Get the SEQID for the command */
438static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
439{
440 switch (cmd) {
Brian Norris58b89a12014-04-08 19:16:49 -0700441 case SPINOR_OP_READ_1_1_4:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800442 return SEQID_QUAD_READ;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700443 case SPINOR_OP_WREN:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800444 return SEQID_WREN;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700445 case SPINOR_OP_WRDI:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800446 return SEQID_WRDI;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700447 case SPINOR_OP_RDSR:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800448 return SEQID_RDSR;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700449 case SPINOR_OP_SE:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800450 return SEQID_SE;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700451 case SPINOR_OP_CHIP_ERASE:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800452 return SEQID_CHIP_ERASE;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700453 case SPINOR_OP_PP:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800454 return SEQID_PP;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700455 case SPINOR_OP_RDID:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800456 return SEQID_RDID;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700457 case SPINOR_OP_WRSR:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800458 return SEQID_WRSR;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700459 case SPINOR_OP_RDCR:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800460 return SEQID_RDCR;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700461 case SPINOR_OP_EN4B:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800462 return SEQID_EN4B;
Brian Norrisb02e7f32014-04-08 18:15:31 -0700463 case SPINOR_OP_BRWR:
Huang Shijiee46ecda2014-02-24 18:37:42 +0800464 return SEQID_BRWR;
465 default:
466 dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
467 break;
468 }
469 return -EINVAL;
470}
471
472static int
473fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
474{
Brian Norrisa965d042014-04-10 15:49:38 -0700475 void __iomem *base = q->iobase;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800476 int seqid;
477 u32 reg, reg2;
478 int err;
479
480 init_completion(&q->c);
481 dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len:%d, cmd:%.2x\n",
482 q->chip_base_addr, addr, len, cmd);
483
484 /* save the reg */
485 reg = readl(base + QUADSPI_MCR);
486
487 writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR);
488 writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
489 base + QUADSPI_RBCT);
490 writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
491
492 do {
493 reg2 = readl(base + QUADSPI_SR);
494 if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
495 udelay(1);
496 dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2);
497 continue;
498 }
499 break;
500 } while (1);
501
502 /* trigger the LUT now */
503 seqid = fsl_qspi_get_seqid(q, cmd);
504 writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR);
505
506 /* Wait for the interrupt. */
Nicholas Mc Guire219a8d12015-02-01 06:15:46 -0500507 if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) {
Huang Shijiee46ecda2014-02-24 18:37:42 +0800508 dev_err(q->dev,
509 "cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n",
510 cmd, addr, readl(base + QUADSPI_FR),
511 readl(base + QUADSPI_SR));
512 err = -ETIMEDOUT;
513 } else {
514 err = 0;
515 }
516
517 /* restore the MCR */
518 writel(reg, base + QUADSPI_MCR);
519
520 return err;
521}
522
523/* Read out the data from the QUADSPI_RBDR buffer registers. */
524static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf)
525{
526 u32 tmp;
527 int i = 0;
528
529 while (len > 0) {
530 tmp = readl(q->iobase + QUADSPI_RBDR + i * 4);
531 tmp = fsl_qspi_endian_xchg(q, tmp);
532 dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n",
533 q->chip_base_addr, tmp);
534
535 if (len >= 4) {
536 *((u32 *)rxbuf) = tmp;
537 rxbuf += 4;
538 } else {
539 memcpy(rxbuf, &tmp, len);
540 break;
541 }
542
543 len -= 4;
544 i++;
545 }
546}
547
548/*
549 * If we have changed the content of the flash by writing or erasing,
550 * we need to invalidate the AHB buffer. If we do not do so, we may read out
551 * the wrong data. The spec tells us reset the AHB domain and Serial Flash
552 * domain at the same time.
553 */
554static inline void fsl_qspi_invalid(struct fsl_qspi *q)
555{
556 u32 reg;
557
558 reg = readl(q->iobase + QUADSPI_MCR);
559 reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK;
560 writel(reg, q->iobase + QUADSPI_MCR);
561
562 /*
563 * The minimum delay : 1 AHB + 2 SFCK clocks.
564 * Delay 1 us is enough.
565 */
566 udelay(1);
567
568 reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK);
569 writel(reg, q->iobase + QUADSPI_MCR);
570}
571
572static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
573 u8 opcode, unsigned int to, u32 *txbuf,
574 unsigned count, size_t *retlen)
575{
576 int ret, i, j;
577 u32 tmp;
578
579 dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len : %d\n",
580 q->chip_base_addr, to, count);
581
582 /* clear the TX FIFO. */
583 tmp = readl(q->iobase + QUADSPI_MCR);
Alexander Stein038761d2015-07-02 11:37:56 +0200584 writel(tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800585
586 /* fill the TX data to the FIFO */
587 for (j = 0, i = ((count + 3) / 4); j < i; j++) {
588 tmp = fsl_qspi_endian_xchg(q, *txbuf);
589 writel(tmp, q->iobase + QUADSPI_TBDR);
590 txbuf++;
591 }
592
Frank Lid371cbf2015-08-04 10:25:35 -0500593 /* fill the TXFIFO upto 16 bytes for i.MX7d */
594 if (needs_fill_txfifo(q))
595 for (; i < 4; i++)
596 writel(tmp, q->iobase + QUADSPI_TBDR);
597
Huang Shijiee46ecda2014-02-24 18:37:42 +0800598 /* Trigger it */
599 ret = fsl_qspi_runcmd(q, opcode, to, count);
600
601 if (ret == 0 && retlen)
602 *retlen += count;
603
604 return ret;
605}
606
607static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
608{
609 int nor_size = q->nor_size;
610 void __iomem *base = q->iobase;
611
612 writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
613 writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
614 writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
615 writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
616}
617
618/*
619 * There are two different ways to read out the data from the flash:
620 * the "IP Command Read" and the "AHB Command Read".
621 *
622 * The IC guy suggests we use the "AHB Command Read" which is faster
623 * then the "IP Command Read". (What's more is that there is a bug in
624 * the "IP Command Read" in the Vybrid.)
625 *
626 * After we set up the registers for the "AHB Command Read", we can use
627 * the memcpy to read the data directly. A "missed" access to the buffer
628 * causes the controller to clear the buffer, and use the sequence pointed
629 * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
630 */
631static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
632{
633 void __iomem *base = q->iobase;
634 int seqid;
635
636 /* AHB configuration for access buffer 0/1/2 .*/
637 writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
638 writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
639 writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
Allen Xu4e898ce2015-01-14 00:28:56 +0800640 /*
641 * Set ADATSZ with the maximum AHB buffer size to improve the
642 * read performance.
643 */
644 writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8)
645 << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800646
647 /* We only use the buffer3 */
648 writel(0, base + QUADSPI_BUF0IND);
649 writel(0, base + QUADSPI_BUF1IND);
650 writel(0, base + QUADSPI_BUF2IND);
651
652 /* Set the default lut sequence for AHB Read. */
653 seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
654 writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
655 q->iobase + QUADSPI_BFGENCR);
656}
657
Allen Xucacbef42015-08-04 10:25:58 -0500658/* This function was used to prepare and enable QSPI clock */
659static int fsl_qspi_clk_prep_enable(struct fsl_qspi *q)
660{
661 int ret;
662
663 ret = clk_prepare_enable(q->clk_en);
664 if (ret)
665 return ret;
666
667 ret = clk_prepare_enable(q->clk);
668 if (ret) {
669 clk_disable_unprepare(q->clk_en);
670 return ret;
671 }
672
673 return 0;
674}
675
676/* This function was used to disable and unprepare QSPI clock */
677static void fsl_qspi_clk_disable_unprep(struct fsl_qspi *q)
678{
679 clk_disable_unprepare(q->clk);
680 clk_disable_unprepare(q->clk_en);
681
682}
683
Huang Shijiee46ecda2014-02-24 18:37:42 +0800684/* We use this function to do some basic init for spi_nor_scan(). */
685static int fsl_qspi_nor_setup(struct fsl_qspi *q)
686{
687 void __iomem *base = q->iobase;
688 u32 reg;
689 int ret;
690
Allen Xucacbef42015-08-04 10:25:58 -0500691 /* disable and unprepare clock to avoid glitch pass to controller */
692 fsl_qspi_clk_disable_unprep(q);
693
694 /* the default frequency, we will change it in the future. */
Huang Shijiee46ecda2014-02-24 18:37:42 +0800695 ret = clk_set_rate(q->clk, 66000000);
696 if (ret)
697 return ret;
698
Allen Xucacbef42015-08-04 10:25:58 -0500699 ret = fsl_qspi_clk_prep_enable(q);
700 if (ret)
701 return ret;
702
Huang Shijiee46ecda2014-02-24 18:37:42 +0800703 /* Init the LUT table. */
704 fsl_qspi_init_lut(q);
705
706 /* Disable the module */
707 writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
708 base + QUADSPI_MCR);
709
710 reg = readl(base + QUADSPI_SMPR);
711 writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK
712 | QUADSPI_SMPR_FSPHS_MASK
713 | QUADSPI_SMPR_HSENA_MASK
714 | QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
715
716 /* Enable the module */
717 writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
718 base + QUADSPI_MCR);
719
720 /* enable the interrupt */
721 writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
722
723 return 0;
724}
725
726static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
727{
728 unsigned long rate = q->clk_rate;
729 int ret;
730
Han Xu80d37722015-08-04 10:25:29 -0500731 if (needs_4x_clock(q))
Huang Shijiee46ecda2014-02-24 18:37:42 +0800732 rate *= 4;
733
Allen Xucacbef42015-08-04 10:25:58 -0500734 /* disable and unprepare clock to avoid glitch pass to controller */
735 fsl_qspi_clk_disable_unprep(q);
736
Huang Shijiee46ecda2014-02-24 18:37:42 +0800737 ret = clk_set_rate(q->clk, rate);
738 if (ret)
739 return ret;
740
Allen Xucacbef42015-08-04 10:25:58 -0500741 ret = fsl_qspi_clk_prep_enable(q);
742 if (ret)
743 return ret;
744
Huang Shijiee46ecda2014-02-24 18:37:42 +0800745 /* Init the LUT table again. */
746 fsl_qspi_init_lut(q);
747
748 /* Init for AHB read */
749 fsl_qspi_init_abh_read(q);
750
751 return 0;
752}
753
Fabian Frederick66610442015-03-16 20:20:28 +0100754static const struct of_device_id fsl_qspi_dt_ids[] = {
Huang Shijiee46ecda2014-02-24 18:37:42 +0800755 { .compatible = "fsl,vf610-qspi", .data = (void *)&vybrid_data, },
756 { .compatible = "fsl,imx6sx-qspi", .data = (void *)&imx6sx_data, },
Frank Lid371cbf2015-08-04 10:25:35 -0500757 { .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
Frank Li74a081d12015-08-04 10:25:47 -0500758 { .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
Huang Shijiee46ecda2014-02-24 18:37:42 +0800759 { /* sentinel */ }
760};
761MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
762
763static void fsl_qspi_set_base_addr(struct fsl_qspi *q, struct spi_nor *nor)
764{
765 q->chip_base_addr = q->nor_size * (nor - q->nor);
766}
767
768static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
769{
770 int ret;
771 struct fsl_qspi *q = nor->priv;
772
773 ret = fsl_qspi_runcmd(q, opcode, 0, len);
774 if (ret)
775 return ret;
776
777 fsl_qspi_read_data(q, len, buf);
778 return 0;
779}
780
781static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
782 int write_enable)
783{
784 struct fsl_qspi *q = nor->priv;
785 int ret;
786
787 if (!buf) {
788 ret = fsl_qspi_runcmd(q, opcode, 0, 1);
789 if (ret)
790 return ret;
791
Brian Norrisb02e7f32014-04-08 18:15:31 -0700792 if (opcode == SPINOR_OP_CHIP_ERASE)
Huang Shijiee46ecda2014-02-24 18:37:42 +0800793 fsl_qspi_invalid(q);
794
795 } else if (len > 0) {
796 ret = fsl_qspi_nor_write(q, nor, opcode, 0,
797 (u32 *)buf, len, NULL);
798 } else {
799 dev_err(q->dev, "invalid cmd %d\n", opcode);
800 ret = -EINVAL;
801 }
802
803 return ret;
804}
805
806static void fsl_qspi_write(struct spi_nor *nor, loff_t to,
807 size_t len, size_t *retlen, const u_char *buf)
808{
809 struct fsl_qspi *q = nor->priv;
810
811 fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
812 (u32 *)buf, len, retlen);
813
814 /* invalid the data in the AHB buffer. */
815 fsl_qspi_invalid(q);
816}
817
818static int fsl_qspi_read(struct spi_nor *nor, loff_t from,
819 size_t len, size_t *retlen, u_char *buf)
820{
821 struct fsl_qspi *q = nor->priv;
822 u8 cmd = nor->read_opcode;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800823
Han Xu49bd7062015-08-04 10:25:22 -0500824 /* if necessary,ioremap buffer before AHB read, */
825 if (!q->ahb_addr) {
826 q->memmap_offs = q->chip_base_addr + from;
827 q->memmap_len = len > QUADSPI_MIN_IOMAP ? len : QUADSPI_MIN_IOMAP;
828
829 q->ahb_addr = ioremap_nocache(
830 q->memmap_phy + q->memmap_offs,
831 q->memmap_len);
832 if (!q->ahb_addr) {
833 dev_err(q->dev, "ioremap failed\n");
834 return -ENOMEM;
835 }
836 /* ioremap if the data requested is out of range */
837 } else if (q->chip_base_addr + from < q->memmap_offs
838 || q->chip_base_addr + from + len >
839 q->memmap_offs + q->memmap_len) {
840 iounmap(q->ahb_addr);
841
842 q->memmap_offs = q->chip_base_addr + from;
843 q->memmap_len = len > QUADSPI_MIN_IOMAP ? len : QUADSPI_MIN_IOMAP;
844 q->ahb_addr = ioremap_nocache(
845 q->memmap_phy + q->memmap_offs,
846 q->memmap_len);
847 if (!q->ahb_addr) {
848 dev_err(q->dev, "ioremap failed\n");
849 return -ENOMEM;
850 }
851 }
852
853 dev_dbg(q->dev, "cmd [%x],read from 0x%p, len:%d\n",
854 cmd, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
855 len);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800856
Huang Shijiee46ecda2014-02-24 18:37:42 +0800857 /* Read out the data directly from the AHB buffer.*/
Han Xu49bd7062015-08-04 10:25:22 -0500858 memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
859 len);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800860
861 *retlen += len;
862 return 0;
863}
864
865static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
866{
867 struct fsl_qspi *q = nor->priv;
868 int ret;
869
870 dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
871 nor->mtd->erasesize / 1024, q->chip_base_addr, (u32)offs);
872
Huang Shijiee46ecda2014-02-24 18:37:42 +0800873 ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
874 if (ret)
875 return ret;
876
877 fsl_qspi_invalid(q);
878 return 0;
879}
880
881static int fsl_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
882{
883 struct fsl_qspi *q = nor->priv;
884 int ret;
885
Han Xu392d39c2015-05-13 14:40:57 -0500886 mutex_lock(&q->lock);
Allen Xucacbef42015-08-04 10:25:58 -0500887
888 ret = fsl_qspi_clk_prep_enable(q);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800889 if (ret)
Han Xu392d39c2015-05-13 14:40:57 -0500890 goto err_mutex;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800891
Huang Shijiee46ecda2014-02-24 18:37:42 +0800892 fsl_qspi_set_base_addr(q, nor);
893 return 0;
Han Xu392d39c2015-05-13 14:40:57 -0500894
Han Xu392d39c2015-05-13 14:40:57 -0500895err_mutex:
896 mutex_unlock(&q->lock);
Han Xu392d39c2015-05-13 14:40:57 -0500897 return ret;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800898}
899
900static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
901{
902 struct fsl_qspi *q = nor->priv;
903
Allen Xucacbef42015-08-04 10:25:58 -0500904 fsl_qspi_clk_disable_unprep(q);
Han Xu392d39c2015-05-13 14:40:57 -0500905 mutex_unlock(&q->lock);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800906}
907
908static int fsl_qspi_probe(struct platform_device *pdev)
909{
910 struct device_node *np = pdev->dev.of_node;
911 struct mtd_part_parser_data ppdata;
912 struct device *dev = &pdev->dev;
913 struct fsl_qspi *q;
914 struct resource *res;
915 struct spi_nor *nor;
916 struct mtd_info *mtd;
917 int ret, i = 0;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800918 const struct of_device_id *of_id =
919 of_match_device(fsl_qspi_dt_ids, &pdev->dev);
920
921 q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
922 if (!q)
923 return -ENOMEM;
924
925 q->nor_num = of_get_child_count(dev->of_node);
926 if (!q->nor_num || q->nor_num > FSL_QSPI_MAX_CHIP)
927 return -ENODEV;
928
929 /* find the resources */
930 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI");
931 q->iobase = devm_ioremap_resource(dev, res);
Fabio Estevamb1ab4742015-01-22 22:43:07 -0200932 if (IS_ERR(q->iobase))
933 return PTR_ERR(q->iobase);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800934
935 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
936 "QuadSPI-memory");
Han Xu49bd7062015-08-04 10:25:22 -0500937 if (!devm_request_mem_region(dev, res->start, resource_size(res),
938 res->name)) {
939 dev_err(dev, "can't request region for resource %pR\n", res);
940 return -EBUSY;
941 }
Fabio Estevamb1ab4742015-01-22 22:43:07 -0200942
Huang Shijiee46ecda2014-02-24 18:37:42 +0800943 q->memmap_phy = res->start;
944
945 /* find the clocks */
946 q->clk_en = devm_clk_get(dev, "qspi_en");
Fabio Estevamb1ab4742015-01-22 22:43:07 -0200947 if (IS_ERR(q->clk_en))
948 return PTR_ERR(q->clk_en);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800949
950 q->clk = devm_clk_get(dev, "qspi");
Fabio Estevamb1ab4742015-01-22 22:43:07 -0200951 if (IS_ERR(q->clk))
952 return PTR_ERR(q->clk);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800953
Allen Xucacbef42015-08-04 10:25:58 -0500954 ret = fsl_qspi_clk_prep_enable(q);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800955 if (ret) {
Allen Xucacbef42015-08-04 10:25:58 -0500956 dev_err(dev, "can not enable the clock\n");
Fabio Estevam77adc082014-10-17 17:14:01 -0300957 goto clk_failed;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800958 }
959
960 /* find the irq */
961 ret = platform_get_irq(pdev, 0);
962 if (ret < 0) {
Fabio Estevamdc6525c2015-02-09 10:07:19 -0200963 dev_err(dev, "failed to get the irq: %d\n", ret);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800964 goto irq_failed;
965 }
966
967 ret = devm_request_irq(dev, ret,
968 fsl_qspi_irq_handler, 0, pdev->name, q);
969 if (ret) {
Fabio Estevamdc6525c2015-02-09 10:07:19 -0200970 dev_err(dev, "failed to request irq: %d\n", ret);
Huang Shijiee46ecda2014-02-24 18:37:42 +0800971 goto irq_failed;
972 }
973
974 q->dev = dev;
975 q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data;
976 platform_set_drvdata(pdev, q);
977
978 ret = fsl_qspi_nor_setup(q);
979 if (ret)
980 goto irq_failed;
981
982 if (of_get_property(np, "fsl,qspi-has-second-chip", NULL))
Fabio Estevamcfe4af32015-01-13 20:14:15 -0200983 q->has_second_chip = true;
Huang Shijiee46ecda2014-02-24 18:37:42 +0800984
Han Xu392d39c2015-05-13 14:40:57 -0500985 mutex_init(&q->lock);
986
Huang Shijiee46ecda2014-02-24 18:37:42 +0800987 /* iterate the subnodes. */
988 for_each_available_child_of_node(dev->of_node, np) {
Huang Shijiee46ecda2014-02-24 18:37:42 +0800989 char modalias[40];
990
991 /* skip the holes */
Fabio Estevamcfe4af32015-01-13 20:14:15 -0200992 if (!q->has_second_chip)
Huang Shijiee46ecda2014-02-24 18:37:42 +0800993 i *= 2;
994
995 nor = &q->nor[i];
996 mtd = &q->mtd[i];
997
998 nor->mtd = mtd;
999 nor->dev = dev;
1000 nor->priv = q;
1001 mtd->priv = nor;
1002
1003 /* fill the hooks */
1004 nor->read_reg = fsl_qspi_read_reg;
1005 nor->write_reg = fsl_qspi_write_reg;
1006 nor->read = fsl_qspi_read;
1007 nor->write = fsl_qspi_write;
1008 nor->erase = fsl_qspi_erase;
1009
1010 nor->prepare = fsl_qspi_prep;
1011 nor->unprepare = fsl_qspi_unprep;
1012
Fabio Estevamb26171e2014-10-17 15:31:08 -03001013 ret = of_modalias_node(np, modalias, sizeof(modalias));
1014 if (ret < 0)
Han Xu392d39c2015-05-13 14:40:57 -05001015 goto mutex_failed;
Huang Shijiee46ecda2014-02-24 18:37:42 +08001016
Huang Shijiee46ecda2014-02-24 18:37:42 +08001017 ret = of_property_read_u32(np, "spi-max-frequency",
1018 &q->clk_rate);
1019 if (ret < 0)
Han Xu392d39c2015-05-13 14:40:57 -05001020 goto mutex_failed;
Huang Shijiee46ecda2014-02-24 18:37:42 +08001021
1022 /* set the chip address for READID */
1023 fsl_qspi_set_base_addr(q, nor);
1024
Ben Hutchings70f3ce02014-09-29 11:47:54 +02001025 ret = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
Huang Shijiee46ecda2014-02-24 18:37:42 +08001026 if (ret)
Han Xu392d39c2015-05-13 14:40:57 -05001027 goto mutex_failed;
Huang Shijiee46ecda2014-02-24 18:37:42 +08001028
1029 ppdata.of_node = np;
1030 ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
1031 if (ret)
Han Xu392d39c2015-05-13 14:40:57 -05001032 goto mutex_failed;
Huang Shijiee46ecda2014-02-24 18:37:42 +08001033
1034 /* Set the correct NOR size now. */
1035 if (q->nor_size == 0) {
1036 q->nor_size = mtd->size;
1037
1038 /* Map the SPI NOR to accessiable address */
1039 fsl_qspi_set_map_addr(q);
1040 }
1041
1042 /*
1043 * The TX FIFO is 64 bytes in the Vybrid, but the Page Program
1044 * may writes 265 bytes per time. The write is working in the
1045 * unit of the TX FIFO, not in the unit of the SPI NOR's page
1046 * size.
1047 *
1048 * So shrink the spi_nor->page_size if it is larger then the
1049 * TX FIFO.
1050 */
1051 if (nor->page_size > q->devtype_data->txfifo)
1052 nor->page_size = q->devtype_data->txfifo;
1053
1054 i++;
1055 }
1056
1057 /* finish the rest init. */
1058 ret = fsl_qspi_nor_setup_last(q);
1059 if (ret)
1060 goto last_init_failed;
1061
Allen Xucacbef42015-08-04 10:25:58 -05001062 fsl_qspi_clk_disable_unprep(q);
Huang Shijiee46ecda2014-02-24 18:37:42 +08001063 return 0;
1064
1065last_init_failed:
Fabio Estevamcfe4af32015-01-13 20:14:15 -02001066 for (i = 0; i < q->nor_num; i++) {
1067 /* skip the holes */
1068 if (!q->has_second_chip)
1069 i *= 2;
Huang Shijiee46ecda2014-02-24 18:37:42 +08001070 mtd_device_unregister(&q->mtd[i]);
Fabio Estevamcfe4af32015-01-13 20:14:15 -02001071 }
Han Xu392d39c2015-05-13 14:40:57 -05001072mutex_failed:
1073 mutex_destroy(&q->lock);
Huang Shijiee46ecda2014-02-24 18:37:42 +08001074irq_failed:
Allen Xucacbef42015-08-04 10:25:58 -05001075 fsl_qspi_clk_disable_unprep(q);
Fabio Estevam77adc082014-10-17 17:14:01 -03001076clk_failed:
Allen Xucacbef42015-08-04 10:25:58 -05001077 dev_err(dev, "Freescale QuadSPI probe failed\n");
Huang Shijiee46ecda2014-02-24 18:37:42 +08001078 return ret;
1079}
1080
1081static int fsl_qspi_remove(struct platform_device *pdev)
1082{
1083 struct fsl_qspi *q = platform_get_drvdata(pdev);
1084 int i;
1085
Fabio Estevamcfe4af32015-01-13 20:14:15 -02001086 for (i = 0; i < q->nor_num; i++) {
1087 /* skip the holes */
1088 if (!q->has_second_chip)
1089 i *= 2;
Huang Shijiee46ecda2014-02-24 18:37:42 +08001090 mtd_device_unregister(&q->mtd[i]);
Fabio Estevamcfe4af32015-01-13 20:14:15 -02001091 }
Huang Shijiee46ecda2014-02-24 18:37:42 +08001092
1093 /* disable the hardware */
1094 writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
1095 writel(0x0, q->iobase + QUADSPI_RSER);
1096
Han Xu392d39c2015-05-13 14:40:57 -05001097 mutex_destroy(&q->lock);
Han Xu49bd7062015-08-04 10:25:22 -05001098
1099 if (q->ahb_addr)
1100 iounmap(q->ahb_addr);
1101
Huang Shijiee46ecda2014-02-24 18:37:42 +08001102 return 0;
1103}
1104
Allen Xu45c6a0c2015-01-13 04:56:40 +08001105static int fsl_qspi_suspend(struct platform_device *pdev, pm_message_t state)
1106{
1107 return 0;
1108}
1109
1110static int fsl_qspi_resume(struct platform_device *pdev)
1111{
Allen Xucacbef42015-08-04 10:25:58 -05001112 int ret;
Allen Xu45c6a0c2015-01-13 04:56:40 +08001113 struct fsl_qspi *q = platform_get_drvdata(pdev);
1114
Allen Xucacbef42015-08-04 10:25:58 -05001115 ret = fsl_qspi_clk_prep_enable(q);
1116 if (ret)
1117 return ret;
1118
Allen Xu45c6a0c2015-01-13 04:56:40 +08001119 fsl_qspi_nor_setup(q);
1120 fsl_qspi_set_map_addr(q);
1121 fsl_qspi_nor_setup_last(q);
1122
Allen Xucacbef42015-08-04 10:25:58 -05001123 fsl_qspi_clk_disable_unprep(q);
1124
Allen Xu45c6a0c2015-01-13 04:56:40 +08001125 return 0;
1126}
1127
Huang Shijiee46ecda2014-02-24 18:37:42 +08001128static struct platform_driver fsl_qspi_driver = {
1129 .driver = {
1130 .name = "fsl-quadspi",
1131 .bus = &platform_bus_type,
Huang Shijiee46ecda2014-02-24 18:37:42 +08001132 .of_match_table = fsl_qspi_dt_ids,
1133 },
1134 .probe = fsl_qspi_probe,
1135 .remove = fsl_qspi_remove,
Allen Xu45c6a0c2015-01-13 04:56:40 +08001136 .suspend = fsl_qspi_suspend,
1137 .resume = fsl_qspi_resume,
Huang Shijiee46ecda2014-02-24 18:37:42 +08001138};
1139module_platform_driver(fsl_qspi_driver);
1140
1141MODULE_DESCRIPTION("Freescale QuadSPI Controller Driver");
1142MODULE_AUTHOR("Freescale Semiconductor Inc.");
1143MODULE_LICENSE("GPL v2");