467 lines
17 KiB
C
Executable File
467 lines
17 KiB
C
Executable File
/*
|
|
* drvSPINAND.c- Sigmastar
|
|
*
|
|
* Copyright (C) 2018 Sigmastar Technology Corp.
|
|
*
|
|
* Author: edie.chen <edie.chen@sigmastar.com.tw>
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <malloc.h>
|
|
#include <linux/err.h>
|
|
//#include <linux/compat.h>
|
|
#include <asm/io.h>
|
|
#include <asm/errno.h>
|
|
|
|
|
|
#include <linux/string.h>
|
|
// Common Definition
|
|
#include "MsCommon.h"
|
|
#include "MsVersion.h"
|
|
#include "MsTypes.h"
|
|
//#include "MsOS.h"
|
|
#include "spinand.h"
|
|
// Internal Definition
|
|
#include "../../inc/common/drvSPINAND.h"
|
|
|
|
// #ifndef _DRV_SPICMD_H_
|
|
// #include "../../inc/common/drvSPICMD.h"
|
|
// #endif
|
|
|
|
|
|
//extern SPINAND_FLASH_INFO_t _gtSpinandInfo;
|
|
|
|
|
|
#if defined(MSOS_TYPE_LINUX)
|
|
#include <sys/ioctl.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#endif
|
|
|
|
//==========================================================================
|
|
// Define
|
|
//==========================================================================
|
|
|
|
//==========================================================================
|
|
// Global Variable
|
|
//==========================================================================
|
|
U8 u8MagicData[] = {0x4D, 0x53, 0x54, 0x41, 0x52, 0x53, 0x45, 0x4D, 0x49, 0x55, 0x53, 0x46, 0x44, 0x43, 0x49, 0x53};
|
|
#define HW_TIMER_DELAY_1us 1
|
|
#define HW_TIMER_DELAY_10us 10
|
|
#define HW_TIMER_DELAY_100us 100
|
|
#define HW_TIMER_DELAY_1ms (1000 * HW_TIMER_DELAY_1us)
|
|
#define HW_TIMER_DELAY_5ms (5 * HW_TIMER_DELAY_1ms)
|
|
#if 0
|
|
SPINAND_FLASH_INFO_t gtSpiNandInfoTable[]=
|
|
{ //u8_IDByteCnt au8_ID u16_SpareByteCnt u16_PageByteCnt u16_BlkPageCnt u16_BlkCnt u16_SectorByteCnt
|
|
{2, {MID_GD , 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 4096, 512, 0},
|
|
{2, {MID_GD , 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 0},
|
|
{2, {MID_GD , 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 0},
|
|
{2, {MID_GD , 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 0},
|
|
{2, {MID_GD , 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 0},
|
|
{2, {MID_GD , 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 2048, 512, 0},
|
|
{2, {MID_MICRON , 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 2},
|
|
{2, {MID_MICRON , 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 2048, 512, 2},
|
|
{2, {MID_MICRON , 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 4096, 512, 2},
|
|
{2, {MID_ATO , 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 0},
|
|
{2, {MID_WINBOND, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 0},
|
|
{2, {MID_MXIC , 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 1024, 512, 0},
|
|
{2, {MID_MXIC , 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 2048, 512, 2},
|
|
{2, {MID_TOSHIBA, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 64, 2048, 64, 2048, 512, 2},
|
|
{2, {0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0, 0, 0, 0, 0, 0},
|
|
};
|
|
|
|
#endif
|
|
#if defined(SUPPORT_SPINAND_QUAD) && SUPPORT_SPINAND_QUAD
|
|
SPINAND_MODE gSpiMode = E_SPINAND_QUAD_MODE;
|
|
#else
|
|
SPINAND_MODE gSpiMode = E_SPINAND_SINGLE_MODE;
|
|
#endif
|
|
Mdev_SPINAND_SetDriving SetDriving = NULL;
|
|
//==========================================================================
|
|
// Global Function
|
|
//==========================================================================
|
|
static BOOL _MDrv_SPINAND_GET_INFO(void)
|
|
{
|
|
U32 u32Ret;
|
|
U8 u8_IDByteCnt;
|
|
U8 u8Spare[16];
|
|
U8 u8Data[512];
|
|
U8 u8Idx, u8Status;
|
|
U8 *u8SrcAddr, *u8DstAddr;
|
|
U16 u16PageIndex;
|
|
SPI_NAND_DRIVER_t *pSpiNandDrv = (SPI_NAND_DRIVER_t*)drvSPINAND_get_DrvContext_address();
|
|
u8SrcAddr = u8Data;
|
|
u8DstAddr = (U8*)(&pSpiNandDrv->tSpinandInfo);
|
|
|
|
// if ecc error read back up block(block2 ,4, 6, 8)
|
|
for(u8Idx = 0; u8Idx < CIS_MAX_BACKUP * 2; u8Idx+=2)
|
|
{
|
|
u16PageIndex = (pSpiNandDrv->tSpinandInfo.u16_BlkPageCnt ? pSpiNandDrv->tSpinandInfo.u16_BlkPageCnt : 64) * u8Idx;
|
|
//read data to cache first
|
|
u32Ret = HAL_SPINAND_RFC(u16PageIndex, &u8Status);
|
|
|
|
if(u32Ret != ERR_SPINAND_SUCCESS)//|| u8Status & ECC_STATUS_ERR
|
|
{
|
|
spi_nand_debug("read data to cache first != ERR_SPINAND_SUCCESS\n");
|
|
continue;
|
|
}
|
|
|
|
// Read SPINand Data
|
|
// printf("source %p", u8SrcAddr);
|
|
u32Ret = HAL_SPINAND_Read (0, 512, u8SrcAddr);
|
|
if(u32Ret != ERR_SPINAND_SUCCESS)
|
|
{
|
|
spi_nand_debug("Read SPINand Data != ERR_SPINAND_SUCCESS\n");
|
|
continue;
|
|
}
|
|
|
|
// Read SPINand Spare Data
|
|
u32Ret = HAL_SPINAND_Read(2048, 16, u8Spare);
|
|
if(u32Ret != ERR_SPINAND_SUCCESS)
|
|
{
|
|
spi_nand_debug("Read SPINand Spare Data != ERR_SPINAND_SUCCESS\n");
|
|
continue;
|
|
}
|
|
|
|
if(memcmp((const void *) u8SrcAddr, (const void *) u8MagicData, sizeof(u8MagicData)) != 0)
|
|
{
|
|
spi_nand_err("Magic number Error %p\n", u8SrcAddr);
|
|
continue;
|
|
}
|
|
|
|
u8SrcAddr += sizeof(u8MagicData);
|
|
memcpy(u8DstAddr, u8SrcAddr, sizeof(SPINAND_FLASH_INFO_t));
|
|
{
|
|
//HAL_SPINAND_ReadID(pSpiNandDrv->tSpinandInfo.u8_IDByteCnt, pSpiNandDrv->tSpinandInfo.au8_ID);
|
|
//Use max 3 bytes to read ID because GCIS might fixed to 2 bytes only.
|
|
HAL_SPINAND_ReadID(SPINAND_ID_SIZE, pSpiNandDrv->tSpinandInfo.au8_ID);
|
|
if(pSpiNandDrv->tSpinandInfo.u8_IDByteCnt != SPINAND_ID_SIZE)
|
|
{
|
|
if((pSpiNandDrv->tSpinandInfo.au8_ID[2] == pSpiNandDrv->tSpinandInfo.au8_ID[0]) ||
|
|
pSpiNandDrv->tSpinandInfo.au8_ID[2] == 0xFF || pSpiNandDrv->tSpinandInfo.au8_ID[2] == 0x7F/*ESMT*/)
|
|
{//2 bytes
|
|
pSpiNandDrv->tSpinandInfo.au8_ID[2] = 0;
|
|
}
|
|
else
|
|
{//3 bytes
|
|
pSpiNandDrv->tSpinandInfo.u8_IDByteCnt = 3;
|
|
}
|
|
}
|
|
spi_nand_err("Found SPINAND INFO ");
|
|
for(u8_IDByteCnt = 0; u8_IDByteCnt < pSpiNandDrv->tSpinandInfo.u8_IDByteCnt;u8_IDByteCnt++)
|
|
{
|
|
printf("(0x%X) ",pSpiNandDrv->tSpinandInfo.au8_ID[u8_IDByteCnt]);
|
|
}
|
|
printf("\r\n");
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL MDrv_SPINAND_Init(SPINAND_FLASH_INFO_t *tSpinandInfo)
|
|
{
|
|
|
|
U8 u8ID[SPINAND_ID_SIZE];
|
|
// U32 u32Index;
|
|
U32 u32Ret;
|
|
BOOL bReFind = FALSE;
|
|
SPI_NAND_DRIVER_t *pSpiNandDrv = (SPI_NAND_DRIVER_t*)drvSPINAND_get_DrvContext_address();
|
|
// 1. HAL init
|
|
//
|
|
_u8SPINANDDbgLevel = E_SPINAND_DBGLV_DEBUG;
|
|
|
|
MDrv_SPINAND_Init_Detect_ID:
|
|
#if 1
|
|
u32Ret = HAL_SPINAND_Init();
|
|
if(u32Ret != ERR_SPINAND_SUCCESS)
|
|
{
|
|
tSpinandInfo->au8_ID[0] = 0xFF;
|
|
tSpinandInfo->au8_ID[1] = 0xFF;
|
|
tSpinandInfo->u8_IDByteCnt = 2;
|
|
if(!bReFind)
|
|
{
|
|
bReFind = TRUE;
|
|
HAL_SPINAND_CSCONFIG();
|
|
goto MDrv_SPINAND_Init_Detect_ID;
|
|
}
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
/*_MDrv_SPINAND_GET_INFO : Search CIS in block 0 2 4 8.*/
|
|
if(!_MDrv_SPINAND_GET_INFO())
|
|
{
|
|
u32Ret = HAL_SPINAND_ReadID(SPINAND_ID_SIZE, u8ID);
|
|
if(u32Ret != ERR_SPINAND_SUCCESS)
|
|
{
|
|
spi_nand_debug("Can't not Detect SPINAND Device!!!!\r");
|
|
tSpinandInfo->au8_ID[0] = 0xFF;
|
|
tSpinandInfo->au8_ID[1] = 0xFF;
|
|
tSpinandInfo->u8_IDByteCnt = 2;
|
|
return FALSE;
|
|
}
|
|
spi_nand_debug("Spi-nand device detect! MID =%x, DID =%x\r",u8ID[0], u8ID[1]);
|
|
tSpinandInfo->au8_ID[0] = u8ID[0];
|
|
tSpinandInfo->au8_ID[1] = u8ID[1];
|
|
tSpinandInfo->u8_IDByteCnt = 2;
|
|
return FALSE;
|
|
#if 0
|
|
spi_nand_debug("Search nand ID on internal table");
|
|
for (u32Index = 0; gtSpiNandInfoTable[u32Index].au8_ID[0] != 0; u32Index++)
|
|
{
|
|
if(gtSpiNandInfoTable[u32Index].au8_ID[0] == u8ID[0] &&
|
|
gtSpiNandInfoTable[u32Index].au8_ID[1] == u8ID[1])
|
|
{
|
|
spi_nand_debug("SPINAND Device DETECT");
|
|
memcpy(tSpinandInfo, >SpiNandInfoTable[u32Index], sizeof(SPINAND_FLASH_INFO_t));
|
|
// memcpy(&_gtSpinandInfo, >SpiNandInfoTable[u32Index], sizeof(SPINAND_FLASH_INFO_t));
|
|
break;
|
|
}
|
|
}
|
|
if((!gtSpiNandInfoTable[u32Index].au8_ID[0]) && (!gtSpiNandInfoTable[u32Index].au8_ID[1]))
|
|
{
|
|
tSpinandInfo->au8_ID[0] = u8ID[0];
|
|
tSpinandInfo->au8_ID[1] = u8ID[1];
|
|
tSpinandInfo->u8_IDByteCnt = 2;
|
|
if(!bReFind)
|
|
{
|
|
bReFind = TRUE;
|
|
HAL_SPINAND_CSCONFIG();
|
|
goto MDrv_SPINAND_Init_Detect_ID;
|
|
}
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
memcpy(tSpinandInfo, &pSpiNandDrv->tSpinandInfo, sizeof(SPINAND_FLASH_INFO_t));
|
|
}
|
|
|
|
if(pSpiNandDrv->tSpinandInfo.au8_ID[0] == MID_GD)
|
|
{
|
|
#if defined(SUPPORT_SPINAND_QUAD) && SUPPORT_SPINAND_QUAD
|
|
if(pSpiNandDrv->tSpinandInfo.au8_ID[1] == 0xD1 ||
|
|
pSpiNandDrv->tSpinandInfo.au8_ID[1] == 0xD9)
|
|
{
|
|
gSpiMode = E_SPINAND_QUAD_MODE_IO;
|
|
printk("\r\n GD Quad mode enabled\r\n");
|
|
//HAL_SPINAND_SetCKG(108);
|
|
HAL_SPINAND_PreHandle(gSpiMode);
|
|
}
|
|
#else
|
|
//printk("\r\n XXXX regular mode XXXX\r\n");
|
|
#endif
|
|
SetDriving = GD_SPINAND_SetDriving;
|
|
}
|
|
|
|
if (pSpiNandDrv->tSpinandInfo.au8_ID[0] == MID_XTX) /*XTX NAND flash need to pull down QE bit when use single mode*/
|
|
{
|
|
#if !defined(SUPPORT_SPINAND_QUAD) || (0 == SUPPORT_SPINAND_QUAD)
|
|
|
|
U8 u8Status;
|
|
|
|
HAL_SPINAND_ReadStatusRegister(&u8Status, SPI_NAND_REG_FEAT);
|
|
if(u8Status & QUAD_ENABLE)
|
|
{
|
|
u8Status &= ~(QUAD_ENABLE);
|
|
HAL_SPINAND_WriteStatusRegister(u8Status, SPI_NAND_REG_FEAT);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if(tSpinandInfo->au8_ID[0] == 0x2c && tSpinandInfo->au8_ID[1] == 0x24)//two plane
|
|
{
|
|
tSpinandInfo->u8PlaneCnt = 2;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
/*void MDrv_SPINAND_ForceInit(SPINAND_FLASH_INFO_t *tSpinandInfo)
|
|
{
|
|
memcpy(&_gtSpinandInfo, tSpinandInfo, sizeof(SPINAND_FLASH_INFO_t));
|
|
}*/
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
// Read SPINAND Data
|
|
// @param u32_PageIdx : page index of read data in specific block
|
|
// @return TRUE : succeed
|
|
// @return FALSE : fail
|
|
// @note : If Enable ISP engine, the XIU mode does not work
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
U32 MDrv_SPINAND_Read(U32 u32_PageIdx, U8 *u8Data, U8 *pu8_SpareBuf)
|
|
{
|
|
U8 u8Status;
|
|
U32 u32Ret = ERR_SPINAND_SUCCESS;
|
|
U16 u16ColumnAddr = 0;
|
|
SPI_NAND_DRIVER_t *pSpiNandDrv = (SPI_NAND_DRIVER_t*)drvSPINAND_get_DrvContext_address();
|
|
|
|
if((pSpiNandDrv->tSpinandInfo.au8_ID[0] == 0xEF) &&
|
|
(pSpiNandDrv->tSpinandInfo.au8_ID[1] == 0xAB) &&
|
|
(pSpiNandDrv->tSpinandInfo.au8_ID[2] == 0x21))
|
|
{
|
|
U16 u16DiePageCnt = MDrv_SPINAND_CountBits(pSpiNandDrv->tSpinandInfo.u16_BlkCnt*pSpiNandDrv->tSpinandInfo.u16_BlkPageCnt);
|
|
HAL_SPINAND_DieSelect((U8)(u32_PageIdx >> (u16DiePageCnt-1)));
|
|
}
|
|
|
|
//read data to cache first
|
|
u32Ret = HAL_SPINAND_RFC(u32_PageIdx, &u8Status);
|
|
|
|
if(u32Ret != ERR_SPINAND_SUCCESS)
|
|
{
|
|
return u32Ret;
|
|
}
|
|
|
|
// HAL_SPINAND_PLANE_HANDLER(u32_PageIdx);
|
|
|
|
// Read SPINand Data
|
|
|
|
if(pSpiNandDrv->tSpinandInfo.u8PlaneCnt && (((u32_PageIdx/pSpiNandDrv->tSpinandInfo.u16_BlkPageCnt)&0x1) == 1))
|
|
{
|
|
u16ColumnAddr |= (1<<12); // plane select for MICRON & 2GB
|
|
spi_nand_msg("PLANE: u16ColumnAddr %x\n", u16ColumnAddr);
|
|
}
|
|
|
|
#if defined(SUPPORT_SPINAND_QUAD) && SUPPORT_SPINAND_QUAD
|
|
HAL_SPINAND_SetMode(gSpiMode);
|
|
#endif
|
|
u32Ret = HAL_SPINAND_Read (u16ColumnAddr, pSpiNandDrv->tSpinandInfo.u16_PageByteCnt, u8Data);
|
|
#if defined(SUPPORT_SPINAND_QUAD) && SUPPORT_SPINAND_QUAD
|
|
HAL_SPINAND_SetMode(E_SPINAND_SINGLE_MODE);
|
|
#endif
|
|
|
|
if(u32Ret != ERR_SPINAND_SUCCESS)
|
|
{
|
|
return u32Ret;
|
|
}
|
|
|
|
// Read SPINand Spare Data
|
|
u32Ret= HAL_SPINAND_Read(pSpiNandDrv->tSpinandInfo.u16_PageByteCnt, pSpiNandDrv->tSpinandInfo.u16_SpareByteCnt, pu8_SpareBuf);
|
|
|
|
if(u32Ret == ERR_SPINAND_SUCCESS)
|
|
{
|
|
if(u8Status == ECC_1_3_CORRECTED)
|
|
u32Ret = ERR_SPINAND_ECC_1_3_CORRECTED;
|
|
if(u8Status == ECC_4_6_CORRECTED)
|
|
u32Ret = ERR_SPINAND_ECC_4_6_CORRECTED;
|
|
if(u8Status == ECC_7_8_CORRECTED)
|
|
u32Ret = ERR_SPINAND_ECC_7_8_CORRECTED;
|
|
if(u8Status == ECC_NOT_CORRECTED)
|
|
{
|
|
u32Ret = ERR_SPINAND_ECC_ERROR;
|
|
printf("ecc error P: 0x%x\r\n", u32_PageIdx);
|
|
}
|
|
}
|
|
return u32Ret;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
// Read SPINAND Data From Random column address
|
|
// @param u32_PageIdx : page index of read data in specific block
|
|
// @return TRUE : succeed
|
|
// @return FALSE : fail
|
|
// @note : If Enable ISP engine, the XIU mode does not work
|
|
//-------------------------------------------------------------------------------------------------
|
|
U32 MDrv_SPINAND_Read_RandomIn(U32 u32_PageIdx, U32 u32_Column, U32 u32_Byte, U8 *u8Data)
|
|
{
|
|
return HAL_SPINAND_Read_RandomIn(u32_PageIdx, u32_Column, u32_Byte, u8Data);
|
|
}
|
|
|
|
U32 MDrv_SPINAND_ReadStatusRegister(MS_U8 *u8Status, MS_U8 u8Addr)
|
|
{
|
|
return HAL_SPINAND_ReadStatusRegister(u8Status, u8Addr);
|
|
}
|
|
|
|
U32 MDrv_SPINAND_WriteStatusRegister(MS_U8 *u8Status, MS_U8 u8Addr)
|
|
{
|
|
return HAL_SPINAND_WriteStatusRegister(*u8Status, u8Addr);
|
|
}
|
|
|
|
U32 MDrv_SPINAND_SetMode(SPINAND_MODE eMode)
|
|
{
|
|
return HAL_SPINAND_SetMode(eMode);
|
|
}
|
|
|
|
U32 MDrv_SPINAND_Write(U32 u32_PageIdx, U8 *u8Data, U8 *pu8_SpareBuf)
|
|
{
|
|
SPI_NAND_DRIVER_t *pSpiNandDrv = (SPI_NAND_DRIVER_t*)drvSPINAND_get_DrvContext_address();
|
|
|
|
if((pSpiNandDrv->tSpinandInfo.au8_ID[0] == 0xEF) &&
|
|
(pSpiNandDrv->tSpinandInfo.au8_ID[1] == 0xAB) &&
|
|
(pSpiNandDrv->tSpinandInfo.au8_ID[2] == 0x21))
|
|
{
|
|
U16 u16DiePageCnt = MDrv_SPINAND_CountBits(pSpiNandDrv->tSpinandInfo.u16_BlkCnt*pSpiNandDrv->tSpinandInfo.u16_BlkPageCnt);
|
|
HAL_SPINAND_DieSelect((U8)(u32_PageIdx >> (u16DiePageCnt-1)));
|
|
}
|
|
return HAL_SPINAND_Write(u32_PageIdx, u8Data, pu8_SpareBuf);
|
|
}
|
|
|
|
U8 MDrv_SPINAND_ReadID(U16 u16Size, U8 *u8Data)
|
|
{
|
|
return HAL_SPINAND_ReadID(u16Size, u8Data);
|
|
}
|
|
|
|
U32 MDrv_SPINAND_BLOCK_ERASE(U32 u32_PageIdx)
|
|
{
|
|
SPI_NAND_DRIVER_t *pSpiNandDrv = (SPI_NAND_DRIVER_t*)drvSPINAND_get_DrvContext_address();
|
|
|
|
if((pSpiNandDrv->tSpinandInfo.au8_ID[0] == 0xEF) &&
|
|
(pSpiNandDrv->tSpinandInfo.au8_ID[1] == 0xAB) &&
|
|
(pSpiNandDrv->tSpinandInfo.au8_ID[2] == 0x21))
|
|
{
|
|
U16 u16DiePageCnt = MDrv_SPINAND_CountBits(pSpiNandDrv->tSpinandInfo.u16_BlkCnt*pSpiNandDrv->tSpinandInfo.u16_BlkPageCnt);
|
|
HAL_SPINAND_DieSelect((U8)(u32_PageIdx >> (u16DiePageCnt-1)));
|
|
}
|
|
return HAL_SPINAND_BLOCKERASE(u32_PageIdx);
|
|
}
|
|
|
|
U32 MDrv_SPINAND_EnableOtp(BOOL bEnable)
|
|
{
|
|
return HAL_SPINAND_EnableOtp(bEnable);
|
|
}
|
|
|
|
U32 MDrv_SPINAND_LockOtp(void)
|
|
{
|
|
return HAL_SPINAND_LockOtp();
|
|
}
|
|
|
|
U8 MDrv_SPINAND_WB_BBM(U32 u32LBA, U32 u32PBA)
|
|
{
|
|
printf("[WB bbm] replace LBA 0x%x to PBA 0x%x \r\n", u32LBA, u32PBA);
|
|
return HAL_SPINAND_WB_BBM(u32LBA, u32PBA);
|
|
}
|
|
|
|
U8 MDrv_SPINAND_WB_DumpBBM(U8 *u8Data)
|
|
{
|
|
return HAL_SPINAND_WB_DumpBBM(u8Data);
|
|
}
|
|
|
|
void SpiNandMain(unsigned int dwSramAddress, unsigned int dwSramSize)
|
|
{
|
|
U8 u8Data[2];
|
|
MDrv_SPINAND_ReadID(2,u8Data);
|
|
}
|
|
|
|
BOOL MDrv_SPINAND_SetDevDriving(U16 u16Driving)
|
|
{
|
|
if(SetDriving)
|
|
{
|
|
return SetDriving(u16Driving);
|
|
}
|
|
printf("No Dev Driving Setting function\n");
|
|
return 0;
|
|
}
|