source: rtems/bsps/arm/lpc32xx/include/bsp/nand-mlc.h @ 2afb22b

5
Last change on this file since 2afb22b was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

  • Property mode set to 100644
File size: 10.9 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.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
33extern "C" {
34#endif /* __cplusplus */
35
36/**
37 * @defgroup lpc32xx_nand_mlc NAND MLC Controller
38 *
39 * @ingroup arm_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_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
91/** @} */
92
93/**
94 * @name NAND Flash Clock Control Register (FLASHCLK_CTRL)
95 *
96 * @{
97 */
98
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
106/** @} */
107
108/**
109 * @name MLC NAND Timing Register (MLC_TIME_REG)
110 *
111 * @{
112 */
113
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
122/** @} */
123
124/**
125 * @name MLC NAND Lock Protection Register (MLC_LOCK_PR)
126 *
127 * @{
128 */
129
130#define MLC_UNLOCK_PROT 0xa25e
131
132/** @} */
133
134/**
135 * @name MLC NAND Status Register (MLC_ISR)
136 *
137 * @{
138 */
139
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
147/** @} */
148
149/**
150 * @name MLC NAND Controller Configuration Register (MLC_ICR)
151 *
152 * @{
153 */
154
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
160/** @} */
161
162/**
163 * @name MLC NAND Auto Encode Register (MLC_ECC_AUTO_ENC)
164 *
165 * @{
166 */
167
168#define MLC_ECC_AUTO_ENC_PROGRAM BSP_BIT32(8)
169
170/** @} */
171
172/**
173 * @name NAND Status Register
174 *
175 * @{
176 */
177
178#define NAND_STATUS_ERROR (1U << 0)
179#define NAND_STATUS_READY (1U << 6)
180#define NAND_STATUS_NOT_PROTECTED (1U << 7)
181
182/** @} */
183
184/**
185 * @brief MLC NAND controller configuration.
186 */
187typedef struct {
188  uint32_t flags;
189
190  uint32_t block_count;
191
192  /**
193   * @brief Value for the MLC NAND Timing Register (MLC_TIME_REG).
194   */
195  uint32_t time;
196} lpc32xx_mlc_config;
197
198/**
199 * @brief Selects small pages (512 Bytes user data and 16 Bytes spare data)
200 * or large pages (2048 Bytes user data and 64 Bytes spare data) if not set.
201 */
202#define MLC_SMALL_PAGES 0x1U
203
204/**
205 * @Brief Selects 4/5 address cycles for small/large pages or 3/4 address
206 * cycles if not set.
207 */
208#define MLC_MANY_ADDRESS_CYCLES 0x2U
209
210/**
211 * @brief Selects 64 pages per block or 128 pages per block if not set.
212 *
213 * This flag is only valid for large pages.
214 */
215#define MLC_NORMAL_BLOCKS 0x4U
216
217/**
218 * @brief Selects 16-bit IO width or 8-bit IO width if not set.
219 */
220#define MLC_IO_WIDTH_16_BIT 0x8U
221
222/**
223 * @brief Initializes the MLC NAND controller according to @a cfg.
224 */
225void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg);
226
227uint32_t lpc32xx_mlc_page_size(void);
228
229uint32_t lpc32xx_mlc_pages_per_block(void);
230
231uint32_t lpc32xx_mlc_block_count(void);
232
233uint32_t lpc32xx_mlc_io_width(void);
234
235void lpc32xx_mlc_write_protection(
236  uint32_t page_index_low,
237  uint32_t page_index_high
238);
239
240void lpc32xx_mlc_read_id(uint8_t *id, size_t n);
241
242/**
243 * @brief Reads the page with index @a page_index.
244 *
245 * Bytes 6 to 15 of the spare area will contain the ECC.
246 *
247 * If the read is successful, then the @a symbol_error_count will contain the
248 * number of detected symbol errors (0, 1, 2, 3, or 4), else the value will be
249 * 0xffffffff.  The @a symbol_error_count pointer may be @c NULL.
250 *
251 * @retval RTEMS_SUCCESSFUL Successful operation.
252 * @retval RTEMS_INVALID_ID Invalid @a page_index value.
253 * @retval RTEMS_IO_ERROR Uncorrectable bit error.
254 */
255rtems_status_code lpc32xx_mlc_read_page(
256  uint32_t page_index,
257  void *data,
258  void *spare,
259  uint32_t *symbol_error_count
260);
261
262/**
263 * @brief Checks if the block with index @a block_index is valid.
264 *
265 * The initial valid block information of the manufacturer will be used.
266 * Unfortunately there seems to be no standard for this.  A block will be
267 * considered as bad if the first or second page of this block does not contain
268 * 0xff at the 6th byte of the spare area.  This should work for flashes with
269 * small pages and a 8-bit IO width.
270 *
271 * @retval RTEMS_SUCCESSFUL The block is valid.
272 * @retval RTEMS_INVALID_ID Invalid @a block_index value.
273 * @retval RTEMS_IO_ERROR Uncorrectable bit error.
274 * @retval RTEMS_INCORRECT_STATE The block is bad.
275 * @retval RTEMS_NOT_IMPLEMENTED No implementation available for this flash
276 * type.
277 */
278rtems_status_code lpc32xx_mlc_is_valid_block(uint32_t block_index);
279
280/**
281 * @brief Erases the block with index @a block_index.
282 *
283 * @retval RTEMS_SUCCESSFUL Successful operation.
284 * @retval RTEMS_INVALID_ID Invalid @a block_index value.
285 * @retval RTEMS_UNSATISFIED Erase error.
286 */
287rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index);
288
289/**
290 * @brief Erases the block with index @a block_index.
291 *
292 * In case of an erase error all pages and the spare areas of this block are
293 * programmed with zero values.  This will hopefully mark the block as bad.
294 *
295 * @retval RTEMS_SUCCESSFUL Successful operation.
296 * @retval RTEMS_INCORRECT_STATE The block is bad.
297 * @retval RTEMS_INVALID_ID Invalid @a block_index value.
298 * @retval RTEMS_UNSATISFIED Erase error.
299 * @retval RTEMS_NOT_IMPLEMENTED No implementation available for this flash
300 * type.
301 */
302rtems_status_code lpc32xx_mlc_erase_block_safe(uint32_t block_index);
303
304/**
305 * @brief Erases the block with index @a block_index.
306 *
307 * Variant of lpc32xx_mlc_erase_block_safe() with more parameters for
308 * efficiency reasons.  The @a page_begin must be the index of the first page
309 * of the block.  The @a page_end must be the page index of the last page of
310 * the block plus one.
311 */
312rtems_status_code lpc32xx_mlc_erase_block_safe_3(
313  uint32_t block_index,
314  uint32_t page_begin,
315  uint32_t page_end
316);
317
318/**
319 * @brief Writes zero values to the pages specified by @a page_begin and
320 * @a page_end.
321 *
322 * The data and spare area are cleared to zero.  This marks the pages as bad.
323 */
324void lpc32xx_mlc_zero_pages(uint32_t page_begin, uint32_t page_end);
325
326/**
327 * @brief Writes the page with index @a page_index.
328 *
329 * Only the bytes 0 to 5 of the spare area can be used for user data, the bytes
330 * 6 to 15 will be used for the automatically generated ECC.
331 *
332 * @retval RTEMS_SUCCESSFUL Successful operation.
333 * @retval RTEMS_INVALID_ID Invalid @a page_index value.
334 * @retval RTEMS_IO_ERROR Write error.
335 */
336rtems_status_code lpc32xx_mlc_write_page_with_ecc(
337  uint32_t page_index,
338  const void *data,
339  const void *spare
340);
341
342/**
343 * @brief Writes @a src_size Bytes from @a src to the flash area specified by
344 * @a block_begin and @a block_end.
345 *
346 * The @a page_buffer will be used as an intermediate buffer.
347 *
348 * @retval RTEMS_SUCCESSFUL Successful operation.
349 * @retval RTEMS_INVALID_ID Invalid @a block_begin or @a block_end value.
350 * @retval RTEMS_IO_ERROR Too many bad blocks or source area too big.
351 */
352rtems_status_code lpc32xx_mlc_write_blocks(
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
360/**
361 * @brief Read blocks process function type.
362 *
363 * @see lpc32xx_mlc_read_blocks().
364 *
365 * @retval false Continue processing.
366 * @retval true Stop processing.
367 */
368typedef 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
376/**
377 * @brief Reads the pages of block @a block_begin up to and excluding
378 * @a block_end.
379 *
380 * For each page @a process will be called with the @a process_arg parameter,
381 * the page_index, the page data and the page spare.
382 *
383 * The @a page_buffer_0 and @a page_buffer_1 will be used as
384 * intermediate buffers.
385 */
386rtems_status_code lpc32xx_mlc_read_blocks(
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
395/**
396 * @brief Checks if the page spare area indicates to a bad page.
397 *
398 * If the first (byte offset 0) or sixth (byte offset 5) byte of the spare area
399 * has a value other than 0xff, then it returns @a true (the page is bad), else
400 * it returns @a false (the page is not bad).
401 *
402 * Samsung uses the sixth byte to indicate a bad page.  Mircon uses the first
403 * and sixth byte to indicate a bad page.
404 *
405 * This functions works only for small page flashes.
406 */
407static 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
416/** @} */
417
418#ifdef __cplusplus
419}
420#endif /* __cplusplus */
421
422#endif /* LIBBSP_ARM_LPC32XX_NAND_MLC_H */
Note: See TracBrowser for help on using the repository browser.