From patchwork Mon May 4 14:08:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 245028 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Mon, 4 May 2020 22:08:55 +0800 Subject: [PATCH 06/14] nand: Update SPL MXS NAND mini driver In-Reply-To: <20200504140903.23602-1-peng.fan@nxp.com> References: <20200504140903.23602-1-peng.fan@nxp.com> Message-ID: <20200504140903.23602-7-peng.fan@nxp.com> From: Ye Li Update the mini driver to add support for getting ecc info from ONFI and support read image data from page unaligned NAND address. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand_spl.c | 41 ++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c index a653dfa5ed..ae50cc37b5 100644 --- a/drivers/mtd/nand/raw/mxs_nand_spl.c +++ b/drivers/mtd/nand/raw/mxs_nand_spl.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2014 Gateworks Corporation + * Copyright 2019 NXP * Author: Tim Harvey */ #include @@ -38,6 +39,12 @@ static void mxs_nand_command(struct mtd_info *mtd, unsigned int command, if (command == NAND_CMD_READ0) { chip->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_CLE); chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0); + } else if (command == NAND_CMD_RNDOUT) { + /* No ready / busy check necessary */ + chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART, + NAND_NCE | NAND_CLE); + chip->cmd_ctrl(mtd, NAND_CMD_NONE, + NAND_NCE); } /* wait for nand ready */ @@ -212,23 +219,39 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf) unsigned int page; unsigned int nand_page_per_block; unsigned int sz = 0; + u8 *page_buf = NULL; + u32 page_off; chip = mtd_to_nand(mtd); if (!chip->numchips) return -ENODEV; + + page_buf = malloc(mtd->writesize); + if (!page_buf) + return -ENOMEM; + page = offs >> chip->page_shift; + page_off = offs & (mtd->writesize - 1); nand_page_per_block = mtd->erasesize / mtd->writesize; - debug("%s offset:0x%08x len:%d page:%d\n", __func__, offs, size, page); + debug("%s offset:0x%08x len:%d page:%x\n", __func__, offs, size, page); - size = roundup(size, mtd->writesize); - while (sz < size) { - if (mxs_read_page_ecc(mtd, buf, page) < 0) + while (size) { + if (mxs_read_page_ecc(mtd, page_buf, page) < 0) return -1; - sz += mtd->writesize; + + if (size > (mtd->writesize - page_off)) + sz = (mtd->writesize - page_off); + else + sz = size; + + memcpy(buf, page_buf + page_off, sz); + offs += mtd->writesize; page++; - buf += mtd->writesize; + buf += (mtd->writesize - page_off); + page_off = 0; + size -= sz; /* * Check if we have crossed a block boundary, and if so @@ -242,12 +265,16 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf) while (is_badblock(mtd, offs, 1)) { page = page + nand_page_per_block; /* Check i we've reached the end of flash. */ - if (page >= mtd->size >> chip->page_shift) + if (page >= mtd->size >> chip->page_shift) { + free(page_buf); return -ENOMEM; + } } } } + free(page_buf); + return 0; }