274 lines
8.1 KiB
C
274 lines
8.1 KiB
C
/*
|
|
* spinand_ids.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.
|
|
*/
|
|
#include <mach/sunxi_spinand.h>
|
|
#include "spinand_ecc_op.h"
|
|
|
|
extern void NAND_Memcpy(void *pAddr_dst, void *pAddr_src, unsigned int len);
|
|
|
|
enum badblock_flag {
|
|
FIRST_PAGE = 0,
|
|
FIRST_TWO_PAGE,
|
|
LAST_PAGE,
|
|
LAST_TWO_PAGE,
|
|
};
|
|
|
|
struct __NandPhyInfoPar_t ext_spinand_idts[] = {
|
|
/*-----------------------------XTX--------------------------*/
|
|
{
|
|
/* XT26G01C */
|
|
.NandID = {0x0B, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 1024,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_QUAD_READ | NAND_MULTI_READ |
|
|
NAND_MULTI_PROGRAM | NAND_MAX_BLK_ERASE_CNT,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_PAGE, /* the 1st page */
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 65000,
|
|
.EccType = BIT4_LIMIT5_TO_8_ERR15,
|
|
.EccProtectedType = SIZE16_OFF0_LEN16,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_4,
|
|
},
|
|
{
|
|
/* XT26G02E */
|
|
.NandID = {0x2c, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 2048,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_MULTI_READ |
|
|
NAND_MULTI_PROGRAM | NAND_MAX_BLK_ERASE_CNT |
|
|
NAND_TWO_PLANE_SELECT,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_PAGE,
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 65000,
|
|
.EccType = BIT3_LIMIT3_LIMIT_5_ERR2,
|
|
.EccProtectedType = SIZE64_OFF32_LEN32,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_4,
|
|
},
|
|
{
|
|
/* XTX26G01A */
|
|
.NandID = {0x0B, 0xE1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 1024,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_MULTI_READ |
|
|
NAND_MULTI_PROGRAM | NAND_MAX_BLK_ERASE_CNT,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_PAGE,
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 50000,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_2,
|
|
.EccType = BIT4_LIMIT5_TO_7_ERR8_LIMIT_12,
|
|
.EccProtectedType = SIZE16_OFF8_LEN16,
|
|
},
|
|
{
|
|
/* XTX26G02A */
|
|
.NandID = {0x0B, 0xE2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 2048,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_QUAD_READ | NAND_MULTI_READ |
|
|
NAND_MULTI_PROGRAM | NAND_MAX_BLK_ERASE_CNT,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_PAGE,
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 50000,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_2,
|
|
.EccType = BIT4_LIMIT5_TO_7_ERR8_LIMIT_12,
|
|
.EccProtectedType = SIZE16_OFF8_LEN16,
|
|
},
|
|
|
|
/*--------------------------GigaDevice--------------------------*/
|
|
{
|
|
/* GD5F1GQ4UCYIG */
|
|
.NandID = {0xc8, 0xb1, 0x48, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 1024,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_MULTI_PROGRAM |
|
|
NAND_ONEDUMMY_AFTER_RANDOMREAD,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_PAGE, /* the 1st page */
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 50000,
|
|
.EccType = BIT3_LIMIT2_TO_6_ERR7,
|
|
.EccProtectedType = SIZE16_OFF0_LEN16,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_4,
|
|
},
|
|
{
|
|
/* GD5F2GQ5UEXXG */
|
|
.NandID = {0xc8, 0x52, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 2048,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_QUAD_READ | NAND_MULTI_PROGRAM |
|
|
NAND_MULTI_READ | NAND_MAX_BLK_ERASE_CNT,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_PAGE, /* the 1st page */
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 50000,
|
|
.EccType = BIT2_LIMIT1_ERR2_LIMIT3,
|
|
.EccProtectedType = SIZE16_OFF0_LEN16,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_4,
|
|
},
|
|
/*--------------------------FM--------------------------*/
|
|
{
|
|
/* FM25S01A*/
|
|
.NandID = {0xa1, 0xe4, 0x48, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 1024,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_QUAD_READ | NAND_MULTI_PROGRAM |
|
|
NAND_MULTI_READ | NAND_MAX_BLK_ERASE_CNT,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_TWO_PAGE, /* the 1st page */
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 50000,
|
|
.EccType = BIT2_LIMIT1_ERR2,
|
|
.EccProtectedType = SIZE16_OFF0_LEN16,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_4,
|
|
},
|
|
{
|
|
/* FM25S02A*/
|
|
.NandID = {0xa1, 0xe5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 2048,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_QUAD_READ | NAND_MULTI_PROGRAM |
|
|
NAND_MULTI_READ | NAND_MAX_BLK_ERASE_CNT,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_TWO_PAGE, /* the 1st page */
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 50000,
|
|
.EccType = BIT2_LIMIT1_ERR2,
|
|
.EccProtectedType = SIZE16_OFF0_LEN16,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_4,
|
|
},
|
|
/*--------------------------FORESEE--------------------------*/
|
|
{
|
|
/* FS35ND01G-S1Y2*/
|
|
.NandID = {0xcd, 0xea, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 1024,
|
|
.OperationOpt = NAND_DUAL_READ |NAND_MULTI_PROGRAM |
|
|
NAND_MULTI_READ,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_PAGE, /* the 1st page */
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 50000,
|
|
.EccType = BIT2_LIMIT1_ERR2,
|
|
.EccProtectedType = SIZE16_OFF0_LEN16,
|
|
.ecc_status_shift = ECC_STATUS_SHIFT_4,
|
|
},
|
|
|
|
/*------------------------------MXIC-----------------------------*/
|
|
{
|
|
/* MX35LF1GE4AB */
|
|
.NandID = {0xc2, 0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
.DieCntPerChip = 1,
|
|
.SectCntPerPage = 4,
|
|
.PageCntPerBlk = 64,
|
|
.BlkCntPerDie = 1024,
|
|
.OperationOpt = NAND_DUAL_READ | NAND_QUAD_READ | NAND_MULTI_PROGRAM,
|
|
.AccessFreq = 100,
|
|
.SpiMode = 0,
|
|
.pagewithbadflag = FIRST_TWO_PAGE, /* the 1st or 2nd page */
|
|
.spi_nand_function = &spinand_function,
|
|
.MultiPlaneBlockOffset = 1,
|
|
.MaxEraseTimes = 65000,
|
|
.EccType = BIT4_LIMIT3_TO_4_ERR15 | HAS_EXT_ECC_STATUS,
|
|
/**
|
|
* MX35LF1GE4AB should use SIZE16_OFF4_LEN12, however, in order
|
|
* to compatibility with versions already sent to customers,
|
|
* which do not use general physical layout, we used
|
|
* SIZE16_OFF4_LEN4_OFF8 instead.
|
|
*/
|
|
.EccProtectedType = SIZE16_OFF4_LEN4_OFF8,
|
|
},
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
{ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0}, // NULL
|
|
};
|
|
|
|
struct match_id {
|
|
int match_id_len;
|
|
struct __NandPhyInfoPar_t *match_nand_manu;
|
|
};
|
|
|
|
|
|
extern int NAND_Print(const char *fmt, ...);
|
|
__s32 seek_chip_from_ext_idts(unsigned char *chipid, struct __NandPhyInfoPar_t *nand_arch_info)
|
|
{
|
|
__s32 i = 0, j = 0;
|
|
int m = 0;
|
|
struct __NandPhyInfoPar_t *tmpNandManu = NULL;
|
|
|
|
struct match_id last_match = {
|
|
.match_id_len = 0,
|
|
.match_nand_manu = NULL,
|
|
};
|
|
|
|
for (i = 0; i < (sizeof(ext_spinand_idts) / sizeof(ext_spinand_idts[0])); i++) {
|
|
tmpNandManu = &ext_spinand_idts[i];
|
|
|
|
if (tmpNandManu->NandID[0] != chipid[0])
|
|
continue;
|
|
m = 1;
|
|
for (j = 1; j < 6; j++) {
|
|
if (tmpNandManu->NandID[j] == chipid[j] && tmpNandManu->NandID[j] != 0xff)
|
|
m++;
|
|
else
|
|
break;
|
|
}
|
|
if (m >= 2 && m > last_match.match_id_len) {
|
|
last_match.match_id_len = m;
|
|
last_match.match_nand_manu = tmpNandManu;
|
|
}
|
|
}
|
|
|
|
if (last_match.match_nand_manu != NULL) {
|
|
NAND_Memcpy(nand_arch_info, last_match.match_nand_manu, sizeof(struct __NandPhyInfoPar_t));
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|