summaryrefslogtreecommitdiff
path: root/chip/it83xx/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/it83xx/system.c')
-rw-r--r--chip/it83xx/system.c475
1 files changed, 0 insertions, 475 deletions
diff --git a/chip/it83xx/system.c b/chip/it83xx/system.c
deleted file mode 100644
index 16871e5826..0000000000
--- a/chip/it83xx/system.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/* Copyright 2013 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.
- */
-
-/* System module for Chrome EC : hardware specific implementation */
-
-#include "console.h"
-#include "cpu.h"
-#include "cros_version.h"
-#include "ec2i_chip.h"
-#include "flash.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "intc.h"
-#include "link_defs.h"
-#include "registers.h"
-#include "system.h"
-#include "task.h"
-#include "util.h"
-#include "watchdog.h"
-
-void system_hibernate(uint32_t seconds, uint32_t microseconds)
-{
-#ifdef CONFIG_HOSTCMD_PD
- /* Inform the PD MCU that we are going to hibernate. */
- host_command_pd_request_hibernate();
- /* Wait to ensure exchange with PD before hibernating. */
- msleep(100);
-#endif
-
- /* Flush console before hibernating */
- cflush();
-
- if (board_hibernate)
- board_hibernate();
-
- /* chip specific standby mode */
- __enter_hibernate(seconds, microseconds);
-}
-
-/* Clear reset flags if it's not cleared in check_reset_cause() */
-static int delayed_clear_reset_flags;
-static void clear_reset_flags(void)
-{
- if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON) &&
- delayed_clear_reset_flags) {
- chip_save_reset_flags(0);
- }
-}
-DECLARE_HOOK(HOOK_INIT, clear_reset_flags, HOOK_PRIO_LAST);
-
-#if !defined(CONFIG_HOSTCMD_LPC) && !defined(CONFIG_HOSTCMD_ESPI)
-static void system_save_panic_data_to_bram(void)
-{
- uint8_t *ptr = (uint8_t *)PANIC_DATA_PTR;
-
- for (int i = 0; i < CONFIG_PANIC_DATA_SIZE; i++)
- IT83XX_BRAM_BANK0(i + BRAM_PANIC_DATA_START) = ptr[i];
-}
-
-static void system_restore_panic_data_from_bram(void)
-{
- uint8_t *ptr = (uint8_t *)PANIC_DATA_PTR;
-
- for (int i = 0; i < CONFIG_PANIC_DATA_SIZE; i++)
- ptr[i] = IT83XX_BRAM_BANK0(i + BRAM_PANIC_DATA_START);
-}
-BUILD_ASSERT(BRAM_PANIC_LEN >= CONFIG_PANIC_DATA_SIZE);
-#else
-static void system_save_panic_data_to_bram(void) {}
-static void system_restore_panic_data_from_bram(void) {}
-#endif
-
-static void system_reset_ec_by_gpg1(void)
-{
- system_save_panic_data_to_bram();
- /* Set GPG1 as output high and wait until EC reset. */
- IT83XX_GPIO_CTRL(GPIO_G, 1) = GPCR_PORT_PIN_MODE_OUTPUT;
- IT83XX_GPIO_DATA(GPIO_G) |= BIT(1);
- while (1)
- ;
-}
-
-static void check_reset_cause(void)
-{
- uint32_t flags;
- uint8_t raw_reset_cause = IT83XX_GCTRL_RSTS & 0x03;
- uint8_t raw_reset_cause2 = IT83XX_GCTRL_SPCTRL4 & 0x07;
-
- /* Restore saved reset flags. */
- flags = chip_read_reset_flags();
-
- /* Clear reset cause. */
- IT83XX_GCTRL_RSTS |= 0x03;
- IT83XX_GCTRL_SPCTRL4 |= 0x07;
-
- /* Determine if watchdog reset or power on reset. */
- if (raw_reset_cause & 0x02) {
- flags |= EC_RESET_FLAG_WATCHDOG;
- if (IS_ENABLED(CONFIG_IT83XX_HARD_RESET_BY_GPG1)) {
- /*
- * Save watchdog reset flag to BRAM so we can restore
- * the flag on next reboot.
- */
- chip_save_reset_flags(EC_RESET_FLAG_WATCHDOG);
- /*
- * Assert GPG1 to reset EC and then EC_RST_ODL will be
- * toggled.
- */
- system_reset_ec_by_gpg1();
- }
- } else if (raw_reset_cause & 0x01) {
- flags |= EC_RESET_FLAG_POWER_ON;
- } else {
- if ((IT83XX_GCTRL_RSTS & 0xC0) == 0x80)
- flags |= EC_RESET_FLAG_POWER_ON;
- }
-
- if (raw_reset_cause2 & 0x04)
- flags |= EC_RESET_FLAG_RESET_PIN;
-
- /* watchdog module triggers these reset */
- if (flags & (EC_RESET_FLAG_HARD | EC_RESET_FLAG_SOFT))
- flags &= ~EC_RESET_FLAG_WATCHDOG;
-
- /*
- * On power-on of some boards, H1 releases the EC from reset but then
- * quickly asserts and releases the reset a second time. This means the
- * EC sees 2 resets. In order to carry over some important flags (e.g.
- * HIBERNATE) to the second resets, the reset flag will not be wiped if
- * we know this is the first reset.
- */
- if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON) &&
- (flags & EC_RESET_FLAG_POWER_ON)) {
- if (flags & EC_RESET_FLAG_INITIAL_PWR) {
- /* Second boot, clear the flag immediately */
- chip_save_reset_flags(0);
- } else {
- /*
- * First boot, Keep current flags and set INITIAL_PWR
- * flag. EC reset should happen soon.
- *
- * It's possible that H1 never trigger EC reset, or
- * reset happens before this line. Both cases should be
- * fine because we will have the correct flag anyway.
- */
- chip_save_reset_flags(chip_read_reset_flags() |
- EC_RESET_FLAG_INITIAL_PWR);
-
- /*
- * Schedule chip_save_reset_flags(0) later.
- * Wait until end of HOOK_INIT should be long enough.
- */
- delayed_clear_reset_flags = 1;
- }
- } else {
- /* Clear saved reset flags. */
- chip_save_reset_flags(0);
- }
-
- system_set_reset_flags(flags);
-
- /* Clear PD contract recorded in bram if this is a power-on reset. */
- if (IS_ENABLED(CONFIG_IT83XX_RESET_PD_CONTRACT_IN_BRAM) &&
- (flags == (EC_RESET_FLAG_POWER_ON | EC_RESET_FLAG_RESET_PIN))) {
- for (int i = 0; i < MAX_SYSTEM_BBRAM_IDX_PD_PORTS; i++)
- system_set_bbram((SYSTEM_BBRAM_IDX_PD0 + i), 0);
- }
-
- if ((IS_ENABLED(CONFIG_IT83XX_HARD_RESET_BY_GPG1)) &&
- (flags & ~(EC_RESET_FLAG_POWER_ON | EC_RESET_FLAG_RESET_PIN)))
- system_restore_panic_data_from_bram();
-}
-
-static void system_reset_cause_is_unknown(void)
-{
- /* No reset cause and not sysjump. */
- if (!system_get_reset_flags() && !system_jumped_to_this_image())
- /*
- * We decrease 4 or 2 for "ec_reset_lp" here, that depend on
- * which jump and link instruction has executed.
- * eg: Andes core (jral5: LP=PC+2, jal: LP=PC+4)
- */
- ccprintf("===Unknown reset! jump from %x or %x===\n",
- ec_reset_lp - 4, ec_reset_lp - 2);
-}
-DECLARE_HOOK(HOOK_INIT, system_reset_cause_is_unknown, HOOK_PRIO_FIRST);
-
-int system_is_reboot_warm(void)
-{
- uint32_t reset_flags;
- /*
- * Check reset cause here,
- * gpio_pre_init is executed faster than system_pre_init
- */
- check_reset_cause();
- reset_flags = system_get_reset_flags();
-
- if ((reset_flags & EC_RESET_FLAG_RESET_PIN) ||
- (reset_flags & EC_RESET_FLAG_POWER_ON) ||
- (reset_flags & EC_RESET_FLAG_WATCHDOG) ||
- (reset_flags & EC_RESET_FLAG_HARD) ||
- (reset_flags & EC_RESET_FLAG_SOFT) ||
- (reset_flags & EC_RESET_FLAG_HIBERNATE))
- return 0;
- else
- return 1;
-}
-
-void chip_pre_init(void)
-{
- /* bit1=0: disable pre-defined command */
- IT83XX_SMB_SFFCTL &= ~IT83XX_SMB_HSAPE;
-
- /* bit0, EC received the special waveform from iteflash */
- if (IT83XX_GCTRL_DBGROS & IT83XX_SMB_DBGR) {
- /*
- * Wait ~200ms, so iteflash will have enough time to let
- * EC enter follow mode. And once EC goes into follow mode, EC
- * will be stayed here (no following sequences, eg:
- * enable watchdog/write protect/power-on sequence...) until
- * we reset it.
- */
- for (int i = 0; i < (200 * MSEC / 15); i++)
- /* delay ~15.25us */
- IT83XX_GCTRL_WNCKR = 0;
- }
-
- if (IS_ENABLED(IT83XX_ETWD_HW_RESET_SUPPORT))
- /* System triggers a soft reset by default (command: reboot). */
- IT83XX_GCTRL_ETWDUARTCR &= ~ETWD_HW_RST_EN;
-
- if (IS_ENABLED(IT83XX_RISCV_WAKEUP_CPU_WITHOUT_INT_ENABLED))
- /*
- * bit7: wake up CPU if it is in low power mode and
- * an interrupt is pending.
- */
- IT83XX_GCTRL_WMCR |= BIT(7);
-}
-
-#define BRAM_VALID_MAGIC 0x4252414D /* "BRAM" */
-#define BRAM_VALID_MAGIC_FIELD0 (BRAM_VALID_MAGIC & 0xff)
-#define BRAM_VALID_MAGIC_FIELD1 ((BRAM_VALID_MAGIC >> 8) & 0xff)
-#define BRAM_VALID_MAGIC_FIELD2 ((BRAM_VALID_MAGIC >> 16) & 0xff)
-#define BRAM_VALID_MAGIC_FIELD3 ((BRAM_VALID_MAGIC >> 24) & 0xff)
-void chip_bram_valid(void)
-{
- int i;
-
- if ((BRAM_VALID_FLAGS0 != BRAM_VALID_MAGIC_FIELD0) ||
- (BRAM_VALID_FLAGS1 != BRAM_VALID_MAGIC_FIELD1) ||
- (BRAM_VALID_FLAGS2 != BRAM_VALID_MAGIC_FIELD2) ||
- (BRAM_VALID_FLAGS3 != BRAM_VALID_MAGIC_FIELD3)) {
- /*
- * Magic does not match, so BRAM must be uninitialized. Clear
- * entire Bank0 BRAM, and set magic value.
- */
- for (i = 0; i < BRAM_IDX_VALID_FLAGS0; i++)
- IT83XX_BRAM_BANK0(i) = 0;
-
- BRAM_VALID_FLAGS0 = BRAM_VALID_MAGIC_FIELD0;
- BRAM_VALID_FLAGS1 = BRAM_VALID_MAGIC_FIELD1;
- BRAM_VALID_FLAGS2 = BRAM_VALID_MAGIC_FIELD2;
- BRAM_VALID_FLAGS3 = BRAM_VALID_MAGIC_FIELD3;
- }
-
-#if defined(CONFIG_PRESERVE_LOGS) && defined(CONFIG_IT83XX_HARD_RESET_BY_GPG1)
- if (BRAM_EC_LOG_STATUS == EC_LOG_SAVED_IN_FLASH) {
- /* Restore EC logs from flash. */
- memcpy((void *)__preserved_logs_start,
- (const void *)CHIP_FLASH_PRESERVE_LOGS_BASE,
- (uintptr_t)__preserved_logs_size);
- }
- BRAM_EC_LOG_STATUS = 0;
-#endif
-}
-
-void system_pre_init(void)
-{
- /* No initialization required */
-
-}
-
-uint32_t chip_read_reset_flags(void)
-{
- uint32_t flags = 0;
- flags |= BRAM_RESET_FLAGS0 << 24;
- flags |= BRAM_RESET_FLAGS1 << 16;
- flags |= BRAM_RESET_FLAGS2 << 8;
- flags |= BRAM_RESET_FLAGS3;
- return flags;
-}
-
-void chip_save_reset_flags(uint32_t save_flags)
-{
- BRAM_RESET_FLAGS0 = save_flags >> 24;
- BRAM_RESET_FLAGS1 = (save_flags >> 16) & 0xff;
- BRAM_RESET_FLAGS2 = (save_flags >> 8) & 0xff;
- BRAM_RESET_FLAGS3 = save_flags & 0xff;
-}
-
-void system_reset(int flags)
-{
- uint32_t save_flags = 0;
-
- /* We never get this warning message in normal case. */
- if (IT83XX_GCTRL_DBGROS & IT83XX_SMB_DBGR) {
- ccprintf("!Reset will be failed due to EC is in debug mode!\n");
- cflush();
- }
-
-#if defined(CONFIG_PRESERVE_LOGS) && defined(CONFIG_IT83XX_HARD_RESET_BY_GPG1)
- /* Saving EC logs into flash before reset. */
- crec_flash_physical_erase(CHIP_FLASH_PRESERVE_LOGS_BASE,
- CHIP_FLASH_PRESERVE_LOGS_SIZE);
- crec_flash_physical_write(CHIP_FLASH_PRESERVE_LOGS_BASE,
- (uintptr_t)__preserved_logs_size, __preserved_logs_start);
- BRAM_EC_LOG_STATUS = EC_LOG_SAVED_IN_FLASH;
-#endif
-
- /* Disable interrupts to avoid task swaps during reboot. */
- interrupt_disable();
-
- /* Handle saving common reset flags. */
- system_encode_save_flags(flags, &save_flags);
-
- if (clock_ec_wake_from_sleep())
- save_flags |= EC_RESET_FLAG_HIBERNATE;
-
- /* Store flags to battery backed RAM. */
- chip_save_reset_flags(save_flags);
-
- /* If WAIT_EXT is set, then allow 10 seconds for external reset */
- if (flags & SYSTEM_RESET_WAIT_EXT) {
- int i;
-
- /* Wait 10 seconds for external reset */
- for (i = 0; i < 1000; i++) {
- watchdog_reload();
- udelay(10000);
- }
- }
-
- /* bit0: enable watchdog hardware reset. */
-#ifdef IT83XX_ETWD_HW_RESET_SUPPORT
- if (flags & SYSTEM_RESET_HARD)
- IT83XX_GCTRL_ETWDUARTCR |= ETWD_HW_RST_EN;
-#endif
- /* Set GPG1 as output high and wait until EC reset. */
- if (IS_ENABLED(CONFIG_IT83XX_HARD_RESET_BY_GPG1))
- system_reset_ec_by_gpg1();
-
- /*
- * Writing invalid key to watchdog module triggers a soft or hardware
- * reset. It depends on the setting of bit0 at ETWDUARTCR register.
- */
- IT83XX_ETWD_ETWCFG |= 0x20;
- IT83XX_ETWD_EWDKEYR = 0x00;
-
- /* Spin and wait for reboot; should never return */
- while (1)
- ;
-}
-
-int system_set_scratchpad(uint32_t value)
-{
- BRAM_SCRATCHPAD3 = (value >> 24) & 0xff;
- BRAM_SCRATCHPAD2 = (value >> 16) & 0xff;
- BRAM_SCRATCHPAD1 = (value >> 8) & 0xff;
- BRAM_SCRATCHPAD0 = value & 0xff;
-
- return EC_SUCCESS;
-}
-
-int system_get_scratchpad(uint32_t *value)
-{
- *value = (BRAM_SCRATCHPAD3 << 24) | (BRAM_SCRATCHPAD2 << 16) |
- (BRAM_SCRATCHPAD1 << 8) | (BRAM_SCRATCHPAD0);
- return EC_SUCCESS;
-}
-
-static uint32_t system_get_chip_id(void)
-{
-#ifdef IT83XX_CHIP_ID_3BYTES
- return (IT83XX_GCTRL_CHIPID1 << 16) | (IT83XX_GCTRL_CHIPID2 << 8) |
- IT83XX_GCTRL_CHIPID3;
-#else
- return (IT83XX_GCTRL_CHIPID1 << 8) | IT83XX_GCTRL_CHIPID2;
-#endif
-}
-
-static uint8_t system_get_chip_version(void)
-{
- /* bit[3-0], chip version */
- return IT83XX_GCTRL_CHIPVER & 0x0F;
-}
-
-static char to_hex(int x)
-{
- if (x >= 0 && x <= 9)
- return '0' + x;
- return 'a' + x - 10;
-}
-
-const char *system_get_chip_vendor(void)
-{
- return "ite";
-}
-
-const char *system_get_chip_name(void)
-{
- static char buf[8] = {'i', 't'};
- int num = (IS_ENABLED(IT83XX_CHIP_ID_3BYTES) ? 4 : 3);
- uint32_t chip_id = system_get_chip_id();
-
- for (int n = 2; num >= 0; n++, num--)
- buf[n] = to_hex(chip_id >> (num * 4) & 0xF);
-
- return buf;
-}
-
-const char *system_get_chip_revision(void)
-{
- static char buf[3];
- uint8_t rev = system_get_chip_version();
-
- buf[0] = to_hex(rev + 0xa);
- buf[1] = 'x';
- buf[2] = '\0';
- return buf;
-}
-
-static int bram_idx_lookup(enum system_bbram_idx idx)
-{
- if (idx == SYSTEM_BBRAM_IDX_PD0)
- return BRAM_IDX_PD0;
- if (idx == SYSTEM_BBRAM_IDX_PD1)
- return BRAM_IDX_PD1;
- if (idx == SYSTEM_BBRAM_IDX_PD2)
- return BRAM_IDX_PD2;
- return -1;
-}
-
-int system_get_bbram(enum system_bbram_idx idx, uint8_t *value)
-{
- int bram_idx = bram_idx_lookup(idx);
-
- if (bram_idx < 0)
- return EC_ERROR_INVAL;
-
- *value = IT83XX_BRAM_BANK0(bram_idx);
- return EC_SUCCESS;
-}
-
-int system_set_bbram(enum system_bbram_idx idx, uint8_t value)
-{
- int bram_idx = bram_idx_lookup(idx);
-
- if (bram_idx < 0)
- return EC_ERROR_INVAL;
-
- IT83XX_BRAM_BANK0(bram_idx) = value;
- return EC_SUCCESS;
-}
-
-uintptr_t system_get_fw_reset_vector(uintptr_t base)
-{
- /*
- * Because our reset vector is at the beginning of image copy
- * (see init.S). So I just need to return 'base' here and EC will jump
- * to the reset vector.
- */
- return base;
-}