unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / flash / arm / mxc / v2_0 / include / mxc_nfc.h
1 #ifndef _MXC_NFC_H_
2 #define _MXC_NFC_H_
3 //==========================================================================
4 //
5 //      mxc_nfc.h
6 //
7 //      Flash programming to support NAND flash on Freescale MXC platforms
8 //
9 //==========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 //
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 //
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //==========================================================================
43 //#####DESCRIPTIONBEGIN####
44 //
45 // Author(s):    Kevin Zhang <k.zhang@freescale.com>
46 // Contributors: Kevin Zhang <k.zhang@freescale.com>
47 // Date:         2006-01-23
48 // Purpose:
49 // Description:
50 //
51 //####DESCRIPTIONEND####
52 //
53 //==========================================================================
54
55 #include <pkgconf/devs_flash_onmxc.h>
56 #include "mxc_nand_specifics.h"
57
58
59 #if defined(NFC_V1_1)
60 #define PG_2K_DATA_OP_MULTI_CYCLES()    false
61 #else
62 #define PG_2K_DATA_OP_MULTI_CYCLES()    true
63 #endif
64
65 #define ADDR_INPUT_SIZE                                 8
66 #define NAND_MAIN_BUF0                                  (NFC_BASE + 0x000)
67 #define NAND_MAIN_BUF1                                  (NFC_BASE + 0x200)
68 #define NAND_MAIN_BUF2                                  (NFC_BASE + 0x400)
69 #define NAND_MAIN_BUF3                                  (NFC_BASE + 0x600)
70 #if defined(NFC_V1_1)
71 #define NAND_MAIN_BUF4                                  (NFC_BASE + 0x800)
72 #define NAND_MAIN_BUF5                                  (NFC_BASE + 0xA00)
73 #define NAND_MAIN_BUF6                                  (NFC_BASE + 0xC00)
74 #define NAND_MAIN_BUF7                                  (NFC_BASE + 0xE00)
75 #define NAND_SPAR_BUF0                                  (NFC_BASE + 0x1000)
76 #define NAND_SPAR_BUF1                                  (NFC_BASE + 0x1040)
77 #define NAND_SPAR_BUF2                                  (NFC_BASE + 0x1080)
78 #define NAND_SPAR_BUF3                                  (NFC_BASE + 0x10C0)
79 #define NAND_SPAR_BUF4                                  (NFC_BASE + 0x1100)
80 #define NAND_SPAR_BUF5                                  (NFC_BASE + 0x1140)
81 #define NAND_SPAR_BUF6                                  (NFC_BASE + 0x1180)
82 #define NAND_SPAR_BUF7                                  (NFC_BASE + 0x11C0)
83 #define NFC_BUF_COUNT                                   8
84 #define NFC_SPARE_BUF_SZ                                64
85 #else
86 #define NAND_SPAR_BUF0                                  (NFC_BASE + 0x800)
87 #define NAND_SPAR_BUF1                                  (NFC_BASE + 0x810)
88 #define NAND_SPAR_BUF2                                  (NFC_BASE + 0x820)
89 #define NAND_SPAR_BUF3                                  (NFC_BASE + 0x830)
90 #define NAND_RESERVED                                   (NFC_BASE + 0x840)
91 #define NFC_BUF_COUNT                                   4
92 #define NFC_SPARE_BUF_SZ                                16
93 #endif
94
95 #define NFC_BUFSIZE_REG                                 (NAND_REG_BASE + 0x00)
96 #define RAM_BUFFER_ADDRESS_REG                  (NAND_REG_BASE + 0x04)
97 #define NAND_FLASH_ADD_REG                              (NAND_REG_BASE + 0x06)
98 #define NAND_FLASH_CMD_REG                              (NAND_REG_BASE + 0x08)
99 #define NFC_CONFIGURATION_REG                   (NAND_REG_BASE + 0x0A)
100 #define ECC_STATUS_RESULT_REG                   (NAND_REG_BASE + 0x0C)
101 #define ECC_RSLT_MAIN_AREA_REG                  (NAND_REG_BASE + 0x0E)
102 #define ECC_RSLT_SPARE_AREA_REG                 (NAND_REG_BASE + 0x10)
103 #define NF_WR_PROT_REG                                  (NAND_REG_BASE + 0x12)
104 #define NAND_FLASH_WR_PR_ST_REG                 (NAND_REG_BASE + 0x18)
105 #define NAND_FLASH_CONFIG1_REG                  (NAND_REG_BASE + 0x1A)
106 #define NAND_FLASH_CONFIG2_REG                  (NAND_REG_BASE + 0x1C)
107 #if defined(NFC_V1_1)
108 #define UNLOCK_START_BLK_ADD_REG                (NAND_REG_BASE + 0x20)
109 #define UNLOCK_END_BLK_ADD_REG                  (NAND_REG_BASE + 0x22)
110 #define UNLOCK_START_BLK_ADD1_REG               (NAND_REG_BASE + 0x24)
111 #define UNLOCK_END_BLK_ADD1_REG                 (NAND_REG_BASE + 0x26)
112 #define UNLOCK_START_BLK_ADD2_REG               (NAND_REG_BASE + 0x28)
113 #define UNLOCK_END_BLK_ADD2_REG                 (NAND_REG_BASE + 0x2A)
114 #define UNLOCK_START_BLK_ADD3_REG               (NAND_REG_BASE + 0x2C)
115 #define UNLOCK_END_BLK_ADD3_REG                 (NAND_REG_BASE + 0x2E)
116 #else
117 #define UNLOCK_START_BLK_ADD_REG                (NAND_REG_BASE + 0x14)
118 #define UNLOCK_END_BLK_ADD_REG                  (NAND_REG_BASE + 0x16)
119 #endif
120
121 #define NUM_OF_CS_LINES                                 1
122 #define NFC_BUFSIZE                                             0
123
124 enum nfc_internal_buf {
125     RAM_BUF_0,
126     RAM_BUF_1,
127     RAM_BUF_2,
128     RAM_BUF_3,
129     RAM_BUF_4,
130     RAM_BUF_5,
131     RAM_BUF_6,
132     RAM_BUF_7,
133 };
134
135 enum nfc_output_mode {
136     FDO_PAGE_SPARE      = 0x0008,
137     FDO_SPARE_ONLY      = 0x1008,  // LSB has to be 0x08
138     FDO_FLASH_ID        = 0x0010,
139     FDO_FLASH_STATUS    = 0x0020,
140 };
141
142 #define wait_for_auto_prog_done()
143
144 // Polls the NANDFC to wait for an operation to complete
145 #define wait_op_done() CYG_MACRO_START                                                                                          \
146         volatile int mxc_nfc_wait_loop;                                                                                                 \
147         while (!(readw(NAND_FLASH_CONFIG2_REG) & NAND_FLASH_CONFIG2_INT_DONE)) {                \
148                 for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++);      \
149         }                                                                                                                                                               \
150 CYG_MACRO_END
151
152 /*!
153  * NAND flash data output operation (reading data from NAND flash)
154  * @param buf_no    internal ram buffer number that will contain data
155  *                  to be outputted from the NAND flash after operation done
156  * @param mode      one of the mode defined in enum nfc_output_mode
157  * @param ecc_en    1 - ecc enabled; 0 - ecc disabled
158  */
159 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
160                             int ecc_en)
161 {
162     u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
163
164     config1 |= readw(NAND_FLASH_CONFIG1_REG);
165
166     if (mode == FDO_SPARE_ONLY) {
167         config1 |= NAND_FLASH_CONFIG1_SP_EN;
168     }
169
170     writew(config1, NAND_FLASH_CONFIG1_REG);
171     writew(buf_no, RAM_BUFFER_ADDRESS_REG);
172     writew(mode & 0xFF, NAND_FLASH_CONFIG2_REG);
173     wait_op_done();
174 }
175
176 static void NFC_CMD_INPUT(u32 cmd)
177 {
178     writew(cmd, NAND_FLASH_CMD_REG);
179     writew(NAND_FLASH_CONFIG2_FCMD_EN, NAND_FLASH_CONFIG2_REG);
180     wait_op_done();
181 }
182
183 static u16 NFC_STATUS_READ(void)
184 {
185     u16 flash_status;
186     u16 saved = readw(NAND_MAIN_BUF0);
187
188     NFC_CMD_INPUT(FLASH_Status);
189     NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_STATUS, 1);
190     flash_status = readw(NAND_MAIN_BUF0) & 0x00FF;
191
192     // restore
193     writew(saved, NAND_MAIN_BUF0);
194
195     return flash_status;
196 }
197
198 /*!
199  * NAND flash data input operation (writing data to NAND flash)
200  * @param buf_no    internal ram buffer number containing data to be
201  *                  written into the NAND flash
202  * @param area      NFC_SPARE_ONLY or NFC_MAIN_ONLY,
203  * @param ecc_en    1 - ecc enabled; 0 - ecc disabled
204  */
205 static void NFC_DATA_INPUT(enum nfc_internal_buf buf_no, enum nfc_page_area area,
206                            int ecc_en)
207 {
208     u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
209
210     config1 |= readw(NAND_FLASH_CONFIG1_REG);
211
212     if (area == NFC_SPARE_ONLY) {
213         config1 |= NAND_FLASH_CONFIG1_SP_EN;
214 #ifdef CYGPKG_HAL_ARM_MXC91221
215         config1 &= ~NAND_FLASH_CONFIG1_ECC_EN;
216 #endif
217     }
218
219     writew(config1, NAND_FLASH_CONFIG1_REG);
220     writew(buf_no, RAM_BUFFER_ADDRESS_REG);
221
222     // start operation
223     writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
224     wait_op_done();
225 }
226
227 static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
228 {
229     writew(buf_no, RAM_BUFFER_ADDRESS_REG);
230     writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
231     wait_op_done();
232 }
233
234 /*!
235  * The NFC has to be preset before performing any operation
236  */
237 static void NFC_PRESET(u32 max_block_count)
238 {
239     // Unlock the internal RAM buffer
240     writew(NFC_CONFIGURATION_UNLOCKED, NFC_CONFIGURATION_REG);
241     // First Block to be unlocked
242     writew(0, UNLOCK_START_BLK_ADD_REG);
243     // Last Unlock Block
244     writew(max_block_count, UNLOCK_END_BLK_ADD_REG);
245     // Unlock Block Command
246     writew(NF_WR_PROT_UNLOCK, NF_WR_PROT_REG);
247 }
248
249 static void NFC_SET_NFC_ACTIVE_CS(u32 cs_line)
250 {
251     // not needed.
252 }
253
254 /*!
255  * Issue the address input operation
256  * @param       addr    the address for the address input operation
257  */
258 static void NFC_ADDR_INPUT(u32 addr)
259 {
260     writew(addr & ((1 << ADDR_INPUT_SIZE) - 1), NAND_FLASH_ADD_REG);
261     writew(NAND_FLASH_CONFIG2_FADD_EN, NAND_FLASH_CONFIG2_REG);
262     wait_op_done();
263 }
264
265 #if defined(NFC_V1_1)
266 #define NFC_ARCH_INIT() CYG_MACRO_START                         \
267         unsigned int tmp, reg;                                                  \
268         tmp = flash_dev_info->page_size / 512;                  \
269         if (flash_dev_info->spare_size) {                               \
270                 writew((flash_dev_info->spare_size >> 1),       \
271                                 ECC_RSLT_SPARE_AREA_REG);                       \
272         }                                                                                               \
273         writew(0x2, NFC_CONFIGURATION_REG);                             \
274         reg = readw(NAND_FLASH_CONFIG1_REG) | 0x800;    \
275         if ((flash_dev_info->spare_size / tmp) > 16)    \
276                 reg &= ~1;                                                                      \
277         else                                                                                    \
278                 reg |= 1;                                                                       \
279         writew(reg, NAND_FLASH_CONFIG1_REG);                    \
280 CYG_MACRO_END
281 #else
282 #define NFC_ARCH_INIT()
283 #endif /*NFC_V1_1*/
284
285 #define NAND_ADD0_REG       0xDEADDAED
286 #define NAND_ADD8_REG       0xDEADDAED
287 #define NAND_CMD_REG        0xDEADDAED
288 #define NAND_LAUNCH_AUTO_PROG        0xDEADDAED
289 #define NAND_STATUS_SUM_REG          0xDEADDAED
290 #define NAND_LAUNCH_AUTO_READ        0xDEADDAED
291 #define NAND_LAUNCH_AUTO_ERASE       0xDEADDAED
292
293 #endif // _MXC_NFC_H_