Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  Copyright © 2008 Ilya Yanok, Emcraft Systems
0004  */
0005 
0006 #include <linux/slab.h>
0007 #include <linux/module.h>
0008 #include <linux/mtd/mtd.h>
0009 #include <linux/mtd/rawnand.h>
0010 #include <linux/mtd/partitions.h>
0011 #include <linux/of_address.h>
0012 #include <linux/of_platform.h>
0013 #include <linux/io.h>
0014 
0015 #define FPGA_NAND_CMD_MASK      (0x7 << 28)
0016 #define FPGA_NAND_CMD_COMMAND       (0x0 << 28)
0017 #define FPGA_NAND_CMD_ADDR      (0x1 << 28)
0018 #define FPGA_NAND_CMD_READ      (0x2 << 28)
0019 #define FPGA_NAND_CMD_WRITE     (0x3 << 28)
0020 #define FPGA_NAND_BUSY          (0x1 << 15)
0021 #define FPGA_NAND_ENABLE        (0x1 << 31)
0022 #define FPGA_NAND_DATA_SHIFT        16
0023 
0024 struct socrates_nand_host {
0025     struct nand_controller  controller;
0026     struct nand_chip    nand_chip;
0027     void __iomem        *io_base;
0028     struct device       *dev;
0029 };
0030 
0031 /**
0032  * socrates_nand_write_buf -  write buffer to chip
0033  * @this:   NAND chip object
0034  * @buf:    data buffer
0035  * @len:    number of bytes to write
0036  */
0037 static void socrates_nand_write_buf(struct nand_chip *this, const uint8_t *buf,
0038                     int len)
0039 {
0040     int i;
0041     struct socrates_nand_host *host = nand_get_controller_data(this);
0042 
0043     for (i = 0; i < len; i++) {
0044         out_be32(host->io_base, FPGA_NAND_ENABLE |
0045                 FPGA_NAND_CMD_WRITE |
0046                 (buf[i] << FPGA_NAND_DATA_SHIFT));
0047     }
0048 }
0049 
0050 /**
0051  * socrates_nand_read_buf -  read chip data into buffer
0052  * @this:   NAND chip object
0053  * @buf:    buffer to store date
0054  * @len:    number of bytes to read
0055  */
0056 static void socrates_nand_read_buf(struct nand_chip *this, uint8_t *buf,
0057                    int len)
0058 {
0059     int i;
0060     struct socrates_nand_host *host = nand_get_controller_data(this);
0061     uint32_t val;
0062 
0063     val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ;
0064 
0065     out_be32(host->io_base, val);
0066     for (i = 0; i < len; i++) {
0067         buf[i] = (in_be32(host->io_base) >>
0068                 FPGA_NAND_DATA_SHIFT) & 0xff;
0069     }
0070 }
0071 
0072 /**
0073  * socrates_nand_read_byte -  read one byte from the chip
0074  * @mtd:    MTD device structure
0075  */
0076 static uint8_t socrates_nand_read_byte(struct nand_chip *this)
0077 {
0078     uint8_t byte;
0079     socrates_nand_read_buf(this, &byte, sizeof(byte));
0080     return byte;
0081 }
0082 
0083 /*
0084  * Hardware specific access to control-lines
0085  */
0086 static void socrates_nand_cmd_ctrl(struct nand_chip *nand_chip, int cmd,
0087                    unsigned int ctrl)
0088 {
0089     struct socrates_nand_host *host = nand_get_controller_data(nand_chip);
0090     uint32_t val;
0091 
0092     if (cmd == NAND_CMD_NONE)
0093         return;
0094 
0095     if (ctrl & NAND_CLE)
0096         val = FPGA_NAND_CMD_COMMAND;
0097     else
0098         val = FPGA_NAND_CMD_ADDR;
0099 
0100     if (ctrl & NAND_NCE)
0101         val |= FPGA_NAND_ENABLE;
0102 
0103     val |= (cmd & 0xff) << FPGA_NAND_DATA_SHIFT;
0104 
0105     out_be32(host->io_base, val);
0106 }
0107 
0108 /*
0109  * Read the Device Ready pin.
0110  */
0111 static int socrates_nand_device_ready(struct nand_chip *nand_chip)
0112 {
0113     struct socrates_nand_host *host = nand_get_controller_data(nand_chip);
0114 
0115     if (in_be32(host->io_base) & FPGA_NAND_BUSY)
0116         return 0; /* busy */
0117     return 1;
0118 }
0119 
0120 static int socrates_attach_chip(struct nand_chip *chip)
0121 {
0122     if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
0123         chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
0124         chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
0125 
0126     return 0;
0127 }
0128 
0129 static const struct nand_controller_ops socrates_ops = {
0130     .attach_chip = socrates_attach_chip,
0131 };
0132 
0133 /*
0134  * Probe for the NAND device.
0135  */
0136 static int socrates_nand_probe(struct platform_device *ofdev)
0137 {
0138     struct socrates_nand_host *host;
0139     struct mtd_info *mtd;
0140     struct nand_chip *nand_chip;
0141     int res;
0142 
0143     /* Allocate memory for the device structure (and zero it) */
0144     host = devm_kzalloc(&ofdev->dev, sizeof(*host), GFP_KERNEL);
0145     if (!host)
0146         return -ENOMEM;
0147 
0148     host->io_base = of_iomap(ofdev->dev.of_node, 0);
0149     if (host->io_base == NULL) {
0150         dev_err(&ofdev->dev, "ioremap failed\n");
0151         return -EIO;
0152     }
0153 
0154     nand_chip = &host->nand_chip;
0155     mtd = nand_to_mtd(nand_chip);
0156     host->dev = &ofdev->dev;
0157 
0158     nand_controller_init(&host->controller);
0159     host->controller.ops = &socrates_ops;
0160     nand_chip->controller = &host->controller;
0161 
0162     /* link the private data structures */
0163     nand_set_controller_data(nand_chip, host);
0164     nand_set_flash_node(nand_chip, ofdev->dev.of_node);
0165     mtd->name = "socrates_nand";
0166     mtd->dev.parent = &ofdev->dev;
0167 
0168     nand_chip->legacy.cmd_ctrl = socrates_nand_cmd_ctrl;
0169     nand_chip->legacy.read_byte = socrates_nand_read_byte;
0170     nand_chip->legacy.write_buf = socrates_nand_write_buf;
0171     nand_chip->legacy.read_buf = socrates_nand_read_buf;
0172     nand_chip->legacy.dev_ready = socrates_nand_device_ready;
0173 
0174     /* TODO: I have no idea what real delay is. */
0175     nand_chip->legacy.chip_delay = 20;  /* 20us command delay time */
0176 
0177     /*
0178      * This driver assumes that the default ECC engine should be TYPE_SOFT.
0179      * Set ->engine_type before registering the NAND devices in order to
0180      * provide a driver specific default value.
0181      */
0182     nand_chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
0183 
0184     dev_set_drvdata(&ofdev->dev, host);
0185 
0186     res = nand_scan(nand_chip, 1);
0187     if (res)
0188         goto out;
0189 
0190     res = mtd_device_register(mtd, NULL, 0);
0191     if (!res)
0192         return res;
0193 
0194     nand_cleanup(nand_chip);
0195 
0196 out:
0197     iounmap(host->io_base);
0198     return res;
0199 }
0200 
0201 /*
0202  * Remove a NAND device.
0203  */
0204 static int socrates_nand_remove(struct platform_device *ofdev)
0205 {
0206     struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
0207     struct nand_chip *chip = &host->nand_chip;
0208     int ret;
0209 
0210     ret = mtd_device_unregister(nand_to_mtd(chip));
0211     WARN_ON(ret);
0212     nand_cleanup(chip);
0213 
0214     iounmap(host->io_base);
0215 
0216     return 0;
0217 }
0218 
0219 static const struct of_device_id socrates_nand_match[] =
0220 {
0221     {
0222         .compatible   = "abb,socrates-nand",
0223     },
0224     {},
0225 };
0226 
0227 MODULE_DEVICE_TABLE(of, socrates_nand_match);
0228 
0229 static struct platform_driver socrates_nand_driver = {
0230     .driver = {
0231         .name = "socrates_nand",
0232         .of_match_table = socrates_nand_match,
0233     },
0234     .probe      = socrates_nand_probe,
0235     .remove     = socrates_nand_remove,
0236 };
0237 
0238 module_platform_driver(socrates_nand_driver);
0239 
0240 MODULE_LICENSE("GPL");
0241 MODULE_AUTHOR("Ilya Yanok");
0242 MODULE_DESCRIPTION("NAND driver for Socrates board");