summaryrefslogtreecommitdiff
path: root/chip/npcx/system-npcx7.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/npcx/system-npcx7.c')
-rw-r--r--chip/npcx/system-npcx7.c392
1 files changed, 0 insertions, 392 deletions
diff --git a/chip/npcx/system-npcx7.c b/chip/npcx/system-npcx7.c
deleted file mode 100644
index 89b3e25e9b..0000000000
--- a/chip/npcx/system-npcx7.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/* 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.
- */
-
-#include <stdnoreturn.h>
-
-/* System module driver depends on chip series for Chrome EC */
-#include "common.h"
-#include "console.h"
-#include "cpu.h"
-#include "ec_commands.h"
-#include "hooks.h"
-#include "lct_chip.h"
-#include "registers.h"
-#include "system.h"
-#include "task.h"
-#include "util.h"
-#include "gpio.h"
-#include "hwtimer_chip.h"
-#include "mpu.h"
-#include "system_chip.h"
-#include "rom_chip.h"
-
-#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
-
-/* Macros for last 32K ram block */
-#define LAST_RAM_BLK ((NPCX_RAM_SIZE / (32 * 1024)) - 1)
-/* Higher bits are reserved and need to be masked */
-#define RAM_PD_MASK (~BIT(LAST_RAM_BLK))
-
-#ifdef CONFIG_WORKAROUND_FLASH_DOWNLOAD_API
-#define LFW_OFFSET 0x160
-/* Begin address of Suspend RAM for little FW (GDMA utilities). */
-uintptr_t __lpram_lfw_start = CONFIG_LPRAM_BASE + LFW_OFFSET;
-#endif
-/*****************************************************************************/
-/* IC specific low-level driver depends on chip series */
-
-/*
- * Configure address 0x40001600 (Low Power RAM) in the the MPU
- * (Memory Protection Unit) as a "regular" memory
- */
-void system_mpu_config(void)
-{
-#ifdef CONFIG_WORKAROUND_FLASH_DOWNLOAD_API
- /*
- * npcx9 Rev.1 has the problem for download_from_flash API.
- * Workwaroud it by by the system_download_from_flash function
- * in the suspend RAM like npcx5.
- * TODO: Remove this when A2 chip is available
- */
- /* Enable MPU */
- CPU_MPU_CTRL = 0x7;
-
- /* Create a new MPU Region to allow execution from low-power ram */
- CPU_MPU_RNR = REGION_CHIP_RESERVED;
- CPU_MPU_RASR = CPU_MPU_RASR & 0xFFFFFFFE; /* Disable region */
- CPU_MPU_RBAR = CONFIG_LPRAM_BASE; /* Set region base address */
- /*
- * Set region size & attribute and enable region
- * [31:29] - Reserved.
- * [28] - XN (Execute Never) = 0
- * [27] - Reserved.
- * [26:24] - AP = 011 (Full access)
- * [23:22] - Reserved.
- * [21:19,18,17,16] - TEX,S,C,B = 001000 (Normal memory)
- * [15:8] - SRD = 0 (Subregions enabled)
- * [7:6] - Reserved.
- * [5:1] - SIZE = 01001 (1K)
- * [0] - ENABLE = 1 (enabled)
- */
- CPU_MPU_RASR = 0x03080013;
-#endif
-}
-
-#ifdef CONFIG_HIBERNATE_PSL
-#ifndef NPCX_PSL_MODE_SUPPORT
-#error "Do not enable CONFIG_HIBERNATE_PSL if npcx ec doesn't support PSL mode!"
-#endif
-
-static enum psl_pin_t system_gpio_to_psl(enum gpio_signal signal)
-{
- enum psl_pin_t psl_no;
- const struct gpio_info *g = gpio_list + signal;
-
- if (g->port == GPIO_PORT_D && g->mask == MASK_PIN2) /* GPIOD2 */
- psl_no = PSL_IN1;
- else if (g->port == GPIO_PORT_0 && (g->mask & 0x07)) /* GPIO00/01/02 */
- psl_no = GPIO_MASK_TO_NUM(g->mask) + 1;
- else
- psl_no = PSL_NONE;
-
- return psl_no;
-}
-
-#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9
-void system_set_psl_gpo(int level)
-{
- if (level)
- SET_BIT(NPCX_GLUE_PSL_MCTL1, NPCX_GLUE_PSL_MCTL1_PSL_GPO_CTL);
- else
- CLEAR_BIT(NPCX_GLUE_PSL_MCTL1, NPCX_GLUE_PSL_MCTL1_PSL_GPO_CTL);
-}
-#endif
-
-void system_enter_psl_mode(void)
-{
- /* Configure pins from GPIOs to PSL which rely on VSBY power rail. */
- gpio_config_module(MODULE_PMU, 1);
-
- /*
- * In npcx7, only physical PSL_IN pins can pull PSL_OUT to high and
- * reboot ec.
- * In npcx9, LCT timeout event can also pull PSL_OUT.
- * We won't decide the wake cause now but only mark we are entering
- * hibernation via PSL.
- * The actual wakeup cause will be checked by the PSL input event bits
- * when ec reboots.
- */
- NPCX_BBRAM(BBRM_DATA_INDEX_WAKE) = HIBERNATE_WAKE_PSL;
-
-#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9
- /*
- * If pulse mode is enabled, the VCC power is turned off by the
- * external component (Ex: PMIC) but PSL_OUT. So we can just return
- * here.
- */
- if (IS_BIT_SET(NPCX_GLUE_PSL_MCTL1, NPCX_GLUE_PSL_MCTL1_PLS_EN))
- return;
-#endif
-
- /*
- * Pull PSL_OUT (GPIO85) to low to cut off ec's VCC power rail by
- * setting bit 5 of PDOUT(8).
- */
- SET_BIT(NPCX_PDOUT(GPIO_PORT_8), 5);
-}
-
-/* Hibernate function implemented by PSL (Power Switch Logic) mode. */
-noreturn void __keep __enter_hibernate_in_psl(void)
-{
- system_enter_psl_mode();
- /* Spin and wait for PSL cuts power; should never return */
- while (1)
- ;
-}
-
-static void system_psl_type_sel(enum psl_pin_t psl_pin, uint32_t flags)
-{
- /* Set PSL input events' type as level or edge trigger */
- if ((flags & GPIO_INT_F_HIGH) || (flags & GPIO_INT_F_LOW))
- CLEAR_BIT(NPCX_GLUE_PSL_CTS, psl_pin + 4);
- else if ((flags & GPIO_INT_F_RISING) ||
- (flags & GPIO_INT_F_FALLING))
- SET_BIT(NPCX_GLUE_PSL_CTS, psl_pin + 4);
-
- /*
- * Set PSL input events' polarity is low (high-to-low) active or
- * high (low-to-high) active
- */
- if (flags & GPIO_HIB_WAKE_HIGH)
- SET_BIT(NPCX_DEVALT(ALT_GROUP_D), 2 * psl_pin);
- else
- CLEAR_BIT(NPCX_DEVALT(ALT_GROUP_D), 2 * psl_pin);
-}
-
-int system_config_psl_mode(enum gpio_signal signal)
-{
- enum psl_pin_t psl_no;
- const struct gpio_info *g = gpio_list + signal;
-
- psl_no = system_gpio_to_psl(signal);
- if (psl_no == PSL_NONE)
- return 0;
-
- system_psl_type_sel(psl_no, g->flags);
- return 1;
-}
-
-#else
-/**
- * Hibernate function in last 32K ram block for npcx7 series.
- * Do not use global variable since we also turn off data ram.
- */
-noreturn void __keep __attribute__ ((section(".after_init")))
-__enter_hibernate_in_last_block(void)
-{
- /*
- * The hibernate utility is located in the last block of RAM. The size
- * of each RAM block is 32KB. We turn off all blocks except last one
- * for better power consumption.
- */
- NPCX_RAM_PD(0) = RAM_PD_MASK & 0xFF;
-#if defined(CHIP_FAMILY_NPCX7)
- NPCX_RAM_PD(1) = (RAM_PD_MASK >> 8) & 0x0F;
-#elif defined(CHIP_FAMILY_NPCX9)
- NPCX_RAM_PD(1) = (RAM_PD_MASK >> 8) & 0x7F;
-#endif
-
- /* Set deep idle mode */
- NPCX_PMCSR = 0x6;
-
- /* Enter deep idle, wake-up by GPIOs or RTC */
- asm volatile ("wfi");
-
- /* RTC wake-up */
- if (IS_BIT_SET(NPCX_WTC, NPCX_WTC_PTO))
- /*
- * Mark wake-up reason for hibernate
- * Do not call bbram_data_write directly cause of
- * no stack.
- */
- NPCX_BBRAM(BBRM_DATA_INDEX_WAKE) = HIBERNATE_WAKE_MTC;
-#ifdef NPCX_LCT_SUPPORT
- else if (IS_BIT_SET(NPCX_LCTSTAT, NPCX_LCTSTAT_EVST)) {
- NPCX_BBRAM(BBRM_DATA_INDEX_WAKE) = HIBERNATE_WAKE_LCT;
- /* Clear LCT event */
- NPCX_LCTSTAT = BIT(NPCX_LCTSTAT_EVST);
- }
-#endif
- else
- /* Otherwise, we treat it as GPIOs wake-up */
- NPCX_BBRAM(BBRM_DATA_INDEX_WAKE) = HIBERNATE_WAKE_PIN;
-
- /* Start a watchdog reset */
- NPCX_WDCNT = 0x01;
- /* Reload and restart Timer 0 */
- SET_BIT(NPCX_T0CSR, NPCX_T0CSR_RST);
- /* Wait for timer is loaded and restart */
- while (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_RST))
- ;
-
- /* Spin and wait for reboot; should never return */
- while (1)
- ;
-}
-#endif
-
-/**
- * Hibernate function for different Nuvoton chip series.
- */
-void __hibernate_npcx_series(void)
-{
-#ifdef CONFIG_HIBERNATE_PSL
- __enter_hibernate_in_psl();
-#else
- /* Make sure this is located in the last 32K code RAM block */
- ASSERT((uint32_t)(&__after_init_end) - CONFIG_PROGRAM_MEMORY_BASE
- < (32*1024));
-
- /* Execute hibernate func in last 32K block */
- __enter_hibernate_in_last_block();
-#endif
-}
-
-#if defined(CONFIG_HIBERNATE_PSL)
-static void report_psl_wake_source(void)
-{
- if (!(system_get_reset_flags() & EC_RESET_FLAG_HIBERNATE))
- return;
-
- CPRINTS("PSL_CTS: 0x%x", NPCX_GLUE_PSL_CTS & 0xf);
-#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9
- CPRINTS("PSL_MCTL1 event: 0x%x", NPCX_GLUE_PSL_MCTL1 & 0x18);
-#endif
-}
-DECLARE_HOOK(HOOK_INIT, report_psl_wake_source, HOOK_PRIO_DEFAULT);
-#endif
-
-/*
- * npcx9 Rev.1 has the problem for download_from_flash API.
- * Workwaroud it by executing the system_download_from_flash function
- * in the suspend RAM like npcx5.
- * TODO: Removing npcx9 when Rev.2 is available.
- */
-#ifdef CONFIG_WORKAROUND_FLASH_DOWNLOAD_API
-#ifdef CONFIG_EXTERNAL_STORAGE
-/* Sysjump utilities in low power ram for npcx9 series. */
-noreturn void __keep __attribute__ ((section(".lowpower_ram2")))
-__start_gdma(uint32_t exeAddr)
-{
- /* Enable GDMA now */
- SET_BIT(NPCX_GDMA_CTL, NPCX_GDMA_CTL_GDMAEN);
-
- /* Start GDMA */
- SET_BIT(NPCX_GDMA_CTL, NPCX_GDMA_CTL_SOFTREQ);
-
- /* Wait for transfer to complete/fail */
- while (!IS_BIT_SET(NPCX_GDMA_CTL, NPCX_GDMA_CTL_TC) &&
- !IS_BIT_SET(NPCX_GDMA_CTL, NPCX_GDMA_CTL_GDMAERR))
- ;
-
- /* Disable GDMA now */
- CLEAR_BIT(NPCX_GDMA_CTL, NPCX_GDMA_CTL_GDMAEN);
-
- /*
- * Failure occurs during GMDA transaction. Let watchdog issue and
- * boot from RO region again.
- */
- if (IS_BIT_SET(NPCX_GDMA_CTL, NPCX_GDMA_CTL_GDMAERR))
- while (1)
- ;
-
- /*
- * Jump to the exeAddr address if needed. Setting bit 0 of address to
- * indicate it's a thumb branch for cortex-m series CPU.
- */
- ((void (*)(void))(exeAddr | 0x01))();
-
- /* Should never get here */
- while (1)
- ;
-}
-
-/* Bypass for GMDA issue of ROM api utilities only on npcx5 series. */
-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((size % chunkSize) == 0 && (srcAddr % chunkSize) == 0 &&
- (dstAddr % chunkSize) == 0);
-
- /* Check valid address for jumpiing */
- ASSERT(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);
-}
-#endif /* CONFIG_EXTERNAL_STORAGE */
-#endif