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