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_MIN 1
59 #define NFC_DEBUG_MED 2
60 #define NFC_DEBUG_MAX 3
61 #define NFC_DEBUG_DEF NFC_DEBUG_MED
63 #define PG_2K_DATA_OP_MULTI_CYCLES() false
65 typedef unsigned short u16;
66 typedef unsigned int u32;
67 typedef unsigned char u8;
69 #define ADDR_INPUT_SIZE 8
70 //----------------------------------------------------------------------------
71 // Common device details.
72 #define FLASH_Read_ID (0x90)
73 #if CYGHWR_DEVS_FLASH_MXC_NAND_RESET_WORKAROUND
74 #define FLASH_Reset 0xFFFF
76 #define FLASH_Reset (0xFF)
78 #define FLASH_Read_Mode1 (0x00)
79 #define FLASH_Read_Mode1_2K (0x30)
80 #define FLASH_Read_Mode2 (0x01)
81 #define FLASH_Read_Mode3 (0x50)
82 #define FLASH_Program (0x10)
83 #define FLASH_Send_Data (0x80)
84 #define FLASH_Status (0x70)
85 #define FLASH_Block_Erase (0x60)
86 #define FLASH_Start_Erase (0xD0)
88 #define NAND_MAIN_BUF0 (NFC_BASE + 0x000)
89 #define NAND_MAIN_BUF1 (NFC_BASE + 0x200)
90 #define NAND_MAIN_BUF2 (NFC_BASE + 0x400)
91 #define NAND_MAIN_BUF3 (NFC_BASE + 0x600)
92 #define NAND_SPAR_BUF0 (NFC_BASE + 0x800)
93 #define NAND_SPAR_BUF1 (NFC_BASE + 0x810)
94 #define NAND_SPAR_BUF2 (NFC_BASE + 0x820)
95 #define NAND_SPAR_BUF3 (NFC_BASE + 0x830)
96 #define NAND_RESERVED (NFC_BASE + 0x840)
98 #define NFC_BUFSIZE_REG (NAND_REG_BASE + 0x00)
99 #define RAM_BUFFER_ADDRESS_REG (NAND_REG_BASE + 0x04)
100 #define NAND_FLASH_ADD_REG (NAND_REG_BASE + 0x06)
101 #define NAND_FLASH_CMD_REG (NAND_REG_BASE + 0x08)
102 #define NFC_CONFIGURATION_REG (NAND_REG_BASE + 0x0A)
103 #define ECC_STATUS_RESULT_REG (NAND_REG_BASE + 0x0C)
104 #define ECC_RSLT_MAIN_AREA_REG (NAND_REG_BASE + 0x0E)
105 #define ECC_RSLT_SPARE_AREA_REG (NAND_REG_BASE + 0x10)
106 #define NF_WR_PROT_REG (NAND_REG_BASE + 0x12)
107 #define UNLOCK_START_BLK_ADD_REG (NAND_REG_BASE + 0x14)
108 #define UNLOCK_END_BLK_ADD_REG (NAND_REG_BASE + 0x16)
109 #define NAND_FLASH_WR_PR_ST_REG (NAND_REG_BASE + 0x18)
110 #define NAND_FLASH_CONFIG1_REG (NAND_REG_BASE + 0x1A)
111 #define NAND_FLASH_CONFIG2_REG (NAND_REG_BASE + 0x1C)
113 enum nfc_internal_buf {
114 RAM_BUF_0 = 0x0 << 4,
115 RAM_BUF_1 = 0x1 << 4,
116 RAM_BUF_2 = 0x2 << 4,
117 RAM_BUF_3 = 0x3 << 4,
120 enum nfc_output_mode {
121 FDO_PAGE_SPARE = 0x0008,
122 FDO_SPARE_ONLY = 0x1008, // LSB has to be 0x08
123 FDO_FLASH_ID = 0x0010,
124 FDO_FLASH_STATUS = 0x0020,
128 * Defined the "complete" address input operations which may involve
129 * more than one cycle of single address input operation.
132 ADDRESS_INPUT_READ_ID,
133 ADDRESS_INPUT_READ_PAGE,
134 ADDRESS_INPUT_PROGRAM_PAGE,
135 ADDRESS_INPUT_ERASE_BLOCK,
145 MXC_NAND_16_BIT = 16,
153 // read column 464-465 byte but only 464 for bad block marker
154 #define BAD_BLK_MARKER_464 (NAND_MAIN_BUF3 + 464)
155 // read column 4-5 byte, but only 5 is used for swapped main area data
156 #define BAD_BLK_MARKER_SP_5 (NAND_SPAR_BUF3 + 4)
158 // Polls the NANDFC to wait for an operation to complete
159 #define wait_op_done() \
161 volatile int mxc_nfc_wait_loop; \
162 while ((readl(NFC_IPC_REG) & NFC_IPC_INT) == 0) \
163 {for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++);} \
164 write_nfc_ip_reg(0, NFC_IPC_REG); \
167 int nfc_read_region(u32 la, u32 maddr, int len);
168 int nfc_program_region(u32 la, u32 maddr, int len);
169 int nfc_erase_region(u32 la, int len);
171 static void write_nfc_ip_reg(u32 val, u32 reg)
173 volatile int mxc_nfc_wait_loop;
175 writel(NFC_IPC_CREQ, NFC_IPC_REG);
176 for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++);
179 writel(0, NFC_IPC_REG);
183 * NAND flash data output operation (reading data from NAND flash)
184 * @param buf_no internal ram buffer number that will contain data
185 * to be outputted from the NAND flash after operation done
186 * @param mode one of the mode defined in enum nfc_output_mode
187 * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
189 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
192 u32 v = readl(NFC_FLASH_CONFIG2_REG);
194 if ((v & NFC_FLASH_CONFIG2_ECC_EN) != 0 && ecc_en == 0) {
195 write_nfc_ip_reg(v & ~NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
197 if ((v & NFC_FLASH_CONFIG2_ECC_EN) == 0 && ecc_en != 0) {
198 write_nfc_ip_reg(v | NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
201 v = readl(NAND_CONFIGURATION1_REG);
203 if (mode == FDO_SPARE_ONLY) {
204 v = (v & ~0x31) | buf_no | NAND_CONFIGURATION1_SP_EN;
206 v = (v & ~0x31) | buf_no;
209 writel(v, NAND_CONFIGURATION1_REG);
211 writel(mode & 0xFF, NAND_LAUNCH_REG);
215 static void NFC_CMD_INPUT(u32 cmd)
217 writel(cmd & 0xFFFF, NAND_ADD_CMD_REG);
218 writel(NAND_LAUNCH_FCMD, NAND_LAUNCH_REG);
222 static u16 NFC_STATUS_READ(void)
225 u16 saved = readw(NAND_MAIN_BUF0);
227 NFC_CMD_INPUT(FLASH_Status);
228 NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_STATUS, 1);
229 flash_status = readw(NAND_MAIN_BUF0) & 0x00FF;
232 writew(saved, NAND_MAIN_BUF0);
238 * NAND flash data input operation (writing data to NAND flash)
239 * @param buf_no internal ram buffer number containing data to be
240 * written into the NAND flash
241 * @param area NFC_SPARE_ONLY or NFC_MAIN_ONLY,
242 * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
244 static void NFC_DATA_INPUT(enum nfc_internal_buf buf_no, enum nfc_page_area area,
247 u32 v = readl(NFC_FLASH_CONFIG2_REG);
249 // setup config2 register for ECC enable or not
250 if ((v & NFC_FLASH_CONFIG2_ECC_EN) != 0 && ecc_en == 0) {
251 write_nfc_ip_reg(v & ~NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
253 if ((v & NFC_FLASH_CONFIG2_ECC_EN) == 0 && ecc_en != 0) {
254 write_nfc_ip_reg(v | NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
257 // setup config1 register for ram buffer number, spare-only or not
258 v = readl(NAND_CONFIGURATION1_REG);
260 if (area == NFC_SPARE_ONLY) {
261 v = (v & ~0x31) | buf_no | NAND_CONFIGURATION1_SP_EN;
263 v = (v & ~0x31) | buf_no;
266 writel(v, NAND_CONFIGURATION1_REG);
269 writel(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
273 static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
277 // setup config1 register for ram buffer number, spare-only or not
278 v = readl(NAND_CONFIGURATION1_REG);
279 v = (v & ~0x30) | buf_no;
280 writel(v, NAND_CONFIGURATION1_REG);
283 writel(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
288 * The NFC has to be preset before performing any operation
290 static void NFC_PRESET(u32 max_block_count)
292 // not needed. It is done in plf_hardware_init()
296 * Issue the address input operation
297 * @param addr the address for the address input operation
299 static void NFC_ADDR_INPUT(u32 addr)
301 writel((addr & ((1 << ADDR_INPUT_SIZE) - 1)) << 16, NAND_ADD_CMD_REG);
302 writel(NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
306 #endif // _MXC_NFC_V2_H_