blob: 9f882a52b95be5aaefc51576f047345eb3b6c7d9 [file] [log] [blame]
Markus Klotzbücher69493282006-02-28 18:05:25 +01001/*
2 * (C) Copyright 2006 DENX Software Engineering
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include <common.h>
24
25#if (CONFIG_COMMANDS & CFG_CMD_NAND)
26#ifdef CONFIG_NEW_NAND_CODE
27
28#include <nand.h>
29#include <asm/arch/pxa-regs.h>
30
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +010031/* mk@tbd move this to pxa-regs */
32#define OSCR_CLK_FREQ 3.250 /* MHz */
33
34#define CFG_DFC_DEBUG1
35#define CFG_DFC_DEBUG2
36
37#ifdef CFG_DFC_DEBUG1
38# define DFC_DEBUG1(fmt, args...) printf(fmt, ##args)
39#else
40# define DFC_DEBUG1(fmt, args...)
41#endif
42
43#ifdef CFG_DFC_DEBUG2
44# define DFC_DEBUG2(fmt, args...) printf(fmt, ##args)
45#else
46# define DFC_DEBUG2(fmt, args...)
47#endif
48
49static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
50
51static struct nand_bbt_descr delta_bbt_descr = {
52 .options = 0,
53 .offs = 0,
54 .len = 2,
55 .pattern = scan_ff_pattern
56};
57
58static struct nand_oobinfo delta_oob = {
59 .useecc = MTD_NANDECC_AUTOPLACE,
60 .eccbytes = 6,
61 .eccpos = {2, 3, 4, 5, 6, 7},
62 .oobfree = { {8, 2}, {12, 4} }
63};
64
65
Markus Klotzbücher69493282006-02-28 18:05:25 +010066/*
Markus Klotzbücher481911c2006-03-01 23:33:27 +010067 * not required for Monahans DFC
Markus Klotzbücher69493282006-02-28 18:05:25 +010068 */
69static void delta_hwcontrol(struct mtd_info *mtdinfo, int cmd)
70{
Markus Klotzbücher481911c2006-03-01 23:33:27 +010071 return;
Markus Klotzbücher69493282006-02-28 18:05:25 +010072}
73
Markus Klotzbücher69493282006-02-28 18:05:25 +010074/* read device ready pin */
75static int delta_device_ready(struct mtd_info *mtdinfo)
76{
77 if(NDSR & NDSR_RDY)
78 return 1;
79 else
80 return 0;
Markus Klotzbücher69493282006-02-28 18:05:25 +010081 return 0;
82}
83
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +010084/*
85 * Write buf to the DFC Controller Data Buffer
86 */
87static void delta_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
88{
89 unsigned long bytes_multi = len & 0xfffffffc;
90 unsigned long rest = len & 0x3;
91 unsigned long *long_buf;
92 int i;
93
94 if(bytes_multi) {
95 for(i=0; i<bytes_multi; i+=4) {
96 long_buf = (unsigned long*) &buf[i];
97 NDDB = *long_buf;
98 }
99 }
100 if(rest) {
101 printf("delta_write_buf: ERROR, writing non 4-byte aligned data.\n");
102 }
103 return;
104}
105
106
107/*
108 * These functions are quite problematic for the DFC. Luckily they are
109 * not used in the current nand code, except for nand_command, which
110 * we've defined our own anyway. The problem is, that we always need
111 * to write 4 bytes to the DFC Data Buffer, but in these functions we
112 * don't know if to buffer the bytes/half words until we've gathered 4
113 * bytes or if to send them straight away.
114 *
115 * Solution: Don't use these with Mona's DFC and complain loudly.
116 */
117static void delta_write_word(struct mtd_info *mtd, u16 word)
118{
119 printf("delta_write_word: WARNING, this function does not work with the Monahans DFC!\n");
120}
121static void delta_write_byte(struct mtd_info *mtd, u_char byte)
122{
123 printf("delta_write_byte: WARNING, this function does not work with the Monahans DFC!\n");
124}
125
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100126/* The original:
127 * static void delta_read_buf(struct mtd_info *mtd, const u_char *buf, int len)
128 *
129 * Shouldn't this be "u_char * const buf" ?
130 */
131static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len)
Markus Klotzbücher69493282006-02-28 18:05:25 +0100132{
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100133 int i, j;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100134
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100135 /* we have to be carefull not to overflow the buffer if len is
136 * not a multiple of 4 */
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100137 unsigned long bytes_multi = len & 0xfffffffc;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100138 unsigned long rest = len & 0x3;
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100139 unsigned long *long_buf;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100140
141 /* if there are any, first copy multiple of 4 bytes */
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100142 if(bytes_multi) {
143 for(i=0; i<bytes_multi; i+=4) {
144 long_buf = (unsigned long*) &buf[i];
Markus Klotzbücherbb1ff042006-03-02 12:10:01 +0100145 *long_buf = NDDB;
146 }
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100147 }
148
149 /* ...then the rest */
150 if(rest) {
151 unsigned long rest_data = NDDB;
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100152 for(j=0;j<rest; j++)
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100153 buf[i+j] = (u_char) ((rest_data>>j) & 0xff);
154 }
155
156 return;
157}
158
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100159/*
160 * read a word. Not implemented as not used in NAND code.
161 */
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100162static u16 delta_read_word(struct mtd_info *mtd)
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100163{
164 printf("delta_write_byte: UNIMPLEMENTED.\n");
165}
166
167/* global var, too bad: mk@tbd: move to ->priv pointer */
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100168static unsigned long read_buf = 0;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100169static int bytes_read = -1;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100170
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100171/* read a byte from NDDB Because we can only read 4 bytes from NDDB at
172 * a time, we buffer the remaining bytes. The buffer is reset when a
173 * new command is sent to the chip.
174 */
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100175static u_char delta_read_byte(struct mtd_info *mtd)
176{
177/* struct nand_chip *this = mtd->priv; */
178 unsigned char byte;
179
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100180 if(bytes_read < 0) {
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100181 read_buf = NDDB;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100182 bytes_read = 0;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100183 }
184 byte = (unsigned char) (read_buf>>(8 * bytes_read++));
185 if(bytes_read >= 4)
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100186 bytes_read = -1;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100187
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100188 DFC_DEBUG2("delta_read_byte: byte %u: 0x%x of (0x%x).\n", bytes_read, byte, read_buf);
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100189 return byte;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100190}
191
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100192/* calculate delta between OSCR values start and now */
193static unsigned long get_delta(unsigned long start)
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100194{
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100195 unsigned long cur = OSCR;
196
197 if(cur < start) /* OSCR overflowed */
198 return (cur + (start^0xffffffff));
199 else
200 return (cur - start);
201}
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100202
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100203/* delay function, this doesn't belong here */
204static void wait_us(unsigned long us)
205{
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100206 unsigned long start = OSCR;
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100207 us *= OSCR_CLK_FREQ;
208
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100209 while (get_delta(start) < us) {
210 /* do nothing */
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100211 }
212}
213
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100214static void delta_clear_nddb()
215{
216 NDCR &= ~NDCR_ND_RUN;
217 wait_us(CFG_NAND_OTHER_TO);
218}
219
220/* wait_event with timeout */
221static unsigned long delta_wait_event2(unsigned long event)
222{
223 unsigned long ndsr, timeout, start = OSCR;
224
225 if(!event)
226 return 0xff000000;
227 else if(event & (NDSR_CS0_CMDD | NDSR_CS0_BBD))
228 timeout = CFG_NAND_PROG_ERASE_TO * OSCR_CLK_FREQ;
229 else
230 timeout = CFG_NAND_OTHER_TO * OSCR_CLK_FREQ;
231
232 while(1) {
233 ndsr = NDSR;
234 if(ndsr & event) {
235 NDSR |= event;
236 break;
237 }
238 if(get_delta(start) > timeout) {
239 DFC_DEBUG1("delta_wait_event: TIMEOUT waiting for event: 0x%x.\n", event);
240 return 0xff000000;
241 }
242
243 }
244 return ndsr;
245}
246
247
248#if DEADCODE
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100249/* poll the NAND Controller Status Register for event */
250static void delta_wait_event(unsigned long event)
251{
252 if(!event)
253 return;
254
255 while(1) {
256 if(NDSR & event) {
257 NDSR |= event;
258 break;
259 }
260 }
261}
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100262#endif
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100263
264/* we don't always wan't to do this */
265static void delta_new_cmd()
266{
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100267 int retry = 0;
268 unsigned long status;
269
270 while(retry++ <= CFG_NAND_SENDCMD_RETRY) {
271 /* Clear NDSR */
272 NDSR = 0xFFF;
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100273
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100274 /* set NDCR[NDRUN] */
275 if(!(NDCR & NDCR_ND_RUN))
276 NDCR |= NDCR_ND_RUN;
277
278 status = delta_wait_event2(NDSR_WRCMDREQ);
279
280 if(status & NDSR_WRCMDREQ)
281 return;
282
283 DFC_DEBUG2("delta_new_cmd: FAILED to get WRITECMDREQ, retry: %d.\n", retry);
284 delta_clear_nddb();
285 }
286 DFC_DEBUG1("delta_new_cmd: giving up after %d retries.\n", retry);
287
288#if DEADCODE
289 while(1) {
290 if(NDSR & NDSR_WRCMDREQ) {
291 NDSR |= NDSR_WRCMDREQ; /* Ack */
292 break;
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100293 }
294 }
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100295#endif
296
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100297}
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100298/* this function is called after Programm and Erase Operations to
299 * check for success or failure */
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100300static int delta_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
301{
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100302 unsigned long ndsr=0, event=0;
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100303
304 /* mk@tbd set appropriate timeouts */
305 /* if (state == FL_ERASING) */
306 /* timeo = CFG_HZ * 400; */
307 /* else */
308 /* timeo = CFG_HZ * 20; */
309 if(state == FL_WRITING) {
310 event = NDSR_CS0_CMDD | NDSR_CS0_BBD;
311 } else if(state == FL_ERASING) {
Markus Klotzbücherf8785e92006-03-03 20:13:43 +0100312 event = NDSR_CS0_CMDD | NDSR_CS0_BBD;
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100313 }
314
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100315 ndsr = delta_wait_event2(event);
316
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100317 if((ndsr & NDSR_CS0_BBD) || (ndsr & 0xff000000))
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100318 return(0x1); /* Status Read error */
319 return 0;
320}
321
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100322/* cmdfunc send commands to the DFC */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100323static void delta_cmdfunc(struct mtd_info *mtd, unsigned command,
324 int column, int page_addr)
325{
326 /* register struct nand_chip *this = mtd->priv; */
Markus Klotzbüchere2053f92006-03-02 14:02:36 +0100327 unsigned long ndcb0=0, ndcb1=0, ndcb2=0, event=0;
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100328 unsigned long what_the_hack;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100329
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100330 /* clear the ugly byte read buffer */
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100331 bytes_read = -1;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100332 read_buf = 0;
333
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100334 /* if command is a double byte cmd, we set bit double cmd bit 19 */
335 /* command2 = (command>>8) & 0xFF; */
336 /* ndcb0 = command | ((command2 ? 1 : 0) << 19); *\/ */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100337
338 switch (command) {
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100339 case NAND_CMD_READ0:
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100340 delta_new_cmd();
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100341 ndcb0 = (NAND_CMD_READ0 | (4<<16));
342 column >>= 1; /* adjust for 16 bit bus */
343 ndcb1 = (((column>>1) & 0xff) |
344 ((page_addr<<8) & 0xff00) |
345 ((page_addr<<8) & 0xff0000) |
346 ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */
Markus Klotzbüchere2053f92006-03-02 14:02:36 +0100347 event = NDSR_RDDREQ;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100348 goto write_cmd;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100349 case NAND_CMD_READID:
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100350 delta_new_cmd();
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100351 DFC_DEBUG2("delta_cmdfunc: NAND_CMD_READID.\n");
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100352 ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/
Markus Klotzbüchere2053f92006-03-02 14:02:36 +0100353 event = NDSR_RDDREQ;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100354 goto write_cmd;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100355 case NAND_CMD_PAGEPROG:
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100356 /* sent as a multicommand in NAND_CMD_SEQIN */
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100357 DFC_DEBUG2("delta_cmdfunc: NAND_CMD_PAGEPROG empty due to multicmd.\n");
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100358 goto end;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100359 case NAND_CMD_ERASE1:
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100360 DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE1.\n");
Markus Klotzbücherf8785e92006-03-03 20:13:43 +0100361 delta_new_cmd();
362 ndcb0 = (0xd060 | (1<<25) | (2<<21) | (1<<19) | (3<<16));
363 ndcb1 = (page_addr & 0x00ffffff);
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100364 goto write_cmd;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100365 case NAND_CMD_ERASE2:
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100366 DFC_DEBUG2("delta_cmdfunc: NAND_CMD_ERASE2 empty due to multicmd.\n");
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100367 goto end;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100368 case NAND_CMD_SEQIN:
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100369 /* send PAGE_PROG command(0x1080) */
370 delta_new_cmd();
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100371 DFC_DEBUG2("delta_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG.\n");
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100372 ndcb0 = (0x1080 | (1<<25) | (1<<21) | (1<<19) | (4<<16));
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100373 column >>= 1; /* adjust for 16 bit bus */
374 ndcb1 = (((column>>1) & 0xff) |
375 ((page_addr<<8) & 0xff00) |
376 ((page_addr<<8) & 0xff0000) |
377 ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */
378 event = NDSR_WRDREQ;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100379 goto write_cmd;
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100380/* case NAND_CMD_SEQIN_pointer_operation: */
381
382/* /\* This is confusing because the command names are */
383/* * different compared to the ones in the K9K12Q0C */
384/* * datasheet. Infact this has nothing to do with */
385/* * reading, as the but with page programming */
386/* * (writing). */
387/* * Here we send the multibyte commands */
388/* * cmd1=0x00, cmd2=0x80 (for programming main area) or */
389/* * cmd1=0x50, cmd2=0x80 (for spare area) */
390/* * */
391/* * When all data is written to the buffer, the page */
392/* * program command (0x10) is sent to actually write */
393/* * the data. */
394/* *\/ */
395
396/* printf("delta_cmdfunc: NAND_CMD_SEQIN pointer op called.\n"); */
397
398/* ndcb0 = (NAND_CMD_SEQIN<<8) | (1<<21) | (1<<19) | (4<<16); */
399/* if(column >= mtd->oobblock) { */
400/* /\* OOB area *\/ */
401/* column -= mtd->oobblock; */
402/* ndcb0 |= NAND_CMD_READOOB; */
403/* } else if (column < 256) { */
404/* /\* First 256 bytes --> READ0 *\/ */
405/* ndcb0 |= NAND_CMD_READ0; */
406/* } else { */
407/* /\* Only for 8 bit devices - not delta!!! *\/ */
408/* column -= 256; */
409/* ndcb0 |= NAND_CMD_READ1; */
410/* } */
411/* event = NDSR_WRDREQ; */
412/* break; */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100413 case NAND_CMD_STATUS:
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100414 DFC_DEBUG2("delta_cmdfunc: NAND_CMD_STATUS.\n");
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100415 /* oh, this is not nice. for some reason the real
416 * status byte is in the second read from the data
417 * buffer. The hack is to read the first byte right
418 * here, so the next read access by the nand code
419 * yields the right one.
420 */
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100421 delta_new_cmd();
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100422 ndcb0 = NAND_CMD_STATUS | (4<<21);
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100423 event = NDSR_RDDREQ;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100424#undef READ_STATUS_BUG
Markus Klotzbücher24e12172006-03-03 16:09:28 +0100425#ifdef READ_STATUS_BUG
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100426 NDCB0 = ndcb0;
427 NDCB0 = ndcb1;
428 NDCB0 = ndcb2;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100429 delta_wait_event2(event);
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100430 what_the_hack = NDDB;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100431 if(what_the_hack != 0xffffffff) {
432 DFC_DEBUG2("what the hack.\n");
433 read_buf = what_the_hack;
434 bytes_read = 0;
435 }
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100436 goto end;
Markus Klotzbücher24e12172006-03-03 16:09:28 +0100437#endif
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100438 goto write_cmd;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100439 case NAND_CMD_RESET:
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100440 DFC_DEBUG2("delta_cmdfunc: NAND_CMD_RESET.\n");
441 ndcb0 = NAND_CMD_RESET | (5<<21);
442 event = NDSR_CS0_CMDD;
443 goto write_cmd;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100444 default:
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100445 printk("delta_cmdfunc: error, unsupported command.\n");
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100446 goto end;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100447 }
448
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100449 write_cmd:
Markus Klotzbücher69493282006-02-28 18:05:25 +0100450 NDCB0 = ndcb0;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100451 NDCB0 = ndcb1;
452 NDCB0 = ndcb2;
Markus Klotzbüchere2053f92006-03-02 14:02:36 +0100453
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100454 wait_event:
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100455 delta_wait_event2(event);
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100456 end:
457 return;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100458}
459
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100460static void delta_dfc_gpio_init()
Markus Klotzbücher00c35bd2006-02-28 22:51:01 +0100461{
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100462 DFC_DEBUG2("Setting up DFC GPIO's.\n");
Markus Klotzbücher00c35bd2006-02-28 22:51:01 +0100463
464 /* no idea what is done here, see zylonite.c */
465 GPIO4 = 0x1;
466
467 DF_ALE_WE1 = 0x00000001;
468 DF_ALE_WE2 = 0x00000001;
469 DF_nCS0 = 0x00000001;
470 DF_nCS1 = 0x00000001;
471 DF_nWE = 0x00000001;
472 DF_nRE = 0x00000001;
473 DF_IO0 = 0x00000001;
474 DF_IO8 = 0x00000001;
475 DF_IO1 = 0x00000001;
476 DF_IO9 = 0x00000001;
477 DF_IO2 = 0x00000001;
478 DF_IO10 = 0x00000001;
479 DF_IO3 = 0x00000001;
480 DF_IO11 = 0x00000001;
481 DF_IO4 = 0x00000001;
482 DF_IO12 = 0x00000001;
483 DF_IO5 = 0x00000001;
484 DF_IO13 = 0x00000001;
485 DF_IO6 = 0x00000001;
486 DF_IO14 = 0x00000001;
487 DF_IO7 = 0x00000001;
488 DF_IO15 = 0x00000001;
489
490 DF_nWE = 0x1901;
491 DF_nRE = 0x1901;
492 DF_CLE_NOE = 0x1900;
493 DF_ALE_WE1 = 0x1901;
494 DF_INT_RnB = 0x1900;
495}
496
Markus Klotzbücher69493282006-02-28 18:05:25 +0100497/*
498 * Board-specific NAND initialization. The following members of the
499 * argument are board-specific (per include/linux/mtd/nand_new.h):
500 * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
501 * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
502 * - hwcontrol: hardwarespecific function for accesing control-lines
503 * - dev_ready: hardwarespecific function for accesing device ready/busy line
504 * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
505 * only be provided if a hardware ECC is available
506 * - eccmode: mode of ecc, see defines
507 * - chip_delay: chip dependent delay for transfering data from array to
508 * read regs (tR)
509 * - options: various chip options. They can partly be set to inform
510 * nand_scan about special functionality. See the defines for further
511 * explanation
512 * Members with a "?" were not set in the merged testing-NAND branch,
513 * so they are not set here either.
514 */
515void board_nand_init(struct nand_chip *nand)
516{
517 unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR;
518
519 /* set up GPIO Control Registers */
Markus Klotzbücher00c35bd2006-02-28 22:51:01 +0100520 delta_dfc_gpio_init();
521
Markus Klotzbücher69493282006-02-28 18:05:25 +0100522 /* turn on the NAND Controller Clock (104 MHz @ D0) */
523 CKENA |= (CKENA_4_NAND | CKENA_9_SMC);
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100524
525 /* wait ? */
526/* printf("stupid loop start...\n"); */
527/* wait(200); */
528/* printf("stupid loop end.\n"); */
529
530
Markus Klotzbücher69493282006-02-28 18:05:25 +0100531 /* NAND Timing Parameters (in ns) */
532#define NAND_TIMING_tCH 10
533#define NAND_TIMING_tCS 0
534#define NAND_TIMING_tWH 20
535#define NAND_TIMING_tWP 40
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100536
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100537#define NAND_TIMING_tRH 20
538#define NAND_TIMING_tRP 40
539
540/* #define NAND_TIMING_tRH 25 */
541/* #define NAND_TIMING_tRP 50 */
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100542
Markus Klotzbücher69493282006-02-28 18:05:25 +0100543#define NAND_TIMING_tR 11123
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100544/* #define NAND_TIMING_tWHR 110 */
545#define NAND_TIMING_tWHR 100
Markus Klotzbücher69493282006-02-28 18:05:25 +0100546#define NAND_TIMING_tAR 10
547
548/* Maximum values for NAND Interface Timing Registers in DFC clock
549 * periods */
550#define DFC_MAX_tCH 7
551#define DFC_MAX_tCS 7
552#define DFC_MAX_tWH 7
553#define DFC_MAX_tWP 7
554#define DFC_MAX_tRH 7
555#define DFC_MAX_tRP 15
556#define DFC_MAX_tR 65535
557#define DFC_MAX_tWHR 15
558#define DFC_MAX_tAR 15
559
560#define DFC_CLOCK 104 /* DFC Clock is 104 MHz */
561#define DFC_CLK_PER_US DFC_CLOCK/1000 /* clock period in ns */
562#define MIN(x, y) ((x < y) ? x : y)
563
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100564
565#ifndef CFG_TIMING_TIGHT
Markus Klotzbücher69493282006-02-28 18:05:25 +0100566 tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1),
567 DFC_MAX_tCH);
568 tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US) + 1),
569 DFC_MAX_tCS);
570 tWH = MIN(((unsigned long) (NAND_TIMING_tWH * DFC_CLK_PER_US) + 1),
571 DFC_MAX_tWH);
572 tWP = MIN(((unsigned long) (NAND_TIMING_tWP * DFC_CLK_PER_US) + 1),
573 DFC_MAX_tWP);
574 tRH = MIN(((unsigned long) (NAND_TIMING_tRH * DFC_CLK_PER_US) + 1),
575 DFC_MAX_tRH);
576 tRP = MIN(((unsigned long) (NAND_TIMING_tRP * DFC_CLK_PER_US) + 1),
577 DFC_MAX_tRP);
578 tR = MIN(((unsigned long) (NAND_TIMING_tR * DFC_CLK_PER_US) + 1),
579 DFC_MAX_tR);
580 tWHR = MIN(((unsigned long) (NAND_TIMING_tWHR * DFC_CLK_PER_US) + 1),
581 DFC_MAX_tWHR);
582 tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) + 1),
583 DFC_MAX_tAR);
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100584#else /* this is the tight timing */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100585
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100586 tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US)),
587 DFC_MAX_tCH);
588 tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US)),
589 DFC_MAX_tCS);
590 tWH = MIN(((unsigned long) (NAND_TIMING_tWH * DFC_CLK_PER_US)),
591 DFC_MAX_tWH);
592 tWP = MIN(((unsigned long) (NAND_TIMING_tWP * DFC_CLK_PER_US)),
593 DFC_MAX_tWP);
594 tRH = MIN(((unsigned long) (NAND_TIMING_tRH * DFC_CLK_PER_US)),
595 DFC_MAX_tRH);
596 tRP = MIN(((unsigned long) (NAND_TIMING_tRP * DFC_CLK_PER_US)),
597 DFC_MAX_tRP);
598 tR = MIN(((unsigned long) (NAND_TIMING_tR * DFC_CLK_PER_US) - tCH - 2),
599 DFC_MAX_tR);
600 tWHR = MIN(((unsigned long) (NAND_TIMING_tWHR * DFC_CLK_PER_US) - tCH - 2),
601 DFC_MAX_tWHR);
602 tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) - 2),
603 DFC_MAX_tAR);
604#endif /* CFG_TIMING_TIGHT */
605
606
607 DFC_DEBUG2("tCH=%u, tCS=%u, tWH=%u, tWP=%u, tRH=%u, tRP=%u, tR=%u, tWHR=%u, tAR=%u.\n", tCH, tCS, tWH, tWP, tRH, tRP, tR, tWHR, tAR);
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100608
Markus Klotzbücher69493282006-02-28 18:05:25 +0100609 /* tRP value is split in the register */
610 if(tRP & (1 << 4)) {
611 tRP_high = 1;
612 tRP &= ~(1 << 4);
613 } else {
614 tRP_high = 0;
615 }
616
617 NDTR0CS0 = (tCH << 19) |
618 (tCS << 16) |
619 (tWH << 11) |
620 (tWP << 8) |
621 (tRP_high << 6) |
622 (tRH << 3) |
623 (tRP << 0);
624
625 NDTR1CS0 = (tR << 16) |
626 (tWHR << 4) |
627 (tAR << 0);
628
629
630
631 /* If it doesn't work (unlikely) think about:
632 * - ecc enable
633 * - chip select don't care
634 * - read id byte count
635 *
636 * Intentionally enabled by not setting bits:
637 * - dma (DMA_EN)
638 * - page size = 512
639 * - cs don't care, see if we can enable later!
640 * - row address start position (after second cycle)
641 * - pages per block = 32
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100642 * - ND_RDY : clears command buffer
Markus Klotzbücher69493282006-02-28 18:05:25 +0100643 */
Markus Klotzbücherf8785e92006-03-03 20:13:43 +0100644 /* NDCR_NCSX | /\* Chip select busy don't care *\/ */
645
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100646 NDCR = (NDCR_SPARE_EN | /* use the spare area */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100647 NDCR_DWIDTH_C | /* 16bit DFC data bus width */
648 NDCR_DWIDTH_M | /* 16 bit Flash device data bus width */
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100649 (7 << 16) | /* read id count = 7 ???? mk@tbd */
650 NDCR_ND_ARB_EN | /* enable bus arbiter */
651 NDCR_RDYM | /* flash device ready ir masked */
652 NDCR_CS0_PAGEDM | /* ND_nCSx page done ir masked */
653 NDCR_CS1_PAGEDM |
654 NDCR_CS0_CMDDM | /* ND_CSx command done ir masked */
655 NDCR_CS1_CMDDM |
656 NDCR_CS0_BBDM | /* ND_CSx bad block detect ir masked */
657 NDCR_CS1_BBDM |
658 NDCR_DBERRM | /* double bit error ir masked */
659 NDCR_SBERRM | /* single bit error ir masked */
660 NDCR_WRDREQM | /* write data request ir masked */
661 NDCR_RDDREQM | /* read data request ir masked */
662 NDCR_WRCMDREQM); /* write command request ir masked */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100663
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100664
665 /* wait 10 us due to cmd buffer clear reset */
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100666 /* wait(10); */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100667
668
669 nand->hwcontrol = delta_hwcontrol;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100670/* nand->dev_ready = delta_device_ready; */
Markus Klotzbücher69493282006-02-28 18:05:25 +0100671 nand->eccmode = NAND_ECC_SOFT;
672 nand->chip_delay = NAND_DELAY_US;
673 nand->options = NAND_BUSWIDTH_16;
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100674 nand->waitfunc = delta_wait;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100675 nand->read_byte = delta_read_byte;
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100676 nand->write_byte = delta_write_byte;
677 nand->read_word = delta_read_word;
678 nand->write_word = delta_write_word;
Markus Klotzbücher481911c2006-03-01 23:33:27 +0100679 nand->read_buf = delta_read_buf;
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100680 nand->write_buf = delta_write_buf;
Markus Klotzbücher9187a352006-03-03 15:37:01 +0100681
Markus Klotzbücher69493282006-02-28 18:05:25 +0100682 nand->cmdfunc = delta_cmdfunc;
Markus Klotzbücherbf7cac02006-03-04 18:35:51 +0100683 nand->autooob = &delta_oob;
684 nand->badblock_pattern = &delta_bbt_descr;
Markus Klotzbücher69493282006-02-28 18:05:25 +0100685}
686
687#else
Markus Klotzbücher19fdeff2006-03-03 12:11:11 +0100688 #error "U-Boot legacy NAND support not available for delta board."
Markus Klotzbücher69493282006-02-28 18:05:25 +0100689#endif
690#endif