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