X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=board%2Fprodrive%2Falpr%2Fnand.c;h=50e8d82b4b38efcbe9af59981fd05a1fbbe3650b;hb=3765b3e7bd0f8e46914d417f29cbcb0c72b1acf7;hp=bd9ba3560e9e8a58a3b14e84299ab1a551bcfe41;hpb=64cd52efd1dc51a4a5a0cf10efe5362fab27de29;p=u-boot diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c index bd9ba3560e..50e8d82b4b 100644 --- a/board/prodrive/alpr/nand.c +++ b/board/prodrive/alpr/nand.c @@ -2,89 +2,34 @@ * (C) Copyright 2006 * Heiko Schocher, DENX Software Engineering, hs@denx.de * - * 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. + * (C) Copyright 2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. * - * 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 + * SPDX-License-Identifier: GPL-2.0+ */ #include -#include -#if (CONFIG_COMMANDS & CFG_CMD_NAND) +#if defined(CONFIG_CMD_NAND) +#include #include -#if 0 -#define HS_printf(fmt,arg...) \ - printf("HS %s %s: " fmt,__FILE__, __FUNCTION__, ##arg) -#else -#define HS_printf(fmt,arg...) \ - do { } while (0) -#endif - -#if 0 -#define CPLD_REG uchar -#else -#define CPLD_REG u16 -#endif - struct alpr_ndfc_regs { - CPLD_REG cmd[4]; - CPLD_REG addr_wait; - CPLD_REG term; - CPLD_REG dummy; - uchar dum2[2]; - CPLD_REG data; + u8 cmd[4]; + u8 addr_wait; + u8 term; + u8 dummy; + u8 dummy2; + u8 data; }; static u8 hwctl; -static struct alpr_ndfc_regs *alpr_ndfc; -static int alpr_chip = 0; - -#if 1 -static int pdnb3_nand_dev_ready(struct mtd_info *mtd); - -#if 1 -static u_char alpr_read (void *padr) { - return (u_char )*((u16 *)(padr)); -} -#else -static u_char alpr_read (void *padr) { - u16 hilf; - u_char ret = 0; - hilf = *((u16 *)(padr)); - ret = hilf; -printf("%p hilf: %x ret: %x\n", padr, hilf, ret); - return ret; -} -#endif +static struct alpr_ndfc_regs *alpr_ndfc = NULL; -static void alpr_write (u_char byte, void *padr) { -HS_printf("%p Byte: %x\n", padr, byte); - *(volatile u16 *)padr = (u16)(byte); -} +#define readb(addr) (u8)(*(volatile u8 *)(addr)) +#define writeb(d,addr) *(volatile u8 *)(addr) = ((u8)(d)) -#elif 0 -#define alpr_read(a) (*(volatile u16 *) (a)) -#define alpr_write(a, b) ((*(volatile u16 *) (a)) = (b)) -#else -#define alpr_read(a) readw(a) -#define alpr_write(a, b) writew(a, b) -#endif /* * The ALPR has a NAND Flash Controller (NDFC) that handles all accesses to * the NAND devices. The NDFC has command, address and data registers that @@ -93,179 +38,99 @@ HS_printf("%p Byte: %x\n", padr, byte); * We can then use this information in the read and write functions to * determine which NDFC register to access. * - * There are 2 NAND devices on the board, a Hynix HY27US08561A (32 MByte). + * There are 2 NAND devices on the board, a Hynix HY27US08561A (1 GByte). */ -static void pdnb3_nand_hwcontrol(struct mtd_info *mtd, int cmd) +static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { -HS_printf("cmd: %x\n", 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; - case NAND_CTL_SETNCE: - break; - case NAND_CTL_CLRNCE: - alpr_write(0x00, &(alpr_ndfc->term)); - break; + struct nand_chip *this = mtd->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + hwctl |= 0x1; + else + hwctl &= ~0x1; + if ( ctrl & NAND_ALE ) + hwctl |= 0x2; + else + hwctl &= ~0x2; + if ( (ctrl & NAND_NCE) != NAND_NCE) + writeb(0x00, &(alpr_ndfc->term)); } + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } -static void pdnb3_nand_write_byte(struct mtd_info *mtd, u_char byte) -{ -HS_printf("hwctl: %x %x %x %x\n", hwctl, byte, &(alpr_ndfc->cmd[alpr_chip]), &(alpr_ndfc->addr_wait)); - if (hwctl & 0x1) - alpr_write(byte, &(alpr_ndfc->cmd[alpr_chip])); - else if (hwctl & 0x2) { - alpr_write(byte, &(alpr_ndfc->addr_wait)); - } else - alpr_write(byte, &(alpr_ndfc->data)); -} - -static u_char pdnb3_nand_read_byte(struct mtd_info *mtd) +static u_char alpr_nand_read_byte(struct mtd_info *mtd) { - return alpr_read(&(alpr_ndfc->data)); + return readb(&(alpr_ndfc->data)); } -static void pdnb3_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +static void alpr_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { + struct nand_chip *nand = mtd->priv; int i; -/*printf("%s chip:%d hwctl:%x size:%d\n", __FUNCTION__, alpr_chip, hwctl, len);*/ for (i = 0; i < len; i++) { if (hwctl & 0x1) - alpr_write(buf[i], &(alpr_ndfc->cmd[alpr_chip])); - else if (hwctl & 0x2) { - alpr_write(buf[i], &(alpr_ndfc->addr_wait)); - } else { - alpr_write(buf[i], &(alpr_ndfc->data)); - /*printf("i: %d\n", i);*/ - } + /* + * IO_ADDR_W used as CMD[i] reg to support multiple NAND + * chips. + */ + writeb(buf[i], nand->IO_ADDR_W); + else if (hwctl & 0x2) + writeb(buf[i], &(alpr_ndfc->addr_wait)); + else + writeb(buf[i], &(alpr_ndfc->data)); } } -static void pdnb3_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +static void alpr_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { int i; for (i = 0; i < len; i++) { - buf[i] = alpr_read(&(alpr_ndfc->data)); + buf[i] = readb(&(alpr_ndfc->data)); } } -static int pdnb3_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) +static int alpr_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) { int i; for (i = 0; i < len; i++) - if (buf[i] != alpr_read(&(alpr_ndfc->data))) + if (buf[i] != readb(&(alpr_ndfc->data))) return i; return 0; } -static int pdnb3_nand_dev_ready(struct mtd_info *mtd) +static int alpr_nand_dev_ready(struct mtd_info *mtd) { -#if 1 - volatile u_char val; - -/*printf("%s aufruf\n", __FUNCTION__);*/ /* * Blocking read to wait for NAND to be ready */ - val = alpr_read(&(alpr_ndfc->addr_wait)); + (void)readb(&(alpr_ndfc->addr_wait)); /* * Return always true */ return 1; -#else - u8 hwctl_org = hwctl; - unsigned long timeo; - u8 val; - - hwctl = 0x01; - pdnb3_nand_write_byte (mtd, NAND_CMD_STATUS); - hwctl = hwctl_org; - - reset_timer(); - while (1) { - if (get_timer(0) > timeo) { - printf("Timeout!"); - return 0; - } - -val = pdnb3_nand_read_byte(mtd); -/*printf("%s val: %x\n", __FUNCTION__, val);*/ - if (val & NAND_STATUS_READY) - break; - } - return 1; -#endif - } -static void alpr_select_chip(struct mtd_info *mtd, int chip) +int board_nand_init(struct nand_chip *nand) { - alpr_chip = chip; -} - -static int alpr_nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) -{ - unsigned long timeo; - - if (state == FL_ERASING) - timeo = CFG_HZ * 400; - else - timeo = CFG_HZ * 20; - - if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) - this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1); - else - this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); + alpr_ndfc = (struct alpr_ndfc_regs *)CONFIG_SYS_NAND_BASE; - reset_timer(); + nand->ecc.mode = NAND_ECC_SOFT; - while (1) { - if (get_timer(0) > timeo) { - printf("Timeout!"); - return 0; - } - - if (this->read_byte(mtd) & NAND_STATUS_READY) - break; - } - return this->read_byte(mtd); -} - -void board_nand_init(struct nand_chip *nand) -{ - alpr_ndfc = (struct alpr_ndfc_regs *)CFG_NAND_BASE; - - nand->eccmode = NAND_ECC_SOFT; - - /* Set address of NAND IO lines (Using Linear Data Access Region) */ - nand->IO_ADDR_R = (void __iomem *) ((ulong) alpr_ndfc + 0x10); - nand->IO_ADDR_W = (void __iomem *) ((ulong) alpr_ndfc + 0x10); /* Reference hardware control function */ - nand->hwcontrol = pdnb3_nand_hwcontrol; - /* Set command delay time */ - nand->hwcontrol = pdnb3_nand_hwcontrol; - nand->write_byte = pdnb3_nand_write_byte; - nand->read_byte = pdnb3_nand_read_byte; - nand->write_buf = pdnb3_nand_write_buf; - nand->read_buf = pdnb3_nand_read_buf; - nand->verify_buf = pdnb3_nand_verify_buf; - nand->dev_ready = pdnb3_nand_dev_ready; - nand->select_chip = alpr_select_chip; - nand->waitfunc = alpr_nand_wait; + nand->cmd_ctrl = alpr_nand_hwcontrol; + nand->read_byte = alpr_nand_read_byte; + nand->write_buf = alpr_nand_write_buf; + nand->read_buf = alpr_nand_read_buf; + nand->verify_buf = alpr_nand_verify_buf; + nand->dev_ready = alpr_nand_dev_ready; + + return 0; } #endif