uboot/drivers/mtd/nand/raw/mxs_nand_spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2014 Gateworks Corporation
   4 * Author: Tim Harvey <tharvey@gateworks.com>
   5 */
   6#include <common.h>
   7#include <nand.h>
   8#include <malloc.h>
   9#include <mxs_nand.h>
  10
  11static struct mtd_info *mtd;
  12static struct nand_chip nand_chip;
  13
  14static void mxs_nand_command(struct mtd_info *mtd, unsigned int command,
  15                             int column, int page_addr)
  16{
  17        register struct nand_chip *chip = mtd_to_nand(mtd);
  18        u32 timeo, time_start;
  19
  20        /* write out the command to the device */
  21        chip->cmd_ctrl(mtd, command, NAND_CLE);
  22
  23        /* Serially input address */
  24        if (column != -1) {
  25                chip->cmd_ctrl(mtd, column, NAND_ALE);
  26                chip->cmd_ctrl(mtd, column >> 8, NAND_ALE);
  27        }
  28        if (page_addr != -1) {
  29                chip->cmd_ctrl(mtd, page_addr, NAND_ALE);
  30                chip->cmd_ctrl(mtd, page_addr >> 8, NAND_ALE);
  31                /* One more address cycle for devices > 128MiB */
  32                if (chip->chipsize > (128 << 20))
  33                        chip->cmd_ctrl(mtd, page_addr >> 16, NAND_ALE);
  34        }
  35        chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0);
  36
  37        if (command == NAND_CMD_READ0) {
  38                chip->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_CLE);
  39                chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0);
  40        }
  41
  42        /* wait for nand ready */
  43        ndelay(100);
  44        timeo = (CONFIG_SYS_HZ * 20) / 1000;
  45        time_start = get_timer(0);
  46        while (get_timer(time_start) < timeo) {
  47                if (chip->dev_ready(mtd))
  48                        break;
  49        }
  50}
  51
  52#if defined (CONFIG_SPL_NAND_IDENT)
  53
  54/* Trying to detect the NAND flash using ONFi, JEDEC, and (extended) IDs */
  55static int mxs_flash_full_ident(struct mtd_info *mtd)
  56{
  57        int nand_maf_id, nand_dev_id;
  58        struct nand_chip *chip = mtd_to_nand(mtd);
  59        struct nand_flash_dev *type;
  60
  61        type = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, NULL);
  62
  63        if (IS_ERR(type)) {
  64                chip->select_chip(mtd, -1);
  65                return PTR_ERR(type);
  66        }
  67
  68        return 0;
  69}
  70
  71#else
  72
  73/* Trying to detect the NAND flash using ONFi only */
  74static int mxs_flash_onfi_ident(struct mtd_info *mtd)
  75{
  76        register struct nand_chip *chip = mtd_to_nand(mtd);
  77        int i;
  78        u8 mfg_id, dev_id;
  79        u8 id_data[8];
  80        struct nand_onfi_params *p = &chip->onfi_params;
  81
  82        /* Reset the chip */
  83        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
  84
  85        /* Send the command for reading device ID */
  86        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
  87
  88        /* Read manufacturer and device IDs */
  89        mfg_id = chip->read_byte(mtd);
  90        dev_id = chip->read_byte(mtd);
  91
  92        /* Try again to make sure */
  93        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
  94        for (i = 0; i < 8; i++)
  95                id_data[i] = chip->read_byte(mtd);
  96        if (id_data[0] != mfg_id || id_data[1] != dev_id) {
  97                printf("second ID read did not match");
  98                return -1;
  99        }
 100        debug("0x%02x:0x%02x ", mfg_id, dev_id);
 101
 102        /* read ONFI */
 103        chip->onfi_version = 0;
 104        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
 105        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
 106            chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') {
 107                return -2;
 108        }
 109
 110        /* we have ONFI, probe it */
 111        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
 112        chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
 113        mtd->name = p->model;
 114        mtd->writesize = le32_to_cpu(p->byte_per_page);
 115        mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
 116        mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
 117        chip->chipsize = le32_to_cpu(p->blocks_per_lun);
 118        chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
 119        /* Calculate the address shift from the page size */
 120        chip->page_shift = ffs(mtd->writesize) - 1;
 121        chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
 122        /* Convert chipsize to number of pages per chip -1 */
 123        chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
 124        chip->badblockbits = 8;
 125
 126        debug("erasesize=%d (>>%d)\n", mtd->erasesize, chip->phys_erase_shift);
 127        debug("writesize=%d (>>%d)\n", mtd->writesize, chip->page_shift);
 128        debug("oobsize=%d\n", mtd->oobsize);
 129        debug("chipsize=%lld\n", chip->chipsize);
 130
 131        return 0;
 132}
 133
 134#endif /* CONFIG_SPL_NAND_IDENT */
 135
 136static int mxs_flash_ident(struct mtd_info *mtd)
 137{
 138        int ret;
 139#if defined (CONFIG_SPL_NAND_IDENT)
 140        ret = mxs_flash_full_ident(mtd);
 141#else
 142        ret = mxs_flash_onfi_ident(mtd);
 143#endif
 144        return ret;
 145}
 146
 147static int mxs_read_page_ecc(struct mtd_info *mtd, void *buf, unsigned int page)
 148{
 149        register struct nand_chip *chip = mtd_to_nand(mtd);
 150        int ret;
 151
 152        chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page);
 153        ret = nand_chip.ecc.read_page(mtd, chip, buf, 1, page);
 154        if (ret < 0) {
 155                printf("read_page failed %d\n", ret);
 156                return -1;
 157        }
 158        return 0;
 159}
 160
 161static int is_badblock(struct mtd_info *mtd, loff_t offs, int allowbbt)
 162{
 163        register struct nand_chip *chip = mtd_to_nand(mtd);
 164        unsigned int block = offs >> chip->phys_erase_shift;
 165        unsigned int page = offs >> chip->page_shift;
 166
 167        debug("%s offs=0x%08x block:%d page:%d\n", __func__, (int)offs, block,
 168              page);
 169        chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
 170        memset(chip->oob_poi, 0, mtd->oobsize);
 171        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 172
 173        return chip->oob_poi[0] != 0xff;
 174}
 175
 176/* setup mtd and nand structs and init mxs_nand driver */
 177void nand_init(void)
 178{
 179        /* return if already initalized */
 180        if (nand_chip.numchips)
 181                return;
 182
 183        /* init mxs nand driver */
 184        mxs_nand_init_spl(&nand_chip);
 185        mtd = nand_to_mtd(&nand_chip);
 186        /* set mtd functions */
 187        nand_chip.cmdfunc = mxs_nand_command;
 188        nand_chip.scan_bbt = nand_default_bbt;
 189        nand_chip.numchips = 1;
 190
 191        /* identify flash device */
 192        if (mxs_flash_ident(mtd)) {
 193                printf("Failed to identify\n");
 194                nand_chip.numchips = 0; /* If fail, don't use nand */
 195                return;
 196        }
 197
 198        /* allocate and initialize buffers */
 199        nand_chip.buffers = memalign(ARCH_DMA_MINALIGN,
 200                                     sizeof(*nand_chip.buffers));
 201        nand_chip.oob_poi = nand_chip.buffers->databuf + mtd->writesize;
 202        /* setup flash layout (does not scan as we override that) */
 203        mtd->size = nand_chip.chipsize;
 204        nand_chip.scan_bbt(mtd);
 205        mxs_nand_setup_ecc(mtd);
 206}
 207
 208int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
 209{
 210        struct nand_chip *chip;
 211        unsigned int page;
 212        unsigned int nand_page_per_block;
 213        unsigned int sz = 0;
 214
 215        chip = mtd_to_nand(mtd);
 216        if (!chip->numchips)
 217                return -ENODEV;
 218        page = offs >> chip->page_shift;
 219        nand_page_per_block = mtd->erasesize / mtd->writesize;
 220
 221        debug("%s offset:0x%08x len:%d page:%d\n", __func__, offs, size, page);
 222
 223        size = roundup(size, mtd->writesize);
 224        while (sz < size) {
 225                if (mxs_read_page_ecc(mtd, buf, page) < 0)
 226                        return -1;
 227                sz += mtd->writesize;
 228                offs += mtd->writesize;
 229                page++;
 230                buf += mtd->writesize;
 231
 232                /*
 233                 * Check if we have crossed a block boundary, and if so
 234                 * check for bad block.
 235                 */
 236                if (!(page % nand_page_per_block)) {
 237                        /*
 238                         * Yes, new block. See if this block is good. If not,
 239                         * loop until we find a good block.
 240                         */
 241                        while (is_badblock(mtd, offs, 1)) {
 242                                page = page + nand_page_per_block;
 243                                /* Check i we've reached the end of flash. */
 244                                if (page >= mtd->size >> chip->page_shift)
 245                                        return -ENOMEM;
 246                        }
 247                }
 248        }
 249
 250        return 0;
 251}
 252
 253int nand_default_bbt(struct mtd_info *mtd)
 254{
 255        return 0;
 256}
 257
 258void nand_deselect(void)
 259{
 260}
 261
 262