2 * SPI-NOR driver for NXP SPI Flash Interface (SPIFI)
4 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
6 * Based on Freescale QuadSPI driver:
7 * Copyright (C) 2013 Freescale Semiconductor, Inc.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
15 #include <linux/clk.h>
16 #include <linux/err.h>
18 #include <linux/iopoll.h>
19 #include <linux/module.h>
20 #include <linux/mtd/mtd.h>
21 #include <linux/mtd/partitions.h>
22 #include <linux/mtd/spi-nor.h>
24 #include <linux/of_device.h>
25 #include <linux/platform_device.h>
26 #include <linux/spi/spi.h>
28 /* NXP SPIFI registers, bits and macros */
29 #define SPIFI_CTRL 0x000
30 #define SPIFI_CTRL_TIMEOUT(timeout) (timeout)
31 #define SPIFI_CTRL_CSHIGH(cshigh) ((cshigh) << 16)
32 #define SPIFI_CTRL_MODE3 BIT(23)
33 #define SPIFI_CTRL_DUAL BIT(28)
34 #define SPIFI_CTRL_FBCLK BIT(30)
35 #define SPIFI_CMD 0x004
36 #define SPIFI_CMD_DATALEN(dlen) ((dlen) & 0x3fff)
37 #define SPIFI_CMD_DOUT BIT(15)
38 #define SPIFI_CMD_INTLEN(ilen) ((ilen) << 16)
39 #define SPIFI_CMD_FIELDFORM(field) ((field) << 19)
40 #define SPIFI_CMD_FIELDFORM_ALL_SERIAL SPIFI_CMD_FIELDFORM(0x0)
41 #define SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA SPIFI_CMD_FIELDFORM(0x1)
42 #define SPIFI_CMD_FRAMEFORM(frame) ((frame) << 21)
43 #define SPIFI_CMD_FRAMEFORM_OPCODE_ONLY SPIFI_CMD_FRAMEFORM(0x1)
44 #define SPIFI_CMD_OPCODE(op) ((op) << 24)
45 #define SPIFI_ADDR 0x008
46 #define SPIFI_IDATA 0x00c
47 #define SPIFI_CLIMIT 0x010
48 #define SPIFI_DATA 0x014
49 #define SPIFI_MCMD 0x018
50 #define SPIFI_STAT 0x01c
51 #define SPIFI_STAT_MCINIT BIT(0)
52 #define SPIFI_STAT_CMD BIT(1)
53 #define SPIFI_STAT_RESET BIT(4)
55 #define SPI_NOR_MAX_ID_LEN 6
59 struct clk
*clk_spifi
;
61 void __iomem
*io_base
;
62 void __iomem
*flash_base
;
68 static int nxp_spifi_wait_for_cmd(struct nxp_spifi
*spifi
)
73 ret
= readb_poll_timeout(spifi
->io_base
+ SPIFI_STAT
, stat
,
74 !(stat
& SPIFI_STAT_CMD
), 10, 30);
76 dev_warn(spifi
->dev
, "command timed out\n");
81 static int nxp_spifi_reset(struct nxp_spifi
*spifi
)
86 writel(SPIFI_STAT_RESET
, spifi
->io_base
+ SPIFI_STAT
);
87 ret
= readb_poll_timeout(spifi
->io_base
+ SPIFI_STAT
, stat
,
88 !(stat
& SPIFI_STAT_RESET
), 10, 30);
90 dev_warn(spifi
->dev
, "state reset timed out\n");
95 static int nxp_spifi_set_memory_mode_off(struct nxp_spifi
*spifi
)
99 if (!spifi
->memory_mode
)
102 ret
= nxp_spifi_reset(spifi
);
104 dev_err(spifi
->dev
, "unable to enter command mode\n");
106 spifi
->memory_mode
= false;
111 static int nxp_spifi_set_memory_mode_on(struct nxp_spifi
*spifi
)
116 if (spifi
->memory_mode
)
119 writel(spifi
->mcmd
, spifi
->io_base
+ SPIFI_MCMD
);
120 ret
= readb_poll_timeout(spifi
->io_base
+ SPIFI_STAT
, stat
,
121 stat
& SPIFI_STAT_MCINIT
, 10, 30);
123 dev_err(spifi
->dev
, "unable to enter memory mode\n");
125 spifi
->memory_mode
= true;
130 static int nxp_spifi_read_reg(struct spi_nor
*nor
, u8 opcode
, u8
*buf
, int len
)
132 struct nxp_spifi
*spifi
= nor
->priv
;
136 ret
= nxp_spifi_set_memory_mode_off(spifi
);
140 cmd
= SPIFI_CMD_DATALEN(len
) |
141 SPIFI_CMD_OPCODE(opcode
) |
142 SPIFI_CMD_FIELDFORM_ALL_SERIAL
|
143 SPIFI_CMD_FRAMEFORM_OPCODE_ONLY
;
144 writel(cmd
, spifi
->io_base
+ SPIFI_CMD
);
147 *buf
++ = readb(spifi
->io_base
+ SPIFI_DATA
);
149 return nxp_spifi_wait_for_cmd(spifi
);
152 static int nxp_spifi_write_reg(struct spi_nor
*nor
, u8 opcode
, u8
*buf
, int len
)
154 struct nxp_spifi
*spifi
= nor
->priv
;
158 ret
= nxp_spifi_set_memory_mode_off(spifi
);
162 cmd
= SPIFI_CMD_DOUT
|
163 SPIFI_CMD_DATALEN(len
) |
164 SPIFI_CMD_OPCODE(opcode
) |
165 SPIFI_CMD_FIELDFORM_ALL_SERIAL
|
166 SPIFI_CMD_FRAMEFORM_OPCODE_ONLY
;
167 writel(cmd
, spifi
->io_base
+ SPIFI_CMD
);
170 writeb(*buf
++, spifi
->io_base
+ SPIFI_DATA
);
172 return nxp_spifi_wait_for_cmd(spifi
);
175 static int nxp_spifi_read(struct spi_nor
*nor
, loff_t from
, size_t len
,
176 size_t *retlen
, u_char
*buf
)
178 struct nxp_spifi
*spifi
= nor
->priv
;
181 ret
= nxp_spifi_set_memory_mode_on(spifi
);
185 memcpy_fromio(buf
, spifi
->flash_base
+ from
, len
);
191 static void nxp_spifi_write(struct spi_nor
*nor
, loff_t to
, size_t len
,
192 size_t *retlen
, const u_char
*buf
)
194 struct nxp_spifi
*spifi
= nor
->priv
;
198 ret
= nxp_spifi_set_memory_mode_off(spifi
);
202 writel(to
, spifi
->io_base
+ SPIFI_ADDR
);
205 cmd
= SPIFI_CMD_DOUT
|
206 SPIFI_CMD_DATALEN(len
) |
207 SPIFI_CMD_FIELDFORM_ALL_SERIAL
|
208 SPIFI_CMD_OPCODE(nor
->program_opcode
) |
209 SPIFI_CMD_FRAMEFORM(spifi
->nor
.addr_width
+ 1);
210 writel(cmd
, spifi
->io_base
+ SPIFI_CMD
);
213 writeb(*buf
++, spifi
->io_base
+ SPIFI_DATA
);
215 nxp_spifi_wait_for_cmd(spifi
);
218 static int nxp_spifi_erase(struct spi_nor
*nor
, loff_t offs
)
220 struct nxp_spifi
*spifi
= nor
->priv
;
224 ret
= nxp_spifi_set_memory_mode_off(spifi
);
228 writel(offs
, spifi
->io_base
+ SPIFI_ADDR
);
230 cmd
= SPIFI_CMD_FIELDFORM_ALL_SERIAL
|
231 SPIFI_CMD_OPCODE(nor
->erase_opcode
) |
232 SPIFI_CMD_FRAMEFORM(spifi
->nor
.addr_width
+ 1);
233 writel(cmd
, spifi
->io_base
+ SPIFI_CMD
);
235 return nxp_spifi_wait_for_cmd(spifi
);
238 static int nxp_spifi_setup_memory_cmd(struct nxp_spifi
*spifi
)
240 switch (spifi
->nor
.flash_read
) {
243 spifi
->mcmd
= SPIFI_CMD_FIELDFORM_ALL_SERIAL
;
247 spifi
->mcmd
= SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA
;
250 dev_err(spifi
->dev
, "unsupported SPI read mode\n");
254 /* Memory mode supports address length between 1 and 4 */
255 if (spifi
->nor
.addr_width
< 1 || spifi
->nor
.addr_width
> 4)
258 spifi
->mcmd
|= SPIFI_CMD_OPCODE(spifi
->nor
.read_opcode
) |
259 SPIFI_CMD_INTLEN(spifi
->nor
.read_dummy
/ 8) |
260 SPIFI_CMD_FRAMEFORM(spifi
->nor
.addr_width
+ 1);
265 static void nxp_spifi_dummy_id_read(struct spi_nor
*nor
)
267 u8 id
[SPI_NOR_MAX_ID_LEN
];
268 nor
->read_reg(nor
, SPINOR_OP_RDID
, id
, SPI_NOR_MAX_ID_LEN
);
271 static int nxp_spifi_setup_flash(struct nxp_spifi
*spifi
,
272 struct device_node
*np
)
274 enum read_mode flash_read
;
279 if (!of_property_read_u32(np
, "spi-rx-bus-width", &property
)) {
290 dev_err(spifi
->dev
, "unsupported rx-bus-width\n");
295 if (of_find_property(np
, "spi-cpha", NULL
))
298 if (of_find_property(np
, "spi-cpol", NULL
))
301 /* Setup control register defaults */
302 ctrl
= SPIFI_CTRL_TIMEOUT(1000) |
303 SPIFI_CTRL_CSHIGH(15) |
306 if (mode
& SPI_RX_DUAL
) {
307 ctrl
|= SPIFI_CTRL_DUAL
;
308 flash_read
= SPI_NOR_DUAL
;
309 } else if (mode
& SPI_RX_QUAD
) {
310 ctrl
&= ~SPIFI_CTRL_DUAL
;
311 flash_read
= SPI_NOR_QUAD
;
313 ctrl
|= SPIFI_CTRL_DUAL
;
314 flash_read
= SPI_NOR_NORMAL
;
317 switch (mode
& (SPI_CPHA
| SPI_CPOL
)) {
319 ctrl
&= ~SPIFI_CTRL_MODE3
;
322 ctrl
|= SPIFI_CTRL_MODE3
;
325 dev_err(spifi
->dev
, "only mode 0 and 3 supported\n");
329 writel(ctrl
, spifi
->io_base
+ SPIFI_CTRL
);
331 spifi
->nor
.dev
= spifi
->dev
;
332 spi_nor_set_flash_node(&spifi
->nor
, np
);
333 spifi
->nor
.priv
= spifi
;
334 spifi
->nor
.read
= nxp_spifi_read
;
335 spifi
->nor
.write
= nxp_spifi_write
;
336 spifi
->nor
.erase
= nxp_spifi_erase
;
337 spifi
->nor
.read_reg
= nxp_spifi_read_reg
;
338 spifi
->nor
.write_reg
= nxp_spifi_write_reg
;
341 * The first read on a hard reset isn't reliable so do a
342 * dummy read of the id before calling spi_nor_scan().
343 * The reason for this problem is unknown.
345 * The official NXP spifilib uses more or less the same
346 * workaround that is applied here by reading the device
349 nxp_spifi_dummy_id_read(&spifi
->nor
);
351 ret
= spi_nor_scan(&spifi
->nor
, NULL
, flash_read
);
353 dev_err(spifi
->dev
, "device scan failed\n");
357 ret
= nxp_spifi_setup_memory_cmd(spifi
);
359 dev_err(spifi
->dev
, "memory command setup failed\n");
363 ret
= mtd_device_register(&spifi
->nor
.mtd
, NULL
, 0);
365 dev_err(spifi
->dev
, "mtd device parse failed\n");
372 static int nxp_spifi_probe(struct platform_device
*pdev
)
374 struct device_node
*flash_np
;
375 struct nxp_spifi
*spifi
;
376 struct resource
*res
;
379 spifi
= devm_kzalloc(&pdev
->dev
, sizeof(*spifi
), GFP_KERNEL
);
383 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "spifi");
384 spifi
->io_base
= devm_ioremap_resource(&pdev
->dev
, res
);
385 if (IS_ERR(spifi
->io_base
))
386 return PTR_ERR(spifi
->io_base
);
388 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "flash");
389 spifi
->flash_base
= devm_ioremap_resource(&pdev
->dev
, res
);
390 if (IS_ERR(spifi
->flash_base
))
391 return PTR_ERR(spifi
->flash_base
);
393 spifi
->clk_spifi
= devm_clk_get(&pdev
->dev
, "spifi");
394 if (IS_ERR(spifi
->clk_spifi
)) {
395 dev_err(&pdev
->dev
, "spifi clock not found\n");
396 return PTR_ERR(spifi
->clk_spifi
);
399 spifi
->clk_reg
= devm_clk_get(&pdev
->dev
, "reg");
400 if (IS_ERR(spifi
->clk_reg
)) {
401 dev_err(&pdev
->dev
, "reg clock not found\n");
402 return PTR_ERR(spifi
->clk_reg
);
405 ret
= clk_prepare_enable(spifi
->clk_reg
);
407 dev_err(&pdev
->dev
, "unable to enable reg clock\n");
411 ret
= clk_prepare_enable(spifi
->clk_spifi
);
413 dev_err(&pdev
->dev
, "unable to enable spifi clock\n");
417 spifi
->dev
= &pdev
->dev
;
418 platform_set_drvdata(pdev
, spifi
);
420 /* Initialize and reset device */
421 nxp_spifi_reset(spifi
);
422 writel(0, spifi
->io_base
+ SPIFI_IDATA
);
423 writel(0, spifi
->io_base
+ SPIFI_MCMD
);
424 nxp_spifi_reset(spifi
);
426 flash_np
= of_get_next_available_child(pdev
->dev
.of_node
, NULL
);
428 dev_err(&pdev
->dev
, "no SPI flash device to configure\n");
433 ret
= nxp_spifi_setup_flash(spifi
, flash_np
);
435 dev_err(&pdev
->dev
, "unable to setup flash chip\n");
442 clk_disable_unprepare(spifi
->clk_spifi
);
444 clk_disable_unprepare(spifi
->clk_reg
);
448 static int nxp_spifi_remove(struct platform_device
*pdev
)
450 struct nxp_spifi
*spifi
= platform_get_drvdata(pdev
);
452 mtd_device_unregister(&spifi
->nor
.mtd
);
453 clk_disable_unprepare(spifi
->clk_spifi
);
454 clk_disable_unprepare(spifi
->clk_reg
);
459 static const struct of_device_id nxp_spifi_match
[] = {
460 {.compatible
= "nxp,lpc1773-spifi"},
463 MODULE_DEVICE_TABLE(of
, nxp_spifi_match
);
465 static struct platform_driver nxp_spifi_driver
= {
466 .probe
= nxp_spifi_probe
,
467 .remove
= nxp_spifi_remove
,
470 .of_match_table
= nxp_spifi_match
,
473 module_platform_driver(nxp_spifi_driver
);
475 MODULE_DESCRIPTION("NXP SPI Flash Interface driver");
476 MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
477 MODULE_LICENSE("GPL v2");