Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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