s3c2410.c revision 9db41f9edcb87ae050fcb171c44be7f212728d54
1/* linux/drivers/mtd/nand/s3c2410.c 2 * 3 * Copyright © 2004-2008 Simtec Electronics 4 * http://armlinux.simtec.co.uk/ 5 * Ben Dooks <ben@simtec.co.uk> 6 * 7 * Samsung S3C2410/S3C2440/S3C2412 NAND driver 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22*/ 23 24#ifdef CONFIG_MTD_NAND_S3C2410_DEBUG 25#define DEBUG 26#endif 27 28#include <linux/module.h> 29#include <linux/types.h> 30#include <linux/init.h> 31#include <linux/kernel.h> 32#include <linux/string.h> 33#include <linux/ioport.h> 34#include <linux/platform_device.h> 35#include <linux/delay.h> 36#include <linux/err.h> 37#include <linux/slab.h> 38#include <linux/clk.h> 39#include <linux/cpufreq.h> 40 41#include <linux/mtd/mtd.h> 42#include <linux/mtd/nand.h> 43#include <linux/mtd/nand_ecc.h> 44#include <linux/mtd/partitions.h> 45 46#include <asm/io.h> 47 48#include <plat/regs-nand.h> 49#include <plat/nand.h> 50 51#ifdef CONFIG_MTD_NAND_S3C2410_HWECC 52static int hardware_ecc = 1; 53#else 54static int hardware_ecc = 0; 55#endif 56 57#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP 58static int clock_stop = 1; 59#else 60static const int clock_stop = 0; 61#endif 62 63 64/* new oob placement block for use with hardware ecc generation 65 */ 66 67static struct nand_ecclayout nand_hw_eccoob = { 68 .eccbytes = 3, 69 .eccpos = {0, 1, 2}, 70 .oobfree = {{8, 8}} 71}; 72 73/* controller and mtd information */ 74 75struct s3c2410_nand_info; 76 77/** 78 * struct s3c2410_nand_mtd - driver MTD structure 79 * @mtd: The MTD instance to pass to the MTD layer. 80 * @chip: The NAND chip information. 81 * @set: The platform information supplied for this set of NAND chips. 82 * @info: Link back to the hardware information. 83 * @scan_res: The result from calling nand_scan_ident(). 84*/ 85struct s3c2410_nand_mtd { 86 struct mtd_info mtd; 87 struct nand_chip chip; 88 struct s3c2410_nand_set *set; 89 struct s3c2410_nand_info *info; 90 int scan_res; 91}; 92 93enum s3c_cpu_type { 94 TYPE_S3C2410, 95 TYPE_S3C2412, 96 TYPE_S3C2440, 97}; 98 99/* overview of the s3c2410 nand state */ 100 101/** 102 * struct s3c2410_nand_info - NAND controller state. 103 * @mtds: An array of MTD instances on this controoler. 104 * @platform: The platform data for this board. 105 * @device: The platform device we bound to. 106 * @area: The IO area resource that came from request_mem_region(). 107 * @clk: The clock resource for this controller. 108 * @regs: The area mapped for the hardware registers described by @area. 109 * @sel_reg: Pointer to the register controlling the NAND selection. 110 * @sel_bit: The bit in @sel_reg to select the NAND chip. 111 * @mtd_count: The number of MTDs created from this controller. 112 * @save_sel: The contents of @sel_reg to be saved over suspend. 113 * @clk_rate: The clock rate from @clk. 114 * @cpu_type: The exact type of this controller. 115 */ 116struct s3c2410_nand_info { 117 /* mtd info */ 118 struct nand_hw_control controller; 119 struct s3c2410_nand_mtd *mtds; 120 struct s3c2410_platform_nand *platform; 121 122 /* device info */ 123 struct device *device; 124 struct resource *area; 125 struct clk *clk; 126 void __iomem *regs; 127 void __iomem *sel_reg; 128 int sel_bit; 129 int mtd_count; 130 unsigned long save_sel; 131 unsigned long clk_rate; 132 133 enum s3c_cpu_type cpu_type; 134 135#ifdef CONFIG_CPU_FREQ 136 struct notifier_block freq_transition; 137#endif 138}; 139 140/* conversion functions */ 141 142static struct s3c2410_nand_mtd *s3c2410_nand_mtd_toours(struct mtd_info *mtd) 143{ 144 return container_of(mtd, struct s3c2410_nand_mtd, mtd); 145} 146 147static struct s3c2410_nand_info *s3c2410_nand_mtd_toinfo(struct mtd_info *mtd) 148{ 149 return s3c2410_nand_mtd_toours(mtd)->info; 150} 151 152static struct s3c2410_nand_info *to_nand_info(struct platform_device *dev) 153{ 154 return platform_get_drvdata(dev); 155} 156 157static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) 158{ 159 return dev->dev.platform_data; 160} 161 162static inline int allow_clk_stop(struct s3c2410_nand_info *info) 163{ 164 return clock_stop; 165} 166 167/* timing calculations */ 168 169#define NS_IN_KHZ 1000000 170 171/** 172 * s3c_nand_calc_rate - calculate timing data. 173 * @wanted: The cycle time in nanoseconds. 174 * @clk: The clock rate in kHz. 175 * @max: The maximum divider value. 176 * 177 * Calculate the timing value from the given parameters. 178 */ 179static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) 180{ 181 int result; 182 183 result = (wanted * clk) / NS_IN_KHZ; 184 result++; 185 186 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 187 188 if (result > max) { 189 printk("%d ns is too big for current clock rate %ld\n", wanted, clk); 190 return -1; 191 } 192 193 if (result < 1) 194 result = 1; 195 196 return result; 197} 198 199#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk)) 200 201/* controller setup */ 202 203/** 204 * s3c2410_nand_setrate - setup controller timing information. 205 * @info: The controller instance. 206 * 207 * Given the information supplied by the platform, calculate and set 208 * the necessary timing registers in the hardware to generate the 209 * necessary timing cycles to the hardware. 210 */ 211static int s3c2410_nand_setrate(struct s3c2410_nand_info *info) 212{ 213 struct s3c2410_platform_nand *plat = info->platform; 214 int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; 215 int tacls, twrph0, twrph1; 216 unsigned long clkrate = clk_get_rate(info->clk); 217 unsigned long uninitialized_var(set), cfg, uninitialized_var(mask); 218 unsigned long flags; 219 220 /* calculate the timing information for the controller */ 221 222 info->clk_rate = clkrate; 223 clkrate /= 1000; /* turn clock into kHz for ease of use */ 224 225 if (plat != NULL) { 226 tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max); 227 twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8); 228 twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8); 229 } else { 230 /* default timings */ 231 tacls = tacls_max; 232 twrph0 = 8; 233 twrph1 = 8; 234 } 235 236 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { 237 dev_err(info->device, "cannot get suitable timings\n"); 238 return -EINVAL; 239 } 240 241 dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", 242 tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); 243 244 switch (info->cpu_type) { 245 case TYPE_S3C2410: 246 mask = (S3C2410_NFCONF_TACLS(3) | 247 S3C2410_NFCONF_TWRPH0(7) | 248 S3C2410_NFCONF_TWRPH1(7)); 249 set = S3C2410_NFCONF_EN; 250 set |= S3C2410_NFCONF_TACLS(tacls - 1); 251 set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); 252 set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); 253 break; 254 255 case TYPE_S3C2440: 256 case TYPE_S3C2412: 257 mask = (S3C2410_NFCONF_TACLS(tacls_max - 1) | 258 S3C2410_NFCONF_TWRPH0(7) | 259 S3C2410_NFCONF_TWRPH1(7)); 260 261 set = S3C2440_NFCONF_TACLS(tacls - 1); 262 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); 263 set |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); 264 break; 265 266 default: 267 BUG(); 268 } 269 270 local_irq_save(flags); 271 272 cfg = readl(info->regs + S3C2410_NFCONF); 273 cfg &= ~mask; 274 cfg |= set; 275 writel(cfg, info->regs + S3C2410_NFCONF); 276 277 local_irq_restore(flags); 278 279 dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); 280 281 return 0; 282} 283 284/** 285 * s3c2410_nand_inithw - basic hardware initialisation 286 * @info: The hardware state. 287 * 288 * Do the basic initialisation of the hardware, using s3c2410_nand_setrate() 289 * to setup the hardware access speeds and set the controller to be enabled. 290*/ 291static int s3c2410_nand_inithw(struct s3c2410_nand_info *info) 292{ 293 int ret; 294 295 ret = s3c2410_nand_setrate(info); 296 if (ret < 0) 297 return ret; 298 299 switch (info->cpu_type) { 300 case TYPE_S3C2410: 301 default: 302 break; 303 304 case TYPE_S3C2440: 305 case TYPE_S3C2412: 306 /* enable the controller and de-assert nFCE */ 307 308 writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); 309 } 310 311 return 0; 312} 313 314/** 315 * s3c2410_nand_select_chip - select the given nand chip 316 * @mtd: The MTD instance for this chip. 317 * @chip: The chip number. 318 * 319 * This is called by the MTD layer to either select a given chip for the 320 * @mtd instance, or to indicate that the access has finished and the 321 * chip can be de-selected. 322 * 323 * The routine ensures that the nFCE line is correctly setup, and any 324 * platform specific selection code is called to route nFCE to the specific 325 * chip. 326 */ 327static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) 328{ 329 struct s3c2410_nand_info *info; 330 struct s3c2410_nand_mtd *nmtd; 331 struct nand_chip *this = mtd->priv; 332 unsigned long cur; 333 334 nmtd = this->priv; 335 info = nmtd->info; 336 337 if (chip != -1 && allow_clk_stop(info)) 338 clk_enable(info->clk); 339 340 cur = readl(info->sel_reg); 341 342 if (chip == -1) { 343 cur |= info->sel_bit; 344 } else { 345 if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { 346 dev_err(info->device, "invalid chip %d\n", chip); 347 return; 348 } 349 350 if (info->platform != NULL) { 351 if (info->platform->select_chip != NULL) 352 (info->platform->select_chip) (nmtd->set, chip); 353 } 354 355 cur &= ~info->sel_bit; 356 } 357 358 writel(cur, info->sel_reg); 359 360 if (chip == -1 && allow_clk_stop(info)) 361 clk_disable(info->clk); 362} 363 364/* s3c2410_nand_hwcontrol 365 * 366 * Issue command and address cycles to the chip 367*/ 368 369static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd, 370 unsigned int ctrl) 371{ 372 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 373 374 if (cmd == NAND_CMD_NONE) 375 return; 376 377 if (ctrl & NAND_CLE) 378 writeb(cmd, info->regs + S3C2410_NFCMD); 379 else 380 writeb(cmd, info->regs + S3C2410_NFADDR); 381} 382 383/* command and control functions */ 384 385static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd, 386 unsigned int ctrl) 387{ 388 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 389 390 if (cmd == NAND_CMD_NONE) 391 return; 392 393 if (ctrl & NAND_CLE) 394 writeb(cmd, info->regs + S3C2440_NFCMD); 395 else 396 writeb(cmd, info->regs + S3C2440_NFADDR); 397} 398 399/* s3c2410_nand_devready() 400 * 401 * returns 0 if the nand is busy, 1 if it is ready 402*/ 403 404static int s3c2410_nand_devready(struct mtd_info *mtd) 405{ 406 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 407 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; 408} 409 410static int s3c2440_nand_devready(struct mtd_info *mtd) 411{ 412 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 413 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; 414} 415 416static int s3c2412_nand_devready(struct mtd_info *mtd) 417{ 418 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 419 return readb(info->regs + S3C2412_NFSTAT) & S3C2412_NFSTAT_READY; 420} 421 422/* ECC handling functions */ 423 424static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, 425 u_char *read_ecc, u_char *calc_ecc) 426{ 427 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 428 unsigned int diff0, diff1, diff2; 429 unsigned int bit, byte; 430 431 pr_debug("%s(%p,%p,%p,%p)\n", __func__, mtd, dat, read_ecc, calc_ecc); 432 433 diff0 = read_ecc[0] ^ calc_ecc[0]; 434 diff1 = read_ecc[1] ^ calc_ecc[1]; 435 diff2 = read_ecc[2] ^ calc_ecc[2]; 436 437 pr_debug("%s: rd %02x%02x%02x calc %02x%02x%02x diff %02x%02x%02x\n", 438 __func__, 439 read_ecc[0], read_ecc[1], read_ecc[2], 440 calc_ecc[0], calc_ecc[1], calc_ecc[2], 441 diff0, diff1, diff2); 442 443 if (diff0 == 0 && diff1 == 0 && diff2 == 0) 444 return 0; /* ECC is ok */ 445 446 /* sometimes people do not think about using the ECC, so check 447 * to see if we have an 0xff,0xff,0xff read ECC and then ignore 448 * the error, on the assumption that this is an un-eccd page. 449 */ 450 if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff 451 && info->platform->ignore_unset_ecc) 452 return 0; 453 454 /* Can we correct this ECC (ie, one row and column change). 455 * Note, this is similar to the 256 error code on smartmedia */ 456 457 if (((diff0 ^ (diff0 >> 1)) & 0x55) == 0x55 && 458 ((diff1 ^ (diff1 >> 1)) & 0x55) == 0x55 && 459 ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) { 460 /* calculate the bit position of the error */ 461 462 bit = ((diff2 >> 3) & 1) | 463 ((diff2 >> 4) & 2) | 464 ((diff2 >> 5) & 4); 465 466 /* calculate the byte position of the error */ 467 468 byte = ((diff2 << 7) & 0x100) | 469 ((diff1 << 0) & 0x80) | 470 ((diff1 << 1) & 0x40) | 471 ((diff1 << 2) & 0x20) | 472 ((diff1 << 3) & 0x10) | 473 ((diff0 >> 4) & 0x08) | 474 ((diff0 >> 3) & 0x04) | 475 ((diff0 >> 2) & 0x02) | 476 ((diff0 >> 1) & 0x01); 477 478 dev_dbg(info->device, "correcting error bit %d, byte %d\n", 479 bit, byte); 480 481 dat[byte] ^= (1 << bit); 482 return 1; 483 } 484 485 /* if there is only one bit difference in the ECC, then 486 * one of only a row or column parity has changed, which 487 * means the error is most probably in the ECC itself */ 488 489 diff0 |= (diff1 << 8); 490 diff0 |= (diff2 << 16); 491 492 if ((diff0 & ~(1<<fls(diff0))) == 0) 493 return 1; 494 495 return -1; 496} 497 498/* ECC functions 499 * 500 * These allow the s3c2410 and s3c2440 to use the controller's ECC 501 * generator block to ECC the data as it passes through] 502*/ 503 504static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) 505{ 506 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 507 unsigned long ctrl; 508 509 ctrl = readl(info->regs + S3C2410_NFCONF); 510 ctrl |= S3C2410_NFCONF_INITECC; 511 writel(ctrl, info->regs + S3C2410_NFCONF); 512} 513 514static void s3c2412_nand_enable_hwecc(struct mtd_info *mtd, int mode) 515{ 516 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 517 unsigned long ctrl; 518 519 ctrl = readl(info->regs + S3C2440_NFCONT); 520 writel(ctrl | S3C2412_NFCONT_INIT_MAIN_ECC, info->regs + S3C2440_NFCONT); 521} 522 523static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode) 524{ 525 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 526 unsigned long ctrl; 527 528 ctrl = readl(info->regs + S3C2440_NFCONT); 529 writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT); 530} 531 532static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) 533{ 534 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 535 536 ecc_code[0] = readb(info->regs + S3C2410_NFECC + 0); 537 ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1); 538 ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2); 539 540 pr_debug("%s: returning ecc %02x%02x%02x\n", __func__, 541 ecc_code[0], ecc_code[1], ecc_code[2]); 542 543 return 0; 544} 545 546static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) 547{ 548 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 549 unsigned long ecc = readl(info->regs + S3C2412_NFMECC0); 550 551 ecc_code[0] = ecc; 552 ecc_code[1] = ecc >> 8; 553 ecc_code[2] = ecc >> 16; 554 555 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]); 556 557 return 0; 558} 559 560static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) 561{ 562 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 563 unsigned long ecc = readl(info->regs + S3C2440_NFMECC0); 564 565 ecc_code[0] = ecc; 566 ecc_code[1] = ecc >> 8; 567 ecc_code[2] = ecc >> 16; 568 569 pr_debug("%s: returning ecc %06lx\n", __func__, ecc & 0xffffff); 570 571 return 0; 572} 573 574/* over-ride the standard functions for a little more speed. We can 575 * use read/write block to move the data buffers to/from the controller 576*/ 577 578static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 579{ 580 struct nand_chip *this = mtd->priv; 581 readsb(this->IO_ADDR_R, buf, len); 582} 583 584static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 585{ 586 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 587 readsl(info->regs + S3C2440_NFDATA, buf, len / 4); 588} 589 590static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 591{ 592 struct nand_chip *this = mtd->priv; 593 writesb(this->IO_ADDR_W, buf, len); 594} 595 596static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 597{ 598 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 599 writesl(info->regs + S3C2440_NFDATA, buf, len / 4); 600} 601 602/* cpufreq driver support */ 603 604#ifdef CONFIG_CPU_FREQ 605 606static int s3c2410_nand_cpufreq_transition(struct notifier_block *nb, 607 unsigned long val, void *data) 608{ 609 struct s3c2410_nand_info *info; 610 unsigned long newclk; 611 612 info = container_of(nb, struct s3c2410_nand_info, freq_transition); 613 newclk = clk_get_rate(info->clk); 614 615 if ((val == CPUFREQ_POSTCHANGE && newclk < info->clk_rate) || 616 (val == CPUFREQ_PRECHANGE && newclk > info->clk_rate)) { 617 s3c2410_nand_setrate(info); 618 } 619 620 return 0; 621} 622 623static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info) 624{ 625 info->freq_transition.notifier_call = s3c2410_nand_cpufreq_transition; 626 627 return cpufreq_register_notifier(&info->freq_transition, 628 CPUFREQ_TRANSITION_NOTIFIER); 629} 630 631static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info) 632{ 633 cpufreq_unregister_notifier(&info->freq_transition, 634 CPUFREQ_TRANSITION_NOTIFIER); 635} 636 637#else 638static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info) 639{ 640 return 0; 641} 642 643static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info) 644{ 645} 646#endif 647 648/* device management functions */ 649 650static int s3c24xx_nand_remove(struct platform_device *pdev) 651{ 652 struct s3c2410_nand_info *info = to_nand_info(pdev); 653 654 platform_set_drvdata(pdev, NULL); 655 656 if (info == NULL) 657 return 0; 658 659 s3c2410_nand_cpufreq_deregister(info); 660 661 /* Release all our mtds and their partitions, then go through 662 * freeing the resources used 663 */ 664 665 if (info->mtds != NULL) { 666 struct s3c2410_nand_mtd *ptr = info->mtds; 667 int mtdno; 668 669 for (mtdno = 0; mtdno < info->mtd_count; mtdno++, ptr++) { 670 pr_debug("releasing mtd %d (%p)\n", mtdno, ptr); 671 nand_release(&ptr->mtd); 672 } 673 674 kfree(info->mtds); 675 } 676 677 /* free the common resources */ 678 679 if (info->clk != NULL && !IS_ERR(info->clk)) { 680 if (!allow_clk_stop(info)) 681 clk_disable(info->clk); 682 clk_put(info->clk); 683 } 684 685 if (info->regs != NULL) { 686 iounmap(info->regs); 687 info->regs = NULL; 688 } 689 690 if (info->area != NULL) { 691 release_resource(info->area); 692 kfree(info->area); 693 info->area = NULL; 694 } 695 696 kfree(info); 697 698 return 0; 699} 700 701#ifdef CONFIG_MTD_PARTITIONS 702const char *part_probes[] = { "cmdlinepart", NULL }; 703static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, 704 struct s3c2410_nand_mtd *mtd, 705 struct s3c2410_nand_set *set) 706{ 707 struct mtd_partition *part_info; 708 int nr_part = 0; 709 710 if (set == NULL) 711 return add_mtd_device(&mtd->mtd); 712 713 if (set->nr_partitions == 0) { 714 mtd->mtd.name = set->name; 715 nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, 716 &part_info, 0); 717 } else { 718 if (set->nr_partitions > 0 && set->partitions != NULL) { 719 nr_part = set->nr_partitions; 720 part_info = set->partitions; 721 } 722 } 723 724 if (nr_part > 0 && part_info) 725 return add_mtd_partitions(&mtd->mtd, part_info, nr_part); 726 727 return add_mtd_device(&mtd->mtd); 728} 729#else 730static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, 731 struct s3c2410_nand_mtd *mtd, 732 struct s3c2410_nand_set *set) 733{ 734 return add_mtd_device(&mtd->mtd); 735} 736#endif 737 738/** 739 * s3c2410_nand_init_chip - initialise a single instance of an chip 740 * @info: The base NAND controller the chip is on. 741 * @nmtd: The new controller MTD instance to fill in. 742 * @set: The information passed from the board specific platform data. 743 * 744 * Initialise the given @nmtd from the information in @info and @set. This 745 * readies the structure for use with the MTD layer functions by ensuring 746 * all pointers are setup and the necessary control routines selected. 747 */ 748static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, 749 struct s3c2410_nand_mtd *nmtd, 750 struct s3c2410_nand_set *set) 751{ 752 struct nand_chip *chip = &nmtd->chip; 753 void __iomem *regs = info->regs; 754 755 chip->write_buf = s3c2410_nand_write_buf; 756 chip->read_buf = s3c2410_nand_read_buf; 757 chip->select_chip = s3c2410_nand_select_chip; 758 chip->chip_delay = 50; 759 chip->priv = nmtd; 760 chip->options = 0; 761 chip->controller = &info->controller; 762 763 switch (info->cpu_type) { 764 case TYPE_S3C2410: 765 chip->IO_ADDR_W = regs + S3C2410_NFDATA; 766 info->sel_reg = regs + S3C2410_NFCONF; 767 info->sel_bit = S3C2410_NFCONF_nFCE; 768 chip->cmd_ctrl = s3c2410_nand_hwcontrol; 769 chip->dev_ready = s3c2410_nand_devready; 770 break; 771 772 case TYPE_S3C2440: 773 chip->IO_ADDR_W = regs + S3C2440_NFDATA; 774 info->sel_reg = regs + S3C2440_NFCONT; 775 info->sel_bit = S3C2440_NFCONT_nFCE; 776 chip->cmd_ctrl = s3c2440_nand_hwcontrol; 777 chip->dev_ready = s3c2440_nand_devready; 778 chip->read_buf = s3c2440_nand_read_buf; 779 chip->write_buf = s3c2440_nand_write_buf; 780 break; 781 782 case TYPE_S3C2412: 783 chip->IO_ADDR_W = regs + S3C2440_NFDATA; 784 info->sel_reg = regs + S3C2440_NFCONT; 785 info->sel_bit = S3C2412_NFCONT_nFCE0; 786 chip->cmd_ctrl = s3c2440_nand_hwcontrol; 787 chip->dev_ready = s3c2412_nand_devready; 788 789 if (readl(regs + S3C2410_NFCONF) & S3C2412_NFCONF_NANDBOOT) 790 dev_info(info->device, "System booted from NAND\n"); 791 792 break; 793 } 794 795 chip->IO_ADDR_R = chip->IO_ADDR_W; 796 797 nmtd->info = info; 798 nmtd->mtd.priv = chip; 799 nmtd->mtd.owner = THIS_MODULE; 800 nmtd->set = set; 801 802 if (hardware_ecc) { 803 chip->ecc.calculate = s3c2410_nand_calculate_ecc; 804 chip->ecc.correct = s3c2410_nand_correct_data; 805 chip->ecc.mode = NAND_ECC_HW; 806 807 switch (info->cpu_type) { 808 case TYPE_S3C2410: 809 chip->ecc.hwctl = s3c2410_nand_enable_hwecc; 810 chip->ecc.calculate = s3c2410_nand_calculate_ecc; 811 break; 812 813 case TYPE_S3C2412: 814 chip->ecc.hwctl = s3c2412_nand_enable_hwecc; 815 chip->ecc.calculate = s3c2412_nand_calculate_ecc; 816 break; 817 818 case TYPE_S3C2440: 819 chip->ecc.hwctl = s3c2440_nand_enable_hwecc; 820 chip->ecc.calculate = s3c2440_nand_calculate_ecc; 821 break; 822 823 } 824 } else { 825 chip->ecc.mode = NAND_ECC_SOFT; 826 } 827 828 if (set->ecc_layout != NULL) 829 chip->ecc.layout = set->ecc_layout; 830 831 if (set->disable_ecc) 832 chip->ecc.mode = NAND_ECC_NONE; 833 834 switch (chip->ecc.mode) { 835 case NAND_ECC_NONE: 836 dev_info(info->device, "NAND ECC disabled\n"); 837 break; 838 case NAND_ECC_SOFT: 839 dev_info(info->device, "NAND soft ECC\n"); 840 break; 841 case NAND_ECC_HW: 842 dev_info(info->device, "NAND hardware ECC\n"); 843 break; 844 default: 845 dev_info(info->device, "NAND ECC UNKNOWN\n"); 846 break; 847 } 848 849 /* If you use u-boot BBT creation code, specifying this flag will 850 * let the kernel fish out the BBT from the NAND, and also skip the 851 * full NAND scan that can take 1/2s or so. Little things... */ 852 if (set->flash_bbt) 853 chip->options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN; 854} 855 856/** 857 * s3c2410_nand_update_chip - post probe update 858 * @info: The controller instance. 859 * @nmtd: The driver version of the MTD instance. 860 * 861 * This routine is called after the chip probe has succesfully completed 862 * and the relevant per-chip information updated. This call ensure that 863 * we update the internal state accordingly. 864 * 865 * The internal state is currently limited to the ECC state information. 866*/ 867static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, 868 struct s3c2410_nand_mtd *nmtd) 869{ 870 struct nand_chip *chip = &nmtd->chip; 871 872 dev_dbg(info->device, "chip %p => page shift %d\n", 873 chip, chip->page_shift); 874 875 if (chip->ecc.mode != NAND_ECC_HW) 876 return; 877 878 /* change the behaviour depending on wether we are using 879 * the large or small page nand device */ 880 881 if (chip->page_shift > 10) { 882 chip->ecc.size = 256; 883 chip->ecc.bytes = 3; 884 } else { 885 chip->ecc.size = 512; 886 chip->ecc.bytes = 3; 887 chip->ecc.layout = &nand_hw_eccoob; 888 } 889} 890 891/* s3c24xx_nand_probe 892 * 893 * called by device layer when it finds a device matching 894 * one our driver can handled. This code checks to see if 895 * it can allocate all necessary resources then calls the 896 * nand layer to look for devices 897*/ 898static int s3c24xx_nand_probe(struct platform_device *pdev) 899{ 900 struct s3c2410_platform_nand *plat = to_nand_plat(pdev); 901 enum s3c_cpu_type cpu_type; 902 struct s3c2410_nand_info *info; 903 struct s3c2410_nand_mtd *nmtd; 904 struct s3c2410_nand_set *sets; 905 struct resource *res; 906 int err = 0; 907 int size; 908 int nr_sets; 909 int setno; 910 911 cpu_type = platform_get_device_id(pdev)->driver_data; 912 913 pr_debug("s3c2410_nand_probe(%p)\n", pdev); 914 915 info = kmalloc(sizeof(*info), GFP_KERNEL); 916 if (info == NULL) { 917 dev_err(&pdev->dev, "no memory for flash info\n"); 918 err = -ENOMEM; 919 goto exit_error; 920 } 921 922 memset(info, 0, sizeof(*info)); 923 platform_set_drvdata(pdev, info); 924 925 spin_lock_init(&info->controller.lock); 926 init_waitqueue_head(&info->controller.wq); 927 928 /* get the clock source and enable it */ 929 930 info->clk = clk_get(&pdev->dev, "nand"); 931 if (IS_ERR(info->clk)) { 932 dev_err(&pdev->dev, "failed to get clock\n"); 933 err = -ENOENT; 934 goto exit_error; 935 } 936 937 clk_enable(info->clk); 938 939 /* allocate and map the resource */ 940 941 /* currently we assume we have the one resource */ 942 res = pdev->resource; 943 size = res->end - res->start + 1; 944 945 info->area = request_mem_region(res->start, size, pdev->name); 946 947 if (info->area == NULL) { 948 dev_err(&pdev->dev, "cannot reserve register region\n"); 949 err = -ENOENT; 950 goto exit_error; 951 } 952 953 info->device = &pdev->dev; 954 info->platform = plat; 955 info->regs = ioremap(res->start, size); 956 info->cpu_type = cpu_type; 957 958 if (info->regs == NULL) { 959 dev_err(&pdev->dev, "cannot reserve register region\n"); 960 err = -EIO; 961 goto exit_error; 962 } 963 964 dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs); 965 966 /* initialise the hardware */ 967 968 err = s3c2410_nand_inithw(info); 969 if (err != 0) 970 goto exit_error; 971 972 sets = (plat != NULL) ? plat->sets : NULL; 973 nr_sets = (plat != NULL) ? plat->nr_sets : 1; 974 975 info->mtd_count = nr_sets; 976 977 /* allocate our information */ 978 979 size = nr_sets * sizeof(*info->mtds); 980 info->mtds = kmalloc(size, GFP_KERNEL); 981 if (info->mtds == NULL) { 982 dev_err(&pdev->dev, "failed to allocate mtd storage\n"); 983 err = -ENOMEM; 984 goto exit_error; 985 } 986 987 memset(info->mtds, 0, size); 988 989 /* initialise all possible chips */ 990 991 nmtd = info->mtds; 992 993 for (setno = 0; setno < nr_sets; setno++, nmtd++) { 994 pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info); 995 996 s3c2410_nand_init_chip(info, nmtd, sets); 997 998 nmtd->scan_res = nand_scan_ident(&nmtd->mtd, 999 (sets) ? sets->nr_chips : 1); 1000 1001 if (nmtd->scan_res == 0) { 1002 s3c2410_nand_update_chip(info, nmtd); 1003 nand_scan_tail(&nmtd->mtd); 1004 s3c2410_nand_add_partition(info, nmtd, sets); 1005 } 1006 1007 if (sets != NULL) 1008 sets++; 1009 } 1010 1011 err = s3c2410_nand_cpufreq_register(info); 1012 if (err < 0) { 1013 dev_err(&pdev->dev, "failed to init cpufreq support\n"); 1014 goto exit_error; 1015 } 1016 1017 if (allow_clk_stop(info)) { 1018 dev_info(&pdev->dev, "clock idle support enabled\n"); 1019 clk_disable(info->clk); 1020 } 1021 1022 pr_debug("initialised ok\n"); 1023 return 0; 1024 1025 exit_error: 1026 s3c24xx_nand_remove(pdev); 1027 1028 if (err == 0) 1029 err = -EINVAL; 1030 return err; 1031} 1032 1033/* PM Support */ 1034#ifdef CONFIG_PM 1035 1036static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) 1037{ 1038 struct s3c2410_nand_info *info = platform_get_drvdata(dev); 1039 1040 if (info) { 1041 info->save_sel = readl(info->sel_reg); 1042 1043 /* For the moment, we must ensure nFCE is high during 1044 * the time we are suspended. This really should be 1045 * handled by suspending the MTDs we are using, but 1046 * that is currently not the case. */ 1047 1048 writel(info->save_sel | info->sel_bit, info->sel_reg); 1049 1050 if (!allow_clk_stop(info)) 1051 clk_disable(info->clk); 1052 } 1053 1054 return 0; 1055} 1056 1057static int s3c24xx_nand_resume(struct platform_device *dev) 1058{ 1059 struct s3c2410_nand_info *info = platform_get_drvdata(dev); 1060 unsigned long sel; 1061 1062 if (info) { 1063 clk_enable(info->clk); 1064 s3c2410_nand_inithw(info); 1065 1066 /* Restore the state of the nFCE line. */ 1067 1068 sel = readl(info->sel_reg); 1069 sel &= ~info->sel_bit; 1070 sel |= info->save_sel & info->sel_bit; 1071 writel(sel, info->sel_reg); 1072 1073 if (allow_clk_stop(info)) 1074 clk_disable(info->clk); 1075 } 1076 1077 return 0; 1078} 1079 1080#else 1081#define s3c24xx_nand_suspend NULL 1082#define s3c24xx_nand_resume NULL 1083#endif 1084 1085/* driver device registration */ 1086 1087static struct platform_device_id s3c24xx_driver_ids[] = { 1088 { 1089 .name = "s3c2410-nand", 1090 .driver_data = TYPE_S3C2410, 1091 }, { 1092 .name = "s3c2440-nand", 1093 .driver_data = TYPE_S3C2440, 1094 }, { 1095 .name = "s3c2412-nand", 1096 .driver_data = TYPE_S3C2412, 1097 }, 1098 { } 1099}; 1100 1101MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids); 1102 1103static struct platform_driver s3c24xx_nand_driver = { 1104 .probe = s3c24xx_nand_probe, 1105 .remove = s3c24xx_nand_remove, 1106 .suspend = s3c24xx_nand_suspend, 1107 .resume = s3c24xx_nand_resume, 1108 .id_table = s3c24xx_driver_ids, 1109 .driver = { 1110 .name = "s3c24xx-nand", 1111 .owner = THIS_MODULE, 1112 }, 1113}; 1114 1115static int __init s3c2410_nand_init(void) 1116{ 1117 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); 1118 1119 return platform_driver_register(&s3c24xx_nand_driver); 1120} 1121 1122static void __exit s3c2410_nand_exit(void) 1123{ 1124 platform_driver_unregister(&s3c24xx_nand_driver); 1125} 1126 1127module_init(s3c2410_nand_init); 1128module_exit(s3c2410_nand_exit); 1129 1130MODULE_LICENSE("GPL"); 1131MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 1132MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); 1133