#define FLEXRAM 0x14000000
+#define MSCM_OCMDR0 0x40001400
#define FMC_PFB01CR 0x4001f004
#define FTFx_FSTAT 0x40020000
#define FTFx_FCNFG 0x40020001
#define WDOG_STCTRH 0x40052000
#define SMC_PMCTRL 0x4007E001
#define SMC_PMSTAT 0x4007E003
+#define MCM_PLACR 0xF000300C
/* Values */
#define PM_STAT_RUN 0x01
#define KINETIS_SDID_SERIESID_MASK 0x00F00000
#define KINETIS_SDID_SERIESID_K 0x00000000
#define KINETIS_SDID_SERIESID_KL 0x00100000
+#define KINETIS_SDID_SERIESID_KE 0x00200000
#define KINETIS_SDID_SERIESID_KW 0x00500000
#define KINETIS_SDID_SERIESID_KV 0x00600000
#define KINETIS_SDID_SUBFAMID_KX4 0x04000000
#define KINETIS_SDID_SUBFAMID_KX5 0x05000000
#define KINETIS_SDID_SUBFAMID_KX6 0x06000000
+#define KINETIS_SDID_SUBFAMID_KX7 0x07000000
+#define KINETIS_SDID_SUBFAMID_KX8 0x08000000
#define KINETIS_SDID_FAMILYID_MASK 0xF0000000
#define KINETIS_SDID_FAMILYID_K0X 0x00000000
#define KINETIS_SDID_FAMILYID_K4X 0x40000000
#define KINETIS_SDID_FAMILYID_K6X 0x60000000
#define KINETIS_SDID_FAMILYID_K7X 0x70000000
+#define KINETIS_SDID_FAMILYID_K8X 0x80000000
+
+/* The field originally named DIEID has new name/meaning on KE1x */
+#define KINETIS_SDID_PROJECTID_MASK KINETIS_SDID_DIEID_MASK
+#define KINETIS_SDID_PROJECTID_KE1xF 0x00000080
+#define KINETIS_SDID_PROJECTID_KE1xZ 0x00000100
struct kinetis_flash_bank {
bool probed;
enum {
FS_PROGRAM_SECTOR = 1,
FS_PROGRAM_LONGWORD = 2,
- FS_PROGRAM_PHRASE = 4, /* Unsupported */
- FS_INVALIDATE_CACHE = 8,
+ FS_PROGRAM_PHRASE = 4, /* Unsupported */
+ FS_INVALIDATE_CACHE_K = 8, /* using FMC->PFB0CR/PFB01CR */
+ FS_INVALIDATE_CACHE_L = 0x10, /* using MCM->PLACR */
+ FS_INVALIDATE_CACHE_MSCM = 0x20,
} flash_support;
};
static void kinetis_invalidate_flash_cache(struct flash_bank *bank)
{
struct kinetis_flash_bank *kinfo = bank->driver_priv;
- uint8_t pfb01cr_byte2 = 0xf0;
- if (!(kinfo->flash_support & FS_INVALIDATE_CACHE))
- return;
+ if (kinfo->flash_support & FS_INVALIDATE_CACHE_K)
+ target_write_u8(bank->target, FMC_PFB01CR + 2, 0xf0);
+ /* Set CINV_WAY bits - request invalidate of all cache ways */
+ /* FMC_PFB0CR has same address and CINV_WAY bits as FMC_PFB01CR */
+
+ else if (kinfo->flash_support & FS_INVALIDATE_CACHE_L)
+ target_write_u8(bank->target, MCM_PLACR + 1, 0x04);
+ /* set bit CFCC - Clear Flash Controller Cache */
+
+ else if (kinfo->flash_support & FS_INVALIDATE_CACHE_MSCM)
+ target_write_u32(bank->target, MSCM_OCMDR0, 0x30);
+ /* disable data prefetch and flash speculate */
- target_write_memory(bank->target, FMC_PFB01CR + 2, 1, 1, &pfb01cr_byte2);
return;
}
if (!(kinfo->flash_support & FS_PROGRAM_SECTOR)) {
/* fallback to longword write */
fallback = 1;
- LOG_WARNING("This device supports Program Longword execution only.");
+ LOG_INFO("This device supports Program Longword execution only.");
} else {
result = kinetis_make_ram_ready(bank->target);
if (result != ERROR_OK) {
pflash_sector_size_bytes = 1<<10;
nvm_sector_size_bytes = 1<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_K_SDID_K10_M72:
case KINETIS_K_SDID_K20_M72:
pflash_sector_size_bytes = 2<<10;
nvm_sector_size_bytes = 1<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
kinfo->max_flash_prog_size = 1<<10;
break;
case KINETIS_K_SDID_K10_M100:
pflash_sector_size_bytes = 2<<10;
nvm_sector_size_bytes = 2<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_K_SDID_K21_M120:
case KINETIS_K_SDID_K22_M120:
kinfo->max_flash_prog_size = 1<<10;
nvm_sector_size_bytes = 4<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_K_SDID_K10_M120:
case KINETIS_K_SDID_K20_M120:
pflash_sector_size_bytes = 4<<10;
nvm_sector_size_bytes = 4<<10;
num_blocks = 4;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
default:
LOG_ERROR("Unsupported K-family FAMID");
/* K02FN64, K02FN128: FTFA, 2kB sectors */
pflash_sector_size_bytes = 2<<10;
num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX2: {
/* MK24FN1M */
pflash_sector_size_bytes = 4<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
kinfo->max_flash_prog_size = 1<<10;
break;
}
/* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */
pflash_sector_size_bytes = 2<<10;
/* autodetect 1 or 2 blocks */
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
}
LOG_ERROR("Unsupported Kinetis K22 DIEID");
if ((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {
/* K24FN256 - smaller pflash with FTFA */
num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
}
/* K24FN1M without errata 7534 */
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
kinfo->max_flash_prog_size = 1<<10;
break;
nvm_sector_size_bytes = 4<<10;
kinfo->max_flash_prog_size = 1<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:
nvm_sector_size_bytes = 4<<10;
kinfo->max_flash_prog_size = 1<<10;
num_blocks = 4;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
+
+ case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX0:
+ case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX1:
+ case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX2:
+ /* K80FN256, K81FN256, K82FN256 */
+ pflash_sector_size_bytes = 4<<10;
+ num_blocks = 1;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ break;
+
default:
LOG_ERROR("Unsupported Kinetis FAMILYID SUBFAMID");
}
pflash_sector_size_bytes = 1<<10;
nvm_sector_size_bytes = 1<<10;
/* autodetect 1 or 2 blocks */
- kinfo->flash_support = FS_PROGRAM_LONGWORD;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
break;
case KINETIS_SDID_SERIESID_KV:
/* KV10: FTFA, 1kB sectors */
pflash_sector_size_bytes = 1<<10;
num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
break;
case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX1:
/* KV11: FTFA, 2kB sectors */
pflash_sector_size_bytes = 2<<10;
num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
break;
case KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX0:
/* KV31: FTFA, 2kB sectors, 2 blocks */
pflash_sector_size_bytes = 2<<10;
/* autodetect 1 or 2 blocks */
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX2:
/* KV4x: FTFA, 4kB sectors */
pflash_sector_size_bytes = 4<<10;
num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
default:
}
break;
+ case KINETIS_SDID_SERIESID_KE:
+ /* KE1x-series */
+ switch (kinfo->sim_sdid &
+ (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK | KINETIS_SDID_PROJECTID_MASK)) {
+ case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX4 | KINETIS_SDID_PROJECTID_KE1xZ:
+ case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX5 | KINETIS_SDID_PROJECTID_KE1xZ:
+ /* KE1xZ: FTFE, 2kB sectors */
+ pflash_sector_size_bytes = 2<<10;
+ nvm_sector_size_bytes = 2<<10;
+ kinfo->max_flash_prog_size = 1<<9;
+ num_blocks = 2;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_L;
+ break;
+
+ case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX4 | KINETIS_SDID_PROJECTID_KE1xF:
+ case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX6 | KINETIS_SDID_PROJECTID_KE1xF:
+ case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX8 | KINETIS_SDID_PROJECTID_KE1xF:
+ /* KE1xF: FTFE, 4kB sectors */
+ pflash_sector_size_bytes = 4<<10;
+ nvm_sector_size_bytes = 2<<10;
+ kinfo->max_flash_prog_size = 1<<10;
+ num_blocks = 2;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_MSCM;
+ break;
+
+ default:
+ LOG_ERROR("Unsupported KE FAMILYID SUBFAMID");
+ }
+ break;
+
default:
LOG_ERROR("Unsupported K-series");
}