diff options
author | Keith Short <keithshort@chromium.org> | 2021-08-20 12:54:31 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-08-26 19:54:43 +0000 |
commit | 71c1a4e5f6b174c1cb9b65fdd6a14944820b308a (patch) | |
tree | cbc98ea373a2ae5d0b3721379155ce6553a893f5 /zephyr/shim/chip | |
parent | ed193ca2912e2e5a310cca4f87ce552b8832b5c3 (diff) | |
download | chrome-ec-71c1a4e5f6b174c1cb9b65fdd6a14944820b308a.tar.gz |
zephyr: compile NPCX monitor
Compile the NPCX monitor code under the Zephyr environment.
BUG=b:197162681
BRANCH=none
TEST=Build zephyr for volteer. Verify npcx_monitor.bin is created.
Signed-off-by: Keith Short <keithshort@chromium.org>
Change-Id: Idba6e013288eb9c300c91ea57313db08e13b2e97
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3116567
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-by: Wai-Hong Tam <waihong@google.com>
Reviewed-by: CH Lin <chlin56@nuvoton.com>
Diffstat (limited to 'zephyr/shim/chip')
-rw-r--r-- | zephyr/shim/chip/npcx/CMakeLists.txt | 7 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/include/flash_chip.h | 3 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/npcx_monitor/CMakeLists.txt | 47 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.c | 343 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.h | 33 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.ld | 52 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/npcx_monitor/registers.h | 360 |
7 files changed, 845 insertions, 0 deletions
diff --git a/zephyr/shim/chip/npcx/CMakeLists.txt b/zephyr/shim/chip/npcx/CMakeLists.txt index a184d678f6..d3cd4b48fd 100644 --- a/zephyr/shim/chip/npcx/CMakeLists.txt +++ b/zephyr/shim/chip/npcx/CMakeLists.txt @@ -2,6 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# When building code coverage, the final Zephyr image isn't actually linked +# and there's no valid image to program. Skip compiling and linking the NPCX +# monitor when coverage is enabled. +if (NOT DEFINED CONFIG_COVERAGE) + add_subdirectory(npcx_monitor) +endif() + zephyr_library_include_directories(include) zephyr_library_sources(clock.c) diff --git a/zephyr/shim/chip/npcx/include/flash_chip.h b/zephyr/shim/chip/npcx/include/flash_chip.h index c8b3426e69..622633c570 100644 --- a/zephyr/shim/chip/npcx/include/flash_chip.h +++ b/zephyr/shim/chip/npcx/include/flash_chip.h @@ -25,4 +25,7 @@ #define CONFIG_RW_STORAGE_OFF 0 +/* Use 4k sector erase for NPCX monitor flash erase operations. */ +#define NPCX_MONITOR_FLASH_ERASE_SIZE 0x1000 + #endif /* __CROS_EC_FLASH_CHIP_H */ diff --git a/zephyr/shim/chip/npcx/npcx_monitor/CMakeLists.txt b/zephyr/shim/chip/npcx/npcx_monitor/CMakeLists.txt new file mode 100644 index 0000000000..661eb86e91 --- /dev/null +++ b/zephyr/shim/chip/npcx/npcx_monitor/CMakeLists.txt @@ -0,0 +1,47 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# The NPCX monitor source needs the chip type and flash layout information +# provided by the board configuration. This is provided by +# zephyr/shim/include/config_chip.h, so we need all the include directories +# of the Zephyr application. +zephyr_get_include_directories_for_lang(C zephyr_includes STRIP_PREFIX) + +# Something in the zephyr_get_compile_options_for_lang() output causes the +# "-imacros" option to get dropped during expansion when passed to +# target_compile_options(). Fetch the compile options directly from +# zephyr_interface which works as expected. +get_property( + zephyr_compile_options + TARGET zephyr_interface + PROPERTY INTERFACE_COMPILE_OPTIONS + ) + +add_executable(npcx_monitor npcx_monitor.c) +target_include_directories(npcx_monitor PRIVATE + "${PLATFORM_EC}/zephyr/shim/include" + "${PLATFORM_EC}/zephyr/shim/chip/npcx/include" + ) +target_include_directories(npcx_monitor PRIVATE "${zephyr_includes}") +target_compile_options(npcx_monitor PRIVATE "${zephyr_compile_options}") + +target_link_options(npcx_monitor BEFORE PRIVATE + -nostdlib + -g + -mthumb + -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/npcx_monitor.ld + ) + +# Create the NPCX monitor binary, locate it the root of the build +# directory as it needs to be found by the flash_util script +set(npcx_monitor_elf ${CMAKE_CURRENT_BINARY_DIR}/npcx_monitor.elf) +set(npcx_monitor_bin ${CMAKE_BINARY_DIR}/npcx_monitor.bin) + +add_custom_target(generate_npcx_monitor + COMMAND ${CMAKE_OBJCOPY} -O binary ${npcx_monitor_elf} ${npcx_monitor_bin} + BYPRODUCTS ${npcx_monitor_bin} + DEPENDS npcx_monitor + ) + +add_dependencies(zephyr generate_npcx_monitor) diff --git a/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.c b/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.c new file mode 100644 index 0000000000..2bd9455a91 --- /dev/null +++ b/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.c @@ -0,0 +1,343 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * NPCX SoC spi flash update tool - monitor firmware + */ + +#include <stdint.h> +#include <sys/util.h> +#include "config_chip.h" +#include "npcx_monitor.h" +#include "registers.h" + +/* + * TODO(b/197162681): This was copied from chip/npcx/spiflashfw but this + * needs to be moved to Zephyr upstream + */ + +/*****************************************************************************/ +/* spi flash internal functions */ +void sspi_flash_pinmux(int enable) +{ + if (enable) + CLEAR_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI); + else + SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI); + + /* CS0/1 pinmux */ + if (enable) { +#if (FIU_CHIP_SELECT == 1) + SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_1); +#elif (FIU_CHIP_SELECT == 2) + SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_2); +#endif + } else { + CLEAR_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_1); + CLEAR_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_2); + } +} + +void sspi_flash_tristate(int enable) +{ + if (enable) { + /* Enable FIU pins to tri-state */ + SET_BIT(NPCX_DEVCNT, NPCX_DEVCNT_F_SPI_TRIS); + } else { + /* Disable FIU pins to tri-state */ + CLEAR_BIT(NPCX_DEVCNT, NPCX_DEVCNT_F_SPI_TRIS); + } +} + +void sspi_flash_execute_cmd(uint8_t code, uint8_t cts) +{ + /* set UMA_CODE */ + NPCX_UMA_CODE = code; + /* execute UMA flash transaction */ + NPCX_UMA_CTS = cts; + while (IS_BIT_SET(NPCX_UMA_CTS, NPCX_UMA_CTS_EXEC_DONE)) + ; +} + +void sspi_flash_cs_level(int level) +{ + /* level is high */ + if (level) { + /* Set chip select to high */ + SET_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1); + } else { /* level is low */ + /* Set chip select to low */ + CLEAR_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1); + } +} + +void sspi_flash_wait_ready(void) +{ + uint8_t mask = SPI_FLASH_SR1_BUSY; + + /* Chip Select down. */ + sspi_flash_cs_level(0); + /* Command for Read status register */ + sspi_flash_execute_cmd(CMD_READ_STATUS_REG, MASK_CMD_ONLY); + do { + /* Read status register */ + NPCX_UMA_CTS = MASK_RD_1BYTE; + while (IS_BIT_SET(NPCX_UMA_CTS, NPCX_UMA_CTS_EXEC_DONE)) + ; + } while (NPCX_UMA_DB0 & mask); /* Wait for Busy clear */ + /* Chip Select high. */ + sspi_flash_cs_level(1); +} + +int sspi_flash_write_enable(void) +{ + uint8_t mask = SPI_FLASH_SR1_WEL; + /* Write enable command */ + sspi_flash_execute_cmd(CMD_WRITE_EN, MASK_CMD_ONLY); + /* Wait for flash is not busy */ + sspi_flash_wait_ready(); + + if (NPCX_UMA_DB0 & mask) + return 1; + else + return 0; +} + +void sspi_flash_set_address(uint32_t dest_addr) +{ + uint8_t *addr = (uint8_t *)&dest_addr; + /* Write address */ + NPCX_UMA_AB2 = addr[2]; + NPCX_UMA_AB1 = addr[1]; + NPCX_UMA_AB0 = addr[0]; +} + +void sspi_flash_burst_write(unsigned int dest_addr, unsigned int bytes, + const char *data) +{ + unsigned int i; + /* Chip Select down. */ + sspi_flash_cs_level(0); + /* Set erase address */ + sspi_flash_set_address(dest_addr); + /* Start write */ + sspi_flash_execute_cmd(CMD_FLASH_PROGRAM, MASK_CMD_WR_ADR); + for (i = 0; i < bytes; i++) { + sspi_flash_execute_cmd(*data, MASK_CMD_WR_ONLY); + data++; + } + /* Chip Select up */ + sspi_flash_cs_level(1); +} + +int sspi_flash_physical_clear_stsreg(void) +{ + /* Disable tri-state */ + sspi_flash_tristate(0); + /* Enable write */ + sspi_flash_write_enable(); + + NPCX_UMA_DB0 = 0x0; + NPCX_UMA_DB1 = 0x0; + + /* Write status register 1/2 */ + sspi_flash_execute_cmd(CMD_WRITE_STATUS_REG, MASK_CMD_WR_2BYTE); + + /* Wait writing completed */ + sspi_flash_wait_ready(); + + /* Read status register 1/2 for checking */ + sspi_flash_execute_cmd(CMD_READ_STATUS_REG, MASK_CMD_RD_1BYTE); + if (NPCX_UMA_DB0 != 0x00) + return 0; + sspi_flash_execute_cmd(CMD_READ_STATUS_REG2, MASK_CMD_RD_1BYTE); + if (NPCX_UMA_DB0 != 0x00) + return 0; + /* Enable tri-state */ + sspi_flash_tristate(1); + + return 1; +} + +void sspi_flash_physical_write(int offset, int size, const char *data) +{ + int dest_addr = offset; + const int sz_page = CONFIG_FLASH_WRITE_IDEAL_SIZE; + + /* Disable tri-state */ + sspi_flash_tristate(0); + + /* Write the data per CONFIG_FLASH_WRITE_IDEAL_SIZE bytes */ + for (; size >= sz_page; size -= sz_page) { + /* Enable write */ + sspi_flash_write_enable(); + /* Burst UMA transaction */ + sspi_flash_burst_write(dest_addr, sz_page, data); + /* Wait write completed */ + sspi_flash_wait_ready(); + + data += sz_page; + dest_addr += sz_page; + } + + /* Handle final partial page, if any */ + if (size != 0) { + /* Enable write */ + sspi_flash_write_enable(); + /* Burst UMA transaction */ + sspi_flash_burst_write(dest_addr, size, data); + + /* Wait write completed */ + sspi_flash_wait_ready(); + } + + /* Enable tri-state */ + sspi_flash_tristate(1); +} + +void sspi_flash_physical_erase(int offset, int size) +{ + /* Disable tri-state */ + sspi_flash_tristate(0); + + /* Alignment has been checked in upper layer */ + for (; size > 0; size -= NPCX_MONITOR_FLASH_ERASE_SIZE, + offset += NPCX_MONITOR_FLASH_ERASE_SIZE) { + /* Enable write */ + sspi_flash_write_enable(); + /* Set erase address */ + sspi_flash_set_address(offset); + /* Start erase */ + sspi_flash_execute_cmd(CMD_SECTOR_ERASE, MASK_CMD_ADR); + + /* Wait erase completed */ + sspi_flash_wait_ready(); + } + + /* Enable tri-state */ + sspi_flash_tristate(1); +} + +int sspi_flash_verify(int offset, int size, const char *data) +{ + int i, result; + uint8_t *ptr_flash; + uint8_t *ptr_mram; + uint8_t cmp_data; + + ptr_flash = (uint8_t *)(CONFIG_MAPPED_STORAGE_BASE + offset); + ptr_mram = (uint8_t *)data; + result = 1; + + /* Disable tri-state */ + sspi_flash_tristate(0); + + /* Start to verify */ + for (i = 0; i < size; i++) { + cmp_data = ptr_mram ? ptr_mram[i] : 0xFF; + if (ptr_flash[i] != cmp_data) { + result = 0; + break; + } + } + + /* Enable tri-state */ + sspi_flash_tristate(1); + return result; +} + +int sspi_flash_get_image_used(const char *fw_base) +{ + const uint8_t *image; + int size = MAX(CONFIG_RO_SIZE, CONFIG_RW_SIZE); /* max size is 128KB */ + + image = (const uint8_t *)fw_base; + /* + * Scan backwards looking for 0xea byte, which is by definition the + * last byte of the image. See ec.lds.S for how this is inserted at + * the end of the image. + */ + for (size--; size > 0 && image[size] != 0xea; size--) + ; + + return size ? size + 1 : 0; /* 0xea byte IS part of the image */ + +} + +/* Entry function of spi upload function */ +uint32_t __attribute__ ((section(".startup_text"))) +sspi_flash_upload(int spi_offset, int spi_size) +{ + /* + * Flash image has been uploaded to Code RAM + */ + uint32_t sz_image; + uint32_t uut_tag; + const char *image_base; + uint32_t *flag_upload = (uint32_t *)SPI_PROGRAMMING_FLAG; + struct monitor_header_tag *monitor_header = + (struct monitor_header_tag *)NPCX_MONITOR_HEADER_ADDR; + + *flag_upload = 0; + + uut_tag = monitor_header->tag; + /* If it is UUT tag, read required parameters from header */ + if (uut_tag == NPCX_MONITOR_UUT_TAG) { + sz_image = monitor_header->size; + spi_offset = monitor_header->dest_addr; + image_base = (const char *)(monitor_header->src_addr); + } else { + sz_image = spi_size; + image_base = (const char *)CONFIG_PROGRAM_MEMORY_BASE; + } + + /* Unlock & stop watchdog */ + NPCX_WDSDM = 0x87; + NPCX_WDSDM = 0x61; + NPCX_WDSDM = 0x63; + + /* UMA Unlock */ + CLEAR_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_UMA_LOCK); + + /* + * If UUT is used, assuming the target is the internal flash. + * Don't switch the pinmux and make sure bit 7 of DEVALT0 is set. + */ + if (uut_tag == NPCX_MONITOR_UUT_TAG) + SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI); + else + /* Set pinmux first */ + sspi_flash_pinmux(1); + + /* Get size of image automatically */ + if (sz_image == 0) + sz_image = sspi_flash_get_image_used(image_base); + + /* Clear status reg of spi flash for protection */ + if (sspi_flash_physical_clear_stsreg()) { + /* Start to erase */ + sspi_flash_physical_erase(spi_offset, sz_image); + /* Start to write */ + if (image_base != NULL) + sspi_flash_physical_write(spi_offset, sz_image, + image_base); + /* Verify data */ + if (sspi_flash_verify(spi_offset, sz_image, image_base)) + *flag_upload |= 0x02; + } + if (uut_tag != NPCX_MONITOR_UUT_TAG) + /* Disable pinmux */ + sspi_flash_pinmux(0); + + /* Mark we have finished upload work */ + *flag_upload |= 0x01; + + /* Return the status back to ROM code is required for UUT */ + if (uut_tag == NPCX_MONITOR_UUT_TAG) + return *flag_upload; + + /* Infinite loop */ + for (;;) + ; +} + diff --git a/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.h b/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.h new file mode 100644 index 0000000000..c5415d94db --- /dev/null +++ b/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.h @@ -0,0 +1,33 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef __CROS_EC_NPCX_MONITOR_H +#define __CROS_EC_NPCX_MONITOR_H + +#include <stdint.h> + +#define NPCX_MONITOR_UUT_TAG 0xA5075001 +#define NPCX_MONITOR_HEADER_ADDR 0x200C3000 + +/* Flag to record the progress of programming SPI flash */ +#define SPI_PROGRAMMING_FLAG 0x200C4000 + +struct monitor_header_tag { + /* offset 0x00: TAG NPCX_MONITOR_TAG */ + uint32_t tag; + /* offset 0x04: Size of the binary being programmed (in bytes) */ + uint32_t size; + /* offset 0x08: The RAM address of the binary to program into the SPI */ + uint32_t src_addr; + /* offset 0x0C: The Flash address to be programmed (Absolute address) */ + uint32_t dest_addr; + /* offset 0x10: Maximum allowable flash clock frequency */ + uint8_t max_clock; + /* offset 0x11: SPI Flash read mode */ + uint8_t read_mode; + /* offset 0x12: Reserved */ + uint16_t reserved; +} __packed; + +#endif /* __CROS_EC_NPCX_MONITOR_H */ diff --git a/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.ld b/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.ld new file mode 100644 index 0000000000..03e38b0609 --- /dev/null +++ b/zephyr/shim/chip/npcx/npcx_monitor/npcx_monitor.ld @@ -0,0 +1,52 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * NPCX SoC spi flash update tool + */ + +/* Memory Spaces Definitions */ +MEMORY +{ + CODERAM (rx) : ORIGIN = 0x200C3020, LENGTH = 0xFE0 +} + +/* + * The entry point is informative, for debuggers and simulators, + * since the Cortex-M vector points to it anyway. + */ +ENTRY(sspi_flash_upload) + + +/* Sections Definitions */ + +SECTIONS +{ + .startup_text : + { + . = ALIGN(4); + *(.startup_text ) /* Startup code */ + . = ALIGN(4); + } >CODERAM + + /* + * The program code is stored in the .text section, + * which goes to CODERAM. + */ + .text : + { + . = ALIGN(4); + *(.text .text.*) /* all remaining code */ + *(.rodata .rodata.*) /* read-only data (constants) */ + } >CODERAM + + . = ALIGN(4); + _etext = .; + + /* + * This address is used by the startup code to + * initialise the .data section. + */ + _sidata = _etext; + +} diff --git a/zephyr/shim/chip/npcx/npcx_monitor/registers.h b/zephyr/shim/chip/npcx/npcx_monitor/registers.h new file mode 100644 index 0000000000..cc0a6b96fe --- /dev/null +++ b/zephyr/shim/chip/npcx/npcx_monitor/registers.h @@ -0,0 +1,360 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Register map for NPCX processor + * + * This is meant to be temporary until the NPCX monitor support is moved + * to Zephyr upstream + */ + +#ifndef __CROS_EC_REGISTERS_H +#define __CROS_EC_REGISTERS_H + +/* + * The monitor code doesn't build cleanly under the Zephyr environment if + * include/common.h is included. Replicate the register access macros until + * this code is moved upstream. + */ + +/* Macros to access registers */ +#define REG64_ADDR(addr) ((volatile uint64_t *)(addr)) +#define REG32_ADDR(addr) ((volatile uint32_t *)(addr)) +#define REG16_ADDR(addr) ((volatile uint16_t *)(addr)) +#define REG8_ADDR(addr) ((volatile uint8_t *)(addr)) + +#define REG64(addr) (*REG64_ADDR(addr)) +#define REG32(addr) (*REG32_ADDR(addr)) +#define REG16(addr) (*REG16_ADDR(addr)) +#define REG8(addr) (*REG8_ADDR(addr)) + +/* Standard macros / definitions */ +#define GENERIC_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define GENERIC_MIN(x, y) ((x) < (y) ? (x) : (y)) +#ifndef MAX +#define MAX(a, b) \ + ({ \ + __typeof__(a) temp_a = (a); \ + __typeof__(b) temp_b = (b); \ + \ + GENERIC_MAX(temp_a, temp_b); \ + }) +#endif +#ifndef MIN +#define MIN(a, b) \ + ({ \ + __typeof__(a) temp_a = (a); \ + __typeof__(b) temp_b = (b); \ + \ + GENERIC_MIN(temp_a, temp_b); \ + }) +#endif +#ifndef NULL +#define NULL ((void *)0) +#endif + +/******************************************************************************/ +/* + * Macro Functions + */ +/* Bit functions */ +#define SET_BIT(reg, bit) ((reg) |= (0x1 << (bit))) +#define CLEAR_BIT(reg, bit) ((reg) &= (~(0x1 << (bit)))) +#define IS_BIT_SET(reg, bit) (((reg) >> (bit)) & (0x1)) +#define UPDATE_BIT(reg, bit, cond) { if (cond) \ + SET_BIT(reg, bit); \ + else \ + CLEAR_BIT(reg, bit); } +/* Field functions */ +#define GET_POS_FIELD(pos, size) pos +#define GET_SIZE_FIELD(pos, size) size +#define FIELD_POS(field) GET_POS_##field +#define FIELD_SIZE(field) GET_SIZE_##field +/* Read field functions */ +#define GET_FIELD(reg, field) \ + _GET_FIELD_(reg, FIELD_POS(field), FIELD_SIZE(field)) +#define _GET_FIELD_(reg, f_pos, f_size) (((reg)>>(f_pos)) & ((1<<(f_size))-1)) +/* Write field functions */ +#define SET_FIELD(reg, field, value) \ + _SET_FIELD_(reg, FIELD_POS(field), FIELD_SIZE(field), value) +#define _SET_FIELD_(reg, f_pos, f_size, value) \ + ((reg) = ((reg) & (~(((1 << (f_size))-1) << (f_pos)))) \ + | ((value) << (f_pos))) + + +/* NPCX7 & NPCX9 */ +#define NPCX_DEVALT(n) REG8(NPCX_SCFG_BASE_ADDR + 0x010 + (n)) + +/******************************************************************************/ +/* + * NPCX (Nuvoton M4 EC) Register Definitions + */ + +/* Modules Map */ +#define NPCX_ESPI_BASE_ADDR 0x4000A000 +#define NPCX_MDC_BASE_ADDR 0x4000C000 +#define NPCX_PMC_BASE_ADDR 0x4000D000 +#define NPCX_SIB_BASE_ADDR 0x4000E000 +#define NPCX_SHI_BASE_ADDR 0x4000F000 +#define NPCX_SHM_BASE_ADDR 0x40010000 +#define NPCX_GDMA_BASE_ADDR 0x40011000 +#define NPCX_FIU_BASE_ADDR 0x40020000 +#define NPCX_KBSCAN_REGS_BASE 0x400A3000 +#define NPCX_WOV_BASE_ADDR 0x400A4000 +#define NPCX_APM_BASE_ADDR 0x400A4800 +#define NPCX_GLUE_REGS_BASE 0x400A5000 +#define NPCX_BBRAM_BASE_ADDR 0x400AF000 +#define NPCX_PS2_BASE_ADDR 0x400B1000 +#define NPCX_HFCG_BASE_ADDR 0x400B5000 +#define NPCX_LFCG_BASE_ADDR 0x400B5100 +#define NPCX_FMUL2_BASE_ADDR 0x400B5200 +#define NPCX_MTC_BASE_ADDR 0x400B7000 +#define NPCX_MSWC_BASE_ADDR 0x400C1000 +#define NPCX_SCFG_BASE_ADDR 0x400C3000 +#define NPCX_KBC_BASE_ADDR 0x400C7000 +#define NPCX_ADC_BASE_ADDR 0x400D1000 +#define NPCX_SPI_BASE_ADDR 0x400D2000 +#define NPCX_PECI_BASE_ADDR 0x400D4000 +#define NPCX_TWD_BASE_ADDR 0x400D8000 + +/* Multi-Modules Map */ +#define NPCX_PWM_BASE_ADDR(mdl) (0x40080000 + ((mdl) * 0x2000L)) +#define NPCX_GPIO_BASE_ADDR(mdl) (0x40081000 + ((mdl) * 0x2000L)) +#define NPCX_ITIM_BASE_ADDR(mdl) (0x400B0000 + ((mdl) * 0x2000L)) +#define NPCX_MIWU_BASE_ADDR(mdl) (0x400BB000 + ((mdl) * 0x2000L)) +#define NPCX_MFT_BASE_ADDR(mdl) (0x400E1000 + ((mdl) * 0x2000L)) +#define NPCX_PM_CH_BASE_ADDR(mdl) (0x400C9000 + ((mdl) * 0x2000L)) + + +/******************************************************************************/ +/* System Configuration (SCFG) Registers */ +#define NPCX_DEVCNT REG8(NPCX_SCFG_BASE_ADDR + 0x000) +#define NPCX_STRPST REG8(NPCX_SCFG_BASE_ADDR + 0x001) +#define NPCX_RSTCTL REG8(NPCX_SCFG_BASE_ADDR + 0x002) +#define NPCX_DEV_CTL4 REG8(NPCX_SCFG_BASE_ADDR + 0x006) +#define NPCX_LFCGCALCNT REG8(NPCX_SCFG_BASE_ADDR + 0x021) +#define NPCX_PUPD_EN0 REG8(NPCX_SCFG_BASE_ADDR + 0x028) +#define NPCX_PUPD_EN1 REG8(NPCX_SCFG_BASE_ADDR + 0x029) +#define NPCX_SCFG_VER REG8(NPCX_SCFG_BASE_ADDR + 0x02F) + +#define TEST_BKSL REG8(NPCX_SCFG_BASE_ADDR + 0x037) +#define TEST0 REG8(NPCX_SCFG_BASE_ADDR + 0x038) +#define BLKSEL 0 + +/* SCFG register fields */ +#define NPCX_DEVCNT_F_SPI_TRIS 6 +#define NPCX_DEVCNT_HIF_TYP_SEL_FIELD FIELD(2, 2) +#define NPCX_DEVCNT_JEN1_HEN 5 +#define NPCX_DEVCNT_JEN0_HEN 4 +#define NPCX_STRPST_TRIST 1 +#define NPCX_STRPST_TEST 2 +#define NPCX_STRPST_JEN1 4 +#define NPCX_STRPST_JEN0 5 +#define NPCX_STRPST_SPI_COMP 7 +#define NPCX_RSTCTL_VCC1_RST_STS 0 +#define NPCX_RSTCTL_DBGRST_STS 1 +#define NPCX_RSTCTL_VCC1_RST_SCRATCH 3 +#define NPCX_RSTCTL_LRESET_PLTRST_MODE 5 +#define NPCX_RSTCTL_HIPRST_MODE 6 +#define NPCX_DEV_CTL4_F_SPI_SLLK 2 +#define NPCX_DEV_CTL4_SPI_SP_SEL 4 +#define NPCX_DEV_CTL4_WP_IF 5 +#define NPCX_DEV_CTL4_VCC1_RST_LK 6 +#define NPCX_DEVPU0_I2C0_0_PUE 0 +#define NPCX_DEVPU0_I2C0_1_PUE 1 +#define NPCX_DEVPU0_I2C1_0_PUE 2 +#define NPCX_DEVPU0_I2C2_0_PUE 4 +#define NPCX_DEVPU0_I2C3_0_PUE 6 +#define NPCX_DEVPU1_F_SPI_PUD_EN 7 + +/* DEVALT */ +/* pin-mux for SPI/FIU */ +#define NPCX_DEVALT0_SPIP_SL 0 +#define NPCX_DEVALT0_GPIO_NO_SPIP 3 +#define NPCX_DEVALT0_F_SPI_CS1_2 4 +#define NPCX_DEVALT0_F_SPI_CS1_1 5 +#define NPCX_DEVALT0_F_SPI_QUAD 6 +#define NPCX_DEVALT0_NO_F_SPI 7 + +/******************************************************************************/ +/* Flash Interface Unit (FIU) Registers */ +#define NPCX_FIU_CFG REG8(NPCX_FIU_BASE_ADDR + 0x000) +#define NPCX_BURST_CFG REG8(NPCX_FIU_BASE_ADDR + 0x001) +#define NPCX_RESP_CFG REG8(NPCX_FIU_BASE_ADDR + 0x002) +#define NPCX_SPI_FL_CFG REG8(NPCX_FIU_BASE_ADDR + 0x014) +#define NPCX_UMA_CODE REG8(NPCX_FIU_BASE_ADDR + 0x016) +#define NPCX_UMA_AB0 REG8(NPCX_FIU_BASE_ADDR + 0x017) +#define NPCX_UMA_AB1 REG8(NPCX_FIU_BASE_ADDR + 0x018) +#define NPCX_UMA_AB2 REG8(NPCX_FIU_BASE_ADDR + 0x019) +#define NPCX_UMA_DB0 REG8(NPCX_FIU_BASE_ADDR + 0x01A) +#define NPCX_UMA_DB1 REG8(NPCX_FIU_BASE_ADDR + 0x01B) +#define NPCX_UMA_DB2 REG8(NPCX_FIU_BASE_ADDR + 0x01C) +#define NPCX_UMA_DB3 REG8(NPCX_FIU_BASE_ADDR + 0x01D) +#define NPCX_UMA_CTS REG8(NPCX_FIU_BASE_ADDR + 0x01E) +#define NPCX_UMA_ECTS REG8(NPCX_FIU_BASE_ADDR + 0x01F) +#define NPCX_UMA_DB0_3 REG32(NPCX_FIU_BASE_ADDR + 0x020) +#define NPCX_FIU_RD_CMD REG8(NPCX_FIU_BASE_ADDR + 0x030) +#define NPCX_FIU_DMM_CYC REG8(NPCX_FIU_BASE_ADDR + 0x032) +#define NPCX_FIU_EXT_CFG REG8(NPCX_FIU_BASE_ADDR + 0x033) +#define NPCX_FIU_UMA_AB0_3 REG32(NPCX_FIU_BASE_ADDR + 0x034) + +/* FIU register fields */ +#define NPCX_RESP_CFG_IAD_EN 0 +#define NPCX_RESP_CFG_DEV_SIZE_EX 2 +#define NPCX_UMA_CTS_A_SIZE 3 +#define NPCX_UMA_CTS_C_SIZE 4 +#define NPCX_UMA_CTS_RD_WR 5 +#define NPCX_UMA_CTS_DEV_NUM 6 +#define NPCX_UMA_CTS_EXEC_DONE 7 +#define NPCX_UMA_ECTS_SW_CS0 0 +#define NPCX_UMA_ECTS_SW_CS1 1 +#define NPCX_UMA_ECTS_SEC_CS 2 +#define NPCX_UMA_ECTS_UMA_LOCK 3 + +/******************************************************************************/ +/* KBC Registers */ +#define NPCX_HICTRL REG8(NPCX_KBC_BASE_ADDR + 0x000) +#define NPCX_HIIRQC REG8(NPCX_KBC_BASE_ADDR + 0x002) +#define NPCX_HIKMST REG8(NPCX_KBC_BASE_ADDR + 0x004) +#define NPCX_HIKDO REG8(NPCX_KBC_BASE_ADDR + 0x006) +#define NPCX_HIMDO REG8(NPCX_KBC_BASE_ADDR + 0x008) +#define NPCX_KBCVER REG8(NPCX_KBC_BASE_ADDR + 0x009) +#define NPCX_HIKMDI REG8(NPCX_KBC_BASE_ADDR + 0x00A) +#define NPCX_SHIKMDI REG8(NPCX_KBC_BASE_ADDR + 0x00B) + +/* KBC register field */ +#define NPCX_HICTRL_OBFKIE 0 /* Automatic Serial IRQ1 for KBC */ +#define NPCX_HICTRL_OBFMIE 1 /* Automatic Serial IRQ12 for Mouse*/ +#define NPCX_HICTRL_OBECIE 2 /* KBC OBE interrupt enable */ +#define NPCX_HICTRL_IBFCIE 3 /* KBC IBF interrupt enable */ +#define NPCX_HICTRL_PMIHIE 4 /* Automatic Serial IRQ11 for PMC1 */ +#define NPCX_HICTRL_PMIOCIE 5 /* PMC1 OBE interrupt enable */ +#define NPCX_HICTRL_PMICIE 6 /* PMC1 IBF interrupt enable */ +#define NPCX_HICTRL_FW_OBF 7 /* Firmware control over OBF */ + +#define NPCX_HIKMST_OBF 0 /* KB output buffer is full */ + +/******************************************************************************/ +/* Timer Watch Dog (TWD) Registers */ +#define NPCX_TWCFG REG8(NPCX_TWD_BASE_ADDR + 0x000) +#define NPCX_TWCP REG8(NPCX_TWD_BASE_ADDR + 0x002) +#define NPCX_TWDT0 REG16(NPCX_TWD_BASE_ADDR + 0x004) +#define NPCX_T0CSR REG8(NPCX_TWD_BASE_ADDR + 0x006) +#define NPCX_WDCNT REG8(NPCX_TWD_BASE_ADDR + 0x008) +#define NPCX_WDSDM REG8(NPCX_TWD_BASE_ADDR + 0x00A) +#define NPCX_TWMT0 REG16(NPCX_TWD_BASE_ADDR + 0x00C) +#define NPCX_TWMWD REG8(NPCX_TWD_BASE_ADDR + 0x00E) +#define NPCX_WDCP REG8(NPCX_TWD_BASE_ADDR + 0x010) + +/* TWD register fields */ +#define NPCX_TWCFG_LTWCFG 0 +#define NPCX_TWCFG_LTWCP 1 +#define NPCX_TWCFG_LTWDT0 2 +#define NPCX_TWCFG_LWDCNT 3 +#define NPCX_TWCFG_WDCT0I 4 +#define NPCX_TWCFG_WDSDME 5 +#define NPCX_TWCFG_WDRST_MODE 6 +#define NPCX_TWCFG_WDC2POR 7 +#define NPCX_T0CSR_RST 0 +#define NPCX_T0CSR_TC 1 +#define NPCX_T0CSR_WDLTD 3 +#define NPCX_T0CSR_WDRST_STS 4 +#define NPCX_T0CSR_WD_RUN 5 +#define NPCX_T0CSR_TESDIS 7 + +/******************************************************************************/ +/* SPI Register */ +#define NPCX_SPI_DATA REG16(NPCX_SPI_BASE_ADDR + 0x00) +#define NPCX_SPI_CTL1 REG16(NPCX_SPI_BASE_ADDR + 0x02) +#define NPCX_SPI_STAT REG8(NPCX_SPI_BASE_ADDR + 0x04) + +/* SPI register fields */ +#define NPCX_SPI_CTL1_SPIEN 0 +#define NPCX_SPI_CTL1_SNM 1 +#define NPCX_SPI_CTL1_MOD 2 +#define NPCX_SPI_CTL1_EIR 5 +#define NPCX_SPI_CTL1_EIW 6 +#define NPCX_SPI_CTL1_SCM 7 +#define NPCX_SPI_CTL1_SCIDL 8 +#define NPCX_SPI_CTL1_SCDV 9 +#define NPCX_SPI_STAT_BSY 0 +#define NPCX_SPI_STAT_RBF 1 + +/******************************************************************************/ +/* Flash Utiltiy definition */ +/* + * Flash commands for the W25Q16CV SPI flash + */ +#define CMD_READ_ID 0x9F +#define CMD_READ_MAN_DEV_ID 0x90 +#define CMD_WRITE_EN 0x06 +#define CMD_WRITE_STATUS 0x50 +#define CMD_READ_STATUS_REG 0x05 +#define CMD_READ_STATUS_REG2 0x35 +#define CMD_WRITE_STATUS_REG 0x01 +#define CMD_FLASH_PROGRAM 0x02 +#define CMD_SECTOR_ERASE 0x20 +#define CMD_BLOCK_32K_ERASE 0x52 +#define CMD_BLOCK_64K_ERASE 0xd8 +#define CMD_PROGRAM_UINT_SIZE 0x08 +#define CMD_PAGE_SIZE 0x00 +#define CMD_READ_ID_TYPE 0x47 +#define CMD_FAST_READ 0x0B + +/* + * Status registers for the W25Q16CV SPI flash + */ +#define SPI_FLASH_SR2_SUS BIT(7) +#define SPI_FLASH_SR2_CMP BIT(6) +#define SPI_FLASH_SR2_LB3 BIT(5) +#define SPI_FLASH_SR2_LB2 BIT(4) +#define SPI_FLASH_SR2_LB1 BIT(3) +#define SPI_FLASH_SR2_QE BIT(1) +#define SPI_FLASH_SR2_SRP1 BIT(0) +#define SPI_FLASH_SR1_SRP0 BIT(7) +#define SPI_FLASH_SR1_SEC BIT(6) +#define SPI_FLASH_SR1_TB BIT(5) +#define SPI_FLASH_SR1_BP2 BIT(4) +#define SPI_FLASH_SR1_BP1 BIT(3) +#define SPI_FLASH_SR1_BP0 BIT(2) +#define SPI_FLASH_SR1_WEL BIT(1) +#define SPI_FLASH_SR1_BUSY BIT(0) + + +/* 0: F_CS0 1: F_CS1_1(GPIO86) 2:F_CS1_2(GPIOA6) */ +#define FIU_CHIP_SELECT 0 +/* Create UMA control mask */ +#define MASK(bit) (0x1 << (bit)) +#define A_SIZE 0x03 /* 0: No ADR field 1: 3-bytes ADR field */ +#define C_SIZE 0x04 /* 0: 1-Byte CMD field 1:No CMD field */ +#define RD_WR 0x05 /* 0: Read 1: Write */ +#define DEV_NUM 0x06 /* 0: PVT is used 1: SHD is used */ +#define EXEC_DONE 0x07 +#define D_SIZE_1 0x01 +#define D_SIZE_2 0x02 +#define D_SIZE_3 0x03 +#define D_SIZE_4 0x04 +#define FLASH_SEL MASK(DEV_NUM) + +#define MASK_CMD_ONLY (MASK(EXEC_DONE) | FLASH_SEL) +#define MASK_CMD_ADR (MASK(EXEC_DONE) | FLASH_SEL | MASK(A_SIZE)) +#define MASK_CMD_ADR_WR (MASK(EXEC_DONE) | FLASH_SEL | MASK(RD_WR) \ + |MASK(A_SIZE) | D_SIZE_1) +#define MASK_RD_1BYTE (MASK(EXEC_DONE) | FLASH_SEL | MASK(C_SIZE) | D_SIZE_1) +#define MASK_RD_2BYTE (MASK(EXEC_DONE) | FLASH_SEL | MASK(C_SIZE) | D_SIZE_2) +#define MASK_RD_3BYTE (MASK(EXEC_DONE) | FLASH_SEL | MASK(C_SIZE) | D_SIZE_3) +#define MASK_RD_4BYTE (MASK(EXEC_DONE) | FLASH_SEL | MASK(C_SIZE) | D_SIZE_4) +#define MASK_CMD_RD_1BYTE (MASK(EXEC_DONE) | FLASH_SEL | D_SIZE_1) +#define MASK_CMD_RD_2BYTE (MASK(EXEC_DONE) | FLASH_SEL | D_SIZE_2) +#define MASK_CMD_RD_3BYTE (MASK(EXEC_DONE) | FLASH_SEL | D_SIZE_3) +#define MASK_CMD_RD_4BYTE (MASK(EXEC_DONE) | FLASH_SEL | D_SIZE_4) +#define MASK_CMD_WR_ONLY (MASK(EXEC_DONE) | FLASH_SEL | MASK(RD_WR)) +#define MASK_CMD_WR_1BYTE (MASK(EXEC_DONE) | FLASH_SEL | MASK(RD_WR) \ + | MASK(C_SIZE) | D_SIZE_1) +#define MASK_CMD_WR_2BYTE (MASK(EXEC_DONE) | FLASH_SEL | MASK(RD_WR) \ + | MASK(C_SIZE) | D_SIZE_2) +#define MASK_CMD_WR_ADR (MASK(EXEC_DONE) | FLASH_SEL | MASK(RD_WR) \ + | MASK(A_SIZE)) + + +#endif /* __CROS_EC_REGISTERS_H */ |