]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/delta/nand.c
First steps implementing NAND support. Not working, fails to read ID.
[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  * hardware specific access to control-lines
33  * function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c)
34  */
35 static void delta_hwcontrol(struct mtd_info *mtdinfo, int cmd)
36 {
37 #if 0
38         struct nand_chip *this = mtdinfo->priv;
39         ulong base = (ulong) this->IO_ADDR_W;
40
41         switch(cmd) {
42         case NAND_CTL_SETCLE:
43                 MACRO_NAND_CTL_SETCLE((unsigned long)base);
44                 break;
45         case NAND_CTL_CLRCLE:
46                 MACRO_NAND_CTL_CLRCLE((unsigned long)base);
47                 break;
48         case NAND_CTL_SETALE:
49                 MACRO_NAND_CTL_SETALE((unsigned long)base);
50                 break;
51         case NAND_CTL_CLRALE:
52                 MACRO_NAND_CTL_CLRALE((unsigned long)base);
53                 break;
54         case NAND_CTL_SETNCE:
55                 MACRO_NAND_ENABLE_CE((unsigned long)base);
56                 break;
57         case NAND_CTL_CLRNCE:
58                 MACRO_NAND_DISABLE_CE((unsigned long)base);
59                 break;
60         }
61 #endif
62 }
63
64
65 /* read device ready pin */
66 static int delta_device_ready(struct mtd_info *mtdinfo)
67 {
68         if(NDSR & NDSR_RDY)
69                 return 1;
70         else
71                 return 0;
72 #if 0
73         struct nand_chip *this = mtdinfo->priv;
74         ulong rb_gpio_pin;
75
76         /* use the base addr to find out which chip are we dealing with */
77         switch((ulong) this->IO_ADDR_W) {
78         case CFG_NAND0_BASE:
79                 rb_gpio_pin = CFG_NAND0_RDY;
80                 break;
81         case CFG_NAND1_BASE:
82                 rb_gpio_pin = CFG_NAND1_RDY;
83                 break;
84         default: /* this should never happen */
85                 return 0;
86                 break;
87         }
88
89         if (in32(GPIO0_IR) & rb_gpio_pin)
90                 return 1;
91 #endif
92         return 0;
93 }
94
95 static u_char delta_read_byte(struct mtd_info *mtd)
96 {
97 /*      struct nand_chip *this = mtd->priv; */
98         unsigned long tmp;
99
100         /* wait for read request */
101         while(1) {
102                 if(NDSR & NDSR_RDDREQ) {
103                         NDSR |= NDSR_RDDREQ;
104                         break;
105                 }
106         }
107
108         tmp = NDDB;
109         printk("delta_read_byte: 0x%x.\n", tmp); 
110         return (u_char) tmp;
111 }
112
113 /* this is really monahans, not board specific ... */
114 static void delta_cmdfunc(struct mtd_info *mtd, unsigned command, 
115                           int column, int page_addr)
116 {
117         /* register struct nand_chip *this = mtd->priv; */
118         unsigned long ndcb0=0, ndcb1=0, ndcb2=0;
119         uchar command2;
120
121         /* Clear NDSR */
122         NDSR = 0xFFF;
123         
124         /* apparently NDCR[NDRUN] needs to be set before writing to NDCBx */
125         NDCR |= NDCR_ND_RUN;
126
127         /* wait for write command request 
128          * hmm, might be nice if this could time-out. mk@tbd
129          */
130         while(1) {
131                 if(NDSR & NDSR_WRCMDREQ) {
132                         NDSR |= NDSR_WRCMDREQ; /* Ack */
133                         break;
134                 }
135         }
136
137         /* if command is a double byte cmd, we set bit double cmd bit 19 */
138         command2 = (command>>8) & 0xFF;
139         ndcb0 = command | ((command2 ? 1 : 0) << 19);
140
141         switch (command) {
142         case NAND_CMD_READID:
143                 printk("delta_cmdfunc: NAND_CMD_READID.\n");
144                 ndcb0 |= ((3 << 21) | (2 << 16));
145                 break;
146         case NAND_CMD_PAGEPROG:
147         case NAND_CMD_ERASE1:
148         case NAND_CMD_ERASE2:
149         case NAND_CMD_SEQIN:
150         case NAND_CMD_STATUS:
151                 return;
152         case NAND_CMD_RESET:
153                 return;
154         default:
155                 printk("delta_cmdfunc: error, unkown command issued.\n");
156                 return;
157         }
158
159         NDCB0 = ndcb0;
160         NDCB1 = ndcb1;
161         NDCB2 = ndcb2;  
162 }
163
164 /*
165  * Board-specific NAND initialization. The following members of the
166  * argument are board-specific (per include/linux/mtd/nand_new.h):
167  * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
168  * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
169  * - hwcontrol: hardwarespecific function for accesing control-lines
170  * - dev_ready: hardwarespecific function for  accesing device ready/busy line
171  * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
172  *   only be provided if a hardware ECC is available
173  * - eccmode: mode of ecc, see defines
174  * - chip_delay: chip dependent delay for transfering data from array to
175  *   read regs (tR)
176  * - options: various chip options. They can partly be set to inform
177  *   nand_scan about special functionality. See the defines for further
178  *   explanation
179  * Members with a "?" were not set in the merged testing-NAND branch,
180  * so they are not set here either.
181  */
182 void board_nand_init(struct nand_chip *nand)
183 {
184         unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR;
185
186         /* set up GPIO Control Registers */
187         
188         /* turn on the NAND Controller Clock (104 MHz @ D0) */
189         CKENA |= (CKENA_4_NAND | CKENA_9_SMC);
190         
191         /* NAND Timing Parameters (in ns) */
192 #define NAND_TIMING_tCH         10
193 #define NAND_TIMING_tCS         0
194 #define NAND_TIMING_tWH         20
195 #define NAND_TIMING_tWP         40
196 #define NAND_TIMING_tRH         20
197 #define NAND_TIMING_tRP         40
198 #define NAND_TIMING_tR          11123
199 #define NAND_TIMING_tWHR        110
200 #define NAND_TIMING_tAR         10
201
202 /* Maximum values for NAND Interface Timing Registers in DFC clock
203  * periods */
204 #define DFC_MAX_tCH             7
205 #define DFC_MAX_tCS             7
206 #define DFC_MAX_tWH             7
207 #define DFC_MAX_tWP             7
208 #define DFC_MAX_tRH             7
209 #define DFC_MAX_tRP             15
210 #define DFC_MAX_tR              65535
211 #define DFC_MAX_tWHR            15
212 #define DFC_MAX_tAR             15
213
214 #define DFC_CLOCK               104             /* DFC Clock is 104 MHz */
215 #define DFC_CLK_PER_US          DFC_CLOCK/1000  /* clock period in ns */
216 #define MIN(x, y)               ((x < y) ? x : y)
217
218         
219         tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1), 
220                   DFC_MAX_tCH);
221         tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US) + 1), 
222                   DFC_MAX_tCS);
223         tWH = MIN(((unsigned long) (NAND_TIMING_tWH * DFC_CLK_PER_US) + 1),
224                   DFC_MAX_tWH);
225         tWP = MIN(((unsigned long) (NAND_TIMING_tWP * DFC_CLK_PER_US) + 1),
226                   DFC_MAX_tWP);
227         tRH = MIN(((unsigned long) (NAND_TIMING_tRH * DFC_CLK_PER_US) + 1),
228                   DFC_MAX_tRH);
229         tRP = MIN(((unsigned long) (NAND_TIMING_tRP * DFC_CLK_PER_US) + 1),
230                   DFC_MAX_tRP);
231         tR = MIN(((unsigned long) (NAND_TIMING_tR * DFC_CLK_PER_US) + 1),
232                  DFC_MAX_tR);
233         tWHR = MIN(((unsigned long) (NAND_TIMING_tWHR * DFC_CLK_PER_US) + 1),
234                    DFC_MAX_tWHR);
235         tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) + 1),
236                   DFC_MAX_tAR);
237         
238
239         /* tRP value is split in the register */
240         if(tRP & (1 << 4)) {
241                 tRP_high = 1;
242                 tRP &= ~(1 << 4);
243         } else {
244                 tRP_high = 0;
245         }
246
247         NDTR0CS0 = (tCH << 19) |
248                 (tCS << 16) |
249                 (tWH << 11) |
250                 (tWP << 8) |
251                 (tRP_high << 6) |
252                 (tRH << 3) |
253                 (tRP << 0);
254         
255         NDTR1CS0 = (tR << 16) |
256                 (tWHR << 4) |
257                 (tAR << 0);
258
259         
260
261         /* If it doesn't work (unlikely) think about:
262          *  - ecc enable
263          *  - chip select don't care
264          *  - read id byte count
265          *
266          * Intentionally enabled by not setting bits:
267          *  - dma (DMA_EN)
268          *  - page size = 512
269          *  - cs don't care, see if we can enable later!
270          *  - row address start position (after second cycle)
271          *  - pages per block = 32
272          */
273         NDCR = (NDCR_ND_ARB_EN |        /* enable bus arbiter */
274                 NDCR_SPARE_EN |         /* use the spare area */
275                 NDCR_DWIDTH_C |         /* 16bit DFC data bus width  */
276                 NDCR_DWIDTH_M |         /* 16 bit Flash device data bus width */
277                 (2 << 16) |             /* read id count = 7 ???? mk@tbd */
278                 NDCE_RDYM |             /* flash device ready ir masked */
279                 NDCE_CS0_PAGEDM |       /* ND_nCSx page done ir masked */
280                 NDCE_CS1_PAGEDM |
281                 NDCE_CS0_CMDDM |        /* ND_CSx command done ir masked */
282                 NDCE_CS1_CMDDM |
283                 NDCE_CS0_BBDM |         /* ND_CSx bad block detect ir masked */
284                 NDCE_CS1_BBDM |
285                 NDCE_DBERRM |           /* double bit error ir masked */ 
286                 NDCE_SBERRM |           /* single bit error ir masked */
287                 NDCE_WRDREQM |          /* write data request ir masked */
288                 NDCE_RDDREQM |          /* read data request ir masked */
289                 NDCE_WRCMDREQM);        /* write command request ir masked */
290         
291         
292         
293         nand->hwcontrol = delta_hwcontrol;
294         nand->dev_ready = delta_device_ready;
295         nand->eccmode = NAND_ECC_SOFT;
296         nand->chip_delay = NAND_DELAY_US;
297         nand->options = NAND_BUSWIDTH_16;
298         nand->read_byte = delta_read_byte;
299         nand->cmdfunc = delta_cmdfunc;
300         /*      nand->options = NAND_SAMSUNG_LP_OPTIONS; */
301 }
302
303 #else
304 #error "U-Boot legacy NAND support not available for delta board."
305 #endif
306 #endif