419 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * TXx9 NAND flash memory controller driver4 * Based on RBTX49xx patch from CELF patch archive.5 *6 * (C) Copyright TOSHIBA CORPORATION 2004-20077 * All Rights Reserved.8 */9#include <linux/err.h>10#include <linux/init.h>11#include <linux/slab.h>12#include <linux/module.h>13#include <linux/platform_device.h>14#include <linux/delay.h>15#include <linux/mtd/mtd.h>16#include <linux/mtd/rawnand.h>17#include <linux/mtd/partitions.h>18#include <linux/io.h>19#include <linux/platform_data/txx9/ndfmc.h>20 21/* TXX9 NDFMC Registers */22#define TXX9_NDFDTR 0x0023#define TXX9_NDFMCR 0x0424#define TXX9_NDFSR 0x0825#define TXX9_NDFISR 0x0c26#define TXX9_NDFIMR 0x1027#define TXX9_NDFSPR 0x1428#define TXX9_NDFRSTR 0x18 /* not TX4939 */29 30/* NDFMCR : NDFMC Mode Control */31#define TXX9_NDFMCR_WE 0x8032#define TXX9_NDFMCR_ECC_ALL 0x6033#define TXX9_NDFMCR_ECC_RESET 0x6034#define TXX9_NDFMCR_ECC_READ 0x4035#define TXX9_NDFMCR_ECC_ON 0x2036#define TXX9_NDFMCR_ECC_OFF 0x0037#define TXX9_NDFMCR_CE 0x1038#define TXX9_NDFMCR_BSPRT 0x04 /* TX4925/TX4926 only */39#define TXX9_NDFMCR_ALE 0x0240#define TXX9_NDFMCR_CLE 0x0141/* TX4939 only */42#define TXX9_NDFMCR_X16 0x040043#define TXX9_NDFMCR_DMAREQ_MASK 0x030044#define TXX9_NDFMCR_DMAREQ_NODMA 0x000045#define TXX9_NDFMCR_DMAREQ_128 0x010046#define TXX9_NDFMCR_DMAREQ_256 0x020047#define TXX9_NDFMCR_DMAREQ_512 0x030048#define TXX9_NDFMCR_CS_MASK 0x0c49#define TXX9_NDFMCR_CS(ch) ((ch) << 2)50 51/* NDFMCR : NDFMC Status */52#define TXX9_NDFSR_BUSY 0x8053/* TX4939 only */54#define TXX9_NDFSR_DMARUN 0x4055 56/* NDFMCR : NDFMC Reset */57#define TXX9_NDFRSTR_RST 0x0158 59struct txx9ndfmc_priv {60 struct platform_device *dev;61 struct nand_chip chip;62 int cs;63 const char *mtdname;64};65 66#define MAX_TXX9NDFMC_DEV 467struct txx9ndfmc_drvdata {68 struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];69 void __iomem *base;70 unsigned char hold; /* in gbusclock */71 unsigned char spw; /* in gbusclock */72 struct nand_controller controller;73};74 75static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)76{77 struct nand_chip *chip = mtd_to_nand(mtd);78 struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip);79 return txx9_priv->dev;80}81 82static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)83{84 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);85 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);86 87 return drvdata->base + (reg << plat->shift);88}89 90static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)91{92 return __raw_readl(ndregaddr(dev, reg));93}94 95static void txx9ndfmc_write(struct platform_device *dev,96 u32 val, unsigned int reg)97{98 __raw_writel(val, ndregaddr(dev, reg));99}100 101static uint8_t txx9ndfmc_read_byte(struct nand_chip *chip)102{103 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));104 105 return txx9ndfmc_read(dev, TXX9_NDFDTR);106}107 108static void txx9ndfmc_write_buf(struct nand_chip *chip, const uint8_t *buf,109 int len)110{111 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));112 void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);113 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);114 115 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);116 while (len--)117 __raw_writel(*buf++, ndfdtr);118 txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);119}120 121static void txx9ndfmc_read_buf(struct nand_chip *chip, uint8_t *buf, int len)122{123 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));124 void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);125 126 while (len--)127 *buf++ = __raw_readl(ndfdtr);128}129 130static void txx9ndfmc_cmd_ctrl(struct nand_chip *chip, int cmd,131 unsigned int ctrl)132{133 struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip);134 struct platform_device *dev = txx9_priv->dev;135 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);136 137 if (ctrl & NAND_CTRL_CHANGE) {138 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);139 140 mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);141 mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;142 mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;143 /* TXX9_NDFMCR_CE bit is 0:high 1:low */144 mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;145 if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {146 mcr &= ~TXX9_NDFMCR_CS_MASK;147 mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);148 }149 txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);150 }151 if (cmd != NAND_CMD_NONE)152 txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);153 if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {154 /* dummy write to update external latch */155 if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)156 txx9ndfmc_write(dev, 0, TXX9_NDFDTR);157 }158}159 160static int txx9ndfmc_dev_ready(struct nand_chip *chip)161{162 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));163 164 return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);165}166 167static int txx9ndfmc_calculate_ecc(struct nand_chip *chip, const uint8_t *dat,168 uint8_t *ecc_code)169{170 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));171 int eccbytes;172 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);173 174 mcr &= ~TXX9_NDFMCR_ECC_ALL;175 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);176 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);177 for (eccbytes = chip->ecc.bytes; eccbytes > 0; eccbytes -= 3) {178 ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);179 ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);180 ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);181 ecc_code += 3;182 }183 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);184 return 0;185}186 187static int txx9ndfmc_correct_data(struct nand_chip *chip, unsigned char *buf,188 unsigned char *read_ecc,189 unsigned char *calc_ecc)190{191 int eccsize;192 int corrected = 0;193 int stat;194 195 for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) {196 stat = rawnand_sw_hamming_correct(chip, buf, read_ecc,197 calc_ecc);198 if (stat < 0)199 return stat;200 corrected += stat;201 buf += 256;202 read_ecc += 3;203 calc_ecc += 3;204 }205 return corrected;206}207 208static void txx9ndfmc_enable_hwecc(struct nand_chip *chip, int mode)209{210 struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));211 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);212 213 mcr &= ~TXX9_NDFMCR_ECC_ALL;214 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);215 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);216 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);217}218 219static void txx9ndfmc_initialize(struct platform_device *dev)220{221 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);222 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);223 int tmout = 100;224 225 if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)226 ; /* no NDFRSTR. Write to NDFSPR resets the NDFMC. */227 else {228 /* reset NDFMC */229 txx9ndfmc_write(dev,230 txx9ndfmc_read(dev, TXX9_NDFRSTR) |231 TXX9_NDFRSTR_RST,232 TXX9_NDFRSTR);233 while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {234 if (--tmout == 0) {235 dev_err(&dev->dev, "reset failed.\n");236 break;237 }238 udelay(1);239 }240 }241 /* setup Hold Time, Strobe Pulse Width */242 txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);243 txx9ndfmc_write(dev,244 (plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?245 TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);246}247 248#define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \249 DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)250 251static int txx9ndfmc_attach_chip(struct nand_chip *chip)252{253 struct mtd_info *mtd = nand_to_mtd(chip);254 255 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)256 return 0;257 258 chip->ecc.strength = 1;259 260 if (mtd->writesize >= 512) {261 chip->ecc.size = 512;262 chip->ecc.bytes = 6;263 } else {264 chip->ecc.size = 256;265 chip->ecc.bytes = 3;266 }267 268 chip->ecc.calculate = txx9ndfmc_calculate_ecc;269 chip->ecc.correct = txx9ndfmc_correct_data;270 chip->ecc.hwctl = txx9ndfmc_enable_hwecc;271 272 return 0;273}274 275static const struct nand_controller_ops txx9ndfmc_controller_ops = {276 .attach_chip = txx9ndfmc_attach_chip,277};278 279static int txx9ndfmc_probe(struct platform_device *dev)280{281 struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);282 int hold, spw;283 int i;284 struct txx9ndfmc_drvdata *drvdata;285 unsigned long gbusclk = plat->gbus_clock;286 287 drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);288 if (!drvdata)289 return -ENOMEM;290 drvdata->base = devm_platform_ioremap_resource(dev, 0);291 if (IS_ERR(drvdata->base))292 return PTR_ERR(drvdata->base);293 294 hold = plat->hold ?: 20; /* tDH */295 spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */296 297 hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);298 spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);299 if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)300 hold -= 2; /* actual hold time : (HOLD + 2) BUSCLK */301 spw -= 1; /* actual wait time : (SPW + 1) BUSCLK */302 hold = clamp(hold, 1, 15);303 drvdata->hold = hold;304 spw = clamp(spw, 1, 15);305 drvdata->spw = spw;306 dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",307 (gbusclk + 500000) / 1000000, hold, spw);308 309 nand_controller_init(&drvdata->controller);310 drvdata->controller.ops = &txx9ndfmc_controller_ops;311 312 platform_set_drvdata(dev, drvdata);313 txx9ndfmc_initialize(dev);314 315 for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {316 struct txx9ndfmc_priv *txx9_priv;317 struct nand_chip *chip;318 struct mtd_info *mtd;319 320 if (!(plat->ch_mask & (1 << i)))321 continue;322 txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),323 GFP_KERNEL);324 if (!txx9_priv)325 continue;326 chip = &txx9_priv->chip;327 mtd = nand_to_mtd(chip);328 mtd->dev.parent = &dev->dev;329 330 chip->legacy.read_byte = txx9ndfmc_read_byte;331 chip->legacy.read_buf = txx9ndfmc_read_buf;332 chip->legacy.write_buf = txx9ndfmc_write_buf;333 chip->legacy.cmd_ctrl = txx9ndfmc_cmd_ctrl;334 chip->legacy.dev_ready = txx9ndfmc_dev_ready;335 chip->legacy.chip_delay = 100;336 chip->controller = &drvdata->controller;337 338 nand_set_controller_data(chip, txx9_priv);339 txx9_priv->dev = dev;340 341 if (plat->ch_mask != 1) {342 txx9_priv->cs = i;343 txx9_priv->mtdname = kasprintf(GFP_KERNEL, "%s.%u",344 dev_name(&dev->dev), i);345 } else {346 txx9_priv->cs = -1;347 txx9_priv->mtdname = kstrdup(dev_name(&dev->dev),348 GFP_KERNEL);349 }350 if (!txx9_priv->mtdname) {351 kfree(txx9_priv);352 dev_err(&dev->dev, "Unable to allocate MTD name.\n");353 continue;354 }355 if (plat->wide_mask & (1 << i))356 chip->options |= NAND_BUSWIDTH_16;357 358 if (nand_scan(chip, 1)) {359 kfree(txx9_priv->mtdname);360 kfree(txx9_priv);361 continue;362 }363 mtd->name = txx9_priv->mtdname;364 365 mtd_device_register(mtd, NULL, 0);366 drvdata->mtds[i] = mtd;367 }368 369 return 0;370}371 372static void txx9ndfmc_remove(struct platform_device *dev)373{374 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);375 int ret, i;376 377 for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {378 struct mtd_info *mtd = drvdata->mtds[i];379 struct nand_chip *chip;380 struct txx9ndfmc_priv *txx9_priv;381 382 if (!mtd)383 continue;384 chip = mtd_to_nand(mtd);385 txx9_priv = nand_get_controller_data(chip);386 387 ret = mtd_device_unregister(nand_to_mtd(chip));388 WARN_ON(ret);389 nand_cleanup(chip);390 kfree(txx9_priv->mtdname);391 kfree(txx9_priv);392 }393}394 395#ifdef CONFIG_PM396static int txx9ndfmc_resume(struct platform_device *dev)397{398 if (platform_get_drvdata(dev))399 txx9ndfmc_initialize(dev);400 return 0;401}402#else403#define txx9ndfmc_resume NULL404#endif405 406static struct platform_driver txx9ndfmc_driver = {407 .probe = txx9ndfmc_probe,408 .remove_new = txx9ndfmc_remove,409 .resume = txx9ndfmc_resume,410 .driver = {411 .name = "txx9ndfmc",412 },413};414module_platform_driver(txx9ndfmc_driver);415 416MODULE_LICENSE("GPL");417MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");418MODULE_ALIAS("platform:txx9ndfmc");419