diff options
Diffstat (limited to 'chip/max32660/flash_chip.c')
-rw-r--r-- | chip/max32660/flash_chip.c | 404 |
1 files changed, 0 insertions, 404 deletions
diff --git a/chip/max32660/flash_chip.c b/chip/max32660/flash_chip.c deleted file mode 100644 index ace87294a7..0000000000 --- a/chip/max32660/flash_chip.c +++ /dev/null @@ -1,404 +0,0 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* MAX32660 Flash Memory Module for Chrome EC */ - -#include "flash.h" -#include "switch.h" -#include "system.h" -#include "timer.h" -#include "util.h" -#include "watchdog.h" -#include "registers.h" -#include "common.h" -#include "icc_regs.h" -#include "flc_regs.h" - -#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args) - -/***** Definitions *****/ - -/// Bit mask that can be used to find the starting address of a page in flash -#define MXC_FLASH_PAGE_MASK ~(MXC_FLASH_PAGE_SIZE - 1) - -/// Calculate the address of a page in flash from the page number -#define MXC_FLASH_PAGE_ADDR(page) \ - (MXC_FLASH_MEM_BASE + ((unsigned long)page * MXC_FLASH_PAGE_SIZE)) - -void flash_operation(void) -{ - volatile uint32_t *line_addr; - volatile uint32_t __attribute__((unused)) line; - - // Clear the cache - MXC_ICC->cache_ctrl ^= MXC_F_ICC_CACHE_CTRL_CACHE_EN; - MXC_ICC->cache_ctrl ^= MXC_F_ICC_CACHE_CTRL_CACHE_EN; - - // Clear the line fill buffer - line_addr = (uint32_t *)(MXC_FLASH_MEM_BASE); - line = *line_addr; - - line_addr = (uint32_t *)(MXC_FLASH_MEM_BASE + MXC_FLASH_PAGE_SIZE); - line = *line_addr; -} - -static int flash_busy(void) -{ - return (MXC_FLC->cn & - (MXC_F_FLC_CN_WR | MXC_F_FLC_CN_ME | MXC_F_FLC_CN_PGE)); -} - -static int flash_init_controller(void) -{ - // Set flash clock divider to generate a 1MHz clock from the APB clock - MXC_FLC->clkdiv = SystemCoreClock / 1000000; - - /* Check if the flash controller is busy */ - if (flash_busy()) { - return EC_ERROR_BUSY; - } - - /* Clear stale errors */ - if (MXC_FLC->intr & MXC_F_FLC_INTR_AF) { - MXC_FLC->intr &= ~MXC_F_FLC_INTR_AF; - } - - /* Unlock flash */ - MXC_FLC->cn = (MXC_FLC->cn & ~MXC_F_FLC_CN_UNLOCK) | - MXC_S_FLC_CN_UNLOCK_UNLOCKED; - - return EC_SUCCESS; -} - -static int flash_device_page_erase(uint32_t address) -{ - int err; - - if ((err = flash_init_controller()) != EC_SUCCESS) - return err; - - // Align address on page boundary - address = address - (address % MXC_FLASH_PAGE_SIZE); - - /* Write paflash_init_controllerde */ - MXC_FLC->cn = (MXC_FLC->cn & ~MXC_F_FLC_CN_ERASE_CODE) | - MXC_S_FLC_CN_ERASE_CODE_ERASEPAGE; - /* Issue page erase command */ - MXC_FLC->addr = address; - MXC_FLC->cn |= MXC_F_FLC_CN_PGE; - - /* Wait until flash operation is complete */ - while (flash_busy()) - ; - - /* Lock flash */ - MXC_FLC->cn &= ~MXC_F_FLC_CN_UNLOCK; - - /* Check access violations */ - if (MXC_FLC->intr & MXC_F_FLC_INTR_AF) { - MXC_FLC->intr &= ~MXC_F_FLC_INTR_AF; - return EC_ERROR_UNKNOWN; - } - - flash_operation(); - - return EC_SUCCESS; -} - -int flash_physical_write(int offset, int size, const char *data) -{ - int err; - uint32_t bytes_written; - uint8_t current_data[4]; - - if ((err = flash_init_controller()) != EC_SUCCESS) - return err; - - // write in 32-bit units until we are 128-bit aligned - MXC_FLC->cn &= ~MXC_F_FLC_CN_BRST; - MXC_FLC->cn |= MXC_F_FLC_CN_WDTH; - - // Align the address and read/write if we have to - if (offset & 0x3) { - - // Figure out how many bytes we have to write to round up the - // address - bytes_written = 4 - (offset & 0x3); - - // Save the data currently in the flash - memcpy(current_data, (void *)(offset & (~0x3)), 4); - - // Modify current_data to insert the data from buffer - memcpy(¤t_data[4 - bytes_written], data, bytes_written); - - // Write the modified data - MXC_FLC->addr = offset - (offset % 4); - memcpy((void *)&MXC_FLC->data[0], ¤t_data, 4); - MXC_FLC->cn |= MXC_F_FLC_CN_WR; - - /* Wait until flash operation is complete */ - while (flash_busy()) - ; - - offset += bytes_written; - size -= bytes_written; - data += bytes_written; - } - - while ((size >= 4) && ((offset & 0x1F) != 0)) { - MXC_FLC->addr = offset; - memcpy((void *)&MXC_FLC->data[0], data, 4); - MXC_FLC->cn |= MXC_F_FLC_CN_WR; - - /* Wait until flash operation is complete */ - while (flash_busy()) - ; - - offset += 4; - size -= 4; - data += 4; - } - - if (size >= 16) { - - // write in 128-bit bursts while we can - MXC_FLC->cn &= ~MXC_F_FLC_CN_WDTH; - - while (size >= 16) { - MXC_FLC->addr = offset; - memcpy((void *)&MXC_FLC->data[0], data, 16); - MXC_FLC->cn |= MXC_F_FLC_CN_WR; - - /* Wait until flash operation is complete */ - while (flash_busy()) - ; - - offset += 16; - size -= 16; - data += 16; - } - - // Return to 32-bit writes. - MXC_FLC->cn |= MXC_F_FLC_CN_WDTH; - } - - while (size >= 4) { - MXC_FLC->addr = offset; - memcpy((void *)&MXC_FLC->data[0], data, 4); - MXC_FLC->cn |= MXC_F_FLC_CN_WR; - - /* Wait until flash operation is complete */ - while (flash_busy()) - ; - - offset += 4; - size -= 4; - data += 4; - } - - if (size > 0) { - // Save the data currently in the flash - memcpy(current_data, (void *)(offset), 4); - - // Modify current_data to insert the data from data - memcpy(current_data, data, size); - - MXC_FLC->addr = offset; - memcpy((void *)&MXC_FLC->data[0], current_data, 4); - MXC_FLC->cn |= MXC_F_FLC_CN_WR; - - /* Wait until flash operation is complete */ - while (flash_busy()) - ; - } - - /* Lock flash */ - MXC_FLC->cn &= ~MXC_F_FLC_CN_UNLOCK; - - /* Check access violations */ - if (MXC_FLC->intr & MXC_F_FLC_INTR_AF) { - MXC_FLC->intr &= ~MXC_F_FLC_INTR_AF; - return EC_ERROR_UNKNOWN; - } - - flash_operation(); - - return EC_SUCCESS; -} - -/*****************************************************************************/ -/* Physical layer APIs */ - -int flash_physical_erase(int offset, int size) -{ - int i; - int pages; - int error_status; - - /* - * erase 'size' number of bytes starting at address 'offset' - */ - /* calculate the number of pages */ - pages = size / CONFIG_FLASH_ERASE_SIZE; - /* iterate over the number of pages */ - for (i = 0; i < pages; i++) { - /* erase the page after calculating the start address */ - error_status = flash_device_page_erase( - offset + (i * CONFIG_FLASH_ERASE_SIZE)); - if (error_status != EC_SUCCESS) { - return error_status; - } - } - return EC_SUCCESS; -} - -int flash_physical_get_protect(int bank) -{ - /* Not protected */ - return 0; -} - -uint32_t flash_physical_get_protect_flags(void) -{ - /* no flags set */ - return 0; -} - -uint32_t flash_physical_get_valid_flags(void) -{ - /* These are the flags we're going to pay attention to */ - return EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_RO_NOW | - EC_FLASH_PROTECT_ALL_NOW; -} - -uint32_t flash_physical_get_writable_flags(uint32_t cur_flags) -{ - /* no flags writable */ - return 0; -} - -int flash_physical_protect_at_boot(uint32_t new_flags) -{ - /* nothing to do here */ - return EC_SUCCESS; -} - -int flash_physical_protect_now(int all) -{ - /* nothing to do here */ - return EC_SUCCESS; -} - -/*****************************************************************************/ -/* High-level APIs */ - -int flash_pre_init(void) -{ - return EC_SUCCESS; -} - -/*****************************************************************************/ -/* Test Commands */ - -/* - * Read, Write, and Erase a page of flash memory using chip routines - * NOTE: This is a DESTRUCTIVE test for the range of flash pages tested - * make sure that PAGE_START is beyond your flash code. - */ -static int command_flash_test1(int argc, char **argv) -{ - int i; - uint8_t *ptr; - const uint32_t PAGE_START = 9; - const uint32_t PAGE_END = 32; - uint32_t page; - int error_status; - uint32_t flash_address; - const int BUFFER_SIZE = 32; - uint8_t buffer[BUFFER_SIZE]; - - /* - * As a test, write unique data to each page in this for loop, later - * verify data in pages - */ - for (page = PAGE_START; page < PAGE_END; page++) { - flash_address = page * CONFIG_FLASH_ERASE_SIZE; - - /* - * erase page - */ - error_status = flash_physical_erase(flash_address, - CONFIG_FLASH_ERASE_SIZE); - if (error_status != EC_SUCCESS) { - CPRINTS("Error with flash_physical_erase\n"); - return EC_ERROR_UNKNOWN; - } - - /* - * verify page was erased - */ - // CPRINTS("read flash page %d, address %x, ", page, - // flash_address); - ptr = (uint8_t *)flash_address; - for (i = 0; i < CONFIG_FLASH_ERASE_SIZE; i++) { - if (*ptr++ != 0xff) { - CPRINTS("Error with verifying page erase\n"); - return EC_ERROR_UNKNOWN; - } - } - - /* - * write pattern to page, just write BUFFER_SIZE worth of data - */ - for (i = 0; i < BUFFER_SIZE; i++) { - buffer[i] = i + page; - } - error_status = flash_physical_write(flash_address, BUFFER_SIZE, - buffer); - if (error_status != EC_SUCCESS) { - CPRINTS("Error with flash_physical_write\n"); - return EC_ERROR_UNKNOWN; - } - } - - /* - * Verify data in pages - */ - for (page = PAGE_START; page < PAGE_END; page++) { - flash_address = page * CONFIG_FLASH_ERASE_SIZE; - - /* - * read a portion of flash memory - */ - ptr = (uint8_t *)flash_address; - for (i = 0; i < BUFFER_SIZE; i++) { - if (*ptr++ != (i + page)) { - CPRINTS("Error with verifing written test " - "data\n"); - return EC_ERROR_UNKNOWN; - } - } - CPRINTS("Verified Erase, Write, Read page %d", page); - } - - /* - * Clean up after tests - */ - for (page = PAGE_START; page <= PAGE_END; page++) { - flash_address = page * CONFIG_FLASH_ERASE_SIZE; - error_status = flash_physical_erase(flash_address, - CONFIG_FLASH_ERASE_SIZE); - if (error_status != EC_SUCCESS) { - CPRINTS("Error with flash_physical_erase\n"); - return EC_ERROR_UNKNOWN; - } - } - - CPRINTS("done command_flash_test1."); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(flashtest1, command_flash_test1, "flashtest1", - "Flash chip routine tests"); |