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 mtd_info                 mtd;
 108        struct nand_chip                chip;
 109        struct s3c2410_nand_set         *set;
 110        struct s3c2410_nand_info        *info;
 111        int                             scan_res;
 112};
 113
 114enum s3c_cpu_type {
 115        TYPE_S3C2410,
 116        TYPE_S3C2412,
 117        TYPE_S3C2440,
 118};
 119
 120enum s3c_nand_clk_state {
 121        CLOCK_DISABLE   = 0,
 122        CLOCK_ENABLE,
 123        CLOCK_SUSPEND,
 124};
 125
 126/* overview of the s3c2410 nand state */
 127
 128/**
 129 * struct s3c2410_nand_info - NAND controller state.
 130 * @mtds: An array of MTD instances on this controoler.
 131 * @platform: The platform data for this board.
 132 * @device: The platform device we bound to.
 133 * @clk: The clock resource for this controller.
 134 * @regs: The area mapped for the hardware registers.
 135 * @sel_reg: Pointer to the register controlling the NAND selection.
 136 * @sel_bit: The bit in @sel_reg to select the NAND chip.
 137 * @mtd_count: The number of MTDs created from this controller.
 138 * @save_sel: The contents of @sel_reg to be saved over suspend.
 139 * @clk_rate: The clock rate from @clk.
 140 * @clk_state: The current clock state.
 141 * @cpu_type: The exact type of this controller.
 142 */
 143struct s3c2410_nand_info {
 144        /* mtd info */
 145        struct nand_hw_control          controller;
 146        struct s3c2410_nand_mtd         *mtds;
 147        struct s3c2410_platform_nand    *platform;
 148
 149        /* device info */
 150        struct device                   *device;
 151        struct clk                      *clk;
 152        void __iomem                    *regs;
 153        void __iomem                    *sel_reg;
 154        int                             sel_bit;
 155        int                             mtd_count;
 156        unsigned long                   save_sel;
 157        unsigned long                   clk_rate;
 158        enum s3c_nand_clk_state         clk_state;
 159
 160        enum s3c_cpu_type               cpu_type;
 161
 162#ifdef CONFIG_CPU_FREQ
 163        struct notifier_block   freq_transition;
 164#endif
 165};
 166
 167/* conversion functions */
 168
 169static struct s3c2410_nand_mtd *s3c2410_nand_mtd_toours(struct mtd_info *mtd)
 170{
 171        return container_of(mtd, struct s3c2410_nand_mtd, mtd);
 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->priv;
 386        unsigned long cur;
 387
 388        nmtd = this->priv;
 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->priv;
 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->priv;
 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(&ptr->mtd);
 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                mtd->mtd.name = set->name;
 766
 767                return mtd_device_parse_register(&mtd->mtd, NULL, NULL,
 768                                         set->partitions, set->nr_partitions);
 769        }
 770
 771        return -ENODEV;
 772}
 773
 774/**
 775 * s3c2410_nand_init_chip - initialise a single instance of an chip
 776 * @info: The base NAND controller the chip is on.
 777 * @nmtd: The new controller MTD instance to fill in.
 778 * @set: The information passed from the board specific platform data.
 779 *
 780 * Initialise the given @nmtd from the information in @info and @set. This
 781 * readies the structure for use with the MTD layer functions by ensuring
 782 * all pointers are setup and the necessary control routines selected.
 783 */
 784static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
 785                                   struct s3c2410_nand_mtd *nmtd,
 786                                   struct s3c2410_nand_set *set)
 787{
 788        struct nand_chip *chip = &nmtd->chip;
 789        void __iomem *regs = info->regs;
 790
 791        chip->write_buf    = s3c2410_nand_write_buf;
 792        chip->read_buf     = s3c2410_nand_read_buf;
 793        chip->select_chip  = s3c2410_nand_select_chip;
 794        chip->chip_delay   = 50;
 795        chip->priv         = nmtd;
 796        chip->options      = set->options;
 797        chip->controller   = &info->controller;
 798
 799        switch (info->cpu_type) {
 800        case TYPE_S3C2410:
 801                chip->IO_ADDR_W = regs + S3C2410_NFDATA;
 802                info->sel_reg   = regs + S3C2410_NFCONF;
 803                info->sel_bit   = S3C2410_NFCONF_nFCE;
 804                chip->cmd_ctrl  = s3c2410_nand_hwcontrol;
 805                chip->dev_ready = s3c2410_nand_devready;
 806                break;
 807
 808        case TYPE_S3C2440:
 809                chip->IO_ADDR_W = regs + S3C2440_NFDATA;
 810                info->sel_reg   = regs + S3C2440_NFCONT;
 811                info->sel_bit   = S3C2440_NFCONT_nFCE;
 812                chip->cmd_ctrl  = s3c2440_nand_hwcontrol;
 813                chip->dev_ready = s3c2440_nand_devready;
 814                chip->read_buf  = s3c2440_nand_read_buf;
 815                chip->write_buf = s3c2440_nand_write_buf;
 816                break;
 817
 818        case TYPE_S3C2412:
 819                chip->IO_ADDR_W = regs + S3C2440_NFDATA;
 820                info->sel_reg   = regs + S3C2440_NFCONT;
 821                info->sel_bit   = S3C2412_NFCONT_nFCE0;
 822                chip->cmd_ctrl  = s3c2440_nand_hwcontrol;
 823                chip->dev_ready = s3c2412_nand_devready;
 824
 825                if (readl(regs + S3C2410_NFCONF) & S3C2412_NFCONF_NANDBOOT)
 826                        dev_info(info->device, "System booted from NAND\n");
 827
 828                break;
 829        }
 830
 831        chip->IO_ADDR_R = chip->IO_ADDR_W;
 832
 833        nmtd->info         = info;
 834        nmtd->mtd.priv     = chip;
 835        nmtd->mtd.owner    = THIS_MODULE;
 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->ecc_layout != NULL)
 865                chip->ecc.layout = set->ecc_layout;
 866
 867        if (set->disable_ecc)
 868                chip->ecc.mode  = NAND_ECC_NONE;
 869
 870        switch (chip->ecc.mode) {
 871        case NAND_ECC_NONE:
 872                dev_info(info->device, "NAND ECC disabled\n");
 873                break;
 874        case NAND_ECC_SOFT:
 875                dev_info(info->device, "NAND soft ECC\n");
 876                break;
 877        case NAND_ECC_HW:
 878                dev_info(info->device, "NAND hardware ECC\n");
 879                break;
 880        default:
 881                dev_info(info->device, "NAND ECC UNKNOWN\n");
 882                break;
 883        }
 884
 885        /* If you use u-boot BBT creation code, specifying this flag will
 886         * let the kernel fish out the BBT from the NAND, and also skip the
 887         * full NAND scan that can take 1/2s or so. Little things... */
 888        if (set->flash_bbt) {
 889                chip->bbt_options |= NAND_BBT_USE_FLASH;
 890                chip->options |= NAND_SKIP_BBTSCAN;
 891        }
 892}
 893
 894/**
 895 * s3c2410_nand_update_chip - post probe update
 896 * @info: The controller instance.
 897 * @nmtd: The driver version of the MTD instance.
 898 *
 899 * This routine is called after the chip probe has successfully completed
 900 * and the relevant per-chip information updated. This call ensure that
 901 * we update the internal state accordingly.
 902 *
 903 * The internal state is currently limited to the ECC state information.
 904*/
 905static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
 906                                     struct s3c2410_nand_mtd *nmtd)
 907{
 908        struct nand_chip *chip = &nmtd->chip;
 909
 910        dev_dbg(info->device, "chip %p => page shift %d\n",
 911                chip, chip->page_shift);
 912
 913        if (chip->ecc.mode != NAND_ECC_HW)
 914                return;
 915
 916                /* change the behaviour depending on whether we are using
 917                 * the large or small page nand device */
 918
 919        if (chip->page_shift > 10) {
 920                chip->ecc.size      = 256;
 921                chip->ecc.bytes     = 3;
 922        } else {
 923                chip->ecc.size      = 512;
 924                chip->ecc.bytes     = 3;
 925                chip->ecc.layout    = &nand_hw_eccoob;
 926        }
 927}
 928
 929/* s3c24xx_nand_probe
 930 *
 931 * called by device layer when it finds a device matching
 932 * one our driver can handled. This code checks to see if
 933 * it can allocate all necessary resources then calls the
 934 * nand layer to look for devices
 935*/
 936static int s3c24xx_nand_probe(struct platform_device *pdev)
 937{
 938        struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
 939        enum s3c_cpu_type cpu_type;
 940        struct s3c2410_nand_info *info;
 941        struct s3c2410_nand_mtd *nmtd;
 942        struct s3c2410_nand_set *sets;
 943        struct resource *res;
 944        int err = 0;
 945        int size;
 946        int nr_sets;
 947        int setno;
 948
 949        cpu_type = platform_get_device_id(pdev)->driver_data;
 950
 951        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 952        if (info == NULL) {
 953                err = -ENOMEM;
 954                goto exit_error;
 955        }
 956
 957        platform_set_drvdata(pdev, info);
 958
 959        spin_lock_init(&info->controller.lock);
 960        init_waitqueue_head(&info->controller.wq);
 961
 962        /* get the clock source and enable it */
 963
 964        info->clk = devm_clk_get(&pdev->dev, "nand");
 965        if (IS_ERR(info->clk)) {
 966                dev_err(&pdev->dev, "failed to get clock\n");
 967                err = -ENOENT;
 968                goto exit_error;
 969        }
 970
 971        s3c2410_nand_clk_set_state(info, CLOCK_ENABLE);
 972
 973        /* allocate and map the resource */
 974
 975        /* currently we assume we have the one resource */
 976        res = pdev->resource;
 977        size = resource_size(res);
 978
 979        info->device    = &pdev->dev;
 980        info->platform  = plat;
 981        info->cpu_type  = cpu_type;
 982
 983        info->regs = devm_ioremap_resource(&pdev->dev, res);
 984        if (IS_ERR(info->regs)) {
 985                err = PTR_ERR(info->regs);
 986                goto exit_error;
 987        }
 988
 989        dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs);
 990
 991        /* initialise the hardware */
 992
 993        err = s3c2410_nand_inithw(info);
 994        if (err != 0)
 995                goto exit_error;
 996
 997        sets = (plat != NULL) ? plat->sets : NULL;
 998        nr_sets = (plat != NULL) ? plat->nr_sets : 1;
 999
1000        info->mtd_count = nr_sets;
1001
1002        /* allocate our information */
1003
1004        size = nr_sets * sizeof(*info->mtds);
1005        info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
1006        if (info->mtds == NULL) {
1007                err = -ENOMEM;
1008                goto exit_error;
1009        }
1010
1011        /* initialise all possible chips */
1012
1013        nmtd = info->mtds;
1014
1015        for (setno = 0; setno < nr_sets; setno++, nmtd++) {
1016                pr_debug("initialising set %d (%p, info %p)\n",
1017                         setno, nmtd, info);
1018
1019                s3c2410_nand_init_chip(info, nmtd, sets);
1020
1021                nmtd->scan_res = nand_scan_ident(&nmtd->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(&nmtd->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 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