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