uboot/drivers/mtd/nand/kmeter1_nand.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009
   3 * Heiko Schocher, DENX Software Engineering, hs@denx.de
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25#include <nand.h>
  26#include <asm/io.h>
  27
  28#define CONFIG_NAND_MODE_REG    (void *)(CONFIG_SYS_NAND_BASE + 0x20000)
  29#define CONFIG_NAND_DATA_REG    (void *)(CONFIG_SYS_NAND_BASE + 0x30000)
  30
  31#define read_mode()     in_8(CONFIG_NAND_MODE_REG)
  32#define write_mode(val) out_8(CONFIG_NAND_MODE_REG, val)
  33#define read_data()     in_8(CONFIG_NAND_DATA_REG)
  34#define write_data(val) out_8(CONFIG_NAND_DATA_REG, val)
  35
  36#define KPN_RDY2        (1 << 7)
  37#define KPN_RDY1        (1 << 6)
  38#define KPN_WPN         (1 << 4)
  39#define KPN_CE2N        (1 << 3)
  40#define KPN_CE1N        (1 << 2)
  41#define KPN_ALE         (1 << 1)
  42#define KPN_CLE         (1 << 0)
  43
  44#define KPN_DEFAULT_CHIP_DELAY 50
  45
  46static int kpn_chip_ready(void)
  47{
  48        if (read_mode() & KPN_RDY1)
  49                return 1;
  50
  51        return 0;
  52}
  53
  54static void kpn_wait_rdy(void)
  55{
  56        int cnt = 1000000;
  57
  58        while (--cnt && !kpn_chip_ready())
  59                udelay(1);
  60
  61        if (!cnt)
  62                printf ("timeout while waiting for RDY\n");
  63}
  64
  65static void kpn_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
  66{
  67        u8 reg_val = read_mode();
  68
  69        if (ctrl & NAND_CTRL_CHANGE) {
  70                reg_val = reg_val & ~(KPN_ALE + KPN_CLE);
  71
  72                if (ctrl & NAND_CLE)
  73                        reg_val = reg_val | KPN_CLE;
  74                if (ctrl & NAND_ALE)
  75                        reg_val = reg_val | KPN_ALE;
  76                if (ctrl & NAND_NCE)
  77                        reg_val = reg_val & ~KPN_CE1N;
  78                else
  79                        reg_val = reg_val | KPN_CE1N;
  80
  81                write_mode(reg_val);
  82        }
  83        if (cmd != NAND_CMD_NONE)
  84                write_data(cmd);
  85
  86        /* wait until flash is ready */
  87        kpn_wait_rdy();
  88}
  89
  90static u_char kpn_nand_read_byte(struct mtd_info *mtd)
  91{
  92        return read_data();
  93}
  94
  95static void kpn_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
  96{
  97        int i;
  98
  99        for (i = 0; i < len; i++) {
 100                write_data(buf[i]);
 101                kpn_wait_rdy();
 102        }
 103}
 104
 105static void kpn_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 106{
 107        int i;
 108
 109        for (i = 0; i < len; i++)
 110                buf[i] = read_data();
 111}
 112
 113static int kpn_nand_dev_ready(struct mtd_info *mtd)
 114{
 115        kpn_wait_rdy();
 116
 117        return 1;
 118}
 119
 120int board_nand_init(struct nand_chip *nand)
 121{
 122        nand->ecc.mode = NAND_ECC_SOFT;
 123
 124        /* Reference hardware control function */
 125        nand->cmd_ctrl  = kpn_nand_hwcontrol;
 126        nand->read_byte  = kpn_nand_read_byte;
 127        nand->write_buf  = kpn_nand_write_buf;
 128        nand->read_buf   = kpn_nand_read_buf;
 129        nand->dev_ready  = kpn_nand_dev_ready;
 130        nand->chip_delay = KPN_DEFAULT_CHIP_DELAY;
 131
 132        /* reset mode register */
 133        write_mode(KPN_CE1N + KPN_CE2N + KPN_WPN);
 134        return 0;
 135}
 136