1 /* -------------------------------- Arctic Core ------------------------------
2 * Copyright (C) 2009-2011 ArcCore AB <contact@arccore.com>
3 * Licensed under ArcCore Embedded Software License Agreement.
4 * -------------------------------- Arctic Core ------------------------------*/
9 * Created on: 29 aug 2011
12 * Interface for the low level flash written by freescale (flash_ll_h7f_c90.c )
14 * This file aims to support support all mpc55xx as well as mpc56xx.
17 /* ----------------------------[includes]------------------------------------*/
23 #include "flash_ll_h7f_c90.h"
26 //#include "flash_mpc5xxx.h"
29 #define USE_DEBUG_PRINTF
32 #define ASSERT(_x) assert(_x)
34 /* ----------------------------[private define]------------------------------*/
36 #define PFLASH_CTRL_BASE 0xFFE8_8000
37 #define PFCR0 (PFLASH_CTRL_BASE + 0x1c)
38 #define PFCR1 (PFLASH_CTRL_BASE + 0x20)
39 #define PFAPR (PFLASH_CTRL_BASE + 0x24)
41 #define NVLML_LME (1<<31)
44 //#define FLASH_BANK_CNT 3
45 #define PASSWORD_LOW_MID 0xA1A11111UL
46 #define PASSWORD_HIGH 0xB2B22222UL
47 #define PASSWORD_SECONDARY_LOW_MID 0xC3C33333UL
49 /* ----------------------------[private macro]-------------------------------*/
51 /* Check if two ranges overlap (_a0->_a1 is first range ) */
52 #define OVERLAP(_a0,_a1, _b0, _b1 ) ( ( ((_a0) <= (_b0)) && ((_b0) <= (_a1)) ) || \
53 ( ((_b0) <= (_a0)) && ((_a0) <= (_b1)) ) )
55 /* ----------------------------[private typedef]-----------------------------*/
56 /* ----------------------------[private function prototypes]-----------------*/
57 /* ----------------------------[private variables]---------------------------*/
59 /* ----------------------------[private functions]---------------------------*/
60 /* ----------------------------[public functions]----------------------------*/
63 * Convert address to strange block format that freescale likes.
70 static bool getAffectedBlocks( const FlashType *bPtr, uintptr_t addr, size_t size, uint32_t (*fb)[ADDR_SPACE_CNT] ) {
72 bool anyAffected = false;
75 memset(fb, 0, sizeof(*fb) );
77 /* Check if sector range overlaps */
78 for (int sector = 0; sector < bPtr->sectCnt; sector++)
80 if (OVERLAP( addr,addr+size-1,
81 bPtr->sectAddr[sector],bPtr->sectAddr[sector+1]-1))
83 addrSpace = bPtr->addrSpace[sector];
84 (*fb)[ADDR_SPACE_GET(addrSpace)] |= (1 << ADDR_SPACE_GET_SECTOR(addrSpace));
96 void Flash_Init(void) {
98 /* TODO: Does freescale setup the platform flash controller with sane
103 uint32_t Flash_Lock(const FlashType *fPtr, uint32_t op, uintptr_t from, uint32_t size) {
104 uint32_t flashBlocks[ADDR_SPACE_CNT];
106 const FlashType *bPtr;
110 LDEBUG_PRINTF("Flash_lock from:%p size:%ul\n");
112 for (bank = 0; bank < FLASH_BANK_CNT; bank++) {
115 getAffectedBlocks(bPtr, from, size, &flashBlocks);
117 /* ---------- Low/Mid ---------- */
118 lock = (flashBlocks[ADDR_SPACE_MID]<<16) | flashBlocks[ADDR_SPACE_LOW];
120 regAddr = bPtr->regBase + C90FL_LML;
122 /* Unlock LML (enable LME bit) */
123 if ( (READ32(regAddr) & NVLML_LME) == 0 ) {
124 WRITE32(regAddr,PASSWORD_LOW_MID);
127 if( op & FLASH_OP_UNLOCK ) {
128 WRITE32(regAddr,(~lock) & READ32(regAddr) );
130 WRITE32(regAddr,(lock) | READ32(regAddr) );
133 regAddr = bPtr->regBase + C90FL_SLL;
134 /* Unlock secondary, SLL (enable LME bit) */
135 if ( (READ32(regAddr) & NVLML_LME) == 0 ) {
136 WRITE32(regAddr,PASSWORD_SECONDARY_LOW_MID);
139 if( op & FLASH_OP_UNLOCK ) {
140 WRITE32(regAddr,(~lock) & READ32(regAddr) );
142 WRITE32(regAddr,(lock) | READ32(regAddr) );
147 /* ---------- high ----------*/
148 lock = flashBlocks[ADDR_SPACE_HIGH];
150 regAddr = bPtr->regBase + C90FL_HBL;
151 /* Unlock LML (enable LME bit) */
152 if ( (READ32(regAddr) & NVLML_LME) == 0 ) {
153 WRITE32(regAddr,PASSWORD_HIGH);
157 if( op & FLASH_OP_UNLOCK ) {
158 WRITE32(regAddr,(~lock) & READ32(regAddr) );
160 WRITE32(regAddr,(lock) | READ32(regAddr) );
174 uint32_t Flash_Erase( const FlashType *fPtr, uintptr_t dest, uint32_t size, flashCbType cb) {
176 uint32_t flashBlocks[ADDR_SPACE_CNT];
177 const FlashType *bPtr;
180 /* FSL functions are for each bank, so loop over banks */
181 for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {
184 affected = getAffectedBlocks(bPtr, dest, size, &flashBlocks);
185 if( affected == false ) {
189 rv = FSL_FlashEraseStart(bPtr->regBase, dest, flashBlocks[0],
190 flashBlocks[1], flashBlocks[2]);
193 return EE_ERROR_PE_OPT;
197 while ((rv = FSL_FlashCheckStatus(bPtr->regBase)) != EE_OK) {
199 if (rv == EE_ERROR_PE_OPT) {
221 uint32_t Flash_ProgramStart( const FlashType *fPtr, uint32_t *to, uint32_t * from, uint32_t * size, flashCbType cb) {
223 uint16_t fSize = size;
224 uint32_t fDest = (uint32_t) to;
225 uint32_t fSource = (uint32_t) from;
226 uint32_t flashBlocks[ADDR_SPACE_CNT];
228 const FlashType *bPtr;
232 /* Check double word alignment */
233 ASSERT((size % 8) == 0 );
235 /* FSL functions are for each bank, so loop over banks */
236 for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {
239 affected = getAffectedBlocks(bPtr, to, size, &flashBlocks);
240 if( affected == false ) {
241 /* This bank was not affected */
245 /* Program to the end of bank */
246 maxToProg = MIN(fSize, (bPtr->sectAddr[0] + bPtr->bankSize - fDest));
251 rv = FSL_FlashProgramStart(bPtr->regBase, &fDest, &maxToProg, &fSource);
254 return EE_ERROR_PE_OPT;
259 while ((rv = FSL_FlashCheckStatus(bPtr->regBase)) != EE_OK) {
261 if (rv == EE_ERROR_PE_OPT) {
284 uint32_t Flash_ProgramPageStart( const FlashType *fPtr, uint32_t *to, uint32_t * from, uint32_t * size, flashCbType cb) {
285 uint32_t flashBlocks[ADDR_SPACE_CNT];
286 const FlashType *bPtr;
290 /* Check double word alignment */
291 ASSERT((*size % 8) == 0 );
293 /* FSL functions are for each bank, so loop over banks */
294 for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {
297 affected = getAffectedBlocks(bPtr, *to, *size, &flashBlocks);
298 if( affected == false ) {
299 /* This bank was not affected */
303 return FSL_FlashProgramStart(bPtr->regBase, to, size, from);
308 uint32_t Flash_CheckStatus( const FlashType *fPtr ) {
309 return FSL_FlashCheckStatus(fPtr->regBase);
312 uint32_t Flash_SectorAligned( const FlashType *fPtr, uintptr_t addr ) {
313 uint32_t rv = EE_ERROR_MISMATCH;
314 const FlashType *bPtr;
316 for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {
319 /* In range of bank */
320 if( (addr >= bPtr->sectAddr[0]) &&
321 (addr <= (bPtr->sectAddr[bPtr->sectCnt])) )
323 for (int sector = 0; sector < bPtr->sectCnt; sector++)
325 if( addr == bPtr->sectAddr[sector] ) {