uboot/drivers/mtd/nand/jz4740_nand.c
<<
>>
Prefs
   1/*
   2 * Platform independend driver for JZ4740.
   3 *
   4 * Copyright (c) 2007 Ingenic Semiconductor Inc.
   5 * Author: <jlwei@ingenic.cn>
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9#include <common.h>
  10
  11#include <nand.h>
  12#include <asm/io.h>
  13#include <asm/jz4740.h>
  14
  15#define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000)
  16#define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000)
  17#define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000)
  18
  19#define JZ_NAND_ECC_CTRL_ENCODING       BIT(3)
  20#define JZ_NAND_ECC_CTRL_RS             BIT(2)
  21#define JZ_NAND_ECC_CTRL_RESET          BIT(1)
  22#define JZ_NAND_ECC_CTRL_ENABLE         BIT(0)
  23
  24#define EMC_SMCR1_OPT_NAND      0x094c4400
  25/* Optimize the timing of nand */
  26
  27static struct jz4740_emc * emc = (struct jz4740_emc *)JZ4740_EMC_BASE;
  28
  29static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
  30        .eccbytes = 72,
  31        .eccpos = {
  32                12, 13, 14, 15, 16, 17, 18, 19,
  33                20, 21, 22, 23, 24, 25, 26, 27,
  34                28, 29, 30, 31, 32, 33, 34, 35,
  35                36, 37, 38, 39, 40, 41, 42, 43,
  36                44, 45, 46, 47, 48, 49, 50, 51,
  37                52, 53, 54, 55, 56, 57, 58, 59,
  38                60, 61, 62, 63, 64, 65, 66, 67,
  39                68, 69, 70, 71, 72, 73, 74, 75,
  40                76, 77, 78, 79, 80, 81, 82, 83 },
  41        .oobfree = {
  42                {.offset = 2,
  43                 .length = 10 },
  44                {.offset = 84,
  45                 .length = 44 } }
  46};
  47
  48static int is_reading;
  49
  50static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
  51{
  52        struct nand_chip *this = mtd->priv;
  53        uint32_t reg;
  54
  55        if (ctrl & NAND_CTRL_CHANGE) {
  56                if (ctrl & NAND_ALE)
  57                        this->IO_ADDR_W = JZ_NAND_ADDR_ADDR;
  58                else if (ctrl & NAND_CLE)
  59                        this->IO_ADDR_W = JZ_NAND_CMD_ADDR;
  60                else
  61                        this->IO_ADDR_W = JZ_NAND_DATA_ADDR;
  62
  63                reg = readl(&emc->nfcsr);
  64                if (ctrl & NAND_NCE)
  65                        reg |= EMC_NFCSR_NFCE1;
  66                else
  67                        reg &= ~EMC_NFCSR_NFCE1;
  68                writel(reg, &emc->nfcsr);
  69        }
  70
  71        if (cmd != NAND_CMD_NONE)
  72                writeb(cmd, this->IO_ADDR_W);
  73}
  74
  75static int jz_nand_device_ready(struct mtd_info *mtd)
  76{
  77        return (readl(GPIO_PXPIN(2)) & 0x40000000) ? 1 : 0;
  78}
  79
  80void board_nand_select_device(struct nand_chip *nand, int chip)
  81{
  82        /*
  83         * Don't use "chip" to address the NAND device,
  84         * generate the cs from the address where it is encoded.
  85         */
  86}
  87
  88static int jz_nand_rs_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
  89                                u_char *ecc_code)
  90{
  91        uint32_t status;
  92        int i;
  93
  94        if (is_reading)
  95                return 0;
  96
  97        do {
  98                status = readl(&emc->nfints);
  99        } while (!(status & EMC_NFINTS_ENCF));
 100
 101        /* disable ecc */
 102        writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr);
 103
 104        for (i = 0; i < 9; i++)
 105                ecc_code[i] = readb(&emc->nfpar[i]);
 106
 107        return 0;
 108}
 109
 110static void jz_nand_hwctl(struct mtd_info *mtd, int mode)
 111{
 112        uint32_t reg;
 113
 114        writel(0, &emc->nfints);
 115        reg = readl(&emc->nfecr);
 116        reg |= JZ_NAND_ECC_CTRL_RESET;
 117        reg |= JZ_NAND_ECC_CTRL_ENABLE;
 118        reg |= JZ_NAND_ECC_CTRL_RS;
 119
 120        switch (mode) {
 121        case NAND_ECC_READ:
 122                reg &= ~JZ_NAND_ECC_CTRL_ENCODING;
 123                is_reading = 1;
 124                break;
 125        case NAND_ECC_WRITE:
 126                reg |= JZ_NAND_ECC_CTRL_ENCODING;
 127                is_reading = 0;
 128                break;
 129        default:
 130                break;
 131        }
 132
 133        writel(reg, &emc->nfecr);
 134}
 135
 136/* Correct 1~9-bit errors in 512-bytes data */
 137static void jz_rs_correct(unsigned char *dat, int idx, int mask)
 138{
 139        int i;
 140
 141        idx--;
 142
 143        i = idx + (idx >> 3);
 144        if (i >= 512)
 145                return;
 146
 147        mask <<= (idx & 0x7);
 148
 149        dat[i] ^= mask & 0xff;
 150        if (i < 511)
 151                dat[i + 1] ^= (mask >> 8) & 0xff;
 152}
 153
 154static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
 155                                   u_char *read_ecc, u_char *calc_ecc)
 156{
 157        int k;
 158        uint32_t errcnt, index, mask, status;
 159
 160        /* Set PAR values */
 161        const uint8_t all_ff_ecc[] = {
 162                0xcd, 0x9d, 0x90, 0x58, 0xf4, 0x8b, 0xff, 0xb7, 0x6f };
 163
 164        if (read_ecc[0] == 0xff && read_ecc[1] == 0xff &&
 165            read_ecc[2] == 0xff && read_ecc[3] == 0xff &&
 166            read_ecc[4] == 0xff && read_ecc[5] == 0xff &&
 167            read_ecc[6] == 0xff && read_ecc[7] == 0xff &&
 168            read_ecc[8] == 0xff) {
 169                for (k = 0; k < 9; k++)
 170                        writeb(all_ff_ecc[k], &emc->nfpar[k]);
 171        } else {
 172                for (k = 0; k < 9; k++)
 173                        writeb(read_ecc[k], &emc->nfpar[k]);
 174        }
 175        /* Set PRDY */
 176        writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr);
 177
 178        /* Wait for completion */
 179        do {
 180                status = readl(&emc->nfints);
 181        } while (!(status & EMC_NFINTS_DECF));
 182
 183        /* disable ecc */
 184        writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr);
 185
 186        /* Check decoding */
 187        if (!(status & EMC_NFINTS_ERR))
 188                return 0;
 189
 190        if (status & EMC_NFINTS_UNCOR) {
 191                printf("uncorrectable ecc\n");
 192                return -1;
 193        }
 194
 195        errcnt = (status & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
 196
 197        switch (errcnt) {
 198        case 4:
 199                index = (readl(&emc->nferr[3]) & EMC_NFERR_INDEX_MASK) >>
 200                        EMC_NFERR_INDEX_BIT;
 201                mask = (readl(&emc->nferr[3]) & EMC_NFERR_MASK_MASK) >>
 202                        EMC_NFERR_MASK_BIT;
 203                jz_rs_correct(dat, index, mask);
 204        case 3:
 205                index = (readl(&emc->nferr[2]) & EMC_NFERR_INDEX_MASK) >>
 206                        EMC_NFERR_INDEX_BIT;
 207                mask = (readl(&emc->nferr[2]) & EMC_NFERR_MASK_MASK) >>
 208                        EMC_NFERR_MASK_BIT;
 209                jz_rs_correct(dat, index, mask);
 210        case 2:
 211                index = (readl(&emc->nferr[1]) & EMC_NFERR_INDEX_MASK) >>
 212                        EMC_NFERR_INDEX_BIT;
 213                mask = (readl(&emc->nferr[1]) & EMC_NFERR_MASK_MASK) >>
 214                        EMC_NFERR_MASK_BIT;
 215                jz_rs_correct(dat, index, mask);
 216        case 1:
 217                index = (readl(&emc->nferr[0]) & EMC_NFERR_INDEX_MASK) >>
 218                        EMC_NFERR_INDEX_BIT;
 219                mask = (readl(&emc->nferr[0]) & EMC_NFERR_MASK_MASK) >>
 220                        EMC_NFERR_MASK_BIT;
 221                jz_rs_correct(dat, index, mask);
 222        default:
 223                break;
 224        }
 225
 226        return errcnt;
 227}
 228
 229/*
 230 * Main initialization routine
 231 */
 232int board_nand_init(struct nand_chip *nand)
 233{
 234        uint32_t reg;
 235
 236        reg = readl(&emc->nfcsr);
 237        reg |= EMC_NFCSR_NFE1;  /* EMC setup, Set NFE bit */
 238        writel(reg, &emc->nfcsr);
 239
 240        writel(EMC_SMCR1_OPT_NAND, &emc->smcr[1]);
 241
 242        nand->IO_ADDR_R         = JZ_NAND_DATA_ADDR;
 243        nand->IO_ADDR_W         = JZ_NAND_DATA_ADDR;
 244        nand->cmd_ctrl          = jz_nand_cmd_ctrl;
 245        nand->dev_ready         = jz_nand_device_ready;
 246        nand->ecc.hwctl         = jz_nand_hwctl;
 247        nand->ecc.correct       = jz_nand_rs_correct_data;
 248        nand->ecc.calculate     = jz_nand_rs_calculate_ecc;
 249        nand->ecc.mode          = NAND_ECC_HW_OOB_FIRST;
 250        nand->ecc.size          = CONFIG_SYS_NAND_ECCSIZE;
 251        nand->ecc.bytes         = CONFIG_SYS_NAND_ECCBYTES;
 252        nand->ecc.strength      = 4;
 253        nand->ecc.layout        = &qi_lb60_ecclayout_2gb;
 254        nand->chip_delay        = 50;
 255        nand->bbt_options       |= NAND_BBT_USE_FLASH;
 256
 257        return 0;
 258}
 259