From 9c47f314a56e1ee0dfa56ff9cd41f8d851712b1b Mon Sep 17 00:00:00 2001 From: Dino Li Date: Wed, 11 Aug 2021 16:18:57 +0800 Subject: [PATCH] flash: it8xxx2: add a short delay before #CS be driven high The delay will ensure last byte has been latched in before This also change the method of reading status register from re-send read status command on each read to read status register continuously. Signed-off-by: Dino Li --- drivers/flash/flash_ite_it8xxx2.c | 30 ++++++++++++++++------ soc/riscv/riscv-ite/common/chip_chipregs.h | 5 ++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/flash/flash_ite_it8xxx2.c b/drivers/flash/flash_ite_it8xxx2.c index a01d1c4afa1..b66a86da6a2 100644 --- a/drivers/flash/flash_ite_it8xxx2.c +++ b/drivers/flash/flash_ite_it8xxx2.c @@ -159,6 +159,18 @@ void __ram_code ramcode_flash_fsce_high(void) /* FSCE# high level */ flash_regs->SMFI_ECINDAR1 = (FLASH_FSCE_HIGH_ADDRESS >> 8) & GENMASK(7, 0); + /* + * A short delay (15~30 us) before #CS be driven high to ensure + * last byte has been latched in. + * + * For a loop that writing 0 to WNCKR register for N times, the delay + * value will be: ((N-1) / 65.536 kHz) to (N / 65.536 kHz). + * So we perform 2 consecutive writes to WNCKR here to ensure the + * minimum delay is 15us. + */ + IT83XX_GCTRL_WNCKR = 0; + IT83XX_GCTRL_WNCKR = 0; + /* Writing 0 to EC-indirect memory data register */ flash_regs->SMFI_ECINDDR = 0x00; } @@ -197,9 +209,12 @@ void __ram_code ramcode_flash_transaction(int wlen, uint8_t *wbuf, int rlen, void __ram_code ramcode_flash_cmd_read_status(enum flash_status_mask mask, enum flash_status_mask target) { - uint8_t status[1]; + struct flash_it8xxx2_regs *const flash_regs = FLASH_IT8XXX2_REG_BASE; uint8_t cmd_rs[] = {FLASH_CMD_RS}; + /* Send read status command */ + ramcode_flash_transaction(sizeof(cmd_rs), cmd_rs, 0, NULL, CMD_CONTINUE); + /* * We prefer no timeout here. We can always get the status * we want, or wait for watchdog triggered to check @@ -207,14 +222,13 @@ void __ram_code ramcode_flash_cmd_read_status(enum flash_status_mask mask, * This will avoid fetching unknown instruction from e-flash * and causing exception. */ - while (1) { - /* read status */ - ramcode_flash_transaction(sizeof(cmd_rs), cmd_rs, 1, status, CMD_END); - /* only bit[1:0] valid */ - if ((status[0] & mask) == target) { - break; - } + while ((flash_regs->SMFI_ECINDDR & mask) != target) { + /* read status and check if it is we want. */ + ; } + + /* transaction done, drive #CS high */ + ramcode_flash_fsce_high(); } void __ram_code ramcode_flash_cmd_write_enable(void) diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/riscv-ite/common/chip_chipregs.h index 7b2a9d03900..759364f554d 100644 --- a/soc/riscv/riscv-ite/common/chip_chipregs.h +++ b/soc/riscv/riscv-ite/common/chip_chipregs.h @@ -1856,6 +1856,11 @@ enum chip_pll_mode { #define IT83XX_GCTRL_CHIPVER ECREG(IT83XX_GCTRL_BASE + 0x02) #define IT83XX_GCTRL_DBGROS ECREG(IT83XX_GCTRL_BASE + 0x03) #define IT83XX_SMB_DBGR BIT(0) + +/* + * Writing 00h to this register and the CPU program counter will be paused + * until the next low to high transition of the 65.536 clock. + */ #define IT83XX_GCTRL_WNCKR ECREG(IT83XX_GCTRL_BASE + 0x0B) #define IT83XX_GCTRL_RSTS ECREG(IT83XX_GCTRL_BASE + 0x06) #define IT83XX_GCTRL_BADRSEL ECREG(IT83XX_GCTRL_BASE + 0x0A)