Exemplo n.º 1
0
__s32 _UpdateExtMultiPlanePara(void)
{
	__u32 id_number_ctl;
	__u32 script_twoplane, para;

	id_number_ctl = NAND_GetNandIDNumCtrl();
	if (0x0 != id_number_ctl)
	{
		if (id_number_ctl & (1U<<1))//bit 1, set twoplane para
		{
			para = NAND_GetNandExtPara(1);
			if(0xffffffff != para) //get script success
			{
				if(((para & 0xffffff) == NandIDNumber) || ((para & 0xffffff) == 0xeeeeee))
				{
					script_twoplane = (para >> 24) & 0xff;
					PHY_DBG("_UpdateExtMultiPlanePara: get twoplane para from script success: ", script_twoplane);
					if (script_twoplane == 1) {
						PHY_DBG("%d\n", script_twoplane);
						if (NandSupportTwoPlaneOp) {
							//PHY_DBG("NAND_UpdatePhyArch: current nand support two plane op!\n");
							NandStorageInfo.PlaneCntPerDie = 2;
							NandStorageInfo.OperationOpt |= NAND_MULTI_READ;
				       	 	NandStorageInfo.OperationOpt |= NAND_MULTI_PROGRAM;
						} else {
							PHY_DBG("_UpdateExtMultiPlanePara: current nand do not support two plane op, set to 0!\n");
							NandStorageInfo.PlaneCntPerDie = 1;
							NandStorageInfo.OperationOpt &= ~NAND_MULTI_READ;
				       	 	NandStorageInfo.OperationOpt &= ~NAND_MULTI_PROGRAM;
						}
					} else if (script_twoplane == 0){
						PHY_DBG("%d\n", script_twoplane);
						NandStorageInfo.PlaneCntPerDie = 1;
						NandStorageInfo.OperationOpt &= ~NAND_MULTI_READ;
			       	 	NandStorageInfo.OperationOpt &= ~NAND_MULTI_PROGRAM;
					} else {
						PHY_DBG("%d, wrong parameter(0,1)\n", script_twoplane);
						return -1;
					}
				}
				else
				{
					PHY_ERR("_UpdateExtMultiPlanePara: wrong id number, 0x%x/0x%x\n", (para & 0xffffff), NandIDNumber);
					return -1;
				}
			}
Exemplo n.º 2
0
/*
	0: no physic arch info;
	1: ok;
	-1: fail;
*/
__s32 _GetOldPhysicArch(void *phy_arch, __u32 *good_blk_no)
{
	__s32 ret, ret2 = 0;
	__u32 b, chip = 0;
	__u32 start_blk=12, blk_cnt=100;
	__u8 oob[128];
	struct __NandStorageInfo_t *parch;
	struct boot_physical_param nand_op;

	//parch = (struct __NandStorageInfo_t *)PHY_TMP_PAGE_CACHE;
	parch = (struct __NandStorageInfo_t *)MALLOC(64*1024);
	if(!parch)
	{
		PRINT("%s,malloc fail\n",__func__);
		ret2 = -1;
		goto EXIT;
	}

	for (b=start_blk; b<start_blk+blk_cnt; b++)
	{
		nand_op.chip = chip;
		nand_op.block = b;
		nand_op.page = 0;
		nand_op.mainbuf = (void *)parch;
		nand_op.oobbuf = oob;

		ret = PHY_SimpleRead(&nand_op); //PHY_SimpleRead_CurCH(&nand_op);
		PHY_DBG("_GetOldPhysicArch: ch: %d, chip %d, block %d, page 0, "
				"oob: 0x%x, 0x%x, 0x%x, 0x%x\n",NandIndex,nand_op.chip, nand_op.block,
				oob[0], oob[1], oob[2], oob[3]);
		if (ret>=0)
		{
			if (oob[0]==0x00)
			{
				if ((oob[1]==0x50) && (oob[2]==0x48) && (oob[3]==0x59) && (oob[4]==0x41) && (oob[5]==0x52) && (oob[6]==0x43) && (oob[7]==0x48))
				{
					//*((struct __NandStorageInfo_t *)phy_arch) = *parch;
					if((parch->PlaneCntPerDie !=1) && (parch->PlaneCntPerDie !=2))
					{
						PHY_DBG("_GetOldPhysicArch: get old physic arch ok,but para error: 0x%x 0x%x!\n", parch->OperationOpt, parch->PlaneCntPerDie);
					}
					else
					{
						MEMCPY(phy_arch, parch, sizeof(struct __NandStorageInfo_t));
						PHY_DBG("_GetOldPhysicArch: get old physic arch ok, 0x%x 0x%x!\n", parch->OperationOpt, parch->PlaneCntPerDie);
						ret2 = 1;
						break;
					}
				}
				else
				{
					PHY_DBG("_GetOldPhysicArch: mark bad block!\n");
				}
			}
			else if(oob[0]==0xff)
			{
				PHY_DBG("_GetOldPhysicArch: find a good block, but no physic arch info.\n");
				ret2 = 2;//blank page
				break;
			}
			else
			{
				PHY_DBG("_GetOldPhysicArch: unkonwn1!\n");
			}
		}
		else
		{
			if (oob[0]==0xff)
			{
				PHY_DBG("_GetOldPhysicArch: blank block!\n");
				ret2 = 2;
				break;
			}
			else if (oob[0]==0)
			{
				PHY_DBG("_GetOldPhysicArch: bad block!\n");
			}
			else
			{
				PHY_DBG("_GetOldPhysicArch: unkonwn2!\n");
			}
		}
	}

	if (b == (start_blk+blk_cnt)) {
		ret2 = -1;
		*good_blk_no = 0;
	} else
		*good_blk_no = b;

EXIT:
    FREE(parch, 64*1024);

	return ret2;
}
Exemplo n.º 3
0
__s32 _SetNewPhysicArch(void *phy_arch)
{
	__s32 ret;
	__u32 i, b, p, chip = 0;
	__u32 start_blk=12, blk_cnt=100;
	__u8 oob[128];
	__u32 good_blk_no;
	struct __NandStorageInfo_t *parch;
	struct __NandStorageInfo_t arch_tmp = {0};
	struct boot_physical_param nand_op;

    //parch = (struct __NandStorageInfo_t *)PHY_TMP_PAGE_CACHE;
	parch = (struct __NandStorageInfo_t *)MALLOC(64*1024);

	/* in order to get good block, get old physic arch info */
	ret = _GetOldPhysicArch(&arch_tmp, &good_blk_no);
	if (ret == -1) {
		/* can not find good block */
		PHY_ERR("_SetNewPhysicArch: can not find good block: 12~112\n");
		FREE(parch, 64*1024);
		return ret;
	}

	PHY_DBG("_SetNewPhysicArch: write physic arch to blk %d...\n", good_blk_no);

	for (b=good_blk_no; b<start_blk+blk_cnt; b++)
	{
		nand_op.chip = chip;
		nand_op.block = b;
		nand_op.page = 0;
		nand_op.mainbuf = (void *)parch; //PHY_TMP_PAGE_CACHE;
		nand_op.oobbuf = oob;

		ret = PHY_SimpleErase(&nand_op); //PHY_SimpleErase_CurCH(&nand_op);
		if (ret<0)
		{
			PHY_ERR("_SetNewPhysicArch: erase chip %d, block %d error\n", nand_op.chip, nand_op.block);

			for (i=0; i<128; i++)
		    	oob[i] = 0x0;

			for (p=0; p<NandStorageInfo.PageCntPerPhyBlk; p++)
			{
				nand_op.page = p;
				ret = PHY_SimpleWrite(&nand_op); //PHY_SimpleWrite_CurCH(&nand_op);
				if (ret<0) {
					PHY_ERR("_SetNewPhysicArch: mark bad block, write chip %d, block %d, page %d error\n", nand_op.chip, nand_op.block, nand_op.page);
				}
			}
		}
		else
		{
			PHY_DBG("_SetNewPhysicArch: erase block %d ok.\n", b);

			for (i=0; i<128; i++)
		    	oob[i] = 0x88;
		    oob[0] = 0x00; //bad block flag
			oob[1] = 0x50; //80; //'P'
			oob[2] = 0x48; //72; //'H'
			oob[3] = 0x59; //89; //'Y'
			oob[4] = 0x41; //65; //'A'
			oob[5] = 0x52; //82; //'R'
			oob[6] = 0x43; //67; //'C'
			oob[7] = 0x48; //72; //'H'

			//MEMSET(parch, 0x0, 1024);
			MEMCPY(parch, phy_arch, sizeof(struct __NandStorageInfo_t));
			//*parch = *((struct __NandStorageInfo_t *)phy_arch);
			for (p=0; p<NandStorageInfo.PageCntPerPhyBlk; p++)
			{
				nand_op.page = p;
				ret = PHY_SimpleWrite(&nand_op); //PHY_SimpleWrite_CurCH(&nand_op);
				if(ret<0)
				{
					PHY_ERR("_SetNewPhysicArch: write chip %d, block %d, page %d error\n", nand_op.chip, nand_op.block, nand_op.page);
					FREE(parch, 64*1024);
					return -1;
				}
			}
			break;
		}
	}

	PHY_DBG("_SetNewPhysicArch: ============\n");
    ret = _GetOldPhysicArch(&arch_tmp, &good_blk_no);
	if (ret == -1) {
		/* can not find good block */
		PHY_ERR("_SetNewPhysicArch: can not find good block: 12~112\n");
		FREE(parch, 64*1024);
		return ret;
	}

	FREE(parch, 64*1024);

	return 0;
}
Exemplo n.º 4
0
/*
************************************************************************************************************************
*                           ANALYZE NAND FLASH STORAGE SYSTEM
*
*Description: Analyze nand flash storage system, generate the nand flash physical
*             architecture parameter and connect information.
*
*Arguments  : none
*
*Return     : analyze result;
*               = 0     analyze successful;
*               < 0     analyze failed, can't recognize or some other error.
************************************************************************************************************************
*/
__s32  SCN_AnalyzeNandSystem(void)
{
    __s32 i,result;
    __u8  tmpChipID[8];
	__u8  uniqueID[32];
    struct __NandPhyInfoPar_t tmpNandPhyInfo;

    //init nand flash storage information to default value
    NandStorageInfo.ChipCnt = 1;
    NandStorageInfo.ChipConnectInfo = 1;
    NandStorageInfo.RbConnectMode= 1;
    NandStorageInfo.RbCnt= 1;
    NandStorageInfo.RbConnectInfo= 1;
    NandStorageInfo.BankCntPerChip = 1;
    NandStorageInfo.DieCntPerChip = 1;
    NandStorageInfo.PlaneCntPerDie = 1;
    NandStorageInfo.SectorCntPerPage = 4;
    NandStorageInfo.PageCntPerPhyBlk = 64;
    NandStorageInfo.BlkCntPerDie = 1024;
    NandStorageInfo.OperationOpt = 0;
    NandStorageInfo.FrequencePar = 10;
    NandStorageInfo.EccMode = 0;
	NandStorageInfo.ReadRetryType= 0;

    //reset the nand flash chip on boot chip select
    result = PHY_ResetChip(BOOT_CHIP_SELECT_NUM);
    result |= PHY_SynchBank(BOOT_CHIP_SELECT_NUM, SYNC_CHIP_MODE);
    if(result)
    {
        SCAN_ERR("[SCAN_ERR] Reset boot nand flash chip failed!\n");
        return -1;
    }

    //read nand flash chip ID from boot chip
    result = PHY_ReadNandId(BOOT_CHIP_SELECT_NUM, tmpChipID);
    if(result)
    {
        SCAN_ERR("[SCAN_ERR] Read chip ID from boot chip failed!\n");
        return -1;
    }
    SCAN_DBG("[SCAN_DBG] Nand flash chip id is:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
            tmpChipID[0],tmpChipID[1],tmpChipID[2],tmpChipID[3], tmpChipID[4],tmpChipID[5]);

    //search the nand flash physical architecture parameter by nand ID
    result = _SearchNandArchi(tmpChipID, &tmpNandPhyInfo);
    if(result)
    {
        SCAN_ERR("[SCAN_ERR] search nand physical architecture parameter failed!\n");
        return -1;
    }

    //set the nand flash physical architecture parameter
    NandStorageInfo.BankCntPerChip = tmpNandPhyInfo.DieCntPerChip;
    NandStorageInfo.DieCntPerChip = tmpNandPhyInfo.DieCntPerChip;
    NandStorageInfo.PlaneCntPerDie = 2;
    NandStorageInfo.SectorCntPerPage = tmpNandPhyInfo.SectCntPerPage;
    NandStorageInfo.PageCntPerPhyBlk = tmpNandPhyInfo.PageCntPerBlk;
    NandStorageInfo.BlkCntPerDie = tmpNandPhyInfo.BlkCntPerDie;
    NandStorageInfo.OperationOpt = tmpNandPhyInfo.OperationOpt;
    NandStorageInfo.FrequencePar = tmpNandPhyInfo.AccessFreq;
    NandStorageInfo.EccMode = tmpNandPhyInfo.EccMode;
    NandStorageInfo.NandChipId[0] = tmpNandPhyInfo.NandID[0];
    NandStorageInfo.NandChipId[1] = tmpNandPhyInfo.NandID[1];
    NandStorageInfo.NandChipId[2] = tmpNandPhyInfo.NandID[2];
    NandStorageInfo.NandChipId[3] = tmpNandPhyInfo.NandID[3];
    NandStorageInfo.NandChipId[4] = tmpNandPhyInfo.NandID[4];
    NandStorageInfo.NandChipId[5] = tmpNandPhyInfo.NandID[5];
    NandStorageInfo.NandChipId[6] = tmpNandPhyInfo.NandID[6];
    NandStorageInfo.NandChipId[7] = tmpNandPhyInfo.NandID[7];
    NandStorageInfo.ValidBlkRatio = tmpNandPhyInfo.ValidBlkRatio;
	NandStorageInfo.ReadRetryType = tmpNandPhyInfo.ReadRetryType;
	NandStorageInfo.DDRType       = tmpNandPhyInfo.DDRType;
    //set the optional operation parameter
    NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneReadCmd[0];
    NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneReadCmd[1];
    NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneWriteCmd[0];
    NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneWriteCmd[1];
    NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyReadCmd[0];
    NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyReadCmd[1];
    NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[2] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyReadCmd[2];
    NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[0] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyWriteCmd[0];
    NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[1] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyWriteCmd[1];
    NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[2] = tmpNandPhyInfo.OptionOp->MultiPlaneCopyWriteCmd[2];
    NandStorageInfo.OptPhyOpPar.MultiPlaneStatusCmd = tmpNandPhyInfo.OptionOp->MultiPlaneStatusCmd;
    NandStorageInfo.OptPhyOpPar.InterBnk0StatusCmd = tmpNandPhyInfo.OptionOp->InterBnk0StatusCmd;
    NandStorageInfo.OptPhyOpPar.InterBnk1StatusCmd = tmpNandPhyInfo.OptionOp->InterBnk1StatusCmd;
    NandStorageInfo.OptPhyOpPar.BadBlockFlagPosition = tmpNandPhyInfo.OptionOp->BadBlockFlagPosition;
    NandStorageInfo.OptPhyOpPar.MultiPlaneBlockOffset = tmpNandPhyInfo.OptionOp->MultiPlaneBlockOffset;

    //set some configurable  optional operation parameter
    if(!CFG_SUPPORT_MULTI_PLANE_PROGRAM)
    {
        NandStorageInfo.OperationOpt &= ~NAND_MULTI_READ;
        NandStorageInfo.OperationOpt &= ~NAND_MULTI_PROGRAM;
    }

    if(!CFG_SUPPORT_INT_INTERLEAVE)
    {
        NandStorageInfo.OperationOpt &= ~NAND_INT_INTERLEAVE;
    }

    if(!CFG_SUPPORT_RANDOM)
    {
        NandStorageInfo.OperationOpt &= ~NAND_RANDOM;
    }

    if(!CFG_SUPPORT_READ_RETRY)
    {
        NandStorageInfo.OperationOpt &= ~NAND_READ_RETRY;
    }

    if(!CFG_SUPPORT_ALIGN_NAND_BNK)
    {
        NandStorageInfo.OperationOpt |= NAND_PAGE_ADR_NO_SKIP;
    }


    //process the plane count of a die and the bank count of a chip
    if(!SUPPORT_MULTI_PROGRAM)
    {
        NandStorageInfo.PlaneCntPerDie = 1;
    }

    if(!SUPPORT_INT_INTERLEAVE)
    {
        NandStorageInfo.BankCntPerChip = 1;
    }

     //process the rb connect infomation
    for(i=1; i<MAX_CHIP_SELECT_CNT; i++)
    {
        //reset current nand flash chip
        PHY_ResetChip((__u32)i);

        //read the nand chip ID from current nand flash chip
        PHY_ReadNandId((__u32)i, tmpChipID);
        //check if the nand flash id same as the boot chip
        if((tmpChipID[0] == NandStorageInfo.NandChipId[0]) && (tmpChipID[1] == NandStorageInfo.NandChipId[1])
            && (tmpChipID[2] == NandStorageInfo.NandChipId[2]) && (tmpChipID[3] == NandStorageInfo.NandChipId[3])
            && ((tmpChipID[4] == NandStorageInfo.NandChipId[4])||(NandStorageInfo.NandChipId[4]==0xff))
            && ((tmpChipID[5] == NandStorageInfo.NandChipId[5])||(NandStorageInfo.NandChipId[5]==0xff)))
        {
            NandStorageInfo.ChipCnt++;
            NandStorageInfo.ChipConnectInfo |= (1<<i);
        }
    }

    //process the rb connect infomation
    {
        NandStorageInfo.RbConnectMode = 0xff;

        if((NandStorageInfo.ChipCnt == 1) && (NandStorageInfo.ChipConnectInfo & (1<<0)))
        {
             NandStorageInfo.RbConnectMode =1;
        }
        else if(NandStorageInfo.ChipCnt == 2)
        {
    	      if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<1)))
		    NandStorageInfo.RbConnectMode =2;
	      else if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<2)))
		    NandStorageInfo.RbConnectMode =3;
		else if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<7)))
		    NandStorageInfo.RbConnectMode =0; 	//special use, only one rb

        }

        else if(NandStorageInfo.ChipCnt == 4)
        {
    	      if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<1))
			  	&&  (NandStorageInfo.ChipConnectInfo & (1<<2)) &&  (NandStorageInfo.ChipConnectInfo & (1<<3)) )
		    NandStorageInfo.RbConnectMode =4;
	      else if((NandStorageInfo.ChipConnectInfo & (1<<0)) && (NandStorageInfo.ChipConnectInfo & (1<<2))
			  	&&  (NandStorageInfo.ChipConnectInfo & (1<<4)) &&  (NandStorageInfo.ChipConnectInfo & (1<<6)) )
		    NandStorageInfo.RbConnectMode =5;
        }
        else if(NandStorageInfo.ChipCnt == 8)
        {
	      NandStorageInfo.RbConnectMode =8;
        }

		if( NandStorageInfo.RbConnectMode == 0xff)
            {
        	    SCAN_ERR("%s : check nand rb connect fail, ChipCnt =  %x, ChipConnectInfo = %x \n",__FUNCTION__, NandStorageInfo.ChipCnt, NandStorageInfo.ChipConnectInfo);
        	    return -1;
		}


    }


    //process the external inter-leave operation
    if(CFG_SUPPORT_EXT_INTERLEAVE)
    {
        if(NandStorageInfo.ChipCnt > 1)
        {
            NandStorageInfo.OperationOpt |= NAND_EXT_INTERLEAVE;
        }
    }
    else
    {
        NandStorageInfo.OperationOpt &= ~NAND_EXT_INTERLEAVE;
    }

	if(SUPPORT_READ_UNIQUE_ID)
	{
		for(i=0; i<NandStorageInfo.ChipCnt; i++)
		{
			PHY_ReadNandUniqueId(i, uniqueID);
		}

	}

	/*configure page size*/
	{
		NFC_INIT_INFO nand_info;
		nand_info.bus_width = 0x0;
		nand_info.ce_ctl = 0x0;
		nand_info.ce_ctl1 = 0x0;
		nand_info.debug = 0x0;
		nand_info.pagesize = SECTOR_CNT_OF_SINGLE_PAGE;
		nand_info.rb_sel = 1;
		nand_info.serial_access_mode = 1;
		nand_info.ddr_type = DDR_TYPE;
		NFC_ChangMode(&nand_info);
	}

	PHY_ChangeMode(1);

	if(SUPPORT_READ_RETRY)
	{
	    PHY_DBG("NFC Read Retry Init. \n");
		NFC_ReadRetryInit(READ_RETRY_TYPE);

		for(i=0; i<NandStorageInfo.ChipCnt;i++)
	    {
	        PHY_GetDefaultParam(i);
	    }

	}
    //print nand flash physical architecture parameter
    SCAN_DBG("\n\n");
    SCAN_DBG("[SCAN_DBG] ==============Nand Architecture Parameter==============\n");
    SCAN_DBG("[SCAN_DBG]    Nand Chip ID:         0x%x 0x%x\n",
        (NandStorageInfo.NandChipId[0] << 0) | (NandStorageInfo.NandChipId[1] << 8)
        | (NandStorageInfo.NandChipId[2] << 16) | (NandStorageInfo.NandChipId[3] << 24),
        (NandStorageInfo.NandChipId[4] << 0) | (NandStorageInfo.NandChipId[5] << 8)
        | (NandStorageInfo.NandChipId[6] << 16) | (NandStorageInfo.NandChipId[7] << 24));
    SCAN_DBG("[SCAN_DBG]    Nand Chip Count:      0x%x\n", NandStorageInfo.ChipCnt);
    SCAN_DBG("[SCAN_DBG]    Nand Chip Connect:    0x%x\n", NandStorageInfo.ChipConnectInfo);
	SCAN_DBG("[SCAN_DBG]    Nand Rb Connect Mode:      0x%x\n", NandStorageInfo.RbConnectMode);
    SCAN_DBG("[SCAN_DBG]    Sector Count Of Page: 0x%x\n", NandStorageInfo.SectorCntPerPage);
    SCAN_DBG("[SCAN_DBG]    Page Count Of Block:  0x%x\n", NandStorageInfo.PageCntPerPhyBlk);
    SCAN_DBG("[SCAN_DBG]    Block Count Of Die:   0x%x\n", NandStorageInfo.BlkCntPerDie);
    SCAN_DBG("[SCAN_DBG]    Plane Count Of Die:   0x%x\n", NandStorageInfo.PlaneCntPerDie);
    SCAN_DBG("[SCAN_DBG]    Die Count Of Chip:    0x%x\n", NandStorageInfo.DieCntPerChip);
    SCAN_DBG("[SCAN_DBG]    Bank Count Of Chip:   0x%x\n", NandStorageInfo.BankCntPerChip);
    SCAN_DBG("[SCAN_DBG]    Optional Operation:   0x%x\n", NandStorageInfo.OperationOpt);
    SCAN_DBG("[SCAN_DBG]    Access Frequence:     0x%x\n", NandStorageInfo.FrequencePar);
    SCAN_DBG("[SCAN_DBG]    ECC Mode:             0x%x\n", NandStorageInfo.EccMode);
	SCAN_DBG("[SCAN_DBG]    Read Retry Type:      0x%x\n", NandStorageInfo.ReadRetryType);
	SCAN_DBG("[SCAN_DBG]    DDR Type:             0x%x\n", NandStorageInfo.DDRType);
    SCAN_DBG("[SCAN_DBG] =======================================================\n\n");

    //print nand flash optional operation parameter
    SCAN_DBG("[SCAN_DBG] ==============Optional Operaion Parameter==============\n");
    SCAN_DBG("[SCAN_DBG]    MultiPlaneReadCmd:      0x%x, 0x%x\n",
        NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[0],NandStorageInfo.OptPhyOpPar.MultiPlaneReadCmd[1]);
    SCAN_DBG("[SCAN_DBG]    MultiPlaneWriteCmd:     0x%x, 0x%x\n",
        NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[0],NandStorageInfo.OptPhyOpPar.MultiPlaneWriteCmd[1]);
    SCAN_DBG("[SCAN_DBG]    MultiPlaneCopyReadCmd:  0x%x, 0x%x, 0x%x\n",
        NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[0],NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[1],
        NandStorageInfo.OptPhyOpPar.MultiPlaneCopyReadCmd[2]);
    SCAN_DBG("[SCAN_DBG]    MultiPlaneCopyWriteCmd: 0x%x, 0x%x, 0x%x\n",
        NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[0], NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[1],
        NandStorageInfo.OptPhyOpPar.MultiPlaneCopyWriteCmd[2]);
    SCAN_DBG("[SCAN_DBG]    MultiPlaneStatusCmd:    0x%x\n", NandStorageInfo.OptPhyOpPar.MultiPlaneStatusCmd);
    SCAN_DBG("[SCAN_DBG]    InterBnk0StatusCmd:     0x%x\n", NandStorageInfo.OptPhyOpPar.InterBnk0StatusCmd);
    SCAN_DBG("[SCAN_DBG]    InterBnk1StatusCmd:     0x%x\n", NandStorageInfo.OptPhyOpPar.InterBnk1StatusCmd);
    SCAN_DBG("[SCAN_DBG]    BadBlockFlagPosition:   0x%x\n", NandStorageInfo.OptPhyOpPar.BadBlockFlagPosition);
    SCAN_DBG("[SCAN_DBG]    MultiPlaneBlockOffset:  0x%x\n", NandStorageInfo.OptPhyOpPar.MultiPlaneBlockOffset);
    SCAN_DBG("[SCAN_DBG] =======================================================\n");

    return 0;
}