Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:04

0001 /**
0002  * @file
0003  *
0004  * @ingroup lpc32xx_nand_mlc
0005  *
0006  * @brief NAND MLC controller API.
0007  */
0008 
0009 /*
0010  * Copyright (C) 2010, 2011 embedded brains GmbH & Co. KG
0011  *
0012  * Copyright (c) 2011 Stephan Hoffmann <sho@reLinux.de>
0013  *
0014  * The license and distribution terms for this file may be
0015  * found in the file LICENSE in this distribution or at
0016  * http://www.rtems.org/license/LICENSE.
0017  */
0018 
0019 #ifndef LIBBSP_ARM_LPC32XX_NAND_MLC_H
0020 #define LIBBSP_ARM_LPC32XX_NAND_MLC_H
0021 
0022 #include <rtems.h>
0023 
0024 #include <bsp/utility.h>
0025 
0026 #ifdef __cplusplus
0027 extern "C" {
0028 #endif /* __cplusplus */
0029 
0030 /**
0031  * @defgroup lpc32xx_nand_mlc NAND MLC Controller
0032  *
0033  * @ingroup RTEMSBSPsARMLPC32XX
0034  *
0035  * @brief NAND MLC Controller.
0036  *
0037  * Timing constraints:
0038  *
0039  * -# (WR_LOW + 1) / HCLK >= tWP
0040  * -# (WR_HIGH - WR_LOW) / HCLK >= tWH
0041  * -# (WR_LOW + 1) / HCLK + (WR_HIGH - WR_LOW) / HCLK >= tWC
0042  * -# (RD_LOW + 1) / HCLK >= tRP
0043  * -# (RD_LOW + 1) / HCLK >= tREA + tSU
0044  * -# (RD_HIGH - RD_LOW) / HCLK >= tREH
0045  * -# (RD_LOW + 1) / HCLK + (RD_HIGH - RD_LOW) / HCLK >= tRC
0046  * -# (RD_HIGH - RD_LOW) / HCLK + NAND_TA / HCLK >= tRHZ
0047  * -# BUSY_DELAY / HCLK >= max(tWB, tRB)
0048  * -# TCEA_DELAY / HCLK >= tCEA - tREA
0049  *
0050  * Known flash layouts (Format: SP = small pages, LP = large pages / address
0051  * cycles / pages per block):
0052  *
0053  * -# SP/3/32
0054  * -# SP/4/32
0055  * -# LP/4/64
0056  * -# LP/5/64
0057  * -# LP/5/128
0058  *
0059  * @{
0060  */
0061 
0062 /**
0063  * @name MLC NAND Flash Dimensions
0064  *
0065  * @{
0066  */
0067 
0068 #define MLC_SMALL_PAGE_SIZE 528
0069 #define MLC_SMALL_DATA_SIZE 512
0070 #define MLC_SMALL_SPARE_SIZE 16
0071 #define MLC_SMALL_USER_SPARE_SIZE 6
0072 #define MLC_SMALL_ECC_SPARE_SIZE 10
0073 #define MLC_SMALL_DATA_WORD_COUNT (MLC_SMALL_DATA_SIZE / 4)
0074 #define MLC_SMALL_SPARE_WORD_COUNT (MLC_SMALL_SPARE_SIZE / 4)
0075 #define MLC_SMALL_PAGES_PER_LARGE_PAGE 4
0076 #define MLC_LARGE_PAGE_SIZE \
0077   (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_PAGE_SIZE)
0078 #define MLC_LARGE_DATA_SIZE \
0079   (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_DATA_SIZE)
0080 #define MLC_LARGE_SPARE_SIZE \
0081   (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_SPARE_SIZE)
0082 #define MLC_LARGE_DATA_WORD_COUNT (MLC_LARGE_DATA_SIZE / 4)
0083 #define MLC_LARGE_SPARE_WORD_COUNT (MLC_LARGE_SPARE_SIZE / 4)
0084 
0085 /** @} */
0086 
0087 /**
0088  * @name NAND Flash Clock Control Register (FLASHCLK_CTRL)
0089  *
0090  * @{
0091  */
0092 
0093 #define FLASHCLK_IRQ_MLC BSP_BIT32(5)
0094 #define FLASHCLK_MLC_DMA_RNB BSP_BIT32(4)
0095 #define FLASHCLK_MLC_DMA_INT BSP_BIT32(3)
0096 #define FLASHCLK_SELECT_SLC BSP_BIT32(2)
0097 #define FLASHCLK_MLC_CLK_ENABLE BSP_BIT32(1)
0098 #define FLASHCLK_SLC_CLK_ENABLE BSP_BIT32(0)
0099 
0100 /** @} */
0101 
0102 /**
0103  * @name MLC NAND Timing Register (MLC_TIME_REG)
0104  *
0105  * @{
0106  */
0107 
0108 #define MLC_TIME_WR_LOW(val) BSP_FLD32(val, 0, 3)
0109 #define MLC_TIME_WR_HIGH(val) BSP_FLD32(val, 4, 7)
0110 #define MLC_TIME_RD_LOW(val) BSP_FLD32(val, 8, 11)
0111 #define MLC_TIME_RD_HIGH(val) BSP_FLD32(val, 12, 15)
0112 #define MLC_TIME_NAND_TA(val) BSP_FLD32(val, 16, 18)
0113 #define MLC_TIME_BUSY_DELAY(val) BSP_FLD32(val, 19, 23)
0114 #define MLC_TIME_TCEA_DELAY(val) BSP_FLD32(val, 24, 25)
0115 
0116 /** @} */
0117 
0118 /**
0119  * @name MLC NAND Lock Protection Register (MLC_LOCK_PR)
0120  *
0121  * @{
0122  */
0123 
0124 #define MLC_UNLOCK_PROT 0xa25e
0125 
0126 /** @} */
0127 
0128 /**
0129  * @name MLC NAND Status Register (MLC_ISR)
0130  *
0131  * @{
0132  */
0133 
0134 #define MLC_ISR_DECODER_FAILURE BSP_BIT32(6)
0135 #define MLC_ISR_SYMBOL_ERRORS(reg) BSP_FLD32GET(reg, 4, 5)
0136 #define MLC_ISR_ERRORS_DETECTED BSP_BIT32(3)
0137 #define MLC_ISR_ECC_READY BSP_BIT32(2)
0138 #define MLC_ISR_CONTROLLER_READY BSP_BIT32(1)
0139 #define MLC_ISR_NAND_READY BSP_BIT32(0)
0140 
0141 /** @} */
0142 
0143 /**
0144  * @name MLC NAND Controller Configuration Register (MLC_ICR)
0145  *
0146  * @{
0147  */
0148 
0149 #define MLC_ICR_SOFT_WRITE_PROT BSP_BIT32(3)
0150 #define MLC_ICR_LARGE_PAGES BSP_BIT32(2)
0151 #define MLC_ICR_ADDR_WORD_COUNT_4_5 BSP_BIT32(1)
0152 #define MLC_ICR_IO_BUS_16 BSP_BIT32(0)
0153 
0154 /** @} */
0155 
0156 /**
0157  * @name MLC NAND Auto Encode Register (MLC_ECC_AUTO_ENC)
0158  *
0159  * @{
0160  */
0161 
0162 #define MLC_ECC_AUTO_ENC_PROGRAM BSP_BIT32(8)
0163 
0164 /** @} */
0165 
0166 /**
0167  * @name NAND Status Register
0168  *
0169  * @{
0170  */
0171 
0172 #define NAND_STATUS_ERROR (1U << 0)
0173 #define NAND_STATUS_READY (1U << 6)
0174 #define NAND_STATUS_NOT_PROTECTED (1U << 7)
0175 
0176 /** @} */
0177 
0178 /**
0179  * @brief MLC NAND controller configuration.
0180  */
0181 typedef struct {
0182   uint32_t flags;
0183 
0184   uint32_t block_count;
0185 
0186   /**
0187    * @brief Value for the MLC NAND Timing Register (MLC_TIME_REG).
0188    */
0189   uint32_t time;
0190 } lpc32xx_mlc_config;
0191 
0192 /**
0193  * @brief Selects small pages (512 Bytes user data and 16 Bytes spare data)
0194  * or large pages (2048 Bytes user data and 64 Bytes spare data) if not set.
0195  */
0196 #define MLC_SMALL_PAGES 0x1U
0197 
0198 /**
0199  * @Brief Selects 4/5 address cycles for small/large pages or 3/4 address
0200  * cycles if not set.
0201  */
0202 #define MLC_MANY_ADDRESS_CYCLES 0x2U
0203 
0204 /**
0205  * @brief Selects 64 pages per block or 128 pages per block if not set.
0206  *
0207  * This flag is only valid for large pages.
0208  */
0209 #define MLC_NORMAL_BLOCKS 0x4U
0210 
0211 /**
0212  * @brief Selects 16-bit IO width or 8-bit IO width if not set.
0213  */
0214 #define MLC_IO_WIDTH_16_BIT 0x8U
0215 
0216 /**
0217  * @brief Initializes the MLC NAND controller according to @a cfg.
0218  */
0219 void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg);
0220 
0221 uint32_t lpc32xx_mlc_page_size(void);
0222 
0223 uint32_t lpc32xx_mlc_pages_per_block(void);
0224 
0225 uint32_t lpc32xx_mlc_block_count(void);
0226 
0227 uint32_t lpc32xx_mlc_io_width(void);
0228 
0229 void lpc32xx_mlc_write_protection(
0230   uint32_t page_index_low,
0231   uint32_t page_index_high
0232 );
0233 
0234 void lpc32xx_mlc_read_id(uint8_t *id, size_t n);
0235 
0236 /**
0237  * @brief Reads the page with index @a page_index.
0238  *
0239  * Bytes 6 to 15 of the spare area will contain the ECC.
0240  *
0241  * If the read is successful, then the @a symbol_error_count will contain the
0242  * number of detected symbol errors (0, 1, 2, 3, or 4), else the value will be
0243  * 0xffffffff.  The @a symbol_error_count pointer may be @c NULL.
0244  *
0245  * @retval RTEMS_SUCCESSFUL Successful operation.
0246  * @retval RTEMS_INVALID_ID Invalid @a page_index value.
0247  * @retval RTEMS_IO_ERROR Uncorrectable bit error.
0248  */
0249 rtems_status_code lpc32xx_mlc_read_page(
0250   uint32_t page_index,
0251   void *data,
0252   void *spare,
0253   uint32_t *symbol_error_count
0254 );
0255 
0256 /**
0257  * @brief Checks if the block with index @a block_index is valid.
0258  *
0259  * The initial valid block information of the manufacturer will be used.
0260  * Unfortunately there seems to be no standard for this.  A block will be
0261  * considered as bad if the first or second page of this block does not contain
0262  * 0xff at the 6th byte of the spare area.  This should work for flashes with
0263  * small pages and a 8-bit IO width.
0264  *
0265  * @retval RTEMS_SUCCESSFUL The block is valid.
0266  * @retval RTEMS_INVALID_ID Invalid @a block_index value.
0267  * @retval RTEMS_IO_ERROR Uncorrectable bit error.
0268  * @retval RTEMS_INCORRECT_STATE The block is bad.
0269  * @retval RTEMS_NOT_IMPLEMENTED No implementation available for this flash
0270  * type.
0271  */
0272 rtems_status_code lpc32xx_mlc_is_valid_block(uint32_t block_index);
0273 
0274 /**
0275  * @brief Erases the block with index @a block_index.
0276  *
0277  * @retval RTEMS_SUCCESSFUL Successful operation.
0278  * @retval RTEMS_INVALID_ID Invalid @a block_index value.
0279  * @retval RTEMS_UNSATISFIED Erase error.
0280  */
0281 rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index);
0282 
0283 /**
0284  * @brief Erases the block with index @a block_index.
0285  *
0286  * In case of an erase error all pages and the spare areas of this block are
0287  * programmed with zero values.  This will hopefully mark the block as bad.
0288  *
0289  * @retval RTEMS_SUCCESSFUL Successful operation.
0290  * @retval RTEMS_INCORRECT_STATE The block is bad.
0291  * @retval RTEMS_INVALID_ID Invalid @a block_index value.
0292  * @retval RTEMS_UNSATISFIED Erase error.
0293  * @retval RTEMS_NOT_IMPLEMENTED No implementation available for this flash
0294  * type.
0295  */
0296 rtems_status_code lpc32xx_mlc_erase_block_safe(uint32_t block_index);
0297 
0298 /**
0299  * @brief Erases the block with index @a block_index.
0300  *
0301  * Variant of lpc32xx_mlc_erase_block_safe() with more parameters for
0302  * efficiency reasons.  The @a page_begin must be the index of the first page
0303  * of the block.  The @a page_end must be the page index of the last page of
0304  * the block plus one.
0305  */
0306 rtems_status_code lpc32xx_mlc_erase_block_safe_3(
0307   uint32_t block_index,
0308   uint32_t page_begin,
0309   uint32_t page_end
0310 );
0311 
0312 /**
0313  * @brief Writes zero values to the pages specified by @a page_begin and
0314  * @a page_end.
0315  *
0316  * The data and spare area are cleared to zero.  This marks the pages as bad.
0317  */
0318 void lpc32xx_mlc_zero_pages(uint32_t page_begin, uint32_t page_end);
0319 
0320 /**
0321  * @brief Writes the page with index @a page_index.
0322  *
0323  * Only the bytes 0 to 5 of the spare area can be used for user data, the bytes
0324  * 6 to 15 will be used for the automatically generated ECC.
0325  *
0326  * @retval RTEMS_SUCCESSFUL Successful operation.
0327  * @retval RTEMS_INVALID_ID Invalid @a page_index value.
0328  * @retval RTEMS_IO_ERROR Write error.
0329  */
0330 rtems_status_code lpc32xx_mlc_write_page_with_ecc(
0331   uint32_t page_index,
0332   const void *data,
0333   const void *spare
0334 );
0335 
0336 /**
0337  * @brief Writes @a src_size Bytes from @a src to the flash area specified by
0338  * @a block_begin and @a block_end.
0339  *
0340  * The @a page_buffer will be used as an intermediate buffer.
0341  *
0342  * @retval RTEMS_SUCCESSFUL Successful operation.
0343  * @retval RTEMS_INVALID_ID Invalid @a block_begin or @a block_end value.
0344  * @retval RTEMS_IO_ERROR Too many bad blocks or source area too big.
0345  */
0346 rtems_status_code lpc32xx_mlc_write_blocks(
0347   uint32_t block_begin,
0348   uint32_t block_end,
0349   const void *src,
0350   size_t src_size,
0351   uint32_t page_buffer [MLC_LARGE_DATA_WORD_COUNT]
0352 );
0353 
0354 /**
0355  * @brief Read blocks process function type.
0356  *
0357  * @see lpc32xx_mlc_read_blocks().
0358  *
0359  * @retval false Continue processing.
0360  * @retval true Stop processing.
0361  */
0362 typedef bool (*lpc32xx_mlc_read_process)(
0363   void *process_arg,
0364   uint32_t page_index,
0365   uint32_t page_size,
0366   uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT],
0367   uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]
0368 );
0369 
0370 /**
0371  * @brief Reads the pages of block @a block_begin up to and excluding
0372  * @a block_end.
0373  *
0374  * For each page @a process will be called with the @a process_arg parameter,
0375  * the page_index, the page data and the page spare.
0376  *
0377  * The @a page_buffer_0 and @a page_buffer_1 will be used as
0378  * intermediate buffers.
0379  */
0380 rtems_status_code lpc32xx_mlc_read_blocks(
0381   uint32_t block_begin,
0382   uint32_t block_end,
0383   lpc32xx_mlc_read_process process,
0384   void *process_arg,
0385   uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT],
0386   uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT]
0387 );
0388 
0389 /**
0390  * @brief Checks if the page spare area indicates to a bad page.
0391  *
0392  * If the first (byte offset 0) or sixth (byte offset 5) byte of the spare area
0393  * has a value other than 0xff, then it returns @a true (the page is bad), else
0394  * it returns @a false (the page is not bad).
0395  *
0396  * Samsung uses the sixth byte to indicate a bad page.  Mircon uses the first
0397  * and sixth byte to indicate a bad page.
0398  *
0399  * This functions works only for small page flashes.
0400  */
0401 static inline bool lpc32xx_mlc_is_bad_page(const uint32_t *spare)
0402 {
0403   uint32_t first_byte_mask = 0x000000ff;
0404   uint32_t sixth_byte_mask = 0x0000ff00;
0405 
0406   return (spare [0] & first_byte_mask) != first_byte_mask
0407     || (spare [1] & sixth_byte_mask) != sixth_byte_mask;
0408 }
0409 
0410 /** @} */
0411 
0412 #ifdef __cplusplus
0413 }
0414 #endif /* __cplusplus */
0415 
0416 #endif /* LIBBSP_ARM_LPC32XX_NAND_MLC_H */