3 //==========================================================================
7 // Flash programming to support NAND flash on Freescale MXC platforms
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.
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.
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
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.
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.
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.
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####
45 // Author(s): Kevin Zhang <k.zhang@freescale.com>
46 // Contributors: Kevin Zhang <k.zhang@freescale.com>
51 //####DESCRIPTIONEND####
53 //==========================================================================
55 #include <pkgconf/devs_flash_onmxc.h>
56 #include "mxc_nand_specifics.h"
60 #define PG_2K_DATA_OP_MULTI_CYCLES() false
62 #define PG_2K_DATA_OP_MULTI_CYCLES() true
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)
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
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
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)
117 #define UNLOCK_START_BLK_ADD_REG (NAND_REG_BASE + 0x14)
118 #define UNLOCK_END_BLK_ADD_REG (NAND_REG_BASE + 0x16)
121 #define NUM_OF_CS_LINES 1
122 #define NFC_BUFSIZE 0
124 enum nfc_internal_buf {
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,
142 #define wait_for_auto_prog_done()
143 #define nfc_reg_read(a) readl(a)
144 #define nfc_reg_write(v,a) writel(v,a)
146 // Polls the NANDFC to wait for an operation to complete
147 #define wait_op_done() CYG_MACRO_START \
148 volatile int mxc_nfc_wait_loop; \
149 while (!(readw(NAND_FLASH_CONFIG2_REG) & NAND_FLASH_CONFIG2_INT_DONE)) { \
150 for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++); \
155 * NAND flash data output operation (reading data from NAND flash)
156 * @param buf_no internal ram buffer number that will contain data
157 * to be outputted from the NAND flash after operation done
158 * @param mode one of the mode defined in enum nfc_output_mode
159 * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
161 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
164 u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
166 config1 |= readw(NAND_FLASH_CONFIG1_REG);
168 if (mode == FDO_SPARE_ONLY) {
169 config1 |= NAND_FLASH_CONFIG1_SP_EN;
172 writew(config1, NAND_FLASH_CONFIG1_REG);
173 writew(buf_no, RAM_BUFFER_ADDRESS_REG);
174 writew(mode & 0xFF, NAND_FLASH_CONFIG2_REG);
178 static void NFC_CMD_INPUT(u32 cmd)
180 writew(cmd, NAND_FLASH_CMD_REG);
181 writew(NAND_FLASH_CONFIG2_FCMD_EN, NAND_FLASH_CONFIG2_REG);
185 static u16 NFC_STATUS_READ(void)
188 u16 saved = readw(NAND_MAIN_BUF0);
190 NFC_CMD_INPUT(FLASH_Status);
191 NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_STATUS, 1);
192 flash_status = readw(NAND_MAIN_BUF0) & 0x00FF;
195 writew(saved, NAND_MAIN_BUF0);
201 * NAND flash data input operation (writing data to NAND flash)
202 * @param buf_no internal ram buffer number containing data to be
203 * written into the NAND flash
204 * @param area NFC_SPARE_ONLY or NFC_MAIN_ONLY,
205 * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
207 static void NFC_DATA_INPUT(enum nfc_internal_buf buf_no, enum nfc_page_area area,
210 u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
212 config1 |= readw(NAND_FLASH_CONFIG1_REG);
214 if (area == NFC_SPARE_ONLY) {
215 config1 |= NAND_FLASH_CONFIG1_SP_EN;
216 #ifdef CYGPKG_HAL_ARM_MXC91221
217 config1 &= ~NAND_FLASH_CONFIG1_ECC_EN;
221 writew(config1, NAND_FLASH_CONFIG1_REG);
222 writew(buf_no, RAM_BUFFER_ADDRESS_REG);
225 writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
229 static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
231 writew(buf_no, RAM_BUFFER_ADDRESS_REG);
232 writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
237 * The NFC has to be preset before performing any operation
239 static void NFC_PRESET(u32 max_block_count)
241 // Unlock the internal RAM buffer
242 writew(NFC_CONFIGURATION_UNLOCKED, NFC_CONFIGURATION_REG);
243 // First Block to be unlocked
244 writew(0, UNLOCK_START_BLK_ADD_REG);
246 writew(max_block_count, UNLOCK_END_BLK_ADD_REG);
247 // Unlock Block Command
248 writew(NF_WR_PROT_UNLOCK, NF_WR_PROT_REG);
251 static void NFC_SET_NFC_ACTIVE_CS(u32 cs_line)
257 * Issue the address input operation
258 * @param addr the address for the address input operation
260 static void NFC_ADDR_INPUT(u32 addr)
262 writew(addr & ((1 << ADDR_INPUT_SIZE) - 1), NAND_FLASH_ADD_REG);
263 writew(NAND_FLASH_CONFIG2_FADD_EN, NAND_FLASH_CONFIG2_REG);
267 #if defined(NFC_V1_1)
268 #define NFC_ARCH_INIT() CYG_MACRO_START \
269 unsigned int tmp, reg; \
270 tmp = flash_dev_info->page_size / 512; \
271 if (flash_dev_info->spare_size) { \
272 writew((flash_dev_info->spare_size >> 1), \
273 ECC_RSLT_SPARE_AREA_REG); \
275 writew(0x2, NFC_CONFIGURATION_REG); \
276 reg = readw(NAND_FLASH_CONFIG1_REG) | 0x800; \
277 if ((flash_dev_info->spare_size / tmp) > 16) \
281 writew(reg, NAND_FLASH_CONFIG1_REG); \
284 #define NFC_ARCH_INIT()
287 #define NAND_ADD0_REG 0xDEADDAED
288 #define NAND_ADD8_REG 0xDEADDAED
289 #define NAND_CMD_REG 0xDEADDAED
290 #define NAND_LAUNCH_AUTO_PROG 0xDEADDAED
291 #define NAND_STATUS_SUM_REG 0xDEADDAED
292 #define NAND_LAUNCH_AUTO_READ 0xDEADDAED
293 #define NAND_LAUNCH_AUTO_ERASE 0xDEADDAED
295 #endif // _MXC_NFC_H_