From 887e2ec9ecf49366a60a49b32b73825804909865 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 7 Sep 2006 11:51:23 +0200 Subject: Add support for AMCC Sequoia PPC440EPx eval board - Add support for PPC440EPx & PPC440GRx - Add support for PPC440EP(x)/GR(x) NAND controller in cpu/ppc4xx directory - Add NAND boot functionality for Sequoia board, please see doc/README.nand-boot-ppc440 for details - This Sequoia NAND image doesn't support environment in NAND for now. This will be added in a short while. Patch by Stefan Roese, 07 Sep 2006 --- cpu/ppc4xx/ndfc.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 cpu/ppc4xx/ndfc.c (limited to 'cpu/ppc4xx/ndfc.c') diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c new file mode 100644 index 0000000..e4ab326 --- /dev/null +++ b/cpu/ppc4xx/ndfc.c @@ -0,0 +1,173 @@ +/* + * Overview: + * Platform independend driver for NDFC (NanD Flash Controller) + * integrated into EP440 cores + * + * (C) Copyright 2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * Based on original work by + * Thomas Gleixner + * Copyright 2006 IBM + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY) + +#include +#include +#include +#include + +static u8 hwctl = 0; + +static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd) +{ + switch (cmd) { + case NAND_CTL_SETCLE: + hwctl |= 0x1; + break; + + case NAND_CTL_CLRCLE: + hwctl &= ~0x1; + break; + + case NAND_CTL_SETALE: + hwctl |= 0x2; + break; + + case NAND_CTL_CLRALE: + hwctl &= ~0x2; + break; + } +} + +static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W; + + if (hwctl & 0x1) + out8(base + NDFC_CMD, byte); + else if (hwctl & 0x2) + out8(base + NDFC_ALE, byte); + else + out8(base + NDFC_DATA, byte); +} + +static u_char ndfc_read_byte(struct mtd_info *mtdinfo) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W; + + return (in8(base + NDFC_DATA)); +} + +static int ndfc_dev_ready(struct mtd_info *mtdinfo) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W; + + while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY)) + ; + + return 1; +} + +#ifndef CONFIG_NAND_SPL +/* + * Don't use these speedup functions in NAND boot image, since the image + * has to fit into 4kByte. + */ + +/* + * Speedups for buffer read/write/verify + * + * NDFC allows 32bit read/write of data. So we can speed up the buffer + * functions. No further checking, as nand_base will always read/write + * page aligned. + */ +static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W; + uint32_t *p = (uint32_t *) buf; + + for(;len > 0; len -= 4) + *p++ = in32(base + NDFC_DATA); +} + +static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W; + uint32_t *p = (uint32_t *) buf; + + for(; len > 0; len -= 4) + out32(base + NDFC_DATA, *p++); +} + +static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W; + uint32_t *p = (uint32_t *) buf; + + for(; len > 0; len -= 4) + if (*p++ != in32(base + NDFC_DATA)) + return -1; + + return 0; +} +#endif /* #ifndef CONFIG_NAND_SPL */ + +void board_nand_init(struct nand_chip *nand) +{ + nand->eccmode = NAND_ECC_SOFT; + + nand->hwcontrol = ndfc_hwcontrol; + nand->read_byte = ndfc_read_byte; + nand->write_byte = ndfc_write_byte; + nand->dev_ready = ndfc_dev_ready; + +#ifndef CONFIG_NAND_SPL + nand->write_buf = ndfc_write_buf; + nand->read_buf = ndfc_read_buf; + nand->verify_buf = ndfc_verify_buf; +#else + /* + * Setup EBC (CS0 only right now) + */ + mtdcr(ebccfga, xbcfg); + mtdcr(ebccfgd, 0xb8400000); + + mtebc(pb0cr, CFG_EBC_PB0CR); + mtebc(pb0ap, CFG_EBC_PB0AP); +#endif + + /* Set NandFlash Core Configuration Register */ + /* Chip select 3, 1col x 2 rows */ + out32(CFG_NAND_BASE + NDFC_CCR, 0x00000000 | (CFG_NAND_CS << 24)); + out32(CFG_NAND_BASE + NDFC_BCFG0 + (CFG_NAND_CS << 2), 0x80002222); +} + +#endif -- cgit v1.1