RTEMS  5.1
nand-mlc.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2010-2011 embedded brains GmbH. All rights reserved.
11  *
12  * embedded brains GmbH
13  * Obere Lagerstr. 30
14  * 82178 Puchheim
15  * Germany
16  * <rtems@embedded-brains.de>
17  *
18  * Copyright (c) 2011 Stephan Hoffmann <sho@reLinux.de>
19  *
20  * The license and distribution terms for this file may be
21  * found in the file LICENSE in this distribution or at
22  * http://www.rtems.org/license/LICENSE.
23  */
24 
25 #ifndef LIBBSP_ARM_LPC32XX_NAND_MLC_H
26 #define LIBBSP_ARM_LPC32XX_NAND_MLC_H
27 
28 #include <rtems.h>
29 
30 #include <bsp/utility.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif /* __cplusplus */
35 
74 #define MLC_SMALL_PAGE_SIZE 528
75 #define MLC_SMALL_DATA_SIZE 512
76 #define MLC_SMALL_SPARE_SIZE 16
77 #define MLC_SMALL_USER_SPARE_SIZE 6
78 #define MLC_SMALL_ECC_SPARE_SIZE 10
79 #define MLC_SMALL_DATA_WORD_COUNT (MLC_SMALL_DATA_SIZE / 4)
80 #define MLC_SMALL_SPARE_WORD_COUNT (MLC_SMALL_SPARE_SIZE / 4)
81 #define MLC_SMALL_PAGES_PER_LARGE_PAGE 4
82 #define MLC_LARGE_PAGE_SIZE \
83  (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_PAGE_SIZE)
84 #define MLC_LARGE_DATA_SIZE \
85  (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_DATA_SIZE)
86 #define MLC_LARGE_SPARE_SIZE \
87  (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_SPARE_SIZE)
88 #define MLC_LARGE_DATA_WORD_COUNT (MLC_LARGE_DATA_SIZE / 4)
89 #define MLC_LARGE_SPARE_WORD_COUNT (MLC_LARGE_SPARE_SIZE / 4)
90 
99 #define FLASHCLK_IRQ_MLC BSP_BIT32(5)
100 #define FLASHCLK_MLC_DMA_RNB BSP_BIT32(4)
101 #define FLASHCLK_MLC_DMA_INT BSP_BIT32(3)
102 #define FLASHCLK_SELECT_SLC BSP_BIT32(2)
103 #define FLASHCLK_MLC_CLK_ENABLE BSP_BIT32(1)
104 #define FLASHCLK_SLC_CLK_ENABLE BSP_BIT32(0)
105 
114 #define MLC_TIME_WR_LOW(val) BSP_FLD32(val, 0, 3)
115 #define MLC_TIME_WR_HIGH(val) BSP_FLD32(val, 4, 7)
116 #define MLC_TIME_RD_LOW(val) BSP_FLD32(val, 8, 11)
117 #define MLC_TIME_RD_HIGH(val) BSP_FLD32(val, 12, 15)
118 #define MLC_TIME_NAND_TA(val) BSP_FLD32(val, 16, 18)
119 #define MLC_TIME_BUSY_DELAY(val) BSP_FLD32(val, 19, 23)
120 #define MLC_TIME_TCEA_DELAY(val) BSP_FLD32(val, 24, 25)
121 
130 #define MLC_UNLOCK_PROT 0xa25e
131 
140 #define MLC_ISR_DECODER_FAILURE BSP_BIT32(6)
141 #define MLC_ISR_SYMBOL_ERRORS(reg) BSP_FLD32GET(reg, 4, 5)
142 #define MLC_ISR_ERRORS_DETECTED BSP_BIT32(3)
143 #define MLC_ISR_ECC_READY BSP_BIT32(2)
144 #define MLC_ISR_CONTROLLER_READY BSP_BIT32(1)
145 #define MLC_ISR_NAND_READY BSP_BIT32(0)
146 
155 #define MLC_ICR_SOFT_WRITE_PROT BSP_BIT32(3)
156 #define MLC_ICR_LARGE_PAGES BSP_BIT32(2)
157 #define MLC_ICR_ADDR_WORD_COUNT_4_5 BSP_BIT32(1)
158 #define MLC_ICR_IO_BUS_16 BSP_BIT32(0)
159 
168 #define MLC_ECC_AUTO_ENC_PROGRAM BSP_BIT32(8)
169 
178 #define NAND_STATUS_ERROR (1U << 0)
179 #define NAND_STATUS_READY (1U << 6)
180 #define NAND_STATUS_NOT_PROTECTED (1U << 7)
181 
187 typedef struct {
188  uint32_t flags;
189 
190  uint32_t block_count;
191 
195  uint32_t time;
197 
202 #define MLC_SMALL_PAGES 0x1U
203 
208 #define MLC_MANY_ADDRESS_CYCLES 0x2U
209 
215 #define MLC_NORMAL_BLOCKS 0x4U
216 
220 #define MLC_IO_WIDTH_16_BIT 0x8U
221 
225 void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg);
226 
227 uint32_t lpc32xx_mlc_page_size(void);
228 
229 uint32_t lpc32xx_mlc_pages_per_block(void);
230 
231 uint32_t lpc32xx_mlc_block_count(void);
232 
233 uint32_t lpc32xx_mlc_io_width(void);
234 
235 void lpc32xx_mlc_write_protection(
236  uint32_t page_index_low,
237  uint32_t page_index_high
238 );
239 
240 void lpc32xx_mlc_read_id(uint8_t *id, size_t n);
241 
256  uint32_t page_index,
257  void *data,
258  void *spare,
259  uint32_t *symbol_error_count
260 );
261 
278 rtems_status_code lpc32xx_mlc_is_valid_block(uint32_t block_index);
279 
287 rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index);
288 
302 rtems_status_code lpc32xx_mlc_erase_block_safe(uint32_t block_index);
303 
313  uint32_t block_index,
314  uint32_t page_begin,
315  uint32_t page_end
316 );
317 
324 void lpc32xx_mlc_zero_pages(uint32_t page_begin, uint32_t page_end);
325 
337  uint32_t page_index,
338  const void *data,
339  const void *spare
340 );
341 
353  uint32_t block_begin,
354  uint32_t block_end,
355  const void *src,
356  size_t src_size,
357  uint32_t page_buffer [MLC_LARGE_DATA_WORD_COUNT]
358 );
359 
368 typedef bool (*lpc32xx_mlc_read_process)(
369  void *process_arg,
370  uint32_t page_index,
371  uint32_t page_size,
372  uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT],
373  uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]
374 );
375 
387  uint32_t block_begin,
388  uint32_t block_end,
389  lpc32xx_mlc_read_process process,
390  void *process_arg,
391  uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT],
392  uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT]
393 );
394 
407 static inline bool lpc32xx_mlc_is_bad_page(const uint32_t *spare)
408 {
409  uint32_t first_byte_mask = 0x000000ff;
410  uint32_t sixth_byte_mask = 0x0000ff00;
411 
412  return (spare [0] & first_byte_mask) != first_byte_mask
413  || (spare [1] & sixth_byte_mask) != sixth_byte_mask;
414 }
415 
418 #ifdef __cplusplus
419 }
420 #endif /* __cplusplus */
421 
422 #endif /* LIBBSP_ARM_LPC32XX_NAND_MLC_H */
rtems_status_code lpc32xx_mlc_read_page(uint32_t page_index, void *data, void *spare, uint32_t *symbol_error_count)
Reads the page with index page_index.
Definition: nand-mlc.c:211
rtems_status_code lpc32xx_mlc_read_blocks(uint32_t block_begin, uint32_t block_end, lpc32xx_mlc_read_process process, void *process_arg, uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT], uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT])
Reads the pages of block block_begin up to and excluding block_end.
Definition: nand-mlc-read-blocks.c:51
rtems_status_code lpc32xx_mlc_erase_block_safe(uint32_t block_index)
Erases the block with index block_index.
Definition: nand-mlc-erase-block-safe.c:111
rtems_status_code lpc32xx_mlc_write_page_with_ecc(uint32_t page_index, const void *data, const void *spare)
Writes the page with index page_index.
Definition: nand-mlc.c:339
bool(* lpc32xx_mlc_read_process)(void *process_arg, uint32_t page_index, uint32_t page_size, uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT], uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT])
Read blocks process function type.
Definition: nand-mlc.h:368
rtems_status_code lpc32xx_mlc_erase_block_safe_3(uint32_t block_index, uint32_t page_begin, uint32_t page_end)
Erases the block with index block_index.
Definition: nand-mlc-erase-block-safe.c:92
rtems_status_code
Classic API Status.
Definition: status.h:43
void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg)
Initializes the MLC NAND controller according to cfg.
Definition: nand-mlc.c:165
Utility macros.
uint32_t time
Value for the MLC NAND Timing Register (MLC_TIME_REG).
Definition: nand-mlc.h:195
MLC NAND controller configuration.
Definition: nand-mlc.h:187
rtems_status_code lpc32xx_mlc_write_blocks(uint32_t block_begin, uint32_t block_end, const void *src, size_t src_size, uint32_t page_buffer [MLC_LARGE_DATA_WORD_COUNT])
Writes src_size Bytes from src to the flash area specified by block_begin and block_end.
rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index)
Erases the block with index block_index.
Definition: nand-mlc.c:319
void lpc32xx_mlc_zero_pages(uint32_t page_begin, uint32_t page_end)
Writes zero values to the pages specified by page_begin and page_end.
Definition: nand-mlc-erase-block-safe.c:30
rtems_status_code lpc32xx_mlc_is_valid_block(uint32_t block_index)
Checks if the block with index block_index is valid.
Definition: nand-mlc-erase-block-safe.c:84