]> git.sur5r.net Git - u-boot/blob - board/delta/nand.c
Moved the waiting loop for "Read Data Request" RDDREQ into the
[u-boot] / board / delta / nand.c
1 /*
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
31 /*
32  * not required for Monahans DFC
33  */
34 static void delta_hwcontrol(struct mtd_info *mtdinfo, int cmd)
35 {
36         return;
37 }
38
39 /* read device ready pin */
40 static int delta_device_ready(struct mtd_info *mtdinfo)
41 {
42         if(NDSR & NDSR_RDY)
43                 return 1;
44         else
45                 return 0;
46         return 0;
47 }
48
49 /* The original:
50  * static void delta_read_buf(struct mtd_info *mtd, const u_char *buf, int len)
51  *
52  * Shouldn't this be "u_char * const buf" ?
53  */
54 static void delta_read_buf(struct mtd_info *mtd, u_char* const buf, int len)
55 {
56         int i, j;
57
58         /* we have to be carefull not to overflow the buffer if len is
59          * not a multiple of 4 */
60         unsigned long num_words = len & 0xfffffffc;
61         unsigned long rest = len & 0x3;
62
63         /* if there are any, first copy multiple of 4 bytes */
64         if(num_words) {
65                 for(i=0; i<num_words; i+=4) {
66                         unsigned long *long_buf = &buf[i];
67 /*                      ((unsigned long *) &buf[i]) = NDDB; */
68                         *long_buf = NDDB;
69                 }
70         }
71         
72         /* ...then the rest */
73         if(rest) {
74                 unsigned long rest_data = NDDB;
75                 for(j=0;j<rest;j++)
76                         buf[i+j] = (u_char) ((rest_data>>j) & 0xff);
77         }
78
79         return;
80 }
81
82 /* global var, too bad */
83 static unsigned long read_buf = 0;
84 static unsigned char bytes_read = 0;
85
86 /* wait for read request */
87 static void delta_wait_event(unsigned long event)
88 {
89         if(!event)
90                 return;
91         
92         while(1) {
93                 if(NDSR & event) {
94                         NDSR |= event;
95                         break;
96                 }
97         }
98 }
99 static u_char delta_read_byte(struct mtd_info *mtd)
100 {
101 /*      struct nand_chip *this = mtd->priv; */
102         unsigned char byte;
103
104         if(bytes_read == 0) {
105                 read_buf = NDDB;
106                 printk("delta_read_byte: 0x%x.\n", read_buf);   
107         }
108         byte = (unsigned char) (read_buf>>(8 * bytes_read++));
109         if(bytes_read >= 4)
110                 bytes_read = 0;
111
112         printf("delta_read_byte: returning 0x%x.\n", byte);
113         return byte;
114 }
115
116 /* this is really monahans, not board specific ... */
117 static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, 
118                           int column, int page_addr)
119 {
120         /* register struct nand_chip *this = mtd->priv; */
121         unsigned long ndcb0=0, ndcb1=0, ndcb2=0, event=0;
122
123         /* clear the ugly byte read buffer */
124         bytes_read = 0;
125         read_buf = 0;
126         
127         /* Clear NDSR */
128         NDSR = 0xFFF;
129         
130         /* apparently NDCR[NDRUN] needs to be set before writing to NDCBx */
131         NDCR |= NDCR_ND_RUN;
132
133         /* wait for write command request 
134          * hmm, might be nice if this could time-out. mk@tbd
135          */
136         while(1) {
137                 if(NDSR & NDSR_WRCMDREQ) {
138                         NDSR |= NDSR_WRCMDREQ; /* Ack */
139                         break;
140                 }
141         }
142
143         /* if command is a double byte cmd, we set bit double cmd bit 19  */
144         /*      command2 = (command>>8) & 0xFF;  */
145         /*      ndcb0 = command | ((command2 ? 1 : 0) << 19); *\/ */
146
147         switch (command) {
148         case NAND_CMD_READ0:
149                 ndcb0 = (NAND_CMD_READ0 | (4<<16));
150                 column >>= 1; /* adjust for 16 bit bus */
151                 ndcb1 = (((column>>1) & 0xff) |
152                          ((page_addr<<8) & 0xff00) |
153                          ((page_addr<<8) & 0xff0000) |
154                          ((page_addr<<8) & 0xff000000)); /* make this 0x01000000 ? */
155                 event = NDSR_RDDREQ;
156                 break;  
157         case NAND_CMD_READID:
158                 printk("delta_cmdfunc: NAND_CMD_READID.\n");
159                 ndcb0 = (NAND_CMD_READID | (3 << 21) | (1 << 16)); /* addr cycles*/
160                 event = NDSR_RDDREQ;
161                 break;
162         case NAND_CMD_PAGEPROG:
163                 break;
164         case NAND_CMD_ERASE1:
165         case NAND_CMD_ERASE2:
166                 break;
167         case NAND_CMD_SEQIN:
168                 ndcb0 = (NAND_CMD_SEQIN<<8) | (1<<19) | (4<<16);
169                 if(column >= mtd->oobblock) {
170                         /* OOB area */
171                         column -= mtd->oobblock;
172                         ndcb0 |= NAND_CMD_READOOB;
173                 } else if (column < 256) {
174                         /* First 256 bytes --> READ0 */
175                         ndcb0 |= NAND_CMD_READ0;
176                 } else {
177                         /* Only for 8 bit devices - not delta!!! */
178                         column -= 256;
179                         ndcb0 |= NAND_CMD_READ1;
180                 }
181                 break;
182         case NAND_CMD_STATUS:
183                 return;
184         case NAND_CMD_RESET:
185                 return;
186         default:
187                 printk("delta_cmdfunc: error, unsupported command.\n");
188                 return;
189         }
190
191         NDCB0 = ndcb0;
192         NDCB0 = ndcb1;
193         NDCB0 = ndcb2;
194
195         /* wait for event */
196         delta_wait_event(event);
197 }
198
199 static void delta_dfc_gpio_init()
200 {
201         printf("Setting up DFC GPIO's.\n");
202
203         /* no idea what is done here, see zylonite.c */
204         GPIO4 = 0x1;
205         
206         DF_ALE_WE1 = 0x00000001;
207         DF_ALE_WE2 = 0x00000001;
208         DF_nCS0 = 0x00000001;
209         DF_nCS1 = 0x00000001;
210         DF_nWE = 0x00000001;
211         DF_nRE = 0x00000001;
212         DF_IO0 = 0x00000001;
213         DF_IO8 = 0x00000001;
214         DF_IO1 = 0x00000001;
215         DF_IO9 = 0x00000001;
216         DF_IO2 = 0x00000001;
217         DF_IO10 = 0x00000001;
218         DF_IO3 = 0x00000001;
219         DF_IO11 = 0x00000001;
220         DF_IO4 = 0x00000001;
221         DF_IO12 = 0x00000001;
222         DF_IO5 = 0x00000001;
223         DF_IO13 = 0x00000001;
224         DF_IO6 = 0x00000001;
225         DF_IO14 = 0x00000001;
226         DF_IO7 = 0x00000001;
227         DF_IO15 = 0x00000001;
228
229         DF_nWE = 0x1901;
230         DF_nRE = 0x1901;
231         DF_CLE_NOE = 0x1900;
232         DF_ALE_WE1 = 0x1901;
233         DF_INT_RnB = 0x1900;
234 }
235
236 /*
237  * Board-specific NAND initialization. The following members of the
238  * argument are board-specific (per include/linux/mtd/nand_new.h):
239  * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
240  * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
241  * - hwcontrol: hardwarespecific function for accesing control-lines
242  * - dev_ready: hardwarespecific function for  accesing device ready/busy line
243  * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
244  *   only be provided if a hardware ECC is available
245  * - eccmode: mode of ecc, see defines
246  * - chip_delay: chip dependent delay for transfering data from array to
247  *   read regs (tR)
248  * - options: various chip options. They can partly be set to inform
249  *   nand_scan about special functionality. See the defines for further
250  *   explanation
251  * Members with a "?" were not set in the merged testing-NAND branch,
252  * so they are not set here either.
253  */
254 void wait(unsigned long us)
255 {
256 #define OSCR_CLK_FREQ 3.250 /* kHz */
257
258         unsigned long start = OSCR;
259         unsigned long delta = 0, cur;
260         us *= OSCR_CLK_FREQ;
261
262         while (delta < us) {
263                 cur = OSCR;
264                 if(cur < start) /* OSCR overflowed */
265                         delta = cur + (start^0xffffffff);
266                 else
267                         delta = cur - start;
268         }
269 }
270
271 void board_nand_init(struct nand_chip *nand)
272 {
273         unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR;
274
275         /* set up GPIO Control Registers */
276         delta_dfc_gpio_init();
277
278         /* turn on the NAND Controller Clock (104 MHz @ D0) */
279         CKENA |= (CKENA_4_NAND | CKENA_9_SMC);
280
281         /* wait ? */
282 /*      printf("stupid loop start...\n"); */
283 /*      wait(200); */
284 /*      printf("stupid loop end.\n"); */
285                 
286
287         /* NAND Timing Parameters (in ns) */
288 #define NAND_TIMING_tCH         10
289 #define NAND_TIMING_tCS         0
290 #define NAND_TIMING_tWH         20
291 #define NAND_TIMING_tWP         40
292 /* #define NAND_TIMING_tRH      20 */
293 /* #define NAND_TIMING_tRP      40 */
294
295 #define NAND_TIMING_tRH         25
296 #define NAND_TIMING_tRP         50
297
298 #define NAND_TIMING_tR          11123
299 #define NAND_TIMING_tWHR        110
300 #define NAND_TIMING_tAR         10
301
302 /* Maximum values for NAND Interface Timing Registers in DFC clock
303  * periods */
304 #define DFC_MAX_tCH             7
305 #define DFC_MAX_tCS             7
306 #define DFC_MAX_tWH             7
307 #define DFC_MAX_tWP             7
308 #define DFC_MAX_tRH             7
309 #define DFC_MAX_tRP             15
310 #define DFC_MAX_tR              65535
311 #define DFC_MAX_tWHR            15
312 #define DFC_MAX_tAR             15
313
314 #define DFC_CLOCK               104             /* DFC Clock is 104 MHz */
315 #define DFC_CLK_PER_US          DFC_CLOCK/1000  /* clock period in ns */
316 #define MIN(x, y)               ((x < y) ? x : y)
317
318         
319         tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1), 
320                   DFC_MAX_tCH);
321         tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US) + 1), 
322                   DFC_MAX_tCS);
323         tWH = MIN(((unsigned long) (NAND_TIMING_tWH * DFC_CLK_PER_US) + 1),
324                   DFC_MAX_tWH);
325         tWP = MIN(((unsigned long) (NAND_TIMING_tWP * DFC_CLK_PER_US) + 1),
326                   DFC_MAX_tWP);
327         tRH = MIN(((unsigned long) (NAND_TIMING_tRH * DFC_CLK_PER_US) + 1),
328                   DFC_MAX_tRH);
329         tRP = MIN(((unsigned long) (NAND_TIMING_tRP * DFC_CLK_PER_US) + 1),
330                   DFC_MAX_tRP);
331         tR = MIN(((unsigned long) (NAND_TIMING_tR * DFC_CLK_PER_US) + 1),
332                  DFC_MAX_tR);
333         tWHR = MIN(((unsigned long) (NAND_TIMING_tWHR * DFC_CLK_PER_US) + 1),
334                    DFC_MAX_tWHR);
335         tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) + 1),
336                   DFC_MAX_tAR);
337         
338
339         printf("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);
340
341         /* tRP value is split in the register */
342         if(tRP & (1 << 4)) {
343                 tRP_high = 1;
344                 tRP &= ~(1 << 4);
345         } else {
346                 tRP_high = 0;
347         }
348
349         NDTR0CS0 = (tCH << 19) |
350                 (tCS << 16) |
351                 (tWH << 11) |
352                 (tWP << 8) |
353                 (tRP_high << 6) |
354                 (tRH << 3) |
355                 (tRP << 0);
356         
357         NDTR1CS0 = (tR << 16) |
358                 (tWHR << 4) |
359                 (tAR << 0);
360
361         
362
363         /* If it doesn't work (unlikely) think about:
364          *  - ecc enable
365          *  - chip select don't care
366          *  - read id byte count
367          *
368          * Intentionally enabled by not setting bits:
369          *  - dma (DMA_EN)
370          *  - page size = 512
371          *  - cs don't care, see if we can enable later!
372          *  - row address start position (after second cycle)
373          *  - pages per block = 32
374          *  - ND_RDY : clears command buffer
375          */
376         NDCR = (NDCR_SPARE_EN |         /* use the spare area */
377                 NDCR_DWIDTH_C |         /* 16bit DFC data bus width  */
378                 NDCR_DWIDTH_M |         /* 16 bit Flash device data bus width */
379                 NDCR_NCSX |             /* Chip select busy don't care */
380                 (7 << 16) |             /* read id count = 7 ???? mk@tbd */
381                 NDCR_ND_ARB_EN |        /* enable bus arbiter */
382                 NDCR_RDYM |             /* flash device ready ir masked */
383                 NDCR_CS0_PAGEDM |       /* ND_nCSx page done ir masked */
384                 NDCR_CS1_PAGEDM |
385                 NDCR_CS0_CMDDM |        /* ND_CSx command done ir masked */
386                 NDCR_CS1_CMDDM |
387                 NDCR_CS0_BBDM |         /* ND_CSx bad block detect ir masked */
388                 NDCR_CS1_BBDM |
389                 NDCR_DBERRM |           /* double bit error ir masked */ 
390                 NDCR_SBERRM |           /* single bit error ir masked */
391                 NDCR_WRDREQM |          /* write data request ir masked */
392                 NDCR_RDDREQM |          /* read data request ir masked */
393                 NDCR_WRCMDREQM);        /* write command request ir masked */
394         
395
396         /* wait 10 us due to cmd buffer clear reset */
397 /*      wait(10); */
398         
399         
400         nand->hwcontrol = delta_hwcontrol;
401 /*      nand->dev_ready = delta_device_ready; */
402         nand->eccmode = NAND_ECC_SOFT;
403         nand->chip_delay = NAND_DELAY_US;
404         nand->options = NAND_BUSWIDTH_16;
405         nand->read_byte = delta_read_byte;
406         nand->read_buf = delta_read_buf;
407         nand->cmdfunc = delta_cmdfunc;
408         /*      nand->options = NAND_SAMSUNG_LP_OPTIONS; */
409 }
410
411 #else
412 #error "U-Boot legacy NAND support not available for delta board."
413 #endif
414 #endif