Files

630 lines
20 KiB
Perl
Raw Permalink Normal View History

2026-09-22 09:38:26 +08:00
#!/usr/local/bin/perl -w
# SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0
# Copyright (C) 2023 Unisoc, Inc.
# Author: Liangji.chen <liangji.chen@unisoc.com>
# This file is used for create sprd_nand_param.h
use File::Basename;
#use strict;
my $LOCAL_PATH;
BEGIN
{
$LOCAL_PATH = dirname($0);
}
#print "xxx $LOCAL_PATH\n";
use lib "$LOCAL_PATH/Spreadsheet";
use lib "$LOCAL_PATH/";
require 'ParseExcel.pm';
#****************************************************************************
# Customization Field
#****************************************************************************
my $DebugPrint = "no";
my $VersionAndChanglist = "2.0 support autodetect NAND ID and improvement\n";
my @MemoryDeviceList;
my $SPRD_NAND_PARAM_H = "sprd_nand_param.h";
my $MEMORY_DEVICE_LIST_XLS = "vendor/sprd/tools/mcp_gen/mcp.xls";
my $CONFIG_INI = "";
#****************************************************************************
# Main Thread Field
#****************************************************************************
if(@ARGV > 1)
{
my $parameters="";
my $where;
my $value;
my $tag;
for($j = 0;$j<@ARGV;$j++)
{
$parameters.=$ARGV[$j];
$parameters.=" ";
}
print "$parameters\n";
$value = &get_parameter_str($parameters,"-h");
if(length($value) > 0)
{
$SPRD_NAND_PARAM_H = $value;
print "$SPRD_NAND_PARAM_H\n";
}
$value = &get_parameter_str($parameters,"-x");
if(length($value) > 0)
{
$MEMORY_DEVICE_LIST_XLS = $value;
print "$MEMORY_DEVICE_LIST_XLS\n";
}
$value = &get_parameter_str($parameters,"-i");
if(length($value) > 0)
{
$CONFIG_INI = $value;
print "$CONFIG_INI\n";
if(! -e $CONFIG_INI){
#die "$CONFIG_INI not exist\n"
$CONFIG_INI = "";
}
}
}
&ReadNANDExcelFile();
&GenNANDHeaderFile();
if($DebugPrint eq "yes"){
print "nandgen done\n";
}
exit 0;
#****************************************************************************
# Subfunction Field
#****************************************************************************
sub ReadNANDExcelFile
{
my @all_column=[];
my $SheetName = "NAND";
my $parser = Spreadsheet::ParseExcel->new();
my $Book = $parser->Parse($MEMORY_DEVICE_LIST_XLS);
my $sheet = $Book->Worksheet($SheetName);
my %COLUMN_LIST;
my $tmp;
my $row;
my $col;
for($col = 0, $row = 0,$tmp = &xls_cell_value($sheet, $row, $col); $tmp; $col++, $tmp = &xls_cell_value($sheet, $row, $col))
{
$COLUMN_LIST{$tmp} = $col;
}
@all_column=sort (keys(%COLUMN_LIST));
if($DebugPrint eq "yes"){
print "@all_column\n";
}
for($row = 1,$tmp = &xls_cell_value($sheet, $row, $COLUMN_LIST{Part_Number});$tmp;$row++,$tmp = &xls_cell_value($sheet, $row, $COLUMN_LIST{Part_Number}))
{
foreach $i (@all_column){
$MemoryDeviceList[$row-1]{$i}=&xls_cell_value($sheet, $row, $COLUMN_LIST{$i});
}
}
if($DebugPrint eq "yes"){
print "~~~~~~~~~EXCEL INFO~~~~~~~~~~~\n";
for($index=0;$index<@MemoryDeviceList;$index++){
print "index:$index\n";
foreach $i (@all_column){
printf ("%-15s:%-20s ",$i,$MemoryDeviceList[$index]->{$i});
}
print "\n";
}
print "~~~~~~~~~There are $index Nand Chips~~~~~~~~~~~\n";
}
}
sub GenNANDHeaderFile()
{
my %InFileChip;
my %ChipParamters;
my $Longest_ID=0;
my $Chip_count=0;
my %maker_table_hash;
my %device_table_hash;
my $device_table_num=0;
my @device_table;
my @p_list;
my $SpareSize_B_2;
my $Type0;
my $Type1;
my $timing_ace_ns;
my $timing_rwl_ns;
my $timing_rwh_ns;
if(-e $SPRD_NAND_PARAM_H)
{
`chmod 777 $SPRD_NAND_PARAM_H`;
}
if(length($CONFIG_INI) > 0){
open(FD, "<$CONFIG_INI");
@p_list=<FD>;
close FD;
}
for($iter=0;$iter<@MemoryDeviceList;$iter++){
my $ID_length=0;
my $ID=$MemoryDeviceList[$iter]->{Nand_ID};
if(!exists($ChipParamters{$ID})){
my $partnumber = $MemoryDeviceList[$iter]->{Part_Number};
if(!&partnumber_is_exist($partnumber,@p_list)){
print "The chip:$ID $partnumber not selected.\n";
}
elsif(length($ID)%2){
print "The chip:$ID have wrong number,",length($ID),".\n";
}
else{
$ID_length=length($ID)/2-1;
if($ID_length > $Longest_ID){
$Longest_ID = $ID_length;
}
#print "\$Longest_ID=$Longest_ID\n";
$InFileChip{$iter}={'ID'=>$ID,'IDLength'=>$ID_length};
$ChipParamters{$ID}={'BlockSize_KB'=>$MemoryDeviceList[$iter]->{BlockSize_KB},'BlockNum'=>$MemoryDeviceList[$iter]->{BlockNum},
'PageSize_KB'=>$MemoryDeviceList[$iter]->{PageSize_KB},'SectSize_B'=>$MemoryDeviceList[$iter]->{SectSize_B},
'BusWidth'=>$MemoryDeviceList[$iter]->{BusWidth},
'Cycles'=>$MemoryDeviceList[$iter]->{Cycles},'spareSize_B'=>$MemoryDeviceList[$iter]->{spareSize_B},
'oob_nbadpos'=>$MemoryDeviceList[$iter]->{oob_nBadPos_B},'oob_nbadlen'=>$MemoryDeviceList[$iter]->{oob_nBadLen_B},
'oob_nEccBits_b'=>$MemoryDeviceList[$iter]->{oob_nEccBits_b},'oob_nEccPos_B'=>$MemoryDeviceList[$iter]->{oob_nEccPos_B},
'oob_nEccSize_B'=>$MemoryDeviceList[$iter]->{oob_nEccSize_B},'oob_nInfoPos_B'=>$MemoryDeviceList[$iter]->{oob_nInfoPos_B},
'oob_nInfoSize_B'=>$MemoryDeviceList[$iter]->{oob_nInfoSize_B},'Cell_type'=>$MemoryDeviceList[$iter]->{Cell_type},
'Intf_type'=>$MemoryDeviceList[$iter]->{Intf_type},'Support_cache'=>$MemoryDeviceList[$iter]->{Support_cache},
'Plane_sel_bit'=>$MemoryDeviceList[$iter]->{Plane_sel_bit},'Max_IO_Freq'=>$MemoryDeviceList[$iter]->{Max_IO_Freq},
};
$Chip_count++;
}
}# if(!exists($ChipParamters{$ID}))
else{#if ID is same,check if parameters is same.
if($ChipParamters{$ID}->{BlockSize_KB} == $MemoryDeviceList[$iter]->{BlockSize_KB}
&& $ChipParamters{$ID}->{BlockNum} == $MemoryDeviceList[$iter]->{BlockNum}
&& $ChipParamters{$ID}->{PageSize_KB} == $MemoryDeviceList[$iter]->{PageSize_KB}
&& $ChipParamters{$ID}->{SectSize_B} == $MemoryDeviceList[$iter]->{SectSize_B}
&& $ChipParamters{$ID}->{BusWidth} eq $MemoryDeviceList[$iter]->{BusWidth}
&& $ChipParamters{$ID}->{spareSize_B} eq $MemoryDeviceList[$iter]->{spareSize_B}
&& $ChipParamters{$ID}->{oob_nEccBits_b} eq $MemoryDeviceList[$iter]->{oob_nEccBits_b}
&& $ChipParamters{$ID}->{oob_nEccPos_B} eq $MemoryDeviceList[$iter]->{oob_nEccPos_B}
&& $ChipParamters{$ID}->{oob_nEccSize_B} eq $MemoryDeviceList[$iter]->{oob_nEccSize_B}
&& $ChipParamters{$ID}->{oob_nInfoPos_B} eq $MemoryDeviceList[$iter]->{oob_nInfoPos_B}
&& $ChipParamters{$ID}->{oob_nInfoSize_B} eq $MemoryDeviceList[$iter]->{oob_nInfoSize_B}){
print "There more than 1 chip have the ID:$MemoryDeviceList[$iter]->{Nand_ID},bypass it\n";
}
else{
print "$ChipParamters{$ID}->{BlockSize_KB},$ChipParamters{$ID}->{BlockNum},$ChipParamters{$ID}->{PageSize_KB},$ChipParamters{$ID}->{SectSize_B},$ChipParamters{$ID}->{BusWidth}";
print ",$ChipParamters{$ID}->{spareSize_B},$ChipParamters{$ID}->{oob_nEccBits_b},$ChipParamters{$ID}->{oob_nEccPos_B},$ChipParamters{$ID}->{oob_nEccSize_B},$ChipParamters{$ID}->{oob_nInfoPos_B},$ChipParamters{$ID}->{oob_nInfoSize_B}\n";
print "$MemoryDeviceList[$iter]->{BlockSize_KB},$MemoryDeviceList[$iter]->{BlockNum},$MemoryDeviceList[$iter]->{PageSize_KB},$MemoryDeviceList[$iter]->{SectSize_B},$MemoryDeviceList[$iter]->{BusWidth}";
print ",$MemoryDeviceList[$iter]->{spareSize_B},$MemoryDeviceList[$iter]->{oob_nEccBits_b},$MemoryDeviceList[$iter]->{oob_nEccPos_B},$MemoryDeviceList[$iter]->{oob_nEccSize_B},$MemoryDeviceList[$iter]->{oob_nInfoPos_B},$MemoryDeviceList[$iter]->{oob_nInfoSize_B}\n";
die "There more than 1 chip have the ID:$MemoryDeviceList[$iter]->{Nand_ID},but paramters is not same,you should modify the excel!!!!\n";
}
}
}
print "Chip_count=$Chip_count\n";
open(FD, ">$SPRD_NAND_PARAM_H") or &error_handler("open $SPRD_NAND_PARAM_H fail\n", __FILE__, __LINE__);
print FD "#ifndef __SPRD_NAND_PARAM_H__\n#define __SPRD_NAND_PARAM_H__\n\n";
print FD "#define STATIC_FUNC static __attribute__((unused))\n";
print FD &sprd_nand_param_h_head();
foreach $it (sort by_index (keys(%InFileChip))){
my $ID=$InFileChip{$it}->{ID};
#creat ID arry string
my @ID_arry=($ID =~ m/([\dA-Fa-f]{2})/gs);
my $arry_str="{";
for($i=0;$i<$Longest_ID;$i++){
if($i<@ID_arry){
$arry_str.="0x$ID_arry[$i]";
}else{
$arry_str.="0x00";
}
if($i<$Longest_ID-1){
$arry_str.=",";
}
}
$maker_table_hash{$ID_arry[0]}=$MemoryDeviceList[$it]->{Vendor};
$device_table_hash{$ID}={'ID_vendor'=>$ID_arry[0],'ID_type'=>$ID_arry[1],'Vendor'=>$MemoryDeviceList[$it]->{Vendor},'Part_Number'=>$MemoryDeviceList[$it]->{Part_Number},'BusWidth'=>$MemoryDeviceList[$it]->{BusWidth},'Type2'=>$MemoryDeviceList[$it]->{Type2},'BlockSize_KB'=>$MemoryDeviceList[$it]->{BlockSize_KB},'BlockNum'=>$MemoryDeviceList[$it]->{BlockNum}};
}
foreach $ID (keys(%device_table_hash)){
my $find=0;
for($i=0;$i<$device_table_num;$i++){
#print "$device_table_hash{$ID}->{Vendor} $device_table[$i]\n";
if($device_table_hash{$ID}->{Vendor} eq $device_table[$i]){
$find=1;
last;
}
}
if($find == 1){
next;
}
$device_table[$device_table_num]=$device_table_hash{$ID}->{Vendor};
#print "$device_table[$device_table_num]\n";
$device_table_num++;
}
print FD "#ifdef SPRD_NAND_DEVICE_TBL\n";
for($i=0;$i<@device_table;$i++){
my $l_maker=lc($device_table[$i]);
print FD "STATIC_FUNC struct sprd_nand_device "."$l_maker"."_device_table[] = {\n";
foreach $ID (keys(%device_table_hash)){
if($device_table_hash{$ID}->{Vendor} eq $device_table[$i]){
$Type0 = $device_table_hash{$ID}->{BlockSize_KB}*$device_table_hash{$ID}->{BlockNum}*8/(1024*1024);
$Type1 = substr($device_table_hash{$ID}->{BusWidth},3);
$Type1 = "x".$Type1;
print FD "\t{0x$device_table_hash{$ID}->{ID_type},\"$device_table_hash{$ID}->{Part_Number}\",\"$Type0"."Gb,$Type1,$device_table_hash{$ID}->{Type2}\"},\n";
}
}
print FD "\t{0x00,NULL,NULL}\n";
print FD "};\n\n";
}
print FD "STATIC_FUNC struct sprd_nand_maker maker_table[] = {\n";
foreach $ID_vendor (keys(%maker_table_hash)){
my $l_maker=lc($maker_table_hash{$ID_vendor});
print FD "\t{0x$ID_vendor,\"$maker_table_hash{$ID_vendor}\","."$l_maker"."_device_table},\n";
}
print FD "\t{0x00,NULL,NULL}\n";
print FD "};\n\n";
print FD "STATIC_FUNC struct sprd_nand_param sprd_nand_param_table[] = {\n";
foreach $it (sort by_index (keys(%InFileChip))){
my $ID=$InFileChip{$it}->{ID};
#creat ID arry string
my @ID_arry=($ID =~ m/([\dA-Fa-f]{2})/gs);
my $arry_str="{";
for($i=0;$i<$Longest_ID;$i++){
if($i<@ID_arry){
$arry_str.="0x$ID_arry[$i]";
}else{
$arry_str.="0x00";
}
if($i<$Longest_ID-1){
$arry_str.=",";
}
}
$arry_str.="}";
if($DebugPrint eq "yes"){
print "ID=$arry_str\n";
}
#print string to file
$SpareSize_B_2 = $MemoryDeviceList[$it]->{PageSize_KB}*1024/$MemoryDeviceList[$it]->{SectSize_B}*$MemoryDeviceList[$it]->{spareSize_B};
$timing_ace_ns = ($MemoryDeviceList[$it]->{timing_T_clh} > $MemoryDeviceList[$it]->{timing_T_alh}) ? $MemoryDeviceList[$it]->{timing_T_clh}:$MemoryDeviceList[$it]->{timing_T_alh};
$timing_rwl_ns = $MemoryDeviceList[$it]->{timing_T_wp};
$timing_rwh_ns = $MemoryDeviceList[$it]->{timing_T_wh};
print FD "\t{//$MemoryDeviceList[$it]->{Vendor}\n\t\t$arry_str,0x$ID_arry[0],0x$ID_arry[1], ";
print FD "\n\t\tSZ_K_BLOCK($MemoryDeviceList[$it]->{BlockSize_KB}),NUM_BLOCK($MemoryDeviceList[$it]->{BlockNum}), SZ_K_PAGE($MemoryDeviceList[$it]->{PageSize_KB}),SZ_B_SECTOR($MemoryDeviceList[$it]->{SectSize_B}),SZ_B_SPARE($SpareSize_B_2),$MemoryDeviceList[$it]->{BusWidth},$MemoryDeviceList[$it]->{Cycles},";
print FD "\n\t\t{$timing_ace_ns,$timing_rwl_ns,$timing_rwh_ns},";
print FD "\n\t\t{SZ_B_OOB($MemoryDeviceList[$it]->{spareSize_B}),ECC_BITS($MemoryDeviceList[$it]->{oob_nEccBits_b}),POS_ECC($MemoryDeviceList[$it]->{oob_nEccPos_B}),SZ_ECC($MemoryDeviceList[$it]->{oob_nEccSize_B}),POS_INFO($MemoryDeviceList[$it]->{oob_nInfoPos_B}),SZ_INFO($MemoryDeviceList[$it]->{oob_nInfoSize_B})},";
print FD "\n\t\tBAD_POS($MemoryDeviceList[$it]->{oob_nBadPos_B}),BAD_LEN($MemoryDeviceList[$it]->{oob_nBadLen_B}),";
print FD "\n\t\tCELL_TYPE($MemoryDeviceList[$it]->{Cell_type}),INTF_TYPE($MemoryDeviceList[$it]->{Intf_type}),IS_SUPT_CACHE_FUNC($MemoryDeviceList[$it]->{Support_cache}),";
print FD "\n\t\tPLANE_SEL_BIT($MemoryDeviceList[$it]->{Plane_sel_bit}),MAX_IO_FREQ($MemoryDeviceList[$it]->{Max_IO_Freq}),";
print FD "\n\t},\n";
}
print FD "\t{\n\t\t{0x00, 0x00, 0x00, 0x00, 0x00},0x00,0x00, ";
print FD "\n\t\tSZ_K_BLOCK(256),NUM_BLOCK(2048), SZ_K_PAGE(4),SZ_B_SECTOR(512),SZ_B_SPARE(128),0x01,0x05,";
print FD "\n\t\t{10,21,15},";
print FD "\n\t\t{SZ_B_OOB(16),ECC_BITS(8),POS_ECC(2),SZ_ECC(14),POS_INFO(0),SZ_INFO(0)},";
print FD "\n\t\tBAD_POS(2),BAD_LEN(0),";
print FD "\n\t\tCELL_TYPE(0),INTF_TYPE(0),IS_SUPT_CACHE_FUNC(no),";
print FD "\n\t\tPLANE_SEL_BIT(-1),MAX_IO_FREQ(0),";
print FD "\n\t}\n";
print FD "};\n\n";
print FD "#endif /* ifdef SPRD_NAND_DEVICE_TBL */\n";
#print FD &sprd_nand_param_h_fuction();
print FD "#endif\n";
close FD;
}
#****************************************************************************************
# subroutine: xls_cell_value
# return: Excel cell value no matter it's in merge area or not, and in windows or not
# input: $Sheet: Specified Excel Sheet
# input: $row: Specified row number
# input: $col: Specified column number
#****************************************************************************************
sub xls_cell_value()
{
my($Sheet, $row, $col) = @_;
my $cell = $Sheet->get_cell($row, $col);
if (defined $cell)
{
return $cell->Value();
} else
{
print "$Sheet: row=$row, col=$col undefined\n";
return;
}
}
sub partnumber_is_exist()
{
my($partnumber, @p_list) = @_;
my $where;
#print "$partnumber\n";
if(@p_list < 1){
#no mcp_config.ini,so select all
return 1;
}
foreach $it (@p_list){
chomp($it);
$it =~ s/^\s+//g;
$where = index($it,"\#");
if($where == 0){
#print "bypass $it\n";
}
else{
if($partnumber eq $it){
return 1;
}
}
}
return 0;
}
sub get_parameter_str()
{
my($parameters, $tag) = @_;
my $where;
my $ret;
$where=index($parameters,$tag);
if($where >= 0)
{
#bypass "-s ","-h ",and etc
$ret=substr($parameters,$where+3);
$where=index($ret," ");
if($where >= 0)
{
$ret=substr($ret,0,$where);
}
return $ret;
}
return "";
}
#****************************************************************************
# subroutine: error_handler
# input: $error_msg: error message
#****************************************************************************
sub error_handler()
{
my($error_msg, $file, $line_no) = @_;
my $final_error_msg = "NandGen ERROR: $error_msg at $file line $line_no\n";
print $final_error_msg;
die $final_error_msg;
}
sub by_index
{$a<=>$b}
sub sprd_nand_param_h_head()
{
my $template = <<"__TEMPLATE";
#define yes 1
#define no 0
#define NAND_MAX_ID_LEN 5
#define BW_08 0x00
#define BW_16 0x01
#define CYCLES_3 0x03
#define CYCLES_4 0x04
#define CYCLES_5 0x05
#define NUM_BLOCK(n) (n)
#define SZ_K_BLOCK(n) (n * 1024)
#define SZ_K_PAGE(n) (n * 1024)
#define SZ_B_BLOCK(n) (n)
#define SZ_B_PAGE(n) (n)
#define SZ_B_SPARE(n) (n)
#define SZ_B_OOB(n) (n)
#define SZ_B_SECTOR(n) (n)
#define BAD_LEN(n) (n)
#define BAD_POS(n) (n)
#define ECC_BITS(n) (n)
#define SZ_ECC(n) (n)
#define POS_ECC(n) (n)
#define SZ_INFO(n) (n)
#define POS_INFO(n) (n)
#define PLANE_SEL_BIT(n) (n) /* bit for plane select */
#define IS_SUPT_CACHE_FUNC(n) (n) /* 0:not support cache function 1: support cache function */
#define INTF_TYPE(n) (n)
#define CELL_TYPE(n) (n)
#define CALC_ECC_SIZE(n) ((14 * (n) + 7) / 8)
#define MAX_IO_FREQ(n) (n)
struct sprd_nand_device {
uint8_t id_device;
char* p_name;
char* p_type;
};
struct sprd_nand_maker {
uint8_t idmaker;
char* p_name;
struct sprd_nand_device* p_devtab;
};
struct sprd_nand_oob {
uint16_t oob_size; /* 16 */
uint8_t ecc_bits;
uint16_t ecc_pos;
uint16_t ecc_size; /* 4 */
uint16_t info_pos;
uint16_t info_size;
};
struct sprd_nand_timing {
uint8_t ace_ns; /* ALE, CLE end of delay timing, unit: ns */
uint8_t rwl_ns; /* WE, RE, IO, pulse timing, unit: ns */
uint8_t rwh_ns; /* WE, RE, IO, high hold timing, unit: ns */
};
struct sprd_nand_param {
uint8_t id[NAND_MAX_ID_LEN];
uint8_t idmaker;
uint8_t id_device;
uint32_t blk_size; /* 256K */
uint32_t blk_num;
uint32_t page_size; /* 4K */
uint16_t nsect_size; /* 512 */
uint16_t nspare_size;
uint8_t nbus_width;
uint8_t ncycles;
struct sprd_nand_timing s_timing;
struct sprd_nand_oob s_oob;
uint8_t oob_bad_pos;
uint8_t oob_bad_len;
uint8_t cell_type;
uint8_t intf_type;
uint8_t supt_cache_func;
int plane_sel_bit;
uint32_t max_io_freq;
};
__TEMPLATE
return $template;
}
sub sprd_nand_param_h_fuction()
{
my $template_fuction = <<"__TEMPLATE";
print FD "#ifdef SPRD_NAND_DEVICE_TBL\n";
STATIC_FUNC struct sprd_nand_maker* __FindMaker(uint8_t idmaker) {
struct sprd_nand_maker* pmaker = maker_table;
while (pmaker->idmaker != 0) {
if(pmaker->idmaker == idmaker) {
return pmaker;
}
pmaker++;
}
return NULL;
}
STATIC_FUNC struct sprd_nand_device* __FindDevice(struct sprd_nand_maker* pmaker, uint8_t id_device) {
struct sprd_nand_device* pdevice = pmaker->p_devtab;
while (pdevice->id_device != 0) {
if(pdevice->id_device == id_device) {
return pdevice;
}
pdevice++;
}
return NULL;
}
STATIC_FUNC void __PrintNandInfo(struct sprd_nand_param* p) {
struct sprd_nand_device* pdevice;
struct sprd_nand_maker* pmaker;
DPRINT("%s\\n", __func__);
pmaker = __FindMaker(p->idmaker);
pdevice = __FindDevice(pmaker, p->id_device);
DPRINT("device is %s:%s\\n", pmaker->p_name, pdevice->p_name);
DPRINT("block size is %d\\n", p->blk_size);
DPRINT("page size is %d\\n", p->page_size);
DPRINT("spare size is %d\\n", p->nspare_size);
DPRINT("eccbits is %d\\n", p->s_oob.ecc_bits);
}
STATIC_FUNC void __ParseNandParam(uint8_t* id) {
struct sprd_nand_param* param = sprd_nand_param_table;
while(param->idmaker != 0) {
if ((param->id[0] == id[0]) &&
(param->id[4] == id[1])) {
__PrintNandInfo(param);
return param;
}
param++;
}
return;
}
STATIC_FUNC int __SprdCheckNancParam(struct sprd_nand_param* param) {
struct sprd_nand_device* pdevice;
struct sprd_nand_maker* pmaker;
struct sprd_nand_oob* poob = &param->s_oob;
uint8_t sector_num = param->page_size / param->nsect_size;
DPRINT("%s\\n", __func__);
if (param->idmaker != param->id[0]) {
DPRINT("%s: id is not match!!!!!!!!!!!!!!!\\n", __func__);
SPRD_ASSERT(0);
}
if (param->id_device != param->id[1]) {
DPRINT("%s: id is not match!!!!!!!!!!!!!!!\\n", __func__);
SPRD_ASSERT(0);
}
if (poob->oob_size * sector_num > param->nspare_size) {
DPRINT("%s: OOB size is not match!!!!!!!!!!!!!!!\\n", __func__);
SPRD_ASSERT(0);
}
if (poob->ecc_pos + poob->ecc_size > poob->oob_size) {
DPRINT("%s: ECC size exceeds the oob!!!!!!!!!!!!!!!\\n", __func__);
SPRD_ASSERT(0);
}
if (CALC_ECC_SIZE(poob->ecc_bits) != poob->ecc_size) {
DPRINT("%s: ECC size is wrong!!!!!!!!!!!!!!!\\n", __func__);
SPRD_ASSERT(0);
}
if (poob->info_pos + poob->info_size != poob->ecc_pos) {
DPRINT("%s: Info position is wrong!!!!!!!!!!!!!!!\\n", __func__);
SPRD_ASSERT(0);
}
return 0;
}
STATIC_FUNC struct sprd_nand_param* SprdGetNandParam(uint8_t* id) {
struct sprd_nand_param* param = sprd_nand_param_table;
int i;
DPRINT("%s\\n", __func__);
for (i = 0; i < 5; i++) {
DPRINT("id[%d] is %x\\n", i, id[i]);
}
//__ParseNandParam(id);
while(param->idmaker != 0) {
if ((param->id[0] == id[0]) &&
(param->id[1] == id[1]) &&
(param->id[2] == id[2]) &&
(param->id[3] == id[3]) &&
(param->id[4] == id[4])) {
__PrintNandInfo(param);
__SprdCheckNancParam(param);
return param;
}
param++;
}
DPRINT("Nand params unconfigured, please check it. Halt on booting!!!\\n");
for(;;) /*relax*/;
return NULL;
}
print FD "#endif /*ifdef SPRD_NAND_DEVICE_TBL*/\n";
__TEMPLATE
return $template_fuction;
}