]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc.h
Initial revision
[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 #define NFC_DEBUG_NONE  0
59 #define NFC_DEBUG_MIN   1
60 #define NFC_DEBUG_MED   2
61 #define NFC_DEBUG_MAX   3
62 #define NFC_DEBUG_DEF   NFC_DEBUG_NONE
63
64 #define PG_2K_DATA_OP_MULTI_CYCLES()        true
65
66 typedef unsigned short u16;
67 typedef unsigned int u32;
68 typedef unsigned char u8;
69
70 #define ADDR_INPUT_SIZE                 8
71 //----------------------------------------------------------------------------
72 // Common device details.
73 #define FLASH_Read_ID                   (0x90)
74 #if CYGHWR_DEVS_FLASH_MXC_NAND_RESET_WORKAROUND
75 #define FLASH_Reset                     0xFFFF
76 #else
77 #define FLASH_Reset                     (0xFF)
78 #endif
79 #define FLASH_Read_Mode1                (0x00)
80 #define FLASH_Read_Mode1_2K             (0x30)
81 #define FLASH_Read_Mode2                (0x01)
82 #define FLASH_Read_Mode3                (0x50)
83 #define FLASH_Program                   (0x10)
84 #define FLASH_Send_Data                 (0x80)
85 #define FLASH_Status                    (0x70)
86 #define FLASH_Block_Erase               (0x60)
87 #define FLASH_Start_Erase               (0xD0)
88
89 #define NAND_MAIN_BUF0                  (NFC_BASE + 0x000)
90 #define NAND_MAIN_BUF1                  (NFC_BASE + 0x200)
91 #define NAND_MAIN_BUF2                  (NFC_BASE + 0x400)
92 #define NAND_MAIN_BUF3                  (NFC_BASE + 0x600)
93 #define NAND_SPAR_BUF0                  (NFC_BASE + 0x800)
94 #define NAND_SPAR_BUF1                  (NFC_BASE + 0x810)
95 #define NAND_SPAR_BUF2                  (NFC_BASE + 0x820)
96 #define NAND_SPAR_BUF3                  (NFC_BASE + 0x830)
97 #define NAND_RESERVED                   (NFC_BASE + 0x840)
98
99 #define NFC_BUFSIZE_REG                 (NAND_REG_BASE + 0x00)
100 #define RAM_BUFFER_ADDRESS_REG          (NAND_REG_BASE + 0x04)
101 #define NAND_FLASH_ADD_REG              (NAND_REG_BASE + 0x06)
102 #define NAND_FLASH_CMD_REG              (NAND_REG_BASE + 0x08)
103 #define NFC_CONFIGURATION_REG           (NAND_REG_BASE + 0x0A)
104 #define ECC_STATUS_RESULT_REG           (NAND_REG_BASE + 0x0C)
105 #define ECC_RSLT_MAIN_AREA_REG          (NAND_REG_BASE + 0x0E)
106 #define ECC_RSLT_SPARE_AREA_REG         (NAND_REG_BASE + 0x10)
107 #define NF_WR_PROT_REG                  (NAND_REG_BASE + 0x12)
108 #define UNLOCK_START_BLK_ADD_REG        (NAND_REG_BASE + 0x14)
109 #define UNLOCK_END_BLK_ADD_REG          (NAND_REG_BASE + 0x16)
110 #define NAND_FLASH_WR_PR_ST_REG         (NAND_REG_BASE + 0x18)
111 #define NAND_FLASH_CONFIG1_REG          (NAND_REG_BASE + 0x1A)
112 #define NAND_FLASH_CONFIG2_REG          (NAND_REG_BASE + 0x1C)
113
114 enum nfc_internal_buf {
115     RAM_BUF_0,
116     RAM_BUF_1,
117     RAM_BUF_2,
118     RAM_BUF_3,
119 };
120
121 enum nfc_output_mode {
122     FDO_PAGE_SPARE      = 0x0008,
123     FDO_SPARE_ONLY      = 0x1008,  // LSB has to be 0x08
124     FDO_FLASH_ID        = 0x0010,
125     FDO_FLASH_STATUS    = 0x0020,
126 };
127
128 /*!
129  * Defined the "complete" address input operations which may involve
130  * more than one cycle of single address input operation.
131  */
132 enum nfc_addr_ops {
133     ADDRESS_INPUT_READ_ID,
134     ADDRESS_INPUT_READ_PAGE,
135     ADDRESS_INPUT_PROGRAM_PAGE,
136     ADDRESS_INPUT_ERASE_BLOCK,
137 };
138
139 enum nfc_page_area {
140     NFC_SPARE_ONLY,
141     NFC_MAIN_ONLY,
142 };
143
144 enum {
145     MXC_NAND_8_BIT = 8,
146     MXC_NAND_16_BIT =  16,
147 };
148
149 enum {
150     NAND_SLC = 0,
151     NAND_MLC = 1,
152 };
153
154 // read column 464-465 byte but only 464 for bad block marker
155 #define BAD_BLK_MARKER_464          (NAND_MAIN_BUF3 + 464)
156 // read column 4-5 byte, but only 5 is used for swapped main area data
157 #define BAD_BLK_MARKER_SP_5         (NAND_SPAR_BUF3 + 4)
158
159 // Polls the NANDFC to wait for an operation to complete
160 static inline void wait_op_done(void)
161 {
162         int mxc_nfc_wait_loop;
163         while (!(readw(NAND_FLASH_CONFIG2_REG) & NAND_FLASH_CONFIG2_INT_DONE)) {
164                 for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++);
165         }
166 }
167
168 int nfc_read_region(u32 la, u32 maddr, int len);
169 int nfc_program_region(u32 la, u32 maddr, int len);
170 int nfc_erase_region(u32 la, int len);
171
172
173 /*!
174  * NAND flash data output operation (reading data from NAND flash)
175  * @param buf_no    internal ram buffer number that will contain data
176  *                  to be outputted from the NAND flash after operation done
177  * @param mode      one of the mode defined in enum nfc_output_mode
178  */
179 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
180                             int ecc_en)
181 {
182     u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
183
184     config1 |= readw(NAND_FLASH_CONFIG1_REG);
185
186     if (mode == FDO_SPARE_ONLY) {
187         config1 |= NAND_FLASH_CONFIG1_SP_EN;
188 #ifdef CYGPKG_HAL_ARM_MXC91221
189         config1 &= ~NAND_FLASH_CONFIG1_ECC_EN;
190 #endif
191     }
192
193     writew(config1, NAND_FLASH_CONFIG1_REG);
194     writew(buf_no, RAM_BUFFER_ADDRESS_REG);
195     writew(mode & 0xFF, NAND_FLASH_CONFIG2_REG);
196     wait_op_done();
197 }
198
199 static void NFC_CMD_INPUT(u32 cmd)
200 {
201     writew(cmd, NAND_FLASH_CMD_REG);
202     writew(NAND_FLASH_CONFIG2_FCMD_EN, NAND_FLASH_CONFIG2_REG);
203     wait_op_done();
204 }
205
206 static u16 NFC_STATUS_READ(void)
207 {
208     u16 flash_status;
209     u16 saved = readw(NAND_MAIN_BUF0);
210
211     NFC_CMD_INPUT(FLASH_Status);
212     NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_STATUS, 1);
213     flash_status = readw(NAND_MAIN_BUF0) & 0x00FF;
214
215     // restore
216     writew(saved, NAND_MAIN_BUF0); 
217
218     return flash_status;
219 }
220
221 /*!
222  * NAND flash data input operation (writing data to NAND flash)
223  * @param buf_no    internal ram buffer number containing data to be
224  *                  written into the NAND flash
225  * @param area      NFC_SPARE_ONLY or NFC_MAIN_ONLY,
226  * @param ecc_en    1 - ecc enabled; 0 - ecc disabled
227  */
228 static void NFC_DATA_INPUT(enum nfc_internal_buf buf_no, enum nfc_page_area area,
229                            int ecc_en)
230 {
231     u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
232
233     config1 |= readw(NAND_FLASH_CONFIG1_REG);
234
235     if (area == NFC_SPARE_ONLY) {
236         config1 |= NAND_FLASH_CONFIG1_SP_EN;
237 #ifdef CYGPKG_HAL_ARM_MXC91221
238         config1 &= ~NAND_FLASH_CONFIG1_ECC_EN;
239 #endif
240     }
241
242     writew(config1, NAND_FLASH_CONFIG1_REG);
243     writew(buf_no, RAM_BUFFER_ADDRESS_REG);
244
245     // start operation
246     writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
247     wait_op_done();
248 }
249
250 static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
251 {
252     writew(buf_no, RAM_BUFFER_ADDRESS_REG);
253     writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
254     wait_op_done();
255 }
256
257 /*!
258  * The NFC has to be preset before performing any operation
259  */
260 static void NFC_PRESET(u32 max_block_count)
261 {
262     // Unlock the internal RAM buffer
263     writew(NFC_CONFIGURATION_UNLOCKED, NFC_CONFIGURATION_REG);
264     // First Block to be unlocked
265     writew(0, UNLOCK_START_BLK_ADD_REG);
266     // Last Unlock Block
267     writew(max_block_count, UNLOCK_END_BLK_ADD_REG);
268     // Unlock Block Command
269     writew(NF_WR_PROT_UNLOCK, NF_WR_PROT_REG);
270 }
271
272 /*!
273  * Issue the address input operation
274  * @param       addr    the address for the address input operation
275  */
276 static void NFC_ADDR_INPUT(u32 addr)
277 {
278     writew(addr & ((1 << ADDR_INPUT_SIZE) - 1), NAND_FLASH_ADD_REG);
279     writew(NAND_FLASH_CONFIG2_FADD_EN, NAND_FLASH_CONFIG2_REG);
280     wait_op_done();
281 }
282
283 #endif // _MXC_NFC_H_