0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/err.h>
0010 #include <linux/init.h>
0011 #include <linux/slab.h>
0012 #include <linux/module.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/delay.h>
0015 #include <linux/mtd/mtd.h>
0016 #include <linux/mtd/rawnand.h>
0017 #include <linux/mtd/partitions.h>
0018 #include <linux/io.h>
0019 #include <linux/platform_data/txx9/ndfmc.h>
0020
0021
0022 #define TXX9_NDFDTR 0x00
0023 #define TXX9_NDFMCR 0x04
0024 #define TXX9_NDFSR 0x08
0025 #define TXX9_NDFISR 0x0c
0026 #define TXX9_NDFIMR 0x10
0027 #define TXX9_NDFSPR 0x14
0028 #define TXX9_NDFRSTR 0x18
0029
0030
0031 #define TXX9_NDFMCR_WE 0x80
0032 #define TXX9_NDFMCR_ECC_ALL 0x60
0033 #define TXX9_NDFMCR_ECC_RESET 0x60
0034 #define TXX9_NDFMCR_ECC_READ 0x40
0035 #define TXX9_NDFMCR_ECC_ON 0x20
0036 #define TXX9_NDFMCR_ECC_OFF 0x00
0037 #define TXX9_NDFMCR_CE 0x10
0038 #define TXX9_NDFMCR_BSPRT 0x04
0039 #define TXX9_NDFMCR_ALE 0x02
0040 #define TXX9_NDFMCR_CLE 0x01
0041
0042 #define TXX9_NDFMCR_X16 0x0400
0043 #define TXX9_NDFMCR_DMAREQ_MASK 0x0300
0044 #define TXX9_NDFMCR_DMAREQ_NODMA 0x0000
0045 #define TXX9_NDFMCR_DMAREQ_128 0x0100
0046 #define TXX9_NDFMCR_DMAREQ_256 0x0200
0047 #define TXX9_NDFMCR_DMAREQ_512 0x0300
0048 #define TXX9_NDFMCR_CS_MASK 0x0c
0049 #define TXX9_NDFMCR_CS(ch) ((ch) << 2)
0050
0051
0052 #define TXX9_NDFSR_BUSY 0x80
0053
0054 #define TXX9_NDFSR_DMARUN 0x40
0055
0056
0057 #define TXX9_NDFRSTR_RST 0x01
0058
0059 struct txx9ndfmc_priv {
0060 struct platform_device *dev;
0061 struct nand_chip chip;
0062 int cs;
0063 const char *mtdname;
0064 };
0065
0066 #define MAX_TXX9NDFMC_DEV 4
0067 struct txx9ndfmc_drvdata {
0068 struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];
0069 void __iomem *base;
0070 unsigned char hold;
0071 unsigned char spw;
0072 struct nand_controller controller;
0073 };
0074
0075 static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
0076 {
0077 struct nand_chip *chip = mtd_to_nand(mtd);
0078 struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip);
0079 return txx9_priv->dev;
0080 }
0081
0082 static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)
0083 {
0084 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
0085 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
0086
0087 return drvdata->base + (reg << plat->shift);
0088 }
0089
0090 static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)
0091 {
0092 return __raw_readl(ndregaddr(dev, reg));
0093 }
0094
0095 static void txx9ndfmc_write(struct platform_device *dev,
0096 u32 val, unsigned int reg)
0097 {
0098 __raw_writel(val, ndregaddr(dev, reg));
0099 }
0100
0101 static uint8_t txx9ndfmc_read_byte(struct nand_chip *chip)
0102 {
0103 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
0104
0105 return txx9ndfmc_read(dev, TXX9_NDFDTR);
0106 }
0107
0108 static void txx9ndfmc_write_buf(struct nand_chip *chip, const uint8_t *buf,
0109 int len)
0110 {
0111 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
0112 void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
0113 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
0114
0115 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);
0116 while (len--)
0117 __raw_writel(*buf++, ndfdtr);
0118 txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
0119 }
0120
0121 static void txx9ndfmc_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
0122 {
0123 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
0124 void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
0125
0126 while (len--)
0127 *buf++ = __raw_readl(ndfdtr);
0128 }
0129
0130 static void txx9ndfmc_cmd_ctrl(struct nand_chip *chip, int cmd,
0131 unsigned int ctrl)
0132 {
0133 struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip);
0134 struct platform_device *dev = txx9_priv->dev;
0135 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
0136
0137 if (ctrl & NAND_CTRL_CHANGE) {
0138 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
0139
0140 mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);
0141 mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;
0142 mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;
0143
0144 mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;
0145 if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {
0146 mcr &= ~TXX9_NDFMCR_CS_MASK;
0147 mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);
0148 }
0149 txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
0150 }
0151 if (cmd != NAND_CMD_NONE)
0152 txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);
0153 if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {
0154
0155 if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)
0156 txx9ndfmc_write(dev, 0, TXX9_NDFDTR);
0157 }
0158 }
0159
0160 static int txx9ndfmc_dev_ready(struct nand_chip *chip)
0161 {
0162 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
0163
0164 return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);
0165 }
0166
0167 static int txx9ndfmc_calculate_ecc(struct nand_chip *chip, const uint8_t *dat,
0168 uint8_t *ecc_code)
0169 {
0170 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
0171 int eccbytes;
0172 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
0173
0174 mcr &= ~TXX9_NDFMCR_ECC_ALL;
0175 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
0176 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);
0177 for (eccbytes = chip->ecc.bytes; eccbytes > 0; eccbytes -= 3) {
0178 ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);
0179 ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);
0180 ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);
0181 ecc_code += 3;
0182 }
0183 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
0184 return 0;
0185 }
0186
0187 static int txx9ndfmc_correct_data(struct nand_chip *chip, unsigned char *buf,
0188 unsigned char *read_ecc,
0189 unsigned char *calc_ecc)
0190 {
0191 int eccsize;
0192 int corrected = 0;
0193 int stat;
0194
0195 for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) {
0196 stat = rawnand_sw_hamming_correct(chip, buf, read_ecc,
0197 calc_ecc);
0198 if (stat < 0)
0199 return stat;
0200 corrected += stat;
0201 buf += 256;
0202 read_ecc += 3;
0203 calc_ecc += 3;
0204 }
0205 return corrected;
0206 }
0207
0208 static void txx9ndfmc_enable_hwecc(struct nand_chip *chip, int mode)
0209 {
0210 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
0211 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
0212
0213 mcr &= ~TXX9_NDFMCR_ECC_ALL;
0214 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);
0215 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
0216 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);
0217 }
0218
0219 static void txx9ndfmc_initialize(struct platform_device *dev)
0220 {
0221 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
0222 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
0223 int tmout = 100;
0224
0225 if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)
0226 ;
0227 else {
0228
0229 txx9ndfmc_write(dev,
0230 txx9ndfmc_read(dev, TXX9_NDFRSTR) |
0231 TXX9_NDFRSTR_RST,
0232 TXX9_NDFRSTR);
0233 while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {
0234 if (--tmout == 0) {
0235 dev_err(&dev->dev, "reset failed.\n");
0236 break;
0237 }
0238 udelay(1);
0239 }
0240 }
0241
0242 txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);
0243 txx9ndfmc_write(dev,
0244 (plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?
0245 TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);
0246 }
0247
0248 #define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \
0249 DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)
0250
0251 static int txx9ndfmc_attach_chip(struct nand_chip *chip)
0252 {
0253 struct mtd_info *mtd = nand_to_mtd(chip);
0254
0255 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
0256 return 0;
0257
0258 chip->ecc.strength = 1;
0259
0260 if (mtd->writesize >= 512) {
0261 chip->ecc.size = 512;
0262 chip->ecc.bytes = 6;
0263 } else {
0264 chip->ecc.size = 256;
0265 chip->ecc.bytes = 3;
0266 }
0267
0268 chip->ecc.calculate = txx9ndfmc_calculate_ecc;
0269 chip->ecc.correct = txx9ndfmc_correct_data;
0270 chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
0271
0272 return 0;
0273 }
0274
0275 static const struct nand_controller_ops txx9ndfmc_controller_ops = {
0276 .attach_chip = txx9ndfmc_attach_chip,
0277 };
0278
0279 static int __init txx9ndfmc_probe(struct platform_device *dev)
0280 {
0281 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
0282 int hold, spw;
0283 int i;
0284 struct txx9ndfmc_drvdata *drvdata;
0285 unsigned long gbusclk = plat->gbus_clock;
0286
0287 drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
0288 if (!drvdata)
0289 return -ENOMEM;
0290 drvdata->base = devm_platform_ioremap_resource(dev, 0);
0291 if (IS_ERR(drvdata->base))
0292 return PTR_ERR(drvdata->base);
0293
0294 hold = plat->hold ?: 20;
0295 spw = plat->spw ?: 90;
0296
0297 hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
0298 spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
0299 if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
0300 hold -= 2;
0301 spw -= 1;
0302 hold = clamp(hold, 1, 15);
0303 drvdata->hold = hold;
0304 spw = clamp(spw, 1, 15);
0305 drvdata->spw = spw;
0306 dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
0307 (gbusclk + 500000) / 1000000, hold, spw);
0308
0309 nand_controller_init(&drvdata->controller);
0310 drvdata->controller.ops = &txx9ndfmc_controller_ops;
0311
0312 platform_set_drvdata(dev, drvdata);
0313 txx9ndfmc_initialize(dev);
0314
0315 for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
0316 struct txx9ndfmc_priv *txx9_priv;
0317 struct nand_chip *chip;
0318 struct mtd_info *mtd;
0319
0320 if (!(plat->ch_mask & (1 << i)))
0321 continue;
0322 txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
0323 GFP_KERNEL);
0324 if (!txx9_priv)
0325 continue;
0326 chip = &txx9_priv->chip;
0327 mtd = nand_to_mtd(chip);
0328 mtd->dev.parent = &dev->dev;
0329
0330 chip->legacy.read_byte = txx9ndfmc_read_byte;
0331 chip->legacy.read_buf = txx9ndfmc_read_buf;
0332 chip->legacy.write_buf = txx9ndfmc_write_buf;
0333 chip->legacy.cmd_ctrl = txx9ndfmc_cmd_ctrl;
0334 chip->legacy.dev_ready = txx9ndfmc_dev_ready;
0335 chip->legacy.chip_delay = 100;
0336 chip->controller = &drvdata->controller;
0337
0338 nand_set_controller_data(chip, txx9_priv);
0339 txx9_priv->dev = dev;
0340
0341 if (plat->ch_mask != 1) {
0342 txx9_priv->cs = i;
0343 txx9_priv->mtdname = kasprintf(GFP_KERNEL, "%s.%u",
0344 dev_name(&dev->dev), i);
0345 } else {
0346 txx9_priv->cs = -1;
0347 txx9_priv->mtdname = kstrdup(dev_name(&dev->dev),
0348 GFP_KERNEL);
0349 }
0350 if (!txx9_priv->mtdname) {
0351 kfree(txx9_priv);
0352 dev_err(&dev->dev, "Unable to allocate MTD name.\n");
0353 continue;
0354 }
0355 if (plat->wide_mask & (1 << i))
0356 chip->options |= NAND_BUSWIDTH_16;
0357
0358 if (nand_scan(chip, 1)) {
0359 kfree(txx9_priv->mtdname);
0360 kfree(txx9_priv);
0361 continue;
0362 }
0363 mtd->name = txx9_priv->mtdname;
0364
0365 mtd_device_register(mtd, NULL, 0);
0366 drvdata->mtds[i] = mtd;
0367 }
0368
0369 return 0;
0370 }
0371
0372 static int __exit txx9ndfmc_remove(struct platform_device *dev)
0373 {
0374 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
0375 int ret, i;
0376
0377 if (!drvdata)
0378 return 0;
0379 for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
0380 struct mtd_info *mtd = drvdata->mtds[i];
0381 struct nand_chip *chip;
0382 struct txx9ndfmc_priv *txx9_priv;
0383
0384 if (!mtd)
0385 continue;
0386 chip = mtd_to_nand(mtd);
0387 txx9_priv = nand_get_controller_data(chip);
0388
0389 ret = mtd_device_unregister(nand_to_mtd(chip));
0390 WARN_ON(ret);
0391 nand_cleanup(chip);
0392 kfree(txx9_priv->mtdname);
0393 kfree(txx9_priv);
0394 }
0395 return 0;
0396 }
0397
0398 #ifdef CONFIG_PM
0399 static int txx9ndfmc_resume(struct platform_device *dev)
0400 {
0401 if (platform_get_drvdata(dev))
0402 txx9ndfmc_initialize(dev);
0403 return 0;
0404 }
0405 #else
0406 #define txx9ndfmc_resume NULL
0407 #endif
0408
0409 static struct platform_driver txx9ndfmc_driver = {
0410 .remove = __exit_p(txx9ndfmc_remove),
0411 .resume = txx9ndfmc_resume,
0412 .driver = {
0413 .name = "txx9ndfmc",
0414 },
0415 };
0416
0417 module_platform_driver_probe(txx9ndfmc_driver, txx9ndfmc_probe);
0418
0419 MODULE_LICENSE("GPL");
0420 MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
0421 MODULE_ALIAS("platform:txx9ndfmc");