kinetis : Add flash sector size detection for K21 MCU.
[fw/openocd] / src / flash / nor / kinetis.c
index 59750db0aef0d42b8050f8fb6da79dca914b4bc3..6512ce7602d62189f162b5b7e3db1bba60feb863 100644 (file)
  * 8:7 of the read-only SIM_SDID register reflect the granularity
  * settings 0..3, so sector sizes and block counts are applicable
  * according to the following table.
+ * NB. These undocumented bits does not work for all MCUs.
+ * A more reliable way is to detect the particular MCU model from the
+ * SDID field and pick the correct granularity based on that. See
+ * the handling of K21 in kinetis_read_part_info() for an example.
  */
 
 const struct {
@@ -120,6 +124,21 @@ const struct {
 #define FTFx_CMD_SETFLEXRAM 0x81
 #define FTFx_CMD_MASSERASE  0x44
 
+#define KINETIS_SDID_FAMID_MASK 0x00000070
+#define KINETIS_SDID_FAMID_K10  0x00000000
+#define KINETIS_SDID_FAMID_K12  0x00000000
+#define KINETIS_SDID_FAMID_K20  0x00000010
+#define KINETIS_SDID_FAMID_K22  0x00000010
+#define KINETIS_SDID_FAMID_K30  0x00000020
+#define KINETIS_SDID_FAMID_K11  0x00000020
+#define KINETIS_SDID_FAMID_K61  0x00000020
+#define KINETIS_SDID_FAMID_K40  0x00000030
+#define KINETIS_SDID_FAMID_K21  0x00000030
+#define KINETIS_SDID_FAMID_K60  0x00000040
+#define KINETIS_SDID_FAMID_K62  0x00000040
+#define KINETIS_SDID_FAMID_K70  0x00000050
+#define KINETIS_SDID_FAMID_KW24 0x00000060
+
 struct kinetis_flash_bank {
        unsigned granularity;
        unsigned bank_ordinal;
@@ -741,6 +760,9 @@ static int kinetis_read_part_info(struct flash_bank *bank)
        if (i == 1) {
                kinfo->klxx = 1;
                granularity = 0;
+       } else if ((kinfo->sim_sdid & KINETIS_SDID_FAMID_MASK)
+               == KINETIS_SDID_FAMID_K21) {
+               granularity = 2;
        } else
                granularity = (kinfo->sim_sdid >> 7) & 0x03;
 
@@ -1051,26 +1073,13 @@ static int kinetis_blank_check(struct flash_bank *bank)
        return ERROR_OK;
 }
 
-static int kinetis_flash_read(struct flash_bank *bank,
-               uint8_t *buffer, uint32_t offset, uint32_t count)
-{
-       LOG_WARNING("kinetis_flash_read not supported yet");
-
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       return ERROR_FLASH_OPERATION_FAILED;
-}
-
 struct flash_driver kinetis_flash = {
        .name = "kinetis",
        .flash_bank_command = kinetis_flash_bank_command,
        .erase = kinetis_erase,
        .protect = kinetis_protect,
        .write = kinetis_write,
-       .read = kinetis_flash_read,
+       .read = default_flash_read,
        .probe = kinetis_probe,
        .auto_probe = kinetis_auto_probe,
        .erase_check = kinetis_blank_check,