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