Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  Copyright (C) 2004 Richard Purdie
0004  *  Copyright (C) 2008 Dmitry Baryshkov
0005  *
0006  *  Based on Sharp's NAND driver sharp_sl.c
0007  */
0008 
0009 #include <linux/slab.h>
0010 #include <linux/module.h>
0011 #include <linux/delay.h>
0012 #include <linux/mtd/mtd.h>
0013 #include <linux/mtd/rawnand.h>
0014 #include <linux/mtd/partitions.h>
0015 #include <linux/mtd/sharpsl.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/io.h>
0019 
0020 struct sharpsl_nand {
0021     struct nand_controller  controller;
0022     struct nand_chip    chip;
0023 
0024     void __iomem        *io;
0025 };
0026 
0027 static inline struct sharpsl_nand *mtd_to_sharpsl(struct mtd_info *mtd)
0028 {
0029     return container_of(mtd_to_nand(mtd), struct sharpsl_nand, chip);
0030 }
0031 
0032 /* register offset */
0033 #define ECCLPLB     0x00    /* line parity 7 - 0 bit */
0034 #define ECCLPUB     0x04    /* line parity 15 - 8 bit */
0035 #define ECCCP       0x08    /* column parity 5 - 0 bit */
0036 #define ECCCNTR     0x0C    /* ECC byte counter */
0037 #define ECCCLRR     0x10    /* cleare ECC */
0038 #define FLASHIO     0x14    /* Flash I/O */
0039 #define FLASHCTL    0x18    /* Flash Control */
0040 
0041 /* Flash control bit */
0042 #define FLRYBY      (1 << 5)
0043 #define FLCE1       (1 << 4)
0044 #define FLWP        (1 << 3)
0045 #define FLALE       (1 << 2)
0046 #define FLCLE       (1 << 1)
0047 #define FLCE0       (1 << 0)
0048 
0049 /*
0050  *  hardware specific access to control-lines
0051  *  ctrl:
0052  *  NAND_CNE: bit 0 -> ! bit 0 & 4
0053  *  NAND_CLE: bit 1 -> bit 1
0054  *  NAND_ALE: bit 2 -> bit 2
0055  *
0056  */
0057 static void sharpsl_nand_hwcontrol(struct nand_chip *chip, int cmd,
0058                    unsigned int ctrl)
0059 {
0060     struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
0061 
0062     if (ctrl & NAND_CTRL_CHANGE) {
0063         unsigned char bits = ctrl & 0x07;
0064 
0065         bits |= (ctrl & 0x01) << 4;
0066 
0067         bits ^= 0x11;
0068 
0069         writeb((readb(sharpsl->io + FLASHCTL) & ~0x17) | bits, sharpsl->io + FLASHCTL);
0070     }
0071 
0072     if (cmd != NAND_CMD_NONE)
0073         writeb(cmd, chip->legacy.IO_ADDR_W);
0074 }
0075 
0076 static int sharpsl_nand_dev_ready(struct nand_chip *chip)
0077 {
0078     struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
0079     return !((readb(sharpsl->io + FLASHCTL) & FLRYBY) == 0);
0080 }
0081 
0082 static void sharpsl_nand_enable_hwecc(struct nand_chip *chip, int mode)
0083 {
0084     struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
0085     writeb(0, sharpsl->io + ECCCLRR);
0086 }
0087 
0088 static int sharpsl_nand_calculate_ecc(struct nand_chip *chip,
0089                       const u_char * dat, u_char * ecc_code)
0090 {
0091     struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
0092     ecc_code[0] = ~readb(sharpsl->io + ECCLPUB);
0093     ecc_code[1] = ~readb(sharpsl->io + ECCLPLB);
0094     ecc_code[2] = (~readb(sharpsl->io + ECCCP) << 2) | 0x03;
0095     return readb(sharpsl->io + ECCCNTR) != 0;
0096 }
0097 
0098 static int sharpsl_attach_chip(struct nand_chip *chip)
0099 {
0100     if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
0101         return 0;
0102 
0103     chip->ecc.size = 256;
0104     chip->ecc.bytes = 3;
0105     chip->ecc.strength = 1;
0106     chip->ecc.hwctl = sharpsl_nand_enable_hwecc;
0107     chip->ecc.calculate = sharpsl_nand_calculate_ecc;
0108     chip->ecc.correct = rawnand_sw_hamming_correct;
0109 
0110     return 0;
0111 }
0112 
0113 static const struct nand_controller_ops sharpsl_ops = {
0114     .attach_chip = sharpsl_attach_chip,
0115 };
0116 
0117 /*
0118  * Main initialization routine
0119  */
0120 static int sharpsl_nand_probe(struct platform_device *pdev)
0121 {
0122     struct nand_chip *this;
0123     struct mtd_info *mtd;
0124     struct resource *r;
0125     int err = 0;
0126     struct sharpsl_nand *sharpsl;
0127     struct sharpsl_nand_platform_data *data = dev_get_platdata(&pdev->dev);
0128 
0129     if (!data) {
0130         dev_err(&pdev->dev, "no platform data!\n");
0131         return -EINVAL;
0132     }
0133 
0134     /* Allocate memory for MTD device structure and private data */
0135     sharpsl = kzalloc(sizeof(struct sharpsl_nand), GFP_KERNEL);
0136     if (!sharpsl)
0137         return -ENOMEM;
0138 
0139     r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0140     if (!r) {
0141         dev_err(&pdev->dev, "no io memory resource defined!\n");
0142         err = -ENODEV;
0143         goto err_get_res;
0144     }
0145 
0146     /* map physical address */
0147     sharpsl->io = ioremap(r->start, resource_size(r));
0148     if (!sharpsl->io) {
0149         dev_err(&pdev->dev, "ioremap to access Sharp SL NAND chip failed\n");
0150         err = -EIO;
0151         goto err_ioremap;
0152     }
0153 
0154     /* Get pointer to private data */
0155     this = (struct nand_chip *)(&sharpsl->chip);
0156 
0157     nand_controller_init(&sharpsl->controller);
0158     sharpsl->controller.ops = &sharpsl_ops;
0159     this->controller = &sharpsl->controller;
0160 
0161     /* Link the private data with the MTD structure */
0162     mtd = nand_to_mtd(this);
0163     mtd->dev.parent = &pdev->dev;
0164     mtd_set_ooblayout(mtd, data->ecc_layout);
0165 
0166     platform_set_drvdata(pdev, sharpsl);
0167 
0168     /*
0169      * PXA initialize
0170      */
0171     writeb(readb(sharpsl->io + FLASHCTL) | FLWP, sharpsl->io + FLASHCTL);
0172 
0173     /* Set address of NAND IO lines */
0174     this->legacy.IO_ADDR_R = sharpsl->io + FLASHIO;
0175     this->legacy.IO_ADDR_W = sharpsl->io + FLASHIO;
0176     /* Set address of hardware control function */
0177     this->legacy.cmd_ctrl = sharpsl_nand_hwcontrol;
0178     this->legacy.dev_ready = sharpsl_nand_dev_ready;
0179     /* 15 us command delay time */
0180     this->legacy.chip_delay = 15;
0181     this->badblock_pattern = data->badblock_pattern;
0182 
0183     /* Scan to find existence of the device */
0184     err = nand_scan(this, 1);
0185     if (err)
0186         goto err_scan;
0187 
0188     /* Register the partitions */
0189     mtd->name = "sharpsl-nand";
0190 
0191     err = mtd_device_parse_register(mtd, data->part_parsers, NULL,
0192                     data->partitions, data->nr_partitions);
0193     if (err)
0194         goto err_add;
0195 
0196     /* Return happy */
0197     return 0;
0198 
0199 err_add:
0200     nand_cleanup(this);
0201 
0202 err_scan:
0203     iounmap(sharpsl->io);
0204 err_ioremap:
0205 err_get_res:
0206     kfree(sharpsl);
0207     return err;
0208 }
0209 
0210 /*
0211  * Clean up routine
0212  */
0213 static int sharpsl_nand_remove(struct platform_device *pdev)
0214 {
0215     struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev);
0216     struct nand_chip *chip = &sharpsl->chip;
0217     int ret;
0218 
0219     /* Unregister device */
0220     ret = mtd_device_unregister(nand_to_mtd(chip));
0221     WARN_ON(ret);
0222 
0223     /* Release resources */
0224     nand_cleanup(chip);
0225 
0226     iounmap(sharpsl->io);
0227 
0228     /* Free the driver's structure */
0229     kfree(sharpsl);
0230 
0231     return 0;
0232 }
0233 
0234 static struct platform_driver sharpsl_nand_driver = {
0235     .driver = {
0236         .name   = "sharpsl-nand",
0237     },
0238     .probe      = sharpsl_nand_probe,
0239     .remove     = sharpsl_nand_remove,
0240 };
0241 
0242 module_platform_driver(sharpsl_nand_driver);
0243 
0244 MODULE_LICENSE("GPL");
0245 MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
0246 MODULE_DESCRIPTION("Device specific logic for NAND flash on Sharp SL-C7xx Series");