rt-thread/bsp/phytium/libraries/standalone/drivers/nand/fnand/fnand.h

303 lines
12 KiB
C
Raw Normal View History

/*
* Copyright : (C) 2022 Phytium Information Technology, Inc.
* All Rights Reserved.
*
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
* either version 1.0 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Phytium Public License for more details.
*
*
* FilePath: fnand.h
* Date: 2022-05-07 15:40:42
* LastEditTime: 2022-05-07 15:40:42
* Description:  This files is for
*
* Modify History:
* Ver   Who        Date         Changes
* ----- ------     --------    --------------------------------------
*/
#ifndef DRIVERS_NAND_FNAND_H
#define DRIVERS_NAND_FNAND_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "ftypes.h"
#include "fassert.h"
#include "fnand_dma.h"
#include "fnand_timing.h"
#include "fparameters.h"
#include "fkernel.h"
#define FNAND_ERR_OPERATION FT_CODE_ERR(ErrModBsp, ErrNand, 0x1u)
#define FNAND_ERR_INVAILD_PARAMETER FT_CODE_ERR(ErrModBsp, ErrNand, 0x2u)
#define FNAND_IS_BUSY FT_CODE_ERR(ErrModBsp, ErrNand, 0x3u)
#define FNAND_OP_TIMEOUT FT_CODE_ERR(ErrModBsp, ErrNand, 0x4u)
#define FNAND_VALUE_ERROR FT_CODE_ERR(ErrModBsp, ErrNand, 0x7u)
#define FNAND_VALUE_FAILURE FT_CODE_ERR(ErrModBsp, ErrNand, 0x8u)
#define FNAND_NOT_FET_TOGGLE_MODE FT_CODE_ERR(ErrModBsp, ErrNand, 0xCu)
#define FNAND_ERR_READ_ECC FT_CODE_ERR(ErrModBsp, ErrNand, 0xBu)
#define FNAND_ERR_IRQ_LACK_OF_CALLBACK FT_CODE_ERR(ErrModBsp, ErrNand, 0xCu)
#define FNAND_ERR_IRQ_OP_FAILED FT_CODE_ERR(ErrModBsp, ErrNand, 0xdu)
#define FNAND_ERR_NOT_MATCH FT_CODE_ERR(ErrModBsp, ErrNand, 0xEu)
#define FNAND_MAX_BLOCKS 32768 /* Max number of Blocks */
#define FNAND_MAX_PAGE_SIZE 16384 /* Max page size of NAND \
flash */
#define FNAND_MAX_SPARE_SIZE 1024 /* Max spare bytes of a NAND \
flash page */
/* dma */
#define FNAND_DMA_MAX_LENGTH (32*1024)
/* options */
/* These constants are used as option to FNandSetOption() */
#define FNAND_OPS_INTER_MODE_SELECT 1U /* */
/* These constants are used as parameters to FNandSetIsrHandler() */
#define FNAND_WORK_MODE_POLL 0U
#define FNAND_WORK_MODE_ISR 1U
/* NAND Flash Interface */
#define FNAND_ONFI_MODE 0U
#define FNAND_TOGGLE_MODE 1U
typedef enum
{
FNAND_ASYNC_TIM_INT_MODE0 = 0,
FNAND_ASYNC_TIM_INT_MODE1,
FNAND_ASYNC_TIM_INT_MODE2,
FNAND_ASYNC_TIM_INT_MODE3,
FNAND_ASYNC_TIM_INT_MODE4,
} FNandAsyncTimint;
typedef enum
{
FNAND_CMD_TYPE = 0, /* 采用cmd 类型的操作类型 */
FNAND_WRITE_PAGE_TYPE, /* PAGE program 操作 */
FNAND_READ_PAGE_TYPE, /* PAGE read 操作 */
FNAND_WAIT_ECC_TYPE, /* Waiting ECC FINISH 操作 */
FNAND_TYPE_NUM
} FNandOperationType;
/* Irq Callback events */
typedef enum
{
FNAND_IRQ_BUSY_EVENT = 0,/* nandflash控制器忙状态中断状态位 */
FNAND_IRQ_DMA_BUSY_EVENT, /* dma控制器忙状态中断状态位 */
FNAND_IRQ_DMA_PGFINISH_EVENT, /* dma页操作完成中断状态位 */
FNAND_IRQ_DMA_FINISH_EVENT, /* dma操作完成中断完成中断状态位 */
FNAND_IRQ_FIFO_EMP_EVENT, /* fifo为空中断状态位 */
FNAND_IRQ_FIFO_FULL_EVENT, /* fifo为满中断状态位 */
FNAND_IRQ_FIFO_TIMEOUT_EVENT, /* fifo超时中断状态位 */
FNAND_IRQ_CMD_FINISH_EVENT, /* nand接口命令完成中断状态位 */
FNAND_IRQ_PGFINISH_EVENT, /* nand接口页操作完成中断状态位 */
FNAND_IRQ_RE_EVENT, /* re_n门控打开中断状态位 */
FNAND_IRQ_DQS_EVENT, /* dqs门控打开中断状态位 */
FNAND_IRQ_RB_EVENT, /* rb_n信号busy中断状态位 */
FNAND_IRQ_ECC_FINISH_EVENT, /* ecc完成中断状态蔽位 */
FNAND_IRQ_ECC_ERR_EVENT /* ecc正确中断状态蔽位 */
} FNAND_CALL_BACK_EVENT;
typedef struct
{
u32 bytes_per_page; /* Bytes per page */
u32 spare_bytes_per_page; /* Size of spare area in bytes */
u32 pages_per_block; /* Pages per block */
u32 blocks_per_lun; /* Bocks per LUN */
u8 num_lun; /* Total number of LUN */
u8 flash_width; /* Data width of flash device */
u64 num_pages; /* Total number of pages in device */
u64 num_blocks; /* Total number of blocks in device */
u64 block_size; /* Size of a block in bytes */
u64 device_size; /* Total device size in bytes */
u8 rowaddr_cycles; /* Row address cycles */
u8 coladdr_cycles; /* Column address cycles */
u32 hw_ecc_steps; /* number of ECC steps per page */
u32 hw_ecc_length; /* 产生硬件ecc校验参数的个数 */
u32 ecc_offset; /* spare_bytes_per_page - hw_ecc_length = obb存放硬件ecc校验参数页位置的偏移 */
u32 ecc_step_size; /* 进行读写操作时单次ecc 的步骤的跨度 */
} FNandNandGeometry;
typedef enum
{
FNAND_ASYN_SDR = 0, /* ONFI & Toggle async */
FNAND_ONFI_DDR = 1, /* ONFI sync */
FNAND_TOG_ASYN_DDR = 2 /* Toggle async */
} FNandInterMode;
typedef enum
{
FNAND_TIMING_MODE0 = 0,
FNAND_TIMING_MODE1 = 1,
FNAND_TIMING_MODE2 = 2,
FNAND_TIMING_MODE3 = 3,
FNAND_TIMING_MODE4 = 4,
FNAND_TIMING_MODE5 = 5,
} FNandTimingMode;
typedef struct
{
u32 instance_id; /* Id of device*/
u32 irq_num; /* Irq number */
volatile uintptr_t base_address;
u32 ecc_strength; /* 每次ecc 步骤纠正的位数 */
u32 ecc_step_size; /* 进行读写操作时单次ecc 的步骤的跨度 */
} FNandConfig;
/**
* Bad block pattern
*/
typedef struct
{
u32 options; /**< Options to search the bad block pattern */
u32 offset; /**< Offset to search for specified pattern */
u32 length; /**< Number of bytes to check the pattern */
u8 pattern[2]; /**< Pattern format to search for */
} FNandBadBlockPattern;
typedef struct
{
u32 page_addr;
u8 *page_buf; /* page 数据缓存空间 */
u32 page_offset; /* 从offset开始拷贝页数据 */
u32 page_length; /* 从offset开始拷贝页数据的长度 */
s32 obb_required; /* obb 是否读取的标志位,1 需要操作oob 区域 */
u8 *oob_buf; /* obb 数据缓存空间 */
u32 oob_offset; /* 从offset开始拷贝页数据 */
u32 oob_length; /* 从offset开始拷贝页数据的长度 */
u32 chip_addr; /* 芯片地址 */
} FNandOpData;
/**
* Bad block table descriptor
*/
typedef struct
{
u32 page_offset; /* Page offset where BBT resides */
u32 sig_offset; /* Signature offset in Spare area */
u32 ver_offset; /* Offset of BBT version */
u32 sig_length; /* Length of the signature */
u32 max_blocks; /* Max blocks to search for BBT */
char signature[4]; /* BBT signature */
u8 version; /* BBT version */
u32 valid; /* BBT descriptor is valid or not */
} FNandBbtDesc;
typedef struct
{
u8 bbt[FNAND_MAX_BLOCKS >> 2];
FNandBbtDesc bbt_desc; /* Bad block table descriptor */
FNandBbtDesc bbt_mirror_desc; /* Mirror BBT descriptor */
FNandBadBlockPattern bb_pattern; /* Bad block pattern to search */
} FNandBadBlockManager;
/* DMA */
/* DMA buffer */
struct FNandDmaBuffer
{
u8 data_buffer[FNAND_DMA_MAX_LENGTH];
} __attribute__((packed)) __attribute__((aligned(128)));
/* operation api */
typedef struct _FNand FNand;
typedef FError(*FNandTransferP)(FNand *instance_p, FNandOpData *op_data_p);
typedef FError(*FNandEraseP)(FNand *instance_p, u32 page_address, u32 chip_addr);
typedef void (*FnandIrqEventHandler)(void *args, FNAND_CALL_BACK_EVENT event) ;
typedef FError(*FNandOperationWaitIrqCallback)(void *args);
typedef struct
{
u8 data[8];
u32 len;
} FNandId;
typedef struct _FNand
{
u32 is_ready; /* Device is ininitialized and ready*/
FNandConfig config;
u32 work_mode; /* NAND controler work mode */
/* nand flash info */
FNandInterMode inter_mode[FNAND_CONNECT_MAX_NUM]; /* NAND controler timing work mode */
FNandTimingMode timing_mode[FNAND_CONNECT_MAX_NUM];
u32 nand_flash_interface[FNAND_CONNECT_MAX_NUM] ; /* Nand Flash Interface , followed by FNAND_ONFI_MODE \ FNAND_TOGGLE_MODE*/
struct FNandDmaBuffer dma_data_buffer; /* DMA data buffer */
struct FNandDmaBuffer descriptor_buffer; /* DMA descriptor */
struct FNandSdrTimings sdr_timing; /* SDR NAND chip timings */
/* bbm */
FNandBadBlockManager bbt_manager[FNAND_CONNECT_MAX_NUM]; /* bad block manager handler */
/* nand detect */
FNandNandGeometry nand_geometry[FNAND_CONNECT_MAX_NUM]; /* nand flash infomation */
/* dma 页操作 */
FnandIrqEventHandler irq_event_fun_p; /* Interrupt event response function */
void *irq_args;
FNandOperationWaitIrqCallback wait_irq_fun_p; /* The NAND controller operates the wait function */
void *wait_args;
/* operations */
FNandTransferP write_p ; /* Write page function */
FNandTransferP read_p ; /* Read page function */
FNandTransferP write_oob_p ; /* Write page spare space function */
FNandTransferP read_oob_p ; /* Read page spare space function */
FNandTransferP write_hw_ecc_p ; /* Write page with hardware function */
FNandTransferP read_hw_ecc_p ; /* Read page with hardware function */
FNandEraseP erase_p; /* Erase block function */
} FNand;
FNandConfig *FNandLookupConfig(u32 instance_id);
FError FNandCfgInitialize(FNand *instance_p,
FNandConfig *config_p);
FError FNandScan(FNand *instance_p);
FError FNandSetOption(FNand *instance_p, u32 options, u32 value);
/* API */
FError FNandWritePage(FNand *instance_p, u32 page_addr, u8 *buffer, u32 page_copy_offset, u32 length, u8 *oob_buffer, u32 oob_copy_offset, u32 oob_length, u32 chip_addr);
FError FNandWritePageRaw(FNand *instance_p, u32 page_addr, u8 *buffer, u32 page_copy_offset, u32 length, u8 *oob_buffer, u32 oob_copy_offset, u32 oob_length, u32 chip_addr);
FError FNandReadPage(FNand *instance_p, u32 page_addr, u8 *buffer, u32 page_copy_offset, u32 length, u8 *oob_buffer, u32 oob_copy_offset, u32 oob_length, u32 chip_addr);
FError FNandEraseBlock(FNand *instance_p, u32 block, u32 chip_addr);
FError FNandReadPageOOb(FNand *instance_p, u32 page_addr, u8 *oob_buffer, u32 oob_copy_offset, u32 oob_length, u32 chip_addr);
FError FNandWritePageOOb(FNand *instance_p, u32 page_addr, u8 *oob_buffer, u32 page_copy_offset, u32 oob_length, u32 chip_addr);
FError FNandReadPageRaw(FNand *instance_p, u32 page_addr, u8 *buffer, u32 page_copy_offset, u32 length, u8 *oob_buffer, u32 oob_copy_offset, u32 oob_length, u32 chip_addr);
/* irq */
void FNandSetIsrHandler(FNand *instance_p, FnandIrqEventHandler event_p, void *irq_args);
void FNandIrqHandler(s32 vector, void *param);
void FNandOperationWaitIrqRegister(FNand *instance_p, FNandOperationWaitIrqCallback wait_irq_fun_p, void *wait_args);
void FNandIrqDisable(FNand *instance_p, u32 int_mask);
void FNandIsrEnable(FNand *instance_p, u32 int_mask);
/* bbm */
void FNandInitBbtDesc(FNand *instance_p);
FError FNandScanBbt(FNand *instance_p, u32 target_addr);
FError FNandIsBlockBad(FNand *instance_p, u32 block, u32 target_addr);
FError FNandMarkBlockBad(FNand *instance_p, u32 block, u32 chip_addr);
#ifdef __cplusplus
}
#endif
#endif // !