txx9ndfmc.c (11554B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * TXx9 NAND flash memory controller driver 4 * Based on RBTX49xx patch from CELF patch archive. 5 * 6 * (C) Copyright TOSHIBA CORPORATION 2004-2007 7 * 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 0x00 23#define TXX9_NDFMCR 0x04 24#define TXX9_NDFSR 0x08 25#define TXX9_NDFISR 0x0c 26#define TXX9_NDFIMR 0x10 27#define TXX9_NDFSPR 0x14 28#define TXX9_NDFRSTR 0x18 /* not TX4939 */ 29 30/* NDFMCR : NDFMC Mode Control */ 31#define TXX9_NDFMCR_WE 0x80 32#define TXX9_NDFMCR_ECC_ALL 0x60 33#define TXX9_NDFMCR_ECC_RESET 0x60 34#define TXX9_NDFMCR_ECC_READ 0x40 35#define TXX9_NDFMCR_ECC_ON 0x20 36#define TXX9_NDFMCR_ECC_OFF 0x00 37#define TXX9_NDFMCR_CE 0x10 38#define TXX9_NDFMCR_BSPRT 0x04 /* TX4925/TX4926 only */ 39#define TXX9_NDFMCR_ALE 0x02 40#define TXX9_NDFMCR_CLE 0x01 41/* TX4939 only */ 42#define TXX9_NDFMCR_X16 0x0400 43#define TXX9_NDFMCR_DMAREQ_MASK 0x0300 44#define TXX9_NDFMCR_DMAREQ_NODMA 0x0000 45#define TXX9_NDFMCR_DMAREQ_128 0x0100 46#define TXX9_NDFMCR_DMAREQ_256 0x0200 47#define TXX9_NDFMCR_DMAREQ_512 0x0300 48#define TXX9_NDFMCR_CS_MASK 0x0c 49#define TXX9_NDFMCR_CS(ch) ((ch) << 2) 50 51/* NDFMCR : NDFMC Status */ 52#define TXX9_NDFSR_BUSY 0x80 53/* TX4939 only */ 54#define TXX9_NDFSR_DMARUN 0x40 55 56/* NDFMCR : NDFMC Reset */ 57#define TXX9_NDFRSTR_RST 0x01 58 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 4 67struct 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 __init 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 int __exit txx9ndfmc_remove(struct platform_device *dev) 373{ 374 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev); 375 int ret, i; 376 377 if (!drvdata) 378 return 0; 379 for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) { 380 struct mtd_info *mtd = drvdata->mtds[i]; 381 struct nand_chip *chip; 382 struct txx9ndfmc_priv *txx9_priv; 383 384 if (!mtd) 385 continue; 386 chip = mtd_to_nand(mtd); 387 txx9_priv = nand_get_controller_data(chip); 388 389 ret = mtd_device_unregister(nand_to_mtd(chip)); 390 WARN_ON(ret); 391 nand_cleanup(chip); 392 kfree(txx9_priv->mtdname); 393 kfree(txx9_priv); 394 } 395 return 0; 396} 397 398#ifdef CONFIG_PM 399static int txx9ndfmc_resume(struct platform_device *dev) 400{ 401 if (platform_get_drvdata(dev)) 402 txx9ndfmc_initialize(dev); 403 return 0; 404} 405#else 406#define txx9ndfmc_resume NULL 407#endif 408 409static struct platform_driver txx9ndfmc_driver = { 410 .remove = __exit_p(txx9ndfmc_remove), 411 .resume = txx9ndfmc_resume, 412 .driver = { 413 .name = "txx9ndfmc", 414 }, 415}; 416 417module_platform_driver_probe(txx9ndfmc_driver, txx9ndfmc_probe); 418 419MODULE_LICENSE("GPL"); 420MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver"); 421MODULE_ALIAS("platform:txx9ndfmc");