]> rtime.felk.cvut.cz Git - arc.git/commitdiff
Merge with 5606S repo
authormahi <devnull@localhost>
Thu, 16 Jun 2011 14:30:58 +0000 (16:30 +0200)
committermahi <devnull@localhost>
Thu, 16 Jun 2011 14:30:58 +0000 (16:30 +0200)
arch/ppc/mpc55xx/drivers/Fls.c
arch/ppc/mpc55xx/drivers/Fls_C90FL.c [new file with mode: 0644]
arch/ppc/mpc55xx/drivers/Fls_C90FL.h [new file with mode: 0644]
arch/ppc/mpc55xx/drivers/Mcu.c
arch/ppc/mpc55xx/drivers/Wdg.c
arch/ppc/mpc55xx/drivers/Wdg.h
arch/ppc/mpc55xx/kernel/irq_types.h
arch/ppc/mpc55xx/scripts/linkscript_gcc.ldf

index 759becf834518262fbe8cf5b41577135d2724124..52198809e27e6589bd48571584ec6cf1015c2697 100644 (file)
 #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
@@ -218,7 +240,7 @@ static inline int Fls_Validate( uint32 addr,uint32 length, uint32 api,uint32 rv
   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
@@ -246,6 +268,12 @@ static inline int Fls_Validate( uint32 addr,uint32 length, uint32 api,uint32 rv
     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
@@ -265,7 +293,7 @@ static inline int Fls_Validate( uint32 addr,uint32 length, uint32 api,uint32 rv
   }\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
@@ -324,8 +352,12 @@ typedef struct {
 \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
@@ -336,6 +368,34 @@ SSD_CONFIG ssdConfig = {
     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
@@ -435,6 +495,40 @@ static inline uint32 rlwimi(uint32 val, uint16 sh, uint16 mb,uint16 me)
 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
@@ -455,6 +549,7 @@ static uint32 address_to_block( uint32 addr, uint32 *rem ) {
     block = (-1);\r
     *rem = (-1);\r
   }\r
+#endif\r
   return block;\r
 }\r
 \r
@@ -491,12 +586,16 @@ static void address_to_erase_blocks( Fls_EraseBlockType *eraseBlocks, uint32 add
   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
@@ -520,6 +619,10 @@ void Fls_Init( const Fls_ConfigType *ConfigPtr )
 \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
@@ -527,7 +630,11 @@ void Fls_Init( const Fls_ConfigType *ConfigPtr )
   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
@@ -585,12 +692,55 @@ Std_ReturnType Fls_Erase( Fls_AddressType   TargetAddress,
 \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
@@ -598,6 +748,7 @@ Std_ReturnType Fls_Erase(   Fls_AddressType   TargetAddress,
           eraseBlock.highEnabledBlocks,\r
           &eraseInfo\r
                   );\r
+#endif\r
   return E_OK;\r
 }\r
 \r
@@ -631,8 +782,20 @@ Std_ReturnType Fls_Write (    Fls_AddressType   TargetAddress,
   // 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
@@ -659,10 +822,14 @@ MemIf_JobResultType Fls_GetJobResult( void )
 }\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
@@ -673,7 +840,7 @@ void Fls_MainFunction( void )
       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
@@ -683,7 +850,50 @@ void Fls_MainFunction( void )
     {\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
@@ -711,6 +921,7 @@ void Fls_MainFunction( void )
 #endif\r
         FEE_JOB_ERROR_NOTIFICATION();\r
       }\r
+#endif\r
       break;\r
     }\r
     case FLS_JOB_READ:\r
@@ -726,7 +937,51 @@ void Fls_MainFunction( void )
     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
@@ -755,7 +1010,7 @@ void Fls_MainFunction( void )
 #endif\r
                FEE_JOB_ERROR_NOTIFICATION();\r
       }\r
-\r
+#endif\r
       break;\r
     }\r
     case FLS_JOB_NONE:\r
@@ -765,6 +1020,7 @@ void Fls_MainFunction( void )
   }\r
 }\r
 \r
+\r
 Std_ReturnType Fls_Read (      Fls_AddressType SourceAddress,\r
               uint8 *TargetAddressPtr,\r
               Fls_LengthType Length )\r
@@ -824,10 +1080,12 @@ void Fls_SetMode(                MemIf_ModeType Mode )
 }\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
@@ -838,7 +1096,11 @@ void Fls_Check( uint32 flsBaseAddress, uint32 flsTotalSize )
   // 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
diff --git a/arch/ppc/mpc55xx/drivers/Fls_C90FL.c b/arch/ppc/mpc55xx/drivers/Fls_C90FL.c
new file mode 100644 (file)
index 0000000..09edcb4
--- /dev/null
@@ -0,0 +1,789 @@
+\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
diff --git a/arch/ppc/mpc55xx/drivers/Fls_C90FL.h b/arch/ppc/mpc55xx/drivers/Fls_C90FL.h
new file mode 100644 (file)
index 0000000..ec9a8d1
--- /dev/null
@@ -0,0 +1,66 @@
+/* -------------------------------- Arctic Core ------------------------------\r
+ * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
+ *\r
+ * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
+ *\r
+ * This source code is free software; you can redistribute it and/or modify it\r
+ * under the terms of the GNU General Public License version 2 as published by the\r
+ * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+ * for more details.\r
+ * -------------------------------- Arctic Core ------------------------------*/\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#ifndef FLS_C90FL_H_\r
+#define FLS_C90FL_H_\r
+\r
+#define FLS_ERASE_SECTION __attribute__ ((section (".fls_erase")));\r
+#define FLS_WRITE_SECTION __attribute__ ((section (".fls_write")));\r
+\r
+#define C90FL_BUSY     0x1000\r
+\r
+typedef struct {\r
+       UINT32 dest;\r
+       UINT32 size;\r
+       UINT32 source;\r
+       UINT32 pageSize;\r
+       UINT32 sourceIndex;\r
+       UINT32 temp;\r
+       UINT32 state;\r
+} Fls_ProgInfoType;\r
+\r
+typedef struct {\r
+       UINT32 state;\r
+} Fls_EraseInfoType;\r
+\r
+typedef struct {\r
+       UINT32 lowEnabledBlocks;\r
+       UINT32 midEnabledBlocks;\r
+       UINT32 highEnabledBlocks;\r
+       // 1 - primary, 2 - secondary\r
+       UINT32 shadowBlocks;\r
+} Fls_EraseBlockType;\r
+\r
+// TODO : document API\r
+UINT32 Fls_C90FL_FlashErase ( PSSD_CONFIG pSSDConfig,\r
+                    BOOL shadowFlag,\r
+                    UINT32 lowEnabledBlocks,\r
+                    UINT32 midEnabledBlocks,\r
+                    UINT32 highEnabledBlocks,\r
+                    Fls_EraseInfoType *eraseInfo); //FLS_ERASE_SECTION;\r
+\r
+UINT32 Fls_C90FL_EraseStatus (  PSSD_CONFIG pSSDConfig  );// FLS_ERASE_SECTION ;\r
+\r
+UINT32 Fls_C90FL_Program ( PSSD_CONFIG pSSDConfig, Fls_ProgInfoType *pInfo ); //FLS_WRITE_SECTION ;\r
+\r
+void Fls_C90FL_SetLock ( PSSD_CONFIG pSSDConfig, Fls_EraseBlockType *blocks, UINT8 logic );\r
+#endif /*FLS_C90FL_H_*/\r
index 62cda1163eeed980e76a0f7ba88fd325723c0583..3458dafed1310bae1cf19e7421e13a6de73ecb01 100644 (file)
@@ -377,10 +377,6 @@ Std_ReturnType Mcu_InitClock(const Mcu_ClockType ClockSetting)
     assert(clockSettingsPtr->Pll3 < 8);\r
 \r
 #elif defined(CFG_MPC5606S)\r
-    /* MPC5606S (normal mode)\r
-     *   PHI = ClkIn * LDF / (IDF * ODF )\r
-     */\r
-#warning Do more here...\r
 #else\r
 #error CPU not defined\r
 #endif\r
index fa33479d7fb435b5e26963b00ce6e68aa634a54c..3ee82cf15a1f1081b6eede0d9bf13ac1cf7980f4 100644 (file)
  * for more details.\r
  * -------------------------------- Arctic Core ------------------------------*/\r
 \r
-\r
-/*\r
- * Wdg.c\r
- *\r
- *  Created on: 2009-jul-22\r
- *      Author: rosa\r
- */\r
-\r
 #include "mpc55xx.h"\r
+#include "Wdg.h"\r
 #include "Mcu.h"\r
 \r
 \r
+static const Wdg_ConfigType *configWdgPtr;\r
+static const Wdg_SettingsType *modeWdgConfig;\r
+\r
 void StartWatchdog(void)\r
 {\r
-       // Setup watchdog\r
-       // R0    =  0 Not read only\r
-       // SWRWH =  0 SWT stops counting if the processor core is halted.\r
-       // SWE   =  1 SWT is enabled.\r
-       // SWRI  =  2 If a time-out occurs, the SWT generates a system reset.\r
-       // SWT   = 24 For SWT = n, then time-out period = 2^n system clock cycles, n = 8 9,..., 31.\r
-       //            SWT = 24  =>  period = 262144 clock cycles ( 254ms @ 66MHz )\r
 #if defined(CFG_MPC5567)\r
        ECSM.SWTCR.R =  0x00D8;;\r
 #elif defined(CFG_MPC5606S)\r
-       SWT.CR.R = 0x8000011B; //Default time-out period, 10ms@128khz.\r
+       SWT.CR.R = 0x8000011B;\r
 #else\r
        MCM.SWTCR.R = 0x00D8;\r
 #endif\r
+\r
 }\r
 \r
-void StopWatchdog(void)\r
+ void StopWatchdog(void)\r
+ {\r
+ #if defined(CFG_MPC5567)\r
+       ECSM.SWTCR.R =  0x0059;;\r
+ #elif defined(CFG_MPC5606S)\r
+       SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */\r
+       SWT.SR.R = 0x0000d928;\r
+       SWT.CR.R = 0x8000010A;\r
+ #else\r
+       MCM.SWTCR.R = 0x0059;\r
+ #endif\r
+ }\r
+\r
+void Wdg_Init (const Wdg_ConfigType* ConfigPtr)\r
 {\r
-       // Stop the watchdog\r
-       // R0 = 0     Not read only\r
-       // SWRWH = 0  SWT stops counting if the processor core is halted.\r
-       // SWE = 0    SWT is disabled.\r
-       // SWRI = 2   If a time-out occurs, the SWT generates a system reset.\r
-       // SWT = 19   For SWT = n, then time-out period = 2^n system clock cycles, n = 8 9,..., 31.\r
-       //            SWT = 19  =>  period = 524288 clock cycles ( 8.7ms @ 60MHz )\r
-#if defined(CFG_MPC5567)\r
-       ECSM.SWTCR.R =  0x0059;;\r
-#elif defined(CFG_MPC5606S)\r
-       SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */\r
-       SWT.SR.R = 0x0000d928;\r
-       SWT.CR.R = 0x8000010A;\r
-#else\r
-       MCM.SWTCR.R = 0x0059;\r
+       /* Keep a pointer to the config. */\r
+       configWdgPtr = ConfigPtr;\r
+\r
+       Wdg_SetMode(ConfigPtr->Wdg_ModeConfig->Wdg_DefaultMode);\r
+}\r
+\r
+Std_ReturnType Wdg_SetMode (WdgIf_ModeType Mode)\r
+{\r
+       Std_ReturnType res = E_NOT_OK;\r
+       switch (Mode)\r
+       {\r
+       case WDGIF_OFF_MODE:\r
+               modeWdgConfig = &configWdgPtr->Wdg_ModeConfig->WdgSettingsOff;\r
+               break;\r
+       case WDGIF_FAST_MODE:\r
+               modeWdgConfig = &configWdgPtr->Wdg_ModeConfig->WdgSettingsFast;\r
+               break;\r
+       case WDGIF_SLOW_MODE:\r
+               modeWdgConfig = &(configWdgPtr->Wdg_ModeConfig->WdgSettingsSlow);\r
+               break;\r
+       default:\r
+               modeWdgConfig = 0;\r
+               break;\r
+       }\r
+       if (modeWdgConfig != 0)\r
+       {\r
+               /* Enable watchdog if config tell us to.. */\r
+               if (modeWdgConfig->ActivationBit)\r
+               {\r
+#if defined(CFG_MPC5606S)\r
+                 StopWatchdog(); // must be stopped in order to change TO\r
+                 SWT.TO.R = modeWdgConfig->ReloadValue;\r
 #endif\r
+                       StartWatchdog();\r
+               }\r
+               else\r
+               {\r
+                       StopWatchdog();\r
+               }\r
+               res = E_OK;\r
+       }\r
+\r
+       return res;\r
 }\r
 \r
 \r
 /* This function services the internal Watchdog timer */\r
-void KickWatchdog(void)\r
+void Wdg_Trigger (void)\r
 {\r
-       uint32 prevIEN;\r
+       uint32 tmp;\r
 \r
-       prevIEN = McuE_EnterCriticalSection();\r
+       tmp = McuE_EnterCriticalSection();\r
 \r
        //  According to MPC55xx manual:\r
        //  To prevent the watchdog timer from interrupting or resetting\r
@@ -87,5 +117,5 @@ void KickWatchdog(void)
        MCM.SWTSR.R = 0xAA;\r
 #endif\r
 \r
-       McuE_ExitCriticalSection(prevIEN);\r
+       McuE_ExitCriticalSection(tmp);\r
 }\r
index 5ec99a74e653d668002887b5777c46dea34c7b52..4d148ad4510f89a212474ac23adde0e84ab3d156 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
  * for more details.\r
- * -------------------------------- Arctic Core ------------------------------*/\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*\r
- * Wdg.h\r
- *\r
- *  Created on: 2009-jul-22\r
- *      Author: rosa\r
+ * -------------------------------- Arctic Core ------------------------------\r
  */\r
 \r
 #ifndef WDG_H_\r
 #define WDG_H_\r
 \r
-void StartWatchdog(void);\r
-void StopWatchdog(void);\r
-void KickWatchdog(void);\r
+#include "Wdg_Cfg.h"\r
+\r
+void Wdg_Init (const Wdg_ConfigType* ConfigPtr);\r
+void Wdg_Trigger (void);\r
+Std_ReturnType Wdg_SetMode (WdgIf_ModeType Mode);\r
+\r
+#if (WDG_VERSION_INFO_API == STD_ON)\r
+void Wdg_GetVersionInfo( Std_VersionInfoType *versionInfo );\r
+#define Wdg_GetVersionInfo(_vi) STD_GET_VERSION_INFO(_vi,WDG)\r
+#endif\r
 \r
 #endif /* WDG_H_ */\r
index 045c88bd275f0f40456a1969df07065ad3103506..06f9e3225b1383df78894180cc8e42a3eb4f513a 100644 (file)
@@ -867,12 +867,16 @@ typedef enum
        PERIPHERAL_CLOCK_ESCI_F,\r
        PERIPHERAL_CLOCK_ESCI_G,\r
        PERIPHERAL_CLOCK_ESCI_H,\r
+#if defined(CFG_MPC5606S)\r
+       PERIPHERAL_CLOCK_LIN_A,\r
+       PERIPHERAL_CLOCK_LIN_B,\r
+#endif\r
        PERIPHERAL_CLOCK_IIC_A,\r
        PERIPHERAL_CLOCK_MLB\r
 } McuE_PeriperalClock_t;\r
 \r
 \r
-#if defined(CFG_MPC5516)\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5606S)\r
 #define CPU_Z1         0\r
 #define CPU_Z0 1\r
 #endif\r
index e18f46d40d8d08351dd89d4e7e90d3d7317d683d..e7411d76aaaa3893d96d87598076ab24030a2b4c 100644 (file)
@@ -10,7 +10,6 @@ OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
 OUTPUT_ARCH(powerpc)\r
 ENTRY(_start)\r
 \r
-/*\r
 /*\r
  * _idata - Start of .data in flash \r
  * _data  - start address of .data in RAM\r