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"
58 #define PG_2K_DATA_OP_MULTI_CYCLES() false
60 //----------------------------------------------------------------------------
61 // Common device details.
62 #define NAND_MAIN_BUF0 (NFC_BASE + 0x000)
63 #define NAND_MAIN_BUF1 (NFC_BASE + 0x200)
64 #define NAND_MAIN_BUF2 (NFC_BASE + 0x400)
65 #define NAND_MAIN_BUF3 (NFC_BASE + 0x600)
66 #if defined (NFC_V2_0)
67 #define NAND_SPAR_BUF0 (NFC_BASE + 0x800)
68 #define NAND_SPAR_BUF1 (NFC_BASE + 0x810)
69 #define NAND_SPAR_BUF2 (NFC_BASE + 0x820)
70 #define NAND_SPAR_BUF3 (NFC_BASE + 0x830)
71 #define NAND_RESERVED (NFC_BASE + 0x840)
72 #define NFC_BUF_COUNT 4
73 #define NFC_SPARE_BUF_SZ 16
74 #elif defined (NFC_V2_1)
75 #define NAND_MAIN_BUF4 (NFC_BASE + 0x800)
76 #define NAND_MAIN_BUF5 (NFC_BASE + 0xA00)
77 #define NAND_MAIN_BUF6 (NFC_BASE + 0xC00)
78 #define NAND_MAIN_BUF7 (NFC_BASE + 0xE00)
79 #define NAND_SPAR_BUF0 (NFC_BASE + 0x1000)
80 #define NAND_SPAR_BUF1 (NFC_BASE + 0x1040)
81 #define NAND_SPAR_BUF2 (NFC_BASE + 0x1080)
82 #define NAND_SPAR_BUF3 (NFC_BASE + 0x10C0)
83 #define NAND_SPAR_BUF4 (NFC_BASE + 0x1100)
84 #define NAND_SPAR_BUF5 (NFC_BASE + 0x1140)
85 #define NAND_SPAR_BUF6 (NFC_BASE + 0x1180)
86 #define NAND_SPAR_BUF7 (NFC_BASE + 0x11C0)
87 #define NFC_BUF_COUNT 8
88 #define NFC_SPARE_BUF_SZ 64
93 #define ECC_STATUS_RESULT_REG (NAND_REG_BASE + 0x08)
94 #define NUM_OF_CS_LINES 1
97 #define NFC_PPB_REG NAND_CONFIGURATION2_REG
98 #define NFC_PPB_SHIFT 7
99 #define NFC_PPB_MASK ~(3 << NFC_PPB_SHIFT)
101 enum nfc_internal_buf {
102 RAM_BUF_0 = 0x0 << 4,
103 RAM_BUF_1 = 0x1 << 4,
104 RAM_BUF_2 = 0x2 << 4,
105 RAM_BUF_3 = 0x3 << 4,
106 RAM_BUF_4 = 0x4 << 4,
107 RAM_BUF_5 = 0x5 << 4,
108 RAM_BUF_6 = 0x6 << 4,
109 RAM_BUF_7 = 0x7 << 4,
110 RAM_BUF_MASK = ~(0x7 << 4),
113 enum nfc_output_mode {
114 FDO_PAGE_SPARE = 0x0008,
115 FDO_SPARE_ONLY = 0x1008, // LSB has to be 0x08
116 FDO_FLASH_ID = 0x0010,
117 FDO_FLASH_STATUS = 0x0020,
120 #define wait_for_auto_prog_done()
122 // Polls the NANDFC to wait for an operation to complete
123 #define wait_op_done() CYG_MACRO_START \
124 u32 __nfc_stat = nfc_reg_read(NFC_IPC_REG); \
125 while (!(__nfc_stat & NFC_IPC_INT)) { \
126 __nfc_stat = nfc_reg_read(NFC_IPC_REG); \
128 nfc_reg_write(__nfc_stat & ~NFC_IPC_INT, NFC_IPC_REG); \
132 #define nfc_reg_write(v, r) __nfc_reg_write(v, (void *)(r), #r, __FUNCTION__)
133 static inline void __nfc_reg_write(u32 val, void *addr,
134 const char *reg, const char *fn)
136 nfc_printf(NFC_DEBUG_MAX, "%s: Writing %08x to %s[%04lx]\n", fn, val, reg,
137 (unsigned long)addr & 0x3fff);
141 #define nfc_reg_read(r) __nfc_reg_read((void *)(r), #r, __FUNCTION__)
142 static inline u32 __nfc_reg_read(void *addr,
143 const char *reg, const char *fn)
147 nfc_printf(NFC_DEBUG_MAX, "%s: Read %08x from %s[%04lx]\n", fn, val, reg,
148 (unsigned long)addr & 0x3fff);
152 #define write_nfc_ip_reg(v, r) CYG_MACRO_START \
153 nfc_reg_write(NFC_IPC_CREQ, NFC_IPC_REG); \
154 while (!(nfc_reg_read(NFC_IPC_REG) & NFC_IPC_CACK)); \
155 __nfc_reg_write(v, (void *)(r), #r, __FUNCTION__); \
156 nfc_reg_write(0, NFC_IPC_REG); \
159 #define nfc_reg_read(r) readl(r)
160 #define nfc_reg_write(v, r) writel(v, r)
162 static void write_nfc_ip_reg(u32 val, u32 reg)
164 nfc_reg_write(NFC_IPC_CREQ, NFC_IPC_REG);
165 while (!(nfc_reg_read(NFC_IPC_REG) & NFC_IPC_CACK));
166 nfc_reg_write(val, reg);
167 nfc_reg_write(0, NFC_IPC_REG);
172 * NAND flash data output operation (reading data from NAND flash)
173 * @param buf_no internal ram buffer number that will contain data
174 * to be outputted from the NAND flash after operation done
175 * @param mode one of the mode defined in enum nfc_output_mode
176 * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
178 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
181 u32 v = nfc_reg_read(NFC_FLASH_CONFIG2_REG);
183 if ((v & NFC_FLASH_CONFIG2_ECC_EN) != 0 && ecc_en == 0) {
184 write_nfc_ip_reg(v & ~NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
186 if ((v & NFC_FLASH_CONFIG2_ECC_EN) == 0 && ecc_en != 0) {
187 write_nfc_ip_reg(v | NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
190 v = (nfc_reg_read(NAND_CONFIGURATION1_REG) & RAM_BUF_MASK) | buf_no;
191 if (mode == FDO_SPARE_ONLY) {
192 v |= NAND_CONFIGURATION1_SP_EN;
194 v &= ~NAND_CONFIGURATION1_SP_EN;
196 nfc_reg_write(v, NAND_CONFIGURATION1_REG);
198 nfc_reg_write(mode & 0xFF, NAND_LAUNCH_REG);
202 static void NFC_CMD_INPUT(u32 cmd)
204 nfc_reg_write(cmd & 0xFFFF, NAND_ADD_CMD_REG);
205 nfc_reg_write(NAND_LAUNCH_FCMD, NAND_LAUNCH_REG);
209 static u16 NFC_STATUS_READ(void)
212 u16 saved = readw(NAND_MAIN_BUF0);
214 NFC_CMD_INPUT(FLASH_Status);
215 NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_STATUS, 1);
216 flash_status = readw(NAND_MAIN_BUF0) & 0x00FF;
219 writew(saved, NAND_MAIN_BUF0);
225 * NAND flash data input operation (writing data to NAND flash)
226 * @param buf_no internal ram buffer number containing data to be
227 * written into the NAND flash
228 * @param area NFC_SPARE_ONLY or NFC_MAIN_ONLY,
229 * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
231 static void NFC_DATA_INPUT(enum nfc_internal_buf buf_no, enum nfc_page_area area,
234 u32 v = nfc_reg_read(NFC_FLASH_CONFIG2_REG);
236 // setup config2 register for ECC enable or not
237 if ((v & NFC_FLASH_CONFIG2_ECC_EN) != 0 && ecc_en == 0) {
238 write_nfc_ip_reg(v & ~NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
240 if ((v & NFC_FLASH_CONFIG2_ECC_EN) == 0 && ecc_en != 0) {
241 write_nfc_ip_reg(v | NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
244 // setup config1 register for ram buffer number, spare-only or not
245 v = (nfc_reg_read(NAND_CONFIGURATION1_REG) & RAM_BUF_MASK) | buf_no;
246 if (area == NFC_SPARE_ONLY) {
247 v |= NAND_CONFIGURATION1_SP_EN;
249 v &= ~NAND_CONFIGURATION1_SP_EN;
251 nfc_reg_write(v, NAND_CONFIGURATION1_REG);
254 nfc_reg_write(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
258 static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
262 // setup config1 register for ram buffer number, spare-only or not
263 v = (nfc_reg_read(NAND_CONFIGURATION1_REG) & RAM_BUF_MASK) | buf_no;
264 nfc_reg_write(v, NAND_CONFIGURATION1_REG);
267 nfc_reg_write(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
272 * The NFC has to be preset before performing any operation
274 static void NFC_PRESET(u32 max_block_count)
276 // not needed. It is done in plf_hardware_init()
279 static void NFC_SET_NFC_ACTIVE_CS(u32 cs_line)
285 * Issue the address input operation
286 * @param addr the address for the address input operation
288 static void NFC_ADDR_INPUT(u32 addr)
292 diag_printf("add = 0x%08x, at 0x%08lx\n",
293 (addr & 0xFF) << 16, NAND_ADD_CMD_REG);
294 diag_printf("NAND_LAUNCH_FADD=%08x, NAND_LAUNCH_REG=%08lx\n",
295 NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
298 nfc_reg_write((addr & 0xFF) << 16, NAND_ADD_CMD_REG);
299 nfc_reg_write(NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
303 #define NFC_ARCH_INIT()
304 #define NAND_ADD0_REG 0xDEADDAED
305 #define NAND_ADD8_REG 0xDEADDAED
306 #define NAND_CMD_REG 0xDEADDAED
307 #define NAND_LAUNCH_AUTO_PROG 0xDEADDAED
308 #define NAND_STATUS_SUM_REG 0xDEADDAED
309 #define NAND_LAUNCH_AUTO_READ 0xDEADDAED
310 #define NAND_LAUNCH_AUTO_ERASE 0xDEADDAED
311 #endif // _MXC_NFC_V2_H_