linux/drivers/mtd/spi-nor/controllers/nxp-spifi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * SPI NOR driver for NXP SPI Flash Interface (SPIFI)
   4 *
   5 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
   6 *
   7 * Based on Freescale QuadSPI driver:
   8 * Copyright (C) 2013 Freescale Semiconductor, Inc.
   9 */
  10
  11#include <linux/clk.h>
  12#include <linux/err.h>
  13#include <linux/io.h>
  14#include <linux/iopoll.h>
  15#include <linux/module.h>
  16#include <linux/mtd/mtd.h>
  17#include <linux/mtd/partitions.h>
  18#include <linux/mtd/spi-nor.h>
  19#include <linux/of.h>
  20#include <linux/of_device.h>
  21#include <linux/platform_device.h>
  22#include <linux/spi/spi.h>
  23
  24/* NXP SPIFI registers, bits and macros */
  25#define SPIFI_CTRL                              0x000
  26#define  SPIFI_CTRL_TIMEOUT(timeout)            (timeout)
  27#define  SPIFI_CTRL_CSHIGH(cshigh)              ((cshigh) << 16)
  28#define  SPIFI_CTRL_MODE3                       BIT(23)
  29#define  SPIFI_CTRL_DUAL                        BIT(28)
  30#define  SPIFI_CTRL_FBCLK                       BIT(30)
  31#define SPIFI_CMD                               0x004
  32#define  SPIFI_CMD_DATALEN(dlen)                ((dlen) & 0x3fff)
  33#define  SPIFI_CMD_DOUT                         BIT(15)
  34#define  SPIFI_CMD_INTLEN(ilen)                 ((ilen) << 16)
  35#define  SPIFI_CMD_FIELDFORM(field)             ((field) << 19)
  36#define  SPIFI_CMD_FIELDFORM_ALL_SERIAL         SPIFI_CMD_FIELDFORM(0x0)
  37#define  SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA     SPIFI_CMD_FIELDFORM(0x1)
  38#define  SPIFI_CMD_FRAMEFORM(frame)             ((frame) << 21)
  39#define  SPIFI_CMD_FRAMEFORM_OPCODE_ONLY        SPIFI_CMD_FRAMEFORM(0x1)
  40#define  SPIFI_CMD_OPCODE(op)                   ((op) << 24)
  41#define SPIFI_ADDR                              0x008
  42#define SPIFI_IDATA                             0x00c
  43#define SPIFI_CLIMIT                            0x010
  44#define SPIFI_DATA                              0x014
  45#define SPIFI_MCMD                              0x018
  46#define SPIFI_STAT                              0x01c
  47#define  SPIFI_STAT_MCINIT                      BIT(0)
  48#define  SPIFI_STAT_CMD                         BIT(1)
  49#define  SPIFI_STAT_RESET                       BIT(4)
  50
  51#define SPI_NOR_MAX_ID_LEN      6
  52
  53struct nxp_spifi {
  54        struct device *dev;
  55        struct clk *clk_spifi;
  56        struct clk *clk_reg;
  57        void __iomem *io_base;
  58        void __iomem *flash_base;
  59        struct spi_nor nor;
  60        bool memory_mode;
  61        u32 mcmd;
  62};
  63
  64static int nxp_spifi_wait_for_cmd(struct nxp_spifi *spifi)
  65{
  66        u8 stat;
  67        int ret;
  68
  69        ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
  70                                 !(stat & SPIFI_STAT_CMD), 10, 30);
  71        if (ret)
  72                dev_warn(spifi->dev, "command timed out\n");
  73
  74        return ret;
  75}
  76
  77static int nxp_spifi_reset(struct nxp_spifi *spifi)
  78{
  79        u8 stat;
  80        int ret;
  81
  82        writel(SPIFI_STAT_RESET, spifi->io_base + SPIFI_STAT);
  83        ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
  84                                 !(stat & SPIFI_STAT_RESET), 10, 30);
  85        if (ret)
  86                dev_warn(spifi->dev, "state reset timed out\n");
  87
  88        return ret;
  89}
  90
  91static int nxp_spifi_set_memory_mode_off(struct nxp_spifi *spifi)
  92{
  93        int ret;
  94
  95        if (!spifi->memory_mode)
  96                return 0;
  97
  98        ret = nxp_spifi_reset(spifi);
  99        if (ret)
 100                dev_err(spifi->dev, "unable to enter command mode\n");
 101        else
 102                spifi->memory_mode = false;
 103
 104        return ret;
 105}
 106
 107static int nxp_spifi_set_memory_mode_on(struct nxp_spifi *spifi)
 108{
 109        u8 stat;
 110        int ret;
 111
 112        if (spifi->memory_mode)
 113                return 0;
 114
 115        writel(spifi->mcmd, spifi->io_base + SPIFI_MCMD);
 116        ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
 117                                 stat & SPIFI_STAT_MCINIT, 10, 30);
 118        if (ret)
 119                dev_err(spifi->dev, "unable to enter memory mode\n");
 120        else
 121                spifi->memory_mode = true;
 122
 123        return ret;
 124}
 125
 126static int nxp_spifi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
 127                              size_t len)
 128{
 129        struct nxp_spifi *spifi = nor->priv;
 130        u32 cmd;
 131        int ret;
 132
 133        ret = nxp_spifi_set_memory_mode_off(spifi);
 134        if (ret)
 135                return ret;
 136
 137        cmd = SPIFI_CMD_DATALEN(len) |
 138              SPIFI_CMD_OPCODE(opcode) |
 139              SPIFI_CMD_FIELDFORM_ALL_SERIAL |
 140              SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
 141        writel(cmd, spifi->io_base + SPIFI_CMD);
 142
 143        while (len--)
 144                *buf++ = readb(spifi->io_base + SPIFI_DATA);
 145
 146        return nxp_spifi_wait_for_cmd(spifi);
 147}
 148
 149static int nxp_spifi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
 150                               size_t len)
 151{
 152        struct nxp_spifi *spifi = nor->priv;
 153        u32 cmd;
 154        int ret;
 155
 156        ret = nxp_spifi_set_memory_mode_off(spifi);
 157        if (ret)
 158                return ret;
 159
 160        cmd = SPIFI_CMD_DOUT |
 161              SPIFI_CMD_DATALEN(len) |
 162              SPIFI_CMD_OPCODE(opcode) |
 163              SPIFI_CMD_FIELDFORM_ALL_SERIAL |
 164              SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
 165        writel(cmd, spifi->io_base + SPIFI_CMD);
 166
 167        while (len--)
 168                writeb(*buf++, spifi->io_base + SPIFI_DATA);
 169
 170        return nxp_spifi_wait_for_cmd(spifi);
 171}
 172
 173static ssize_t nxp_spifi_read(struct spi_nor *nor, loff_t from, size_t len,
 174                              u_char *buf)
 175{
 176        struct nxp_spifi *spifi = nor->priv;
 177        int ret;
 178
 179        ret = nxp_spifi_set_memory_mode_on(spifi);
 180        if (ret)
 181                return ret;
 182
 183        memcpy_fromio(buf, spifi->flash_base + from, len);
 184
 185        return len;
 186}
 187
 188static ssize_t nxp_spifi_write(struct spi_nor *nor, loff_t to, size_t len,
 189                               const u_char *buf)
 190{
 191        struct nxp_spifi *spifi = nor->priv;
 192        u32 cmd;
 193        int ret;
 194        size_t i;
 195
 196        ret = nxp_spifi_set_memory_mode_off(spifi);
 197        if (ret)
 198                return ret;
 199
 200        writel(to, spifi->io_base + SPIFI_ADDR);
 201
 202        cmd = SPIFI_CMD_DOUT |
 203              SPIFI_CMD_DATALEN(len) |
 204              SPIFI_CMD_FIELDFORM_ALL_SERIAL |
 205              SPIFI_CMD_OPCODE(nor->program_opcode) |
 206              SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
 207        writel(cmd, spifi->io_base + SPIFI_CMD);
 208
 209        for (i = 0; i < len; i++)
 210                writeb(buf[i], spifi->io_base + SPIFI_DATA);
 211
 212        ret = nxp_spifi_wait_for_cmd(spifi);
 213        if (ret)
 214                return ret;
 215
 216        return len;
 217}
 218
 219static int nxp_spifi_erase(struct spi_nor *nor, loff_t offs)
 220{
 221        struct nxp_spifi *spifi = nor->priv;
 222        u32 cmd;
 223        int ret;
 224
 225        ret = nxp_spifi_set_memory_mode_off(spifi);
 226        if (ret)
 227                return ret;
 228
 229        writel(offs, spifi->io_base + SPIFI_ADDR);
 230
 231        cmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL |
 232              SPIFI_CMD_OPCODE(nor->erase_opcode) |
 233              SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
 234        writel(cmd, spifi->io_base + SPIFI_CMD);
 235
 236        return nxp_spifi_wait_for_cmd(spifi);
 237}
 238
 239static int nxp_spifi_setup_memory_cmd(struct nxp_spifi *spifi)
 240{
 241        switch (spifi->nor.read_proto) {
 242        case SNOR_PROTO_1_1_1:
 243                spifi->mcmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL;
 244                break;
 245        case SNOR_PROTO_1_1_2:
 246        case SNOR_PROTO_1_1_4:
 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->controller_ops->read_reg(nor, SPINOR_OP_RDID, id,
 269                                      SPI_NOR_MAX_ID_LEN);
 270}
 271
 272static const struct spi_nor_controller_ops nxp_spifi_controller_ops = {
 273        .read_reg  = nxp_spifi_read_reg,
 274        .write_reg = nxp_spifi_write_reg,
 275        .read  = nxp_spifi_read,
 276        .write = nxp_spifi_write,
 277        .erase = nxp_spifi_erase,
 278};
 279
 280static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
 281                                 struct device_node *np)
 282{
 283        struct spi_nor_hwcaps hwcaps = {
 284                .mask = SNOR_HWCAPS_READ |
 285                        SNOR_HWCAPS_READ_FAST |
 286                        SNOR_HWCAPS_PP,
 287        };
 288        u32 ctrl, property;
 289        u16 mode = 0;
 290        int ret;
 291
 292        if (!of_property_read_u32(np, "spi-rx-bus-width", &property)) {
 293                switch (property) {
 294                case 1:
 295                        break;
 296                case 2:
 297                        mode |= SPI_RX_DUAL;
 298                        break;
 299                case 4:
 300                        mode |= SPI_RX_QUAD;
 301                        break;
 302                default:
 303                        dev_err(spifi->dev, "unsupported rx-bus-width\n");
 304                        return -EINVAL;
 305                }
 306        }
 307
 308        if (of_find_property(np, "spi-cpha", NULL))
 309                mode |= SPI_CPHA;
 310
 311        if (of_find_property(np, "spi-cpol", NULL))
 312                mode |= SPI_CPOL;
 313
 314        /* Setup control register defaults */
 315        ctrl = SPIFI_CTRL_TIMEOUT(1000) |
 316               SPIFI_CTRL_CSHIGH(15) |
 317               SPIFI_CTRL_FBCLK;
 318
 319        if (mode & SPI_RX_DUAL) {
 320                ctrl |= SPIFI_CTRL_DUAL;
 321                hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2;
 322        } else if (mode & SPI_RX_QUAD) {
 323                ctrl &= ~SPIFI_CTRL_DUAL;
 324                hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
 325        } else {
 326                ctrl |= SPIFI_CTRL_DUAL;
 327        }
 328
 329        switch (mode & SPI_MODE_X_MASK) {
 330        case SPI_MODE_0:
 331                ctrl &= ~SPIFI_CTRL_MODE3;
 332                break;
 333        case SPI_MODE_3:
 334                ctrl |= SPIFI_CTRL_MODE3;
 335                break;
 336        default:
 337                dev_err(spifi->dev, "only mode 0 and 3 supported\n");
 338                return -EINVAL;
 339        }
 340
 341        writel(ctrl, spifi->io_base + SPIFI_CTRL);
 342
 343        spifi->nor.dev   = spifi->dev;
 344        spi_nor_set_flash_node(&spifi->nor, np);
 345        spifi->nor.priv  = spifi;
 346        spifi->nor.controller_ops = &nxp_spifi_controller_ops;
 347
 348        /*
 349         * The first read on a hard reset isn't reliable so do a
 350         * dummy read of the id before calling spi_nor_scan().
 351         * The reason for this problem is unknown.
 352         *
 353         * The official NXP spifilib uses more or less the same
 354         * workaround that is applied here by reading the device
 355         * id multiple times.
 356         */
 357        nxp_spifi_dummy_id_read(&spifi->nor);
 358
 359        ret = spi_nor_scan(&spifi->nor, NULL, &hwcaps);
 360        if (ret) {
 361                dev_err(spifi->dev, "device scan failed\n");
 362                return ret;
 363        }
 364
 365        ret = nxp_spifi_setup_memory_cmd(spifi);
 366        if (ret) {
 367                dev_err(spifi->dev, "memory command setup failed\n");
 368                return ret;
 369        }
 370
 371        ret = mtd_device_register(&spifi->nor.mtd, NULL, 0);
 372        if (ret) {
 373                dev_err(spifi->dev, "mtd device parse failed\n");
 374                return ret;
 375        }
 376
 377        return 0;
 378}
 379
 380static int nxp_spifi_probe(struct platform_device *pdev)
 381{
 382        struct device_node *flash_np;
 383        struct nxp_spifi *spifi;
 384        int ret;
 385
 386        spifi = devm_kzalloc(&pdev->dev, sizeof(*spifi), GFP_KERNEL);
 387        if (!spifi)
 388                return -ENOMEM;
 389
 390        spifi->io_base = devm_platform_ioremap_resource_byname(pdev, "spifi");
 391        if (IS_ERR(spifi->io_base))
 392                return PTR_ERR(spifi->io_base);
 393
 394        spifi->flash_base = devm_platform_ioremap_resource_byname(pdev, "flash");
 395        if (IS_ERR(spifi->flash_base))
 396                return PTR_ERR(spifi->flash_base);
 397
 398        spifi->clk_spifi = devm_clk_get(&pdev->dev, "spifi");
 399        if (IS_ERR(spifi->clk_spifi)) {
 400                dev_err(&pdev->dev, "spifi clock not found\n");
 401                return PTR_ERR(spifi->clk_spifi);
 402        }
 403
 404        spifi->clk_reg = devm_clk_get(&pdev->dev, "reg");
 405        if (IS_ERR(spifi->clk_reg)) {
 406                dev_err(&pdev->dev, "reg clock not found\n");
 407                return PTR_ERR(spifi->clk_reg);
 408        }
 409
 410        ret = clk_prepare_enable(spifi->clk_reg);
 411        if (ret) {
 412                dev_err(&pdev->dev, "unable to enable reg clock\n");
 413                return ret;
 414        }
 415
 416        ret = clk_prepare_enable(spifi->clk_spifi);
 417        if (ret) {
 418                dev_err(&pdev->dev, "unable to enable spifi clock\n");
 419                goto dis_clk_reg;
 420        }
 421
 422        spifi->dev = &pdev->dev;
 423        platform_set_drvdata(pdev, spifi);
 424
 425        /* Initialize and reset device */
 426        nxp_spifi_reset(spifi);
 427        writel(0, spifi->io_base + SPIFI_IDATA);
 428        writel(0, spifi->io_base + SPIFI_MCMD);
 429        nxp_spifi_reset(spifi);
 430
 431        flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
 432        if (!flash_np) {
 433                dev_err(&pdev->dev, "no SPI flash device to configure\n");
 434                ret = -ENODEV;
 435                goto dis_clks;
 436        }
 437
 438        ret = nxp_spifi_setup_flash(spifi, flash_np);
 439        of_node_put(flash_np);
 440        if (ret) {
 441                dev_err(&pdev->dev, "unable to setup flash chip\n");
 442                goto dis_clks;
 443        }
 444
 445        return 0;
 446
 447dis_clks:
 448        clk_disable_unprepare(spifi->clk_spifi);
 449dis_clk_reg:
 450        clk_disable_unprepare(spifi->clk_reg);
 451        return ret;
 452}
 453
 454static int nxp_spifi_remove(struct platform_device *pdev)
 455{
 456        struct nxp_spifi *spifi = platform_get_drvdata(pdev);
 457
 458        mtd_device_unregister(&spifi->nor.mtd);
 459        clk_disable_unprepare(spifi->clk_spifi);
 460        clk_disable_unprepare(spifi->clk_reg);
 461
 462        return 0;
 463}
 464
 465static const struct of_device_id nxp_spifi_match[] = {
 466        {.compatible = "nxp,lpc1773-spifi"},
 467        { /* sentinel */ }
 468};
 469MODULE_DEVICE_TABLE(of, nxp_spifi_match);
 470
 471static struct platform_driver nxp_spifi_driver = {
 472        .probe  = nxp_spifi_probe,
 473        .remove = nxp_spifi_remove,
 474        .driver = {
 475                .name = "nxp-spifi",
 476                .of_match_table = nxp_spifi_match,
 477        },
 478};
 479module_platform_driver(nxp_spifi_driver);
 480
 481MODULE_DESCRIPTION("NXP SPI Flash Interface driver");
 482MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
 483MODULE_LICENSE("GPL v2");
 484