uboot/drivers/mtd/nand/mxc_nand_spl.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009
   3 * Magnus Lilja <lilja.magnus@gmail.com>
   4 *
   5 * (C) Copyright 2008
   6 * Maxim Artamonov, <scn1874 at yandex.ru>
   7 *
   8 * (C) Copyright 2006-2008
   9 * Stefan Roese, DENX Software Engineering, sr at denx.de.
  10 *
  11 * SPDX-License-Identifier:     GPL-2.0+
  12 */
  13
  14#include <common.h>
  15#include <nand.h>
  16#include <asm/arch/imx-regs.h>
  17#include <asm/io.h>
  18#include "mxc_nand.h"
  19
  20#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
  21static struct mxc_nand_regs *const nfc = (void *)NFC_BASE_ADDR;
  22#elif defined(MXC_NFC_V3_2)
  23static struct mxc_nand_regs *const nfc = (void *)NFC_BASE_ADDR_AXI;
  24static struct mxc_nand_ip_regs *const nfc_ip = (void *)NFC_BASE_ADDR;
  25#endif
  26
  27static void nfc_wait_ready(void)
  28{
  29        uint32_t tmp;
  30
  31#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
  32        while (!(readnfc(&nfc->config2) & NFC_V1_V2_CONFIG2_INT))
  33                ;
  34
  35        /* Reset interrupt flag */
  36        tmp = readnfc(&nfc->config2);
  37        tmp &= ~NFC_V1_V2_CONFIG2_INT;
  38        writenfc(tmp, &nfc->config2);
  39#elif defined(MXC_NFC_V3_2)
  40        while (!(readnfc(&nfc_ip->ipc) & NFC_V3_IPC_INT))
  41                ;
  42
  43        /* Reset interrupt flag */
  44        tmp = readnfc(&nfc_ip->ipc);
  45        tmp &= ~NFC_V3_IPC_INT;
  46        writenfc(tmp, &nfc_ip->ipc);
  47#endif
  48}
  49
  50static void nfc_nand_init(void)
  51{
  52#if defined(MXC_NFC_V3_2)
  53        int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
  54        int tmp;
  55
  56        tmp = (readnfc(&nfc_ip->config2) & ~(NFC_V3_CONFIG2_SPAS_MASK |
  57                        NFC_V3_CONFIG2_EDC_MASK | NFC_V3_CONFIG2_PS_MASK)) |
  58                NFC_V3_CONFIG2_SPAS(CONFIG_SYS_NAND_OOBSIZE / 2) |
  59                NFC_V3_CONFIG2_INT_MSK | NFC_V3_CONFIG2_ECC_EN |
  60                NFC_V3_CONFIG2_ONE_CYCLE;
  61        if (CONFIG_SYS_NAND_PAGE_SIZE == 4096)
  62                tmp |= NFC_V3_CONFIG2_PS_4096;
  63        else if (CONFIG_SYS_NAND_PAGE_SIZE == 2048)
  64                tmp |= NFC_V3_CONFIG2_PS_2048;
  65        else if (CONFIG_SYS_NAND_PAGE_SIZE == 512)
  66                tmp |= NFC_V3_CONFIG2_PS_512;
  67        /*
  68         * if spare size is larger that 16 bytes per 512 byte hunk
  69         * then use 8 symbol correction instead of 4
  70         */
  71        if (CONFIG_SYS_NAND_OOBSIZE / ecc_per_page > 16)
  72                tmp |= NFC_V3_CONFIG2_ECC_MODE_8;
  73        else
  74                tmp &= ~NFC_V3_CONFIG2_ECC_MODE_8;
  75        writenfc(tmp, &nfc_ip->config2);
  76
  77        tmp = NFC_V3_CONFIG3_NUM_OF_DEVS(0) |
  78                        NFC_V3_CONFIG3_NO_SDMA |
  79                        NFC_V3_CONFIG3_RBB_MODE |
  80                        NFC_V3_CONFIG3_SBB(6) | /* Reset default */
  81                        NFC_V3_CONFIG3_ADD_OP(0);
  82#ifndef CONFIG_SYS_NAND_BUSWIDTH_16
  83        tmp |= NFC_V3_CONFIG3_FW8;
  84#endif
  85        writenfc(tmp, &nfc_ip->config3);
  86
  87        writenfc(0, &nfc_ip->delay_line);
  88#elif defined(MXC_NFC_V2_1)
  89        int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
  90        int config1;
  91
  92        writenfc(CONFIG_SYS_NAND_OOBSIZE / 2, &nfc->spare_area_size);
  93
  94        /* unlocking RAM Buff */
  95        writenfc(0x2, &nfc->config);
  96
  97        /* hardware ECC checking and correct */
  98        config1 = readnfc(&nfc->config1) | NFC_V1_V2_CONFIG1_ECC_EN |
  99                        NFC_V1_V2_CONFIG1_INT_MSK | NFC_V2_CONFIG1_ONE_CYCLE |
 100                        NFC_V2_CONFIG1_FP_INT;
 101        /*
 102         * if spare size is larger that 16 bytes per 512 byte hunk
 103         * then use 8 symbol correction instead of 4
 104         */
 105        if (CONFIG_SYS_NAND_OOBSIZE / ecc_per_page > 16)
 106                config1 &= ~NFC_V2_CONFIG1_ECC_MODE_4;
 107        else
 108                config1 |= NFC_V2_CONFIG1_ECC_MODE_4;
 109        writenfc(config1, &nfc->config1);
 110#elif defined(MXC_NFC_V1)
 111        /* unlocking RAM Buff */
 112        writenfc(0x2, &nfc->config);
 113
 114        /* hardware ECC checking and correct */
 115        writenfc(NFC_V1_V2_CONFIG1_ECC_EN | NFC_V1_V2_CONFIG1_INT_MSK,
 116                        &nfc->config1);
 117#endif
 118}
 119
 120static void nfc_nand_command(unsigned short command)
 121{
 122        writenfc(command, &nfc->flash_cmd);
 123        writenfc(NFC_CMD, &nfc->operation);
 124        nfc_wait_ready();
 125}
 126
 127static void nfc_nand_address(unsigned short address)
 128{
 129        writenfc(address, &nfc->flash_addr);
 130        writenfc(NFC_ADDR, &nfc->operation);
 131        nfc_wait_ready();
 132}
 133
 134static void nfc_nand_page_address(unsigned int page_address)
 135{
 136        unsigned int page_count;
 137
 138        nfc_nand_address(0x00);
 139
 140        /* code only for large page flash */
 141        if (CONFIG_SYS_NAND_PAGE_SIZE > 512)
 142                nfc_nand_address(0x00);
 143
 144        page_count = CONFIG_SYS_NAND_SIZE / CONFIG_SYS_NAND_PAGE_SIZE;
 145
 146        if (page_address <= page_count) {
 147                page_count--; /* transform 0x01000000 to 0x00ffffff */
 148                do {
 149                        nfc_nand_address(page_address & 0xff);
 150                        page_address = page_address >> 8;
 151                        page_count = page_count >> 8;
 152                } while (page_count);
 153        }
 154
 155        nfc_nand_address(0x00);
 156}
 157
 158static void nfc_nand_data_output(void)
 159{
 160#ifdef NAND_MXC_2K_MULTI_CYCLE
 161        int i;
 162#endif
 163
 164#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 165        writenfc(0, &nfc->buf_addr);
 166#elif defined(MXC_NFC_V3_2)
 167        int config1 = readnfc(&nfc->config1);
 168        config1 &= ~NFC_V3_CONFIG1_RBA_MASK;
 169        writenfc(config1, &nfc->config1);
 170#endif
 171        writenfc(NFC_OUTPUT, &nfc->operation);
 172        nfc_wait_ready();
 173#ifdef NAND_MXC_2K_MULTI_CYCLE
 174        /*
 175         * This NAND controller requires multiple input commands
 176         * for pages larger than 512 bytes.
 177         */
 178        for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) {
 179                writenfc(i, &nfc->buf_addr);
 180                writenfc(NFC_OUTPUT, &nfc->operation);
 181                nfc_wait_ready();
 182        }
 183#endif
 184}
 185
 186static int nfc_nand_check_ecc(void)
 187{
 188#if defined(MXC_NFC_V1)
 189        u16 ecc_status = readw(&nfc->ecc_status_result);
 190        return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2;
 191#elif defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
 192        u32 ecc_status = readl(&nfc->ecc_status_result);
 193        int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
 194        int err_limit = CONFIG_SYS_NAND_OOBSIZE / ecc_per_page > 16 ? 8 : 4;
 195        int subpages = CONFIG_SYS_NAND_PAGE_SIZE / 512;
 196
 197        do {
 198                if ((ecc_status & 0xf) > err_limit)
 199                        return 1;
 200                ecc_status >>= 4;
 201        } while (--subpages);
 202
 203        return 0;
 204#endif
 205}
 206
 207static void nfc_nand_read_page(unsigned int page_address)
 208{
 209        /* read in first 0 buffer */
 210#if defined(MXC_NFC_V1) || defined(MXC_NFC_V2_1)
 211        writenfc(0, &nfc->buf_addr);
 212#elif defined(MXC_NFC_V3_2)
 213        int config1 = readnfc(&nfc->config1);
 214        config1 &= ~NFC_V3_CONFIG1_RBA_MASK;
 215        writenfc(config1, &nfc->config1);
 216#endif
 217        nfc_nand_command(NAND_CMD_READ0);
 218        nfc_nand_page_address(page_address);
 219
 220        if (CONFIG_SYS_NAND_PAGE_SIZE > 512)
 221                nfc_nand_command(NAND_CMD_READSTART);
 222
 223        nfc_nand_data_output(); /* fill the main buffer 0 */
 224}
 225
 226static int nfc_read_page(unsigned int page_address, unsigned char *buf)
 227{
 228        int i;
 229        u32 *src;
 230        u32 *dst;
 231
 232        nfc_nand_read_page(page_address);
 233
 234        if (nfc_nand_check_ecc())
 235                return -EBADMSG;
 236
 237        src = (u32 *)&nfc->main_area[0][0];
 238        dst = (u32 *)buf;
 239
 240        /* main copy loop from NAND-buffer to SDRAM memory */
 241        for (i = 0; i < CONFIG_SYS_NAND_PAGE_SIZE / 4; i++) {
 242                writel(readl(src), dst);
 243                src++;
 244                dst++;
 245        }
 246
 247        return 0;
 248}
 249
 250static int is_badblock(int pagenumber)
 251{
 252        int page = pagenumber;
 253        u32 badblock;
 254        u32 *src;
 255
 256        /* Check the first two pages for bad block markers */
 257        for (page = pagenumber; page < pagenumber + 2; page++) {
 258                nfc_nand_read_page(page);
 259
 260                src = (u32 *)&nfc->spare_area[0][0];
 261
 262                /*
 263                 * IMPORTANT NOTE: The nand flash controller uses a non-
 264                 * standard layout for large page devices. This can
 265                 * affect the position of the bad block marker.
 266                 */
 267                /* Get the bad block marker */
 268                badblock = readl(&src[CONFIG_SYS_NAND_BAD_BLOCK_POS / 4]);
 269                badblock >>= 8 * (CONFIG_SYS_NAND_BAD_BLOCK_POS % 4);
 270                badblock &= 0xff;
 271
 272                /* bad block marker verify */
 273                if (badblock != 0xff)
 274                        return 1; /* potential bad block */
 275        }
 276
 277        return 0;
 278}
 279
 280int nand_spl_load_image(uint32_t from, unsigned int size, void *buf)
 281{
 282        int i;
 283        unsigned int page;
 284        unsigned int maxpages = CONFIG_SYS_NAND_SIZE /
 285                                CONFIG_SYS_NAND_PAGE_SIZE;
 286
 287        nfc_nand_init();
 288
 289        /* Convert to page number */
 290        page = from / CONFIG_SYS_NAND_PAGE_SIZE;
 291        i = 0;
 292
 293        size = roundup(size, CONFIG_SYS_NAND_PAGE_SIZE);
 294        while (i < size / CONFIG_SYS_NAND_PAGE_SIZE) {
 295                if (nfc_read_page(page, buf) < 0)
 296                        return -1;
 297
 298                page++;
 299                i++;
 300                buf = buf + CONFIG_SYS_NAND_PAGE_SIZE;
 301
 302                /*
 303                 * Check if we have crossed a block boundary, and if so
 304                 * check for bad block.
 305                 */
 306                if (!(page % CONFIG_SYS_NAND_PAGE_COUNT)) {
 307                        /*
 308                         * Yes, new block. See if this block is good. If not,
 309                         * loop until we find a good block.
 310                         */
 311                        while (is_badblock(page)) {
 312                                page = page + CONFIG_SYS_NAND_PAGE_COUNT;
 313                                /* Check i we've reached the end of flash. */
 314                                if (page >= maxpages)
 315                                        return -1;
 316                        }
 317                }
 318        }
 319
 320        return 0;
 321}
 322
 323#ifndef CONFIG_SPL_FRAMEWORK
 324/*
 325 * The main entry for NAND booting. It's necessary that SDRAM is already
 326 * configured and available since this code loads the main U-Boot image
 327 * from NAND into SDRAM and starts it from there.
 328 */
 329void nand_boot(void)
 330{
 331        __attribute__((noreturn)) void (*uboot)(void);
 332
 333        /*
 334         * CONFIG_SYS_NAND_U_BOOT_OFFS and CONFIG_SYS_NAND_U_BOOT_SIZE must
 335         * be aligned to full pages
 336         */
 337        if (!nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
 338                        CONFIG_SYS_NAND_U_BOOT_SIZE,
 339                        (uchar *)CONFIG_SYS_NAND_U_BOOT_DST)) {
 340                /* Copy from NAND successful, start U-Boot */
 341                uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
 342                uboot();
 343        } else {
 344                /* Unrecoverable error when copying from NAND */
 345                hang();
 346        }
 347}
 348#endif
 349
 350void nand_init(void) {}
 351void nand_deselect(void) {}
 352