source: SVN/rincon/u-boot/cpu/arm920t/s3c24x0/nand.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 4.5 KB
Line 
1/*
2 * (C) Copyright 2006 OpenMoko, Inc.
3 * Author: Harald Welte <laforge@openmoko.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21#include <common.h>
22
23#if 0
24#define DEBUGN  printf
25#else
26#define DEBUGN(x, args ...) {}
27#endif
28
29#if defined(CONFIG_CMD_NAND)
30#if !defined(CONFIG_NAND_LEGACY)
31
32#include <nand.h>
33#include <s3c2410.h>
34#include <asm/io.h>
35
36#define __REGb(x)       (*(volatile unsigned char *)(x))
37#define __REGi(x)       (*(volatile unsigned int *)(x))
38
39#define NF_BASE         0x4e000000
40#define NFCONF          __REGi(NF_BASE + 0x0)
41#define NFCMD           __REGb(NF_BASE + 0x4)
42#define NFADDR          __REGb(NF_BASE + 0x8)
43#define NFDATA          __REGb(NF_BASE + 0xc)
44#define NFSTAT          __REGb(NF_BASE + 0x10)
45#define NFECC0          __REGb(NF_BASE + 0x14)
46#define NFECC1          __REGb(NF_BASE + 0x15)
47#define NFECC2          __REGb(NF_BASE + 0x16)
48
49#define S3C2410_NFCONF_EN          (1<<15)
50#define S3C2410_NFCONF_512BYTE     (1<<14)
51#define S3C2410_NFCONF_4STEP       (1<<13)
52#define S3C2410_NFCONF_INITECC     (1<<12)
53#define S3C2410_NFCONF_nFCE        (1<<11)
54#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
55#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
56#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
57
58#define S3C2410_ADDR_NALE 4
59#define S3C2410_ADDR_NCLE 8
60
61static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
62{
63        struct nand_chip *chip = mtd->priv;
64
65        DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
66
67        if (ctrl & NAND_CTRL_CHANGE) {
68                ulong IO_ADDR_W = NF_BASE;
69
70                if (!(ctrl & NAND_CLE))
71                        IO_ADDR_W |= S3C2410_ADDR_NCLE;
72                if (!(ctrl & NAND_ALE))
73                        IO_ADDR_W |= S3C2410_ADDR_NALE;
74
75                chip->IO_ADDR_W = (void *)IO_ADDR_W;
76
77                if (ctrl & NAND_NCE)
78                        NFCONF &= ~S3C2410_NFCONF_nFCE;
79                else
80                        NFCONF |= S3C2410_NFCONF_nFCE;
81        }
82
83        if (cmd != NAND_CMD_NONE)
84                writeb(cmd, chip->IO_ADDR_W);
85}
86
87static int s3c2410_dev_ready(struct mtd_info *mtd)
88{
89        DEBUGN("dev_ready\n");
90        return (NFSTAT & 0x01);
91}
92
93#ifdef CONFIG_S3C2410_NAND_HWECC
94void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
95{
96        DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
97        NFCONF |= S3C2410_NFCONF_INITECC;
98}
99
100static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
101                                      u_char *ecc_code)
102{
103        ecc_code[0] = NFECC0;
104        ecc_code[1] = NFECC1;
105        ecc_code[2] = NFECC2;
106        DEBUGN("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
107                mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
108
109        return 0;
110}
111
112static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
113                                     u_char *read_ecc, u_char *calc_ecc)
114{
115        if (read_ecc[0] == calc_ecc[0] &&
116            read_ecc[1] == calc_ecc[1] &&
117            read_ecc[2] == calc_ecc[2])
118                return 0;
119
120        printf("s3c2410_nand_correct_data: not implemented\n");
121        return -1;
122}
123#endif
124
125int board_nand_init(struct nand_chip *nand)
126{
127        u_int32_t cfg;
128        u_int8_t tacls, twrph0, twrph1;
129        S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
130
131        DEBUGN("board_nand_init()\n");
132
133        clk_power->CLKCON |= (1 << 4);
134
135        /* initialize hardware */
136        twrph0 = 3; twrph1 = 0; tacls = 0;
137
138        cfg = S3C2410_NFCONF_EN;
139        cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
140        cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
141        cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
142
143        NFCONF = cfg;
144
145        /* initialize nand_chip data structure */
146        nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e00000c;
147
148        /* read_buf and write_buf are default */
149        /* read_byte and write_byte are default */
150
151        /* hwcontrol always must be implemented */
152        nand->cmd_ctrl = s3c2410_hwcontrol;
153
154        nand->dev_ready = s3c2410_dev_ready;
155
156#ifdef CONFIG_S3C2410_NAND_HWECC
157        nand->ecc.hwctl = s3c2410_nand_enable_hwecc;
158        nand->ecc.calculate = s3c2410_nand_calculate_ecc;
159        nand->ecc.correct = s3c2410_nand_correct_data;
160        nand->ecc.mode = NAND_ECC_HW3_512;
161#else
162        nand->ecc.mode = NAND_ECC_SOFT;
163#endif
164
165#ifdef CONFIG_S3C2410_NAND_BBT
166        nand->options = NAND_USE_FLASH_BBT;
167#else
168        nand->options = 0;
169#endif
170
171        DEBUGN("end of nand_init\n");
172
173        return 0;
174}
175
176#else
177 #error "U-Boot legacy NAND support not available for S3C2410"
178#endif
179#endif
Note: See TracBrowser for help on using the repository browser.