586 lines
13 KiB
C
586 lines
13 KiB
C
|
#include <linux/kernel.h>
|
|||
|
#include <linux/slab.h>
|
|||
|
#include <linux/module.h>
|
|||
|
#include <linux/list.h>
|
|||
|
#include <linux/fs.h>
|
|||
|
#include <linux/blkdev.h>
|
|||
|
#include <linux/blkpg.h>
|
|||
|
#include <linux/spinlock.h>
|
|||
|
#include <linux/hdreg.h>
|
|||
|
#include <linux/init.h>
|
|||
|
#include <linux/semaphore.h>
|
|||
|
#include <linux/platform_device.h>
|
|||
|
#include <linux/clk.h>
|
|||
|
#include <linux/interrupt.h>
|
|||
|
#include <asm/uaccess.h>
|
|||
|
#include <linux/timer.h>
|
|||
|
#include <linux/delay.h>
|
|||
|
#include <linux/clk.h>
|
|||
|
#include <linux/mutex.h>
|
|||
|
/*#include <mach/clock.h>*/
|
|||
|
/*#include <mach/platform.h>*/
|
|||
|
/*#include <mach/hardware.h>*/
|
|||
|
/*#include <mach/sys_config.h>*/
|
|||
|
#include <linux/dma-mapping.h>
|
|||
|
/*#include <mach/dma.h>*/
|
|||
|
#include <linux/wait.h>
|
|||
|
#include <linux/sched.h>
|
|||
|
#include <asm/cacheflush.h>
|
|||
|
/*#include <mach/gpio.h>*/
|
|||
|
#include <linux/gpio.h>
|
|||
|
|
|||
|
#include "nand_lib.h"
|
|||
|
|
|||
|
extern int NAND_Print(const char *fmt, ...);
|
|||
|
|
|||
|
#define OOB_BUF_SIZE 32
|
|||
|
#define NAND_BOOT0_BLK_START 0
|
|||
|
#define NAND_BOOT0_BLK_CNT 2
|
|||
|
#define NAND_UBOOT_BLK_START (NAND_BOOT0_BLK_START+NAND_BOOT0_BLK_CNT)
|
|||
|
#define NAND_UBOOT_BLK_CNT 18
|
|||
|
#define NAND_BOOT0_PAGE_CNT_PER_COPY 32
|
|||
|
|
|||
|
#define debug NAND_Print
|
|||
|
|
|||
|
extern int get_nand_para(void *boot_buf);
|
|||
|
extern int gen_uboot_check_sum(void *boot_buf);
|
|||
|
extern int gen_check_sum(void *boot_buf);
|
|||
|
extern int get_dram_para(void *boot_buf);
|
|||
|
extern int get_nand_para_for_boot1(void *boot_buf);
|
|||
|
|
|||
|
extern int NAND_PhysicLockInit(void);
|
|||
|
extern int NAND_PhysicLock(void);
|
|||
|
extern int NAND_PhysicUnLock(void);
|
|||
|
extern int NAND_PhysicLockExit(void);
|
|||
|
|
|||
|
extern __u32 NAND_GetPageSize(void);
|
|||
|
extern __u32 NAND_GetPageCntPerBlk(void);
|
|||
|
extern __u32 NAND_GetVersion(__u8 *nand_version);
|
|||
|
extern __u32 NAND_GetBlkCntPerChip(void);
|
|||
|
extern __u32 NAND_GetChipCnt(void);
|
|||
|
extern __s32 NAND_GetBlkCntOfDie(void);
|
|||
|
extern int NAND_IS_Secure_sys(void);
|
|||
|
|
|||
|
__s32 burn_boot0_1k_mode(__u32 Boot0_buf)
|
|||
|
{
|
|||
|
__u32 i, j, k;
|
|||
|
__u32 pages_per_block;
|
|||
|
__u32 copies_per_block;
|
|||
|
__u8 oob_buf[32];
|
|||
|
struct boot_physical_param para;
|
|||
|
|
|||
|
debug("burn boot0 normal mode!\n");
|
|||
|
|
|||
|
for (i = 0; i < 32; i++)
|
|||
|
oob_buf[i] = 0xff;
|
|||
|
|
|||
|
NAND_GetVersion(oob_buf);
|
|||
|
if ((oob_buf[0] != 0xff) || (oob_buf[1] != 0x00)) {
|
|||
|
debug("get flash driver version error!");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
/* <20><><EFBFBD> page count */
|
|||
|
pages_per_block = NAND_GetPageCntPerBlk();
|
|||
|
if (pages_per_block % 64) {
|
|||
|
debug("get page cnt per block error %x!\n", pages_per_block);
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
/* cal copy cnt per bock */
|
|||
|
copies_per_block = pages_per_block / NAND_BOOT0_PAGE_CNT_PER_COPY;
|
|||
|
|
|||
|
/* burn boot0 copys */
|
|||
|
for (i = NAND_BOOT0_BLK_START; i < (NAND_BOOT0_BLK_START + NAND_BOOT0_BLK_CNT); i++) {
|
|||
|
debug("boot0 %x \n", i);
|
|||
|
|
|||
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
if (PHY_SimpleErase(¶) < 0) {
|
|||
|
debug("Fail in erasing block %d.\n", i);
|
|||
|
/*continue;*/
|
|||
|
}
|
|||
|
debug("after erase.\n");
|
|||
|
|
|||
|
/* <20>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD>дboot0<74><30><EFBFBD><EFBFBD> */
|
|||
|
for (j = 0; j < copies_per_block; j++) {
|
|||
|
|
|||
|
for (k = 0; k < NAND_BOOT0_PAGE_CNT_PER_COPY; k++) {
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
para.page = j * NAND_BOOT0_PAGE_CNT_PER_COPY + k;
|
|||
|
para.mainbuf = (void *)(Boot0_buf + k * 1024);
|
|||
|
para.oobbuf = oob_buf;
|
|||
|
para.sectorbitmap = 0x3;
|
|||
|
if (PHY_SimpleWrite(¶) < 0) {
|
|||
|
debug("Warning. Fail in writing page %d in block %d.\n", j * NAND_BOOT0_PAGE_CNT_PER_COPY + k, i);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
|
|||
|
error:
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int NAND_BurnBoot0(unsigned int length, void *buf)
|
|||
|
{
|
|||
|
__u32 page_size;
|
|||
|
|
|||
|
NAND_PhysicLock();
|
|||
|
|
|||
|
get_nand_para(buf);
|
|||
|
gen_check_sum(buf);
|
|||
|
|
|||
|
page_size = NAND_GetPageSize();
|
|||
|
|
|||
|
if (burn_boot0_1k_mode((__u32)buf))
|
|||
|
goto error;
|
|||
|
|
|||
|
NAND_PhysicUnLock();
|
|||
|
debug("burn boot 0 nonsecure success\n");
|
|||
|
return 0;
|
|||
|
|
|||
|
error:
|
|||
|
debug("burn boot 0 nonsecure failed\n");
|
|||
|
NAND_PhysicUnLock();
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
__s32 read_boot0_1k_mode(__u32 Boot0_buf)
|
|||
|
{
|
|||
|
__u32 i, j, k, m, err_flag;
|
|||
|
__u32 pages_per_block;
|
|||
|
__u32 copies_per_block;
|
|||
|
__u8 oob_buf[32];
|
|||
|
struct boot_physical_param para;
|
|||
|
|
|||
|
debug("read boot0 normal mode!\n");
|
|||
|
|
|||
|
/* <20><><EFBFBD> page count */
|
|||
|
pages_per_block = NAND_GetPageCntPerBlk();
|
|||
|
if (pages_per_block % 64) {
|
|||
|
debug("get page cnt per block error %x!", pages_per_block);
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
/* cal copy cnt per bock */
|
|||
|
copies_per_block = pages_per_block / NAND_BOOT0_PAGE_CNT_PER_COPY;
|
|||
|
|
|||
|
/* read boot0 copys */
|
|||
|
for (i = NAND_BOOT0_BLK_START; i < (NAND_BOOT0_BLK_START + NAND_BOOT0_BLK_CNT); i++) {
|
|||
|
debug("boot0 blk %x \n", i);
|
|||
|
|
|||
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
|
|||
|
for (j = 0; j < copies_per_block; j++) {
|
|||
|
err_flag = 0;
|
|||
|
for (k = 0; k < NAND_BOOT0_PAGE_CNT_PER_COPY; k++) {
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
para.page = j * NAND_BOOT0_PAGE_CNT_PER_COPY + k;
|
|||
|
para.mainbuf = (void *)(Boot0_buf + k * 1024);
|
|||
|
para.oobbuf = oob_buf;
|
|||
|
para.sectorbitmap = 0x3;
|
|||
|
for (m = 0; m < 32; m++)
|
|||
|
oob_buf[m] = 0x55;
|
|||
|
if (PHY_SimpleRead(¶) < 0) {
|
|||
|
debug("Warning. Fail in read page %d in block %d.\n", j * NAND_BOOT0_PAGE_CNT_PER_COPY + k, i);
|
|||
|
err_flag = 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
if ((oob_buf[0] != 0xff) || (oob_buf[1] != 0x00)) {
|
|||
|
debug("get flash driver version error!\n");
|
|||
|
err_flag = 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (err_flag == 0)
|
|||
|
break;
|
|||
|
}
|
|||
|
if (err_flag == 0)
|
|||
|
break;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
|
|||
|
error:
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
int NAND_ReadBoot0(unsigned int length, void *buf)
|
|||
|
{
|
|||
|
__u32 page_size;
|
|||
|
void *buffer = NULL;
|
|||
|
|
|||
|
buffer = (void *)kmalloc(1024 * 64, GFP_KERNEL);
|
|||
|
if (buffer == NULL) {
|
|||
|
debug("no memory!\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
page_size = NAND_GetPageSize();
|
|||
|
|
|||
|
if (read_boot0_1k_mode((__u32)buffer))
|
|||
|
goto error;
|
|||
|
|
|||
|
memcpy(buf, buffer, length);
|
|||
|
kfree(buffer);
|
|||
|
buffer = NULL;
|
|||
|
debug("nand read boot0 nonsecure ok\n");
|
|||
|
return 0;
|
|||
|
|
|||
|
error:
|
|||
|
kfree(buffer);
|
|||
|
buffer = NULL;
|
|||
|
debug("nand read boot0 nonsecure fail\n");
|
|||
|
return -1;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
__s32 burn_uboot_in_one_blk(__u32 BOOT1_buf, __u32 length)
|
|||
|
{
|
|||
|
__u32 i, k;
|
|||
|
__u8 oob_buf[32];
|
|||
|
__u32 page_size, pages_per_block, pages_per_copy;
|
|||
|
struct boot_physical_param para;
|
|||
|
|
|||
|
debug("burn boot1 in one block!\n");
|
|||
|
|
|||
|
for (i = 0; i < 32; i++)
|
|||
|
oob_buf[i] = 0xff;
|
|||
|
|
|||
|
/* get nand driver version */
|
|||
|
NAND_GetVersion(oob_buf);
|
|||
|
if ((oob_buf[0] != 0xff) || (oob_buf[1] != 0x00)) {
|
|||
|
debug("get flash driver version error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* ��� page count */
|
|||
|
page_size = NAND_GetPageSize();
|
|||
|
{
|
|||
|
if (page_size % 1024) {
|
|||
|
debug("get flash page size error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* ��� page count */
|
|||
|
pages_per_block = NAND_GetPageCntPerBlk();
|
|||
|
if (pages_per_block % 64) {
|
|||
|
debug("get page cnt per block error %x!\n", pages_per_block);
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
debug("pages_per_block: 0x%x\n", pages_per_block);
|
|||
|
|
|||
|
/*
|
|||
|
����ÿ��������ï?
|
|||
|
?½ï¿½page */
|
|||
|
if (length % page_size) {
|
|||
|
debug("uboot length check error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
pages_per_copy = length / page_size;
|
|||
|
if (pages_per_copy > pages_per_block) {
|
|||
|
debug("pages_per_copy check error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
debug("pages_per_copy: 0x%x\n", pages_per_copy);
|
|||
|
|
|||
|
if (page_size == 2048)
|
|||
|
para.sectorbitmap = 0xf;
|
|||
|
else if (page_size == 4096)
|
|||
|
para.sectorbitmap = 0xff;
|
|||
|
else if (page_size == 8192)
|
|||
|
para.sectorbitmap = 0xffff;
|
|||
|
|
|||
|
/* burn uboot */
|
|||
|
for (i = NAND_UBOOT_BLK_START; i < (NAND_UBOOT_BLK_START + NAND_UBOOT_BLK_CNT); i++) {
|
|||
|
debug("boot1 %x \n", i);
|
|||
|
|
|||
|
/* ������ */
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
if (PHY_SimpleErase(¶) < 0) {
|
|||
|
debug("Fail in erasing block %d.\n", i);
|
|||
|
/*continue;*/
|
|||
|
}
|
|||
|
|
|||
|
for (k = 0; k < pages_per_block; k++) {
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
para.page = k;
|
|||
|
para.mainbuf = (void *)(BOOT1_buf + k * page_size);
|
|||
|
para.oobbuf = oob_buf;
|
|||
|
if (PHY_SimpleWrite(¶) < 0) {
|
|||
|
debug("Warning. Fail in writing page %d in block %d.\n", k, i);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
|
|||
|
error:
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
__s32 burn_uboot_in_many_blks(__u32 BOOT1_buf, __u32 length)
|
|||
|
{
|
|||
|
__u32 i, k;
|
|||
|
__u8 oob_buf[32];
|
|||
|
__u32 page_size, pages_per_block, pages_per_copy, blocks_per_copy, block_index;
|
|||
|
struct boot_physical_param para;
|
|||
|
|
|||
|
debug("burn uboot in many blks!\n");
|
|||
|
|
|||
|
for (i = 0; i < 32; i++)
|
|||
|
oob_buf[i] = 0xff;
|
|||
|
|
|||
|
/* get nand driver version */
|
|||
|
NAND_GetVersion(oob_buf);
|
|||
|
if ((oob_buf[0] != 0xff) || (oob_buf[1] != 0x00)) {
|
|||
|
debug("get flash driver version error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* ��� page count */
|
|||
|
page_size = NAND_GetPageSize();
|
|||
|
{
|
|||
|
if (page_size % 1024) {
|
|||
|
debug("get flash page size error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* ��� page count */
|
|||
|
pages_per_block = NAND_GetPageCntPerBlk();
|
|||
|
if (pages_per_block % 64) {
|
|||
|
debug("get page cnt per block error %x!\n", pages_per_block);
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
pages_per_copy = length / page_size;
|
|||
|
if (length % page_size) {
|
|||
|
pages_per_copy++;
|
|||
|
}
|
|||
|
if (pages_per_copy <= pages_per_block) {
|
|||
|
debug("pages_per_copy check error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
blocks_per_copy = pages_per_copy / pages_per_block;
|
|||
|
if (pages_per_copy % pages_per_block) {
|
|||
|
blocks_per_copy++;
|
|||
|
}
|
|||
|
|
|||
|
if (page_size == 2048)
|
|||
|
para.sectorbitmap = 0xf;
|
|||
|
else if (page_size == 4096)
|
|||
|
para.sectorbitmap = 0xff;
|
|||
|
else if (page_size == 8192)
|
|||
|
para.sectorbitmap = 0xffff;
|
|||
|
|
|||
|
/* burn uboot */
|
|||
|
block_index = 0;
|
|||
|
for (i = NAND_UBOOT_BLK_START; i < (NAND_UBOOT_BLK_START + NAND_UBOOT_BLK_CNT); i++) {
|
|||
|
debug("uboot %x \n", i);
|
|||
|
|
|||
|
/* ������ */
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
if (PHY_SimpleErase(¶) < 0) {
|
|||
|
debug("Fail in erasing block %d.\n", i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
/* �ڿ�����дboot0����, lsb mode�£�ÿ����ֻ��дǰ4��page */
|
|||
|
for (k = 0; k < pages_per_block; k++) {
|
|||
|
para.chip = 0;
|
|||
|
para.block = i;
|
|||
|
para.page = k;
|
|||
|
para.mainbuf = (void *)(BOOT1_buf + (block_index * pages_per_block + k) * page_size);
|
|||
|
para.oobbuf = oob_buf;
|
|||
|
if (PHY_SimpleWrite(¶) < 0) {
|
|||
|
debug("Warning. Fail in writing page %d in block %d.\n", k, i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
block_index++;
|
|||
|
if (block_index >= blocks_per_copy)
|
|||
|
block_index = 0;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
error:
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
int NAND_BurnBoot1(unsigned int length, void *buf)
|
|||
|
{
|
|||
|
int ret = 0;
|
|||
|
__u32 page_size, pages_per_block, block_size;
|
|||
|
|
|||
|
NAND_PhysicLock();
|
|||
|
|
|||
|
page_size = NAND_GetPageSize();
|
|||
|
{
|
|||
|
if (page_size % 1024) {
|
|||
|
debug("get flash page size error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pages_per_block = NAND_GetPageCntPerBlk();
|
|||
|
if (pages_per_block % 64) {
|
|||
|
debug("get page cnt per block error %x!\n", pages_per_block);
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
block_size = page_size * pages_per_block;
|
|||
|
if (length % page_size) {
|
|||
|
debug("uboot length check error!\n");
|
|||
|
goto error;
|
|||
|
}
|
|||
|
|
|||
|
if (length <= block_size) {
|
|||
|
ret = burn_uboot_in_one_blk((__u32)buf, length);
|
|||
|
debug("NAND_BurnBoot1, in one blk, %d\n", ret);
|
|||
|
} else {
|
|||
|
ret = burn_uboot_in_many_blks((__u32)buf, length);
|
|||
|
debug("NAND_BurnBoot1, in many blks, %d\n", ret);
|
|||
|
}
|
|||
|
|
|||
|
NAND_PhysicUnLock();
|
|||
|
debug("burn boot 1 success\n");
|
|||
|
return ret;
|
|||
|
|
|||
|
error:
|
|||
|
NAND_PhysicUnLock();
|
|||
|
debug("burn boot 1 failed\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
void test_dram_para(void *buffer)
|
|||
|
{
|
|||
|
int *data;
|
|||
|
int i;
|
|||
|
|
|||
|
data = (int *)buffer;
|
|||
|
for (i = 0; i < 40; i += 4) {
|
|||
|
debug("%x %x %x %x\n", data[i + 0], data[i + 1], data[i + 2], data[i + 3]);
|
|||
|
}
|
|||
|
debug("\n");
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
__u32 PHY_erase_chip(void)
|
|||
|
{
|
|||
|
struct boot_physical_param para_read;
|
|||
|
int i, j, k;
|
|||
|
int ret;
|
|||
|
uint bad_block_flag;
|
|||
|
uint chip_cnt, page_size, page_per_block, blk_cnt_per_chip;
|
|||
|
uint block_cnt_of_die, start_blk;
|
|||
|
int page_index[4];
|
|||
|
uint chip;
|
|||
|
unsigned char oob_buf_read[OOB_BUF_SIZE];
|
|||
|
unsigned char *page_buf_read;
|
|||
|
int error_flag = 0;
|
|||
|
|
|||
|
page_buf_read = (unsigned char *)kmalloc(16 * 1024, GFP_KERNEL);
|
|||
|
if (!page_buf_read) {
|
|||
|
debug("malloc memory for page read fail\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
debug("Ready to erase chip.\n");
|
|||
|
|
|||
|
page_size = NAND_GetPageSize();
|
|||
|
page_per_block = NAND_GetPageCntPerBlk();
|
|||
|
blk_cnt_per_chip = NAND_GetBlkCntPerChip();
|
|||
|
debug("page_size=%d, page_per_block=%d, blk_cnt_per_chip=%d\n", page_size, page_per_block, blk_cnt_per_chip);
|
|||
|
chip_cnt = NAND_GetChipCnt();
|
|||
|
debug("chip_cnt = %x\n", chip_cnt);
|
|||
|
block_cnt_of_die = NAND_GetBlkCntOfDie();
|
|||
|
|
|||
|
page_index[0] = 0;
|
|||
|
page_index[1] = 0xEE;
|
|||
|
page_index[2] = 0xEE;
|
|||
|
page_index[3] = 0xEE;
|
|||
|
|
|||
|
|
|||
|
for (i = 0; i < chip_cnt; i++) {
|
|||
|
/*select chip*/
|
|||
|
chip = i;
|
|||
|
debug("erase chip %u \n", chip);
|
|||
|
|
|||
|
start_blk = 0;
|
|||
|
|
|||
|
/*scan for bad blocks, only erase good block, all 0x00 blocks is defined bad blocks*/
|
|||
|
for (j = start_blk; j < blk_cnt_per_chip; j++) {
|
|||
|
|
|||
|
para_read.block = j;
|
|||
|
|
|||
|
if ((j & 0xff) == 0)
|
|||
|
debug("erase chip %u, block %u\n", chip, para_read.block);
|
|||
|
|
|||
|
para_read.chip = chip;
|
|||
|
para_read.mainbuf = page_buf_read;
|
|||
|
para_read.oobbuf = oob_buf_read;
|
|||
|
|
|||
|
bad_block_flag = 0;
|
|||
|
|
|||
|
for (k = 0; k < 4; k++) {
|
|||
|
para_read.page = page_index[k];
|
|||
|
if (para_read.page == 0xEE)
|
|||
|
break;
|
|||
|
|
|||
|
ret = PHY_SimpleRead(¶_read);
|
|||
|
|
|||
|
/*check the current block is a all 0x00 block*/
|
|||
|
if (oob_buf_read[0] == 0x0) {
|
|||
|
bad_block_flag = 1;
|
|||
|
debug("find a bad block %u\n", para_read.block);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (bad_block_flag)
|
|||
|
continue;
|
|||
|
|
|||
|
|
|||
|
ret = PHY_SimpleErase(¶_read);
|
|||
|
if (ret != 0) {
|
|||
|
debug("erasing block %u failed.\n", para_read.block);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
debug("has cleared the chip.\n");
|
|||
|
if (error_flag)
|
|||
|
debug("the nand is Bad.\n");
|
|||
|
else
|
|||
|
debug("the nand is OK.\n");
|
|||
|
|
|||
|
kfree(page_buf_read);
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
__s32 NAND_Get_OTA_Version(void)
|
|||
|
{
|
|||
|
return 0x1;
|
|||
|
}
|
|||
|
|