sdk-hwV1.3/lichee/linux-4.9/arch/arm/mach-sunxi/include/mach/sunxi_spinand.h

393 lines
14 KiB
C

/*
* spinand.c for SUNXI NAND .
*
* Copyright (C) 2016 Allwinner.
*
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef _SUNXI_NAND_H
#define _SUNXI_NAND_H
#include <asm/types.h>
#ifndef __s8
typedef signed char __s8;
#endif
#ifndef __u8
typedef unsigned char __u8;
#endif
#ifndef __s16
typedef signed short __s16;
#endif
#ifndef __u16
typedef unsigned short __u16;
#endif
#ifndef __s32
typedef signed int __s32;
#endif
#ifndef __u32
typedef unsigned int __u32;
#endif
#ifndef __s64
typedef signed long long __s64;
#endif
#ifndef __u64
typedef unsigned long long __u64;
#endif
#ifndef uchar
typedef unsigned char uchar;
#endif
#ifndef uint16
typedef unsigned short uint16;
#endif
#ifndef uint32
typedef unsigned int uint32;
#endif
#ifndef uint
typedef unsigned int uint;
#endif
#ifndef sint32
typedef int sint32;
#endif
#ifndef uint64
typedef unsigned long long uint64;
#endif
#ifndef sint16
typedef short sint16;
#endif
#ifndef UINT8
typedef unsigned char UINT8;
#endif
#ifndef UINT32
typedef unsigned int UINT32;
#endif
#ifndef SINT32
typedef signed int SINT32;
#endif
#define NULL ((void *)0)
//extern __u32 SPIC_IO_BASE;
/* run time control */
#define TEST_SPI_NO (0)
#define SPI_DEFAULT_CLK (40000000)
#define SPI_TX_WL (32)
#define SPI_RX_WL (32)
#define SPI_FIFO_SIZE (64)
#define SPI_CLK_SRC (1) //0-24M, 1-PLL6
#define SPI_MCLK (40000000)
//#define SPIC_BASE_OS (0x1000)
extern void *NAND_GetIOBaseAddr(u32 no);
#define SPI_BASE (u8 *)(NAND_GetIOBaseAddr(0))
//#define SPI_BASE (0xe086f000)
//#define SPI_IRQNO(_n) (INTC_SRC_SPI0 + (_n))
#define SPI_VAR (SPI_BASE + 0x00)
#define SPI_GCR (SPI_BASE + 0x04)
#define SPI_TCR (SPI_BASE + 0x08)
#define SPI_IER (SPI_BASE + 0x10)
#define SPI_ISR (SPI_BASE + 0x14)
#define SPI_FCR (SPI_BASE + 0x18)
#define SPI_FSR (SPI_BASE + 0x1c)
#define SPI_WCR (SPI_BASE + 0x20)
#define SPI_CCR (SPI_BASE + 0x24)
#define SPI_MBC (SPI_BASE + 0x30)
#define SPI_MTC (SPI_BASE + 0x34)
#define SPI_BCC (SPI_BASE + 0x38)
#define SPI_TXD (SPI_BASE + 0x200)
#define SPI_RXD (SPI_BASE + 0x300)
/* bit field of registers */
#define SPI_SOFT_RST (1U << 31)
#define SPI_TXPAUSE_EN (1U << 7)
#define SPI_MASTER (1U << 1)
#define SPI_ENABLE (1U << 0)
#define SPI_EXCHANGE (1U << 31)
#define SPI_SAMPLE_MODE (1U << 13)
#define SPI_LSB_MODE (1U << 12)
#define SPI_SAMPLE_CTRL (1U << 11)
#define SPI_RAPIDS_MODE (1U << 10)
#define SPI_DUMMY_1 (1U << 9)
#define SPI_DHB (1U << 8)
#define SPI_SET_SS_1 (1U << 7)
#define SPI_SS_MANUAL (1U << 6)
#define SPI_SEL_SS0 (0U << 4)
#define SPI_SEL_SS1 (1U << 4)
#define SPI_SEL_SS2 (2U << 4)
#define SPI_SEL_SS3 (3U << 4)
#define SPI_SS_N_INBST (1U << 3)
#define SPI_SS_ACTIVE0 (1U << 2)
#define SPI_MODE0 (0U << 0)
#define SPI_MODE1 (1U << 0)
#define SPI_MODE2 (2U << 0)
#define SPI_MODE3 (3U << 0)
#define SPI_CPHA (1U << 0)
#define SPI_SS_INT (1U << 13)
#define SPI_TC_INT (1U << 12)
#define SPI_TXUR_INT (1U << 11)
#define SPI_TXOF_INT (1U << 10)
#define SPI_RXUR_INT (1U << 9)
#define SPI_RXOF_INT (1U << 8)
#define SPI_TXFULL_INT (1U << 6)
#define SPI_TXEMPT_INT (1U << 5)
#define SPI_TXREQ_INT (1U << 4)
#define SPI_RXFULL_INT (1U << 2)
#define SPI_RXEMPT_INT (1U << 1)
#define SPI_RXREQ_INT (1U << 0)
#define SPI_ERROR_INT (SPI_TXUR_INT|SPI_TXOF_INT|SPI_RXUR_INT|SPI_RXOF_INT)
#define SPI_TXFIFO_RST (1U << 31)
#define SPI_TXFIFO_TST (1U << 30)
#define SPI_TXDMAREQ_EN (1U << 24)
#define SPI_RXFIFO_RST (1U << 15)
#define SPI_RXFIFO_TST (1U << 14)
#define SPI_RXDMAREQ_EN (1U << 8)
#define SPI_MASTER_DUAL (1U << 28)
#define SPI_NAND_READY (1U << 0)
#define SPI_NAND_ERASE_FAIL (1U << 2)
#define SPI_NAND_WRITE_FAIL (1U << 3)
#define SPI_NAND_ECC_FIRST_BIT (4)
#define SPI_NAND_ECC_BITMAP (0x3)
#define SPI_NAND_INT_ECCSR_BITMAP (0xf)
#define SPI_NAND_WREN 0x06
#define SPI_NAND_WRDI 0x04
#define SPI_NAND_GETSR 0x0f //get status/features
#define SPI_NAND_SETSR 0x1f //set status/features
#define SPI_NAND_PAGE_READ 0x13
#define SPI_NAND_FAST_READ_X1 0x0b
#define SPI_NAND_READ_X1 0x03
#define SPI_NAND_READ_X2 0x3b
#define SPI_NAND_READ_X4 0x6b
#define SPI_NAND_READ_DUAL_IO 0xbb
#define SPI_NAND_READ_QUAD_IO 0xeb
#define SPI_NAND_RDID 0x9f
#define SPI_NAND_PP 0x02
#define SPI_NAND_PP_X4 0x32
#define SPI_NAND_RANDOM_PP 0x84
#define SPI_NAND_RANDOM_PP_X4 0x34
#define SPI_NAND_PE 0x10 //program execute
#define SPI_NAND_BE 0xd8 //block erase
#define SPI_NAND_RESET 0xff
#define SPI_NAND_READ_INT_ECCSTATUS 0x7c
#undef readb
#undef readw
#undef writeb
#undef writew
#define readb(addr) (*((volatile unsigned char *)(addr)))
#define readw(addr) (*((volatile unsigned int *)(addr)))
#define writeb(v, addr) (*((volatile unsigned char *)(addr)) = (unsigned char)(v))
#define writew(v, addr) (*((volatile unsigned int *)(addr)) = (unsigned int)(v))
#define NAND_OP_TRUE (0) //define the successful return value
#define NAND_OP_FALSE (-1) //define the failed return value
//define the return value
//#define ECC_CORRECT 9 //error can be corrected
#define ECC_LIMIT 10 //reach the limit of the ability of ECC
#define ERR_ECC 12 //too much ecc error
#define ERR_NANDFAIL 13 //nand flash program or erase fail
#define ERR_TIMEOUT 14 //hardware timeout
#define SECTOR_SIZE 512 //the size of a sector, based on byte
/* define the mask for the nand flash optional operation */
/* nand flash support dual read operation */
#define NAND_DUAL_READ (1 << 0)
/* nand flash support page dual program operation */
#define NAND_DUAL_PROGRAM (1 << 1)
/* nand flash support multi-plane page read operation */
#define NAND_MULTI_READ (1 << 2)
/* nand flash support multi-plane page program operation */
#define NAND_MULTI_PROGRAM (1 << 3)
/* nand flash support external inter-leave operation, it based multi-chip */
#define NAND_EXT_INTERLEAVE (1 << 4)
/* nand flash support the maximum block erase cnt */
#define NAND_MAX_BLK_ERASE_CNT (1 << 5)
/* nand flash support to read reclaim Operation */
#define NAND_READ_RECLAIM (1 << 6)
/* nand flash need plane select for addr */
#define NAND_TWO_PLANE_SELECT (1 << 7)
#define SPINAND_TWO_PLANE_SELECT NAND_TWO_PLANE_SELECT
/* nand flash need a dummy Byte after random fast read */
#define NAND_ONEDUMMY_AFTER_RANDOMREAD (1 << 8)
/* nand flash only support 8B user meta data under ecc protected */
#define NAND_8B_METADATA_ECC_PROTECTED (1 << 9)
/* nand flash support quad read operation */
#define NAND_QUAD_READ (1<<10)
/* nand flash support page quad program operation */
#define NAND_QUAD_PROGRAM (1<<11)
/* nand flash should not enable QE register bit manually */
#define SPINAND_QUAD_NO_NEED_ENABLE (1 << 12)
enum ecc_status_shift {
ECC_STATUS_SHIFT_0 = 0,
ECC_STATUS_SHIFT_1,
ECC_STATUS_SHIFT_2,
ECC_STATUS_SHIFT_3,
ECC_STATUS_SHIFT_4,
ECC_STATUS_SHIFT_5,
ECC_STATUS_SHIFT_6,
ECC_STATUS_SHIFT_7,
};
//define the nand flash physical information parameter type, for id table
struct __NandPhyInfoPar_t {
__u8 NandID[8]; //the ID number of the nand flash chip
__u8 DieCntPerChip; //the count of the Die in one nand flash chip
__u8 SectCntPerPage; //the count of the sectors in one single physical page
__u16 PageCntPerBlk; //the count of the pages in one single physical block
__u16 BlkCntPerDie; //the count fo the physical blocks in one nand flash Die
__u32 OperationOpt; //the bitmap that marks which optional operation that the nand flash can support
__u16 AccessFreq; //the highest access frequence of the nand flash chip, based on MHz
__u32 SpiMode; //spi nand mode, 0:mode 0, 3:mode 3
__u32 pagewithbadflag; //bad block flag was written at the first byte of spare area of this page
struct spi_nand_function *spi_nand_function; //erase,write,read function for spi nand
__u32 MultiPlaneBlockOffset; //the value of the block number offset between the two plane block
__u32 MaxEraseTimes; //the max erase times of a physic block
__u32 MaxEccBits; //the max ecc bits that nand support
__u32 EccLimitBits; //the ecc limit flag for tne nand
__u32 Idnumber;
__u32 EccType; // Just use in spinand2, select different ecc status type.
__u32 EccProtectedType; // just use in spinand2, select different ecc protected type.
enum ecc_status_shift ecc_status_shift;
__u8 reserved[4]; //reserved for 32bit align
};
//define the nand flash storage system information
struct __NandStorageInfo_t {
__u8 ChipCnt; //the count of the total nand flash chips are currently connecting on the CE pin
__u16 ChipConnectInfo; //chip connect information, bit == 1 means there is a chip connecting on the CE pin
__u8 ConnectMode; //the rb connect mode
__u8 BankCntPerChip; //the count of the banks in one nand chip, multiple banks can support Inter-Leave
__u8 DieCntPerChip; //the count of the dies in one nand chip, block management is based on Die
__u8 PlaneCntPerDie; //the count of planes in one die, multiple planes can support multi-plane operation
__u8 SectorCntPerPage; //the count of sectors in one single physic page, one sector is 0.5k
__u16 PageCntPerPhyBlk; //the count of physic pages in one physic block
__u32 BlkCntPerDie; //the count of the physic blocks in one die, include valid block and invalid block
__u32 OperationOpt; //the mask of the operation types which current nand flash can support support
__u16 FrequencePar; //the parameter of the hardware access clock, based on 'MHz'
__u32 SpiMode; //spi nand mode, 0:mode 0, 3:mode 3
__u8 NandChipId[8]; //the nand chip id of current connecting nand chip
__u32 pagewithbadflag; //bad block flag was written at the first byte of spare area of this page
__u32 MultiPlaneBlockOffset; //the value of the block number offset between the two plane block
__u32 MaxEraseTimes; //the max erase times of a physic block
__u32 MaxEccBits; //the max ecc bits that nand support
__u32 EccLimitBits; //the ecc limit flag for tne nand
__u32 Idnumber;
__u32 EccType; // Just use in spinand2, select different ecc status type.
__u32 EccProtectedType; // just use in spinand2, select different ecc protected type.
struct spi_nand_function *spi_nand_function; //erase,write,read function for spi nand
enum ecc_status_shift ecc_status_shift;
};
//define the page buffer pool for nand flash driver
struct __NandPageCachePool_t {
__u8 *PageCache0; //the pointer to the first page size ram buffer
// __u8 *PageCache1; //the pointer to the second page size ram buffer
// __u8 *PageCache2; //the pointer to the third page size ram buffer
__u8 *SpareCache;
__u8 *TmpPageCache;
__u8 *SpiPageCache;
__u8 *SpareCache1;
};
struct boot_physical_param {
__u32 chip; //chip no
__u32 block; // block no within chip
__u32 page; // apge no within block
__u32 sectorbitmap;
void *mainbuf; //data buf
void *oobbuf; //oob buf
};
struct spi_nand_function {
__s32 (*spi_nand_reset)(__u32 spi_no, __u32 chip);
__s32 (*spi_nand_read_status)(__u32 spi_no, __u32 chip, __u8 status, __u32 mode);
__s32 (*spi_nand_setstatus)(__u32 spi_no, __u32 chip, __u8 reg);
__s32 (*spi_nand_getblocklock)(__u32 spi_no, __u32 chip, __u8 *reg);
__s32 (*spi_nand_setblocklock)(__u32 spi_no, __u32 chip, __u8 reg);
__s32 (*spi_nand_getotp)(__u32 spi_no, __u32 chip, __u8 *reg);
__s32 (*spi_nand_setotp)(__u32 spi_no, __u32 chip, __u8 reg);
__s32 (*spi_nand_getoutdriver)(__u32 spi_no, __u32 chip, __u8 *reg);
__s32 (*spi_nand_setoutdriver)(__u32 spi_no, __u32 chip, __u8 reg);
__s32 (*erase_single_block)(struct boot_physical_param *eraseop);
__s32 (*write_single_page)(struct boot_physical_param *writeop);
__s32 (*read_single_page)(struct boot_physical_param *readop, __u32 spare_only_flag);
};
extern struct spi_nand_function spinand_function;
extern int nand_dma_config_start(__u32 tx_mode, __u32 addr, __u32 length);
extern int NAND_WaitDmaFinish(__u32 tx_flag, __u32 rx_flag);
extern int Nand_Dma_End(__u32 rw, __u32 addr, __u32 length);
extern int spinand_get_mbr(char *buffer, uint len);
extern int spinand_uboot_init(int boot_mode);
extern int spinand_uboot_exit(int force);
extern int spinand_uboot_probe(void);
extern uint spinand_uboot_read(uint start, uint sectors, void *buffer);
extern uint spinand_uboot_write(uint start, uint sectors, void *buffer);
extern int spinand_download_boot0(uint length, void *buffer);
extern int spinand_download_uboot(uint length, void *buffer);
extern int spinand_force_download_uboot(uint length, void *buffer);
extern int spinand_uboot_erase(int user_erase);
extern uint spinand_uboot_get_flash_info(void *buffer, uint length);
extern uint spinand_uboot_set_flash_info(void *buffer, uint length);
extern uint spinand_uboot_get_flash_size(void);
extern int spinand_uboot_flush(void);
extern int SPINAND_Uboot_Force_Erase(void);
uint spinand_upload_boot0(uint length, void *buf);
int spinand_download_boot0_simple(uint length, void *buffer);
#endif