Files
2026-09-22 09:38:26 +08:00

630 lines
20 KiB
Perl
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/local/bin/perl -w
# SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0
# Copyright (C) 2023 Unisoc, Inc.
# Author: Liangji.chen <[email protected]>
# 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;
}