X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmtd%2Fnand%2Fmxs_nand.c;h=036c113ad3e93ad6ffaa8a637d6e042fe2758a94;hb=f0be6ded71bc9ed1b6240a113acef8a2a0cc61b2;hp=bf9414fef1e91f0f95e15e7d5b315307d2e9eab4;hpb=6e2fbdea1b26d75314d87c380a36b0015bf824cf;p=u-boot diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index bf9414fef1..036c113ad3 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -10,36 +10,31 @@ * Copyright (C) 2010 Freescale Semiconductor, Inc. * Copyright (C) 2008 Embedded Alley Solutions, Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * SPDX-License-Identifier: GPL-2.0+ */ +#include #include #include #include -#include #include #include #include #include #include +#include +#include #include -#include +#include #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512 +#if defined(CONFIG_MX6) +#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2 +#else +#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 0 +#endif #define MXS_NAND_METADATA_SIZE 10 #define MXS_NAND_COMMAND_BUFFER_SIZE 32 @@ -160,6 +155,9 @@ static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size, if (page_oob_size == 218) return 16; + + if (page_oob_size == 224) + return 16; } return 0; @@ -546,7 +544,8 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd) * Read a page from NAND. */ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, - uint8_t *buf, int page) + uint8_t *buf, int oob_required, + int page) { struct mxs_nand_info *nand_info = nand->priv; struct mxs_dma_desc *d; @@ -691,8 +690,9 @@ rtn: /* * Write a page to NAND. */ -static void mxs_nand_ecc_write_page(struct mtd_info *mtd, - struct nand_chip *nand, const uint8_t *buf) +static int mxs_nand_ecc_write_page(struct mtd_info *mtd, + struct nand_chip *nand, const uint8_t *buf, + int oob_required) { struct mxs_nand_info *nand_info = nand->priv; struct mxs_dma_desc *d; @@ -748,6 +748,7 @@ static void mxs_nand_ecc_write_page(struct mtd_info *mtd, rtn: mxs_nand_return_dma_descs(nand_info); + return 0; } /* @@ -763,7 +764,7 @@ static int mxs_nand_hook_read_oob(struct mtd_info *mtd, loff_t from, struct mxs_nand_info *nand_info = chip->priv; int ret; - if (ops->mode == MTD_OOB_RAW) + if (ops->mode == MTD_OPS_RAW) nand_info->raw_oob_mode = 1; else nand_info->raw_oob_mode = 0; @@ -788,7 +789,7 @@ static int mxs_nand_hook_write_oob(struct mtd_info *mtd, loff_t to, struct mxs_nand_info *nand_info = chip->priv; int ret; - if (ops->mode == MTD_OOB_RAW) + if (ops->mode == MTD_OPS_RAW) nand_info->raw_oob_mode = 1; else nand_info->raw_oob_mode = 0; @@ -866,7 +867,7 @@ static int mxs_nand_hook_block_markbad(struct mtd_info *mtd, loff_t ofs) * what to do. */ static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand, - int page, int cmd) + int page) { struct mxs_nand_info *nand_info = nand->priv; @@ -980,14 +981,16 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd) tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1) << BCH_FLASHLAYOUT0_ECC0_OFFSET; - tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE; + tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE + >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; writel(tmp, &bch_regs->hw_bch_flash0layout0); tmp = (mtd->writesize + mtd->oobsize) << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1) << BCH_FLASHLAYOUT1_ECCN_OFFSET; - tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE; + tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE + >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; writel(tmp, &bch_regs->hw_bch_flash0layout1); /* Set *all* chip selects to use layout 0 */ @@ -997,19 +1000,19 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd) writel(BCH_CTRL_COMPLETE_IRQ_EN, &bch_regs->hw_bch_ctrl_set); /* Hook some operations at the MTD level. */ - if (mtd->read_oob != mxs_nand_hook_read_oob) { - nand_info->hooked_read_oob = mtd->read_oob; - mtd->read_oob = mxs_nand_hook_read_oob; + if (mtd->_read_oob != mxs_nand_hook_read_oob) { + nand_info->hooked_read_oob = mtd->_read_oob; + mtd->_read_oob = mxs_nand_hook_read_oob; } - if (mtd->write_oob != mxs_nand_hook_write_oob) { - nand_info->hooked_write_oob = mtd->write_oob; - mtd->write_oob = mxs_nand_hook_write_oob; + if (mtd->_write_oob != mxs_nand_hook_write_oob) { + nand_info->hooked_write_oob = mtd->_write_oob; + mtd->_write_oob = mxs_nand_hook_write_oob; } - if (mtd->block_markbad != mxs_nand_hook_block_markbad) { - nand_info->hooked_block_markbad = mtd->block_markbad; - mtd->block_markbad = mxs_nand_hook_block_markbad; + if (mtd->_block_markbad != mxs_nand_hook_block_markbad) { + nand_info->hooked_block_markbad = mtd->_block_markbad; + mtd->_block_markbad = mxs_nand_hook_block_markbad; } /* We use the reference implementation for bad block management. */ @@ -1058,6 +1061,8 @@ int mxs_nand_init(struct mxs_nand_info *info) { struct mxs_gpmi_regs *gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; + struct mxs_bch_regs *bch_regs = + (struct mxs_bch_regs *)MXS_BCH_BASE; int i = 0, j; info->desc = malloc(sizeof(struct mxs_dma_desc *) * @@ -1081,6 +1086,7 @@ int mxs_nand_init(struct mxs_nand_info *info) /* Reset the GPMI block. */ mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg); + mxs_reset_block(&bch_regs->hw_bch_ctrl_reg); /* * Choose NAND mode, set IRQ polarity, disable write protection and @@ -1160,6 +1166,7 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW; nand->ecc.bytes = 9; nand->ecc.size = 512; + nand->ecc.strength = 8; return 0;