summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2019-10-14 10:58:55 +0800
committerCommit Bot <commit-bot@chromium.org>2019-10-21 03:43:08 +0000
commit0152ee73ab98d29c252243547fd89e8713ca4e62 (patch)
treeaaf058998259e8c3c4cd775baa21aab17c0e1606 /chip
parentd88e38674b103108d0491638b506360f2204af28 (diff)
downloadchrome-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.h13
-rw-r--r--chip/it83xx/config_chip_it8xxx2.h2
-rw-r--r--chip/it83xx/flash.c75
-rw-r--r--chip/it83xx/registers.h3
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