#include "Fls.h"\r
/* Freescale driver */\r
#include "ssd_types.h"\r
+#if defined(CFG_MPC5606S)\r
+#include "ssd_c90fl.h"\r
+#else\r
#include "ssd_h7f.h"\r
+#endif\r
#include <stdlib.h>\r
#include <assert.h>\r
#include <string.h>\r
#endif\r
#include "Cpu.h"\r
#include "mpc55xx.h"\r
+#if defined(CFG_MPC5606S)\r
+#include "Fls_C90FL.h"\r
+#else\r
#include "Fls_H7F.h"\r
-\r
-\r
+#endif\r
/* Flash layout for MPC5516 */\r
/*\r
* Low: 8x16K + 2x64k\r
* Mid: 2x128K\r
* High: 8x128K\r
*/\r
-\r
+#if defined(CFG_MPC5606S)\r
+#define C90FL_REG_BASE (UINT32)&CFLASH0\r
+#define C90FL_CODE1_REG_BASE (UINT32)&CFLASH1\r
+#define C90FL_DATA_REG_BASE (UINT32)&DFLASH\r
+#else\r
#define H7F_REG_BASE (UINT32)&FLASH\r
+#endif\r
#define MAIN_ARRAY_BASE 0x00000000\r
\r
+#if defined(CFG_MPC5606S)\r
+#define MAIN_CODE1_ARRAY_BASE 0x00080000\r
+#define MAIN_DATA_ARRAY_BASE 0x00800000\r
+#endif\r
+\r
#ifdef CFG_MPC5516\r
#define SHADOW_ROW_BASE 0x00FF8000\r
#elif defined(CFG_MPC5567)\r
#define SHADOW_ROW_BASE 0x00FFFC00\r
+#elif defined(CFG_MPC5606S)\r
+#define SHADOW_ROW_BASE 0x00200000\r
#endif\r
\r
+#if defined(CFG_MPC5606S)\r
+#define SHADOW_ROW_SIZE 0x00004000\r
+#define FLASH_PAGE_SIZE C90FL_PAGE_SIZE_08\r
+#else\r
#define SHADOW_ROW_SIZE 0x00008000\r
#define FLASH_PAGE_SIZE H7FB_PAGE_SIZE\r
-\r
+#endif\r
#define FLASH_TOTAL_BLOCKS ( 20 )\r
\r
#if 0\r
int lengthOk=0;\\r
const Fls_SectorType* sectorPtr= &Fls_Global.config->FlsSectorList[0];\\r
for (i=0; i<Fls_Global.config->FlsSectorListSize;i++) {\\r
- if ((sectorPtr->FlsSectorStartaddress + (sectorPtr->FlsNumberOfSectors * sectorPtr->FlsSectorSize))>=(uint32_t)(_addr+(_length))){\\r
+ if ((_length!=0) && (sectorPtr->FlsSectorStartaddress + (sectorPtr->FlsNumberOfSectors * sectorPtr->FlsSectorSize))>=(uint32_t)(_addr+(_length))){\\r
lengthOk=1;\\r
}\\r
sectorPtr++;\\r
return _rv; \\r
}\r
\r
+#define FLS_VALIDATE_STATUS_UNINIT(_status, _api)\\r
+ if (MEMIF_UNINIT == _status){\\r
+ Det_ReportError(MODULE_ID_FLS,0,_api,FLS_E_UNINIT); \\r
+ return; \\r
+ }\r
+\r
#define FLS_VALIDATE_STATUS_UNINIT_W_RV(_status, _api, _rv)\\r
if (MEMIF_UNINIT == _status){\\r
Det_ReportError(MODULE_ID_FLS,0,_api,FLS_E_UNINIT); \\r
}\r
\r
#define FLS_VALIDATE_PARAM_DATA_W_RV(_ptr,_api, _rv) \\r
- if(( (uint32)(_ptr)%FLS_READ_PAGE_SIZE != 0 ) || ( (_ptr)==((void *)0))) { \
+ if(( (uint32)(_ptr)%FLS_READ_PAGE_SIZE != 0 ) || ( (_ptr)==((void *)0))) { \\r
Det_ReportError(MODULE_ID_FLS,0,_api,FLS_E_PARAM_DATA); \\r
return _rv; \\r
}\r
\r
\r
SSD_CONFIG ssdConfig = {\r
- H7F_REG_BASE, /* H7F control register base */\r
- MAIN_ARRAY_BASE, /* base of main array */\r
+#if defined(CFG_MPC5606S)\r
+ C90FL_REG_BASE, /* C90FL Flash control register base */\r
+#else\r
+ H7F_REG_BASE, /* H7F control register base */\r
+#endif\r
+ MAIN_ARRAY_BASE, /* base of main array */\r
0, /* size of main array */\r
SHADOW_ROW_BASE, /* base of shadow row */\r
SHADOW_ROW_SIZE, /* size of shadow row */\r
FALSE, /* debug mode selection */\r
};\r
\r
+#if defined(CFG_MPC5606S)\r
+SSD_CONFIG ssdCode1Config = {\r
+ C90FL_CODE1_REG_BASE, /* C90FL Data Flash control register base */\r
+ MAIN_CODE1_ARRAY_BASE, /* base of main array */\r
+ 0, /* size of main array */\r
+ 0, /* base of shadow row. Not available on DFlash */\r
+ 0, /* size of shadow row. Not available on DFlash */\r
+ 0, /* block number in low address space */\r
+ 0, /* block number in middle address space */\r
+ 0, /* block number in high address space */\r
+ FLASH_PAGE_SIZE, /* flash page size selection */\r
+ FALSE /* debug mode selection */\r
+};\r
+\r
+SSD_CONFIG ssdDataConfig = {\r
+ C90FL_DATA_REG_BASE, /* C90FL Data Flash control register base */\r
+ MAIN_DATA_ARRAY_BASE, /* base of main array */\r
+ 0, /* size of main array */\r
+ 0, /* base of shadow row. Not available on DFlash */\r
+ 0, /* size of shadow row. Not available on DFlash */\r
+ 0, /* block number in low address space */\r
+ 0, /* block number in middle address space */\r
+ 0, /* block number in high address space */\r
+ FLASH_PAGE_SIZE, /* flash page size selection */\r
+ FALSE /* debug mode selection */\r
+};\r
+#endif\r
+\r
static Std_VersionInfoType _Fls_VersionInfo = {\r
.vendorID = (uint16)1,\r
.moduleID = (uint16) MODULE_ID_FLS,\r
static uint32 address_to_block( uint32 addr, uint32 *rem ) {\r
uint32 block;\r
\r
+#if defined(CFG_MPC5606S)\r
+ /* CFLASH0 */\r
+ if( addr < 0x80000 ) {\r
+ if ( addr < 0x8000) {\r
+ block = addr / 0x8000;\r
+ *rem = addr % 0x8000;\r
+ } else if ( addr < 0x10000) {\r
+ block = 1 + ( addr - 0x8000 ) / 0x4000;\r
+ *rem = addr % 0x4000;\r
+ } else if ( addr < 0x20000 ) {\r
+ block = 3 + ( addr - 0x10000 ) / 0x8000;\r
+ *rem = addr % 0x8000;\r
+ } else {\r
+ block = 5 + ( addr - 0x20000 ) / 0x20000;\r
+ *rem = addr % 0x20000;\r
+ }\r
+ }\r
+ /* CFLASH1 */\r
+ else if( addr < 0x100000 ) {\r
+ block = (addr - 0x80000) / 0x20000;\r
+ *rem = (addr - 0x80000) % 0x20000;\r
+ }\r
+ /* DFLASH */\r
+ else if (( addr >= 0x800000 )&(addr < 0x810000)) {\r
+ block = (addr - 0x800000) / 0x4000;\r
+ *rem = (addr - 0x800000) % 0x4000;\r
+ }\r
+ else {\r
+ block = (-1);\r
+ *rem = (-1);\r
+ }\r
+\r
+\r
+#else\r
if( addr < 0x20000) {\r
// Low range, 8x16K\r
block = addr / 0x4000;\r
block = (-1);\r
*rem = (-1);\r
}\r
+#endif\r
return block;\r
}\r
\r
mask2 = ((-1UL)>>startBlock)<<startBlock;\r
mask = mask1 & mask2;\r
\r
-\r
+#if defined( MPC5606S )\r
+ eraseBlocks->lowEnabledBlocks = mask&0xffff; // Bits 0..15 indicats low blocks\r
+ eraseBlocks->midEnabledBlocks = (mask>>16)&3; // Bits 16..17 indicats mid blocks\r
+ eraseBlocks->highEnabledBlocks = mask>>18; // Bits 18..23 indicats high blocks\r
+#else\r
// shift things in to make freescale driver happy\r
- eraseBlocks->lowEnabledBlocks = mask&0x3ff; // Bits 0..9 indicats low blocks
- eraseBlocks->midEnabledBlocks = (mask>>10)&3; // Bits 10..11 indicats mid blocks
- eraseBlocks->highEnabledBlocks = mask>>12; // Bits 12..19 indicats high blocks
-\r
+ eraseBlocks->lowEnabledBlocks = mask&0x3ff; // Bits 0..9 indicats low blocks\r
+ eraseBlocks->midEnabledBlocks = (mask>>10)&3; // Bits 10..11 indicats mid blocks\r
+ eraseBlocks->highEnabledBlocks = mask>>12; // Bits 12..19 indicats high blocks\r
+#endif\r
\r
return ;\r
}\r
\r
\r
returnCode = FlashInit( &ssdConfig );\r
+#if defined( CFG_MPC5606S )\r
+ returnCode = FlashInit( &ssdCode1Config );\r
+ returnCode = FlashInit( &ssdDataConfig );\r
+#endif\r
\r
// Lock shadow row..\r
eraseBlocks.lowEnabledBlocks = 0;\r
eraseBlocks.highEnabledBlocks = 0;\r
eraseBlocks.shadowBlocks = 1;\r
\r
+#if defined(CFG_MPC5606S)\r
+ Fls_C90FL_SetLock(&ssdConfig,&eraseBlocks,1);\r
+#else\r
Fls_H7F_SetLock(&eraseBlocks,1);\r
+#endif\r
\r
Fls_Global.status = MEMIF_IDLE;\r
Fls_Global.jobResultType = MEMIF_JOB_OK;\r
\r
eraseBlock.shadowBlocks = 0;\r
// Unlock\r
- Fls_H7F_SetLock(&eraseBlock,0);\r
\r
+#if defined( CFG_MPC5606S )\r
+ if ( TargetAddress < 0x80000 ) {\r
+ Fls_C90FL_SetLock(&ssdConfig, &eraseBlock,0);\r
+ }\r
+ else if ( TargetAddress < 0x100000 ){\r
+ Fls_C90FL_SetLock(&ssdCode1Config, &eraseBlock,0);\r
+ }\r
+ else {\r
+ Fls_C90FL_SetLock(&ssdDataConfig, &eraseBlock,0);\r
+ }\r
+#else\r
+ Fls_H7F_SetLock(&eraseBlock,0);\r
+#endif\r
eraseInfo.state = 0; // Always set this\r
\r
\r
+#if defined( CFG_MPC5606S )\r
+ Fls_Global.sourceAddr = TargetAddress;\r
+\r
+ if ( TargetAddress < 0x80000 ) {\r
+ Fls_C90FL_FlashErase ( &ssdConfig ,\r
+ 0, // shadowFlag...\r
+ eraseBlock.lowEnabledBlocks,\r
+ eraseBlock.midEnabledBlocks,\r
+ eraseBlock.highEnabledBlocks,\r
+ &eraseInfo\r
+ );\r
+ }\r
+ else if ( TargetAddress < 0x100000 ){\r
+ Fls_C90FL_FlashErase ( &ssdCode1Config ,\r
+ 0, // shadowFlag...\r
+ eraseBlock.lowEnabledBlocks,\r
+ eraseBlock.midEnabledBlocks,\r
+ eraseBlock.highEnabledBlocks,\r
+ &eraseInfo\r
+ );\r
+ }\r
+ else {\r
+ Fls_C90FL_FlashErase ( &ssdDataConfig ,\r
+ 0, // shadowFlag...\r
+ eraseBlock.lowEnabledBlocks,\r
+ eraseBlock.midEnabledBlocks,\r
+ eraseBlock.highEnabledBlocks,\r
+ &eraseInfo\r
+ );\r
+ }\r
\r
+#else\r
Fls_H7F_FlashErase ( &ssdConfig ,\r
0, // shadowFlag...\r
eraseBlock.lowEnabledBlocks,\r
eraseBlock.highEnabledBlocks,\r
&eraseInfo\r
);\r
+#endif\r
return E_OK;\r
}\r
\r
// unlock flash....\r
address_to_erase_blocks(&eraseBlock,TargetAddress,Length);\r
eraseBlock.shadowBlocks = 0;\r
- Fls_H7F_SetLock(&eraseBlock,0);\r
\r
+#if defined( CFG_MPC5606S )\r
+ if ( TargetAddress < 0x80000 ) {\r
+ Fls_C90FL_SetLock(&ssdConfig, &eraseBlock,0);\r
+ }\r
+ else if ( TargetAddress < 0x100000 ){\r
+ Fls_C90FL_SetLock(&ssdCode1Config, &eraseBlock,0);\r
+ }\r
+ else {\r
+ Fls_C90FL_SetLock(&ssdDataConfig, &eraseBlock,0);\r
+ }\r
+#else\r
+ Fls_H7F_SetLock(&eraseBlock,0);\r
+#endif\r
return E_OK;\r
}\r
\r
}\r
#endif\r
\r
+\r
void Fls_MainFunction( void )\r
{\r
uint32 flashStatus;\r
int result;\r
+\r
+ FLS_VALIDATE_STATUS_UNINIT(Fls_Global.status, FLS_ERASE_ID);\r
+\r
if( Fls_Global.jobResultType == MEMIF_JOB_PENDING ) {\r
switch(Fls_Global.jobType) {\r
case FLS_JOB_COMPARE:\r
if( result == 0 ) {\r
Fls_Global.jobResultType = MEMIF_JOB_OK;\r
} else {\r
- Fls_Global.jobResultType = MEMIF_JOB_FAILED;\r
+ Fls_Global.jobResultType = MEMIF_BLOCK_INCONSISTENT;\r
}\r
Fls_Global.status = MEMIF_IDLE;\r
Fls_Global.jobType = FLS_JOB_NONE;\r
{\r
// uint32 failAddress;\r
// uint32 failData;\r
-\r
+#if defined(CFG_MPC5606S)\r
+ if ( Fls_Global.sourceAddr < 0x80000 ) {\r
+ flashStatus = Fls_C90FL_EraseStatus(&ssdConfig);\r
+ }\r
+ else if ( Fls_Global.sourceAddr < 0x100000 ){\r
+ flashStatus = Fls_C90FL_EraseStatus(&ssdCode1Config);\r
+ }\r
+ else {\r
+ flashStatus = Fls_C90FL_EraseStatus(&ssdDataConfig);\r
+ }\r
+ if( flashStatus == C90FL_OK ) {\r
+ Fls_EraseBlockType blocks;\r
+ // Lock all.\r
+ blocks.highEnabledBlocks = (-1UL);\r
+ blocks.midEnabledBlocks = (-1UL);\r
+ blocks.highEnabledBlocks = (-1UL);\r
+ blocks.shadowBlocks = (-1UL);\r
+\r
+ if ( Fls_Global.sourceAddr < 0x80000 ) {\r
+ Fls_C90FL_SetLock(&ssdConfig, &blocks,1);\r
+ }\r
+ else if ( Fls_Global.sourceAddr < 0x100000 ){\r
+ Fls_C90FL_SetLock(&ssdCode1Config, &blocks,1);\r
+ }\r
+ else {\r
+ Fls_C90FL_SetLock(&ssdDataConfig, &blocks,1);\r
+ }\r
+ Fls_Global.jobResultType = MEMIF_JOB_OK;\r
+ Fls_Global.jobType = FLS_JOB_NONE;\r
+ Fls_Global.status = MEMIF_IDLE;\r
+ FEE_JOB_END_NOTIFICATION();\r
+ } else if( flashStatus == C90FL_BUSY ) {\r
+ /* Busy, Do nothing */\r
+ } else {\r
+ // Error\r
+ Fls_Global.jobResultType = MEMIF_JOB_FAILED;\r
+ Fls_Global.jobType = FLS_JOB_NONE;\r
+ Fls_Global.status = MEMIF_IDLE;\r
+ #if defined(USE_DEM)\r
+ Dem_ReportErrorStatus(FLS_E_WRITE_FAILED, DEM_EVENT_STATUS_FAILED);\r
+ #endif\r
+ FEE_JOB_ERROR_NOTIFICATION();\r
+ }\r
+#else\r
flashStatus = Fls_H7F_EraseStatus(&ssdConfig);\r
if( flashStatus == H7F_OK ) {\r
Fls_EraseBlockType blocks;\r
#endif\r
FEE_JOB_ERROR_NOTIFICATION();\r
}\r
+#endif\r
break;\r
}\r
case FLS_JOB_READ:\r
case FLS_JOB_WRITE:\r
{\r
// NOT implemented. Hardware error = FLS_E_READ_FAILED\r
-\r
+#if defined(CFG_MPC5606S)\r
+ if ( Fls_Global.flashWriteInfo.dest < 0x80000) {\r
+ flashStatus = Fls_C90FL_Program( &ssdConfig,&Fls_Global.flashWriteInfo);\r
+ }\r
+ else if ( Fls_Global.flashWriteInfo.dest < 0x100000) {\r
+ flashStatus = Fls_C90FL_Program( &ssdCode1Config,&Fls_Global.flashWriteInfo);\r
+ }\r
+ else {\r
+ flashStatus = Fls_C90FL_Program( &ssdDataConfig,&Fls_Global.flashWriteInfo);\r
+ }\r
+ if( flashStatus == C90FL_OK ) {\r
+ Fls_EraseBlockType blocks;\r
+ blocks.highEnabledBlocks = (-1UL);\r
+ blocks.midEnabledBlocks = (-1UL);\r
+ blocks.highEnabledBlocks = (-1UL);\r
+ blocks.shadowBlocks = (-1UL);\r
+\r
+ // Lock all\r
+ if ( Fls_Global.flashWriteInfo.dest < 0x80000 ) {\r
+ Fls_C90FL_SetLock(&ssdConfig, &blocks,1);\r
+ }\r
+ else if ( Fls_Global.flashWriteInfo.dest < 0x100000 ){\r
+ Fls_C90FL_SetLock(&ssdCode1Config, &blocks,1);\r
+ }\r
+ else {\r
+ Fls_C90FL_SetLock(&ssdDataConfig, &blocks,1);\r
+ }\r
+\r
+ Fls_Global.jobResultType = MEMIF_JOB_OK;\r
+ Fls_Global.jobType = FLS_JOB_NONE;\r
+ Fls_Global.status = MEMIF_IDLE;\r
+ FEE_JOB_END_NOTIFICATION();\r
+ } else if( flashStatus == C90FL_BUSY ) {\r
+ /* Busy, Do nothing */\r
+ } else {\r
+ // Error\r
+ Fls_Global.jobResultType = MEMIF_JOB_FAILED;\r
+ Fls_Global.jobType = FLS_JOB_NONE;\r
+ Fls_Global.status = MEMIF_IDLE;\r
+ #if defined(USE_DEM)\r
+ Dem_ReportErrorStatus(FLS_E_WRITE_FAILED, DEM_EVENT_STATUS_FAILED);\r
+ #endif\r
+ FEE_JOB_ERROR_NOTIFICATION();\r
+ }\r
+#else\r
flashStatus = Fls_H7F_Program( &ssdConfig,&Fls_Global.flashWriteInfo);\r
\r
if( flashStatus == H7F_OK ) {\r
#endif\r
FEE_JOB_ERROR_NOTIFICATION();\r
}\r
-\r
+#endif\r
break;\r
}\r
case FLS_JOB_NONE:\r
}\r
}\r
\r
+\r
Std_ReturnType Fls_Read ( Fls_AddressType SourceAddress,\r
uint8 *TargetAddressPtr,\r
Fls_LengthType Length )\r
}\r
#endif\r
\r
+#if ( FLS_VERSION_INFO_API == STD_ON )\r
void Fls_GetVersionInfo( Std_VersionInfoType *VersioninfoPtr )\r
{\r
memcpy(VersioninfoPtr, &_Fls_VersionInfo, sizeof(Std_VersionInfoType));\r
}\r
+#endif\r
\r
void Fls_Check( uint32 flsBaseAddress, uint32 flsTotalSize )\r
{\r
// Enable Flash Non_Correctible Reporting,\r
// Not really necessary but makes more information\r
// available in the MCM registers if an error occurs.\r
+#if defined(CFG_MPC5606S)\r
+ ECSM.ECR.B.EFNCR = 1;\r
+#else\r
MCM.ECR.B.EFNCR = 1;\r
+#endif\r
\r
// Read flash in 32bit chunks, it's most efficient.\r
uint32* memoryChunkPtr = (uint32*)flsBaseAddress;\r
--- /dev/null
+\r
+/*************************************************************************\r
+ * (c) Copyright Motorola 2005, All Rights Reserved *\r
+ *************************************************************************\r
+ * *\r
+ * Motorola reserves the right to make changes without further notice *\r
+ * to any product herein to improve reliability, function or design. *\r
+ * Motorola does not assume any liability arising out of the *\r
+ * application or use of any product, circuit, or software described *\r
+ * herein; neither does it convey any license under its patent rights *\r
+ * nor the rights of others. *\r
+ * *\r
+ * Motorola products are not designed, intended, or authorized for *\r
+ * use as components in systems intended for surgical implant into *\r
+ * the body, or other applications intended to support life, or for *\r
+ * any other application in which the failure of the Motorola product *\r
+ * could create a situation where personal injury or death may occur. *\r
+ * *\r
+ * Should Buyer purchase or use Motorola products for any such *\r
+ * unintended or unauthorized application, Buyer shall indemnify and *\r
+ * hold Motorola and its officers, employees, subsidiaries, *\r
+ * affiliates, and distributors harmless against all claims costs, *\r
+ * damages, and expenses, and reasonable attorney fees arising out *\r
+ * of, directly or indirectly, any claim of personal injury or death *\r
+ * associated with such unintended or unauthorized use, even if such *\r
+ * claim alleges that Motorola was negligent regarding the design *\r
+ * or manufacture of the part. *\r
+ * *\r
+ * Motorola and the Motorola logo* are registered trademarks of *\r
+ * Motorola Ltd. *\r
+ * *\r
+ *************************************************************************/\r
+\r
+/* This file is a a copy and modification of a freescale driver */\r
+\r
+#include "ssd_types.h"\r
+#include "ssd_c90fl.h"\r
+#include <string.h>\r
+#include <assert.h>\r
+#include "Fls_C90FL.h"\r
+#include "mpc55xx.h"\r
+\r
+\r
+#define CFLASH_BASE_ADDR (UINT32)(0xC3F88000)\r
+#define CFLASH1_BASE_ADDR (UINT32)(0xC3FB0000)\r
+#define DFLASH_BASE_ADDR (UINT32)(0xC3F8C000)\r
+#define C1_BASE_ADDR (UINT32)(0xC3FB0000)\r
+#define C2_BASE_ADDR (UINT32)(0xC3FB4000)\r
+\r
+\r
+UINT32 FlashInit ( PSSD_CONFIG pSSDConfig )\r
+{\r
+ register UINT32 returnCode; /* return code */\r
+ UINT32 MCRAddress; /* address of C90FLMCR register */\r
+ UINT32 MCRValue; /* content of C90FLMCR register */\r
+ UINT32 temp; /* temporary variable */\r
+\r
+ MCRAddress = pSSDConfig->c90flRegBase + C90FL_MCR;\r
+ MCRValue = C90FL_REG_READ (MCRAddress);\r
+\r
+ if(CFLASH1_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ MCRValue = 0x02100600;\r
+ }\r
+ returnCode = C90FL_OK;\r
+\r
+ /* Check MCR-EER and MCR-RWE bits */\r
+ returnCode = (MCRValue & (C90FL_MCR_EER|C90FL_MCR_RWE)) >> 14;\r
+ if (returnCode)\r
+ {\r
+ /* Clear EER and RWE bits are set in MCR register */\r
+ C90FL_REG_BIT_SET(MCRAddress,(C90FL_MCR_EER|C90FL_MCR_RWE));\r
+ }\r
+\r
+ pSSDConfig->lowBlockNum = 0;\r
+ pSSDConfig->midBlockNum = 0;\r
+ pSSDConfig->highBlockNum = 0;\r
+\r
+ /* Number of blocks in low address space and fill into SSD_CONFIG structure */\r
+ temp = (MCRValue & C90FL_MCR_LAS) >> 20;\r
+\r
+ /**************************************************************************\r
+ * Number of blocks in low address space and fill into SSD_CONFIG structure\r
+ * LAS = 0: lowBlockNum = 0; Sectorization = 0\r
+ * LAS = 1: lowBlockNum = 2; Sectorization = 2x128K\r
+ * LAS = 2: lowBlockNum = 6; Sectorization = 32K+2x16K+2x32K+128K\r
+ * LAS = 3: lowBlockNum = Res; Sectorization = n.a\r
+ * LAS = 4: lowBlockNum = Res; Sectorization = n.a\r
+ * LAS = 5: lowBlockNum = Res; Sectorization = n.a\r
+ * LAS = 6: lowBlockNum = 4; Sectorization = 4x16K\r
+ * LAS = 7: lowBlockNum = 8; Sectorization = 2x16K+2x32K+2x16K+2x64K\r
+ **************************************************************************/\r
+ switch(temp)\r
+ {\r
+ case 1:\r
+ pSSDConfig->lowBlockNum = 2;\r
+ break;\r
+ case 2:\r
+ pSSDConfig->lowBlockNum = 6;\r
+ break;\r
+ case 6:\r
+ pSSDConfig->lowBlockNum = 4;\r
+ break;\r
+ case 7:\r
+ pSSDConfig->lowBlockNum = 8;\r
+ break;\r
+ }\r
+\r
+ /* Find main array size and fill into SSD_CONFIG structure */\r
+ temp = (MCRValue & C90FL_MCR_SIZE) >> 24;\r
+\r
+ /**************************************************************************\r
+ * Get Main array size and fill into SSD_CONFIG structure\r
+ * Size = 0: Main Array Size = 128KB;\r
+ * Size = 1: Main Array Size = 256KB;\r
+ * Size = 2: Main Array Size = 512KB;\r
+ * Size = 3: Main Array Size = 1MB;\r
+ * Size = 4: Main Array Size = 1.5MB;\r
+ * Size = 5: Main Array Size = 2MB;\r
+ * Size = 6: Main Array Size = 64KB;\r
+ * Size = 7: Main Array Size = Reserved;\r
+ **************************************************************************/\r
+ switch(temp)\r
+ {\r
+ /* case 0:\r
+ temp = 0x20000;\r
+ break;*/\r
+ case 1:\r
+ temp = 0x40000;\r
+ break;\r
+ case 2:\r
+ temp = 0x80000;\r
+ break;\r
+ case 3:\r
+ temp = 0x100000;\r
+ break;\r
+ case 4:\r
+ temp = 0x180000;\r
+ break;\r
+ /* case 5:\r
+ temp = 0x200000;\r
+ break; */\r
+ case 6:\r
+ temp = 0x10000;\r
+ break;\r
+ }\r
+\r
+ /*update Main Array size in SSD config*/\r
+ pSSDConfig->mainArraySize = temp;\r
+\r
+ /**************************************************************************\r
+ * Number of blocks in middle address space and fill into SSD_CONFIG structure\r
+ *\r
+ * C Flash\r
+ * MAS = 0: midBlockNum = 2; Sectorization = 2x128K\r
+ * MAS = 1: midBlockNum = Res; Sectorization = n.a\r
+ *\r
+ * D Flash\r
+ * MAS = 0: midBlockNum = 0; Sectorization = 0\r
+ * MAS = 1: midBlockNum = Res; Sectorization = n.a\r
+ *\r
+ **************************************************************************/\r
+\r
+ /* Determine the number of blocks in middle address space and fill into\r
+ SSD_CONFIG structure.\r
+ */\r
+ if ((UINT32)0x0 == (MCRValue & C90FL_MCR_MAS))\r
+ {\r
+ if(CFLASH_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ pSSDConfig->midBlockNum = 2;\r
+ }\r
+\r
+ if(DFLASH_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ pSSDConfig->midBlockNum = 0;\r
+ }\r
+ }\r
+\r
+ if ( temp > (UINT32)0x00080000 )\r
+ {\r
+ /* (mainArraySize - 512K) / 128K */\r
+ pSSDConfig->highBlockNum = (temp - (UINT32)0x00080000) >> 17;\r
+ }\r
+\r
+#if 0\r
+ /* For C1 and C2 flash array all blocks below to high address space !!!*/\r
+ if((C1_BASE_ADDR == pSSDConfig->c90flRegBase) ||\r
+ (C2_BASE_ADDR == pSSDConfig->c90flRegBase))\r
+ {\r
+ pSSDConfig->lowBlockNum = 0;\r
+ pSSDConfig->midBlockNum = 0;\r
+ pSSDConfig->highBlockNum = 4;\r
+ }\r
+#endif\r
+\r
+ if (pSSDConfig->BDMEnable)\r
+ {\r
+ //asm ( "mr r3,returnCode" ); /* save the return code to R3 */\r
+ #ifdef VLE_ASM\r
+ asm ( "se_sc " ); /* generate system call interrupt */\r
+ #else\r
+ asm ( "sc " );\r
+ #endif\r
+ }\r
+\r
+ return returnCode;\r
+}\r
+\r
+\r
+#define ERASE_STATE_START 0\r
+#define ERASE_STATE_ERASING 1\r
+\r
+\r
+UINT32 Fls_C90FL_FlashErase ( PSSD_CONFIG pSSDConfig,\r
+ BOOL shadowFlag,\r
+ UINT32 lowEnabledBlocks,\r
+ UINT32 midEnabledBlocks,\r
+ UINT32 highEnabledBlocks,\r
+ Fls_EraseInfoType *eraseInfo)\r
+{\r
+ register UINT32 returnCode; /* return code */\r
+ UINT32 c90flRegBase; /* base address of C90FL registers */\r
+ UINT32 MCRAddress; /* address of C90FLMCR register */\r
+ UINT32 LMSAddress; /* address of C90FLLMS register */\r
+ UINT32 MCRValue; /* content of C90FLMCR register */\r
+ UINT32 interlockWriteAddress; /* interlock write address */\r
+\r
+\r
+ if( eraseInfo->state == ERASE_STATE_ERASING ) {\r
+ UINT32 status;\r
+ status = Fls_C90FL_EraseStatus(pSSDConfig);\r
+ if( status == C90FL_OK )\r
+ eraseInfo->state = ERASE_STATE_START;\r
+\r
+ return status;\r
+ }\r
+\r
+\r
+ c90flRegBase = pSSDConfig->c90flRegBase;\r
+ MCRAddress = c90flRegBase + C90FL_MCR;\r
+ MCRValue = C90FL_REG_READ (MCRAddress);\r
+ LMSAddress = c90flRegBase + C90FL_LMS;\r
+\r
+ /* program and/or erase operation in progress */\r
+ if (MCRValue & (C90FL_MCR_PGM | C90FL_MCR_ERS))\r
+ {\r
+ returnCode = C90FL_ERROR_BUSY;\r
+ goto EXIT;\r
+ }\r
+\r
+ /* interlock write address: shadow row block key address */\r
+ /* it will be modified to mainArrayBase in case of erasing main array */\r
+ if((UINT32)0x0 != pSSDConfig->shadowRowBase)\r
+ {\r
+ interlockWriteAddress = pSSDConfig->shadowRowBase + 0xE0;\r
+ }\r
+\r
+ /* initialize returnCode */\r
+ returnCode = C90FL_OK;\r
+\r
+ if (!shadowFlag)\r
+ {\r
+ /* erase the main array blocks */\r
+ interlockWriteAddress = pSSDConfig->mainArrayBase;\r
+\r
+ /* mask off reserved bits for low address space */\r
+ lowEnabledBlocks &= 0xFFFFFFFF >> (32 - pSSDConfig->lowBlockNum);\r
+\r
+ /* mask off reserved bits for mid address space */\r
+ lowEnabledBlocks |= (midEnabledBlocks & (0xFFFFFFFF >> (32 - pSSDConfig->midBlockNum))) << 16;\r
+\r
+ /* mask off reserved bits for high address space */\r
+ highEnabledBlocks &= 0xFFFFFFFF >> (32 - pSSDConfig->highBlockNum);\r
+\r
+ if ( !(lowEnabledBlocks | highEnabledBlocks) )\r
+ {\r
+ /* no blocks to be erased */\r
+ goto EXIT;\r
+ }\r
+\r
+ /* set the block selection registers */\r
+ C90FL_REG_WRITE (LMSAddress, lowEnabledBlocks);\r
+ C90FL_REG_WRITE (c90flRegBase + C90FL_HBS, highEnabledBlocks);\r
+ }\r
+ else\r
+ {\r
+ if((UINT32)0x0 == pSSDConfig->shadowRowBase)\r
+ {\r
+ /* Shadow block erase has been requested but there is no shadow block */\r
+ goto EXIT;\r
+ }\r
+ }\r
+\r
+ /* set MCR-ERS to start erase operation */\r
+ C90FLMCR_BIT_SET (MCRAddress, C90FL_MCR_ERS);\r
+\r
+ /* interlock write */\r
+ *( (UINT32 *)interlockWriteAddress ) = 0xFFFFFFFF;\r
+\r
+ /* write a 1 to MCR-EHV */\r
+ C90FLMCR_BIT_SET (MCRAddress, C90FL_MCR_EHV);\r
+\r
+ /* This is where the freescale driver ends */\r
+ eraseInfo->state = ERASE_STATE_ERASING;\r
+\r
+\r
+EXIT:\r
+ if (pSSDConfig->BDMEnable)\r
+ {\r
+ //asm ( "mr r3,returnCode" ); /* save the return code to R3 */\r
+ asm ( "sc " ); /* generate system call interrupt */\r
+ }\r
+\r
+ return returnCode;\r
+}\r
+\r
+\r
+\r
+UINT32 Fls_C90FL_EraseStatus ( PSSD_CONFIG pSSDConfig )\r
+{\r
+\r
+ UINT32 c90flRegBase; /* base address of C90FL registers */\r
+ UINT32 MCRAddress; /* address of C90FLMCR register */\r
+ UINT32 pfb_cr_val; /* value of PFB_CR register */\r
+ UINT32 returnCode;\r
+\r
+ c90flRegBase = pSSDConfig->c90flRegBase;\r
+ MCRAddress = c90flRegBase + C90FL_MCR;\r
+\r
+ returnCode = C90FL_OK;\r
+\r
+ /* wait until MCR-DONE set */\r
+ if( !(C90FL_REG_READ (MCRAddress) & C90FL_MCR_DONE) )\r
+ {\r
+ return 0x1000; // Ehh, busy\r
+ }\r
+\r
+ /* clear MCR-EHV bit */\r
+ C90FLMCR_BIT_CLEAR (MCRAddress, C90FL_MCR_EHV);\r
+\r
+ /* confirm MCR-PEG = 1 */\r
+ if ( !(C90FL_REG_READ (MCRAddress) & C90FL_MCR_PEG) )\r
+ {\r
+ returnCode = C90FL_ERROR_EGOOD;\r
+ }\r
+\r
+ if(DFLASH_BASE_ADDR != pSSDConfig->c90flRegBase) /* CFLASH */\r
+ {\r
+ /* save PFB_CR */\r
+ pfb_cr_val = C90FL_REG_READ(CFLASH_BASE_ADDR + PFB_CR);\r
+\r
+ /* Invalidate the PFBIU line read buffer */\r
+ C90FL_REG_BIT_CLEAR (CFLASH_BASE_ADDR + PFB_CR, PFB_CR_BFEN);\r
+\r
+ /* clear MCR-ERS bit */\r
+ C90FLMCR_BIT_CLEAR (MCRAddress, C90FL_MCR_ERS);\r
+\r
+ /* restore PFB_CR */\r
+ C90FL_REG_WRITE(CFLASH_BASE_ADDR + PFB_CR, pfb_cr_val);\r
+ }\r
+\r
+ if(DFLASH_BASE_ADDR == pSSDConfig->c90flRegBase) /* DFLASH */\r
+ {\r
+ /* save PFB_CR1 */\r
+ pfb_cr_val = C90FL_REG_READ(CFLASH_BASE_ADDR + PFB_CR1);\r
+\r
+ /* Invalidate the PFBIU holding register */\r
+ C90FL_REG_BIT_CLEAR (CFLASH_BASE_ADDR + PFB_CR1, PFB_CR_BFEN);\r
+\r
+ /* clear MCR-ERS bit */\r
+ C90FLMCR_BIT_CLEAR (MCRAddress, C90FL_MCR_ERS);\r
+\r
+ /* restore PFB_CR1 */\r
+ C90FL_REG_WRITE(CFLASH_BASE_ADDR + PFB_CR1, pfb_cr_val);\r
+ }\r
+//EXIT:\r
+ if (pSSDConfig->BDMEnable)\r
+ {\r
+ //asm ( "mr r3,returnCode" ); /* save the return code to R3 */\r
+ asm ( "sc " ); /* generate system call interrupt */\r
+ }\r
+\r
+ return returnCode;\r
+}\r
+\r
+\r
+// First state.... init stuff\r
+#define STATE_INIT 0\r
+//\r
+#define STATE_PROGRAMMING 1\r
+//#define STATE_WAIT_DONE 2\r
+\r
+#if 0\r
+UINT32 FlashProgram ( PSSD_CONFIG pSSDConfig,\r
+ UINT32 dest,\r
+ UINT32 size,\r
+ UINT32 source,\r
+ void(*CallBack)(void)\r
+ )\r
+#endif\r
+\r
+\r
+#define MY_BUSY 0x1000\r
+\r
+static UINT32 Fls_C90FL_ProgramPage( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo );\r
+static UINT32 Fls_C90FL_ProgramStatus ( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo );\r
+static UINT32 Fls_C90FL_ProgramInit( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo );\r
+\r
+UINT32 Fls_C90FL_Program ( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo )\r
+{\r
+ UINT32 returnCode; /* return code */\r
+\r
+ switch( pInfo->state ) {\r
+ case STATE_INIT:\r
+ returnCode = Fls_C90FL_ProgramInit(pSSDConfig,pInfo);\r
+ if( returnCode == C90FL_OK ) {\r
+ returnCode = Fls_C90FL_ProgramPage(pSSDConfig,pInfo);\r
+ }\r
+ pInfo->state = STATE_PROGRAMMING;\r
+ break;\r
+ case STATE_PROGRAMMING:\r
+ returnCode = Fls_C90FL_ProgramStatus(pSSDConfig,pInfo);\r
+ break;\r
+ default:\r
+ returnCode = 0;\r
+ assert(0);\r
+ break;\r
+ }\r
+\r
+ return returnCode;\r
+}\r
+\r
+static UINT32 Fls_C90FL_ProgramInit( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo ) {\r
+\r
+\r
+ UINT32 returnCode;\r
+ // UINT32 sourceIndex; /* source address index */\r
+ UINT32 MCRAddress; /* address of C90FLMCR register */\r
+ UINT32 MCRValue; /* content of C90FLMCR register */\r
+\r
+ UINT32 shadowRowEnd; /* shadow row base + shadow size */\r
+ UINT32 mainArrayEnd; /* main array base + main array size */\r
+ // UINT32 temp; /* dest + size, or size / C90FL_DWORD_SIZE */\r
+ // UINT32 pageSize; /* page size depending on flash type */\r
+\r
+ UINT8 rangeType; /* position of the program memory range */\r
+ /* rangeType = 1 - shadow row */\r
+ /* rangeType = 2 - main array */\r
+\r
+ // UINT32 pfb_cr_val; /* value of PFB_CR register */\r
+ returnCode = C90FL_OK;\r
+ pInfo->pageSize = 16; /* default setting is 16 bytes */\r
+ MCRAddress = pSSDConfig->c90flRegBase + C90FL_MCR;\r
+\r
+ /* Check alignments */\r
+ if ( (((pInfo->dest | pInfo->size) % C90FL_DWORD_SIZE) != 0) ||\r
+ ((pInfo->source % C90FL_WORD_SIZE) != 0))\r
+ {\r
+ returnCode = C90FL_ERROR_ALIGNMENT;\r
+ goto EXIT;\r
+ }\r
+\r
+ /* The flash range should fall within either shadow row or main array */\r
+ shadowRowEnd = pSSDConfig->shadowRowBase + pSSDConfig->shadowRowSize;\r
+ mainArrayEnd = pSSDConfig->mainArrayBase + pSSDConfig->mainArraySize;\r
+ pInfo->temp = pInfo->dest + pInfo->size;\r
+\r
+ if ((pInfo->dest >= pSSDConfig->shadowRowBase) && (pInfo->dest < shadowRowEnd) &&\r
+ (pInfo->size <= pSSDConfig->shadowRowSize) && (pInfo->temp <= shadowRowEnd))\r
+ {\r
+ /* fall in shadow row */\r
+ rangeType = 1;\r
+ }\r
+ else if ((pInfo->dest >= pSSDConfig->mainArrayBase) && (pInfo->dest < mainArrayEnd) &&\r
+ (pInfo->size <= pSSDConfig->mainArraySize) && (pInfo->temp <= mainArrayEnd))\r
+ {\r
+ /* fall in main array */\r
+ rangeType = 2;\r
+ }\r
+ else\r
+ {\r
+ returnCode = C90FL_ERROR_RANGE;\r
+ goto EXIT;\r
+ }\r
+\r
+ /* Anything to program? */\r
+ if ( !pInfo->size )\r
+ goto EXIT;\r
+\r
+ MCRValue = C90FL_REG_READ (MCRAddress);\r
+\r
+ /* Cases that program operation can start:\r
+ 1. no program and erase sequence:\r
+ (PGM low and ERS low)\r
+ 2. erase suspend with EHV low on main array and try to program main array\r
+ (PGM low, PEAS low, ERS high, ESUS high, EHV low, and rangeType = 2)\r
+\r
+ Cases that program operation cannot start:\r
+ 1. program in progress (PGM high);\r
+ 2. program not in progress (PGM low):\r
+ a. erase in progress but not in suspend state;\r
+ b. erase in suspend state on main array but try to program shadow row;\r
+ c. erase suspend on shadow row; */\r
+\r
+ /* Check if program and/or erase operation in progress */\r
+ if (MCRValue & (C90FL_MCR_PGM | C90FL_MCR_ERS | C90FL_MCR_ESUS))\r
+ {\r
+ returnCode = C90FL_ERROR_BUSY;\r
+ goto EXIT;\r
+ }\r
+\r
+ /* Check MCR-EER and MCR-RWE bit */\r
+ if (MCRValue & (C90FL_MCR_EER | C90FL_MCR_RWE))\r
+ {\r
+ /* use shadow row to release bus error */\r
+ pInfo->temp = *(VUINT32 *)(pSSDConfig->shadowRowBase + 0xE0);\r
+ }\r
+\r
+ /* Set MCR-PGM to start program operation */\r
+ C90FLMCR_BIT_SET (MCRAddress, C90FL_MCR_PGM);\r
+\r
+ /* number of double words */\r
+ pInfo->temp = pInfo->size / C90FL_DWORD_SIZE;\r
+\r
+ /* determine the page size */\r
+ if (pSSDConfig->pageSize == C90FL_PAGE_SIZE_32)\r
+ {\r
+ pInfo->pageSize = (UINT32)32;\r
+ }\r
+ else if(pSSDConfig->pageSize == C90FL_PAGE_SIZE_16)\r
+ {\r
+ pInfo->pageSize = (UINT32)16;\r
+ }\r
+ else if(pSSDConfig->pageSize == C90FL_PAGE_SIZE_08)\r
+ {\r
+ pInfo->pageSize = (UINT32)8;\r
+ }\r
+\r
+ pInfo->sourceIndex = 1;\r
+EXIT:\r
+ if (pSSDConfig->BDMEnable)\r
+ {\r
+ //asm ( "mr r3,returnCode" ); /* save the return code to R3 */\r
+ asm ( "sc " ); /* generate system call interrupt */\r
+ }\r
+\r
+\r
+ return returnCode;\r
+}\r
+\r
+/**\r
+ * Programs a flash page. Assumes that FlashProgram_r() is called before.\r
+ * Subsequent calls are made to this function until the programming operation is done\r
+ *\r
+ * @param pSSDConfig Flash configuration\r
+ * @param pInfo Structure used by the page programmer. It's initially filled in by FlashProgram_r()\r
+ *\r
+ * @returns Status of the flash programming. See ssd_h7f. for more information. 0x1000 added\r
+ * as return value when the device is busy\r
+\r
+ */\r
+\r
+static UINT32 Fls_C90FL_ProgramPage( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo ) {\r
+\r
+ UINT32 returnCode = 0;\r
+\r
+ UINT32 MCRAddress = pSSDConfig->c90flRegBase + C90FL_MCR;\r
+\r
+ /* Program data page by page, with special attention to incomplete page */\r
+ if( pInfo->sourceIndex <= pInfo->temp ) {\r
+ /* Programming write */\r
+ *(UINT64 *)pInfo->dest = *(UINT64 *)pInfo->source;\r
+\r
+ /* Update pInfo->source index */\r
+ pInfo->dest += C90FL_DWORD_SIZE;\r
+ pInfo->source += C90FL_DWORD_SIZE;\r
+\r
+ /* Is it time to do page programming? */\r
+ if ( ((pInfo->dest % pInfo->pageSize) == 0) || (pInfo->sourceIndex == pInfo->temp) )\r
+ {\r
+ /* Set MCR-EHV bit */\r
+ C90FLMCR_BIT_SET (MCRAddress, C90FL_MCR_EHV);\r
+ }\r
+ returnCode = C90FL_BUSY;\r
+ }\r
+\r
+ return returnCode;\r
+}\r
+\r
+\r
+/**\r
+ * Returns the status of the flash programming\r
+ *\r
+ */\r
+\r
+UINT32 Fls_C90FL_ProgramStatus ( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo ) {\r
+\r
+ UINT32 MCRAddress; /* address of C90FLMCR register */\r
+ UINT32 pfb_cr_val;\r
+ UINT32 returnCode = C90FL_OK;\r
+\r
+ MCRAddress = pSSDConfig->c90flRegBase + C90FL_MCR;\r
+\r
+ /* Wait until MCR-DONE set */\r
+ if ( !(C90FL_REG_READ (MCRAddress) & C90FL_MCR_DONE) )\r
+ {\r
+ return C90FL_BUSY;\r
+ }\r
+\r
+ /* Confirm MCR-PEG = 1 */\r
+ if ( !(C90FL_REG_READ (MCRAddress) & C90FL_MCR_PEG) )\r
+ {\r
+ /* Clear MCR-EHV bit */\r
+ C90FLMCR_BIT_CLEAR (MCRAddress, C90FL_MCR_EHV);\r
+\r
+ returnCode = C90FL_ERROR_PGOOD;\r
+ goto EXIT_EHV;\r
+ }\r
+\r
+ /* Clear MCR-EHV bit */\r
+ C90FLMCR_BIT_CLEAR (MCRAddress, C90FL_MCR_EHV);\r
+ pInfo->sourceIndex++;\r
+\r
+ returnCode = Fls_C90FL_ProgramPage( pSSDConfig,pInfo );\r
+ if( (returnCode) == C90FL_BUSY ) {\r
+ return C90FL_BUSY;\r
+ }\r
+\r
+EXIT_EHV:\r
+\r
+ /* Clear MCR-PGM bit */\r
+ C90FLMCR_BIT_CLEAR (MCRAddress, C90FL_MCR_PGM);\r
+\r
+ if(DFLASH_BASE_ADDR != pSSDConfig->c90flRegBase) /* CFLASH */\r
+ {\r
+ /* save PFB_CR */\r
+ pfb_cr_val = C90FL_REG_READ(CFLASH_BASE_ADDR + PFB_CR);\r
+\r
+ /* Invalidate the PFBIU line read buffer */\r
+ C90FL_REG_BIT_CLEAR (CFLASH_BASE_ADDR + PFB_CR, PFB_CR_BFEN);\r
+\r
+ /* restore PFB_CR */\r
+ C90FL_REG_WRITE(CFLASH_BASE_ADDR + PFB_CR, pfb_cr_val);\r
+ }\r
+\r
+ if(DFLASH_BASE_ADDR == pSSDConfig->c90flRegBase) /* DFLASH */\r
+ {\r
+ /* save PFB_CR1 */\r
+ pfb_cr_val = C90FL_REG_READ(CFLASH_BASE_ADDR + PFB_CR1);\r
+\r
+ /* Invalidate the PFBIU holding register */\r
+ C90FL_REG_BIT_CLEAR (CFLASH_BASE_ADDR + PFB_CR1, PFB_CR_BFEN);\r
+\r
+ /* restore PFB_CR1 */\r
+ C90FL_REG_WRITE(CFLASH_BASE_ADDR + PFB_CR1, pfb_cr_val);\r
+ }\r
+\r
+ // Clear our struct....\r
+ memset( pInfo,0x0,sizeof(Fls_ProgInfoType) );\r
+\r
+ return returnCode;\r
+}\r
+\r
+#define FLASH_LMLR_PASSWORD 0xA1A11111 /* Low/Mid address lock enabled password */\r
+#define FLASH_HLR_PASSWORD 0xB2B22222 /* High address lock enabled password */\r
+#define FLASH_SLMLR_PASSWORD 0xC3C33333 /* Secondary low and middle address lock enabled password */\r
+\r
+/* TODO: use PSSD_CONFIG ( regbase, etc instead of hardcoded FLASH ) */\r
+\r
+\r
+/**\r
+ * Function that handles the locks bits the flash. Handled bits\r
+ * are LLOCK, MLOCK, SLOCK, HLOCK\r
+ * Secondary locks are NOT supported.\r
+ *\r
+ * @param blocks - Blocks to set lock or unlock.\r
+ * @param logic - A '1' interpretes 1 in blocks as lock, A '0' as unlock\r
+ */\r
+void Fls_C90FL_SetLock ( PSSD_CONFIG pSSDConfig, Fls_EraseBlockType *blocks, UINT8 logic )\r
+{\r
+ vuint32_t *reg, *sreg;\r
+ //struct FLASH_tag *flashHw = &CFLASH0;\r
+\r
+ if( (blocks->lowEnabledBlocks != 0 ) ||\r
+ (blocks->midEnabledBlocks != 0 ) ||\r
+ (blocks->shadowBlocks != 0 ) )\r
+ {\r
+ if(CFLASH_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ reg = &(CFLASH0.LML.R);\r
+ sreg = &(CFLASH0.SLL.R);\r
+ }\r
+ else if(CFLASH1_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ reg = &(CFLASH1.LML.R);\r
+ sreg = &(CFLASH1.SLL.R);\r
+ }\r
+ else if(DFLASH_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ reg = &(DFLASH.LML.R);\r
+ sreg = &(DFLASH.SLL.R);\r
+ }\r
+ else\r
+ {\r
+ return;\r
+ }\r
+\r
+ // Check if sector is locked\r
+ if( !(*reg & 0x80000000 )) {\r
+ // Unlock the sector with password\r
+ *reg = FLASH_LMLR_PASSWORD;\r
+ }\r
+ if( !(*sreg & 0x80000000 )) {\r
+ // Unlock the sector with password\r
+ *sreg = FLASH_SLMLR_PASSWORD;\r
+ }\r
+\r
+ // set/clear them\r
+ if( logic ) {\r
+ *reg |= ((blocks->midEnabledBlocks<<16)& C90FL_LML_MLOCK) +\r
+ (blocks->lowEnabledBlocks & C90FL_LML_LLOCK) +\r
+ (blocks->shadowBlocks & C90FL_LML_SLOCK);\r
+ } else {\r
+ *reg &= ((~blocks->midEnabledBlocks<<16) & C90FL_LML_MLOCK) |\r
+ ((~blocks->lowEnabledBlocks) & C90FL_LML_LLOCK) |\r
+ ((~blocks->shadowBlocks) & C90FL_LML_SLOCK) ;\r
+ }\r
+ if( logic ) {\r
+ *sreg |= ((blocks->midEnabledBlocks<<16)& C90FL_LML_MLOCK) +\r
+ (blocks->lowEnabledBlocks & C90FL_LML_LLOCK) +\r
+ (blocks->shadowBlocks & C90FL_LML_SLOCK);\r
+ } else {\r
+ *sreg &= ((~blocks->midEnabledBlocks<<16) & C90FL_LML_MLOCK) |\r
+ ((~blocks->lowEnabledBlocks) & C90FL_LML_LLOCK) |\r
+ ((~blocks->shadowBlocks) & C90FL_LML_SLOCK) ;\r
+ }\r
+ }\r
+#if 0\r
+ else {\r
+ reg = &(flashHw->LML.R);\r
+ // Set all\r
+ *reg |= 0x8003003f;\r
+ }\r
+#endif\r
+\r
+ if( (blocks->highEnabledBlocks != 0 )) {\r
+\r
+ if(CFLASH_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ reg = &(CFLASH0.HBL.R);\r
+ }\r
+ else if(CFLASH1_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ reg = &(CFLASH1.HBL.R);\r
+ }\r
+ else if(DFLASH_BASE_ADDR == pSSDConfig->c90flRegBase)\r
+ {\r
+ reg = &(DFLASH.HBL.R);\r
+ }\r
+ else\r
+ {\r
+ return;\r
+ }\r
+\r
+ if( !(*reg & 0x80000000 )) {\r
+ // Unlock\r
+ *reg = FLASH_HLR_PASSWORD;\r
+ }\r
+ // clear\r
+ // *reg &= ~(C90FL_HBL_HBLOCK);\r
+ // Set\r
+ if( logic ) {\r
+ *reg |= ((blocks->highEnabledBlocks)& C90FL_HBL_HBLOCK);\r
+ } else {\r
+ *reg &= ((~blocks->highEnabledBlocks)& C90FL_HBL_HBLOCK);\r
+ }\r
+ }\r
+#if 0\r
+ else {\r
+ reg = &(flashHw->HBR.R);\r
+ // Set all\r
+ *reg |= 0x800000ff;\r
+ }\r
+#endif\r
+}\r
+\r
+\r
+\r