diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2019-10-14 10:58:55 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-21 03:43:08 +0000 |
commit | 0152ee73ab98d29c252243547fd89e8713ca4e62 (patch) | |
tree | aaf058998259e8c3c4cd775baa21aab17c0e1606 /chip | |
parent | d88e38674b103108d0491638b506360f2204af28 (diff) | |
download | chrome-ec-0152ee73ab98d29c252243547fd89e8713ca4e62.tar.gz |
it83xx/flash: add support for KGD flash
Embedded flash of it8xxx2 is KGD, so we made this change
to support it.
BUG=b:133460224
BRANCH=none
TEST=On both it83202 and it8320 EVBs, verify flasherase and flashwrite
console commands.
Change-Id: Idde0846eb8c59a330ccf69d7f6b7aa352c623caa
Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1844657
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/it83xx/config_chip.h | 13 | ||||
-rw-r--r-- | chip/it83xx/config_chip_it8xxx2.h | 2 | ||||
-rw-r--r-- | chip/it83xx/flash.c | 75 | ||||
-rw-r--r-- | chip/it83xx/registers.h | 3 |
4 files changed, 79 insertions, 14 deletions
diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h index e06fb5c62c..40bf280276 100644 --- a/chip/it83xx/config_chip.h +++ b/chip/it83xx/config_chip.h @@ -46,8 +46,13 @@ /* Default task stack size */ #define TASK_STACK_SIZE (512 + CHIP_EXTRA_STACK_SPACE) +#ifdef IT83XX_CHIP_FLASH_IS_KGD +#define CONFIG_FLASH_BANK_SIZE 0x00001000 /* protect bank size */ +#define CONFIG_FLASH_ERASE_SIZE 0x00001000 /* erase bank size */ +#else #define CONFIG_FLASH_BANK_SIZE 0x00000800 /* protect bank size */ #define CONFIG_FLASH_ERASE_SIZE 0x00000400 /* erase bank size */ +#endif #define CONFIG_FLASH_WRITE_SIZE 0x00000004 /* minimum write size */ /* @@ -57,11 +62,19 @@ */ #define IT83XX_ILM_BLOCK_SIZE 0x00001000 +#ifdef IT83XX_CHIP_FLASH_IS_KGD +/* + * One page program instruction allows maximum 256 bytes (a page) of data + * to be programmed. + */ +#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 +#else /* * The AAI program instruction allows continue write flash * until write disable instruction. */ #define CONFIG_FLASH_WRITE_IDEAL_SIZE CONFIG_FLASH_ERASE_SIZE +#endif /****************************************************************************/ /* Define our flash layout. */ diff --git a/chip/it83xx/config_chip_it8xxx2.h b/chip/it83xx/config_chip_it8xxx2.h index deef92893d..88a1ee4960 100644 --- a/chip/it83xx/config_chip_it8xxx2.h +++ b/chip/it83xx/config_chip_it8xxx2.h @@ -33,6 +33,8 @@ #if defined(CHIP_VARIANT_IT83202BX) /* TODO(b/133460224): enable properly chip config option. */ #define CONFIG_FLASH_SIZE 0x00080000 +/* Embedded flash is KGD */ +#define IT83XX_CHIP_FLASH_IS_KGD /* chip id is 3 bytes */ #define IT83XX_CHIP_ID_3BYTES /* diff --git a/chip/it83xx/flash.c b/chip/it83xx/flash.c index ec416ee41a..40f16ac08e 100644 --- a/chip/it83xx/flash.c +++ b/chip/it83xx/flash.c @@ -20,10 +20,24 @@ #define FLASH_DMA_START ((uint32_t) &__flash_dma_start) #define FLASH_DMA_CODE __attribute__((section(".flash_direct_map"))) -#define FLASH_SECTOR_ERASE_SIZE 0x00000400 - +/* erase size of sector is 1KB or 4KB */ +#define FLASH_SECTOR_ERASE_SIZE CONFIG_FLASH_ERASE_SIZE + +#ifdef IT83XX_CHIP_FLASH_IS_KGD +/* page program command */ +#define FLASH_CMD_PAGE_WRITE 0x2 +/* ector erase command (erase size is 4KB) */ +#define FLASH_CMD_SECTOR_ERASE 0x20 +/* command for flash write */ +#define FLASH_CMD_WRITE FLASH_CMD_PAGE_WRITE +#else +/* Auto address increment programming */ +#define FLASH_CMD_AAI_WORD 0xAD /* Flash sector erase (1K bytes) command */ -#define FLASH_CMD_SECTOR_ERASE 0xD7 +#define FLASH_CMD_SECTOR_ERASE 0xD7 +/* command for flash write */ +#define FLASH_CMD_WRITE FLASH_CMD_AAI_WORD +#endif /* Write status register */ #define FLASH_CMD_WRSR 0x01 /* Write disable */ @@ -32,8 +46,6 @@ #define FLASH_CMD_WREN 0x06 /* Read status register */ #define FLASH_CMD_RS 0x05 -/* Auto address increment programming */ -#define FLASH_CMD_AAI_WORD 0xAD #define FLASH_TEXT_START ((uint32_t) &__flash_text_start) /* The default tag index of immu. */ @@ -249,16 +261,48 @@ void FLASH_DMA_CODE dma_flash_cmd_erase(int addr, int cmd) dma_flash_follow_mode_exit(); } -void FLASH_DMA_CODE dma_flash_cmd_aai_write(int addr, int wlen, uint8_t *wbuf) +void FLASH_DMA_CODE dma_flash_cmd_write(int addr, int wlen, uint8_t *wbuf) { int i; - uint8_t aai_write[] = {FLASH_CMD_AAI_WORD, ((addr >> 16) & 0xFF), + uint8_t flash_write[] = {FLASH_CMD_WRITE, ((addr >> 16) & 0xFF), ((addr >> 8) & 0xFF), (addr & 0xFF)}; /* enter EC-indirect follow mode */ dma_flash_follow_mode(); - /* send aai word command */ - dma_flash_transaction(sizeof(aai_write), aai_write, 0, NULL, 0); + /* send flash write command (aai word or page program) */ + dma_flash_transaction(sizeof(flash_write), flash_write, 0, NULL, 0); +#ifdef IT83XX_CHIP_FLASH_IS_KGD + for (i = 0; i < wlen; i++) { + /* send data byte */ + dma_flash_write_dat(wbuf[i]); + + /* + * we want to restart the write sequence every IDEAL_SIZE + * chunk worth of data. + */ + if (!(++addr % CONFIG_FLASH_WRITE_IDEAL_SIZE)) { + uint8_t w_en[] = {FLASH_CMD_WREN}; + + dma_flash_fsce_high(); + /* make sure busy bit cleared. */ + dma_flash_cmd_read_status(FLASH_SR_BUSY, + FLASH_SR_NO_BUSY); + /* send write enable command */ + dma_flash_transaction(sizeof(w_en), w_en, 0, NULL, 1); + /* make sure busy bit cleared and write enabled. */ + dma_flash_cmd_read_status(FLASH_SR_ALL, FLASH_SR_WEL); + /* re-send write command */ + flash_write[1] = (addr >> 16) & 0xff; + flash_write[2] = (addr >> 8) & 0xff; + flash_write[3] = addr & 0xff; + dma_flash_transaction(sizeof(flash_write), flash_write, + 0, NULL, 0); + } + } + dma_flash_fsce_high(); + /* make sure busy bit cleared. */ + dma_flash_cmd_read_status(FLASH_SR_BUSY, FLASH_SR_NO_BUSY); +#else for (i = 0; i < wlen; i += 2) { dma_flash_write_dat(wbuf[i]); dma_flash_write_dat(wbuf[i + 1]); @@ -267,8 +311,9 @@ void FLASH_DMA_CODE dma_flash_cmd_aai_write(int addr, int wlen, uint8_t *wbuf) dma_flash_cmd_read_status(FLASH_SR_BUSY, FLASH_SR_NO_BUSY); /* resend aai word command without address field */ if ((i + 2) < wlen) - dma_flash_transaction(1, aai_write, 0, NULL, 0); + dma_flash_transaction(1, flash_write, 0, NULL, 0); } +#endif /* exit EC-indirect follow mode */ dma_flash_follow_mode_exit(); } @@ -306,10 +351,10 @@ int FLASH_DMA_CODE dma_flash_verify(int addr, int size, const char *data) return EC_SUCCESS; } -void FLASH_DMA_CODE dma_flash_aai_write(int addr, int wlen, const char *wbuf) +void FLASH_DMA_CODE dma_flash_write(int addr, int wlen, const char *wbuf) { dma_flash_cmd_write_enable(); - dma_flash_cmd_aai_write(addr, wlen, (uint8_t *)wbuf); + dma_flash_cmd_write(addr, wlen, (uint8_t *)wbuf); dma_flash_cmd_write_disable(); } @@ -406,7 +451,7 @@ int FLASH_DMA_CODE flash_physical_write(int offset, int size, const char *data) */ interrupt_disable(); - dma_flash_aai_write(offset, size, data); + dma_flash_write(offset, size, data); dma_reset_immu((offset + size) >= IMMU_TAG_INDEX_BY_DEFAULT); ret = dma_flash_verify(offset, size, data); @@ -440,7 +485,7 @@ int FLASH_DMA_CODE flash_physical_erase(int offset, int size) */ interrupt_disable(); - /* Always use sector erase command (1K bytes) */ + /* Always use sector erase command (1K or 4K bytes) */ for (; size > 0; size -= FLASH_SECTOR_ERASE_SIZE) { dma_flash_erase(offset, FLASH_CMD_SECTOR_ERASE); offset += FLASH_SECTOR_ERASE_SIZE; @@ -610,6 +655,8 @@ int flash_pre_init(void) /* By default, select internal flash for indirect fast read. */ IT83XX_SMFI_ECINDAR3 = EC_INDIRECT_READ_INTERNAL_FLASH; + if (IS_ENABLED(IT83XX_CHIP_FLASH_IS_KGD)) + IT83XX_SMFI_FLHCTRL6R |= IT83XX_SMFI_MASK_ECINDPP; flash_code_static_dma(); reset_flags = system_get_reset_flags(); diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index b35e36c255..fbe0c1d295 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -1047,6 +1047,9 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4)) #define IT83XX_SMFI_SCAR2H REG8(IT83XX_SMFI_BASE+0x48) #define IT83XX_SMFI_FLHCTRL3R REG8(IT83XX_SMFI_BASE+0x63) #define IT83XX_SMFI_STCDMACR REG8(IT83XX_SMFI_BASE+0x80) +#define IT83XX_SMFI_FLHCTRL6R REG8(IT83XX_SMFI_BASE+0xA2) +/* Enable EC-indirect page program command */ +#define IT83XX_SMFI_MASK_ECINDPP BIT(3) /* Serial Peripheral Interface (SSPI) */ #define IT83XX_SSPI_BASE 0x00F02600 |