Commit 795cf011 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

+nand functions

parent 057cb78b
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_SPL_NAND_DRIVERS
NORMAL_DRIVERS=y
endif
obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
obj-$(CONFIG_SPL_NAND_ELPHEL393) += elphel393_nand_spl.o
obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o
obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o
obj-$(CONFIG_SPL_NAND_INIT) += nand.o
ifeq ($(CONFIG_SPL_ENV_SUPPORT),y)
obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o
endif
else # not spl
NORMAL_DRIVERS=y
obj-y += nand.o
obj-y += nand_bbt.o
obj-y += nand_ids.o
obj-y += nand_util.o
obj-y += nand_ecc.o
obj-y += nand_base.o
obj-y += nand_timings.o
endif # not spl
ifdef NORMAL_DRIVERS
obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
obj-$(CONFIG_NAND_ARASAN) += arasan_nfc.o
obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
obj-$(CONFIG_NAND_DENALI) += denali.o
obj-$(CONFIG_NAND_DENALI_DT) += denali_dt.o
obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
obj-$(CONFIG_NAND_FSMC) += fsmc_nand.o
obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o
obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o
obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o
obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o
obj-$(CONFIG_NAND_MXC) += mxc_nand.o
obj-$(CONFIG_NAND_MXS) += mxs_nand.o
obj-$(CONFIG_NAND_MXS_DT) += mxs_nand_dt.o
obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
obj-$(CONFIG_NAND_SPEAR) += spr_nand.o
obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
obj-$(CONFIG_NAND_PLAT) += nand_plat.o
obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o
else # minimal SPL drivers
obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o
endif # drivers
/*
* Elphel393 NAND driver for SPL, not based on denali_spl.c
*
* Copyright (C) 2016 Elphel, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <malloc.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <nand.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
extern nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
static int is_badblock(struct mtd_info *mtd, loff_t offs, int allowbbt)
{
register struct nand_chip *chip = mtd->priv;
unsigned int block = offs >> chip->phys_erase_shift;
unsigned int page = offs >> chip->page_shift;
unsigned long data_width = 4;
debug(" is_badblock(): offs=0x%08x block=%d page=%d\n",(int)offs,block,page);
chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
chip->read_buf(mtd, chip->oob_poi, (mtd->oobsize - data_width));
printf(" is_badblock(): offs=0x%08x block=0x%08x page=0x%08x chip->oob_poi[0]=0x%08x\n",(u32)offs,(u32)block,(u32)page,(u32)chip->oob_poi[0]);
return chip->oob_poi[0] != 0xff;
}
//dst or buf - destination in RAM
//offs - u-boot-dtb.img offset in NAND
//size - size of u-boot-dtb.img
int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
{
struct nand_chip *chip;
struct mtd_info *mtd;
unsigned int page;
unsigned int nand_page_per_block;
unsigned int sz = 0;
debug("\nnand_spl_load_image(): offs=0x%08x size=%d (0x%08x) buf_addr=0x%08x\n",offs,size,size,buf);
udelay(10000);
//if (mxs_nand_init()) return -ENODEV;
mtd = &nand_info[0];
//mtd.priv = &nand_chip;
chip = mtd->priv;
page = offs >> chip->page_shift;
nand_page_per_block = mtd->erasesize / mtd->writesize;
debug("%s offset:0x%08x len:%d page:%d\n", __func__, offs, size, page);
debug(" nand_page_per_block= %d\n",nand_page_per_block);
debug(" mtd->writesize= %d\n",mtd->writesize);
debug(" u-boot-dtb.img size is: %d (0x%08x)\n",size,size);
size = roundup(size, mtd->writesize);
debug(" u-boot-dtb.img size after roundup is:%d\n",size);
while (sz < size) {
//if (mxs_read_page_ecc(&mtd, buf, page) < 0)
// return -1;
//printf(" Reading from NAND, offset:0x%08x page_index:%d to MEM address:0x%08x\n",offs, page, buf);
chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
udelay(500);
//read min
chip->read_buf(mtd,buf,min(size-sz, mtd->writesize));
//chip->ecc.read_page(mtd, chip, buf, 0, page);
sz += mtd->writesize;
offs += mtd->writesize;
page++;
buf += mtd->writesize;
/*
* Check if we have crossed a block boundary, and if so
* check for bad block.
*/
//on-die ecc is enabled
//if (!(page % nand_page_per_block)) {
// /*
// * Yes, new block. See if this block is good. If not,
// * loop until we find a good block.
// */
// while (is_badblock(&mtd, offs, 1)) {
// page = page + nand_page_per_block;
// /* Check we've reached the end of flash. */
// if (page >= mtd->size >> chip->page_shift)
// return -ENOMEM;
// }
//}
}
return 0;
}
/* already defined in nand.c
// nand_init() - initialize data to make nand usable by SPL
void nand_init(void)
{
puts("nand_init()\n");
udelay(5000);
board_nand_init();
}
*/
void nand_deselect(void) {
debug("nand_deselect()\n");
udelay(10000);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment