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 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
64 #define PG_2K_DATA_OP_MULTI_CYCLES() true
66 typedef unsigned short u16;
67 typedef unsigned int u32;
68 typedef unsigned char u8;
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
77 #define FLASH_Reset (0xFF)
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)
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)
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)
114 enum nfc_internal_buf {
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,
129 * Defined the "complete" address input operations which may involve
130 * more than one cycle of single address input operation.
133 ADDRESS_INPUT_READ_ID,
134 ADDRESS_INPUT_READ_PAGE,
135 ADDRESS_INPUT_PROGRAM_PAGE,
136 ADDRESS_INPUT_ERASE_BLOCK,
146 MXC_NAND_16_BIT = 16,
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)
159 // Polls the NANDFC to wait for an operation to complete
160 static inline void wait_op_done(void)
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++);
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);
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
179 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
182 u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
184 config1 |= readw(NAND_FLASH_CONFIG1_REG);
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;
193 writew(config1, NAND_FLASH_CONFIG1_REG);
194 writew(buf_no, RAM_BUFFER_ADDRESS_REG);
195 writew(mode & 0xFF, NAND_FLASH_CONFIG2_REG);
199 static void NFC_CMD_INPUT(u32 cmd)
201 writew(cmd, NAND_FLASH_CMD_REG);
202 writew(NAND_FLASH_CONFIG2_FCMD_EN, NAND_FLASH_CONFIG2_REG);
206 static u16 NFC_STATUS_READ(void)
209 u16 saved = readw(NAND_MAIN_BUF0);
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;
216 writew(saved, NAND_MAIN_BUF0);
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
228 static void NFC_DATA_INPUT(enum nfc_internal_buf buf_no, enum nfc_page_area area,
231 u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
233 config1 |= readw(NAND_FLASH_CONFIG1_REG);
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;
242 writew(config1, NAND_FLASH_CONFIG1_REG);
243 writew(buf_no, RAM_BUFFER_ADDRESS_REG);
246 writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
250 static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
252 writew(buf_no, RAM_BUFFER_ADDRESS_REG);
253 writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
258 * The NFC has to be preset before performing any operation
260 static void NFC_PRESET(u32 max_block_count)
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);
267 writew(max_block_count, UNLOCK_END_BLK_ADD_REG);
268 // Unlock Block Command
269 writew(NF_WR_PROT_UNLOCK, NF_WR_PROT_REG);
273 * Issue the address input operation
274 * @param addr the address for the address input operation
276 static void NFC_ADDR_INPUT(u32 addr)
278 writew(addr & ((1 << ADDR_INPUT_SIZE) - 1), NAND_FLASH_ADD_REG);
279 writew(NAND_FLASH_CONFIG2_FADD_EN, NAND_FLASH_CONFIG2_REG);
283 #endif // _MXC_NFC_H_