diff options
author | Yuval Peress <peress@chromium.org> | 2021-06-04 11:44:29 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-06-06 05:44:10 +0000 |
commit | f3dba7f80caccadb9938e6488b7878f096d4baf3 (patch) | |
tree | 4991e68f0c8b691d75abe4f3dbae35e3c0e587c1 /zephyr/shim/chip/npcx/system_download_from_flash.c | |
parent | 38f66c031143b89d40f9b8499242ca087d16ab8c (diff) | |
download | chrome-ec-f3dba7f80caccadb9938e6488b7878f096d4baf3.tar.gz |
zephyr: npcx9: implement system_download_from_flash
BRANCH=none
BUG=b:188605676
TEST=run `sysjump RW` on brya
Signed-off-by: Yuval Peress <peress@chromium.org>
Change-Id: Ic771a0452cd044355dd2a0e0f32fa6e2d3711a44
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2936009
Reviewed-by: Keith Short <keithshort@chromium.org>
Diffstat (limited to 'zephyr/shim/chip/npcx/system_download_from_flash.c')
-rw-r--r-- | zephyr/shim/chip/npcx/system_download_from_flash.c | 106 |
1 files changed, 105 insertions, 1 deletions
diff --git a/zephyr/shim/chip/npcx/system_download_from_flash.c b/zephyr/shim/chip/npcx/system_download_from_flash.c index 9e80df8f2d..bf50f736cd 100644 --- a/zephyr/shim/chip/npcx/system_download_from_flash.c +++ b/zephyr/shim/chip/npcx/system_download_from_flash.c @@ -3,11 +3,13 @@ * found in the LICENSE file. */ #include <stdnoreturn.h> +#include <sys/__assert.h> #include "common.h" #include "system_chip.h" /* Modules Map */ +#define NPCX_PMC_BASE_ADDR 0x4000D000 #define NPCX_GDMA_BASE_ADDR 0x40011000 /******************************************************************************/ @@ -15,6 +17,7 @@ #define NPCX_GDMA_CTL REG32(NPCX_GDMA_BASE_ADDR + 0x000) #define NPCX_GDMA_SRCB REG32(NPCX_GDMA_BASE_ADDR + 0x004) #define NPCX_GDMA_DSTB REG32(NPCX_GDMA_BASE_ADDR + 0x008) +#define NPCX_GDMA_TCNT REG32(NPCX_GDMA_BASE_ADDR + 0x00C) /******************************************************************************/ /* GDMA register fields */ @@ -33,6 +36,29 @@ #define NPCX_GDMA_CTL_GDMAERR 20 #define NPCX_GDMA_CTL_BLOCK_BUG_CORRECTION_DISABLE 26 +/******************************************************************************/ +/* Low Power RAM definitions */ +#define NPCX_LPRAM_CTRL REG32(0x40001044) + +/******************************************************************************/ +/* Power Management Controller (PMC) Registers */ +#define NPCX_PWDWN_CTL_ADDR(offset) (((offset) < 6) ? \ + (NPCX_PMC_BASE_ADDR + 0x008 + (offset)) : \ + (NPCX_PMC_BASE_ADDR + 0x024)) +#define NPCX_PWDWN_CTL(offset) REG8(NPCX_PWDWN_CTL_ADDR(offset)) + +/* PMC enumeration */ +enum NPCX_PMC_PWDWN_CTL_T { + NPCX_PMC_PWDWN_1 = 0, + NPCX_PMC_PWDWN_2 = 1, + NPCX_PMC_PWDWN_3 = 2, + NPCX_PMC_PWDWN_4 = 3, + NPCX_PMC_PWDWN_5 = 4, + NPCX_PMC_PWDWN_6 = 5, + NPCX_PMC_PWDWN_7 = 6, + NPCX_PMC_PWDWN_CNT, +}; + /* Sysjump utilities in low power ram for npcx series. */ noreturn void __keep __attribute__ ((section(".lowpower_ram2"))) __start_gdma(uint32_t exeAddr) @@ -68,4 +94,82 @@ __start_gdma(uint32_t exeAddr) /* Should never get here */ while (1) ; -}
\ No newline at end of file +} + +/* Begin address of Suspend RAM for little FW (GDMA utilities). */ +#define LFW_OFFSET 0x160 +uintptr_t __lpram_lfw_start = CONFIG_LPRAM_BASE + LFW_OFFSET; + +void system_download_from_flash(uint32_t srcAddr, uint32_t dstAddr, + uint32_t size, uint32_t exeAddr) +{ + int i; + uint8_t chunkSize = 16; /* 4 data burst mode. ie.16 bytes */ + /* + * GDMA utility in Suspend RAM. Setting bit 0 of address to indicate + * it's a thumb branch for cortex-m series CPU. + */ + void (*__start_gdma_in_lpram)(uint32_t) = + (void(*)(uint32_t))(__lpram_lfw_start | 0x01); + + /* + * Before enabling burst mode for better performance of GDMA, it's + * important to make sure srcAddr, dstAddr and size of transactions + * are 16 bytes aligned in case failure occurs. + */ + __ASSERT_NO_MSG((size % chunkSize) == 0 && (srcAddr % chunkSize) == 0 && + (dstAddr % chunkSize) == 0); + + /* Check valid address for jumpiing */ + __ASSERT_NO_MSG(exeAddr != 0x0); + + /* Enable power for the Low Power RAM */ + CLEAR_BIT(NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_6), 6); + + /* Enable Low Power RAM */ + NPCX_LPRAM_CTRL = 1; + + /* + * Initialize GDMA for flash reading. + * [31:21] - Reserved. + * [20] - GDMAERR = 0 (Indicate GMDA transfer error) + * [19] - Reserved. + * [18] - TC = 0 (Terminal Count. Indicate operation is end.) + * [17] - Reserved. + * [16] - SOFTREQ = 0 (Don't trigger here) + * [15] - DM = 0 (Set normal demand mode) + * [14] - Reserved. + * [13:12] - TWS. = 10 (One double-word for every GDMA transaction) + * [11:10] - Reserved. + * [9] - BME = 1 (4-data ie.16 bytes - Burst mode enable) + * [8] - SIEN = 0 (Stop interrupt disable) + * [7] - SAFIX = 0 (Fixed source address) + * [6] - Reserved. + * [5] - SADIR = 0 (Source address incremented) + * [4] - DADIR = 0 (Destination address incremented) + * [3:2] - GDMAMS = 00 (Software mode) + * [1] - Reserved. + * [0] - ENABLE = 0 (Don't enable yet) + */ + NPCX_GDMA_CTL = 0x00002200; + + /* Set source base address */ + NPCX_GDMA_SRCB = CONFIG_MAPPED_STORAGE_BASE + srcAddr; + + /* Set destination base address */ + NPCX_GDMA_DSTB = dstAddr; + + /* Set number of transfers */ + NPCX_GDMA_TCNT = (size / chunkSize); + + /* Clear Transfer Complete event */ + SET_BIT(NPCX_GDMA_CTL, NPCX_GDMA_CTL_TC); + + /* Copy the __start_gdma_in_lpram instructions to LPRAM */ + for (i = 0; i < &__flash_lplfw_end - &__flash_lplfw_start; i++) + *((uint32_t *)__lpram_lfw_start + i) = + *(&__flash_lplfw_start + i); + + /* Start GDMA in Suspend RAM */ + __start_gdma_in_lpram(exeAddr); +} |