1/* 2 * SPI-NOR driver for NXP SPI Flash Interface (SPIFI) 3 * 4 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> 5 * 6 * Based on Freescale QuadSPI driver: 7 * Copyright (C) 2013 Freescale Semiconductor, Inc. 8 * 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. 12 * 13 */ 14 15#include <linux/clk.h> 16#include <linux/err.h> 17#include <linux/io.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> 23#include <linux/of.h> 24#include <linux/of_device.h> 25#include <linux/platform_device.h> 26#include <linux/spi/spi.h> 27 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) 54 55#define SPI_NOR_MAX_ID_LEN 6 56 57struct nxp_spifi { 58 struct device *dev; 59 struct clk *clk_spifi; 60 struct clk *clk_reg; 61 void __iomem *io_base; 62 void __iomem *flash_base; 63 struct spi_nor nor; 64 bool memory_mode; 65 u32 mcmd; 66}; 67 68static int nxp_spifi_wait_for_cmd(struct nxp_spifi *spifi) 69{ 70 u8 stat; 71 int ret; 72 73 ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat, 74 !(stat & SPIFI_STAT_CMD), 10, 30); 75 if (ret) 76 dev_warn(spifi->dev, "command timed out\n"); 77 78 return ret; 79} 80 81static int nxp_spifi_reset(struct nxp_spifi *spifi) 82{ 83 u8 stat; 84 int ret; 85 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); 89 if (ret) 90 dev_warn(spifi->dev, "state reset timed out\n"); 91 92 return ret; 93} 94 95static int nxp_spifi_set_memory_mode_off(struct nxp_spifi *spifi) 96{ 97 int ret; 98 99 if (!spifi->memory_mode) 100 return 0; 101 102 ret = nxp_spifi_reset(spifi); 103 if (ret) 104 dev_err(spifi->dev, "unable to enter command mode\n"); 105 else 106 spifi->memory_mode = false; 107 108 return ret; 109} 110 111static int nxp_spifi_set_memory_mode_on(struct nxp_spifi *spifi) 112{ 113 u8 stat; 114 int ret; 115 116 if (spifi->memory_mode) 117 return 0; 118 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); 122 if (ret) 123 dev_err(spifi->dev, "unable to enter memory mode\n"); 124 else 125 spifi->memory_mode = true; 126 127 return ret; 128} 129 130static int nxp_spifi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) 131{ 132 struct nxp_spifi *spifi = nor->priv; 133 u32 cmd; 134 int ret; 135 136 ret = nxp_spifi_set_memory_mode_off(spifi); 137 if (ret) 138 return ret; 139 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); 145 146 while (len--) 147 *buf++ = readb(spifi->io_base + SPIFI_DATA); 148 149 return nxp_spifi_wait_for_cmd(spifi); 150} 151 152static int nxp_spifi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) 153{ 154 struct nxp_spifi *spifi = nor->priv; 155 u32 cmd; 156 int ret; 157 158 ret = nxp_spifi_set_memory_mode_off(spifi); 159 if (ret) 160 return ret; 161 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); 168 169 while (len--) 170 writeb(*buf++, spifi->io_base + SPIFI_DATA); 171 172 return nxp_spifi_wait_for_cmd(spifi); 173} 174 175static int nxp_spifi_read(struct spi_nor *nor, loff_t from, size_t len, 176 size_t *retlen, u_char *buf) 177{ 178 struct nxp_spifi *spifi = nor->priv; 179 int ret; 180 181 ret = nxp_spifi_set_memory_mode_on(spifi); 182 if (ret) 183 return ret; 184 185 memcpy_fromio(buf, spifi->flash_base + from, len); 186 *retlen += len; 187 188 return 0; 189} 190 191static void nxp_spifi_write(struct spi_nor *nor, loff_t to, size_t len, 192 size_t *retlen, const u_char *buf) 193{ 194 struct nxp_spifi *spifi = nor->priv; 195 u32 cmd; 196 int ret; 197 198 ret = nxp_spifi_set_memory_mode_off(spifi); 199 if (ret) 200 return; 201 202 writel(to, spifi->io_base + SPIFI_ADDR); 203 *retlen += len; 204 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); 211 212 while (len--) 213 writeb(*buf++, spifi->io_base + SPIFI_DATA); 214 215 nxp_spifi_wait_for_cmd(spifi); 216} 217 218static int nxp_spifi_erase(struct spi_nor *nor, loff_t offs) 219{ 220 struct nxp_spifi *spifi = nor->priv; 221 u32 cmd; 222 int ret; 223 224 ret = nxp_spifi_set_memory_mode_off(spifi); 225 if (ret) 226 return ret; 227 228 writel(offs, spifi->io_base + SPIFI_ADDR); 229 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); 234 235 return nxp_spifi_wait_for_cmd(spifi); 236} 237 238static int nxp_spifi_setup_memory_cmd(struct nxp_spifi *spifi) 239{ 240 switch (spifi->nor.flash_read) { 241 case SPI_NOR_NORMAL: 242 case SPI_NOR_FAST: 243 spifi->mcmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL; 244 break; 245 case SPI_NOR_DUAL: 246 case SPI_NOR_QUAD: 247 spifi->mcmd = SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA; 248 break; 249 default: 250 dev_err(spifi->dev, "unsupported SPI read mode\n"); 251 return -EINVAL; 252 } 253 254 /* Memory mode supports address length between 1 and 4 */ 255 if (spifi->nor.addr_width < 1 || spifi->nor.addr_width > 4) 256 return -EINVAL; 257 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); 261 262 return 0; 263} 264 265static void nxp_spifi_dummy_id_read(struct spi_nor *nor) 266{ 267 u8 id[SPI_NOR_MAX_ID_LEN]; 268 nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); 269} 270 271static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, 272 struct device_node *np) 273{ 274 struct mtd_part_parser_data ppdata; 275 enum read_mode flash_read; 276 u32 ctrl, property; 277 u16 mode = 0; 278 int ret; 279 280 if (!of_property_read_u32(np, "spi-rx-bus-width", &property)) { 281 switch (property) { 282 case 1: 283 break; 284 case 2: 285 mode |= SPI_RX_DUAL; 286 break; 287 case 4: 288 mode |= SPI_RX_QUAD; 289 break; 290 default: 291 dev_err(spifi->dev, "unsupported rx-bus-width\n"); 292 return -EINVAL; 293 } 294 } 295 296 if (of_find_property(np, "spi-cpha", NULL)) 297 mode |= SPI_CPHA; 298 299 if (of_find_property(np, "spi-cpol", NULL)) 300 mode |= SPI_CPOL; 301 302 /* Setup control register defaults */ 303 ctrl = SPIFI_CTRL_TIMEOUT(1000) | 304 SPIFI_CTRL_CSHIGH(15) | 305 SPIFI_CTRL_FBCLK; 306 307 if (mode & SPI_RX_DUAL) { 308 ctrl |= SPIFI_CTRL_DUAL; 309 flash_read = SPI_NOR_DUAL; 310 } else if (mode & SPI_RX_QUAD) { 311 ctrl &= ~SPIFI_CTRL_DUAL; 312 flash_read = SPI_NOR_QUAD; 313 } else { 314 ctrl |= SPIFI_CTRL_DUAL; 315 flash_read = SPI_NOR_NORMAL; 316 } 317 318 switch (mode & (SPI_CPHA | SPI_CPOL)) { 319 case SPI_MODE_0: 320 ctrl &= ~SPIFI_CTRL_MODE3; 321 break; 322 case SPI_MODE_3: 323 ctrl |= SPIFI_CTRL_MODE3; 324 break; 325 default: 326 dev_err(spifi->dev, "only mode 0 and 3 supported\n"); 327 return -EINVAL; 328 } 329 330 writel(ctrl, spifi->io_base + SPIFI_CTRL); 331 332 spifi->nor.dev = spifi->dev; 333 spifi->nor.flash_node = np; 334 spifi->nor.priv = spifi; 335 spifi->nor.read = nxp_spifi_read; 336 spifi->nor.write = nxp_spifi_write; 337 spifi->nor.erase = nxp_spifi_erase; 338 spifi->nor.read_reg = nxp_spifi_read_reg; 339 spifi->nor.write_reg = nxp_spifi_write_reg; 340 341 /* 342 * The first read on a hard reset isn't reliable so do a 343 * dummy read of the id before calling spi_nor_scan(). 344 * The reason for this problem is unknown. 345 * 346 * The official NXP spifilib uses more or less the same 347 * workaround that is applied here by reading the device 348 * id multiple times. 349 */ 350 nxp_spifi_dummy_id_read(&spifi->nor); 351 352 ret = spi_nor_scan(&spifi->nor, NULL, flash_read); 353 if (ret) { 354 dev_err(spifi->dev, "device scan failed\n"); 355 return ret; 356 } 357 358 ret = nxp_spifi_setup_memory_cmd(spifi); 359 if (ret) { 360 dev_err(spifi->dev, "memory command setup failed\n"); 361 return ret; 362 } 363 364 ppdata.of_node = np; 365 ret = mtd_device_parse_register(&spifi->nor.mtd, NULL, &ppdata, NULL, 0); 366 if (ret) { 367 dev_err(spifi->dev, "mtd device parse failed\n"); 368 return ret; 369 } 370 371 return 0; 372} 373 374static int nxp_spifi_probe(struct platform_device *pdev) 375{ 376 struct device_node *flash_np; 377 struct nxp_spifi *spifi; 378 struct resource *res; 379 int ret; 380 381 spifi = devm_kzalloc(&pdev->dev, sizeof(*spifi), GFP_KERNEL); 382 if (!spifi) 383 return -ENOMEM; 384 385 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spifi"); 386 spifi->io_base = devm_ioremap_resource(&pdev->dev, res); 387 if (IS_ERR(spifi->io_base)) 388 return PTR_ERR(spifi->io_base); 389 390 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash"); 391 spifi->flash_base = devm_ioremap_resource(&pdev->dev, res); 392 if (IS_ERR(spifi->flash_base)) 393 return PTR_ERR(spifi->flash_base); 394 395 spifi->clk_spifi = devm_clk_get(&pdev->dev, "spifi"); 396 if (IS_ERR(spifi->clk_spifi)) { 397 dev_err(&pdev->dev, "spifi clock not found\n"); 398 return PTR_ERR(spifi->clk_spifi); 399 } 400 401 spifi->clk_reg = devm_clk_get(&pdev->dev, "reg"); 402 if (IS_ERR(spifi->clk_reg)) { 403 dev_err(&pdev->dev, "reg clock not found\n"); 404 return PTR_ERR(spifi->clk_reg); 405 } 406 407 ret = clk_prepare_enable(spifi->clk_reg); 408 if (ret) { 409 dev_err(&pdev->dev, "unable to enable reg clock\n"); 410 return ret; 411 } 412 413 ret = clk_prepare_enable(spifi->clk_spifi); 414 if (ret) { 415 dev_err(&pdev->dev, "unable to enable spifi clock\n"); 416 goto dis_clk_reg; 417 } 418 419 spifi->dev = &pdev->dev; 420 platform_set_drvdata(pdev, spifi); 421 422 /* Initialize and reset device */ 423 nxp_spifi_reset(spifi); 424 writel(0, spifi->io_base + SPIFI_IDATA); 425 writel(0, spifi->io_base + SPIFI_MCMD); 426 nxp_spifi_reset(spifi); 427 428 flash_np = of_get_next_available_child(pdev->dev.of_node, NULL); 429 if (!flash_np) { 430 dev_err(&pdev->dev, "no SPI flash device to configure\n"); 431 ret = -ENODEV; 432 goto dis_clks; 433 } 434 435 ret = nxp_spifi_setup_flash(spifi, flash_np); 436 if (ret) { 437 dev_err(&pdev->dev, "unable to setup flash chip\n"); 438 goto dis_clks; 439 } 440 441 return 0; 442 443dis_clks: 444 clk_disable_unprepare(spifi->clk_spifi); 445dis_clk_reg: 446 clk_disable_unprepare(spifi->clk_reg); 447 return ret; 448} 449 450static int nxp_spifi_remove(struct platform_device *pdev) 451{ 452 struct nxp_spifi *spifi = platform_get_drvdata(pdev); 453 454 mtd_device_unregister(&spifi->nor.mtd); 455 clk_disable_unprepare(spifi->clk_spifi); 456 clk_disable_unprepare(spifi->clk_reg); 457 458 return 0; 459} 460 461static const struct of_device_id nxp_spifi_match[] = { 462 {.compatible = "nxp,lpc1773-spifi"}, 463 { /* sentinel */ } 464}; 465MODULE_DEVICE_TABLE(of, nxp_spifi_match); 466 467static struct platform_driver nxp_spifi_driver = { 468 .probe = nxp_spifi_probe, 469 .remove = nxp_spifi_remove, 470 .driver = { 471 .name = "nxp-spifi", 472 .of_match_table = nxp_spifi_match, 473 }, 474}; 475module_platform_driver(nxp_spifi_driver); 476 477MODULE_DESCRIPTION("NXP SPI Flash Interface driver"); 478MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>"); 479MODULE_LICENSE("GPL v2"); 480