summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2010-06-23 08:27:57 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2010-06-23 08:27:57 +0000
commit3103d4cbad582cc9e62aaf15fd5af308949a83f0 (patch)
treeb1ff4f68908b3177c614349a2f0252e4b64e9b18 /c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h
parent2010-06-23 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff)
downloadrtems-3103d4cbad582cc9e62aaf15fd5af308949a83f0.tar.bz2
2010-06-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
* make/custom/lpc32xx_mzx_boot_int.cfg, startup/linkcmds.lpc32xx_mzx_boot_int: Removed files. * include/boot.h, include/emc.h, include/i2c.h, include/nand-mlc.h, make/custom/lpc32xx_mzx.cfg, make/custom/lpc32xx_mzx_stage_1.cfg, make/custom/lpc32xx_mzx_stage_2.cfg, misc/boot.c, misc/emc.c, misc/i2c.c, misc/nand-mlc.c, misc/nand-mlc-read-blocks.c, misc/nand-mlc-write-blocks.c, misc/restart.c, startup/linkcmds.lpc32xx, startup/linkcmds.lpc32xx_mzx, startup/linkcmds.lpc32xx_mzx_stage_1, startup/linkcmds.lpc32xx_mzx_stage_2: New files. * configure.ac, Makefile.am, preinstall.am: Reflect changes above. * include/bsp.h, include/lpc32xx.h, irq/irq.c, rtc/rtc-config.c, startup/bspstart.c, startup/bspstarthooks.c, startup/linkcmds.lpc32xx_phycore: Changes throughout.
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h335
1 files changed, 335 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h b/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h
new file mode 100644
index 0000000000..c5849103d0
--- /dev/null
+++ b/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h
@@ -0,0 +1,335 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_nand_mlc
+ *
+ * @brief NAND MLC controller API.
+ */
+
+/*
+ * Copyright (c) 2010
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_LPC32XX_NAND_MLC_H
+#define LIBBSP_ARM_LPC32XX_NAND_MLC_H
+
+#include <rtems.h>
+
+#include <bsp/utility.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup lpc32xx_nand_mlc NAND MLC Controller
+ *
+ * @ingroup lpc32xx
+ *
+ * @brief NAND MLC Controller.
+ *
+ * Timing constraints:
+ *
+ * -# (WR_LOW + 1) / HCLK >= tWP
+ * -# (WR_HIGH - WR_LOW) / HCLK >= tWH
+ * -# (WR_LOW + 1) / HCLK + (WR_HIGH - WR_LOW) / HCLK >= tWC
+ * -# (RD_LOW + 1) / HCLK >= tRP
+ * -# (RD_LOW + 1) / HCLK >= tREA + tSU
+ * -# (RD_HIGH - RD_LOW) / HCLK >= tREH
+ * -# (RD_LOW + 1) / HCLK + (RD_HIGH - RD_LOW) / HCLK >= tRC
+ * -# (RD_HIGH - RD_LOW) / HCLK + NAND_TA / HCLK >= tRHZ
+ * -# BUSY_DELAY / HCLK >= max(tWB, tRB)
+ * -# TCEA_DELAY / HCLK >= tCEA - tREA
+ *
+ * Known flash layouts (Format: SP = small pages, LP = large pages / address
+ * cycles / pages per block):
+ *
+ * -# SP/3/32
+ * -# SP/4/32
+ * -# LP/4/64
+ * -# LP/5/64
+ * -# LP/5/128
+ *
+ * @{
+ */
+
+/**
+ * @name MLC NAND Flash Dimensions
+ *
+ * @{
+ */
+
+#define MLC_SMALL_PAGE_SIZE 528
+#define MLC_SMALL_DATA_SIZE 512
+#define MLC_SMALL_SPARE_SIZE 16
+#define MLC_SMALL_DATA_WORD_COUNT (MLC_SMALL_DATA_SIZE / 4)
+#define MLC_SMALL_SPARE_WORD_COUNT (MLC_SMALL_SPARE_SIZE / 4)
+#define MLC_SMALL_PAGES_PER_LARGE_PAGE 4
+#define MLC_LARGE_PAGE_SIZE \
+ (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_PAGE_SIZE)
+#define MLC_LARGE_DATA_SIZE \
+ (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_DATA_SIZE)
+#define MLC_LARGE_SPARE_SIZE \
+ (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_SPARE_SIZE)
+#define MLC_LARGE_DATA_WORD_COUNT (MLC_LARGE_DATA_SIZE / 4)
+#define MLC_LARGE_SPARE_WORD_COUNT (MLC_LARGE_SPARE_SIZE / 4)
+
+/** @} */
+
+/**
+ * @name NAND Flash Clock Control Register (FLASHCLK_CTRL)
+ *
+ * @{
+ */
+
+#define FLASHCLK_IRQ_MLC BIT32(5)
+#define FLASHCLK_MLC_DMA_RNB BIT32(4)
+#define FLASHCLK_MLC_DMA_INT BIT32(3)
+#define FLASHCLK_SELECT_SLC BIT32(2)
+#define FLASHCLK_MLC_CLK_ENABLE BIT32(1)
+#define FLASHCLK_SLC_CLK_ENABLE BIT32(0)
+
+/** @} */
+
+/**
+ * @name MLC NAND Timing Register (MLC_TIME_REG)
+ *
+ * @{
+ */
+
+#define MLC_TIME_WR_LOW(val) FIELD32(val, 0, 3)
+#define MLC_TIME_WR_HIGH(val) FIELD32(val, 4, 7)
+#define MLC_TIME_RD_LOW(val) FIELD32(val, 8, 11)
+#define MLC_TIME_RD_HIGH(val) FIELD32(val, 12, 15)
+#define MLC_TIME_NAND_TA(val) FIELD32(val, 16, 18)
+#define MLC_TIME_BUSY_DELAY(val) FIELD32(val, 19, 23)
+#define MLC_TIME_TCEA_DELAY(val) FIELD32(val, 24, 25)
+
+/** @} */
+
+/**
+ * @name MLC NAND Lock Protection Register (MLC_LOCK_PR)
+ *
+ * @{
+ */
+
+#define MLC_UNLOCK_PROT 0xa25e
+
+/** @} */
+
+/**
+ * @name MLC NAND Status Register (MLC_ISR)
+ *
+ * @{
+ */
+
+#define MLC_ISR_DECODER_FAILURE BIT32(6)
+#define MLC_ISR_ERRORS_DETECTED BIT32(3)
+#define MLC_ISR_ECC_READY BIT32(2)
+#define MLC_ISR_CONTROLLER_READY BIT32(1)
+#define MLC_ISR_NAND_READY BIT32(0)
+
+/** @} */
+
+/**
+ * @name MLC NAND Controller Configuration Register (MLC_ICR)
+ *
+ * @{
+ */
+
+#define MLC_ICR_SOFT_WRITE_PROT BIT32(3)
+#define MLC_ICR_LARGE_PAGES BIT32(2)
+#define MLC_ICR_ADDR_WORD_COUNT_4_5 BIT32(1)
+#define MLC_ICR_IO_BUS_16 BIT32(0)
+
+/** @} */
+
+/**
+ * @name MLC NAND Auto Encode Register (MLC_ECC_AUTO_ENC)
+ *
+ * @{
+ */
+
+#define MLC_ECC_AUTO_ENC_PROGRAM BIT32(8)
+
+/** @} */
+
+#define MLC_BAD_BLOCK_MASK ((uint32_t) 0xff00)
+
+/**
+ * @name NAND Status Register
+ *
+ * @{
+ */
+
+#define NAND_STATUS_ERROR (1U << 0)
+#define NAND_STATUS_READY (1U << 6)
+#define NAND_STATUS_NOT_PROTECTED (1U << 7)
+
+/** @} */
+
+/**
+ * @brief MLC NAND controller configuration.
+ */
+typedef struct {
+ /**
+ * @brief Selects small pages (512 Bytes user data and 16 Bytes spare data)
+ * or large pages (2048 Bytes user data and 64 Bytes spare data).
+ */
+ bool small_pages;
+
+ /**
+ * @brief Selects 3/4 address cycles for small pages/large pages or 4/5
+ * address cycles.
+ */
+ bool many_address_cycles;
+
+ /**
+ * @brief Selects 64 or 128 pages per block in case of large pages.
+ */
+ bool normal_blocks;
+
+ uint32_t block_count;
+
+ /**
+ * @brief Value for the MLC NAND Timing Register (MLC_TIME_REG).
+ */
+ uint32_t time;
+} lpc32xx_mlc_config;
+
+/**
+ * @brief Initializes the MLC NAND controller according to @a cfg.
+ */
+void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg);
+
+uint32_t lpc32xx_mlc_page_size(void);
+
+uint32_t lpc32xx_mlc_pages_per_block(void);
+
+uint32_t lpc32xx_mlc_block_count(void);
+
+void lpc32xx_mlc_write_protection(
+ uint32_t page_index_low,
+ uint32_t page_index_high
+);
+
+void lpc32xx_mlc_read_id(uint8_t *id, size_t n);
+
+/**
+ * @brief Reads the page with index @a page_index.
+ *
+ * 32-bit reads will be performed.
+ *
+ * Bytes 7 to 15 of the spare area will contain the ECC.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid @a page_index value.
+ * @retval RTEMS_IO_ERROR Uncorrectable bit error.
+ */
+rtems_status_code lpc32xx_mlc_read_page(
+ uint32_t page_index,
+ uint32_t *data,
+ uint32_t *spare
+);
+
+/**
+ * @brief Erases the block with index @a block_index.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid @a block_index value.
+ * @retval RTEMS_IO_ERROR Erase error.
+ */
+rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index);
+
+/**
+ * @brief Writes the page with index @a page_index.
+ *
+ * 32-bit writes will be performed.
+ *
+ * Bytes 7 to 15 of the spare area will be used for the automatically generated
+ * ECC.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid @a page_index value.
+ * @retval RTEMS_IO_ERROR Write error.
+ */
+rtems_status_code lpc32xx_mlc_write_page_with_ecc(
+ uint32_t page_index,
+ const uint32_t *data,
+ const uint32_t *spare
+);
+
+/**
+ * @brief Writes @a src_size Bytes from @a src to the flash area specified by
+ * @a block_begin and @a block_end.
+ *
+ * The @a page_buffer will be used as an intermediate buffer.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid @a block_begin or @a block_end value.
+ * @retval RTEMS_IO_ERROR To many bad blocks or source area to big.
+ */
+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]
+);
+
+/**
+ * @brief Read blocks process function type.
+ *
+ * @see lpc32xx_mlc_read_blocks().
+ *
+ * @retval false Continue processing.
+ * @retval true Stop processing.
+ */
+typedef 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]
+);
+
+/**
+ * @brief Reads the pages of block @a block_begin up to and excluding
+ * @a block_end.
+ *
+ * For each page @a process will be called with the @a process_arg parameter,
+ * the page_index, the page data and the page spare.
+ *
+ * The @a page_buffer_0 and @a page_buffer_1 will be used as
+ * intermediate buffers.
+ */
+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]
+);
+
+static inline bool lpc32xx_mlc_is_bad_page(const uint32_t *spare)
+{
+ return (spare [1] & MLC_BAD_BLOCK_MASK) != MLC_BAD_BLOCK_MASK;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_ARM_LPC32XX_NAND_MLC_H */