176 lines
4.8 KiB
C
Executable File
176 lines
4.8 KiB
C
Executable File
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/signal.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/init.h>
|
|
#include <linux/timer.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <asm/io.h>
|
|
#include <asm/tc3162/tc3162.h>
|
|
#include <asm/tc3162/ledcetrl.h>
|
|
#include <linux/mtd/rt_flash.h>
|
|
#include <ecnt_hook/ecnt_hook.h>
|
|
#include <ecnt_hook/ecnt_hook_spi_nand.h>
|
|
#include "spi/spi_nand_flash.h"
|
|
#if defined(TCSUPPORT_CPU_EN7523)
|
|
#include "../../../../modules/private/auto_bench/7523/autobench.h"
|
|
#elif defined(TCSUPPORT_CPU_EN7528)
|
|
#include "../../../../modules/private/auto_bench/7528/autobench.h"
|
|
#elif defined(TCSUPPORT_CPU_EN7580)
|
|
#include "../../../../modules/private/auto_bench/7580/autobench.h"
|
|
#else
|
|
#include "../../../../modules/private/auto_bench/751627/autobench.h"
|
|
#endif
|
|
|
|
#define SCRIPT_CMD "/usr/script/autobench_flash.sh"
|
|
#define ERASE_CHECK_FILE "/tmp/flash_erase_check"
|
|
#define WRITE_CHECK_FILE "/tmp/flash_write_check"
|
|
#define WRITE_FILE "/userfs/bin/mtd"
|
|
#define ENV_PARAM1 "HOME=/"
|
|
#define ENV_PARAM2 "TERM=vt100"
|
|
#define ENV_PARAM3 "PATH=/sbin:/usr/sbin:/bin:/usr/bin:/userfs/bin"
|
|
#define DBG_EN 0
|
|
#define dbg_printf(fmt, val...) {if(DBG_EN){printk("[DBG(%d) %s:]",__LINE__,__func__);printk(fmt, ##val);printk("\n");}}
|
|
#define TEST_SIZE 2048
|
|
|
|
u8 buf[TEST_SIZE], buf2[TEST_SIZE];
|
|
|
|
void (*flash_callusermodehelper)(int*cmdSeq, int wait);
|
|
EXPORT_SYMBOL(flash_callusermodehelper);
|
|
|
|
#if defined(TCSUPPORT_PARALLEL_NAND)
|
|
extern void parallel_nand_initial_hw(void);
|
|
extern void parallel_nand_chip_select(u8 chip);
|
|
extern SPI_NAND_FLASH_RTN_T parallel_nand_protocol_reset (void);
|
|
extern SPI_NAND_FLASH_RTN_T parallel_nand_protocol_read_id(struct SPI_NAND_FLASH_INFO_T *ptr_rtn_flash_id);
|
|
extern unsigned long spinand_lock(void);
|
|
extern void spinand_unlock(unsigned long spinand_spinlock_flags);
|
|
int parallel_nand_test(void)
|
|
{
|
|
int rtn_status = -1;
|
|
u8 chip = 0, chip_num = 0;
|
|
u32 reg1 = 0, reg2= 0;
|
|
struct SPI_NAND_FLASH_INFO_T flashdev_info[2];
|
|
unsigned long spinand_spinlock_flags;
|
|
|
|
memset(flashdev_info, 0, (sizeof(struct SPI_NAND_FLASH_INFO_T) * 2));
|
|
|
|
spinand_spinlock_flags = spinand_lock();
|
|
reg1 = VPint(0xBFA20224);
|
|
reg2 = VPint(0xBFA1155C);
|
|
VPint(0xBFA1155C) = 0x2;
|
|
VPint(0xBFA20224) = 0x200;
|
|
parallel_nand_initial_hw();
|
|
|
|
for (chip = 0; chip < 2; chip++)
|
|
{
|
|
parallel_nand_chip_select(chip);
|
|
parallel_nand_protocol_reset();
|
|
parallel_nand_protocol_read_id(&flashdev_info[chip]);
|
|
if ((flashdev_info[chip].mfr_id == _SPI_NAND_MANUFACTURER_ID_WINBOND) &&
|
|
(flashdev_info[chip].dev_id == 0xDC) &&
|
|
(flashdev_info[chip].ext_id == 0x549590))
|
|
{
|
|
chip_num++;
|
|
}
|
|
}
|
|
|
|
if ((chip_num == 2))
|
|
{
|
|
rtn_status = 0;
|
|
}
|
|
VPint(0xBFA20224) = reg1;
|
|
VPint(0xBFA1155C) = reg2;
|
|
spinand_unlock(spinand_spinlock_flags);
|
|
|
|
return rtn_status;
|
|
}
|
|
#endif
|
|
|
|
int flash_test(void){
|
|
int i;
|
|
struct file *file = NULL;
|
|
mm_segment_t old_fs;
|
|
|
|
|
|
int cmdSeq[]={FLASH_TEST,CMD_NULL};
|
|
if(flash_callusermodehelper != NULL) {
|
|
flash_callusermodehelper(cmdSeq, UMH_WAIT_PROC);
|
|
}
|
|
|
|
old_fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
|
|
/* Erase check */
|
|
file = filp_open(ERASE_CHECK_FILE, O_RDONLY, 0);
|
|
if(IS_ERR(file)) {
|
|
printk("\r\nwhen open file %s error!",ERASE_CHECK_FILE);
|
|
return -1;
|
|
} else {
|
|
memset(buf, 0x00, TEST_SIZE);
|
|
ecnt_kernel_fs_read(file, buf, TEST_SIZE, &file->f_pos);
|
|
filp_close(file,NULL);
|
|
}
|
|
for(i = 0; i < TEST_SIZE; i++) { /* Erase check fail */
|
|
if(buf[i] != 0xFF) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* Write check */
|
|
file = filp_open(WRITE_FILE, O_RDONLY, 0);
|
|
if(IS_ERR(file)) {
|
|
printk("\r\nwhen open file %s error!",WRITE_FILE);
|
|
return -1;
|
|
} else {
|
|
memset(buf, 0x00, TEST_SIZE);
|
|
ecnt_kernel_fs_read(file, buf, TEST_SIZE, &file->f_pos);
|
|
filp_close(file,NULL);
|
|
}
|
|
file = filp_open(WRITE_CHECK_FILE, O_RDONLY, 0);
|
|
if(IS_ERR(file)) {
|
|
printk("\r\nwhen open file %s error!",WRITE_CHECK_FILE);
|
|
return -1;
|
|
} else {
|
|
memset(buf2, 0x00, TEST_SIZE);
|
|
ecnt_kernel_fs_read(file, buf2, TEST_SIZE, &file->f_pos);
|
|
filp_close(file,NULL);
|
|
}
|
|
if(memcmp(buf, buf2, TEST_SIZE) != 0) { /* Write check fail */
|
|
return -1;
|
|
}
|
|
|
|
set_fs(old_fs);
|
|
return 0;
|
|
}
|
|
|
|
spi_nand_op_t ecnt_spi_nand_operation[] =
|
|
{
|
|
/* autobench */
|
|
flash_test,
|
|
#if defined(TCSUPPORT_PARALLEL_NAND)
|
|
parallel_nand_test,
|
|
#endif
|
|
};
|
|
|
|
ecnt_ret_val ecnt_spi_nand_hook(struct ecnt_data *in_data)
|
|
{
|
|
struct ECNT_SPI_NAND_DATA *spi_nand_data = (struct ECNT_SPI_NAND_DATA *)in_data ;
|
|
|
|
if(spi_nand_data->function_id >= SPI_NAND_FUNCTION_MAX_NUM) {
|
|
printk("spi_nand_data->function_id is %d, exceed max number: %d", spi_nand_data->function_id, SPI_NAND_FUNCTION_MAX_NUM);
|
|
return ECNT_HOOK_ERROR;
|
|
}
|
|
|
|
spi_nand_data->retValue = ecnt_spi_nand_operation[spi_nand_data->function_id](spi_nand_data) ;
|
|
|
|
return ECNT_CONTINUE;
|
|
}
|
|
|