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