📄 nandfmd.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2007, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
#include "basetype.h"
#include "inc.h"
#include "mx27_nandfc.h"
#include "nandfmd.h"
#include <string.h>
//-----------------------------------------------------------------------------
// External Functions
extern BOOL NFCAlloc(void);
extern void NFCWait(BOOL bPoll);
extern BOOL NFCSetClock(BOOL bEnabled);
extern BOOL NFCSetPagesize(BOOL bLargePage);
#define __JIA__
//-----------------------------------------------------------------------------
// External Variables
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
// Local Variables
static u16 g_NandDeviceID;
//-----------------------------------------------------------------------------
// Local Functions
//-----------------------------------------------------------------------------
//
// Function: NFCReadSpare
//
// This function reads the NAND flash controller spare area and provides this
// information to the upper FMD layers.
//
// Parameters:
// pSectorInfoBuff
// [out] Buffer containing sector information read.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
static void NFCReadSpare(PSectorInfo pSectorInfoBuff)
{
pSectorInfoBuff->dwReserved1 = INREG32((u32 *) &g_pNFC->SPARE[0][0]);
*((u16 *) (&pSectorInfoBuff->bOEMReserved)) = INREG16(&g_pNFC->SPARE[0][2]);
pSectorInfoBuff->wReserved2 = INREG16(&g_pNFC->SPARE[0][7]);
}
//-----------------------------------------------------------------------------
//
// Function: NFCWriteSpare
//
// This function writes the spare data provided by the upper FMD layers
// to the NAND flash controller spare area.
//
// Parameters:
// pSectorInfoBuff
// [in] Buffer containing sector information to be written.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
static void NFCWriteSpare(PSectorInfo pSectorInfoBuff)
{
OUTREG32((u32 *) &g_pNFC->SPARE[0][0], pSectorInfoBuff->dwReserved1);
OUTREG16(&g_pNFC->SPARE[0][2], *((u16 *) (&pSectorInfoBuff->bOEMReserved)));
OUTREG16(&g_pNFC->SPARE[0][3], 0xFFFF);
OUTREG32((u32 *) &g_pNFC->SPARE[0][4], 0xFFFFFFFF);
OUTREG16(&g_pNFC->SPARE[0][6], 0xFFFF);
OUTREG16(&g_pNFC->SPARE[0][7], pSectorInfoBuff->wReserved2);
}
//-----------------------------------------------------------------------------
//
// Function: NFCClearSpare
//
// This function clears the NAND flash controller spare area (all
// ones written to the spare area will prevent the spare area of
// the NAND memory device from being updated since only zeros are
// written during a NAND program cycle).
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
static void NFCClearSpare(void)
{
u32 *dest = (u32 *) &g_pNFC->SPARE[0];
OUTREG32(&dest[0], 0xFFFFFFFF);
OUTREG32(&dest[1], 0xFFFFFFFF);
OUTREG32(&dest[2], 0xFFFFFFFF);
OUTREG32(&dest[3], 0xFFFFFFFF);
}
BOOL NFCAlloc(void)
{
// Map peripheral physical address to virtual address
// g_pNFC = (PCSP_NANDFC_REGS) OALPAtoUA(CSP_BASE_REG_PA_NANDFC);
g_pNFC = (volatile PCSP_NANDFC_REGS)(CSP_BASE_REG_PA_NANDFC);
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_Init
//
// This function initializes the flash memory of a device.
//
// Parameters:
// lpActiveReg
// [in] Pointer to the active registry string used to find device
// information from the registry. Set to NULL if not needed.
//
// pRegIn
// [in] Pointer to a PCI_REG_INFO structure. Used to find flash
// hardware on PCI hardware. Set to NULL if not needed.
//
// pRegOut
// [in/out] Pointer to a PCI_REG_INFO structure. Used to return
// flash information. Set to NULL if not needed.
//
// Returns:
// A handle that can be used in a call to FMD_Deinit. It is the
// responsibility of the specific flash media driver (FMD) implementation
// to determine what this value represents. A value of zero (0)
// represents failure.
//
//-----------------------------------------------------------------------------
volatile int fmd_inited=0;
BOOL FMD_Init(void)//LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{
if(fmd_inited)
return TRUE;
fmd_inited=1;
NFCSetClock(TRUE);
// Perform NFC allocations, mappings, and initializations
/*if (!NFCAlloc())
{
ERRORMSG(TRUE, (_T("FMD_Init: failed memory allocation/mapping\r\n")));
goto cleanUp;
}*/
NFCAlloc();
// Unlock buffer pages
OUTREG16(&g_pNFC->NFC_CONFIGURATION,0x02);
// Use NFC buffer #0 for all operations
OUTREG16(&g_pNFC->RAM_BUFF_ADDRESS, 0);
// Configure the NFC
// - Enable hardware ECC
// - Mask NFC interrupt
// - Little endian mode
// - Reset NFC state machine
// - CE signal operates normally
// - 0x0018
OUTREG16(&g_pNFC->NAND_FLASH_CONFIG1,
CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_ECC_EN, NANDFC_NAND_FLASH_CONFIG1_ECC_EN_ENABLE) |
CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_INT_MSK, NANDFC_NAND_FLASH_CONFIG1_INT_MSK_MASK) |
CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_NF_BIG, NANDFC_NAND_FLASH_CONFIG1_NF_BIG_LITTLE) |
CSP_BITFVAL(NANDFC_NAND_FLASH_CONFIG1_NF_CE, NANDFC_NAND_FLASH_CONFIG1_NF_CE_UNFORCE));
NF_CMD(CMD_RESET); // Send flash reset command
// Get manufacturer and device codes.
NF_CMD(CMD_READID); // Read ID command
NF_ADDR(0); // Required address cycle
NF_RD_ID(); // Read ID into NFC buffer
g_NandDeviceID = INREG16(&g_pNFC->MAIN[0]);
if (g_NandDeviceID != NAND_ID_CODE)
{
//ERRORMSG(TRUE, (_T("FMD_Init: invalid device ID (%x)\r\n"), g_NandDeviceID));
return FALSE;
}
// Unlock all blocks
OUTREG16(&g_pNFC->UNLOCK_START_BLK_ADD, 0);
OUTREG16(&g_pNFC->UNLOCK_END_BLK_ADD, NAND_BLOCK_CNT-1);
OUTREG16(&g_pNFC->NF_WR_PROT, NANDFC_NF_WR_PROT_WPC_UNLOCK);
cleanUp:
NFCSetClock(FALSE);
return TRUE;//rc;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_Deinit
//
// This function de-initializes the flash chip.
//
// Parameters:
// hFMD
// [in] The handle returned from FMD_Init.
//
// Returns:
// Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_Deinit(void)//Pvoid hFMD)
{
return(TRUE);
}
//-----------------------------------------------------------------------------
//
// Function: NFCReadMain
//
// This function reads the NAND flash controller main area and provides this
// sector data to the upper FMD layers.
//
// Parameters:
// pSectorBuff
// [out] Buffer containing sector data read.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
static void NFCReadMain(u8_ptr pSectorBuff)
{
/* if((u32)pSectorBuff & 0x1)
{
// Byte-aligned on BYTE[3]
if((u32)pSectorBuff & 0x2)
{
RdPage512Align3(pSectorBuff);
}
// Byte-aligned on BYTE[1]
else
{
RdPage512Align1(pSectorBuff);
}
}
else if ((u32)pSectorBuff & 0x2)
{
// Half-word aligned on BYTE[2]
RdPage512Align2(pSectorBuff);
}
else
{
// Word-aligned
RdPage512Align4(pSectorBuff);
}*/
}
static void FMD_ReadMain(u16_ptr pBuffer,/* u8_ptr pMain,*/ u16 pSize)
{
u16 i;
u16_ptr pMain ;
pMain = (u16 *)(0xD8000000);
for(i = 0; i < pSize; i++)
{
*pBuffer = *pMain ;
pBuffer++ ;
pMain++ ;
}
return;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_ReadSector
//
// This function reads the requested sector data and metadata from the
// flash media.
//
// Parameters:
// startSectorAddr
// [in] The starting physical sector address to read.
//
// pSectorBuff
// [out] Pointer to the buffer that contains the sector data read
// from flash memory. Set to NULL if this data is not needed.
//
// pSectorInfoBuff
// [out] Buffer for an array of sector information structures. There
// is one sector information entry for every sector that is to be read.
// Set to NULL if this data is not needed.
//
// dwNumSectors
// [in] Number of sectors to read.
//
// Returns:
// Returns TRUE on success. Returns FALSE on failure.
//
//-----------------------------------------------------------------------------
BOOL FMD_ReadSector(u32 startSectorAddr, u16_ptr pSectorBuff,
PSectorInfo pSectorInfoBuff, u32 dwNumSectors)
{
u32 SectorAddr = startSectorAddr;
u32 ColumnAddr, RowAddr;
BOOL bSeqRead = FALSE;
BOOL rc = FALSE;
u16 Status;
NFCSetClock(TRUE);
while (dwNumSectors--)
{
RowAddr = (u32)SectorAddr/NAND_SECTORS_PERPAGE;
ColumnAddr = ((u32)SectorAddr%NAND_SECTORS_PERPAGE) * (NAND_SECTOR_SIZE + NAND_SPARE_SIZE);
if (pSectorBuff != NULL)
{
// If read access requires command and address to be sent
if (!bSeqRead)
{
NF_CMD(CMD_READ); // Send page read command.
NF_ADDR_COL(ColumnAddr); // Send column address
NF_ADDR_PAGE(RowAddr); // Send page address
#ifdef NAND_LARGE_PAGE
NF_CMD(CMD_READ_2CYCLE); // Send 2nd cycle read command
#endif
}
// Read page data into NFC buffer
NF_RD_PAGE();
// Move page data from NFC buffer sector buffer
//NFCReadMain(pSectorBuff);
//data = sizeof(pSectorBuff);
//FMD_ReadMain(pSectorBuff,&g_pNFC->MAIN,512);
FMD_ReadMain(pSectorBuff, 256);
//memcpy(pSectorBuff,&g_pNFC->MAIN,data);
if (pSectorInfoBuff != NULL)
{
NFCReadSpare(pSectorInfoBuff);
pSectorInfoBuff++;
}
pSectorBuff += NAND_SECTOR_SIZE;
// Check for uncorrectable ECC errors in main and spare areas
Status = INREG16(&g_pNFC->ECC_STATUS_RESULT);
if (Status & 0xa)
{
goto cleanUp;
}
}
else if (pSectorInfoBuff != NULL)
{
#ifndef NAND_LARGE_PAGE
NF_CMD(CMD_READ2); // Send spare read command.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -