source: rtems/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h @ 542d350e

4.115
Last change on this file since 542d350e was 542d350e, checked in by Sebastian Huber <sebastian.huber@…>, on 07/04/11 at 09:26:19

2011-07-04 Sebastian Huber <sebastian.huber@…>

  • misc/nand-mlc-erase-block-safe.c, misc/nand-mlc-write-blocks.c, include/nand-mlc.h: Fixed write blocks.
  • Property mode set to 100644
File size: 9.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc32xx_nand_mlc
5 *
6 * @brief NAND MLC controller API.
7 */
8
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.com/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
33extern "C" {
34#endif /* __cplusplus */
35
36/**
37 * @defgroup lpc32xx_nand_mlc NAND MLC Controller
38 *
39 * @ingroup lpc32xx
40 *
41 * @brief NAND MLC Controller.
42 *
43 * Timing constraints:
44 *
45 * -# (WR_LOW + 1) / HCLK >= tWP
46 * -# (WR_HIGH - WR_LOW) / HCLK >= tWH
47 * -# (WR_LOW + 1) / HCLK + (WR_HIGH - WR_LOW) / HCLK >= tWC
48 * -# (RD_LOW + 1) / HCLK >= tRP
49 * -# (RD_LOW + 1) / HCLK >= tREA + tSU
50 * -# (RD_HIGH - RD_LOW) / HCLK >= tREH
51 * -# (RD_LOW + 1) / HCLK + (RD_HIGH - RD_LOW) / HCLK >= tRC
52 * -# (RD_HIGH - RD_LOW) / HCLK + NAND_TA / HCLK >= tRHZ
53 * -# BUSY_DELAY / HCLK >= max(tWB, tRB)
54 * -# TCEA_DELAY / HCLK >= tCEA - tREA
55 *
56 * Known flash layouts (Format: SP = small pages, LP = large pages / address
57 * cycles / pages per block):
58 *
59 * -# SP/3/32
60 * -# SP/4/32
61 * -# LP/4/64
62 * -# LP/5/64
63 * -# LP/5/128
64 *
65 * @{
66 */
67
68/**
69 * @name MLC NAND Flash Dimensions
70 *
71 * @{
72 */
73
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_DATA_WORD_COUNT (MLC_SMALL_DATA_SIZE / 4)
78#define MLC_SMALL_SPARE_WORD_COUNT (MLC_SMALL_SPARE_SIZE / 4)
79#define MLC_SMALL_PAGES_PER_LARGE_PAGE 4
80#define MLC_LARGE_PAGE_SIZE \
81  (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_PAGE_SIZE)
82#define MLC_LARGE_DATA_SIZE \
83  (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_DATA_SIZE)
84#define MLC_LARGE_SPARE_SIZE \
85  (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_SPARE_SIZE)
86#define MLC_LARGE_DATA_WORD_COUNT (MLC_LARGE_DATA_SIZE / 4)
87#define MLC_LARGE_SPARE_WORD_COUNT (MLC_LARGE_SPARE_SIZE / 4)
88
89/** @} */
90
91/**
92 * @name NAND Flash Clock Control Register (FLASHCLK_CTRL)
93 *
94 * @{
95 */
96
97#define FLASHCLK_IRQ_MLC BSP_BIT32(5)
98#define FLASHCLK_MLC_DMA_RNB BSP_BIT32(4)
99#define FLASHCLK_MLC_DMA_INT BSP_BIT32(3)
100#define FLASHCLK_SELECT_SLC BSP_BIT32(2)
101#define FLASHCLK_MLC_CLK_ENABLE BSP_BIT32(1)
102#define FLASHCLK_SLC_CLK_ENABLE BSP_BIT32(0)
103
104/** @} */
105
106/**
107 * @name MLC NAND Timing Register (MLC_TIME_REG)
108 *
109 * @{
110 */
111
112#define MLC_TIME_WR_LOW(val) BSP_FLD32(val, 0, 3)
113#define MLC_TIME_WR_HIGH(val) BSP_FLD32(val, 4, 7)
114#define MLC_TIME_RD_LOW(val) BSP_FLD32(val, 8, 11)
115#define MLC_TIME_RD_HIGH(val) BSP_FLD32(val, 12, 15)
116#define MLC_TIME_NAND_TA(val) BSP_FLD32(val, 16, 18)
117#define MLC_TIME_BUSY_DELAY(val) BSP_FLD32(val, 19, 23)
118#define MLC_TIME_TCEA_DELAY(val) BSP_FLD32(val, 24, 25)
119
120/** @} */
121
122/**
123 * @name MLC NAND Lock Protection Register (MLC_LOCK_PR)
124 *
125 * @{
126 */
127
128#define MLC_UNLOCK_PROT 0xa25e
129
130/** @} */
131
132/**
133 * @name MLC NAND Status Register (MLC_ISR)
134 *
135 * @{
136 */
137
138#define MLC_ISR_DECODER_FAILURE BSP_BIT32(6)
139#define MLC_ISR_ERRORS_DETECTED BSP_BIT32(3)
140#define MLC_ISR_ECC_READY BSP_BIT32(2)
141#define MLC_ISR_CONTROLLER_READY BSP_BIT32(1)
142#define MLC_ISR_NAND_READY BSP_BIT32(0)
143
144/** @} */
145
146/**
147 * @name MLC NAND Controller Configuration Register (MLC_ICR)
148 *
149 * @{
150 */
151
152#define MLC_ICR_SOFT_WRITE_PROT BSP_BIT32(3)
153#define MLC_ICR_LARGE_PAGES BSP_BIT32(2)
154#define MLC_ICR_ADDR_WORD_COUNT_4_5 BSP_BIT32(1)
155#define MLC_ICR_IO_BUS_16 BSP_BIT32(0)
156
157/** @} */
158
159/**
160 * @name MLC NAND Auto Encode Register (MLC_ECC_AUTO_ENC)
161 *
162 * @{
163 */
164
165#define MLC_ECC_AUTO_ENC_PROGRAM BSP_BIT32(8)
166
167/** @} */
168
169#define MLC_BAD_BLOCK_MASK ((uint32_t) 0xff00)
170
171/**
172 * @brief Bad block mark.
173 *
174 * We define our own bad block mark to be able to recognize the blocks that
175 * have been marked bad during operation later.
176 */
177#define MLC_BAD_BLOCK_MARK ((uint32_t) 0xbadb)
178
179/**
180 * @brief The bytes 4 and 5 are reserved for bad block handling.
181 */
182#define MLC_RESERVED ((uint32_t) 0xffff)
183
184/**
185 * @name NAND Status Register
186 *
187 * @{
188 */
189
190#define NAND_STATUS_ERROR (1U << 0)
191#define NAND_STATUS_READY (1U << 6)
192#define NAND_STATUS_NOT_PROTECTED (1U << 7)
193
194/** @} */
195
196/**
197 * @brief MLC NAND controller configuration.
198 */
199typedef struct {
200  uint32_t flags;
201
202  uint32_t block_count;
203
204  /**
205   * @brief Value for the MLC NAND Timing Register (MLC_TIME_REG).
206   */
207  uint32_t time;
208} lpc32xx_mlc_config;
209
210/**
211 * @brief Selects small pages (512 Bytes user data and 16 Bytes spare data)
212 * or large pages (2048 Bytes user data and 64 Bytes spare data).
213 */
214#define MLC_SMALL_PAGES 0x1U
215
216/**
217 * @Brief Selects 3/4 address cycles for small pages/large pages or 4/5
218 * address cycles.
219 */
220#define MLC_MANY_ADDRESS_CYCLES 0x2U
221
222/**
223 * @brief Selects 64 or 128 pages per block in case of large pages.
224 */
225#define MLC_NORMAL_BLOCKS 0x4U
226
227/**
228 * @brief Initializes the MLC NAND controller according to @a cfg.
229 */
230void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg);
231
232uint32_t lpc32xx_mlc_page_size(void);
233
234uint32_t lpc32xx_mlc_pages_per_block(void);
235
236uint32_t lpc32xx_mlc_block_count(void);
237
238void lpc32xx_mlc_write_protection(
239  uint32_t page_index_low,
240  uint32_t page_index_high
241);
242
243void lpc32xx_mlc_read_id(uint8_t *id, size_t n);
244
245/**
246 * @brief Reads the page with index @a page_index.
247 *
248 * 32-bit reads will be performed.
249 *
250 * Bytes 7 to 15 of the spare area will contain the ECC.
251 *
252 * @retval RTEMS_SUCCESSFUL Successful operation.
253 * @retval RTEMS_INVALID_ID Invalid @a page_index value.
254 * @retval RTEMS_IO_ERROR Uncorrectable bit error.
255 */
256rtems_status_code lpc32xx_mlc_read_page(
257  uint32_t page_index,
258  uint32_t *data,
259  uint32_t *spare
260);
261
262/**
263 * @brief Erases the block with index @a block_index.
264 *
265 * @retval RTEMS_SUCCESSFUL Successful operation.
266 * @retval RTEMS_INVALID_ID Invalid @a block_index value.
267 * @retval RTEMS_IO_ERROR Erase error.
268 */
269rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index);
270
271/**
272 * @brief Erases the block with index @a block_index.
273 *
274 * In case of an erase error all pages and the spare areas of this block are
275 * programmed with zero values.  This will mark the first and second page as
276 * bad.
277 *
278 * @retval RTEMS_SUCCESSFUL Successful operation.
279 * @retval RTEMS_INCORRECT_STATE The first or second page of this block is bad.
280 * @retval RTEMS_INVALID_ID Invalid @a block_index value.
281 * @retval RTEMS_IO_ERROR Erase error.
282 */
283rtems_status_code lpc32xx_mlc_erase_block_safe(uint32_t block_index);
284
285/**
286 * @brief Erases the block with index @a block_index.
287 *
288 * Variant of lpc32xx_mlc_erase_block_safe() with more parameters for
289 * efficiency reasons.  The @a page_begin must be the index of the first page
290 * of the block.  The @a page_end must be the page index of the last page of
291 * the block plus one.
292 */
293rtems_status_code lpc32xx_mlc_erase_block_safe_3(
294  uint32_t block_index,
295  uint32_t page_begin,
296  uint32_t page_end
297);
298
299/**
300 * @brief Writes zero values to the pages specified by @a page_begin and
301 * @a page_end.
302 *
303 * The data and spare area are cleared to zero.  This marks the pages as bad.
304 */
305void lpc32xx_mlc_zero_pages(uint32_t page_begin, uint32_t page_end);
306
307/**
308 * @brief Writes the page with index @a page_index.
309 *
310 * 32-bit writes will be performed.
311 *
312 * Bytes 7 to 15 of the spare area will be used for the automatically generated
313 * ECC.
314 *
315 * @retval RTEMS_SUCCESSFUL Successful operation.
316 * @retval RTEMS_INVALID_ID Invalid @a page_index value.
317 * @retval RTEMS_IO_ERROR Write error.
318 */
319rtems_status_code lpc32xx_mlc_write_page_with_ecc(
320  uint32_t page_index,
321  const uint32_t *data,
322  const uint32_t *spare
323);
324
325/**
326 * @brief Writes @a src_size Bytes from @a src to the flash area specified by
327 * @a block_begin and @a block_end.
328 *
329 * The @a page_buffer will be used as an intermediate buffer.
330 *
331 * @retval RTEMS_SUCCESSFUL Successful operation.
332 * @retval RTEMS_INVALID_ID Invalid @a block_begin or @a block_end value.
333 * @retval RTEMS_IO_ERROR Too many bad blocks or source area too big.
334 */
335rtems_status_code lpc32xx_mlc_write_blocks(
336  uint32_t block_begin,
337  uint32_t block_end,
338  const void *src,
339  size_t src_size,
340  uint32_t page_buffer [MLC_LARGE_DATA_WORD_COUNT]
341);
342
343/**
344 * @brief Read blocks process function type.
345 *
346 * @see lpc32xx_mlc_read_blocks().
347 *
348 * @retval false Continue processing.
349 * @retval true Stop processing.
350 */
351typedef bool (*lpc32xx_mlc_read_process)(
352  void *process_arg,
353  uint32_t page_index,
354  uint32_t page_size,
355  uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT],
356  uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]
357);
358
359/**
360 * @brief Reads the pages of block @a block_begin up to and excluding
361 * @a block_end.
362 *
363 * For each page @a process will be called with the @a process_arg parameter,
364 * the page_index, the page data and the page spare.
365 *
366 * The @a page_buffer_0 and @a page_buffer_1 will be used as
367 * intermediate buffers.
368 */
369rtems_status_code lpc32xx_mlc_read_blocks(
370  uint32_t block_begin,
371  uint32_t block_end,
372  lpc32xx_mlc_read_process process,
373  void *process_arg,
374  uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT],
375  uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT]
376);
377
378static inline bool lpc32xx_mlc_is_bad_page(const uint32_t *spare)
379{
380  return (spare [1] & MLC_BAD_BLOCK_MASK) != MLC_BAD_BLOCK_MASK;
381}
382
383static inline void lpc32xx_mlc_set_bad_page(uint32_t *spare)
384{
385  spare [1] = MLC_BAD_BLOCK_MARK;
386}
387
388static inline void lpc32xx_mlc_set_reserved(uint32_t *spare)
389{
390  spare [1] = MLC_RESERVED;
391}
392
393/** @} */
394
395#ifdef __cplusplus
396}
397#endif /* __cplusplus */
398
399#endif /* LIBBSP_ARM_LPC32XX_NAND_MLC_H */
Note: See TracBrowser for help on using the repository browser.