s3c2410.c revision ae7304e554642d57993b32265b817e6ae80787de
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 702static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, 703 struct s3c2410_nand_mtd *mtd, 704 struct s3c2410_nand_set *set) 705{ 706 if (set == NULL) 707 return add_mtd_device(&mtd->mtd); 708 709 if (set->nr_partitions > 0 && set->partitions != NULL) { 710 return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions); 711 } 712 713 return add_mtd_device(&mtd->mtd); 714} 715#else 716static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, 717 struct s3c2410_nand_mtd *mtd, 718 struct s3c2410_nand_set *set) 719{ 720 return add_mtd_device(&mtd->mtd); 721} 722#endif 723 724/** 725 * s3c2410_nand_init_chip - initialise a single instance of an chip 726 * @info: The base NAND controller the chip is on. 727 * @nmtd: The new controller MTD instance to fill in. 728 * @set: The information passed from the board specific platform data. 729 * 730 * Initialise the given @nmtd from the information in @info and @set. This 731 * readies the structure for use with the MTD layer functions by ensuring 732 * all pointers are setup and the necessary control routines selected. 733 */ 734static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, 735 struct s3c2410_nand_mtd *nmtd, 736 struct s3c2410_nand_set *set) 737{ 738 struct nand_chip *chip = &nmtd->chip; 739 void __iomem *regs = info->regs; 740 741 chip->write_buf = s3c2410_nand_write_buf; 742 chip->read_buf = s3c2410_nand_read_buf; 743 chip->select_chip = s3c2410_nand_select_chip; 744 chip->chip_delay = 50; 745 chip->priv = nmtd; 746 chip->options = 0; 747 chip->controller = &info->controller; 748 749 switch (info->cpu_type) { 750 case TYPE_S3C2410: 751 chip->IO_ADDR_W = regs + S3C2410_NFDATA; 752 info->sel_reg = regs + S3C2410_NFCONF; 753 info->sel_bit = S3C2410_NFCONF_nFCE; 754 chip->cmd_ctrl = s3c2410_nand_hwcontrol; 755 chip->dev_ready = s3c2410_nand_devready; 756 break; 757 758 case TYPE_S3C2440: 759 chip->IO_ADDR_W = regs + S3C2440_NFDATA; 760 info->sel_reg = regs + S3C2440_NFCONT; 761 info->sel_bit = S3C2440_NFCONT_nFCE; 762 chip->cmd_ctrl = s3c2440_nand_hwcontrol; 763 chip->dev_ready = s3c2440_nand_devready; 764 chip->read_buf = s3c2440_nand_read_buf; 765 chip->write_buf = s3c2440_nand_write_buf; 766 break; 767 768 case TYPE_S3C2412: 769 chip->IO_ADDR_W = regs + S3C2440_NFDATA; 770 info->sel_reg = regs + S3C2440_NFCONT; 771 info->sel_bit = S3C2412_NFCONT_nFCE0; 772 chip->cmd_ctrl = s3c2440_nand_hwcontrol; 773 chip->dev_ready = s3c2412_nand_devready; 774 775 if (readl(regs + S3C2410_NFCONF) & S3C2412_NFCONF_NANDBOOT) 776 dev_info(info->device, "System booted from NAND\n"); 777 778 break; 779 } 780 781 chip->IO_ADDR_R = chip->IO_ADDR_W; 782 783 nmtd->info = info; 784 nmtd->mtd.priv = chip; 785 nmtd->mtd.owner = THIS_MODULE; 786 nmtd->set = set; 787 788 if (hardware_ecc) { 789 chip->ecc.calculate = s3c2410_nand_calculate_ecc; 790 chip->ecc.correct = s3c2410_nand_correct_data; 791 chip->ecc.mode = NAND_ECC_HW; 792 793 switch (info->cpu_type) { 794 case TYPE_S3C2410: 795 chip->ecc.hwctl = s3c2410_nand_enable_hwecc; 796 chip->ecc.calculate = s3c2410_nand_calculate_ecc; 797 break; 798 799 case TYPE_S3C2412: 800 chip->ecc.hwctl = s3c2412_nand_enable_hwecc; 801 chip->ecc.calculate = s3c2412_nand_calculate_ecc; 802 break; 803 804 case TYPE_S3C2440: 805 chip->ecc.hwctl = s3c2440_nand_enable_hwecc; 806 chip->ecc.calculate = s3c2440_nand_calculate_ecc; 807 break; 808 809 } 810 } else { 811 chip->ecc.mode = NAND_ECC_SOFT; 812 } 813 814 if (set->ecc_layout != NULL) 815 chip->ecc.layout = set->ecc_layout; 816 817 if (set->disable_ecc) 818 chip->ecc.mode = NAND_ECC_NONE; 819 820 switch (chip->ecc.mode) { 821 case NAND_ECC_NONE: 822 dev_info(info->device, "NAND ECC disabled\n"); 823 break; 824 case NAND_ECC_SOFT: 825 dev_info(info->device, "NAND soft ECC\n"); 826 break; 827 case NAND_ECC_HW: 828 dev_info(info->device, "NAND hardware ECC\n"); 829 break; 830 default: 831 dev_info(info->device, "NAND ECC UNKNOWN\n"); 832 break; 833 } 834} 835 836/** 837 * s3c2410_nand_update_chip - post probe update 838 * @info: The controller instance. 839 * @nmtd: The driver version of the MTD instance. 840 * 841 * This routine is called after the chip probe has succesfully completed 842 * and the relevant per-chip information updated. This call ensure that 843 * we update the internal state accordingly. 844 * 845 * The internal state is currently limited to the ECC state information. 846*/ 847static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, 848 struct s3c2410_nand_mtd *nmtd) 849{ 850 struct nand_chip *chip = &nmtd->chip; 851 852 dev_dbg(info->device, "chip %p => page shift %d\n", 853 chip, chip->page_shift); 854 855 if (chip->ecc.mode != NAND_ECC_HW) 856 return; 857 858 /* change the behaviour depending on wether we are using 859 * the large or small page nand device */ 860 861 if (chip->page_shift > 10) { 862 chip->ecc.size = 256; 863 chip->ecc.bytes = 3; 864 } else { 865 chip->ecc.size = 512; 866 chip->ecc.bytes = 3; 867 chip->ecc.layout = &nand_hw_eccoob; 868 } 869} 870 871/* s3c24xx_nand_probe 872 * 873 * called by device layer when it finds a device matching 874 * one our driver can handled. This code checks to see if 875 * it can allocate all necessary resources then calls the 876 * nand layer to look for devices 877*/ 878static int s3c24xx_nand_probe(struct platform_device *pdev) 879{ 880 struct s3c2410_platform_nand *plat = to_nand_plat(pdev); 881 enum s3c_cpu_type cpu_type; 882 struct s3c2410_nand_info *info; 883 struct s3c2410_nand_mtd *nmtd; 884 struct s3c2410_nand_set *sets; 885 struct resource *res; 886 int err = 0; 887 int size; 888 int nr_sets; 889 int setno; 890 891 cpu_type = platform_get_device_id(pdev)->driver_data; 892 893 pr_debug("s3c2410_nand_probe(%p)\n", pdev); 894 895 info = kmalloc(sizeof(*info), GFP_KERNEL); 896 if (info == NULL) { 897 dev_err(&pdev->dev, "no memory for flash info\n"); 898 err = -ENOMEM; 899 goto exit_error; 900 } 901 902 memset(info, 0, sizeof(*info)); 903 platform_set_drvdata(pdev, info); 904 905 spin_lock_init(&info->controller.lock); 906 init_waitqueue_head(&info->controller.wq); 907 908 /* get the clock source and enable it */ 909 910 info->clk = clk_get(&pdev->dev, "nand"); 911 if (IS_ERR(info->clk)) { 912 dev_err(&pdev->dev, "failed to get clock\n"); 913 err = -ENOENT; 914 goto exit_error; 915 } 916 917 clk_enable(info->clk); 918 919 /* allocate and map the resource */ 920 921 /* currently we assume we have the one resource */ 922 res = pdev->resource; 923 size = res->end - res->start + 1; 924 925 info->area = request_mem_region(res->start, size, pdev->name); 926 927 if (info->area == NULL) { 928 dev_err(&pdev->dev, "cannot reserve register region\n"); 929 err = -ENOENT; 930 goto exit_error; 931 } 932 933 info->device = &pdev->dev; 934 info->platform = plat; 935 info->regs = ioremap(res->start, size); 936 info->cpu_type = cpu_type; 937 938 if (info->regs == NULL) { 939 dev_err(&pdev->dev, "cannot reserve register region\n"); 940 err = -EIO; 941 goto exit_error; 942 } 943 944 dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs); 945 946 /* initialise the hardware */ 947 948 err = s3c2410_nand_inithw(info); 949 if (err != 0) 950 goto exit_error; 951 952 sets = (plat != NULL) ? plat->sets : NULL; 953 nr_sets = (plat != NULL) ? plat->nr_sets : 1; 954 955 info->mtd_count = nr_sets; 956 957 /* allocate our information */ 958 959 size = nr_sets * sizeof(*info->mtds); 960 info->mtds = kmalloc(size, GFP_KERNEL); 961 if (info->mtds == NULL) { 962 dev_err(&pdev->dev, "failed to allocate mtd storage\n"); 963 err = -ENOMEM; 964 goto exit_error; 965 } 966 967 memset(info->mtds, 0, size); 968 969 /* initialise all possible chips */ 970 971 nmtd = info->mtds; 972 973 for (setno = 0; setno < nr_sets; setno++, nmtd++) { 974 pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info); 975 976 s3c2410_nand_init_chip(info, nmtd, sets); 977 978 nmtd->scan_res = nand_scan_ident(&nmtd->mtd, 979 (sets) ? sets->nr_chips : 1); 980 981 if (nmtd->scan_res == 0) { 982 s3c2410_nand_update_chip(info, nmtd); 983 nand_scan_tail(&nmtd->mtd); 984 s3c2410_nand_add_partition(info, nmtd, sets); 985 } 986 987 if (sets != NULL) 988 sets++; 989 } 990 991 err = s3c2410_nand_cpufreq_register(info); 992 if (err < 0) { 993 dev_err(&pdev->dev, "failed to init cpufreq support\n"); 994 goto exit_error; 995 } 996 997 if (allow_clk_stop(info)) { 998 dev_info(&pdev->dev, "clock idle support enabled\n"); 999 clk_disable(info->clk); 1000 } 1001 1002 pr_debug("initialised ok\n"); 1003 return 0; 1004 1005 exit_error: 1006 s3c24xx_nand_remove(pdev); 1007 1008 if (err == 0) 1009 err = -EINVAL; 1010 return err; 1011} 1012 1013/* PM Support */ 1014#ifdef CONFIG_PM 1015 1016static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) 1017{ 1018 struct s3c2410_nand_info *info = platform_get_drvdata(dev); 1019 1020 if (info) { 1021 info->save_sel = readl(info->sel_reg); 1022 1023 /* For the moment, we must ensure nFCE is high during 1024 * the time we are suspended. This really should be 1025 * handled by suspending the MTDs we are using, but 1026 * that is currently not the case. */ 1027 1028 writel(info->save_sel | info->sel_bit, info->sel_reg); 1029 1030 if (!allow_clk_stop(info)) 1031 clk_disable(info->clk); 1032 } 1033 1034 return 0; 1035} 1036 1037static int s3c24xx_nand_resume(struct platform_device *dev) 1038{ 1039 struct s3c2410_nand_info *info = platform_get_drvdata(dev); 1040 unsigned long sel; 1041 1042 if (info) { 1043 clk_enable(info->clk); 1044 s3c2410_nand_inithw(info); 1045 1046 /* Restore the state of the nFCE line. */ 1047 1048 sel = readl(info->sel_reg); 1049 sel &= ~info->sel_bit; 1050 sel |= info->save_sel & info->sel_bit; 1051 writel(sel, info->sel_reg); 1052 1053 if (allow_clk_stop(info)) 1054 clk_disable(info->clk); 1055 } 1056 1057 return 0; 1058} 1059 1060#else 1061#define s3c24xx_nand_suspend NULL 1062#define s3c24xx_nand_resume NULL 1063#endif 1064 1065/* driver device registration */ 1066 1067static struct platform_device_id s3c24xx_driver_ids[] = { 1068 { 1069 .name = "s3c2410-nand", 1070 .driver_data = TYPE_S3C2410, 1071 }, { 1072 .name = "s3c2440-nand", 1073 .driver_data = TYPE_S3C2440, 1074 }, { 1075 .name = "s3c2412-nand", 1076 .driver_data = TYPE_S3C2412, 1077 }, 1078 { } 1079}; 1080 1081MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids); 1082 1083static struct platform_driver s3c24xx_nand_driver = { 1084 .probe = s3c24xx_nand_probe, 1085 .remove = s3c24xx_nand_remove, 1086 .suspend = s3c24xx_nand_suspend, 1087 .resume = s3c24xx_nand_resume, 1088 .id_table = s3c24xx_driver_ids, 1089 .driver = { 1090 .name = "s3c24xx-nand", 1091 .owner = THIS_MODULE, 1092 }, 1093}; 1094 1095static int __init s3c2410_nand_init(void) 1096{ 1097 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); 1098 1099 return platform_driver_register(&s3c24xx_nand_driver); 1100} 1101 1102static void __exit s3c2410_nand_exit(void) 1103{ 1104 platform_driver_unregister(&s3c24xx_nand_driver); 1105} 1106 1107module_init(s3c2410_nand_init); 1108module_exit(s3c2410_nand_exit); 1109 1110MODULE_LICENSE("GPL"); 1111MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 1112MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); 1113