summaryrefslogtreecommitdiff
path: root/zephyr/shim/chip/mchp
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/shim/chip/mchp')
-rw-r--r--zephyr/shim/chip/mchp/include/flash_chip.h16
-rw-r--r--zephyr/shim/chip/mchp/system.c23
-rw-r--r--zephyr/shim/chip/mchp/system_download_from_flash.c18
-rw-r--r--zephyr/shim/chip/mchp/system_external_storage.c89
4 files changed, 117 insertions, 29 deletions
diff --git a/zephyr/shim/chip/mchp/include/flash_chip.h b/zephyr/shim/chip/mchp/include/flash_chip.h
index 9af8bd330d..b3677fb45c 100644
--- a/zephyr/shim/chip/mchp/include/flash_chip.h
+++ b/zephyr/shim/chip/mchp/include/flash_chip.h
@@ -11,15 +11,19 @@
* Similar to W25X40, both only have one status reg
*/
#define CONFIG_SPI_FLASH_W25X40 /* Internal SPI flash type. */
-
#define CONFIG_FLASH_WRITE_SIZE 0x1 /* minimum write size */
#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 /* one page size for write */
-#define CONFIG_FLASH_ERASE_SIZE 0x10000
+#define CONFIG_FLASH_ERASE_SIZE 0x1000
#define CONFIG_FLASH_BANK_SIZE CONFIG_FLASH_ERASE_SIZE
-/* RO image resides at start of protected region, right after header */
-#define CONFIG_RO_STORAGE_OFF CONFIG_RO_HDR_SIZE
-
-#define CONFIG_RW_STORAGE_OFF 0
+/* RO image resides at 4KB offset in protected region
+ * The first 4KB in the protected region starting at offset 0 contains
+ * the Boot-ROM TAGs and Boot-ROM Header for EC_RO. These objects are
+ * not loaded into RAM.
+ * RW image is never loaded by the Boot-ROM therefore no TAG or Header
+ * is needed. RW starts at offset 0 in RW storage region.
+ */
+#define CONFIG_RO_STORAGE_OFF 0x1000
+#define CONFIG_RW_STORAGE_OFF 0
#endif /* __CROS_EC_FLASH_CHIP_H */
diff --git a/zephyr/shim/chip/mchp/system.c b/zephyr/shim/chip/mchp/system.c
index f4e0d09d4d..25fdfc9897 100644
--- a/zephyr/shim/chip/mchp/system.c
+++ b/zephyr/shim/chip/mchp/system.c
@@ -11,6 +11,29 @@
LOG_MODULE_REGISTER(shim_xec_system, LOG_LEVEL_ERR);
+#define GET_BBRAM_OFS(node) \
+ DT_PROP(DT_PATH(named_bbram_regions, node), offset)
+#define GET_BBRAM_SZ(node) DT_PROP(DT_PATH(named_bbram_regions, node), size)
+
+/*
+ * Reset image type back to RO in BBRAM as watchdog resets.
+ * Watchdog reset will reset EC chip, ROM loader loads RO
+ * image stored in SPI flash chip in default.
+ */
+void cros_chip_wdt_handler(const struct device *wdt_dev, int channel_id)
+{
+ const struct device *bbram_dev = DEVICE_DT_GET(DT_NODELABEL(bbram));
+ uint32_t value = EC_IMAGE_RO;
+
+ if (!device_is_ready(bbram_dev)) {
+ LOG_ERR("WDT ISR: device %s is not ready", bbram_dev->name);
+ return;
+ }
+
+ bbram_write(bbram_dev, GET_BBRAM_OFS(ec_img_load),
+ GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value);
+}
+
static void chip_bbram_status_check(void)
{
const struct device *bbram_dev;
diff --git a/zephyr/shim/chip/mchp/system_download_from_flash.c b/zephyr/shim/chip/mchp/system_download_from_flash.c
index 665db2cccd..99026fe822 100644
--- a/zephyr/shim/chip/mchp/system_download_from_flash.c
+++ b/zephyr/shim/chip/mchp/system_download_from_flash.c
@@ -10,6 +10,10 @@
#include "system_chip.h"
/* Modules Map */
+#define WDT_NODE DT_INST(0, microchip_xec_watchdog)
+#define STRUCT_WDT_REG_BASE_ADDR \
+ ((struct wdt_regs *)(DT_REG_ADDR(WDT_NODE)))
+
#define PCR_NODE DT_INST(0, microchip_xec_pcr)
#define STRUCT_PCR_REG_BASE_ADDR \
((struct pcr_regs *)DT_REG_ADDR_BY_IDX(PCR_NODE, 0))
@@ -26,15 +30,15 @@
(MCHP_QMSPI_STS_DONE | MCHP_QMSPI_STS_DMA_DONE)
#define QSPI_STATUS_ERR \
- (MCHP_QMSPI_STS_TXB_ERR | MCHP_QMSPI_STS_RXB_ERR | \
+ (MCHP_QMSPI_STS_TXB_ERR | MCHP_QMSPI_STS_RXB_ERR | \
MCHP_QMSPI_STS_PROG_ERR | MCHP_QMSPI_STS_LDMA_RX_ERR)
-
noreturn void __keep __attribute__ ((section(".code_in_sram2")))
__start_qspi(uint32_t resetVectAddr)
{
struct pcr_regs *pcr = STRUCT_PCR_REG_BASE_ADDR;
struct qmspi_regs *qspi = STRUCT_QSPI_REG_BASE_ADDR;
+ struct wdt_regs *wdt = STRUCT_WDT_REG_BASE_ADDR;
uint32_t qsts = 0;
uint32_t exeAddr = 0;
@@ -47,6 +51,9 @@ __start_qspi(uint32_t resetVectAddr)
break;
}
+ /* Stop the watchdog */
+ wdt->CTRL &= ~MCHP_WDT_CTRL_EN;
+
qspi->MODE &= ~(MCHP_QMSPI_M_ACTIVATE);
if (qsts & QSPI_STATUS_ERR) {
pcr->SYS_RST |= MCHP_PCR_SYS_RESET_NOW;
@@ -67,8 +74,7 @@ __start_qspi(uint32_t resetVectAddr)
;
}
-/* PK SCM */
-uintptr_t __lfw_sram_start = 0x127800;
+uintptr_t __lfw_sram_start = CONFIG_CROS_EC_RAM_BASE + CONFIG_CROS_EC_RAM_SIZE;
typedef void (*START_QSPI_IN_SRAM_FP)(uint32_t);
@@ -85,9 +91,9 @@ void system_download_from_flash(uint32_t srcAddr, uint32_t dstAddr,
/* Check valid address for jumpiing */
__ASSERT_NO_MSG(exeAddr != 0x0);
-
+ /* Configure QMSPI controller */
qspi->MODE = MCHP_QMSPI_M_SRST;
- fdiv = 4;
+ fdiv = 2;
if (pcr->TURBO_CLK & MCHP_PCR_TURBO_CLK_96M)
fdiv *= 2;
diff --git a/zephyr/shim/chip/mchp/system_external_storage.c b/zephyr/shim/chip/mchp/system_external_storage.c
index 2c7312db3a..c326a07328 100644
--- a/zephyr/shim/chip/mchp/system_external_storage.c
+++ b/zephyr/shim/chip/mchp/system_external_storage.c
@@ -4,13 +4,35 @@
*/
#include <zephyr/devicetree.h>
-#include <zephyr/drivers/syscon.h>
+#include <zephyr/drivers/bbram.h>
+#include <soc.h>
#include "clock_chip.h"
#include "common.h"
#include "system.h"
#include "system_chip.h"
+#include "config_chip.h"
+#define MCHP_ECRO_WORD 0x4F524345u /* ASCII ECRO */
+#define MCHP_ECRW_WORD 0x57524345u /* ASCII ECRW */
+#define MCHP_PCR_NODE DT_INST(0, microchip_xec_pcr)
+
+#define GET_BBRAM_OFS(node) \
+ DT_PROP(DT_PATH(named_bbram_regions, node), offset)
+#define GET_BBRAM_SZ(node) DT_PROP(DT_PATH(named_bbram_regions, node), size)
+
+static const struct device *const bbram_dev =
+ COND_CODE_1(DT_HAS_CHOSEN(cros_ec_bbram),
+ DEVICE_DT_GET(DT_CHOSEN(cros_ec_bbram)), NULL);
+
+/* Build image type string in RO/RW image */
+#ifdef CONFIG_CROS_EC_RO
+const uint32_t mchp_image_type = MCHP_ECRO_WORD;
+#elif CONFIG_CROS_EC_RW
+const uint32_t mchp_image_type = MCHP_ECRW_WORD;
+#else
+#error "Unsupported image type!"
+#endif
/*
* Make sure CONFIG_XXX flash offsets are correct for MEC172x 512KB SPI flash.
@@ -29,19 +51,12 @@ void system_jump_to_booter(void)
case EC_IMAGE_RW:
flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF;
- flash_used = CONFIG_RW_SIZE;
- break;
-#ifdef CONFIG_RW_B
- case EC_IMAGE_RW_B:
- flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
- CONFIG_RW_B_STORAGE_OFF;
- flash_used = CONFIG_RW_SIZE;
+ flash_used = CONFIG_CROS_EC_RW_SIZE;
break;
-#endif
case EC_IMAGE_RO:
default: /* Jump to RO by default */
- flash_offset = 0x100; /* 256 bytes */
- flash_used = (352 * 1024);
+ flash_offset = CONFIG_PLATFORM_EC_RO_HEADER_OFFSET;
+ flash_used = CONFIG_CROS_EC_RO_SIZE;
break;
}
@@ -53,9 +68,11 @@ void system_jump_to_booter(void)
/* MCHP Read selected image from SPI flash into SRAM
* Need a jump to little-fw (LFW).
- * MEC172x Boot-ROM load API is probably not usuable for this.
*/
- system_download_from_flash(flash_offset, 0xC0000u, flash_used, 0xC0004);
+ system_download_from_flash(flash_offset,
+ CONFIG_CROS_EC_PROGRAM_MEMORY_BASE,
+ flash_used,
+ (CONFIG_CROS_EC_PROGRAM_MEMORY_BASE + 4u));
}
uint32_t system_get_lfw_address(void)
@@ -66,13 +83,51 @@ uint32_t system_get_lfw_address(void)
enum ec_image system_get_shrspi_image_copy(void)
{
- return EC_IMAGE_RO;
+ enum ec_image img = EC_IMAGE_UNKNOWN;
+ uint32_t value = 0u;
+
+ if (bbram_dev) {
+ if (!bbram_read(bbram_dev, GET_BBRAM_OFS(ec_img_load),
+ GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value)) {
+ img = (enum ec_image)(value & 0x7fu);
+ }
+ }
+
+ if (img == EC_IMAGE_UNKNOWN) {
+ img = EC_IMAGE_RO;
+ if (mchp_image_type == MCHP_ECRW_WORD) {
+ img = EC_IMAGE_RW;
+ }
+ system_set_image_copy(img);
+ }
+
+ return img;
}
-/*
- * This configures HW to point to EC_RW or EC_RO.
+/* Flash is not memory mapped. Store a flag indicating the image.
+ * ECS WDT_CNT is register available to applications. It implements bits[3:0]
+ * which are not reset by a watch dog event only by VTR/chip reset.
+ * VBAT memory is safer only if the board has a stable VBAT power rail.
*/
void system_set_image_copy(enum ec_image copy)
{
- /* TODO(b/226599277): check if further development is requested */
+ uint32_t value = (uint32_t)copy;
+
+ if (!bbram_dev) {
+ return;
+ }
+
+ switch (copy) {
+ case EC_IMAGE_RW:
+ case EC_IMAGE_RW_B:
+ value = EC_IMAGE_RW;
+ break;
+ case EC_IMAGE_RO:
+ default:
+ value = EC_IMAGE_RO;
+ break;
+ }
+
+ bbram_write(bbram_dev, GET_BBRAM_OFS(ec_img_load),
+ GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value);
}