openocd: fix SPDX tag format for files .c
[fw/openocd] / src / flash / nor / psoc5lp.c
index 87e130fb717ae1ae1ad54b8ba88084ee59b6f174..407efbcab312e28f359d06808ec152824a05f55f 100644 (file)
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /*
  * PSoC 5LP flash driver
  *
  * Copyright (c) 2016 Andreas Färber
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -29,6 +18,7 @@
 #define PM_ACT_CFG12            0x400043AC
 #define SPC_CPU_DATA            0x40004720
 #define SPC_SR                  0x40004722
+#define PRT1_PC2                0x4000500A
 #define PHUB_CH0_BASIC_CFG      0x40007010
 #define PHUB_CH0_ACTION         0x40007014
 #define PHUB_CH0_BASIC_STATUS   0x40007018
 #define PHUB_TDMEM1_ORIG_TD1    0x4000780C
 #define PANTHER_DEVICE_ID       0x4008001C
 
+/* NVL is not actually mapped to the Cortex-M address space
+ * As we need a base address different from other banks in the device
+ * we use the address of NVL programming data in Cypress images */
+#define NVL_META_BASE                  0x90000000
+
 #define PM_ACT_CFG12_EN_EE (1 << 4)
 
 #define SPC_KEY1 0xB6
 
 #define PM_ACT_CFG0_EN_CLK_SPC      (1 << 3)
 
-#define PHUB_CHx_BASIC_CFG_EN       (1 << 0)
-#define PHUB_CHx_BASIC_CFG_WORK_SEP (1 << 5)
+#define PHUB_CHX_BASIC_CFG_EN       (1 << 0)
+#define PHUB_CHX_BASIC_CFG_WORK_SEP (1 << 5)
 
-#define PHUB_CHx_ACTION_CPU_REQ (1 << 0)
+#define PHUB_CHX_ACTION_CPU_REQ (1 << 0)
 
-#define PHUB_CFGMEMx_CFG0 (1 << 7)
+#define PHUB_CFGMEMX_CFG0 (1 << 7)
 
-#define PHUB_TDMEMx_ORIG_TD0_NEXT_TD_PTR_LAST (0xff << 16)
-#define PHUB_TDMEMx_ORIG_TD0_INC_SRC_ADDR     (1 << 24)
+#define PHUB_TDMEMX_ORIG_TD0_NEXT_TD_PTR_LAST (0xff << 16)
+#define PHUB_TDMEMX_ORIG_TD0_INC_SRC_ADDR     (1 << 24)
 
 #define NVL_3_ECCEN  (1 << 3)
 
@@ -228,7 +223,8 @@ static void psoc5lp_get_part_number(const struct psoc5lp_device *dev, char *str)
        }
 
        /* Package does not matter. */
-       strncpy(str + 8, "xx", 2);
+       str[8] = 'x';
+       str[9] = 'x';
 
        /* Temperate range cannot uniquely be identified. */
        str[10] = 'x';
@@ -359,6 +355,31 @@ static int psoc5lp_spc_busy_wait_idle(struct target *target)
        return ERROR_FLASH_OPERATION_FAILED;
 }
 
+static int psoc5lp_spc_load_byte(struct target *target,
+       uint8_t array_id, uint8_t offset, uint8_t value)
+{
+       int retval;
+
+       retval = psoc5lp_spc_write_opcode(target, SPC_LOAD_BYTE);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u8(target, SPC_CPU_DATA, array_id);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u8(target, SPC_CPU_DATA, offset);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u8(target, SPC_CPU_DATA, value);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = psoc5lp_spc_busy_wait_idle(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
 static int psoc5lp_spc_load_row(struct target *target,
        uint8_t array_id, const uint8_t *data, unsigned row_size)
 {
@@ -446,6 +467,25 @@ static int psoc5lp_spc_write_row(struct target *target,
        return ERROR_OK;
 }
 
+static int psoc5lp_spc_write_user_nvl(struct target *target,
+       uint8_t array_id)
+{
+       int retval;
+
+       retval = psoc5lp_spc_write_opcode(target, SPC_WRITE_USER_NVL);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u8(target, SPC_CPU_DATA, array_id);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = psoc5lp_spc_busy_wait_idle(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
 static int psoc5lp_spc_erase_sector(struct target *target,
        uint8_t array_id, uint8_t row_id)
 {
@@ -545,6 +585,245 @@ static int psoc5lp_spc_get_temp(struct target *target, uint8_t samples,
        return ERROR_OK;
 }
 
+static int psoc5lp_spc_read_volatile_byte(struct target *target,
+       uint8_t array_id, uint8_t offset, uint8_t *data)
+{
+       int retval;
+
+       retval = psoc5lp_spc_write_opcode(target, SPC_READ_VOLATILE_BYTE);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u8(target, SPC_CPU_DATA, array_id);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u8(target, SPC_CPU_DATA, offset);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = psoc5lp_spc_busy_wait_data(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_read_u8(target, SPC_CPU_DATA, data);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = psoc5lp_spc_busy_wait_idle(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
+/*
+ * NV Latch
+ */
+
+struct psoc5lp_nvl_flash_bank {
+       bool probed;
+       const struct psoc5lp_device *device;
+};
+
+static int psoc5lp_nvl_read(struct flash_bank *bank,
+       uint8_t *buffer, uint32_t offset, uint32_t count)
+{
+       int retval;
+
+       retval = psoc5lp_spc_enable_clock(bank->target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       while (count > 0) {
+               retval = psoc5lp_spc_read_byte(bank->target,
+                               SPC_ARRAY_NVL_USER, offset, buffer);
+               if (retval != ERROR_OK)
+                       return retval;
+               buffer++;
+               offset++;
+               count--;
+       }
+
+       return ERROR_OK;
+}
+
+static int psoc5lp_nvl_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
+{
+       LOG_WARNING("There is no erase operation for NV Latches");
+       return ERROR_FLASH_OPER_UNSUPPORTED;
+}
+
+static int psoc5lp_nvl_erase_check(struct flash_bank *bank)
+{
+       for (unsigned int i = 0; i < bank->num_sectors; i++)
+               bank->sectors[i].is_erased = 0;
+
+       return ERROR_OK;
+}
+
+static int psoc5lp_nvl_write(struct flash_bank *bank,
+       const uint8_t *buffer, uint32_t offset, uint32_t byte_count)
+{
+       struct target *target = bank->target;
+       uint8_t *current_data, val;
+       bool write_required = false, pullup_needed = false, ecc_changed = false;
+       uint32_t i;
+       int retval;
+
+       if (offset != 0 || byte_count != bank->size) {
+               LOG_ERROR("NVL can only be written in whole");
+               return ERROR_FLASH_OPER_UNSUPPORTED;
+       }
+
+       current_data = calloc(1, bank->size);
+       if (!current_data)
+               return ERROR_FAIL;
+       retval = psoc5lp_nvl_read(bank, current_data, offset, byte_count);
+       if (retval != ERROR_OK) {
+               free(current_data);
+               return retval;
+       }
+       for (i = offset; i < byte_count; i++) {
+               if (current_data[i] != buffer[i]) {
+                       write_required = true;
+                       break;
+               }
+       }
+       if (((buffer[2] & 0x80) == 0x80) && ((current_data[0] & 0x0C) != 0x08))
+               pullup_needed = true;
+       if (((buffer[3] ^ current_data[3]) & 0x08) == 0x08)
+               ecc_changed = true;
+       free(current_data);
+
+       if (!write_required) {
+               LOG_INFO("Unchanged, skipping NVL write");
+               return ERROR_OK;
+       }
+       if (pullup_needed) {
+               retval = target_read_u8(target, PRT1_PC2, &val);
+               if (retval != ERROR_OK)
+                       return retval;
+               val &= 0xF0;
+               val |= 0x05;
+               retval = target_write_u8(target, PRT1_PC2, val);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
+       for (i = offset; i < byte_count; i++) {
+               retval = psoc5lp_spc_load_byte(target,
+                               SPC_ARRAY_NVL_USER, i, buffer[i]);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               retval = psoc5lp_spc_read_volatile_byte(target,
+                               SPC_ARRAY_NVL_USER, i, &val);
+               if (retval != ERROR_OK)
+                       return retval;
+               if (val != buffer[i]) {
+                       LOG_ERROR("Failed to load NVL byte %" PRIu32 ": "
+                               "expected 0x%02" PRIx8 ", read 0x%02" PRIx8,
+                               i, buffer[i], val);
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+       }
+
+       retval = psoc5lp_spc_write_user_nvl(target, SPC_ARRAY_NVL_USER);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (ecc_changed) {
+               retval = target_call_reset_callbacks(target, RESET_INIT);
+               if (retval != ERROR_OK)
+                       LOG_WARNING("Reset failed after enabling or disabling ECC");
+       }
+
+       return ERROR_OK;
+}
+
+static int psoc5lp_nvl_get_info_command(struct flash_bank *bank,
+       struct command_invocation *cmd)
+{
+       struct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;
+       char part_number[PART_NUMBER_LEN];
+
+       psoc5lp_get_part_number(psoc_nvl_bank->device, part_number);
+
+       command_print_sameline(cmd, "%s", part_number);
+
+       return ERROR_OK;
+}
+
+static int psoc5lp_nvl_probe(struct flash_bank *bank)
+{
+       struct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;
+       int retval;
+
+       if (psoc_nvl_bank->probed)
+               return ERROR_OK;
+
+       if (bank->target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       retval = psoc5lp_find_device(bank->target, &psoc_nvl_bank->device);
+       if (retval != ERROR_OK)
+               return retval;
+
+       bank->base = NVL_META_BASE;
+       bank->size = 4;
+       bank->num_sectors = 1;
+       bank->sectors = calloc(bank->num_sectors,
+                              sizeof(struct flash_sector));
+       bank->sectors[0].offset = 0;
+       bank->sectors[0].size = 4;
+       bank->sectors[0].is_erased = -1;
+       bank->sectors[0].is_protected = -1;
+
+       psoc_nvl_bank->probed = true;
+
+       return ERROR_OK;
+}
+
+static int psoc5lp_nvl_auto_probe(struct flash_bank *bank)
+{
+       struct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;
+
+       if (psoc_nvl_bank->probed)
+               return ERROR_OK;
+
+       return psoc5lp_nvl_probe(bank);
+}
+
+FLASH_BANK_COMMAND_HANDLER(psoc5lp_nvl_flash_bank_command)
+{
+       struct psoc5lp_nvl_flash_bank *psoc_nvl_bank;
+
+       psoc_nvl_bank = malloc(sizeof(struct psoc5lp_nvl_flash_bank));
+       if (!psoc_nvl_bank)
+               return ERROR_FLASH_OPERATION_FAILED;
+
+       psoc_nvl_bank->probed = false;
+
+       bank->driver_priv = psoc_nvl_bank;
+
+       return ERROR_OK;
+}
+
+const struct flash_driver psoc5lp_nvl_flash = {
+       .name = "psoc5lp_nvl",
+       .flash_bank_command = psoc5lp_nvl_flash_bank_command,
+       .info = psoc5lp_nvl_get_info_command,
+       .probe = psoc5lp_nvl_probe,
+       .auto_probe = psoc5lp_nvl_auto_probe,
+       .read = psoc5lp_nvl_read,
+       .erase = psoc5lp_nvl_erase,
+       .erase_check = psoc5lp_nvl_erase_check,
+       .write = psoc5lp_nvl_write,
+       .free_driver_priv = default_flash_free_driver_priv,
+};
+
 /*
  * EEPROM
  */
@@ -554,11 +833,12 @@ struct psoc5lp_eeprom_flash_bank {
        const struct psoc5lp_device *device;
 };
 
-static int psoc5lp_eeprom_erase(struct flash_bank *bank, int first, int last)
+static int psoc5lp_eeprom_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
-       int i, retval;
+       int retval;
 
-       for (i = first; i <= last; i++) {
+       for (unsigned int i = first; i <= last; i++) {
                retval = psoc5lp_spc_erase_sector(bank->target,
                                SPC_ARRAY_EEPROM, i);
                if (retval != ERROR_OK)
@@ -612,7 +892,7 @@ static int psoc5lp_eeprom_write(struct flash_bank *bank,
                memset(buf + byte_count, bank->default_padded_value,
                                EEPROM_ROW_SIZE - byte_count);
 
-               LOG_DEBUG("Padding %d bytes", EEPROM_ROW_SIZE - byte_count);
+               LOG_DEBUG("Padding %" PRIu32 " bytes", EEPROM_ROW_SIZE - byte_count);
                retval = psoc5lp_spc_load_row(target, SPC_ARRAY_EEPROM,
                                buf, EEPROM_ROW_SIZE);
                if (retval != ERROR_OK)
@@ -627,24 +907,14 @@ static int psoc5lp_eeprom_write(struct flash_bank *bank,
        return ERROR_OK;
 }
 
-static int psoc5lp_eeprom_protect_check(struct flash_bank *bank)
-{
-       int i;
-
-       for (i = 0; i < bank->num_sectors; i++)
-               bank->sectors[i].is_protected = -1;
-
-       return ERROR_OK;
-}
-
-static int psoc5lp_eeprom_get_info_command(struct flash_bank *bank, char *buf, int buf_size)
+static int psoc5lp_eeprom_get_info_command(struct flash_bank *bank, struct command_invocation *cmd)
 {
        struct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;
        char part_number[PART_NUMBER_LEN];
 
        psoc5lp_get_part_number(psoc_eeprom_bank->device, part_number);
 
-       snprintf(buf, buf_size, "%s", part_number);
+       command_print_sameline(cmd, "%s", part_number);
 
        return ERROR_OK;
 }
@@ -654,7 +924,7 @@ static int psoc5lp_eeprom_probe(struct flash_bank *bank)
        struct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;
        uint32_t flash_addr = bank->base;
        uint32_t val;
-       int i, retval;
+       int retval;
 
        if (psoc_eeprom_bank->probed)
                return ERROR_OK;
@@ -682,7 +952,7 @@ static int psoc5lp_eeprom_probe(struct flash_bank *bank)
        bank->num_sectors = DIV_ROUND_UP(bank->size, EEPROM_SECTOR_SIZE);
        bank->sectors = calloc(bank->num_sectors,
                               sizeof(struct flash_sector));
-       for (i = 0; i < bank->num_sectors; i++) {
+       for (unsigned int i = 0; i < bank->num_sectors; i++) {
                bank->sectors[i].size = EEPROM_SECTOR_SIZE;
                bank->sectors[i].offset = flash_addr - bank->base;
                bank->sectors[i].is_erased = -1;
@@ -724,33 +994,17 @@ FLASH_BANK_COMMAND_HANDLER(psoc5lp_eeprom_flash_bank_command)
        return ERROR_OK;
 }
 
-static const struct command_registration psoc5lp_eeprom_exec_command_handlers[] = {
-       COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration psoc5lp_eeprom_command_handlers[] = {
-       {
-               .name = "psoc5lp_eeprom",
-               .mode = COMMAND_ANY,
-               .help = "PSoC 5LP EEPROM command group",
-               .usage = "",
-               .chain = psoc5lp_eeprom_exec_command_handlers,
-       },
-       COMMAND_REGISTRATION_DONE
-};
-
-struct flash_driver psoc5lp_eeprom_flash = {
+const struct flash_driver psoc5lp_eeprom_flash = {
        .name = "psoc5lp_eeprom",
-       .commands = psoc5lp_eeprom_command_handlers,
        .flash_bank_command = psoc5lp_eeprom_flash_bank_command,
        .info = psoc5lp_eeprom_get_info_command,
        .probe = psoc5lp_eeprom_probe,
        .auto_probe = psoc5lp_eeprom_auto_probe,
-       .protect_check = psoc5lp_eeprom_protect_check,
        .read = default_flash_read,
        .erase = psoc5lp_eeprom_erase,
        .erase_check = default_flash_blank_check,
        .write = psoc5lp_eeprom_write,
+       .free_driver_priv = default_flash_free_driver_priv,
 };
 
 /*
@@ -761,29 +1015,34 @@ struct psoc5lp_flash_bank {
        bool probed;
        const struct psoc5lp_device *device;
        bool ecc_enabled;
+       /* If ecc is disabled, num_sectors counts both std and ecc sectors.
+        * If ecc is enabled, num_sectors indicates just the number of std sectors.
+        * However ecc sector descriptors bank->sector[num_sectors..2*num_sectors-1]
+        * are used for driver private flash operations */
 };
 
-static int psoc5lp_erase(struct flash_bank *bank, int first, int last)
+static int psoc5lp_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
        struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
-       int i, retval;
+       int retval;
 
        if (!psoc_bank->ecc_enabled) {
                /* Silently avoid erasing sectors twice */
                if (last >= first + bank->num_sectors / 2) {
-                       LOG_DEBUG("Skipping duplicate erase of sectors %d to %d",
+                       LOG_DEBUG("Skipping duplicate erase of sectors %u to %u",
                                first + bank->num_sectors / 2, last);
                        last = first + (bank->num_sectors / 2) - 1;
                }
                /* Check for any remaining ECC sectors */
                if (last >= bank->num_sectors / 2) {
-                       LOG_WARNING("Skipping erase of ECC region sectors %d to %d",
+                       LOG_WARNING("Skipping erase of ECC region sectors %u to %u",
                                bank->num_sectors / 2, last);
                        last = (bank->num_sectors / 2) - 1;
                }
        }
 
-       for (i = first; i <= last; i++) {
+       for (unsigned int i = first; i <= last; i++) {
                retval = psoc5lp_spc_erase_sector(bank->target,
                                i / SECTORS_PER_BLOCK, i % SECTORS_PER_BLOCK);
                if (retval != ERROR_OK)
@@ -798,47 +1057,63 @@ static int psoc5lp_erase_check(struct flash_bank *bank)
 {
        struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
        struct target *target = bank->target;
-       uint32_t blank;
-       int i, num_sectors, retval;
+       int retval;
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       num_sectors = bank->num_sectors;
-       if (!psoc_bank->ecc_enabled)
-               num_sectors /= 2;
+       unsigned int num_sectors = bank->num_sectors;
+       if (psoc_bank->ecc_enabled)
+               num_sectors *= 2;       /* count both std and ecc sector always */
 
-       for (i = 0; i < num_sectors; i++) {
-               uint32_t address = bank->base + bank->sectors[i].offset;
-               uint32_t size = bank->sectors[i].size;
+       struct target_memory_check_block *block_array;
+       block_array = malloc(num_sectors * sizeof(struct target_memory_check_block));
+       if (!block_array)
+               return ERROR_FAIL;
 
-               retval = armv7m_blank_check_memory(target, address, size,
-                               &blank, bank->erased_value);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               if (blank == 0x00 && !psoc_bank->ecc_enabled) {
-                       address = bank->base + bank->sectors[num_sectors + i].offset;
-                       size = bank->sectors[num_sectors + i].size;
+       for (unsigned int i = 0; i < num_sectors; i++) {
+               block_array[i].address = bank->base + bank->sectors[i].offset;
+               block_array[i].size = bank->sectors[i].size;
+               block_array[i].result = UINT32_MAX; /* erase state unknown */
+       }
 
-                       retval = armv7m_blank_check_memory(target, address, size,
-                                       &blank, bank->erased_value);
-                       if (retval != ERROR_OK)
-                               return retval;
+       bool fast_check = true;
+       for (unsigned int i = 0; i < num_sectors; ) {
+               retval = armv7m_blank_check_memory(target,
+                                       block_array + i, num_sectors - i,
+                                       bank->erased_value);
+               if (retval < 1) {
+                       /* Run slow fallback if the first run gives no result
+                        * otherwise use possibly incomplete results */
+                       if (i == 0)
+                               fast_check = false;
+                       break;
                }
+               i += retval; /* add number of blocks done this round */
+       }
 
-               if (blank == 0x00) {
-                       bank->sectors[i].is_erased = 1;
-                       bank->sectors[num_sectors + i].is_erased = 1;
+       if (fast_check) {
+               if (psoc_bank->ecc_enabled) {
+                       for (unsigned int i = 0; i < bank->num_sectors; i++)
+                               bank->sectors[i].is_erased =
+                                       (block_array[i].result != 1)
+                                       ? block_array[i].result
+                                       : block_array[i + bank->num_sectors].result;
+                               /* if std sector is erased, use status of ecc sector */
                } else {
-                       bank->sectors[i].is_erased = 0;
-                       bank->sectors[num_sectors + i].is_erased = 0;
+                       for (unsigned int i = 0; i < num_sectors; i++)
+                               bank->sectors[i].is_erased = block_array[i].result;
                }
+               retval = ERROR_OK;
+       } else {
+               LOG_ERROR("Can't run erase check - add working memory");
+               retval = ERROR_FAIL;
        }
+       free(block_array);
 
-       return ERROR_OK;
+       return retval;
 }
 
 static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
@@ -910,7 +1185,7 @@ static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
                        struct working_area *data_area = even_row ? even_row_area : odd_row_area;
                        unsigned len = MIN(ROW_SIZE, byte_count);
 
-                       LOG_DEBUG("Writing load command for array %u row %u at 0x%08" TARGET_PRIxADDR,
+                       LOG_DEBUG("Writing load command for array %u row %u at " TARGET_ADDR_FMT,
                                array_id, row, data_area->address);
 
                        psoc5lp_spc_write_opcode_buffer(target, buf, SPC_LOAD_ROW);
@@ -971,13 +1246,13 @@ static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
 
                        retval = target_write_u32(target,
                                even_row ? PHUB_CH0_BASIC_CFG : PHUB_CH1_BASIC_CFG,
-                               PHUB_CHx_BASIC_CFG_WORK_SEP | PHUB_CHx_BASIC_CFG_EN);
+                               PHUB_CHX_BASIC_CFG_WORK_SEP | PHUB_CHX_BASIC_CFG_EN);
                        if (retval != ERROR_OK)
                                goto err_dma;
 
                        retval = target_write_u32(target,
                                even_row ? PHUB_CFGMEM0_CFG0 : PHUB_CFGMEM1_CFG0,
-                               PHUB_CFGMEMx_CFG0);
+                               PHUB_CFGMEMX_CFG0);
                        if (retval != ERROR_OK)
                                goto err_dma;
 
@@ -989,8 +1264,8 @@ static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
 
                        retval = target_write_u32(target,
                                even_row ? PHUB_TDMEM0_ORIG_TD0 : PHUB_TDMEM1_ORIG_TD0,
-                               PHUB_TDMEMx_ORIG_TD0_INC_SRC_ADDR |
-                               PHUB_TDMEMx_ORIG_TD0_NEXT_TD_PTR_LAST |
+                               PHUB_TDMEMX_ORIG_TD0_INC_SRC_ADDR |
+                               PHUB_TDMEMX_ORIG_TD0_NEXT_TD_PTR_LAST |
                                ((SPC_OPCODE_LEN + 1 + row_size + 3 + SPC_OPCODE_LEN + 5) & 0xfff));
                        if (retval != ERROR_OK)
                                goto err_dma;
@@ -1007,7 +1282,7 @@ static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
 
                        retval = target_write_u32(target,
                                even_row ? PHUB_CH0_ACTION : PHUB_CH1_ACTION,
-                               PHUB_CHx_ACTION_CPU_REQ);
+                               PHUB_CHX_ACTION_CPU_REQ);
                        if (retval != ERROR_OK)
                                goto err_dma_action;
                }
@@ -1033,7 +1308,7 @@ static int psoc5lp_protect_check(struct flash_bank *bank)
        struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
        uint8_t row_data[ROW_SIZE];
        const unsigned protection_bytes_per_sector = ROWS_PER_SECTOR * 2 / 8;
-       unsigned i, j, k, num_sectors;
+       unsigned i, k, num_sectors;
        int retval;
 
        if (bank->target->state != TARGET_HALTED) {
@@ -1053,7 +1328,7 @@ static int psoc5lp_protect_check(struct flash_bank *bank)
                else
                        num_sectors = SECTORS_PER_BLOCK;
 
-               for (j = 0; j < num_sectors; j++) {
+               for (unsigned int j = 0; j < num_sectors; j++) {
                        int sector_nr = i * SECTORS_PER_BLOCK + j;
                        struct flash_sector *sector = &bank->sectors[sector_nr];
                        struct flash_sector *ecc_sector;
@@ -1079,7 +1354,7 @@ static int psoc5lp_protect_check(struct flash_bank *bank)
        return ERROR_OK;
 }
 
-static int psoc5lp_get_info_command(struct flash_bank *bank, char *buf, int buf_size)
+static int psoc5lp_get_info_command(struct flash_bank *bank, struct command_invocation *cmd)
 {
        struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
        char part_number[PART_NUMBER_LEN];
@@ -1088,7 +1363,7 @@ static int psoc5lp_get_info_command(struct flash_bank *bank, char *buf, int buf_
        psoc5lp_get_part_number(psoc_bank->device, part_number);
        ecc = psoc_bank->ecc_enabled ? "ECC enabled" : "ECC disabled";
 
-       snprintf(buf, buf_size, "%s %s", part_number, ecc);
+       command_print_sameline(cmd, "%s %s", part_number, ecc);
 
        return ERROR_OK;
 }
@@ -1099,7 +1374,7 @@ static int psoc5lp_probe(struct flash_bank *bank)
        struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
        uint32_t flash_addr = bank->base;
        uint8_t nvl[4], temp[2];
-       int i, retval;
+       int retval;
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
@@ -1130,7 +1405,7 @@ static int psoc5lp_probe(struct flash_bank *bank)
 
                bank->sectors = calloc(bank->num_sectors * 2,
                                       sizeof(struct flash_sector));
-               for (i = 0; i < bank->num_sectors; i++) {
+               for (unsigned int i = 0; i < bank->num_sectors; i++) {
                        bank->sectors[i].size = SECTOR_SIZE;
                        bank->sectors[i].offset = flash_addr - bank->base;
                        bank->sectors[i].is_erased = -1;
@@ -1139,7 +1414,7 @@ static int psoc5lp_probe(struct flash_bank *bank)
                        flash_addr += bank->sectors[i].size;
                }
                flash_addr = 0x48000000;
-               for (i = bank->num_sectors; i < bank->num_sectors * 2; i++) {
+               for (unsigned int i = bank->num_sectors; i < bank->num_sectors * 2; i++) {
                        bank->sectors[i].size = ROWS_PER_SECTOR * ROW_ECC_SIZE;
                        bank->sectors[i].offset = flash_addr - bank->base;
                        bank->sectors[i].is_erased = -1;
@@ -1184,9 +1459,9 @@ COMMAND_HANDLER(psoc5lp_handle_mass_erase_command)
 
        retval = psoc5lp_spc_erase_all(bank->target);
        if (retval == ERROR_OK)
-               command_print(CMD_CTX, "PSoC 5LP erase succeeded");
+               command_print(CMD, "PSoC 5LP erase succeeded");
        else
-               command_print(CMD_CTX, "PSoC 5LP erase failed");
+               command_print(CMD, "PSoC 5LP erase failed");
 
        return retval;
 }
@@ -1231,7 +1506,7 @@ static const struct command_registration psoc5lp_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-struct flash_driver psoc5lp_flash = {
+const struct flash_driver psoc5lp_flash = {
        .name = "psoc5lp",
        .commands = psoc5lp_command_handlers,
        .flash_bank_command = psoc5lp_flash_bank_command,
@@ -1243,4 +1518,5 @@ struct flash_driver psoc5lp_flash = {
        .erase = psoc5lp_erase,
        .erase_check = psoc5lp_erase_check,
        .write = psoc5lp_write,
+       .free_driver_priv = default_flash_free_driver_priv,
 };