summaryrefslogtreecommitdiff
path: root/zephyr/shim/chip/npcx/system_download_from_flash.c
diff options
context:
space:
mode:
authorYuval Peress <peress@chromium.org>2021-06-04 11:44:29 -0600
committerCommit Bot <commit-bot@chromium.org>2021-06-06 05:44:10 +0000
commitf3dba7f80caccadb9938e6488b7878f096d4baf3 (patch)
tree4991e68f0c8b691d75abe4f3dbae35e3c0e587c1 /zephyr/shim/chip/npcx/system_download_from_flash.c
parent38f66c031143b89d40f9b8499242ca087d16ab8c (diff)
downloadchrome-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.c106
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);
+}