1321 lines
40 KiB
C
1321 lines
40 KiB
C
|
/*******************************************************************************
|
||
|
Copyright (C) Marvell International Ltd. and its affiliates
|
||
|
|
||
|
This software file (the "File") is owned and distributed by Marvell
|
||
|
International Ltd. and/or its affiliates ("Marvell") under the following
|
||
|
alternative licensing terms. Once you have made an election to distribute the
|
||
|
File under one of the following license alternatives, please (i) delete this
|
||
|
introductory statement regarding license alternatives, (ii) delete the two
|
||
|
license alternatives that you have not elected to use and (iii) preserve the
|
||
|
Marvell copyright notice above.
|
||
|
|
||
|
********************************************************************************
|
||
|
Marvell Commercial License Option
|
||
|
|
||
|
If you received this File from Marvell and you have entered into a commercial
|
||
|
license agreement (a "Commercial License") with Marvell, the File is licensed
|
||
|
to you under the terms of the applicable Commercial License.
|
||
|
|
||
|
********************************************************************************
|
||
|
Marvell GPL License Option
|
||
|
|
||
|
If you received this File from Marvell, you may opt to use, redistribute and/or
|
||
|
modify this File in accordance with the terms and conditions of the General
|
||
|
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
|
||
|
available along with the File in the license.txt file or by writing to the Free
|
||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
|
||
|
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
|
||
|
|
||
|
THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
|
||
|
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
|
||
|
DISCLAIMED. The GPL License provides additional details about this warranty
|
||
|
disclaimer.
|
||
|
********************************************************************************
|
||
|
Marvell BSD License Option
|
||
|
|
||
|
If you received this File from Marvell, you may opt to use, redistribute and/or
|
||
|
modify this File under the following licensing terms.
|
||
|
Redistribution and use in source and binary forms, with or without modification,
|
||
|
are permitted provided that the following conditions are met:
|
||
|
|
||
|
* Redistributions of source code must retain the above copyright notice,
|
||
|
this list of conditions and the following disclaimer.
|
||
|
|
||
|
* Redistributions in binary form must reproduce the above copyright
|
||
|
notice, this list of conditions and the following disclaimer in the
|
||
|
documentation and/or other materials provided with the distribution.
|
||
|
|
||
|
* Neither the name of Marvell nor the names of its contributors may be
|
||
|
used to endorse or promote products derived from this software without
|
||
|
specific prior written permission.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
*******************************************************************************/
|
||
|
#include "mflash/mvMFlash.h"
|
||
|
#include "mflash/mvPMFlash.h"
|
||
|
#include "mflash/mvSMFlash.h"
|
||
|
#include "mflash/mvMFlashSpec.h"
|
||
|
#include "mflash/mvPMFlashSpec.h"
|
||
|
#include "mflash/mvSMFlashSpec.h"
|
||
|
|
||
|
/*#define MV_DEBUG*/
|
||
|
#ifdef MV_DEBUG
|
||
|
#define DB(x) x
|
||
|
#else
|
||
|
#define DB(x)
|
||
|
#endif
|
||
|
|
||
|
/* Static Functions */
|
||
|
static MV_STATUS mvMFlashBlockByRegionWr(MV_MFLASH_INFO *pFlash, MV_U32 offset, \
|
||
|
MV_U32 blockSize, MV_U8 *pBlock, MV_BOOL verify, \
|
||
|
MV_BOOL main);
|
||
|
static MV_STATUS mvMFlash64bInfWr (MV_MFLASH_INFO *pFlash, MV_U32 offset, \
|
||
|
MV_U8 *pBuff, MV_BOOL verify);
|
||
|
static MV_STATUS mvMFlash64bWr (MV_MFLASH_INFO *pFlash, MV_U32 offset, \
|
||
|
MV_U8 *pBuff, MV_BOOL verify);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashInit - Initialize a Marvell Flash device
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* This function performs the necessary initialization for a Marvell
|
||
|
* Sunol flash.
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: Structure with Marvell Flash information
|
||
|
* pFlash->baseAddr: flash base address.
|
||
|
* pFlash->ifMode: The mode used SPI or Parallel.
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* pFlash: pointer to the tructure with Marvell Flash information detected
|
||
|
* pFlash->flashModel: flash model deteced
|
||
|
* pFlash->sectorSize: Size of each sector (unified sector size)
|
||
|
* pFlash->sectorNumber: Number of sectors in the flash
|
||
|
* pFlash->infoSize: Size of the Information region.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashInit (MV_MFLASH_INFO *pFlash)
|
||
|
{
|
||
|
MV_U32 manufId;
|
||
|
MV_U16 devId;
|
||
|
MV_U8 reg;
|
||
|
MV_STATUS ret;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
{
|
||
|
/* perform the basic initialization */
|
||
|
if ((ret = mvPMFlashInit(pFlash)) != MV_OK)
|
||
|
return ret;
|
||
|
|
||
|
/* Try to read the device ID and decide the device model */
|
||
|
if ((ret = mvPMFlashIdGet(pFlash, &manufId, &devId)) != MV_OK)
|
||
|
return ret;
|
||
|
|
||
|
/* Get the Serial interface configuration register to check sector size */
|
||
|
if ((ret = mvPMFlashReadConfig4(pFlash, ®)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
{
|
||
|
/* perform the basic initialization */
|
||
|
if ((ret = mvSMFlashInit(pFlash)) != MV_OK)
|
||
|
return ret;
|
||
|
|
||
|
/* Try to read the device ID and decide the device model */
|
||
|
if ((ret = mvSMFlashIdGet(pFlash, &manufId, &devId)) != MV_OK)
|
||
|
return ret;
|
||
|
|
||
|
/* Get the Serial interface configuration register to check sector size */
|
||
|
if ((ret = mvSMFlashReadConfig4(pFlash, ®)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* check the manufacturer Id to be the same as MARVELL */
|
||
|
if (manufId != MV_MFLASH_MANUFACTURER_ID)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Flash unknown manufacturer ID!\n", __FUNCTION__);
|
||
|
return MV_NOT_SUPPORTED;
|
||
|
}
|
||
|
|
||
|
/* based on device ID and the PAGE4K bit fill model, sector size and number */
|
||
|
switch (devId & MV_MFLASH_DEVICE_ID_MASK)
|
||
|
{
|
||
|
case MV_MFLASH_DEVICE_ID_SUNOL_1:
|
||
|
pFlash->flashModel = MV_MFLASH_SUNOL_1;
|
||
|
pFlash->infoSize = MV_MFLASH_INF_MEM_SZ_SUNOL_1;
|
||
|
if (reg & MV_SMFLASH_SRL_CFG4_PG_SIZE_MASK) /* 1 - page is 4K */
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_SMALL;
|
||
|
pFlash->sectorNumber = MV_MFLASH_SMALL_SEC_NUM_SUNOL_1;
|
||
|
}
|
||
|
else /* 0 - page is 32K */
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_BIG;
|
||
|
pFlash->sectorNumber = MV_MFLASH_BIG_SEC_NUM_SUNOL_1;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MV_MFLASH_DEVICE_ID_SUNOL_2:
|
||
|
pFlash->flashModel = MV_MFLASH_SUNOL_2;
|
||
|
pFlash->infoSize = MV_MFLASH_INF_MEM_SZ_SUNOL_2_3;
|
||
|
if (reg & MV_SMFLASH_SRL_CFG4_PG_SIZE_MASK) /* 1 - page is 4K */
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_SMALL;
|
||
|
pFlash->sectorNumber = MV_MFLASH_SMALL_SEC_NUM_SUNOL_2;
|
||
|
}
|
||
|
else /* 0 - page is 32K */
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_BIG;
|
||
|
pFlash->sectorNumber = MV_MFLASH_BIG_SEC_NUM_SUNOL_2;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MV_MFLASH_DEVICE_ID_SUNOL_3:
|
||
|
pFlash->flashModel = MV_MFLASH_SUNOL_3;
|
||
|
pFlash->infoSize = MV_MFLASH_INF_MEM_SZ_SUNOL_2_3;
|
||
|
if (reg & MV_SMFLASH_SRL_CFG4_PG_SIZE_MASK) /* 1 - page is 4K */
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_SMALL;
|
||
|
pFlash->sectorNumber = MV_MFLASH_SMALL_SEC_NUM_SUNOL_3;
|
||
|
}
|
||
|
else /* 0 - page is 32K */
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_BIG;
|
||
|
pFlash->sectorNumber = MV_MFLASH_BIG_SEC_NUM_SUNOL_3;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
mvOsPrintf("%s ERROR: Unknown Flash Device ID!\n", __FUNCTION__);
|
||
|
pFlash->flashModel = MV_MFLASH_MODEL_UNKNOWN;
|
||
|
return MV_NOT_SUPPORTED;
|
||
|
}
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashChipErase - Erase the whole flash
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Erase the whole flash (both the Main and Information region)
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashChipErase (MV_MFLASH_INFO *pFlash)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashChipErase(pFlash);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashChipErase(pFlash);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashMainErase - Erase the main flash region only
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Erase the Main flash region
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashMainErase (MV_MFLASH_INFO *pFlash)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashMainErase(pFlash);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashMainErase(pFlash);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashInfErase - Erase the information flash region only
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Erase the information flash region
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashInfErase (MV_MFLASH_INFO *pFlash)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashInfErase(pFlash);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashInfErase(pFlash);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashSecErase - Erase the single sector of the main flash region
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Erase one sector of the main flash region
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* secOffset: sector offset within the MFlash
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashSecErase (MV_MFLASH_INFO *pFlash, MV_U32 secNumber)
|
||
|
{
|
||
|
MV_U32 i;
|
||
|
MV_U32 * pW = (MV_U32*) ((secNumber * pFlash->sectorSize) + pFlash->baseAddr);
|
||
|
MV_U32 erasedWord = 0xFFFFFFFF;
|
||
|
MV_U32 wordsPerSector = (pFlash->sectorSize / sizeof(MV_U32));
|
||
|
MV_BOOL eraseNeeded = MV_FALSE;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* First compare to FF and check if erase is needed */
|
||
|
for (i=0; i<wordsPerSector; i++)
|
||
|
{
|
||
|
if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)
|
||
|
{
|
||
|
eraseNeeded = MV_TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
++pW;
|
||
|
}
|
||
|
|
||
|
if (!eraseNeeded)
|
||
|
return MV_OK;
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashSecErase(pFlash, secNumber);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashSecErase(pFlash, secNumber);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlash64bWr - Perform the alligned write according to the SPI mode and verify
|
||
|
* type.
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Select the appropriate write api according to the SPI mode and the
|
||
|
* verify flag.
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
static MV_STATUS mvMFlash64bWr (MV_MFLASH_INFO *pFlash, MV_U32 offset,
|
||
|
MV_U8 *pBuff, MV_BOOL verify)
|
||
|
{
|
||
|
MV_STATUS ret;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
#ifndef CONFIG_MARVELL
|
||
|
if(NULL == pBuff)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* call the api based on the SPI mode and the verify option */
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
{
|
||
|
if (verify)
|
||
|
{
|
||
|
if ((ret = mvPMFlash64bWrVerify(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvPMFlash64bWr(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
{
|
||
|
if (verify)
|
||
|
{
|
||
|
if ((ret = mvSMFlash64bWrVerify(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvSMFlash64bWr(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlash64bInfWr - Perform the alligned write to the information region based
|
||
|
* on the SPI mode and verify type.
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Select the appropriate write api according to the SPI mode and the
|
||
|
* verify flag.
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
static MV_STATUS mvMFlash64bInfWr (MV_MFLASH_INFO *pFlash, MV_U32 offset,
|
||
|
MV_U8 *pBuff, MV_BOOL verify)
|
||
|
{
|
||
|
MV_STATUS ret;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
#ifndef CONFIG_MARVELL
|
||
|
if(NULL == pBuff)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* call the api based on the SPI mode and the verify option */
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
{
|
||
|
if (verify)
|
||
|
{
|
||
|
if ((ret = mvPMFlash64bInfWrVerify(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvPMFlash64bInfWr(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
{
|
||
|
if (verify)
|
||
|
{
|
||
|
if ((ret = mvSMFlash64bInfWrVerify(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvSMFlash64bInfWr(pFlash, offset, pBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashBlockByRegionWr - Write a buffer with a custom length and allignment
|
||
|
* based on the region (main or information)
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Program a varient sized block in the selected region of the MFlash
|
||
|
* and perform the verify based on flag.
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
static MV_STATUS mvMFlashBlockByRegionWr(MV_MFLASH_INFO *pFlash, MV_U32 offset,
|
||
|
MV_U32 blockSize, MV_U8 *pBlock, MV_BOOL verify, MV_BOOL main)
|
||
|
{
|
||
|
MV_U8 tempBuff[MV_MFLASH_PROG_CHUNK_SIZE];
|
||
|
MV_U32 data2write = blockSize;
|
||
|
MV_U32 preAllOfst = (offset & MV_MFLASH_PROG_ALIGN_MASK);
|
||
|
MV_U32 preAllSz = (preAllOfst ? (MV_MFLASH_PROG_CHUNK_SIZE - preAllOfst) : 0);
|
||
|
MV_U32 writeOffset = (offset & ~MV_MFLASH_PROG_ALIGN_MASK);
|
||
|
MV_STATUS ret;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
#ifndef CONFIG_MARVELL
|
||
|
if(NULL == pBlock)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* verify that the write commands does not exceed the size */
|
||
|
if ((offset + blockSize) > (pFlash->sectorNumber * pFlash->sectorSize))
|
||
|
{
|
||
|
DB(mvOsPrintf("%s WARNING: Exceeded flash size!!\n", __FUNCTION__);)
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* check if the total block size is less than the first chunk remainder */
|
||
|
if (data2write < preAllSz)
|
||
|
preAllSz = data2write;
|
||
|
|
||
|
/* check if programing does not start at a 64byte alligned offset */
|
||
|
if (preAllSz)
|
||
|
{
|
||
|
/* first copy the original data */
|
||
|
if (main)
|
||
|
{
|
||
|
if ((ret = mvMFlashBlockRd(pFlash, writeOffset, MV_MFLASH_PROG_CHUNK_SIZE, tempBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvMFlashBlockInfRd(pFlash, writeOffset, MV_MFLASH_PROG_CHUNK_SIZE, tempBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* overwrite the data to be changed */
|
||
|
mvOsMemcpy((MV_VOID*)&tempBuff[preAllOfst], pBlock, preAllSz);
|
||
|
|
||
|
/* Perform the 64 bytes write based on the mode and verify type */
|
||
|
if (main)
|
||
|
{
|
||
|
if ((ret = mvMFlash64bWr(pFlash, writeOffset, tempBuff, verify)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvMFlash64bInfWr(pFlash, writeOffset, tempBuff, verify)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* increment pointers and counters */
|
||
|
writeOffset += MV_MFLASH_PROG_CHUNK_SIZE;
|
||
|
data2write -= preAllSz;
|
||
|
pBlock += preAllSz;
|
||
|
}
|
||
|
|
||
|
/* program the data that fits in complete 64bytes chunks */
|
||
|
while (data2write >= MV_MFLASH_PROG_CHUNK_SIZE)
|
||
|
{
|
||
|
/* Perform the 64 bytes write based on the mode and verify type */
|
||
|
if (main)
|
||
|
{
|
||
|
if ((ret = mvMFlash64bWr(pFlash, writeOffset, pBlock, verify)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvMFlash64bInfWr(pFlash, writeOffset, pBlock, verify)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* increment pointers and counters */
|
||
|
writeOffset += MV_MFLASH_PROG_CHUNK_SIZE;
|
||
|
data2write -= MV_MFLASH_PROG_CHUNK_SIZE;
|
||
|
pBlock += MV_MFLASH_PROG_CHUNK_SIZE;
|
||
|
}
|
||
|
|
||
|
/* program the last partial chunk */
|
||
|
if (data2write)
|
||
|
{
|
||
|
/* first copy the original data */
|
||
|
if (main)
|
||
|
{
|
||
|
if ((ret = mvMFlashBlockRd(pFlash, writeOffset, MV_MFLASH_PROG_CHUNK_SIZE, tempBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvMFlashBlockInfRd(pFlash, writeOffset, MV_MFLASH_PROG_CHUNK_SIZE, tempBuff)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* overwrite the data to be changed */
|
||
|
mvOsMemcpy(tempBuff, pBlock, data2write);
|
||
|
|
||
|
/* Perform the 64 bytes write based on the mode and verify type */
|
||
|
if (main)
|
||
|
{
|
||
|
if ((ret = mvMFlash64bWr(pFlash, writeOffset, tempBuff, verify)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((ret = mvMFlash64bInfWr(pFlash, writeOffset, tempBuff, verify)) != MV_OK)
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashBlockWr - Write a buffer with a custom length and allignment
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Program a varient sized block in the Main region of the MFlash.
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* offset: offset within the Information region (limited to 1024)
|
||
|
* blockSize: size in bytes of the buffer to be programmed.
|
||
|
* pBlock: pointer to the 64 bytes buffer to be programed
|
||
|
* verify: bollean flag controlling the compare after program feature
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashBlockWr(MV_MFLASH_INFO *pFlash, MV_U32 offset,
|
||
|
MV_U32 blockSize, MV_U8 *pBlock, MV_BOOL verify)
|
||
|
{
|
||
|
/* check for NULL pointers */
|
||
|
#ifndef CONFIG_MARVELL
|
||
|
if(NULL == pBlock)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (NULL == pFlash)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
return mvMFlashBlockByRegionWr(pFlash, offset, blockSize, pBlock, verify, MV_TRUE /* main region */);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashInfBlockWr - Write a buffer with a custom length and allignment to
|
||
|
* the information region of the flash
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Program a varient sized block in the Information region of the MFlash.
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* offset: offset within the Information region (limited to 1024)
|
||
|
* blockSize: size in bytes of the buffer to be programmed.
|
||
|
* pBlock: pointer to the 64 bytes buffer to be programed
|
||
|
* verify: bollean flag controlling the compare after program feature
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashInfBlockWr(MV_MFLASH_INFO *pFlash, MV_U32 offset,
|
||
|
MV_U32 blockSize, MV_U8 *pBlock, MV_BOOL verify)
|
||
|
{
|
||
|
/* check for NULL pointers */
|
||
|
if ((pFlash == NULL) || (pBlock == NULL))
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
return mvMFlashBlockByRegionWr(pFlash, offset, blockSize, pBlock, verify, MV_FALSE /* info region */);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashBlockRd - Read a block of Memory from the Main Flash
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Read a block of Memory from the Main Flash region
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* offset: offset to read from the main region of the MFlash
|
||
|
* blockSize: number of bytes to read from the offset
|
||
|
* pBlock: pointer of the buffer to fill
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* pBlock: pointer of the buffer holding the data read from flash.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashBlockRd (MV_MFLASH_INFO *pFlash, MV_U32 offset,
|
||
|
MV_U32 blockSize, MV_U8 *pBlock)
|
||
|
{
|
||
|
/* check for NULL pointers */
|
||
|
if ((pFlash == NULL) || (pBlock == NULL))
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashBlockRd(pFlash, offset, blockSize, pBlock);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashBlockRd(pFlash, offset, blockSize, pBlock);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashSecErase - Erase the single sector of the main flash region
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Erase one sector of the main flash region
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* secOffset: sector offset within the MFlash
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashBlockInfRd (MV_MFLASH_INFO *pFlash, MV_U32 offset,
|
||
|
MV_U32 blockSize, MV_U8 *pBlock)
|
||
|
{
|
||
|
/* check for NULL pointers */
|
||
|
if ((pFlash == NULL) || (pBlock == NULL))
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashBlockInfRd(pFlash, offset, blockSize, pBlock);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashBlockInfRd(pFlash, offset, blockSize, pBlock);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashReadConfig - Read the Configuration register
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Perform the Read CONFIGx register RAB
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* regNum: register number to read (1-4 in parallel and 3-4 in spi)
|
||
|
* pConfigReg: pointer to read in the configuration register
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* pConfigReg: pointer with the data read from the configuration register
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashReadConfig (MV_MFLASH_INFO *pFlash, MV_U32 regNum, MV_U8 * pConfigReg)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if ((pFlash == NULL) || (pConfigReg == NULL))
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
{
|
||
|
switch (regNum)
|
||
|
{
|
||
|
case 1:
|
||
|
return mvPMFlashReadConfig1(pFlash, pConfigReg);
|
||
|
|
||
|
case 2:
|
||
|
return mvPMFlashReadConfig2(pFlash, pConfigReg);
|
||
|
|
||
|
case 3:
|
||
|
return mvPMFlashReadConfig3(pFlash, pConfigReg);
|
||
|
|
||
|
case 4:
|
||
|
return mvPMFlashReadConfig4(pFlash, pConfigReg);
|
||
|
|
||
|
default:
|
||
|
DB(mvOsPrintf("%s WARNING: Not supported in parallel mode!!\n", __FUNCTION__);)
|
||
|
return MV_NOT_SUPPORTED;
|
||
|
}
|
||
|
}
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
{
|
||
|
switch (regNum)
|
||
|
{
|
||
|
case 3:
|
||
|
return mvSMFlashReadConfig3(pFlash, pConfigReg);
|
||
|
|
||
|
case 4:
|
||
|
return mvSMFlashReadConfig4(pFlash, pConfigReg);
|
||
|
|
||
|
default:
|
||
|
DB(mvOsPrintf("%s WARNING: Not supported in SPI mode!!\n", __FUNCTION__);)
|
||
|
return MV_NOT_SUPPORTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashSetConfig - Write to the Configuration register
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Perform the write CONFIGx register RAB
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* regNum: register number to write (1-4 in parallel and 3-4 in spi)
|
||
|
* configReg: Data to write in the configuration register
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashSetConfig (MV_MFLASH_INFO *pFlash, MV_U32 regNum, MV_U8 configReg)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
{
|
||
|
switch (regNum)
|
||
|
{
|
||
|
case 1:
|
||
|
return mvPMFlashSetConfig1(pFlash, configReg);
|
||
|
|
||
|
case 2:
|
||
|
return mvPMFlashSetConfig2(pFlash, configReg);
|
||
|
|
||
|
case 3:
|
||
|
return mvPMFlashSetConfig3(pFlash, configReg);
|
||
|
|
||
|
case 4:
|
||
|
return mvPMFlashSetConfig4(pFlash, configReg);
|
||
|
|
||
|
default:
|
||
|
DB(mvOsPrintf("%s WARNING: Not supported in parallel mode!!\n", __FUNCTION__);)
|
||
|
return MV_NOT_SUPPORTED;
|
||
|
}
|
||
|
}
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
{
|
||
|
switch (regNum)
|
||
|
{
|
||
|
case 3:
|
||
|
return mvSMFlashSetConfig3(pFlash, configReg);
|
||
|
|
||
|
case 4:
|
||
|
return mvSMFlashSetConfig4(pFlash, configReg);
|
||
|
|
||
|
default:
|
||
|
DB(mvOsPrintf("%s WARNING: Not supported in SPI mode!!\n", __FUNCTION__);)
|
||
|
return MV_NOT_SUPPORTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashSetSlewRate - Set the slew rate for parallel interface
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Perform the set slew rate register RAB
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* configReg: Data to write in the slew rate register
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashSetSlewRate (MV_MFLASH_INFO *pFlash, MV_U8 configReg)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashSetSlewRate(pFlash, configReg);
|
||
|
|
||
|
DB(mvOsPrintf("%s WARNING: Invalid interface mode!\n", __FUNCTION__);)
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashWriteProtectSet - Set the write protection feature status
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Enable or disable the write protection
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* wp: write protection status (enable = MV_TRUE, disable = MVFALSE)
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashWriteProtectSet (MV_MFLASH_INFO *pFlash, MV_BOOL wp)
|
||
|
{
|
||
|
MV_U32 reg;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* read, modify then write the register */
|
||
|
reg = MV_REG_READ(MV_PMFLASH_IF_CFG_REG);
|
||
|
if (wp) /* active low */
|
||
|
reg &= ~MV_PMFLASH_WP_PROTECT_MASK;
|
||
|
else
|
||
|
reg |= MV_PMFLASH_WP_PROTECT_MASK;
|
||
|
|
||
|
MV_REG_WRITE(MV_PMFLASH_IF_CFG_REG, reg);
|
||
|
|
||
|
return MV_OK;
|
||
|
|
||
|
#if 0
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashWriteProtectSet(pFlash, wp);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashWriteProtectSet(pFlash, wp);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashWriteProtectGet - Get the write protection feature status
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Retreive the write protection status from the hardware (from the MFlash
|
||
|
* controller and not from the flash device configuration register)
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* wp: pointer to the variable to retreive the write protection status in
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
* wp: pointer to the variable holding the write protection status
|
||
|
* (enable = MV_TRUE, disable = MVFALSE)
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashWriteProtectGet(MV_MFLASH_INFO *pFlash, MV_BOOL * pWp)
|
||
|
{
|
||
|
MV_U32 reg;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* read the register and check the bit status */
|
||
|
reg = MV_REG_READ(MV_PMFLASH_IF_CFG_REG);
|
||
|
if (reg & MV_PMFLASH_WP_PROTECT_MASK)
|
||
|
*pWp = MV_FALSE;
|
||
|
else
|
||
|
*pWp = MV_TRUE;
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashSectorSizeSet - Set the sector size
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Set the sector size of the MFLASH main region
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* secSize: size of sector in bytes (either 4K or 32K)
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashSectorSizeSet (MV_MFLASH_INFO *pFlash, MV_U32 secSize)
|
||
|
{
|
||
|
MV_STATUS ret;
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
ret = mvPMFlashSectorSizeSet(pFlash, secSize);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
ret = mvSMFlashSectorSizeSet(pFlash, secSize);
|
||
|
else
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (ret != MV_OK)
|
||
|
return ret;
|
||
|
|
||
|
/* update the sector size and number in the structure */
|
||
|
switch (pFlash->flashModel)
|
||
|
{
|
||
|
case MV_MFLASH_SUNOL_1:
|
||
|
if (secSize == MV_MFLASH_SECTOR_SIZE_SMALL)
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_SMALL;
|
||
|
pFlash->sectorNumber = MV_MFLASH_SMALL_SEC_NUM_SUNOL_1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_BIG;
|
||
|
pFlash->sectorNumber = MV_MFLASH_BIG_SEC_NUM_SUNOL_1;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MV_MFLASH_SUNOL_2:
|
||
|
if (secSize == MV_MFLASH_SECTOR_SIZE_SMALL)
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_SMALL;
|
||
|
pFlash->sectorNumber = MV_MFLASH_SMALL_SEC_NUM_SUNOL_2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_BIG;
|
||
|
pFlash->sectorNumber = MV_MFLASH_BIG_SEC_NUM_SUNOL_2;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MV_MFLASH_SUNOL_3:
|
||
|
if (secSize == MV_MFLASH_SECTOR_SIZE_SMALL)
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_SMALL;
|
||
|
pFlash->sectorNumber = MV_MFLASH_SMALL_SEC_NUM_SUNOL_3;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pFlash->sectorSize = MV_MFLASH_SECTOR_SIZE_BIG;
|
||
|
pFlash->sectorNumber = MV_MFLASH_BIG_SEC_NUM_SUNOL_3;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
mvOsPrintf("%s ERROR: Unknown Flash Type!\n", __FUNCTION__);
|
||
|
return MV_NOT_SUPPORTED;
|
||
|
}
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashPrefetchSet - Set the Prefetch mode enable/disable
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Enable (MV_TRUE) or Disable (MV_FALSE) the prefetch mode
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* prefetch: enable/disable (MV_TRUE/MV_FALSE)
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashPrefetchSet (MV_MFLASH_INFO *pFlash, MV_BOOL prefetch)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashPrefetchSet(pFlash, prefetch);
|
||
|
|
||
|
DB(mvOsPrintf("%s WARNING: Invalid interface mode!\n", __FUNCTION__);)
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashShutdownSet - Shutdown the voltage regulator in the flash device
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Causes the device to enter in a power save mode untill the next access
|
||
|
* to the flash.
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashShutdownSet(MV_MFLASH_INFO *pFlash)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashShutdownSet(pFlash);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashShutdownSet(pFlash);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashIdGet - Retreive the MFlash's manufacturer and device IDs
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Read from the flash the 32bit manufacturer Id and the 16bit device ID
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
* pManfId: pointer to the 32bit variable to read the manufacturer ID in
|
||
|
* pDevId: pointer to the 16bit variable to read the device ID in
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* pManfId: pointer to the 32bit variable holding the manufacturer ID
|
||
|
* pDevId: pointer to the 16bit variable holding the device ID
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashIdGet (MV_MFLASH_INFO *pFlash, MV_U32 * pManfId, MV_U16 * pDevId)
|
||
|
{
|
||
|
/* check for NULL pointer */
|
||
|
if ((pFlash == NULL) || (pManfId == NULL) || (pDevId == NULL))
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
if (pFlash->ifMode == MV_MFLASH_PARALLEL)
|
||
|
return mvPMFlashIdGet(pFlash, pManfId, pDevId);
|
||
|
else if (pFlash->ifMode == MV_MFLASH_SPI)
|
||
|
return mvSMFlashIdGet(pFlash, pManfId, pDevId);
|
||
|
|
||
|
mvOsPrintf("%s ERROR: Invalid interface mode!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* mvMFlashReset - Reset the flash device and the MFlash glue logic
|
||
|
*
|
||
|
* DESCRIPTION:
|
||
|
* Perfom a hard reset for the Marvell Flash and the controller interface
|
||
|
*
|
||
|
* INPUT:
|
||
|
* pFlash: pointer to the MFlash information structure
|
||
|
*
|
||
|
* OUTPUT:
|
||
|
* None.
|
||
|
*
|
||
|
* RETURN:
|
||
|
* Success or Error code.
|
||
|
*
|
||
|
*
|
||
|
*******************************************************************************/
|
||
|
MV_STATUS mvMFlashReset(MV_MFLASH_INFO *pFlash)
|
||
|
{
|
||
|
MV_U32 reg;
|
||
|
|
||
|
/* check for NULL pointer */
|
||
|
if (pFlash == NULL)
|
||
|
{
|
||
|
mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
|
||
|
return MV_BAD_PARAM;
|
||
|
}
|
||
|
|
||
|
/* set both bits 4 and 5 */
|
||
|
reg = MV_REG_READ(MV_PMFLASH_IF_CFG_REG);
|
||
|
reg |= (MV_PMFLASH_RESET_MASK | MV_PMFLASH_IF_RESET_MASK);
|
||
|
MV_REG_WRITE(MV_PMFLASH_IF_CFG_REG, reg);
|
||
|
|
||
|
/* Insert a short delay */
|
||
|
mvOsDelay(1); /* 1ms */
|
||
|
|
||
|
/* reset both bits 4 and 5 */
|
||
|
reg = MV_REG_READ(MV_PMFLASH_IF_CFG_REG);
|
||
|
reg &= ~(MV_PMFLASH_RESET_MASK | MV_PMFLASH_IF_RESET_MASK);
|
||
|
MV_REG_WRITE(MV_PMFLASH_IF_CFG_REG, reg);
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|