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