linux/drivers/mtd/nand/raw/xway_nand.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *
   4 *  Copyright © 2012 John Crispin <john@phrozen.org>
   5 *  Copyright © 2016 Hauke Mehrtens <hauke@hauke-m.de>
   6 */
   7
   8#include <linux/mtd/rawnand.h>
   9#include <linux/of_gpio.h>
  10#include <linux/of_platform.h>
  11
  12#include <lantiq_soc.h>
  13
  14/* nand registers */
  15#define EBU_ADDSEL1             0x24
  16#define EBU_NAND_CON            0xB0
  17#define EBU_NAND_WAIT           0xB4
  18#define  NAND_WAIT_RD           BIT(0) /* NAND flash status output */
  19#define  NAND_WAIT_WR_C         BIT(3) /* NAND Write/Read complete */
  20#define EBU_NAND_ECC0           0xB8
  21#define EBU_NAND_ECC_AC         0xBC
  22
  23/*
  24 * nand commands
  25 * The pins of the NAND chip are selected based on the address bits of the
  26 * "register" read and write. There are no special registers, but an
  27 * address range and the lower address bits are used to activate the
  28 * correct line. For example when the bit (1 << 2) is set in the address
  29 * the ALE pin will be activated.
  30 */
  31#define NAND_CMD_ALE            BIT(2) /* address latch enable */
  32#define NAND_CMD_CLE            BIT(3) /* command latch enable */
  33#define NAND_CMD_CS             BIT(4) /* chip select */
  34#define NAND_CMD_SE             BIT(5) /* spare area access latch */
  35#define NAND_CMD_WP             BIT(6) /* write protect */
  36#define NAND_WRITE_CMD          (NAND_CMD_CS | NAND_CMD_CLE)
  37#define NAND_WRITE_ADDR         (NAND_CMD_CS | NAND_CMD_ALE)
  38#define NAND_WRITE_DATA         (NAND_CMD_CS)
  39#define NAND_READ_DATA          (NAND_CMD_CS)
  40
  41/* we need to tel the ebu which addr we mapped the nand to */
  42#define ADDSEL1_MASK(x)         (x << 4)
  43#define ADDSEL1_REGEN           1
  44
  45/* we need to tell the EBU that we have nand attached and set it up properly */
  46#define BUSCON1_SETUP           (1 << 22)
  47#define BUSCON1_BCGEN_RES       (0x3 << 12)
  48#define BUSCON1_WAITWRC2        (2 << 8)
  49#define BUSCON1_WAITRDC2        (2 << 6)
  50#define BUSCON1_HOLDC1          (1 << 4)
  51#define BUSCON1_RECOVC1         (1 << 2)
  52#define BUSCON1_CMULT4          1
  53
  54#define NAND_CON_CE             (1 << 20)
  55#define NAND_CON_OUT_CS1        (1 << 10)
  56#define NAND_CON_IN_CS1         (1 << 8)
  57#define NAND_CON_PRE_P          (1 << 7)
  58#define NAND_CON_WP_P           (1 << 6)
  59#define NAND_CON_SE_P           (1 << 5)
  60#define NAND_CON_CS_P           (1 << 4)
  61#define NAND_CON_CSMUX          (1 << 1)
  62#define NAND_CON_NANDM          1
  63
  64struct xway_nand_data {
  65        struct nand_controller  controller;
  66        struct nand_chip        chip;
  67        unsigned long           csflags;
  68        void __iomem            *nandaddr;
  69};
  70
  71static u8 xway_readb(struct mtd_info *mtd, int op)
  72{
  73        struct nand_chip *chip = mtd_to_nand(mtd);
  74        struct xway_nand_data *data = nand_get_controller_data(chip);
  75
  76        return readb(data->nandaddr + op);
  77}
  78
  79static void xway_writeb(struct mtd_info *mtd, int op, u8 value)
  80{
  81        struct nand_chip *chip = mtd_to_nand(mtd);
  82        struct xway_nand_data *data = nand_get_controller_data(chip);
  83
  84        writeb(value, data->nandaddr + op);
  85}
  86
  87static void xway_select_chip(struct nand_chip *chip, int select)
  88{
  89        struct xway_nand_data *data = nand_get_controller_data(chip);
  90
  91        switch (select) {
  92        case -1:
  93                ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
  94                ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
  95                spin_unlock_irqrestore(&ebu_lock, data->csflags);
  96                break;
  97        case 0:
  98                spin_lock_irqsave(&ebu_lock, data->csflags);
  99                ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
 100                ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
 101                break;
 102        default:
 103                BUG();
 104        }
 105}
 106
 107static void xway_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl)
 108{
 109        struct mtd_info *mtd = nand_to_mtd(chip);
 110
 111        if (cmd == NAND_CMD_NONE)
 112                return;
 113
 114        if (ctrl & NAND_CLE)
 115                xway_writeb(mtd, NAND_WRITE_CMD, cmd);
 116        else if (ctrl & NAND_ALE)
 117                xway_writeb(mtd, NAND_WRITE_ADDR, cmd);
 118
 119        while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
 120                ;
 121}
 122
 123static int xway_dev_ready(struct nand_chip *chip)
 124{
 125        return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD;
 126}
 127
 128static unsigned char xway_read_byte(struct nand_chip *chip)
 129{
 130        return xway_readb(nand_to_mtd(chip), NAND_READ_DATA);
 131}
 132
 133static void xway_read_buf(struct nand_chip *chip, u_char *buf, int len)
 134{
 135        int i;
 136
 137        for (i = 0; i < len; i++)
 138                buf[i] = xway_readb(nand_to_mtd(chip), NAND_WRITE_DATA);
 139}
 140
 141static void xway_write_buf(struct nand_chip *chip, const u_char *buf, int len)
 142{
 143        int i;
 144
 145        for (i = 0; i < len; i++)
 146                xway_writeb(nand_to_mtd(chip), NAND_WRITE_DATA, buf[i]);
 147}
 148
 149static int xway_attach_chip(struct nand_chip *chip)
 150{
 151        chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
 152
 153        if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 154                chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 155
 156        return 0;
 157}
 158
 159static const struct nand_controller_ops xway_nand_ops = {
 160        .attach_chip = xway_attach_chip,
 161};
 162
 163/*
 164 * Probe for the NAND device.
 165 */
 166static int xway_nand_probe(struct platform_device *pdev)
 167{
 168        struct xway_nand_data *data;
 169        struct mtd_info *mtd;
 170        struct resource *res;
 171        int err;
 172        u32 cs;
 173        u32 cs_flag = 0;
 174
 175        /* Allocate memory for the device structure (and zero it) */
 176        data = devm_kzalloc(&pdev->dev, sizeof(struct xway_nand_data),
 177                            GFP_KERNEL);
 178        if (!data)
 179                return -ENOMEM;
 180
 181        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 182        data->nandaddr = devm_ioremap_resource(&pdev->dev, res);
 183        if (IS_ERR(data->nandaddr))
 184                return PTR_ERR(data->nandaddr);
 185
 186        nand_set_flash_node(&data->chip, pdev->dev.of_node);
 187        mtd = nand_to_mtd(&data->chip);
 188        mtd->dev.parent = &pdev->dev;
 189
 190        data->chip.legacy.cmd_ctrl = xway_cmd_ctrl;
 191        data->chip.legacy.dev_ready = xway_dev_ready;
 192        data->chip.legacy.select_chip = xway_select_chip;
 193        data->chip.legacy.write_buf = xway_write_buf;
 194        data->chip.legacy.read_buf = xway_read_buf;
 195        data->chip.legacy.read_byte = xway_read_byte;
 196        data->chip.legacy.chip_delay = 30;
 197
 198        nand_controller_init(&data->controller);
 199        data->controller.ops = &xway_nand_ops;
 200        data->chip.controller = &data->controller;
 201
 202        platform_set_drvdata(pdev, data);
 203        nand_set_controller_data(&data->chip, data);
 204
 205        /* load our CS from the DT. Either we find a valid 1 or default to 0 */
 206        err = of_property_read_u32(pdev->dev.of_node, "lantiq,cs", &cs);
 207        if (!err && cs == 1)
 208                cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
 209
 210        /* setup the EBU to run in NAND mode on our base addr */
 211        ltq_ebu_w32(CPHYSADDR(data->nandaddr)
 212                    | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
 213
 214        ltq_ebu_w32(BUSCON1_SETUP | BUSCON1_BCGEN_RES | BUSCON1_WAITWRC2
 215                    | BUSCON1_WAITRDC2 | BUSCON1_HOLDC1 | BUSCON1_RECOVC1
 216                    | BUSCON1_CMULT4, LTQ_EBU_BUSCON1);
 217
 218        ltq_ebu_w32(NAND_CON_NANDM | NAND_CON_CSMUX | NAND_CON_CS_P
 219                    | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
 220                    | cs_flag, EBU_NAND_CON);
 221
 222        /* Scan to find existence of the device */
 223        err = nand_scan(&data->chip, 1);
 224        if (err)
 225                return err;
 226
 227        err = mtd_device_register(mtd, NULL, 0);
 228        if (err)
 229                nand_cleanup(&data->chip);
 230
 231        return err;
 232}
 233
 234/*
 235 * Remove a NAND device.
 236 */
 237static int xway_nand_remove(struct platform_device *pdev)
 238{
 239        struct xway_nand_data *data = platform_get_drvdata(pdev);
 240        struct nand_chip *chip = &data->chip;
 241        int ret;
 242
 243        ret = mtd_device_unregister(nand_to_mtd(chip));
 244        WARN_ON(ret);
 245        nand_cleanup(chip);
 246
 247        return 0;
 248}
 249
 250static const struct of_device_id xway_nand_match[] = {
 251        { .compatible = "lantiq,nand-xway" },
 252        {},
 253};
 254
 255static struct platform_driver xway_nand_driver = {
 256        .probe  = xway_nand_probe,
 257        .remove = xway_nand_remove,
 258        .driver = {
 259                .name           = "lantiq,nand-xway",
 260                .of_match_table = xway_nand_match,
 261        },
 262};
 263
 264builtin_platform_driver(xway_nand_driver);
 265