diff options
Diffstat (limited to 'chip/npcx')
73 files changed, 0 insertions, 24506 deletions
diff --git a/chip/npcx/adc.c b/chip/npcx/adc.c deleted file mode 100644 index ea16589d9b..0000000000 --- a/chip/npcx/adc.c +++ /dev/null @@ -1,390 +0,0 @@ -/* Copyright 2014 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-specific ADC module for Chrome EC */ - -#include "adc.h" -#include "atomic.h" -#include "clock.h" -#include "clock_chip.h" -#include "console.h" -#include "common.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) - -/* Maximum time we allow for an ADC conversion */ -#define ADC_TIMEOUT_US SECOND -#define ADC_CLK 2000000 -#define ADC_REGULAR_DLY 0x11 -#define ADC_REGULAR_ADCCNF2 0x8B07 -#define ADC_REGULAR_GENDLY 0x0100 -#define ADC_REGULAR_MEAST 0x0001 - -/* ADC conversion mode */ -enum npcx_adc_conversion_mode { - ADC_CHN_CONVERSION_MODE = 0, - ADC_SCAN_CONVERSION_MODE = 1 -}; - -/* Global variables */ -static volatile task_id_t task_waiting; - -struct mutex adc_lock; - -/** - * Preset ADC operation clock. - * - * @param none - * @return none - * @notes changed when initial or HOOK_FREQ_CHANGE command - */ -void adc_freq_changed(void) -{ - uint8_t prescaler_divider = 0; - - /* Set clock prescaler divider to ADC module*/ - prescaler_divider = (uint8_t)(clock_get_apb1_freq() / ADC_CLK); - if (prescaler_divider >= 1) - prescaler_divider = prescaler_divider - 1; - if (prescaler_divider > 0x3F) - prescaler_divider = 0x3F; - - /* Set Core Clock Division Factor in order to obtain the ADC clock */ - SET_FIELD(NPCX_ATCTL, NPCX_ATCTL_SCLKDIV_FIELD, prescaler_divider); -} -DECLARE_HOOK(HOOK_FREQ_CHANGE, adc_freq_changed, HOOK_PRIO_DEFAULT); - -/** - * Flush an ADC sequencer and initiate a read. - * - * @param input_ch operation channel - * @param timeout preset timeout - * @return TRUE/FALSE success/fail - * @notes set SW-triggered interrupt conversion and one-shot mode in npcx chip - */ -static int start_single_and_wait(enum npcx_adc_input_channel input_ch - , int timeout) -{ - int event; - - task_waiting = task_get_current(); - - /* Stop ADC conversion first */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_STOP); - - /* Set ADC conversion code to SW conversion mode */ - SET_FIELD(NPCX_ADCCNF, NPCX_ADCCNF_ADCMD_FIELD, - ADC_CHN_CONVERSION_MODE); - - /* Set conversion type to one-shot type */ - CLEAR_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCRPTC); - - /* Update number of channel to be converted */ - SET_FIELD(NPCX_ASCADD, NPCX_ASCADD_SADDR_FIELD, input_ch); - - /* Clear End-of-Conversion Event status */ - SET_BIT(NPCX_ADCSTS, NPCX_ADCSTS_EOCEV); - - /* Enable ADC End-of-Conversion Interrupt if applicable */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_INTECEN); - - /* Start conversion */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_START); - - /* Wait for interrupt */ - event = task_wait_event_mask(TASK_EVENT_ADC_DONE, timeout); - - task_waiting = TASK_ID_INVALID; - - return (event == TASK_EVENT_ADC_DONE); - -} - -static uint16_t repetitive_enabled; -void npcx_set_adc_repetitive(enum npcx_adc_input_channel input_ch, int enable) -{ - mutex_lock(&adc_lock); - - /* Stop ADC conversion */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_STOP); - - if (enable) { - /* Forbid EC enter deep sleep during conversion. */ - disable_sleep(SLEEP_MASK_ADC); - /* Turn on ADC */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCEN); - /* Set ADC conversion code to SW conversion mode */ - SET_FIELD(NPCX_ADCCNF, NPCX_ADCCNF_ADCMD_FIELD, - ADC_SCAN_CONVERSION_MODE); - /* Update number of channel to be converted */ - SET_BIT(NPCX_ADCCS, input_ch); - /* Set conversion type to repetitive (runs continuously) */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCRPTC); - repetitive_enabled |= BIT(input_ch); - - /* Start conversion */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_START); - } else { - CLEAR_BIT(NPCX_ADCCS, input_ch); - repetitive_enabled &= ~BIT(input_ch); - - if (!repetitive_enabled) { - /* Turn off ADC */ - CLEAR_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCEN); - /* Set ADC to one-shot mode */ - CLEAR_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCRPTC); - /* Allow ec enter deep sleep */ - enable_sleep(SLEEP_MASK_ADC); - } else { - /* Start conversion again */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_START); - } - } - - mutex_unlock(&adc_lock); -} - -/** - * Return the ADC value from CHNDAT register directly. - * - * @param input_ch channel number - * @return ADC data - */ -int adc_read_data(enum npcx_adc_input_channel input_ch) -{ - const struct adc_t *adc = adc_channels + input_ch; - int value; - uint16_t chn_data; - - chn_data = NPCX_CHNDAT(adc->input_ch); - value = GET_FIELD(chn_data, NPCX_CHNDAT_CHDAT_FIELD) * - adc->factor_mul / adc->factor_div + adc->shift; - return value; -} - -/** - * Start a single conversion and return the result - * - * @param ch operation channel - * @return ADC converted voltage or error message - */ -int adc_read_channel(enum adc_channel ch) -{ - const struct adc_t *adc = adc_channels + ch; - int value; - uint16_t chn_data; - - mutex_lock(&adc_lock); - - /* Forbid ec enter deep sleep during ADC conversion is proceeding. */ - disable_sleep(SLEEP_MASK_ADC); - - /* Turn on ADC */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCEN); - - if (start_single_and_wait(adc->input_ch, ADC_TIMEOUT_US)) { - chn_data = NPCX_CHNDAT(adc->input_ch); - if ((adc->input_ch == - GET_FIELD(NPCX_ASCADD, NPCX_ASCADD_SADDR_FIELD)) - && (IS_BIT_SET(chn_data, - NPCX_CHNDAT_NEW))) { - value = GET_FIELD(chn_data, NPCX_CHNDAT_CHDAT_FIELD) * - adc->factor_mul / adc->factor_div + adc->shift; - } else { - value = ADC_READ_ERROR; - } - } else { - value = ADC_READ_ERROR; - } - - if (!repetitive_enabled) { - /* Turn off ADC */ - CLEAR_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCEN); - /* Allow ec enter deep sleep */ - enable_sleep(SLEEP_MASK_ADC); - } else { - /* Set ADC conversion code to SW conversion mode */ - SET_FIELD(NPCX_ADCCNF, NPCX_ADCCNF_ADCMD_FIELD, - ADC_SCAN_CONVERSION_MODE); - /* Set conversion type to repetitive (runs continuously) */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCRPTC); - /* Start conversion */ - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_START); - } - - mutex_unlock(&adc_lock); - - return value; -} - -/* Board should register these callbacks with npcx_adc_cfg_thresh_int(). */ -static void (*adc_thresh_irqs[NPCX_ADC_THRESH_CNT])(void); - -void npcx_adc_thresh_int_enable(int threshold_idx, int enable) -{ - uint16_t thrcts; - - enable = !!enable; - - if ((threshold_idx < 1) || (threshold_idx > NPCX_ADC_THRESH_CNT)) { - CPRINTS("Invalid ADC thresh index! (%d)", - threshold_idx); - return; - } - threshold_idx--; /* convert to 0-based */ - - /* avoid clearing other threshold status */ - thrcts = NPCX_THRCTS & ~GENMASK(NPCX_ADC_THRESH_CNT - 1, 0); - - if (enable) { - /* clear threshold status */ - SET_BIT(thrcts, threshold_idx); - /* set enable threshold status */ - SET_BIT(thrcts, NPCX_THRCTS_THR1_IEN + threshold_idx); - } else { - CLEAR_BIT(thrcts, NPCX_THRCTS_THR1_IEN + threshold_idx); - } - NPCX_THRCTS = thrcts; -} - -void npcx_adc_register_thresh_irq(int threshold_idx, - const struct npcx_adc_thresh_t *thresh_cfg) -{ - int npcx_adc_ch; - int raw_val; - int mul; - int div; - int shift; - - if ((threshold_idx < 1) || (threshold_idx > NPCX_ADC_THRESH_CNT)) { - CPRINTS("Invalid ADC thresh index! (%d)", - threshold_idx); - return; - } - npcx_adc_ch = adc_channels[thresh_cfg->adc_ch].input_ch; - - if (!thresh_cfg->adc_thresh_cb) { - CPRINTS("No callback for ADC Threshold %d!", - threshold_idx); - return; - } - - /* Fill in the table */ - adc_thresh_irqs[threshold_idx-1] = thresh_cfg->adc_thresh_cb; - - /* Select the channel */ - SET_FIELD(NPCX_THRCTL(threshold_idx), NPCX_THRCTL_CHNSEL, - npcx_adc_ch); - - if (thresh_cfg->lower_or_higher) - SET_BIT(NPCX_THRCTL(threshold_idx), NPCX_THRCTL_L_H); - else - CLEAR_BIT(NPCX_THRCTL(threshold_idx), NPCX_THRCTL_L_H); - - /* Set the threshold value. */ - mul = adc_channels[thresh_cfg->adc_ch].factor_mul; - div = adc_channels[thresh_cfg->adc_ch].factor_div; - shift = adc_channels[thresh_cfg->adc_ch].shift; - - raw_val = (thresh_cfg->thresh_assert - shift) * div / mul; - CPRINTS("ADC THR%d: Setting THRVAL = %d, L_H: %d", threshold_idx, - raw_val, thresh_cfg->lower_or_higher); - SET_FIELD(NPCX_THRCTL(threshold_idx), NPCX_THRCTL_THRVAL, - raw_val); - -#if NPCX_FAMILY_VERSION <= NPCX_FAMILY_NPCX7 - /* Disable deassertion threshold function */ - CLEAR_BIT(NPCX_THR_DCTL(threshold_idx), NPCX_THR_DCTL_THRD_EN); -#endif - - /* Enable threshold detection */ - SET_BIT(NPCX_THRCTL(threshold_idx), NPCX_THRCTL_THEN); -} - -/** - * ADC interrupt handler - * - * @param none - * @return none - * @notes Only handle SW-triggered conversion in npcx chip - */ -void adc_interrupt(void) -{ - int i; - uint16_t thrcts; - - if (IS_BIT_SET(NPCX_ADCCNF, NPCX_ADCCNF_INTECEN) && - IS_BIT_SET(NPCX_ADCSTS, NPCX_ADCSTS_EOCEV)) { - /* Disable End-of-Conversion Interrupt */ - CLEAR_BIT(NPCX_ADCCNF, NPCX_ADCCNF_INTECEN); - - /* Stop conversion for single-shot mode */ - if (!repetitive_enabled) - SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_STOP); - - /* Clear End-of-Conversion Event status */ - SET_BIT(NPCX_ADCSTS, NPCX_ADCSTS_EOCEV); - - /* Wake up the task which was waiting for the interrupt */ - if (task_waiting != TASK_ID_INVALID) - task_set_event(task_waiting, TASK_EVENT_ADC_DONE); - } - - for (i = NPCX_THRCTS_THR1_STS; i < NPCX_ADC_THRESH_CNT; i++) { - if (IS_BIT_SET(NPCX_THRCTS, NPCX_THRCTS_THR1_IEN + i) && - IS_BIT_SET(NPCX_THRCTS, i)) { - /* avoid clearing other threshold status */ - thrcts = NPCX_THRCTS & - ~GENMASK(NPCX_ADC_THRESH_CNT - 1, 0); - /* Clear threshold status */ - SET_BIT(thrcts, i); - NPCX_THRCTS = thrcts; - if (adc_thresh_irqs[i]) - adc_thresh_irqs[i](); - } - } -} -DECLARE_IRQ(NPCX_IRQ_ADC, adc_interrupt, 4); - -/** - * ADC initial. - * - * @param none - * @return none - */ -static void adc_init(void) -{ - /* Configure pins from GPIOs to ADCs */ - gpio_config_module(MODULE_ADC, 1); - - /* Enable ADC clock (bit4 mask = 0x10) */ - clock_enable_peripheral(CGC_OFFSET_ADC, CGC_ADC_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - - /* Set Core Clock Division Factor in order to obtain the ADC clock */ - adc_freq_changed(); - - /* Set regular speed */ - SET_FIELD(NPCX_ATCTL, NPCX_ATCTL_DLY_FIELD, (ADC_REGULAR_DLY - 1)); - - /* Set the other ADC settings */ - NPCX_ADCCNF2 = ADC_REGULAR_ADCCNF2; - NPCX_GENDLY = ADC_REGULAR_GENDLY; - NPCX_MEAST = ADC_REGULAR_MEAST; - - task_waiting = TASK_ID_INVALID; - - /* Enable IRQs */ - task_enable_irq(NPCX_IRQ_ADC); -} -DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_INIT_ADC); diff --git a/chip/npcx/adc_chip.h b/chip/npcx/adc_chip.h deleted file mode 100644 index 300447df16..0000000000 --- a/chip/npcx/adc_chip.h +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright 2014 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-specific ADC module for Chrome EC */ - -#ifndef __CROS_EC_ADC_CHIP_H -#define __CROS_EC_ADC_CHIP_H - -#include "common.h" - -/* Minimum and maximum values returned by raw ADC read. */ -#define ADC_READ_MIN 0 -#define ADC_READ_MAX 1023 -#define ADC_MAX_VOLT 2816 - -/* ADC input channel select */ -enum npcx_adc_input_channel { - NPCX_ADC_CH0 = 0, - NPCX_ADC_CH1, - NPCX_ADC_CH2, - NPCX_ADC_CH3, - NPCX_ADC_CH4, -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - NPCX_ADC_CH5, - NPCX_ADC_CH6, - NPCX_ADC_CH7, - NPCX_ADC_CH8, - NPCX_ADC_CH9, -#endif -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - NPCX_ADC_CH10, - NPCX_ADC_CH11, - #endif - NPCX_ADC_CH_COUNT -}; - -/* Data structure to define ADC channels. */ -struct adc_t { - const char *name; - enum npcx_adc_input_channel input_ch; - int factor_mul; - int factor_div; - int shift; -}; - -/* - * Boards may configure a ADC channel for use with thershold interrupts. - * The threshold levels may be set from 0 to ADC_MAX_VOLT inclusive. - */ -struct npcx_adc_thresh_t { - /* The ADC channel to monitor to generate threshold interrupts. */ - enum adc_channel adc_ch; - - /* Called when the interrupt fires */ - void (*adc_thresh_cb)(void); - - /* If set, threshold event is asserted when <= threshold level */ - int lower_or_higher; - - /* Desired threshold level in mV to assert. */ - int thresh_assert; -}; - -/** - * Boards should call this function to register their threshold interrupt with - * one of the threshold detectors. 'threshold_idx' is 1-based. - * - * @param threshold_idx - 1-based threshold detector index - * @param thresh_cfg - Pointer to ADC threshold interrupt configuration - */ -void npcx_adc_register_thresh_irq(int threshold_idx, - const struct npcx_adc_thresh_t *thresh_cfg); - -/** - * Configure an ADC channel for repetitive conversion. - * - * If you are using ADC threshold interrupts and the need is timing critical, - * you will want to enable this on the ADC channels you have configured for - * threshold interrupts. - * - * NOTE: Enabling this will prevent the EC from entering deep sleep and will - * increase power consumption! - * - * @param input_ch - The ADC channel you wish to configure - * @param enable - 1 to enable, 0 to disable - */ -void npcx_set_adc_repetitive(enum npcx_adc_input_channel input_ch, int enable); - -/** - * Enable/Disable ADC threshold detector interrupt. - * - * @param threshold_idx - 1-based threshold detector index - * @param enable - 1 to enable, 0 to disable - */ -void npcx_adc_thresh_int_enable(int threshold_idx, int enable); - -/** - * Return the ADC value from CHNDAT register directly when the channel is - * configured in the repetitive mode. - * - * @param input_ch channel number - * @return ADC data - */ -int adc_read_data(enum npcx_adc_input_channel input_ch); -#endif /* __CROS_EC_ADC_CHIP_H */ diff --git a/chip/npcx/apm.c b/chip/npcx/apm.c deleted file mode 100644 index 4ab64774c1..0000000000 --- a/chip/npcx/apm.c +++ /dev/null @@ -1,694 +0,0 @@ -/* Copyright 2018 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-specific APM module for Chrome EC */ - -#include "apm_chip.h" -#include "common.h" -#include "registers.h" -#include "util.h" -#include "wov_chip.h" - -static struct apm_config apm_conf; -static struct apm_auto_gain_config apm_gain_conf; - - -static uint32_t apm_indirect_reg[][3] = { - {(NPCX_APM_BASE_ADDR + 0x034), (NPCX_APM_BASE_ADDR + 0x038)}, - {(NPCX_APM_BASE_ADDR + 0x04C), (NPCX_APM_BASE_ADDR + 0x050)}, - {(NPCX_APM_BASE_ADDR + 0x05C), (NPCX_APM_BASE_ADDR + 0x060)} -}; - -#define APM_CNTRL_REG 0 -#define APM_DATA_REG 1 - -/** - * Reads data indirect register. - * - * @param reg_offset - Indirect register APM_MIX_REG, APM_ADC_AGC_REG or - * APM_VAD_REG. - * @param indirect_addr - Indirect access address. - * @return The read data. - */ -static uint8_t apm_read_indirect_data(enum apm_indirect_reg_offset reg_offset, - uint8_t indirect_addr) -{ - /* Set the indirect access address. */ - SET_FIELD(REG8(apm_indirect_reg[reg_offset][APM_CNTRL_REG]), - NPCX_APM_CONTROL_ADD, indirect_addr); - - /* Read command. */ - CLEAR_BIT(REG8(apm_indirect_reg[reg_offset][APM_CNTRL_REG]), - NPCX_APM_CONTROL_LOAD); - - /* Get the data. */ - return REG8(apm_indirect_reg[reg_offset][APM_DATA_REG]); -} - -/** - * Writes data indirect register. - * - * @param reg_offset - Indirect register APM_MIX_REG, APM_ADC_AGC_REG or - * APM_VAD_REG. - * @param indirect_addr - Indirect access address. - * @param value - Written value. - * @return None - */ -static void apm_write_indirect_data(enum apm_indirect_reg_offset reg_offset, - uint8_t indirect_addr, uint8_t value) -{ - /* Set the data. */ - REG8(apm_indirect_reg[reg_offset][APM_DATA_REG]) = value; - - /* Set the indirect access address. */ - SET_FIELD(REG8(apm_indirect_reg[reg_offset][APM_CNTRL_REG]), - NPCX_APM_CONTROL_ADD, indirect_addr); - - /* Write command. */ - SET_BIT(REG8(apm_indirect_reg[reg_offset][APM_CNTRL_REG]), - NPCX_APM_CONTROL_LOAD); - CLEAR_BIT(REG8(apm_indirect_reg[reg_offset][APM_CNTRL_REG]), - NPCX_APM_CONTROL_LOAD); -} - -/** - * Sets the ADC DMIC rate. - * - * @param rate - ADC digital microphone rate - * @return None - */ -void apm_set_adc_dmic_config_l(enum apm_dmic_rate rate) -{ - if (rate == APM_DMIC_RATE_0_75) - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_RATE, - APM_DMIC_RATE_3_0); - else if (rate == APM_DMIC_RATE_1_2) - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_RATE, - APM_DMIC_RATE_2_4); - else - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_RATE, - rate); -} - -/** - * Sets VAD DMIC rate. - * - * @param rate - VAD DMIC rate - * - * @return None - */ -void apm_set_vad_dmic_rate_l(enum apm_dmic_rate rate) -{ - uint8_t vad_data; - - vad_data = apm_read_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_0_REG); - - /* Set VAD_0 register. */ - if (rate == APM_DMIC_RATE_0_75) - SET_FIELD(vad_data, NPCX_VAD_0_VAD_DMIC_FREQ, - APM_DMIC_RATE_3_0); - else if (rate == APM_DMIC_RATE_1_2) - SET_FIELD(vad_data, NPCX_VAD_0_VAD_DMIC_FREQ, - APM_DMIC_RATE_2_4); - else - SET_FIELD(vad_data, NPCX_VAD_0_VAD_DMIC_FREQ, rate); - - apm_write_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_0_REG, vad_data); -} - -/*****************************************************************************/ -/* IC specific low-level driver */ - -/** - * Translates from ADC real value to frequency code - * - * @param adc_freq_val - ADC frequency. - * @return ADC frequency code, 0xFFFF in case of wrong value. - */ -static enum apm_adc_frequency apm_adc_freq_val_2_code(uint32_t adc_freq_val) -{ - enum apm_adc_frequency freq_code; - - switch (adc_freq_val) { - case 8000: - freq_code = APM_ADC_FREQ_8_000_KHZ; - break; - case 12000: - freq_code = APM_ADC_FREQ_12_000_KHZ; - break; - case 16000: - freq_code = APM_ADC_FREQ_16_000_KHZ; - break; - case 24000: - freq_code = APM_ADC_FREQ_24_000_KHZ; - break; - case 32000: - freq_code = APM_ADC_FREQ_32_000_KHZ; - break; - case 48000: - freq_code = APM_ADC_FREQ_48_000_KHZ; - break; - default: - freq_code = APM_ADC_FREQ_UNSUPPORTED; - break; - } - - return freq_code; -} - -/** - * Initiate APM module local parameters.. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_init(void) -{ - apm_conf.adc_ram_dmic_rate = APM_DMIC_RATE_0_75; - apm_conf.adc_i2s_dmic_rate = APM_DMIC_RATE_3_0; - apm_conf.gain_coupling = APM_ADC_CHAN_GAINS_INDEPENDENT; - apm_conf.left_chan_gain = 0; - apm_conf.right_chan_gain = 0; - - apm_gain_conf.stereo_enable = 0; - apm_gain_conf.agc_target = APM_ADC_MAX_TARGET_LEVEL_19_5; - apm_gain_conf.nois_gate_en = 0; - apm_gain_conf.nois_gate_thold = APM_MIN_NOISE_GET_THRESHOLD; - apm_gain_conf.hold_time = APM_HOLD_TIME_128; - apm_gain_conf.attack_time = APM_GAIN_RAMP_TIME_160; - apm_gain_conf.decay_time = APM_GAIN_RAMP_TIME_160; - apm_gain_conf.gain_max = APM_GAIN_VALUE_42_5; - apm_gain_conf.gain_min = APM_GAIN_VALUE_0_0; -} - -/** - * Enables/Disables APM module. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_enable(int enable) -{ - if (enable) { - CLEAR_BIT(NPCX_APM_CR_APM, NPCX_APM_CR_APM_PD); - - /* Work around that enable the AGC. */ - SET_FIELD(NPCX_APM_CR_APM, NPCX_APM_CR_APM_AGC_DIS, 0x00); - - } else - SET_BIT(NPCX_APM_CR_APM, NPCX_APM_CR_APM_PD); -} - -/** - * Enables/Disables voice activity detected interrupt. - * - * @param enable - enabled flag, 1 means enable - * @return APM interrupt mode. - */ -void apm_enable_vad_interrupt(int enable) -{ - wov_interrupt_enable(WOV_VAD_INT_INDX, enable); - wov_interrupt_enable(WOV_VAD_WAKE_INDX, enable); - if (enable) - CLEAR_BIT(NPCX_APM_IMR, NPCX_APM_IMR_VAD_DTC_MASK); - else - SET_BIT(NPCX_APM_IMR, NPCX_APM_IMR_VAD_DTC_MASK); -} - -/** - * Enable/Disable the WoV in the ADC. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_adc_wov_enable(int enable) -{ - if (enable) { - SET_FIELD(NPCX_APM_AICR_ADC, - NPCX_APM_AICR_ADC_ADC_AUDIOIF, 0x00); - } else { - SET_FIELD(NPCX_APM_AICR_ADC, - NPCX_APM_AICR_ADC_ADC_AUDIOIF, 0x03); - } -} - -/** - * Enables/Disables ADC. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_adc_enable(int enable) -{ - if (enable) { - CLEAR_BIT(NPCX_APM_AICR_ADC, NPCX_APM_AICR_ADC_PD_AICR_ADC); - SET_FIELD(NPCX_APM_AICR_ADC, - NPCX_APM_AICR_ADC_ADC_AUDIOIF, 0x00); - } else { - SET_BIT(NPCX_APM_AICR_ADC, NPCX_APM_AICR_ADC_PD_AICR_ADC); - SET_FIELD(NPCX_APM_AICR_ADC, - NPCX_APM_AICR_ADC_ADC_AUDIOIF, 0x03); - } -} - -/** - * sets the ADC frequency. - * - * @param adc_freq - ADC frequency. - * @return None - */ -void apm_adc_set_freq(enum apm_adc_frequency adc_freq) -{ - SET_FIELD(NPCX_APM_FCR_ADC, NPCX_APM_FCR_ADC_ADC_FREQ, adc_freq); -} - -/** - * Configures the ADC. - * - * @param hpf_enable - High pass filter enabled flag, 1 means enable - * @param filter_mode - ADC wind noise filter mode. - * @param adc_freq - ADC frequency. - * @return None - */ -void apm_adc_config(int hpf_enable, - enum apm_adc_wind_noise_filter_mode filter_mode, - enum apm_adc_frequency adc_freq) -{ - if (hpf_enable) - SET_BIT(NPCX_APM_FCR_ADC, NPCX_APM_FCR_ADC_ADC_HPF); - else - CLEAR_BIT(NPCX_APM_FCR_ADC, NPCX_APM_FCR_ADC_ADC_HPF); - - SET_FIELD(NPCX_APM_FCR_ADC, NPCX_APM_FCR_ADC_ADC_WNF, filter_mode); - - SET_FIELD(NPCX_APM_FCR_ADC, NPCX_APM_FCR_ADC_ADC_FREQ, adc_freq); -} - -/** - * Enables/Disables Digital Microphone. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_dmic_enable(int enable) -{ - if (enable) - CLEAR_BIT(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_PD_DMIC); - else - SET_BIT(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_PD_DMIC); -} - -/** - * Sets the RAM ADC DMIC rate. - * - * @param rate - ADC digital microphone rate - * @return None - */ -void apm_set_adc_ram_dmic_config(enum apm_dmic_rate rate) -{ - apm_conf.adc_ram_dmic_rate = rate; -} - -/** - * Gets the RAM ADC DMIC rate. - * - * @param None - * @return ADC digital microphone rate code. - */ -enum apm_dmic_rate apm_get_adc_ram_dmic_rate(void) -{ - return apm_conf.adc_ram_dmic_rate; -} - -/** - * Sets the ADC I2S DMIC rate. - * - * @param rate - ADC digital microphone rate - * @return None - */ -void apm_set_adc_i2s_dmic_config(enum apm_dmic_rate rate) -{ - apm_conf.adc_i2s_dmic_rate = rate; -} - -/** - * Gets the ADC I2S DMIC rate. - * - * @param None - * @return ADC digital microphone rate code. - */ -enum apm_dmic_rate apm_get_adc_i2s_dmic_rate(void) -{ - return apm_conf.adc_i2s_dmic_rate; -} -/** - * Configures Digital Mixer - * - * @param mix_left - Mixer left channel output selection on ADC path. - * @param mix_right - Mixer right channel output selection on ADC path. - * @return None - */ -void apm_digital_mixer_config(enum apm_dig_mix mix_left, - enum apm_dig_mix mix_right) -{ - uint8_t mix_2 = 0; - - SET_FIELD(mix_2, NPCX_APM_MIX_2_AIADCL_SEL, mix_left); - SET_FIELD(mix_2, NPCX_APM_MIX_2_AIADCR_SEL, mix_right); - - apm_write_indirect_data(APM_MIX_REG, APM_INDIRECT_MIX_2_REG, mix_2); -} - -/** - * Enables/Disables the VAD functionality. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_vad_enable(int enable) -{ - if (enable) - NPCX_APM_CR_VAD = 0x80; - else - NPCX_APM_CR_VAD = 0x00; -} - -/** - * Enables/Disables VAD ADC wakeup - * - * @param enable - 1 enable, 0 disable. - * - * @return None - */ -void apm_vad_adc_wakeup_enable(int enable) -{ - uint8_t vad_data; - - vad_data = apm_read_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_0_REG); - - if (enable) - SET_BIT(vad_data, NPCX_VAD_0_VAD_ADC_WAKEUP); - else - CLEAR_BIT(vad_data, NPCX_VAD_0_VAD_ADC_WAKEUP); - - apm_write_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_0_REG, vad_data); -} - -/** - * Sets VAD DMIC rate. - * - * @param rate - VAD DMIC rate - * - * @return None - */ -void apm_set_vad_dmic_rate(enum apm_dmic_rate rate) -{ - apm_conf.vad_dmic_rate = rate; -} - -/** - * Gets VAD DMIC rate. - * - * @param None - * - * @return ADC digital microphone rate code. - */ -enum apm_dmic_rate apm_get_vad_dmic_rate(void) -{ - return apm_conf.vad_dmic_rate; -} - -/** - * Sets VAD Input chanel. - * - * @param chan_src - Processed digital microphone channel - * selection. - * @return None - */ -void apm_set_vad_input_channel(enum apm_vad_in_channel_src chan_src) -{ - uint8_t vad_data; - - vad_data = apm_read_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_0_REG); - - SET_FIELD(vad_data, NPCX_VAD_0_VAD_INSEL, chan_src); - - apm_write_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_0_REG, vad_data); -} - -/** - * Sets VAD sensitivity. - * - * @param sensitivity_db - VAD sensitivity in db. - * @return None - */ -void apm_set_vad_sensitivity(uint8_t sensitivity_db) -{ - uint8_t vad_data; - - vad_data = apm_read_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_1_REG); - - SET_FIELD(vad_data, NPCX_VAD_1_VAD_POWER_SENS, sensitivity_db); - - apm_write_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_1_REG, vad_data); -} - -/** - * Gets VAD sensitivity. - * - * @param None. - * @return VAD sensitivity in db - */ -uint8_t apm_get_vad_sensitivity(void) -{ - uint8_t vad_data; - - vad_data = apm_read_indirect_data(APM_VAD_REG, APM_INDIRECT_VAD_1_REG); - - return GET_FIELD(vad_data, NPCX_VAD_1_VAD_POWER_SENS); -} - -/** - * Restarts VAD functionality. - * - * @param None - * @return None - */ -void apm_vad_restart(void) -{ - SET_BIT(NPCX_APM_CR_VAD_CMD, NPCX_APM_CR_VAD_CMD_VAD_RESTART); -} - -/** - * Restarts VAD functionality. - * - * @param gain_coupling - ADC digital gain coupling (independent or - * rigth tracks left). - * @param left_chan_gain - Left channel ADC digital gain programming value. - * @param right_chan_gain - Right channel ADC digital gain programming value. - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list apm_adc_gain_config(enum apm_adc_gain_coupling gain_coupling, - uint8_t left_chan_gain, uint8_t right_chan_gain) -{ - /* Check parameters validity. */ - if ((left_chan_gain > 0x2B) || (right_chan_gain > 0x2B)) - return EC_ERROR_INVAL; - - /* - * Store the parameters in order to use them in case the function - * was called prioe calling to wov_set_mode. - */ - apm_conf.gain_coupling = gain_coupling; - apm_conf.left_chan_gain = left_chan_gain; - apm_conf.right_chan_gain = right_chan_gain; - - /* Set gain coupling.*/ - if (gain_coupling == APM_ADC_CHAN_GAINS_INDEPENDENT) - CLEAR_BIT(NPCX_APM_GCR_ADCL, NPCX_APM_GCR_ADCL_LRGID); - else - SET_BIT(NPCX_APM_GCR_ADCL, NPCX_APM_GCR_ADCL_LRGID); - - /* set channels gains. */ - SET_FIELD(NPCX_APM_GCR_ADCL, NPCX_APM_GCR_ADCL_GIDL, left_chan_gain); - SET_FIELD(NPCX_APM_GCR_ADCR, NPCX_APM_GCR_ADCR_GIDR, right_chan_gain); - - return EC_SUCCESS; -} - -/** - * Enables/Disables the automatic gain. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_auto_gain_cntrl_enable(int enable) -{ - if (enable) - NPCX_APM_CR_ADC_AGC = 0x80; - else - NPCX_APM_CR_ADC_AGC = 0x00; -} - -/** - * Enables/Disables the automatic gain. - * - * @param gain_cfg - struct of apm auto gain config - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list apm_adc_auto_gain_config( - struct apm_auto_gain_config *gain_cfg) -{ - uint8_t gain_data = 0; - - /* Check parameters validity. */ - - if (gain_cfg->gain_min > gain_cfg->gain_max) - return EC_ERROR_INVAL; - - /* - * Store the parameters in order to use them in case the function - * was called prioe calling to wov_set_mode. - */ - apm_gain_conf.stereo_enable = gain_cfg->stereo_enable; - apm_gain_conf.agc_target = gain_cfg->agc_target; - apm_gain_conf.nois_gate_en = gain_cfg->nois_gate_en; - apm_gain_conf.nois_gate_thold = gain_cfg->nois_gate_thold; - apm_gain_conf.hold_time = gain_cfg->hold_time; - apm_gain_conf.attack_time = gain_cfg->attack_time; - apm_gain_conf.decay_time = gain_cfg->decay_time; - apm_gain_conf.gain_max = gain_cfg->gain_max; - apm_gain_conf.gain_min = gain_cfg->gain_min; - - /* Set the parameters. */ - - if (gain_cfg->stereo_enable) - CLEAR_BIT(gain_data, NPCX_ADC_AGC_0_AGC_STEREO); - else - SET_BIT(gain_data, NPCX_ADC_AGC_0_AGC_STEREO); - - SET_FIELD(gain_data, NPCX_ADC_AGC_0_AGC_TARGET, gain_cfg->agc_target); - - apm_write_indirect_data(APM_ADC_AGC_REG, APM_INDIRECT_ADC_AGC_0_REG, - gain_data); - - gain_data = 0; - - if (gain_cfg->nois_gate_en) - SET_BIT(gain_data, NPCX_ADC_AGC_1_NG_EN); - else - CLEAR_BIT(gain_data, NPCX_ADC_AGC_1_NG_EN); - SET_FIELD(gain_data, NPCX_ADC_AGC_1_NG_THR, gain_cfg->nois_gate_thold); - SET_FIELD(gain_data, NPCX_ADC_AGC_1_HOLD, gain_cfg->hold_time); - - apm_write_indirect_data(APM_ADC_AGC_REG, APM_INDIRECT_ADC_AGC_1_REG, - gain_data); - - gain_data = 0; - - SET_FIELD(gain_data, NPCX_ADC_AGC_2_ATK, gain_cfg->attack_time); - SET_FIELD(gain_data, NPCX_ADC_AGC_2_DCY, gain_cfg->decay_time); - - apm_write_indirect_data(APM_ADC_AGC_REG, APM_INDIRECT_ADC_AGC_2_REG, - gain_data); - - gain_data = 0; - - SET_FIELD(gain_data, NPCX_ADC_AGC_3_AGC_MAX, gain_cfg->gain_max); - - apm_write_indirect_data(APM_ADC_AGC_REG, APM_INDIRECT_ADC_AGC_3_REG, - gain_data); - - gain_data = 0; - - SET_FIELD(gain_data, NPCX_ADC_AGC_4_AGC_MIN, gain_cfg->gain_min); - - apm_write_indirect_data(APM_ADC_AGC_REG, APM_INDIRECT_ADC_AGC_4_REG, - gain_data); - - return EC_SUCCESS; -} - -/** - * Sets APM mode (enables & disables APN sub modules accordingly - * to the APM mode). - * - * @param apm_mode - APM mode, DEFAULT, DETECTION, RECORD or INDEPENDENT modes. - * @return None - */ -void apm_set_mode(enum wov_modes wov_mode) -{ - apm_enable(0); - - switch (wov_mode) { - case WOV_MODE_OFF: - apm_enable_vad_interrupt(0); - apm_dmic_enable(0); - apm_adc_enable(0); - apm_vad_enable(0); - wov_apm_active(0); - break; - - case WOV_MODE_VAD: - apm_clear_vad_detected_bit(); - wov_apm_active(1); - apm_dmic_enable(1); - apm_adc_wov_enable(1); - apm_set_vad_dmic_rate_l(apm_conf.vad_dmic_rate); - apm_set_vad_sensitivity(wov_conf.sensitivity_db); - apm_enable_vad_interrupt(1); - apm_vad_restart(); - apm_vad_enable(1); - break; - - case WOV_MODE_RAM: - case WOV_MODE_I2S: - case WOV_MODE_RAM_AND_I2S: - wov_apm_active(1); - apm_vad_enable(0); - apm_enable_vad_interrupt(0); - if (wov_mode == WOV_MODE_RAM) - apm_set_adc_dmic_config_l(apm_conf.adc_ram_dmic_rate); - else - apm_set_adc_dmic_config_l(apm_conf.adc_i2s_dmic_rate); - apm_dmic_enable(1); - apm_adc_enable(1); - break; - - default: - apm_set_vad_dmic_rate_l(APM_DMIC_RATE_1_0); - apm_set_adc_dmic_config_l(APM_DMIC_RATE_1_0); - apm_vad_enable(0); - apm_enable_vad_interrupt(0); - apm_dmic_enable(0); - apm_adc_enable(0); - wov_apm_active(0); - break; - } - - apm_adc_gain_config(apm_conf.gain_coupling, - apm_conf.left_chan_gain, - apm_conf.right_chan_gain); - - apm_adc_auto_gain_config(&apm_gain_conf); - - apm_adc_set_freq(apm_adc_freq_val_2_code(wov_conf.sample_per_sec)); - - if (wov_mode != WOV_MODE_OFF) - apm_enable(1); -} - -/** - * Clears VAD detected bit in IFR register. - * - * @param None - * @return None. - */ -void apm_clear_vad_detected_bit(void) -{ - apm_vad_enable(0); - - APM_CLEAR_VAD_INTERRUPT; -} diff --git a/chip/npcx/apm_chip.h b/chip/npcx/apm_chip.h deleted file mode 100644 index ad62538374..0000000000 --- a/chip/npcx/apm_chip.h +++ /dev/null @@ -1,461 +0,0 @@ -/* Copyright 2018 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_APM_CHIP_H -#define __CROS_EC_APM_CHIP_H - -#include "common.h" - -/* MIX indirect registers. */ -#define APM_INDIRECT_MIX_2_REG 0x02 - -/* ADC_AGC indirect registers. */ -#define APM_INDIRECT_ADC_AGC_0_REG 0x00 -#define APM_INDIRECT_ADC_AGC_1_REG 0x01 -#define APM_INDIRECT_ADC_AGC_2_REG 0x02 -#define APM_INDIRECT_ADC_AGC_3_REG 0x03 -#define APM_INDIRECT_ADC_AGC_4_REG 0x04 - -/* APM_VAD_REG indirect registers. */ -#define APM_INDIRECT_VAD_0_REG 0x00 -#define APM_INDIRECT_VAD_1_REG 0x01 - -/* APM macros. */ -#define APM_IS_IRQ_PENDING IS_BIT_SET(NPCX_APM_SR, NPCX_APM_SR_IRQ_PEND) -#define APM_IS_VOICE_ACTIVITY_DETECTED \ - IS_BIT_SET(NPCX_APM_IFR, NPCX_APM_IFR_VAD_DTC) -#define APM_CLEAR_VAD_INTERRUPT SET_BIT(NPCX_APM_IFR, NPCX_APM_IFR_VAD_DTC) - -/* Indirect registers. */ -enum apm_indirect_reg_offset { - APM_MIX_REG = 0, - APM_ADC_AGC_REG, - APM_VAD_REG -}; - -/* ADC wind noise filter modes. */ -enum apm_adc_wind_noise_filter_mode { - APM_ADC_WIND_NOISE_FILTER_INACTIVE = 0, - APM_ADC_WIND_NOISE_FILTER_MODE_1_ACTIVE, - APM_ADC_WIND_NOISE_FILTER_MODE_2_ACTIVE, - APM_ADC_WIND_NOISE_FILTER_MODE_3_ACTIVE, -}; - -/* ADC frequency. */ -enum apm_adc_frequency { - APM_ADC_FREQ_8_000_KHZ = 0x00, - APM_ADC_FREQ_11_025_KHZ, - APM_ADC_FREQ_12_000_KHZ, - APM_ADC_FREQ_16_000_KHZ, - APM_ADC_FREQ_22_050_KHZ, - APM_ADC_FREQ_24_000_KHZ, - APM_ADC_FREQ_32_000_KHZ, - APM_ADC_FREQ_44_100_KHZ, - APM_ADC_FREQ_48_000_KHZ, - APM_ADC_FREQ_UNSUPPORTED = 0x0F -}; - -/* DMIC source. */ -enum apm_dmic_src { - APM_CURRENT_DMIC_CHANNEL = 0x01, /* Current channel, left or rigth. */ - APM_AVERAGE_DMIC_CHANNEL = 0x02 /* Average between left & right. */ -}; - -/* ADC digital microphone rate. */ -enum apm_dmic_rate { - /* 3.0, 2.4 & 1.0 must be 0, 1 & 2 respectively */ - APM_DMIC_RATE_3_0 = 0, /* 3.0 -3.25 MHz (default). */ - APM_DMIC_RATE_2_4, /* 2.4 -2.6 MHz. */ - APM_DMIC_RATE_1_0, /* 1.0 -1.08 MHz. */ - APM_DMIC_RATE_1_2, /* 1.2 MHz. */ - APM_DMIC_RATE_0_75 /* 750 KHz. */ -}; - -/* Digitla mixer output. */ -enum apm_dig_mix { - APM_OUT_MIX_NORMAL_INPUT = 0, /* Default. */ - APM_OUT_MIX_CROSS_INPUT, - APM_OUT_MIX_MIXED_INPUT, - APM_OUT_MIX_NO_INPUT -}; - -/* VAD Input Channel Selection */ -enum apm_vad_in_channel_src { - APM_IN_LEFT = 0, - APM_IN_RIGHT, - APM_IN_AVERAGE_LEFT_RIGHT, - APM_IN_RESERVED -}; - -/* ADC digital gain coupling. */ -enum apm_adc_gain_coupling { - APM_ADC_CHAN_GAINS_INDEPENDENT = 0, - APM_ADC_RIGHT_CHAN_GAIN_TRACKS_LEFT -}; - -/* ADC target output level. */ -enum apm_adc_target_out_level { - APM_ADC_MAX_TARGET_LEVEL = 0, - APM_ADC_MAX_TARGET_LEVEL_1_5, - APM_ADC_MAX_TARGET_LEVEL_3_0, - APM_ADC_MAX_TARGET_LEVEL_4_5, - APM_ADC_MAX_TARGET_LEVEL_6_0, - APM_ADC_MAX_TARGET_LEVEL_7_5, - APM_ADC_MAX_TARGET_LEVEL_9_0, - APM_ADC_MAX_TARGET_LEVEL_10_5, - APM_ADC_MAX_TARGET_LEVEL_12_0, - APM_ADC_MAX_TARGET_LEVEL_13_5, - APM_ADC_MAX_TARGET_LEVEL_15_0, - APM_ADC_MAX_TARGET_LEVEL_16_5, - APM_ADC_MAX_TARGET_LEVEL_18_0, - APM_ADC_MAX_TARGET_LEVEL_19_5, /* Default. */ - APM_ADC_MAX_TARGET_LEVEL_21_0, - APM_ADC_MAX_TARGET_LEVEL_22_5 -}; - -/* Noise gate threshold values. */ -enum apm_noise_gate_threshold { - APM_MIN_NOISE_GET_THRESHOLD = 0, - APM_MIN_NOISE_GET_THRESHOLD_6, - APM_MIN_NOISE_GET_THRESHOLD_12, - APM_MIN_NOISE_GET_THRESHOLD_18, - APM_MIN_NOISE_GET_THRESHOLD_24, - APM_MIN_NOISE_GET_THRESHOLD_30, - APM_MIN_NOISE_GET_THRESHOLD_36, - APM_MIN_NOISE_GET_THRESHOLD_42 -}; - -/* Hold time in msec before starting AGC adjustment to the TARGET value. */ -enum apm_agc_adj_hold_time { - APM_HOLD_TIME_0 = 0, - APM_HOLD_TIME_2, - APM_HOLD_TIME_4, - APM_HOLD_TIME_8, - APM_HOLD_TIME_16, - APM_HOLD_TIME_32, - APM_HOLD_TIME_64, - APM_HOLD_TIME_128, /* Default. */ - APM_HOLD_TIME_256, - APM_HOLD_TIME_512, - APM_HOLD_TIME_1024, - APM_HOLD_TIME_2048, - APM_HOLD_TIME_4096, - APM_HOLD_TIME_8192, - APM_HOLD_TIME_16384, - APM_HOLD_TIME_32768 -}; - -/* Attack time in msec - gain ramp down. */ -enum apm_gain_ramp_time { - APM_GAIN_RAMP_TIME_32 = 0, - APM_GAIN_RAMP_TIME_64, - APM_GAIN_RAMP_TIME_96, - APM_GAIN_RAMP_TIME_128, - APM_GAIN_RAMP_TIME_160, /* Default. */ - APM_GAIN_RAMP_TIME_192, - APM_GAIN_RAMP_TIME_224, - APM_GAIN_RAMP_TIME_256, - APM_GAIN_RAMP_TIME_288, - APM_GAIN_RAMP_TIME_320, - APM_GAIN_RAMP_TIME_352, - APM_GAIN_RAMP_TIME_384, - APM_GAIN_RAMP_TIME_416, - APM_GAIN_RAMP_TIME_448, - APM_GAIN_RAMP_TIME_480, - APM_GAIN_RAMP_TIME_512 -}; - -/* Minimum and Maximum gain values. */ -enum apm_gain_values { - APM_GAIN_VALUE_0_0 = 0, - APM_GAIN_VALUE_1_5, - APM_GAIN_VALUE_3_0, - APM_GAIN_VALUE_4_5, - APM_GAIN_VALUE_6_0, - APM_GAIN_VALUE_7_5, - APM_GAIN_VALUE_9_0, - APM_GAIN_VALUE_10_5, - APM_GAIN_VALUE_12_0, - APM_GAIN_VALUE_13_5, - APM_GAIN_VALUE_15_0, - APM_GAIN_VALUE_16_5, - APM_GAIN_VALUE_18_0, - APM_GAIN_VALUE_19_5, - APM_GAIN_VALUE_21_0, - APM_GAIN_VALUE_22_5, - APM_GAIN_VALUE_23_0_1ST, - APM_GAIN_VALUE_23_0_2ND, - APM_GAIN_VALUE_23_0_3RD, - APM_GAIN_VALUE_24_5, - APM_GAIN_VALUE_26_0, - APM_GAIN_VALUE_27_5, - APM_GAIN_VALUE_29_0, - APM_GAIN_VALUE_30_5, - APM_GAIN_VALUE_32_0, - APM_GAIN_VALUE_33_5, - APM_GAIN_VALUE_35_0, - APM_GAIN_VALUE_36_5, - APM_GAIN_VALUE_38_0, - APM_GAIN_VALUE_39_5, - APM_GAIN_VALUE_41_0, - APM_GAIN_VALUE_42_5 -}; - -/* ADC Audio Data Word Length */ -enum apm_adc_data_length { - APM_ADC_DATA_LEN_16_BITS = 0x00, - APM_ADC_DATA_LEN_18_BITS, - APM_ADC_DATA_LEN_20_BITS, - APM_ADC_DATA_LEN_24_BITS -}; - -struct apm_config { - enum apm_dmic_rate vad_dmic_rate; - enum apm_dmic_rate adc_ram_dmic_rate; - enum apm_dmic_rate adc_i2s_dmic_rate; - enum apm_adc_gain_coupling gain_coupling; - uint8_t left_chan_gain; - uint8_t right_chan_gain; -}; -struct apm_auto_gain_config { - int stereo_enable; - enum apm_adc_target_out_level agc_target; - int nois_gate_en; - enum apm_noise_gate_threshold nois_gate_thold; - enum apm_agc_adj_hold_time hold_time; - enum apm_gain_ramp_time attack_time; - enum apm_gain_ramp_time decay_time; - enum apm_gain_values gain_max; - enum apm_gain_values gain_min; -}; - -/*****************************************************************************/ -/* IC specific low-level driver */ -enum wov_modes; -/** - * Sets the RAM ADC DMIC rate. - * - * @param rate - ADC digital microphone rate - * @return None - */ -void apm_set_adc_ram_dmic_config(enum apm_dmic_rate rate); - -/** - * Gets the RAM ADC DMIC rate. - * - * @param None - * @return ADC digital microphone rate code. - */ -enum apm_dmic_rate apm_get_adc_ram_dmic_rate(void); - -/** - * Sets the ADC I2S DMIC rate. - * - * @param rate - ADC digital microphone rate - * @return None - */ -void apm_set_adc_i2s_dmic_config(enum apm_dmic_rate rate); - -/** - * Gets the ADC I2S DMIC rate. - * - * @param None - * @return ADC digital microphone rate code. - */ -enum apm_dmic_rate apm_get_adc_i2s_dmic_rate(void); - -/** - * Sets VAD DMIC rate. - * - * @param rate - VAD DMIC rate - * - * @return None - */ -void apm_set_vad_dmic_rate(enum apm_dmic_rate rate); - -/** - * Gets VAD DMIC rate. - * - * @param None - * - * @return ADC digital microphone rate code. - */ -enum apm_dmic_rate apm_get_vad_dmic_rate(void); - -/** - * Gets the ADC DMIC rate. - * - * @param None - * @return ADC digital microphone rate code. - */ -enum apm_dmic_rate apm_get_adc_dmic_rate(void); - -/** - * Initiate APM module local parameters.. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void apm_init(void); - -/** - * Enables/Disables APM module. - * - * @param enable - enabled flag, true means enable - * @return None - */ -void apm_enable(int enable); - -/** - * Enables/Disables voice activity detected interrupt. - * - * @param enable - enabled flag, true means enable - * @return APM interrupt mode. - */ -void apm_enable_vad_interrupt(int enable); - -/** - * Enables/Disables ADC. - * - * @param enable - enabled flag, true means enable - * @return None - */ -void apm_adc_enable(int enable); - -/** - * sets the ADC frequency. - * - * @param adc_freq - ADC frequency. - * @return None - */ -void apm_adc_set_freq(enum apm_adc_frequency adc_freq); - -/** - * Configures the ADC. - * - * @param hpf_enable - High pass filter enabled flag, true means enable - * @param filter_mode - ADC wind noise filter mode. - * @param adc_freq - ADC frequency. - * @return None - */ -void apm_adc_config(int hpf_enable, - enum apm_adc_wind_noise_filter_mode filter_mode, - enum apm_adc_frequency adc_freq); - -/** - * Enables/Disables Digital Microphone. - * - * @param enable - enabled flag, true means enable - * @return None - */ -void apm_dmic_enable(int enable); - -/** - * Configures Digital Microphone. - * - * @param mix_left - Mixer left channel output selection on ADC path. - * @param mix_right - Mixer right channel output selection on ADC path. - * @return None - */ -void apm_digital_mixer_config(enum apm_dig_mix mix_left, - enum apm_dig_mix mix_right); - -/** - * Enables/Disables the VAD functionality. - * - * @param enable - enabled flag, true means enable - * @return None - */ -void apm_vad_enable(int enable); - -/** - * Enables/Disables VAD ADC wakeup - * - * @param enable - true enable, false disable. - * - * @return None - */ -void apm_vad_adc_wakeup_enable(int enable); - -/** - * Sets VAD Input chanel. - * - * @param chan_src - Processed digital microphone channel - * selection. - * @return None - */ -void apm_set_vad_input_channel(enum apm_vad_in_channel_src chan_src); - -/** - * Sets VAD sensitivity. - * - * @param sensitivity_db - VAD sensitivity in db. - * @return None - */ -void apm_set_vad_sensitivity(uint8_t sensitivity_db); - -/** - * Gets VAD sensitivity. - * - * @param None. - * @return VAD sensitivity in db - */ -uint8_t apm_get_vad_sensitivity(void); - -/** - * Restarts VAD functionality. - * - * @param None - * @return None - */ -void apm_vad_restart(void); - -/** - * Restarts VAD functionality. - * - * @param gain_coupling - ADC digital gain coupling (independent or - * rigth tracks left). - * @param left_chan_gain - Left channel ADC digital gain programming value. - * @param right_chan_gain - Right channel ADC digital gain programming value. - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list apm_adc_gain_config(enum apm_adc_gain_coupling gain_coupling, - uint8_t left_chan_gain, uint8_t right_chan_gain); - -/** - * Enables/Disables the automatic gain. - * - * @param enable - enabled flag, true means enable - * @return None - */ -void apm_auto_gain_cntrl_enable(int enable); - -/** - * Enables/Disables the automatic gain. - * - * @param gain_cfg - struct of apm auto gain config - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list apm_adc_auto_gain_config( - struct apm_auto_gain_config *gain_cfg); - -/** - * Sets APM mode (enables & disables APN sub modules accordingly - * to the APM mode). - * - * @param apm_mode - APM mode, DEFAULT, DETECTION, RECORD or INDEPENDENT modes. - * @return None - */ -void apm_set_mode(enum wov_modes wov_mode); - -/** - * Clears VAD detected bit in IFR register. - * - * @param None - * @return None. - */ -void apm_clear_vad_detected_bit(void); - -#endif /* __CROS_EC_APM_CHIP_H */ diff --git a/chip/npcx/audio_codec_dmic.c b/chip/npcx/audio_codec_dmic.c deleted file mode 100644 index e242a8b2d2..0000000000 --- a/chip/npcx/audio_codec_dmic.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2020 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 "audio_codec.h" -#include "ec_commands.h" -#include "wov_chip.h" - -int audio_codec_dmic_get_max_gain(uint8_t *gain) -{ - *gain = 31; - return EC_SUCCESS; -} - -int audio_codec_dmic_set_gain_idx(uint8_t channel, uint8_t gain) -{ - int left_gain, right_gain; - - wov_get_gain(&left_gain, &right_gain); - - switch (channel) { - case EC_CODEC_DMIC_CHANNEL_0: - left_gain = gain; - break; - case EC_CODEC_DMIC_CHANNEL_1: - right_gain = gain; - break; - default: - return EC_ERROR_UNKNOWN; - } - - wov_set_gain(left_gain, right_gain); - return EC_SUCCESS; -} - -int audio_codec_dmic_get_gain_idx(uint8_t channel, uint8_t *gain) -{ - int left_gain, right_gain; - - wov_get_gain(&left_gain, &right_gain); - - switch (channel) { - case EC_CODEC_DMIC_CHANNEL_0: - *gain = left_gain; - break; - case EC_CODEC_DMIC_CHANNEL_1: - *gain = right_gain; - break; - default: - return EC_ERROR_UNKNOWN; - } - - return EC_SUCCESS; -} diff --git a/chip/npcx/audio_codec_i2s_rx.c b/chip/npcx/audio_codec_i2s_rx.c deleted file mode 100644 index 12c4173048..0000000000 --- a/chip/npcx/audio_codec_i2s_rx.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2020 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 "audio_codec.h" -#include "ec_commands.h" -#include "wov_chip.h" - -#define CPRINTS(format, args...) cprints(CC_AUDIO_CODEC, format, ## args) - -int audio_codec_i2s_rx_enable(void) -{ - /* - * The mic source and sample rate don't need to be set each time - * an i2s stream is started, but the audio codec does not - * contain a method to select these as they must be the values - * set below for proper i2s operation. Since the default values - * set in wov.c are different than what's required, they are set - * each time an i2s stream is started. - */ - wov_set_mic_source(WOV_SRC_STEREO); - - /* Mode must be WOV_MODE_OFF to change sample rate */ - wov_set_mode(WOV_MODE_OFF); - wov_set_sample_rate(48000); - - return wov_set_mode(WOV_MODE_I2S); -} - -int audio_codec_i2s_rx_disable(void) -{ - return wov_set_mode(WOV_MODE_OFF); -} - -int audio_codec_i2s_rx_set_sample_depth(uint8_t depth) -{ - int bits_num; - - if (depth == EC_CODEC_I2S_RX_SAMPLE_DEPTH_24) - bits_num = 24; - else - bits_num = 16; - - /* Sample depth can only be changed when mode is WOV_MODE_OFF */ - wov_set_mode(WOV_MODE_OFF); - return wov_set_sample_depth(bits_num); -} - -int audio_codec_i2s_rx_set_daifmt(uint8_t daifmt) -{ - enum wov_dai_format fmt = WOV_DAI_FMT_I2S; - - switch (daifmt) { - case EC_CODEC_I2S_RX_DAIFMT_I2S: - fmt = WOV_DAI_FMT_I2S; - break; - case EC_CODEC_I2S_RX_DAIFMT_RIGHT_J: - fmt = WOV_DAI_FMT_RIGHT_J; - break; - case EC_CODEC_I2S_RX_DAIFMT_LEFT_J: - fmt = WOV_DAI_FMT_LEFT_J; - break; - } - - /* To change mode setting it must be set to WOV_MODE_OFF */ - wov_set_mode(WOV_MODE_OFF); - wov_set_i2s_fmt(fmt); - - return EC_SUCCESS; -} - -int audio_codec_i2s_rx_set_bclk(uint32_t bclk) -{ - /* To change bclk setting it must be set to WOV_MODE_OFF */ - wov_set_mode(WOV_MODE_OFF); - wov_set_i2s_bclk(bclk); - return EC_SUCCESS; -} diff --git a/chip/npcx/build.mk b/chip/npcx/build.mk deleted file mode 100644 index 4be1b2994f..0000000000 --- a/chip/npcx/build.mk +++ /dev/null @@ -1,92 +0,0 @@ -# -*- makefile -*- -# Copyright 2014 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 chip specific files build -# - -# NPCX SoC has a Cortex-M4F ARM core -CORE:=cortex-m -# Allow the full Cortex-M4 instruction set -CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4 - -# Assign default CHIP_FAMILY as npcx5 for old boards used npcx5 series -ifeq ($(CHIP_FAMILY),) -CHIP_FAMILY:=npcx5 -endif - -# Required chip modules -chip-y=header.o clock.o gpio.o hwtimer.o system.o uart.o uartn.o sib.o -chip-y+=system-$(CHIP_FAMILY).o -chip-y+=gpio-$(CHIP_FAMILY).o - -# Optional chip modules -chip-$(CONFIG_ADC)+=adc.o -chip-$(CONFIG_AUDIO_CODEC)+=apm.o wov.o -chip-$(CONFIG_AUDIO_CODEC_DMIC)+=audio_codec_dmic.o -chip-$(CONFIG_AUDIO_CODEC_I2S_RX)+=audio_codec_i2s_rx.o -chip-$(CONFIG_FANS)+=fan.o -chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o -chip-$(CONFIG_I2C)+=i2c.o i2c-$(CHIP_FAMILY).o -chip-$(CONFIG_HOSTCMD_X86)+=lpc.o -chip-$(CONFIG_HOSTCMD_ESPI)+=espi.o -chip-$(CONFIG_PECI)+=peci.o -chip-$(CONFIG_HOSTCMD_SHI)+=shi.o -chip-$(CONFIG_CEC)+=cec.o -# pwm functions are implemented with the fan functions -chip-$(CONFIG_PWM)+=pwm.o -chip-$(CONFIG_SPI)+=spi.o -chip-$(CONFIG_WATCHDOG)+=watchdog.o -ifndef CONFIG_KEYBOARD_NOT_RAW -chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o -endif - -chip-$(CONFIG_PS2)+=ps2.o -# Only npcx9 or later chip family can support LCT module -ifneq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),npcx5 npcx7)) -chip-y+=lct.o -endif - -chip-$(CONFIG_SHA256_HW_ACCELERATE)+=sha256_chip.o - -# spi monitor program fw for openocd and UUT(UART Update Tool) -npcx-monitor-fw=chip/npcx/spiflashfw/npcx_monitor -npcx-monitor-fw-bin=${out}/$(npcx-monitor-fw).bin -PROJECT_EXTRA+=${npcx-monitor-fw-bin} -# Monitor header is only used for UUT which is not supported on npcx5. -ifneq "$(CHIP_FAMILY)" "npcx5" -npcx-monitor-hdr=chip/npcx/spiflashfw/monitor_hdr -npcx-monitor-hdr-ro-bin=${out}/$(npcx-monitor-hdr)_ro.bin -npcx-monitor-hdr-rw-bin=${out}/$(npcx-monitor-hdr)_rw.bin -PROJECT_EXTRA+=${npcx-monitor-hdr-ro-bin} ${npcx-monitor-hdr-rw-bin} -endif - -# ECST tool is for filling the header used by booter of npcx EC -show_esct_cmd=$(if $(V),,echo ' ECST ' $(subst $(out)/,,$@) ; ) - -# Get the firmware length from the mapfile. This can differ from the file -# size when the CONFIG_CHIP_INIT_ROM_REGION is used. Note that the -fwlen -# parameter for the ecst utility must be in hex. -cmd_fwlen=$(shell awk '\ - /__flash_used =/ {flash_used = strtonum($$1)} \ - END {printf ("%x", flash_used)}' $(1)) - -# ECST options for header -bld_ecst=${out}/util/ecst -chip $(CHIP_VARIANT) \ - -usearmrst -mode bt -ph -i $(1) -o $(2) -nohcrc -nofcrc -flashsize 8 \ - -fwlen $(call cmd_fwlen, $(patsubst %.flat,%.map,$(2))) \ - -spimaxclk 50 -spireadmode dual 1> /dev/null - -# Replace original one with the flat file including header -moveflat=mv -f $(1) $(2) - -# Commands for ECST -cmd_ecst=$(show_esct_cmd)$(call moveflat,$@,$@.tmp);$(call bld_ecst,$@.tmp,$@) - -# Commands to append npcx header in ec.RO.flat -cmd_org_ec_elf_to_flat = $(OBJCOPY) --set-section-flags .roshared=share \ - -O binary $(patsubst %.flat,%.elf,$@) $@ -cmd_npcx_ro_elf_to_flat=$(cmd_org_ec_elf_to_flat);$(cmd_ecst) -cmd_ec_elf_to_flat = $(if $(filter $(out)/RO/ec.RO.flat, $@), \ - $(cmd_npcx_ro_elf_to_flat), $(cmd_org_ec_elf_to_flat) ) diff --git a/chip/npcx/cec.c b/chip/npcx/cec.c deleted file mode 100644 index ebaefa551a..0000000000 --- a/chip/npcx/cec.c +++ /dev/null @@ -1,1040 +0,0 @@ -/* Copyright 2018 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 "atomic.h" -#include "cec.h" -#include "clock_chip.h" -#include "console.h" -#include "ec_commands.h" -#include "fan_chip.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "mkbp_event.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#if !(DEBUG_CEC) -#define CPRINTF(...) -#define CPRINTS(...) -#else -#define CPRINTF(format, args...) cprintf(CC_CEC, format, ## args) -#define CPRINTS(format, args...) cprints(CC_CEC, format, ## args) -#endif - -/* Time in us to timer clock ticks */ -#define APB1_TICKS(t) ((t) * apb1_freq_div_10k / 100) -#if DEBUG_CEC -/* Timer clock ticks to us */ -#define APB1_US(ticks) (100*(ticks)/apb1_freq_div_10k) -#endif - -/* Notification from interrupt to CEC task that data has been received */ -#define TASK_EVENT_RECEIVED_DATA TASK_EVENT_CUSTOM_BIT(0) - -/* CEC broadcast address. Also the highest possible CEC address */ -#define CEC_BROADCAST_ADDR 15 - -/* Address to indicate that no logical address has been set */ -#define CEC_UNREGISTERED_ADDR 255 - -/* - * The CEC specification requires at least one and a maximum of - * five resends attempts - */ -#define CEC_MAX_RESENDS 5 - -/* - * Free time timing (us). Our free-time is calculated from the end of - * the last bit (not from the start). We compensate by having one - * free-time period less than in the spec. - */ -#define NOMINAL_BIT_TICKS APB1_TICKS(2400) - /* Resend */ -#define FREE_TIME_RS_TICKS (2 * (NOMINAL_BIT_TICKS)) -/* New initiator */ -#define FREE_TIME_NI_TICKS (4 * (NOMINAL_BIT_TICKS)) -/* Present initiator */ -#define FREE_TIME_PI_TICKS (6 * (NOMINAL_BIT_TICKS)) - -/* Start bit timing */ -#define START_BIT_LOW_TICKS APB1_TICKS(3700) -#define START_BIT_MIN_LOW_TICKS APB1_TICKS(3500) -#define START_BIT_MAX_LOW_TICKS APB1_TICKS(3900) -#define START_BIT_HIGH_TICKS APB1_TICKS(800) -#define START_BIT_MIN_DURATION_TICKS APB1_TICKS(4300) -#define START_BIT_MAX_DURATION_TICKS APB1_TICKS(5700) - -/* Data bit timing */ -#define DATA_ZERO_LOW_TICKS APB1_TICKS(1500) -#define DATA_ZERO_MIN_LOW_TICKS APB1_TICKS(1300) -#define DATA_ZERO_MAX_LOW_TICKS APB1_TICKS(1700) -#define DATA_ZERO_HIGH_TICKS APB1_TICKS(900) -#define DATA_ZERO_MIN_DURATION_TICKS APB1_TICKS(2050) -#define DATA_ZERO_MAX_DURATION_TICKS APB1_TICKS(2750) - -#define DATA_ONE_LOW_TICKS APB1_TICKS(600) -#define DATA_ONE_MIN_LOW_TICKS APB1_TICKS(400) -#define DATA_ONE_MAX_LOW_TICKS APB1_TICKS(800) -#define DATA_ONE_HIGH_TICKS APB1_TICKS(1800) -#define DATA_ONE_MIN_DURATION_TICKS APB1_TICKS(2050) -#define DATA_ONE_MAX_DURATION_TICKS APB1_TICKS(2750) - -/* Time from low that it should be safe to sample an ACK */ -#define NOMINAL_SAMPLE_TIME_TICKS APB1_TICKS(1050) - -#define DATA_TIME(type, data) ((data) ? (DATA_ONE_ ## type ## _TICKS) : \ - (DATA_ZERO_ ## type ## _TICKS)) -#define DATA_HIGH(data) DATA_TIME(HIGH, data) -#define DATA_LOW(data) DATA_TIME(LOW, data) - -/* - * Number of short pulses seen before the debounce logic goes into ignoring - * the bus for DEBOUNCE_WAIT_LONG instead of DEBOUNCE_WAIT_SHORT - */ -#define DEBOUNCE_CUTOFF 3 - -/* The limit how short a start-bit can be to trigger debounce logic */ -#define DEBOUNCE_LIMIT_TICKS APB1_TICKS(200) -/* The time we ignore the bus for the first three debounce cases */ -#define DEBOUNCE_WAIT_SHORT_TICKS APB1_TICKS(100) -/* The time we ignore the bus after the three initial debounce cases */ -#define DEBOUNCE_WAIT_LONG_TICKS APB1_TICKS(500) - -/* - * The variance in timing we allow outside of the CEC specification for - * incoming signals. Our measurements aren't 100% accurate either, so this - * gives some robustness. - */ -#define VALID_TOLERANCE_TICKS APB1_TICKS(100) - -/* - * Defines used for setting capture timers to a point where we are - * sure that if we get a timeout, something is wrong. - */ -#define CAP_START_LOW_TICKS (START_BIT_MAX_LOW_TICKS + VALID_TOLERANCE_TICKS) -#define CAP_START_HIGH_TICKS (START_BIT_MAX_DURATION_TICKS - \ - START_BIT_MIN_LOW_TICKS + \ - VALID_TOLERANCE_TICKS) -#define CAP_DATA_LOW_TICKS (DATA_ZERO_MAX_LOW_TICKS + VALID_TOLERANCE_TICKS) -#define CAP_DATA_HIGH_TICKS (DATA_ONE_MAX_DURATION_TICKS - \ - DATA_ONE_MIN_LOW_TICKS + \ - VALID_TOLERANCE_TICKS) - -#define VALID_TIME(type, bit, t) \ - ((t) >= ((bit ## _MIN_ ## type ## _TICKS) - (VALID_TOLERANCE_TICKS)) \ - && (t) <= (bit ##_MAX_ ## type ## _TICKS) + (VALID_TOLERANCE_TICKS)) -#define VALID_LOW(bit, t) VALID_TIME(LOW, bit, t) -#define VALID_HIGH(bit, low_time, high_time) \ - (((low_time) + (high_time) <= \ - bit ## _MAX_DURATION_TICKS + VALID_TOLERANCE_TICKS) && \ - ((low_time) + (high_time) >= \ - bit ## _MIN_DURATION_TICKS - VALID_TOLERANCE_TICKS)) -#define VALID_DATA_HIGH(data, low_time, high_time) ((data) ? \ - VALID_HIGH(DATA_ONE, low_time, high_time) : \ - VALID_HIGH(DATA_ZERO, low_time, high_time)) - -/* - * CEC state machine states. Each state typically takes action on entry and - * timeouts. INITIATIOR states are used for sending, FOLLOWER states are used - * for receiving. - */ -enum cec_state { - CEC_STATE_DISABLED = 0, - CEC_STATE_IDLE, - CEC_STATE_INITIATOR_FREE_TIME, - CEC_STATE_INITIATOR_START_LOW, - CEC_STATE_INITIATOR_START_HIGH, - CEC_STATE_INITIATOR_HEADER_INIT_LOW, - CEC_STATE_INITIATOR_HEADER_INIT_HIGH, - CEC_STATE_INITIATOR_HEADER_DEST_LOW, - CEC_STATE_INITIATOR_HEADER_DEST_HIGH, - CEC_STATE_INITIATOR_DATA_LOW, - CEC_STATE_INITIATOR_DATA_HIGH, - CEC_STATE_INITIATOR_EOM_LOW, - CEC_STATE_INITIATOR_EOM_HIGH, - CEC_STATE_INITIATOR_ACK_LOW, - CEC_STATE_INITIATOR_ACK_HIGH, - CEC_STATE_INITIATOR_ACK_VERIFY, - CEC_STATE_FOLLOWER_START_LOW, - CEC_STATE_FOLLOWER_START_HIGH, - CEC_STATE_FOLLOWER_DEBOUNCE, - CEC_STATE_FOLLOWER_HEADER_INIT_LOW, - CEC_STATE_FOLLOWER_HEADER_INIT_HIGH, - CEC_STATE_FOLLOWER_HEADER_DEST_LOW, - CEC_STATE_FOLLOWER_HEADER_DEST_HIGH, - CEC_STATE_FOLLOWER_EOM_LOW, - CEC_STATE_FOLLOWER_EOM_HIGH, - CEC_STATE_FOLLOWER_ACK_LOW, - CEC_STATE_FOLLOWER_ACK_VERIFY, - CEC_STATE_FOLLOWER_ACK_FINISH, - CEC_STATE_FOLLOWER_DATA_LOW, - CEC_STATE_FOLLOWER_DATA_HIGH, -}; - -/* Edge to trigger capture timer interrupt on */ -enum cap_edge { - CAP_EDGE_FALLING, - CAP_EDGE_RISING -}; - -/* Receive buffer and states */ -struct cec_rx { - /* - * The current incoming message being parsed. Copied to - * receive queue upon completion - */ - struct cec_msg_transfer transfer; - /* End of Message received from source? */ - uint8_t eom; - /* A follower NAK:ed a broadcast transfer */ - uint8_t broadcast_nak; - /* - * Keep track of pulse low time to be able to verify - * pulse duration - */ - int low_ticks; - /* Number of too short pulses seen in a row */ - int debounce_count; -}; - -/* Transfer buffer and states */ -struct cec_tx { - /* Outgoing message */ - struct cec_msg_transfer transfer; - /* Message length */ - uint8_t len; - /* Number of resends attempted in current send */ - uint8_t resends; - /* Acknowledge received from sink? */ - uint8_t ack; - /* - * When sending multiple concurrent frames, - * the free-time is slightly higher - */ - int present_initiator; -}; - -/* Single state for CEC. We are INITIATOR, FOLLOWER or IDLE */ -static enum cec_state cec_state; - -/* Parameters and buffers for follower (receiver) state */ -static struct cec_rx cec_rx; - -/* Queue of completed incoming CEC messages */ -static struct cec_rx_queue cec_rx_queue; - -/* Parameters and buffer for initiator (sender) state */ -static struct cec_tx cec_tx; - -/* - * Time between interrupt triggered and the next timer was - * set when measuring pulse width - */ -static int cap_delay; - -/* Value charged into the capture timer on last capture start */ -static int cap_charge; - -/* - * CEC address of ourself. We ack incoming packages on this address. - * However, the AP is responsible for writing the initiator address - * on writes. UINT32_MAX means means that the address hasn't been - * set by the AP yet. - */ -static uint8_t cec_addr = UINT8_MAX; - -/* Events to send to AP */ -static uint32_t cec_events; - -/* APB1 frequency. Store divided by 10k to avoid some runtime divisions */ -static uint32_t apb1_freq_div_10k; - -static void send_mkbp_event(uint32_t event) -{ - atomic_or(&cec_events, event); - mkbp_send_event(EC_MKBP_EVENT_CEC_EVENT); -} - -static void tmr_cap_start(enum cap_edge edge, int timeout) -{ - int mdl = NPCX_MFT_MODULE_1; - - /* Select edge to trigger capture on */ - UPDATE_BIT(NPCX_TMCTRL(mdl), NPCX_TMCTRL_TAEDG, - edge == CAP_EDGE_RISING); - - /* - * Set capture timeout. If we don't have a timeout, we - * turn the timeout interrupt off and only care about - * the edge change. - */ - if (timeout > 0) { - /* - * Store the time it takes from the interrupts starts to when we - * actually get here. This part of the pulse-width needs to be - * taken into account - */ - cap_delay = (0xffff - NPCX_TCNT1(mdl)); - cap_charge = timeout - cap_delay; - NPCX_TCNT1(mdl) = cap_charge; - SET_BIT(NPCX_TIEN(mdl), NPCX_TIEN_TCIEN); - } else { - CLEAR_BIT(NPCX_TIEN(mdl), NPCX_TIEN_TCIEN); - NPCX_TCNT1(mdl) = 0; - } - - /* Clear out old events */ - SET_BIT(NPCX_TECLR(mdl), NPCX_TECLR_TACLR); - SET_BIT(NPCX_TECLR(mdl), NPCX_TECLR_TCCLR); - NPCX_TCRA(mdl) = 0; - /* Start the capture timer */ - SET_FIELD(NPCX_TCKC(mdl), NPCX_TCKC_C1CSEL_FIELD, 1); -} - -static void tmr_cap_stop(void) -{ - int mdl = NPCX_MFT_MODULE_1; - - CLEAR_BIT(NPCX_TIEN(mdl), NPCX_TIEN_TCIEN); - SET_FIELD(NPCX_TCKC(mdl), NPCX_TCKC_C1CSEL_FIELD, 0); -} - -static int tmr_cap_get(void) -{ - int mdl = NPCX_MFT_MODULE_1; - - return (cap_charge + cap_delay - NPCX_TCRA(mdl)); -} - -static void tmr_oneshot_start(int timeout) -{ - int mdl = NPCX_MFT_MODULE_1; - - NPCX_TCNT1(mdl) = timeout; - SET_FIELD(NPCX_TCKC(mdl), NPCX_TCKC_C1CSEL_FIELD, 1); -} - -static void tmr2_start(int timeout) -{ - int mdl = NPCX_MFT_MODULE_1; - - NPCX_TCNT2(mdl) = timeout; - SET_FIELD(NPCX_TCKC(mdl), NPCX_TCKC_C2CSEL_FIELD, 1); -} - -static void tmr2_stop(void) -{ - int mdl = NPCX_MFT_MODULE_1; - - SET_FIELD(NPCX_TCKC(mdl), NPCX_TCKC_C2CSEL_FIELD, 0); -} - -void enter_state(enum cec_state new_state) -{ - int gpio = -1, timeout = -1; - enum cap_edge cap_edge = -1; - uint8_t addr; - - cec_state = new_state; - switch (new_state) { - case CEC_STATE_DISABLED: - gpio = 1; - memset(&cec_rx, 0, sizeof(struct cec_rx)); - memset(&cec_tx, 0, sizeof(struct cec_tx)); - memset(&cec_rx_queue, 0, sizeof(struct cec_rx_queue)); - cap_charge = 0; - cap_delay = 0; - cec_events = 0; - break; - case CEC_STATE_IDLE: - cec_tx.transfer.bit = 0; - cec_tx.transfer.byte = 0; - cec_rx.transfer.bit = 0; - cec_rx.transfer.byte = 0; - if (cec_tx.len > 0) { - /* Execute a postponed send */ - enter_state(CEC_STATE_INITIATOR_FREE_TIME); - } else { - /* Wait for incoming command */ - gpio = 1; - cap_edge = CAP_EDGE_FALLING; - timeout = 0; - } - break; - case CEC_STATE_INITIATOR_FREE_TIME: - gpio = 1; - cap_edge = CAP_EDGE_FALLING; - if (cec_tx.resends) - timeout = FREE_TIME_RS_TICKS; - else if (cec_tx.present_initiator) - timeout = FREE_TIME_PI_TICKS; - else - timeout = FREE_TIME_NI_TICKS; - break; - case CEC_STATE_INITIATOR_START_LOW: - cec_tx.present_initiator = 1; - cec_tx.transfer.bit = 0; - cec_tx.transfer.byte = 0; - gpio = 0; - timeout = START_BIT_LOW_TICKS; - break; - case CEC_STATE_INITIATOR_START_HIGH: - gpio = 1; - cap_edge = CAP_EDGE_FALLING; - timeout = START_BIT_HIGH_TICKS; - break; - case CEC_STATE_INITIATOR_HEADER_INIT_LOW: - case CEC_STATE_INITIATOR_HEADER_DEST_LOW: - case CEC_STATE_INITIATOR_DATA_LOW: - gpio = 0; - timeout = DATA_LOW(cec_transfer_get_bit(&cec_tx.transfer)); - break; - case CEC_STATE_INITIATOR_HEADER_INIT_HIGH: - gpio = 1; - cap_edge = CAP_EDGE_FALLING; - timeout = DATA_HIGH(cec_transfer_get_bit(&cec_tx.transfer)); - break; - case CEC_STATE_INITIATOR_HEADER_DEST_HIGH: - case CEC_STATE_INITIATOR_DATA_HIGH: - gpio = 1; - timeout = DATA_HIGH(cec_transfer_get_bit(&cec_tx.transfer)); - break; - case CEC_STATE_INITIATOR_EOM_LOW: - gpio = 0; - timeout = DATA_LOW(cec_transfer_is_eom(&cec_tx.transfer, - cec_tx.len)); - break; - case CEC_STATE_INITIATOR_EOM_HIGH: - gpio = 1; - timeout = DATA_HIGH(cec_transfer_is_eom(&cec_tx.transfer, - cec_tx.len)); - break; - case CEC_STATE_INITIATOR_ACK_LOW: - gpio = 0; - timeout = DATA_LOW(1); - break; - case CEC_STATE_INITIATOR_ACK_HIGH: - gpio = 1; - /* Aim for the middle of the safe sample time */ - timeout = (DATA_ONE_LOW_TICKS + DATA_ZERO_LOW_TICKS)/2 - - DATA_ONE_LOW_TICKS; - break; - case CEC_STATE_INITIATOR_ACK_VERIFY: - cec_tx.ack = !gpio_get_level(CEC_GPIO_OUT); - if ((cec_tx.transfer.buf[0] & 0x0f) == CEC_BROADCAST_ADDR) { - /* - * We are sending a broadcast. Any follower can - * can NAK a broadcast message the same way they - * would ACK a direct message - */ - cec_tx.ack = !cec_tx.ack; - } - /* - * We are at the safe sample time. Wait - * until the end of this bit - */ - timeout = NOMINAL_BIT_TICKS - NOMINAL_SAMPLE_TIME_TICKS; - break; - case CEC_STATE_FOLLOWER_START_LOW: - cec_tx.present_initiator = 0; - cap_edge = CAP_EDGE_RISING; - timeout = CAP_START_LOW_TICKS; - break; - case CEC_STATE_FOLLOWER_START_HIGH: - cec_rx.debounce_count = 0; - cap_edge = CAP_EDGE_FALLING; - timeout = CAP_START_HIGH_TICKS; - break; - case CEC_STATE_FOLLOWER_DEBOUNCE: - if (cec_rx.debounce_count >= DEBOUNCE_CUTOFF) { - timeout = DEBOUNCE_WAIT_LONG_TICKS; - } else { - timeout = DEBOUNCE_WAIT_SHORT_TICKS; - cec_rx.debounce_count++; - } - break; - case CEC_STATE_FOLLOWER_HEADER_INIT_LOW: - case CEC_STATE_FOLLOWER_HEADER_DEST_LOW: - case CEC_STATE_FOLLOWER_EOM_LOW: - cap_edge = CAP_EDGE_RISING; - timeout = CAP_DATA_LOW_TICKS; - break; - case CEC_STATE_FOLLOWER_HEADER_INIT_HIGH: - case CEC_STATE_FOLLOWER_HEADER_DEST_HIGH: - case CEC_STATE_FOLLOWER_EOM_HIGH: - cap_edge = CAP_EDGE_FALLING; - timeout = CAP_DATA_HIGH_TICKS; - break; - case CEC_STATE_FOLLOWER_ACK_LOW: - addr = cec_rx.transfer.buf[0] & 0x0f; - if (addr == cec_addr) { - /* Destination is our address */ - gpio = 0; - timeout = NOMINAL_SAMPLE_TIME_TICKS; - } else if (addr == CEC_BROADCAST_ADDR) { - /* Don't ack broadcast or packets which destination - * are us, but continue reading - */ - timeout = NOMINAL_SAMPLE_TIME_TICKS; - } - break; - case CEC_STATE_FOLLOWER_ACK_VERIFY: - /* - * We are at safe sample time. A broadcast frame is considered - * lost if any follower pulls the line low - */ - if ((cec_rx.transfer.buf[0] & 0x0f) == CEC_BROADCAST_ADDR) - cec_rx.broadcast_nak = !gpio_get_level(CEC_GPIO_OUT); - else - cec_rx.broadcast_nak = 0; - - /* - * We release the ACK at the end of data zero low - * period (ACK is technically a zero). - */ - timeout = DATA_ZERO_LOW_TICKS - NOMINAL_SAMPLE_TIME_TICKS; - break; - case CEC_STATE_FOLLOWER_ACK_FINISH: - gpio = 1; - if (cec_rx.eom || cec_rx.transfer.byte >= MAX_CEC_MSG_LEN) { - addr = cec_rx.transfer.buf[0] & 0x0f; - if (addr == cec_addr || addr == CEC_BROADCAST_ADDR) { - task_set_event(TASK_ID_CEC, - TASK_EVENT_RECEIVED_DATA); - } - timeout = DATA_ZERO_HIGH_TICKS; - } else { - cap_edge = CAP_EDGE_FALLING; - timeout = CAP_DATA_HIGH_TICKS; - } - break; - case CEC_STATE_FOLLOWER_DATA_LOW: - cap_edge = CAP_EDGE_RISING; - timeout = CAP_DATA_LOW_TICKS; - break; - case CEC_STATE_FOLLOWER_DATA_HIGH: - cap_edge = CAP_EDGE_FALLING; - timeout = CAP_DATA_HIGH_TICKS; - break; - /* No default case, since all states must be handled explicitly */ - } - - if (gpio >= 0) - gpio_set_level(CEC_GPIO_OUT, gpio); - if (timeout >= 0) { - if (cap_edge >= 0) - tmr_cap_start(cap_edge, timeout); - else - tmr_oneshot_start(timeout); - } -} - -static void cec_event_timeout(void) -{ - switch (cec_state) { - case CEC_STATE_DISABLED: - case CEC_STATE_IDLE: - break; - case CEC_STATE_INITIATOR_FREE_TIME: - enter_state(CEC_STATE_INITIATOR_START_LOW); - break; - case CEC_STATE_INITIATOR_START_LOW: - enter_state(CEC_STATE_INITIATOR_START_HIGH); - break; - case CEC_STATE_INITIATOR_START_HIGH: - enter_state(CEC_STATE_INITIATOR_HEADER_INIT_LOW); - break; - case CEC_STATE_INITIATOR_HEADER_INIT_LOW: - enter_state(CEC_STATE_INITIATOR_HEADER_INIT_HIGH); - break; - case CEC_STATE_INITIATOR_HEADER_INIT_HIGH: - cec_transfer_inc_bit(&cec_tx.transfer); - if (cec_tx.transfer.bit == 4) - enter_state(CEC_STATE_INITIATOR_HEADER_DEST_LOW); - else - enter_state(CEC_STATE_INITIATOR_HEADER_INIT_LOW); - break; - case CEC_STATE_INITIATOR_HEADER_DEST_LOW: - enter_state(CEC_STATE_INITIATOR_HEADER_DEST_HIGH); - break; - case CEC_STATE_INITIATOR_HEADER_DEST_HIGH: - cec_transfer_inc_bit(&cec_tx.transfer); - if (cec_tx.transfer.byte == 1) - enter_state(CEC_STATE_INITIATOR_EOM_LOW); - else - enter_state(CEC_STATE_INITIATOR_HEADER_DEST_LOW); - break; - case CEC_STATE_INITIATOR_EOM_LOW: - enter_state(CEC_STATE_INITIATOR_EOM_HIGH); - break; - case CEC_STATE_INITIATOR_EOM_HIGH: - enter_state(CEC_STATE_INITIATOR_ACK_LOW); - break; - case CEC_STATE_INITIATOR_ACK_LOW: - enter_state(CEC_STATE_INITIATOR_ACK_HIGH); - break; - case CEC_STATE_INITIATOR_ACK_HIGH: - enter_state(CEC_STATE_INITIATOR_ACK_VERIFY); - break; - case CEC_STATE_INITIATOR_ACK_VERIFY: - if (cec_tx.ack) { - if (!cec_transfer_is_eom(&cec_tx.transfer, - cec_tx.len)) { - /* More data in this frame */ - enter_state(CEC_STATE_INITIATOR_DATA_LOW); - } else { - /* Transfer completed successfully */ - cec_tx.len = 0; - cec_tx.resends = 0; - enter_state(CEC_STATE_IDLE); - send_mkbp_event(EC_MKBP_CEC_SEND_OK); - } - } else { - if (cec_tx.resends < CEC_MAX_RESENDS) { - /* Resend */ - cec_tx.resends++; - enter_state(CEC_STATE_INITIATOR_FREE_TIME); - } else { - /* Transfer failed */ - cec_tx.len = 0; - cec_tx.resends = 0; - enter_state(CEC_STATE_IDLE); - send_mkbp_event(EC_MKBP_CEC_SEND_FAILED); - } - } - break; - case CEC_STATE_INITIATOR_DATA_LOW: - enter_state(CEC_STATE_INITIATOR_DATA_HIGH); - break; - case CEC_STATE_INITIATOR_DATA_HIGH: - cec_transfer_inc_bit(&cec_tx.transfer); - if (cec_tx.transfer.bit == 0) - enter_state(CEC_STATE_INITIATOR_EOM_LOW); - else - enter_state(CEC_STATE_INITIATOR_DATA_LOW); - break; - case CEC_STATE_FOLLOWER_ACK_LOW: - enter_state(CEC_STATE_FOLLOWER_ACK_VERIFY); - break; - case CEC_STATE_FOLLOWER_ACK_VERIFY: - if (cec_rx.broadcast_nak) - enter_state(CEC_STATE_IDLE); - else - enter_state(CEC_STATE_FOLLOWER_ACK_FINISH); - break; - case CEC_STATE_FOLLOWER_START_LOW: - case CEC_STATE_FOLLOWER_START_HIGH: - case CEC_STATE_FOLLOWER_DEBOUNCE: - case CEC_STATE_FOLLOWER_HEADER_INIT_LOW: - case CEC_STATE_FOLLOWER_HEADER_INIT_HIGH: - case CEC_STATE_FOLLOWER_HEADER_DEST_LOW: - case CEC_STATE_FOLLOWER_HEADER_DEST_HIGH: - case CEC_STATE_FOLLOWER_EOM_LOW: - case CEC_STATE_FOLLOWER_EOM_HIGH: - case CEC_STATE_FOLLOWER_ACK_FINISH: - case CEC_STATE_FOLLOWER_DATA_LOW: - case CEC_STATE_FOLLOWER_DATA_HIGH: - enter_state(CEC_STATE_IDLE); - break; - - } -} - -static void cec_event_cap(void) -{ - int t; - int data; - - switch (cec_state) { - case CEC_STATE_IDLE: - /* A falling edge during idle, likely a start bit */ - enter_state(CEC_STATE_FOLLOWER_START_LOW); - break; - case CEC_STATE_INITIATOR_FREE_TIME: - case CEC_STATE_INITIATOR_START_HIGH: - case CEC_STATE_INITIATOR_HEADER_INIT_HIGH: - /* - * A falling edge during free-time, postpone - * this send and listen - */ - cec_tx.transfer.bit = 0; - cec_tx.transfer.byte = 0; - enter_state(CEC_STATE_FOLLOWER_START_LOW); - break; - case CEC_STATE_FOLLOWER_START_LOW: - /* Rising edge of start bit, validate low time */ - t = tmr_cap_get(); - if (VALID_LOW(START_BIT, t)) { - cec_rx.low_ticks = t; - enter_state(CEC_STATE_FOLLOWER_START_HIGH); - } else if (t < DEBOUNCE_LIMIT_TICKS) { - /* Wait a bit if start-pulses are really short */ - enter_state(CEC_STATE_FOLLOWER_DEBOUNCE); - } else { - enter_state(CEC_STATE_IDLE); - } - break; - case CEC_STATE_FOLLOWER_START_HIGH: - if (VALID_HIGH(START_BIT, cec_rx.low_ticks, tmr_cap_get())) - enter_state(CEC_STATE_FOLLOWER_HEADER_INIT_LOW); - else - enter_state(CEC_STATE_IDLE); - break; - case CEC_STATE_FOLLOWER_HEADER_INIT_LOW: - case CEC_STATE_FOLLOWER_HEADER_DEST_LOW: - case CEC_STATE_FOLLOWER_DATA_LOW: - t = tmr_cap_get(); - if (VALID_LOW(DATA_ZERO, t)) { - cec_rx.low_ticks = t; - cec_transfer_set_bit(&cec_rx.transfer, 0); - enter_state(cec_state + 1); - } else if (VALID_LOW(DATA_ONE, t)) { - cec_rx.low_ticks = t; - cec_transfer_set_bit(&cec_rx.transfer, 1); - enter_state(cec_state + 1); - } else { - enter_state(CEC_STATE_IDLE); - } - break; - case CEC_STATE_FOLLOWER_HEADER_INIT_HIGH: - t = tmr_cap_get(); - data = cec_transfer_get_bit(&cec_rx.transfer); - if (VALID_DATA_HIGH(data, cec_rx.low_ticks, t)) { - cec_transfer_inc_bit(&cec_rx.transfer); - if (cec_rx.transfer.bit == 4) - enter_state(CEC_STATE_FOLLOWER_HEADER_DEST_LOW); - else - enter_state(CEC_STATE_FOLLOWER_HEADER_INIT_LOW); - } else { - enter_state(CEC_STATE_IDLE); - } - break; - case CEC_STATE_FOLLOWER_HEADER_DEST_HIGH: - t = tmr_cap_get(); - data = cec_transfer_get_bit(&cec_rx.transfer); - if (VALID_DATA_HIGH(data, cec_rx.low_ticks, t)) { - cec_transfer_inc_bit(&cec_rx.transfer); - if (cec_rx.transfer.bit == 0) - enter_state(CEC_STATE_FOLLOWER_EOM_LOW); - else - enter_state(CEC_STATE_FOLLOWER_HEADER_DEST_LOW); - } else { - enter_state(CEC_STATE_IDLE); - } - break; - case CEC_STATE_FOLLOWER_EOM_LOW: - t = tmr_cap_get(); - if (VALID_LOW(DATA_ZERO, t)) { - cec_rx.low_ticks = t; - cec_rx.eom = 0; - enter_state(CEC_STATE_FOLLOWER_EOM_HIGH); - } else if (VALID_LOW(DATA_ONE, t)) { - cec_rx.low_ticks = t; - cec_rx.eom = 1; - enter_state(CEC_STATE_FOLLOWER_EOM_HIGH); - } else { - enter_state(CEC_STATE_IDLE); - } - break; - case CEC_STATE_FOLLOWER_EOM_HIGH: - t = tmr_cap_get(); - data = cec_rx.eom; - if (VALID_DATA_HIGH(data, cec_rx.low_ticks, t)) - enter_state(CEC_STATE_FOLLOWER_ACK_LOW); - else - enter_state(CEC_STATE_IDLE); - break; - case CEC_STATE_FOLLOWER_ACK_LOW: - enter_state(CEC_STATE_FOLLOWER_ACK_FINISH); - break; - case CEC_STATE_FOLLOWER_ACK_FINISH: - enter_state(CEC_STATE_FOLLOWER_DATA_LOW); - break; - case CEC_STATE_FOLLOWER_DATA_HIGH: - t = tmr_cap_get(); - data = cec_transfer_get_bit(&cec_rx.transfer); - if (VALID_DATA_HIGH(data, cec_rx.low_ticks, t)) { - cec_transfer_inc_bit(&cec_rx.transfer); - if (cec_rx.transfer.bit == 0) - enter_state(CEC_STATE_FOLLOWER_EOM_LOW); - else - enter_state(CEC_STATE_FOLLOWER_DATA_LOW); - } else { - enter_state(CEC_STATE_IDLE); - } - break; - default: - break; - } -} - -static void cec_event_tx(void) -{ - /* - * If we have an ongoing receive, this transfer - * will start when transitioning to IDLE - */ - if (cec_state == CEC_STATE_IDLE) - enter_state(CEC_STATE_INITIATOR_FREE_TIME); -} - -void cec_isr(void) -{ - int mdl = NPCX_MFT_MODULE_1; - uint8_t events; - - /* Retrieve events NPCX_TECTRL_TAXND */ - events = GET_FIELD(NPCX_TECTRL(mdl), FIELD(0, 4)); - - if (events & BIT(NPCX_TECTRL_TAPND)) { - /* Capture event */ - cec_event_cap(); - } else { - /* - * Capture timeout - * We only care about this if the capture event is not - * happening, since we will get both events in the - * edge-trigger case - */ - if (events & BIT(NPCX_TECTRL_TCPND)) - cec_event_timeout(); - } - /* Oneshot timer, a transfer has been initiated from AP */ - if (events & BIT(NPCX_TECTRL_TDPND)) { - tmr2_stop(); - cec_event_tx(); - } - - /* Clear handled events */ - SET_FIELD(NPCX_TECLR(mdl), FIELD(0, 4), events); -} -DECLARE_IRQ(NPCX_IRQ_MFT_1, cec_isr, 4); - -static int cec_send(const uint8_t *msg, uint8_t len) -{ - int i; - - if (cec_tx.len != 0) - return -1; - - cec_tx.len = len; - - CPRINTS("Send CEC:"); - for (i = 0; i < len && i < MAX_CEC_MSG_LEN; i++) - CPRINTS(" 0x%02x", msg[i]); - - memcpy(cec_tx.transfer.buf, msg, len); - - /* Elevate to interrupt context */ - tmr2_start(0); - - return 0; -} - -static enum ec_status hc_cec_write(struct host_cmd_handler_args *args) -{ - const struct ec_params_cec_write *params = args->params; - - if (cec_state == CEC_STATE_DISABLED) - return EC_RES_UNAVAILABLE; - - if (args->params_size == 0 || args->params_size > MAX_CEC_MSG_LEN) - return EC_RES_INVALID_PARAM; - - if (cec_send(params->msg, args->params_size) != 0) - return EC_RES_BUSY; - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_CEC_WRITE_MSG, hc_cec_write, EC_VER_MASK(0)); - -static int cec_set_enable(uint8_t enable) -{ - int mdl = NPCX_MFT_MODULE_1; - - if (enable != 0 && enable != 1) - return EC_RES_INVALID_PARAM; - - /* Enabling when already enabled? */ - if (enable && cec_state != CEC_STATE_DISABLED) - return EC_RES_SUCCESS; - - /* Disabling when already disabled? */ - if (!enable && cec_state == CEC_STATE_DISABLED) - return EC_RES_SUCCESS; - - if (enable) { - /* Configure GPIO40/TA1 as capture timer input (TA1) */ - CLEAR_BIT(NPCX_DEVALT(0xC), NPCX_DEVALTC_TA1_SL2); - SET_BIT(NPCX_DEVALT(3), NPCX_DEVALT3_TA1_SL1); - - enter_state(CEC_STATE_IDLE); - - /* - * Capture falling edge of first start - * bit to get things going - */ - tmr_cap_start(CAP_EDGE_FALLING, 0); - - /* Enable timer interrupts */ - SET_BIT(NPCX_TIEN(mdl), NPCX_TIEN_TAIEN); - SET_BIT(NPCX_TIEN(mdl), NPCX_TIEN_TDIEN); - - /* Enable multifunction timer interrupt */ - task_enable_irq(NPCX_IRQ_MFT_1); - - CPRINTF("CEC enabled\n"); - } else { - /* Disable timer interrupts */ - CLEAR_BIT(NPCX_TIEN(mdl), NPCX_TIEN_TAIEN); - CLEAR_BIT(NPCX_TIEN(mdl), NPCX_TIEN_TDIEN); - - tmr2_stop(); - tmr_cap_stop(); - - task_disable_irq(NPCX_IRQ_MFT_1); - - /* Configure GPIO40/TA1 back to GPIO */ - CLEAR_BIT(NPCX_DEVALT(3), NPCX_DEVALT3_TA1_SL1); - SET_BIT(NPCX_DEVALT(0xC), NPCX_DEVALTC_TA1_SL2); - - enter_state(CEC_STATE_DISABLED); - - CPRINTF("CEC disabled\n"); - } - - return EC_RES_SUCCESS; -} - -static int cec_set_logical_addr(uint8_t logical_addr) -{ - if (logical_addr >= CEC_BROADCAST_ADDR && - logical_addr != CEC_UNREGISTERED_ADDR) - return EC_RES_INVALID_PARAM; - - cec_addr = logical_addr; - CPRINTF("CEC address set to: %u\n", cec_addr); - - return EC_RES_SUCCESS; -} - -static enum ec_status hc_cec_set(struct host_cmd_handler_args *args) -{ - const struct ec_params_cec_set *params = args->params; - - switch (params->cmd) { - case CEC_CMD_ENABLE: - return cec_set_enable(params->val); - case CEC_CMD_LOGICAL_ADDRESS: - return cec_set_logical_addr(params->val); - } - - return EC_RES_INVALID_PARAM; -} -DECLARE_HOST_COMMAND(EC_CMD_CEC_SET, hc_cec_set, EC_VER_MASK(0)); - - -static enum ec_status hc_cec_get(struct host_cmd_handler_args *args) -{ - struct ec_response_cec_get *response = args->response; - const struct ec_params_cec_get *params = args->params; - - switch (params->cmd) { - case CEC_CMD_ENABLE: - response->val = cec_state == CEC_STATE_DISABLED ? 0 : 1; - break; - case CEC_CMD_LOGICAL_ADDRESS: - response->val = cec_addr; - break; - default: - return EC_RES_INVALID_PARAM; - } - - args->response_size = sizeof(*response); - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_CEC_GET, hc_cec_get, EC_VER_MASK(0)); - -static int cec_get_next_event(uint8_t *out) -{ - uint32_t event_out = atomic_clear(&cec_events); - - memcpy(out, &event_out, sizeof(event_out)); - - return sizeof(event_out); -} -DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_CEC_EVENT, cec_get_next_event); - -static int cec_get_next_msg(uint8_t *out) -{ - int rv; - uint8_t msg_len, msg[MAX_CEC_MSG_LEN]; - - rv = cec_rx_queue_pop(&cec_rx_queue, msg, &msg_len); - if (rv != 0) - return EC_RES_UNAVAILABLE; - - memcpy(out, msg, msg_len); - - return msg_len; -} -DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_CEC_MESSAGE, cec_get_next_msg); - - -static void cec_init(void) -{ - int mdl = NPCX_MFT_MODULE_1; - - /* APB1 is the clock we base the timers on */ - apb1_freq_div_10k = clock_get_apb1_freq()/10000; - - /* Ensure Multi-Function timer is powered up. */ - CLEAR_BIT(NPCX_PWDWN_CTL(mdl), NPCX_PWDWN_CTL1_MFT1_PD); - - /* Mode 2 - Dual-input capture */ - SET_FIELD(NPCX_TMCTRL(mdl), NPCX_TMCTRL_MDSEL_FIELD, NPCX_MFT_MDSEL_2); - - /* Enable capture TCNT1 into TCRA and preset TCNT1. */ - SET_BIT(NPCX_TMCTRL(mdl), NPCX_TMCTRL_TAEN); - - /* If RO doesn't set it, RW needs to set it explicitly. */ - gpio_set_level(CEC_GPIO_PULL_UP, 1); - - /* Ensure the CEC bus is not pulled low by default on startup. */ - gpio_set_level(CEC_GPIO_OUT, 1); - - CPRINTS("CEC initialized"); -} -DECLARE_HOOK(HOOK_INIT, cec_init, HOOK_PRIO_LAST); - -void cec_task(void *unused) -{ - int rv; - uint32_t events; - - CPRINTF("CEC task starting\n"); - - while (1) { - events = task_wait_event(-1); - if (events & TASK_EVENT_RECEIVED_DATA) { - rv = cec_rx_queue_push(&cec_rx_queue, - cec_rx.transfer.buf, - cec_rx.transfer.byte); - if (rv == EC_ERROR_OVERFLOW) { - /* Queue full, prefer the most recent msg */ - cec_rx_queue_flush(&cec_rx_queue); - rv = cec_rx_queue_push(&cec_rx_queue, - cec_rx.transfer.buf, - cec_rx.transfer.byte); - } - if (rv == EC_SUCCESS) - mkbp_send_event(EC_MKBP_EVENT_CEC_MESSAGE); - } - } -} diff --git a/chip/npcx/clock.c b/chip/npcx/clock.c deleted file mode 100644 index ad611973be..0000000000 --- a/chip/npcx/clock.c +++ /dev/null @@ -1,517 +0,0 @@ -/* Copyright 2014 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. - */ - -/* Clocks and power management settings */ - -#include "clock.h" -#include "clock_chip.h" -#include "common.h" -#include "console.h" -#include "cpu.h" -#include "gpio.h" -#include "gpio_chip.h" -#include "hooks.h" -#include "hwtimer.h" -#include "hwtimer_chip.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "uart.h" -#include "uartn.h" -#include "util.h" -#include "watchdog.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CLOCK, outstr) -#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args) - -#define WAKE_INTERVAL 61 /* Unit: 61 usec */ -#define IDLE_PARAMS 0x7 /* Support deep idle, instant wake-up */ - -/* Low power idle statistics */ -#ifdef CONFIG_LOW_POWER_IDLE -static int idle_sleep_cnt; -static int idle_dsleep_cnt; -static uint64_t idle_dsleep_time_us; -/* - * Fixed amount of time to keep the console in use flag true after boot in - * order to give a permanent window in which the low speed clock is not used. - */ -#define CONSOLE_IN_USE_ON_BOOT_TIME (15*SECOND) -static int console_in_use_timeout_sec = 15; -static timestamp_t console_expire_time; -#endif - -/** - * Enable clock to peripheral by setting the CGC register pertaining - * to run, sleep, and/or deep sleep modes. - * - * @param offset Offset of the peripheral. See enum clock_gate_offsets. - * @param mask Bit mask of the bits within CGC reg to set. - * @param mode no used - */ -void clock_enable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode) -{ - /* Don't support for different mode */ - uint8_t reg_mask = mask & 0xff; - - /* Set PD bit to 0 */ - NPCX_PWDWN_CTL(offset) &= ~reg_mask; - /* Wait for clock change to take affect. */ - clock_wait_cycles(3); -} - -/** - * Disable clock to peripheral by setting the CGC register pertaining - * to run, sleep, and/or deep sleep modes. - * - * @param offset Offset of the peripheral. See enum clock_gate_offsets. - * @param mask Bit mask of the bits within CGC reg to clear. - * @param mode no used - */ -void clock_disable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode) -{ - /* Don't support for different mode */ - uint8_t reg_mask = mask & 0xff; - - /* Set PD bit to 1 */ - NPCX_PWDWN_CTL(offset) |= reg_mask; - -} - -/*****************************************************************************/ -/* IC specific low-level driver */ - -/** - * Set the CPU clocks and PLLs. - */ -void clock_init(void) -{ -#if defined(CONFIG_CLOCK_SRC_EXTERNAL) && defined(NPCX_EXT32K_OSC_SUPPORT) - /* Select external 32kHz crystal oscillator as LFCLK source. */ - SET_BIT(NPCX_LFCGCTL2, NPCX_LFCGCTL2_XT_OSC_SL_EN); -#endif - - /* - * Resting the OSC_CLK (even to the same value) will make the clock - * unstable for a little which can affect peripheral communication like - * eSPI. Skip this if not needed (e.g. RW jump) - */ - if (NPCX_HFCGN != HFCGN || NPCX_HFCGML != HFCGML - || NPCX_HFCGMH != HFCGMH) { - /* - * Configure frequency multiplier M/N values according to - * the requested OSC_CLK (Unit:Hz). - */ - NPCX_HFCGN = HFCGN; - NPCX_HFCGML = HFCGML; - NPCX_HFCGMH = HFCGMH; - - /* Load M and N values into the frequency multiplier */ - SET_BIT(NPCX_HFCGCTRL, NPCX_HFCGCTRL_LOAD); - /* Wait for stable */ - while (IS_BIT_SET(NPCX_HFCGCTRL, NPCX_HFCGCTRL_CLK_CHNG)) - ; - } - - /* Set all clock prescalers of core and peripherals. */ -#if defined(CHIP_FAMILY_NPCX5) - NPCX_HFCGP = (FPRED << 4); - NPCX_HFCBCD = (NPCX_HFCBCD & 0xF0) | (APB1DIV | (APB2DIV << 2)); -#elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - NPCX_HFCGP = ((FPRED << 4) | AHB6DIV); - NPCX_HFCBCD = (FIUDIV << 4); - NPCX_HFCBCD1 = (APB1DIV | (APB2DIV << 4)); -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - NPCX_HFCBCD2 = (APB3DIV | (APB4DIV << 4)); -#else - NPCX_HFCBCD2 = APB3DIV; -#endif -#endif - - /* Notify modules of frequency change */ - hook_notify(HOOK_FREQ_CHANGE); - - /* Configure alt. clock GPIOs (eg. optional 32KHz clock) */ - gpio_config_module(MODULE_CLOCK, 1); -} - -#if defined(CHIP_FAMILY_NPCX5) -void clock_turbo(void) -{ - /* Configure Frequency multiplier values to 50MHz */ - NPCX_HFCGN = 0x02; - NPCX_HFCGML = 0xEC; - NPCX_HFCGMH = 0x0B; - - /* Load M and N values into the frequency multiplier */ - SET_BIT(NPCX_HFCGCTRL, NPCX_HFCGCTRL_LOAD); - - /* Wait for stable */ - while (IS_BIT_SET(NPCX_HFCGCTRL, NPCX_HFCGCTRL_CLK_CHNG)) - ; - - /* Keep Core CLK & FMCLK are the same if Core CLK exceed 33MHz */ - NPCX_HFCGP = 0x00; - - /* - * Let APB2 equals Core CLK/2 if default APB2 clock is divisible - * by 1MHz - */ - NPCX_HFCBCD = NPCX_HFCBCD & 0xF3; -} -#elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 -void clock_turbo(void) -{ -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - /* For NPCX9: - * Increase CORE_CLK (CPU) as the same as OSC_CLK. Since - * CORE_CLK > 66MHz, we also need to set FIUDIV as 1 but - * can keep AHB6DIV to 0. - */ - NPCX_HFCGP = 0x00; -#else - /* For NPCX7: - * Increase CORE_CLK (CPU) as the same as OSC_CLK. Since - * CORE_CLK > 66MHz, we also need to set AHB6DIV and FIUDIV as 1. - */ - NPCX_HFCGP = 0x01; -#endif - NPCX_HFCBCD = BIT(4); -} - -void clock_normal(void) -{ - /* Set CORE_CLK (CPU), AHB6_CLK and FIU_CLK back to original values. */ - NPCX_HFCGP = ((FPRED << 4) | AHB6DIV); - NPCX_HFCBCD = (FIUDIV << 4); -} - -void clock_enable_module(enum module_id module, int enable) -{ - /* Assume we have a single task using MODULE_FAST_CPU */ - if (module == MODULE_FAST_CPU) { - if (enable) - clock_turbo(); - else - clock_normal(); - } -} - -#endif - -/** - * Return the current clock frequency in Hz. - */ -int clock_get_freq(void) -{ - return CORE_CLK; -} - -/** - * Return the current FMUL clock frequency in Hz. - */ -int clock_get_fm_freq(void) -{ - return FMCLK; -} - -/** - * Return the current APB1 clock frequency in Hz. - */ -int clock_get_apb1_freq(void) -{ - return NPCX_APB_CLOCK(1); -} - -/** - * Return the current APB2 clock frequency in Hz. - */ -int clock_get_apb2_freq(void) -{ - return NPCX_APB_CLOCK(2); -} - -/** - * Return the current APB3 clock frequency in Hz. - */ -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 -int clock_get_apb3_freq(void) -{ - return NPCX_APB_CLOCK(3); -} -#endif - -/** - * Wait for a number of clock cycles. - * - * Simple busy waiting for use before clocks/timers are initialized. - * - * @param cycles Number of cycles to wait. - */ -void clock_wait_cycles(uint32_t cycles) -{ - asm volatile("1: subs %0, #1\n" - " bne 1b\n" : "+r"(cycles)); -} - -#ifdef CONFIG_LOW_POWER_IDLE -void clock_refresh_console_in_use(void) -{ - /* Set console in use expire time. */ - console_expire_time = get_time(); - console_expire_time.val += console_in_use_timeout_sec * SECOND; - return; -} - -#if defined(CHIP_FAMILY_NPCX5) -void clock_uart2gpio(void) -{ - /* Is pimux to UART? */ - if (npcx_is_uart()) { - /* Flush tx before enter deep idle */ - uart_tx_flush(); - /* Change pinmux to GPIO and disable UART IRQ */ - task_disable_irq(NPCX_IRQ_UART); - /* Set to GPIO */ - npcx_uart2gpio(); - /* Clear pending wakeup */ - uart_clear_pending_wakeup(); - /* Enable MIWU for GPIO (UARTRX) */ - uart_enable_wakeup(1); - } -} - -void clock_gpio2uart(void) -{ - /* Is Pending bit of GPIO (UARTRX) */ - if (uart_is_wakeup_from_gpio()) { - /* Refresh console in-use timer */ - clock_refresh_console_in_use(); - /* Disable MIWU for GPIO (UARTRX) */ - uart_enable_wakeup(0); - /* Go back CR_SIN */ - npcx_gpio2uart(); - /* Enable uart again */ - task_enable_irq(NPCX_IRQ_UART); - } -} -#endif - -/* Idle task. Executed when no tasks are ready to be scheduled. */ -void __idle(void) -{ - timestamp_t t0, t1; - uint32_t next_evt; - uint32_t next_evt_us; - uint16_t evt_count; - - /* - * Initialize console in use to true and specify the console expire - * time in order to give a fixed window on boot in which the low speed - * clock will not be used in idle. - */ - console_expire_time.val = get_time().val + CONSOLE_IN_USE_ON_BOOT_TIME; - - while (1) { - /* - * Disable interrupts before going to deep sleep in order to - * calculate the appropriate time to wake up. Note: the wfi - * instruction waits until an interrupt is pending, so it - * will still wake up even with interrupts disabled. - */ - interrupt_disable(); - - /* Compute event delay */ - t0 = get_time(); - next_evt = __hw_clock_event_get(); - - /* Do we have enough time before next event to deep sleep. */ - if (DEEP_SLEEP_ALLOWED && - /* - * Our HW timer doesn't tick in deep sleep - we do manual - * adjustment based on sleep duration after wake. Avoid - * the tricky overflow case by waiting out the period just - * before overflow. - */ - next_evt != EVT_MAX_EXPIRED_US && - /* Ensure event hasn't already expired */ - next_evt > t0.le.lo && - /* Ensure we have sufficient time before expiration */ - next_evt - t0.le.lo > WAKE_INTERVAL && - /* Make sure it's over console expired time */ - t0.val > console_expire_time.val) { -#if DEBUG_CLK - /* Use GPIO to indicate SLEEP mode */ - CLEAR_BIT(NPCX_PDOUT(0), 0); -#endif - idle_dsleep_cnt++; - - /* Enable Host access wakeup */ - SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6); - -#if defined(CHIP_FAMILY_NPCX5) - /* UART-rx(console) become to GPIO (NONE INT mode) */ - clock_uart2gpio(); -#elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - uartn_wui_en(CONFIG_CONSOLE_UART); -#endif - - /* - * Disable input buffer of all 1.8v i2c ports before - * entering deep sleep for better power consumption. - */ - gpio_enable_1p8v_i2c_wake_up_input(0); - - /* Set deep idle - instant wake-up mode */ - NPCX_PMCSR = IDLE_PARAMS; - - /* Get current counter value of event timer */ - evt_count = __hw_clock_event_count(); - - /* - * TODO (ML): We found the same symptom of idle occurs - * after wake-up from deep idle. Please see task.c for - * more detail. - * Workaround: Apply the same bypass of idle. - */ - asm ("push {r0-r5}\n" - "wfi\n" - "ldm %0, {r0-r5}\n" - "pop {r0-r5}\n" - "isb\n" :: "r" (0x100A8000) - ); - - /* Get time delay cause of deep idle */ - next_evt_us = __hw_clock_get_sleep_time(evt_count); - - /* - * Clear PMCSR manually in case there's wake-up between - * setting it and wfi. - */ - NPCX_PMCSR = 0; -#if defined(CHIP_FAMILY_NPCX5) - /* GPIO back to UART-rx (console) */ - clock_gpio2uart(); -#endif - - /* Enable input buffer of all 1.8v i2c ports. */ - gpio_enable_1p8v_i2c_wake_up_input(1); - - /* Record time spent in deep sleep. */ - idle_dsleep_time_us += next_evt_us; - - /* Fast forward timer according to wake-up timer. */ - t1.val = t0.val + next_evt_us; - /* Leave overflow situation for ITIM32 */ - if (t1.le.hi == t0.le.hi) - force_time(t1); - } else { -#if DEBUG_CLK - /* Use GPIO to indicate NORMAL mode */ - SET_BIT(NPCX_PDOUT(0), 0); -#endif - idle_sleep_cnt++; - - /* - * Using host access to make sure M4 core clock will - * return when the eSPI accesses the Host modules if - * CSAE bit is set. Please notice this symptom only - * occurs at npcx5. - */ -#if defined(CHIP_FAMILY_NPCX5) && defined(CONFIG_HOSTCMD_ESPI) - /* Enable Host access wakeup */ - SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6); -#endif - /* - * Normal idle : wait for interrupt - * TODO (ML): Workaround method for wfi issue. - * Please see task.c for more detail - */ - asm ("push {r0-r5}\n" - "wfi\n" - "ldm %0, {r0-r5}\n" - "pop {r0-r5}\n" - "isb\n" :: "r" (0x100A8000) - ); - } - - /* - * Restore interrupt - * RTOS will leave idle task to handle ISR which wakes up EC - */ - interrupt_enable(); - } -} -#endif /* CONFIG_LOW_POWER_IDLE */ - - -#ifdef CONFIG_LOW_POWER_IDLE -/** - * Print low power idle statistics - */ -static int command_idle_stats(int argc, char **argv) -{ - timestamp_t ts = get_time(); - - ccprintf("Num idle calls that sleep: %d\n", idle_sleep_cnt); - ccprintf("Num idle calls that deep-sleep: %d\n", idle_dsleep_cnt); - ccprintf("Time spent in deep-sleep: %.6llds\n", - idle_dsleep_time_us); - ccprintf("Total time on: %.6llds\n", ts.val); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats, - "", - "Print last idle stats"); - -/** - * Configure deep sleep clock settings. - */ -static int command_dsleep(int argc, char **argv) -{ - int v; - - if (argc > 1) { - if (parse_bool(argv[1], &v)) { - /* - * Force deep sleep not to use low speed clock or - * allow it to use the low speed clock. - */ - if (v) - disable_sleep(SLEEP_MASK_FORCE_NO_LOW_SPEED); - else - enable_sleep(SLEEP_MASK_FORCE_NO_LOW_SPEED); - } else { - /* Set console in use timeout. */ - char *e; - v = strtoi(argv[1], &e, 10); - if (*e) - return EC_ERROR_PARAM1; - - console_in_use_timeout_sec = v; - - /* Refresh console in use to use new timeout. */ - clock_refresh_console_in_use(); - } - } - - ccprintf("Sleep mask: %08x\n", sleep_mask); - ccprintf("Console in use timeout: %d sec\n", - console_in_use_timeout_sec); - ccprintf("PMCSR register: 0x%02x\n", NPCX_PMCSR); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(dsleep, command_dsleep, - "[ on | off | <timeout> sec]", - "Deep sleep clock settings:\nUse 'on' to force deep " - "sleep not to use low speed clock.\nUse 'off' to " - "allow deep sleep to auto-select using the low speed " - "clock.\n" - "Give a timeout value for the console in use timeout.\n" - "See also 'sleepmask'."); -#endif /* CONFIG_LOW_POWER_IDLE */ diff --git a/chip/npcx/clock_chip.h b/chip/npcx/clock_chip.h deleted file mode 100644 index 702b55c52a..0000000000 --- a/chip/npcx/clock_chip.h +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright 2014 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-specific clock module for Chrome EC */ - -#ifndef __CROS_EC_CLOCK_CHIP_H -#define __CROS_EC_CLOCK_CHIP_H - -/* - * EC clock tree plan: (Default OSC_CLK is 40MHz.) - * - * Target OSC_CLK for NPCX7 is 90MHz, FMCLK is 45MHz, CPU and APBs is 15MHz. - * Target OSC_CLK for NPCX5 is 30MHz, FMCLK is 30MHz, CPU and APBs is 15MHz. - */ -#if defined(CHIP_FAMILY_NPCX5) -/* - * NPCX5 clock tree: (Please refer Figure 55. for more information.) - * - * Suggestion: - * - OSC_CLK >= 30MHz, FPRED should be 1, else 0. - * (Keep FMCLK in 30-50 MHz possibly which is tested strictly.) - */ -/* Target OSC_CLK freq */ -#define OSC_CLK 30000000 -/* Core clock prescaler */ -#if (OSC_CLK >= 30000000) -#define FPRED 1 /* CORE_CLK = OSC_CLK(FMCLK)/2 */ -#else -#define FPRED 0 /* CORE_CLK = OSC_CLK(FMCLK) */ -#endif -/* Core domain clock */ -#define CORE_CLK (OSC_CLK / (FPRED + 1)) -/* FMUL clock */ -#define FMCLK OSC_CLK -/* APBs source clock */ -#define APBSRC_CLK CORE_CLK -/* APB1 clock divider */ -#define APB1DIV 3 /* Default APB1 clock = CORE_CLK/4 */ -/* APB2 clock divider */ -#define APB2DIV 0 /* Let APB2 = CORE_CLK since UART baudrate tolerance */ -#elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 -/* - * NPCX7 clock tree: (Please refer Figure 58. for more information.) - * - * Suggestion: - * - OSC_CLK >= 80MHz, XF_RANGE should be 1, else 0. - * - CORE_CLK > 66MHz, AHB6DIV should be 1, else 0. - * - CORE_CLK > 50MHz, FIUDIV should be 1, else 0. - */ -/* Target OSC_CLK freq */ -#define OSC_CLK 90000000 -/* Core clock prescaler */ -#define FPRED 5 /* CORE_CLK = OSC_CLK/6 */ -/* Core domain clock */ -#define CORE_CLK (OSC_CLK / (FPRED + 1)) -/* FMUL clock */ -#if (OSC_CLK >= 80000000) -#define FMCLK (OSC_CLK / 2) /* FMUL clock = OSC_CLK/2 if OSC_CLK >= 80MHz */ -#else -#define FMCLK OSC_CLK /* FMUL clock = OSC_CLK */ -#endif -/* AHB6 clock */ -#if (CORE_CLK > 66000000) -#define AHB6DIV 1 /* AHB6_CLK = CORE_CLK/2 if CORE_CLK > 66MHz */ -#else -#define AHB6DIV 0 /* AHB6_CLK = CORE_CLK */ -#endif -/* FIU clock divider */ -#if (CORE_CLK > 50000000) -#define FIUDIV 1 /* FIU_CLK = CORE_CLK/2 */ -#else -#define FIUDIV 0 /* FIU_CLK = CORE_CLK */ -#endif -/* APBs source clock */ -#define APBSRC_CLK OSC_CLK -/* APB1 clock divider */ -#define APB1DIV 5 /* APB1 clock = OSC_CLK/6 */ -/* APB2 clock divider */ -#define APB2DIV 5 /* APB2 clock = OSC_CLK/6 */ -/* APB3 clock divider */ -#define APB3DIV 5 /* APB3 clock = OSC_CLK/6 */ -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 -/* APB4 clock divider */ -#define APB4DIV 5 /* APB4 clock = OSC_CLK/6 */ -#endif -#endif - -/* Get APB clock freq */ -#define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV + 1)) - -/* - * Frequency multiplier M/N value definitions according to the requested - * OSC_CLK (Unit:Hz). - */ -#if (OSC_CLK > 80000000) -#define HFCGN 0x82 /* Set XF_RANGE as 1 if OSC_CLK >= 80MHz */ -#else -#define HFCGN 0x02 -#endif -#if (OSC_CLK == 100000000) -#define HFCGMH 0x0B -#define HFCGML 0xEC -#elif (OSC_CLK == 90000000) -#define HFCGMH 0x0A -#define HFCGML 0xBA -#elif (OSC_CLK == 80000000) -#define HFCGMH 0x09 -#define HFCGML 0x89 -#elif (OSC_CLK == 66000000) -#define HFCGMH 0x0F -#define HFCGML 0xBC -#elif (OSC_CLK == 50000000) -#define HFCGMH 0x0B -#define HFCGML 0xEC -#elif (OSC_CLK == 48000000) -#define HFCGMH 0x0B -#define HFCGML 0x72 -#elif (OSC_CLK == 40000000) -#define HFCGMH 0x09 -#define HFCGML 0x89 -#elif (OSC_CLK == 33000000) -#define HFCGMH 0x07 -#define HFCGML 0xDE -#elif (OSC_CLK == 30000000) -#define HFCGMH 0x07 -#define HFCGML 0x27 -#elif (OSC_CLK == 26000000) -#define HFCGMH 0x06 -#define HFCGML 0x33 -#else -#error "Unsupported OSC_CLK Frequency" -#endif - -#if defined(CHIP_FAMILY_NPCX5) -#if (OSC_CLK > 50000000) -#error "Unsupported OSC_CLK on NPCX5 series!" -#endif -#elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 -#if (OSC_CLK > 100000000) -#error "Unsupported OSC_CLK on NPCX series!" -#endif -#endif - -/** - * Return the current FMUL clock frequency in Hz. - */ -int clock_get_fm_freq(void); - -/** - * Return the current APB1 clock frequency in Hz. - */ -int clock_get_apb1_freq(void); - -/** - * Return the current APB2 clock frequency in Hz. - */ -int clock_get_apb2_freq(void); - -/** - * Return the current APB3 clock frequency in Hz. - */ -int clock_get_apb3_freq(void); - -/** - * Set the CPU clock to maximum freq for better performance. - */ -void clock_turbo(void); - -/** - * Set the CPU clock back to normal freq. - */ -void clock_turbo_disable(void); - -#endif /* __CROS_EC_CLOCK_CHIP_H */ diff --git a/chip/npcx/config_chip-npcx5.h b/chip/npcx/config_chip-npcx5.h deleted file mode 100644 index 434caba1d8..0000000000 --- a/chip/npcx/config_chip-npcx5.h +++ /dev/null @@ -1,82 +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. - */ -#ifndef __CROS_EC_CONFIG_CHIP_NPCX5_H -#define __CROS_EC_CONFIG_CHIP_NPCX5_H - -/* - * NPCX5 Series Device-Specific Information - * Ex. NPCX5(M)(N)(G) - * @param M: 7: 132-pins package, 8: 128-pins package - * @param N: 5: 128KB RAM Size, 6: 256KB RAM Size - * @param G: Google EC. - */ - -/* Chip ID for all variants */ -#define NPCX585G_CHIP_ID 0x12 -#define NPCX575G_CHIP_ID 0x13 -#define NPCX586G_CHIP_ID 0x16 -#define NPCX576G_CHIP_ID 0x17 - -/*****************************************************************************/ -/* Hardware features */ - -/* Number of UART modules. */ -#define UART_MODULE_COUNT 1 - -/* - * For NPCX5, PS2_3 pins also support other alternate functions (e.g., TA2). - * PS2_3 should be Explicit defined. - */ -#undef NPCX_PS2_MODULE_3 - -/* - * Number of I2C controllers. Controller 0 has 2 ports, so the chip has one - * additional port. - */ -#define CONFIG_I2C_MULTI_PORT_CONTROLLER -/* Number of I2C controllers */ -#define I2C_CONTROLLER_COUNT 4 -/* Number of I2C ports */ -#define I2C_PORT_COUNT 5 - -/*****************************************************************************/ -/* Memory mapping */ -#define NPCX_BTRAM_SIZE 0x800 /* 2KB data ram used by booter. */ -#define CONFIG_RAM_BASE 0x200C0000 /* memory address of data ram */ -#define CONFIG_DATA_RAM_SIZE 0x00008000 /* Size of data RAM */ -#define CONFIG_RAM_SIZE (CONFIG_DATA_RAM_SIZE - NPCX_BTRAM_SIZE) -#define CONFIG_LPRAM_BASE 0x40001600 /* memory address of lpwr ram */ -#define CONFIG_LPRAM_SIZE 0x00000620 /* 1568B low power ram */ - -/* Use chip variant to specify the size and start address of program memory */ -#if defined(CHIP_VARIANT_NPCX5M5G) -/* 96KB RAM for FW code */ -#define NPCX_PROGRAM_MEMORY_SIZE (96 * 1024) -/* program memory base address for 96KB Code RAM (ie. 0x100C0000 - 96KB) */ -#define CONFIG_PROGRAM_MEMORY_BASE 0x100A8000 -#elif defined(CHIP_VARIANT_NPCX5M6G) -/* 224KB RAM for FW code */ -#define NPCX_PROGRAM_MEMORY_SIZE (224 * 1024) -/* program memory base address for 224KB Code RAM (ie. 0x100C0000 - 224KB) */ -#define CONFIG_PROGRAM_MEMORY_BASE 0x10088000 -#else -#error "Unsupported chip variant" -#endif - -/* Total RAM size checking for npcx ec */ -#define NPCX_RAM_SIZE (CONFIG_DATA_RAM_SIZE + NPCX_PROGRAM_MEMORY_SIZE) -#if defined(CHIP_VARIANT_NPCX5M5G) -/* 128KB RAM in NPCX5M5G */ -#if (NPCX_RAM_SIZE != 0x20000) -#error "Wrong memory mapping layout for NPCX5M5G" -#endif -#elif defined(CHIP_VARIANT_NPCX5M6G) -/* 256KB RAM in NPCX5M6G */ -#if (NPCX_RAM_SIZE != 0x40000) -#error "Wrong memory mapping layout for NPCX5M6G" -#endif -#endif - -#endif /* __CROS_EC_CONFIG_CHIP_NPCX5_H */ diff --git a/chip/npcx/config_chip-npcx7.h b/chip/npcx/config_chip-npcx7.h deleted file mode 100644 index 434c3a7889..0000000000 --- a/chip/npcx/config_chip-npcx7.h +++ /dev/null @@ -1,148 +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. - */ - -#ifndef __CROS_EC_CONFIG_CHIP_NPCX7_H -#define __CROS_EC_CONFIG_CHIP_NPCX7_H - -/* - * NPCX7 Series Device-Specific Information - * Ex. NPCX7(M)(N)(G/K/F)(B/C) - * @param M: 8: 128-pins package, 9: 144-pins package - * @param N: 5: 128KB RAM Size, 6: 256KB RAM Size, 7: 384KB RAM Size - * @param G/K/F/W: Google EC depends on specific features. - * @param B/C: (Optional) Chip generation in the same series. - */ - -/* Chip ID for all variants */ -#define NPCX787G_CHIP_ID 0x1F -#define NPCX796F_A_B_CHIP_ID 0x21 -#define NPCX796F_C_CHIP_ID 0x29 -#define NPCX797F_C_CHIP_ID 0x20 -#define NPCX797W_B_CHIP_ID 0x24 -#define NPCX797W_C_CHIP_ID 0x2C - -/*****************************************************************************/ -/* Hardware features */ - -/* The optional hardware features depend on chip variant */ -#if defined(CHIP_VARIANT_NPCX7M6F) || defined(CHIP_VARIANT_NPCX7M6FB) || \ - defined(CHIP_VARIANT_NPCX7M6FC) || defined(CHIP_VARIANT_NPCX7M7FC) || \ - defined(CHIP_VARIANT_NPCX7M7WB) || defined(CHIP_VARIANT_NPCX7M7WC) -#define NPCX_INT_FLASH_SUPPORT /* Internal flash support */ -#define NPCX_PSL_MODE_SUPPORT /* Power switch logic mode for ultra-low power */ -#define NPCX_EXT32K_OSC_SUPPORT /* External 32KHz crytal osc. input support */ -#endif - -#if defined(CHIP_VARIANT_NPCX7M6FB) || defined(CHIP_VARIANT_NPCX7M6FC) || \ - defined(CHIP_VARIANT_NPCX7M7FC) || defined(CHIP_VARIANT_NPCX7M7WB) || \ - defined(CHIP_VARIANT_NPCX7M7WC) -#define NPCX_UART_FIFO_SUPPORT -/* Number of UART modules. */ -#define NPCX_SECOND_UART -#define UART_MODULE_COUNT 2 - -/* - * For NPCX7, PS2_2 & PS2_3 pins also support other alternate functions - * (e.g., ADC5, ADC6, TA2). PS2_2 & PS2_3 should be Explicit defined. - */ -#undef NPCX_PS2_MODULE_2 -#undef NPCX_PS2_MODULE_3 - -/* 64-bit timer support */ -#define NPCX_ITIM64_SUPPORT -#else -#define UART_MODULE_COUNT 1 -#endif - -#if defined(CHIP_VARIANT_NPCX7M7WB) || defined(CHIP_VARIANT_NPCX7M7WC) -#define NPCX_WOV_SUPPORT /* Audio front-end for Wake-on-Voice support */ -#endif - -/* - * Number of I2C controllers. Controller 4/5/6 has 2 ports, so the chip has - * three additional ports. - */ -#define CONFIG_I2C_MULTI_PORT_CONTROLLER -/* Number of I2C controllers */ -#define I2C_CONTROLLER_COUNT 8 -/* Number of I2C ports */ -#ifdef NPCX_PSL_MODE_SUPPORT -#define I2C_PORT_COUNT 10 -#else -#define I2C_PORT_COUNT 11 -#endif - -#define NPCX_I2C_FIFO_SUPPORT - -/* Use SHI module version 2 supported by npcx7 family */ -#define NPCX_SHI_V2 - -/*****************************************************************************/ -/* Memory mapping */ -#define NPCX_BTRAM_SIZE 0x800 /* 2KB data ram used by booter. */ - -#define NPCX_RAM_SIZE (CONFIG_DATA_RAM_SIZE + NPCX_PROGRAM_MEMORY_SIZE) - -#if defined(CHIP_VARIANT_NPCX7M6F) || defined(CHIP_VARIANT_NPCX7M6FB) || \ - defined(CHIP_VARIANT_NPCX7M6FC) || defined(CHIP_VARIANT_NPCX7M6G) - /* 192KB RAM for FW code */ -# define NPCX_PROGRAM_MEMORY_SIZE (192 * 1024) - /* program memory base address for Code RAM (0x100C0000 - 192KB) */ -# define CONFIG_PROGRAM_MEMORY_BASE 0x10090000 -# define CONFIG_RAM_BASE 0x200C0000 /* memory address of data ram */ - /* 62 KB data RAM + 2 KB BT RAM size */ -# define CONFIG_DATA_RAM_SIZE 0x00010000 -#elif defined(CHIP_VARIANT_NPCX7M7WB) - /* 256KB RAM for FW code */ -# define NPCX_PROGRAM_MEMORY_SIZE (256 * 1024) - /* program memory base address for Code RAM (0x100B0000 - 256KB) */ -# define CONFIG_PROGRAM_MEMORY_BASE 0x10070000 -# define CONFIG_RAM_BASE 0x200B0000 /* memory address of data ram */ - /* 126 KB data RAM + 2 KB BT RAM size */ -# define CONFIG_DATA_RAM_SIZE 0x00020000 -#elif defined(CHIP_VARIANT_NPCX7M7FC) || defined(CHIP_VARIANT_NPCX7M7WC) - /* - * Code RAM is normally assumed to be same as image size, but since - * we exclude 4k from the image (see NPCX_PROGRAM_MEMORY_SIZE) we - * need to explicitly configure it. This is the actual size of code - * RAM on-chip. - */ -# define CONFIG_CODE_RAM_SIZE (256 * 1024) - /* - * In npcx797wc and npcx797fc, the code RAM size is limited by the - * internal flash size (i.e. 512 KB/2=256 KB.) The driver has to - * re-organize the memory to: - * 1. the overall memory (RAM) layout is re-organized against the - * datasheet: - * In datasheet: 320 KB code RAM + 64 KB data RAM - * After re-organization: 256 KB code RAM + 128 KB data RAM. - * 2. 256KB program RAM, but only 512K of Flash (vs 1M for the - * -WB). After the boot header is added, a 256K image would be - * too large to fit in either RO or RW sections of Flash (each - * of which is half of it). Because other code assumes that - * image size is a multiple of Flash erase granularity, we - * sacrifice a whole sector. - */ -# define NPCX_PROGRAM_MEMORY_SIZE (CONFIG_CODE_RAM_SIZE - 0x1000) - /* program memory base address for Code RAM (0x100B0000 - 256KB) */ -# define CONFIG_PROGRAM_MEMORY_BASE 0x10070000 -# define CONFIG_RAM_BASE 0x200B0000 /* memory address of data ram */ - /* 126 KB data RAM + 2 KB BT RAM size */ -# define CONFIG_DATA_RAM_SIZE 0x00020000 - - /* - * Override default NPCX_RAM_SIZE because NPCX_PROGRAM_MEMORY_SIZE - * is not the actual size of code RAM. - */ -# undef NPCX_RAM_SIZE -# define NPCX_RAM_SIZE (CONFIG_DATA_RAM_SIZE + CONFIG_CODE_RAM_SIZE) -#else -# error "Unsupported chip variant" -#endif - -#define CONFIG_RAM_SIZE (CONFIG_DATA_RAM_SIZE - NPCX_BTRAM_SIZE) -/* no low power ram in npcx7 series */ - -#endif /* __CROS_EC_CONFIG_CHIP_NPCX7_H */ diff --git a/chip/npcx/config_chip-npcx9.h b/chip/npcx/config_chip-npcx9.h deleted file mode 100644 index 0248c40f86..0000000000 --- a/chip/npcx/config_chip-npcx9.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright 2020 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_CONFIG_CHIP_NPCX9_H -#define __CROS_EC_CONFIG_CHIP_NPCX9_H - -/* - * NPCX9 Series Device-Specific Information - * Ex. NPCX9(M)(N)(G/K/F)(B/C) - * @param M: 9: 144-pins package - * @param N: 3: 320KB RAM Size, 6: 256KB RAM Size. - * @param F: Google EC. - * @param B/C: (Optional) Chip generation in the same series. - */ - -/* Chip ID for all variants */ -#define NPCX996F_CHIP_ID 0x21 -#define NPCX993F_CHIP_ID 0x25 - -/*****************************************************************************/ -/* Hardware features */ - -#define NPCX_EXT32K_OSC_SUPPORT /* External 32KHz crytal osc. input support */ -#define NPCX_INT_FLASH_SUPPORT /* Internal flash support */ -#define NPCX_LCT_SUPPORT /* Long Countdown Timer support */ -#define NPCX_PSL_MODE_SUPPORT /* Power switch logic mode for ultra-low power */ - -#define NPCX_UART_FIFO_SUPPORT -/* Number of UART modules. */ -#define NPCX_SECOND_UART -#define UART_MODULE_COUNT 2 - -/* - * For NPCX9, PS2_2 & PS2_3 pins also support other alternate functions - * (e.g., ADC5, ADC6, TA2). PS2_2 & PS2_3 should be Explicit defined. - */ -#undef NPCX_PS2_MODULE_2 -#undef NPCX_PS2_MODULE_3 - -/* - * Number of I2C controllers. Controller 5/6 has 2 ports, so the chip has - * two additional ports. - */ -#define CONFIG_I2C_MULTI_PORT_CONTROLLER -/* Number of I2C controllers */ -#define I2C_CONTROLLER_COUNT 8 -#define I2C_PORT_COUNT 10 - -#define NPCX_I2C_FIFO_SUPPORT - -/* Use SHI module version 2 supported by npcx7 and latter family */ -#define NPCX_SHI_V2 - -/* PSL_OUT optional configuration */ -/* Set PSL_OUT mode to pulse mode */ -#define NPCX_PSL_CFG_PSL_OUT_PULSE BIT(0) -/* set PSL_OUT to open-drain */ -#define NPCX_PSL_CFG_PSL_OUT_OD BIT(1) -#define CONFIG_HIBERNATE_PSL_OUT_FLAGS 0 - - -#define CONFIG_WORKAROUND_FLASH_DOWNLOAD_API -/*****************************************************************************/ -/* Memory mapping */ -#ifdef CONFIG_WORKAROUND_FLASH_DOWNLOAD_API -#define CONFIG_LPRAM_BASE 0x40001400 /* memory address of lpwr ram */ -#define CONFIG_LPRAM_SIZE 0x00000620 /* 1568B low power ram */ -#endif - -#define NPCX_RAM_SIZE (CONFIG_DATA_RAM_SIZE + NPCX_PROGRAM_MEMORY_SIZE) - -#if defined(CHIP_VARIANT_NPCX9M3F) - /* - * 256KB program RAM, but only 512K of Flash. After the boot header is - * added, a 256K image would be too large to fit in either RO or RW - * sections of Flash (each of which is half of it). Because other code - * assumes that image size is a multiple of Flash erase granularity, we - * sacrifice a whole sector. - */ -# define NPCX_PROGRAM_MEMORY_SIZE (256 * 1024 - 0x1000) - /* program memory base address for Code RAM (0x100C0000 - 256KB) */ -# define CONFIG_PROGRAM_MEMORY_BASE 0x10080000 -# define CONFIG_RAM_BASE 0x200C0000 /* memory address of data ram */ - /* Two blocks of data RAM - total size is 64KB */ -# define CONFIG_DATA_RAM_SIZE 0x00010000 -# define CONFIG_RAM_SIZE CONFIG_DATA_RAM_SIZE - - /* Override default NPCX_RAM_SIZE because we're excluding a block. */ -# undef NPCX_RAM_SIZE -# define NPCX_RAM_SIZE (CONFIG_DATA_RAM_SIZE + \ - NPCX_PROGRAM_MEMORY_SIZE + 0x1000) -#elif defined(CHIP_VARIANT_NPCX9M6F) - /* 192KB RAM for FW code */ -# define NPCX_PROGRAM_MEMORY_SIZE (192 * 1024) - /* program memory base address for Code RAM (0x100C0000 - 192KB) */ -# define CONFIG_PROGRAM_MEMORY_BASE 0x10090000 -# define CONFIG_RAM_BASE 0x200C0000 /* memory address of data ram */ - /* Two blocks of data RAM - total size is 64KB */ -# define CONFIG_DATA_RAM_SIZE 0x00010000 -# define CONFIG_RAM_SIZE CONFIG_DATA_RAM_SIZE -#else -# error "Unsupported chip variant" -#endif - -/* Internal spi-flash setting */ -#define CONFIG_SPI_FLASH_REGS -#define CONFIG_SPI_FLASH_W25Q40 /* Internal spi flash type */ -#define CONFIG_FLASH_SIZE_BYTES 0x00080000 /* 512 KB internal spi flash */ - - -#endif /* __CROS_EC_CONFIG_CHIP_NPCX9_H */ diff --git a/chip/npcx/config_chip.h b/chip/npcx/config_chip.h deleted file mode 100644 index cee339206c..0000000000 --- a/chip/npcx/config_chip.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright 2014 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_CONFIG_CHIP_H -#define __CROS_EC_CONFIG_CHIP_H - -/* CPU core BFD configuration */ -#include "core/cortex-m/config_core.h" - -/* - * Set the chip family version to 4 digits to keep the flexibility in case - * we need the minor version for chip variants in a family. - */ -#define NPCX_FAMILY_NPCX5 5000 -#define NPCX_FAMILY_NPCX7 7000 -#define NPCX_FAMILY_NPCX9 9000 - -/* Features depend on chip family */ -#if defined(CHIP_FAMILY_NPCX5) -#include "config_chip-npcx5.h" -#define NPCX_FAMILY_VERSION NPCX_FAMILY_NPCX5 -#elif defined(CHIP_FAMILY_NPCX7) -#include "config_chip-npcx7.h" -#define NPCX_FAMILY_VERSION NPCX_FAMILY_NPCX7 -#elif defined(CHIP_FAMILY_NPCX9) -#include "config_chip-npcx9.h" -#define NPCX_FAMILY_VERSION NPCX_FAMILY_NPCX9 -#else -#error "Unsupported chip family" -#endif - -/* 32k hz internal oscillator frequency (FRCLK) */ -#define INT_32K_CLOCK 32768 - -/* Number of IRQ vectors on the NVIC */ -#define CONFIG_IRQ_COUNT 64 - -/* Use a bigger console output buffer */ -#undef CONFIG_UART_TX_BUF_SIZE -#define CONFIG_UART_TX_BUF_SIZE 1024 - -/* - * Interval between HOOK_TICK notifications - * Notice instant wake-up from deep-idle cannot exceed 200 ms - */ -#define HOOK_TICK_INTERVAL_MS 200 -#define HOOK_TICK_INTERVAL (HOOK_TICK_INTERVAL_MS * MSEC) - -/* System stack size */ -#define CONFIG_STACK_SIZE 1024 - -/* non-standard task stack sizes */ -#define IDLE_TASK_STACK_SIZE 672 -#define LARGER_TASK_STACK_SIZE 800 -#define VENTI_TASK_STACK_SIZE 928 -#define ULTRA_TASK_STACK_SIZE 1056 -#define TRENTA_TASK_STACK_SIZE 1184 - -#define CHARGER_TASK_STACK_SIZE 800 -#define HOOKS_TASK_STACK_SIZE 800 -#define CONSOLE_TASK_STACK_SIZE 800 - -/* Default task stack size */ -#define TASK_STACK_SIZE 672 - -/* Address of RAM log used by Booter */ -#define ADDR_BOOT_RAMLOG 0x100C7FC0 - -#include "config_flash_layout.h" - -/* Optional features present on this chip */ -#define CONFIG_ADC -#define CONFIG_RTC -#define CONFIG_SWITCH -#define CONFIG_MPU - -/* Chip needs to do custom pre-init */ -#define CONFIG_CHIP_PRE_INIT -/* Default use UART1 as console */ -#define CONFIG_CONSOLE_UART 0 - -#define GPIO_PIN(port, index) GPIO_##port, BIT(index) -#define GPIO_PIN_MASK(p, m) .port = GPIO_##p, .mask = (m) - -#endif /* __CROS_EC_CONFIG_CHIP_H */ diff --git a/chip/npcx/config_flash_layout.h b/chip/npcx/config_flash_layout.h deleted file mode 100644 index 79961548c9..0000000000 --- a/chip/npcx/config_flash_layout.h +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2015 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_CONFIG_FLASH_LAYOUT_H -#define __CROS_EC_CONFIG_FLASH_LAYOUT_H - -/* - * npcx flash layout: - * - Memory-mapped external SPI. - * - Image header at the beginning of protected region, followed by RO image. - * - RW image starts at the second half of flash. - */ - -/* Memmapped, external SPI */ -#define CONFIG_EXTERNAL_STORAGE -#define CONFIG_MAPPED_STORAGE -/* Storage is memory-mapped, but program runs from SRAM */ -#define CONFIG_MAPPED_STORAGE_BASE 0x64000000 -#undef CONFIG_FLASH_PSTATE - -#if defined(CHIP_VARIANT_NPCX5M5G) -#define CONFIG_EC_PROTECTED_STORAGE_OFF 0 -#define CONFIG_EC_PROTECTED_STORAGE_SIZE 0x20000 -#define CONFIG_EC_WRITABLE_STORAGE_OFF 0x20000 -#define CONFIG_EC_WRITABLE_STORAGE_SIZE 0x20000 -#elif defined(CHIP_VARIANT_NPCX5M6G) -#define CONFIG_EC_PROTECTED_STORAGE_OFF 0 -#define CONFIG_EC_PROTECTED_STORAGE_SIZE 0x40000 -#define CONFIG_EC_WRITABLE_STORAGE_OFF 0x40000 -#define CONFIG_EC_WRITABLE_STORAGE_SIZE 0x40000 -#elif defined(CHIP_VARIANT_NPCX7M6F) || defined(CHIP_VARIANT_NPCX7M6FB) || \ - defined(CHIP_VARIANT_NPCX7M6FC) || defined(CHIP_VARIANT_NPCX7M6G) || \ - defined(CHIP_VARIANT_NPCX7M7FC) || defined(CHIP_VARIANT_NPCX7M7WC) -#define CONFIG_EC_PROTECTED_STORAGE_OFF 0 -#define CONFIG_EC_PROTECTED_STORAGE_SIZE 0x40000 -#define CONFIG_EC_WRITABLE_STORAGE_OFF 0x40000 -#define CONFIG_EC_WRITABLE_STORAGE_SIZE 0x40000 -#elif defined(CHIP_VARIANT_NPCX7M7WB) -#define CONFIG_EC_PROTECTED_STORAGE_OFF 0 -#define CONFIG_EC_PROTECTED_STORAGE_SIZE 0x80000 -#define CONFIG_EC_WRITABLE_STORAGE_OFF 0x80000 -#define CONFIG_EC_WRITABLE_STORAGE_SIZE 0x80000 -#elif defined(CHIP_VARIANT_NPCX9M3F) || defined(CHIP_VARIANT_NPCX9M6F) -#define CONFIG_EC_PROTECTED_STORAGE_OFF 0 -#define CONFIG_EC_PROTECTED_STORAGE_SIZE 0x40000 -#define CONFIG_EC_WRITABLE_STORAGE_OFF 0x40000 -#define CONFIG_EC_WRITABLE_STORAGE_SIZE 0x40000 -#else -#error "Unsupported chip variant" -#endif - -/* Header support which is used by booter to copy FW from flash to code ram */ -#define NPCX_RO_HEADER -#define CONFIG_RO_HDR_MEM_OFF 0x0 -#define CONFIG_RO_HDR_SIZE 0x40 - -#define CONFIG_WP_STORAGE_OFF CONFIG_EC_PROTECTED_STORAGE_OFF -#define CONFIG_WP_STORAGE_SIZE CONFIG_EC_PROTECTED_STORAGE_SIZE - -/* RO firmware in program memory - use all of program memory */ -#define CONFIG_RO_MEM_OFF 0 -#define CONFIG_RO_SIZE NPCX_PROGRAM_MEMORY_SIZE - -/* - * ROM resident area in flash used to store data objects that are not copied - * into code RAM. Enable using the CONFIG_CHIP_INIT_ROM_REGION option. - */ -#define CONFIG_RO_ROM_RESIDENT_MEM_OFF CONFIG_RO_SIZE -#define CONFIG_RO_ROM_RESIDENT_SIZE \ - (CONFIG_EC_PROTECTED_STORAGE_SIZE - CONFIG_RO_SIZE) - -/* - * RW firmware in program memory - Identical to RO, only one image loaded at - * a time. - */ -#define CONFIG_RW_MEM_OFF CONFIG_RO_MEM_OFF -#define CONFIG_RW_SIZE CONFIG_RO_SIZE - -#define CONFIG_RW_ROM_RESIDENT_MEM_OFF CONFIG_RW_SIZE -#define CONFIG_RW_ROM_RESIDENT_SIZE \ - (CONFIG_EC_WRITABLE_STORAGE_SIZE - CONFIG_RW_SIZE) - -#if (CONFIG_RO_SIZE != CONFIG_RW_SIZE) -#error "Unsupported.. FLASH_ERASE_SIZE assumes RO and RW size is same!" -#endif - -#if (CONFIG_RO_MEM_OFF != 0) -#error "Unsupported.. CONFIG_RO_MEM_OFF is assumed to be 0!" -#endif - -/* - * The common flash support requires that the CONFIG_WP_STORAGE_SIZE and - * CONFIG_EC_WRITABLE_STORAGE_SIZE are both a multiple of - * CONFIG_FLASH_ERASE_SIZE. - * - * THE NPCX supports erase sizes of 64 KiB, 32 KiB, and 4 KiB. The NPCX flash - * driver does not currently support CONFIG_FLASH_MULTIPLE_REGION, so set - * the erase size to the maximum (64 KiB) for the best performance. - * Using smaller erase sizes increases boot time. If write protected and - * writable flash regions are not a multiple of 64 KiB, then support - * for CONFIG_FLASH_MULTIPLE_REGION must be added. - */ -#define CONFIG_FLASH_ERASE_SIZE 0x10000 -#define NPCX_ERASE_COMMAND CMD_BLOCK_64K_ERASE - -#if (CONFIG_WP_STORAGE_SIZE != CONFIG_EC_WRITABLE_STORAGE_SIZE) -#error "NPCX flash support assumes CONFIG_WP_STORAGE_SIZE and " \ - "CONFIG_EC_WRITABLE_STORAGE_SIZE are the same." -#endif - -/* - * If the total flash size is not a multiple of 64k, this slows the boot - * time. CONFIG_FLASH_MULTIPLE_REGION should be enabled in this case to - * optimize the erase block handling. - */ -#if ((CONFIG_WP_STORAGE_SIZE % CONFIG_FLASH_ERASE_SIZE) != 0) -#error "CONFIG_WP_STORAGE_SIZE is not a multiple of 64K. Correct the flash " \ - "size or add support for CONFIG_FLASH_MULTIPLE_REGION." -#endif - -#define CONFIG_FLASH_BANK_SIZE CONFIG_FLASH_ERASE_SIZE -#define CONFIG_FLASH_WRITE_SIZE 0x1 /* minimum write size */ -#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 /* one page size for write */ - -/* Use 4k sector erase for NPCX monitor flash erase operations. */ -#define NPCX_MONITOR_FLASH_ERASE_SIZE 0x1000 - -/* RO image resides at start of protected region, right after header */ -#define CONFIG_RO_STORAGE_OFF CONFIG_RO_HDR_SIZE -/* RW image resides at start of writable region */ -#define CONFIG_RW_STORAGE_OFF 0 - -#endif /* __CROS_EC_CONFIG_FLASH_LAYOUT_H */ diff --git a/chip/npcx/espi.c b/chip/npcx/espi.c deleted file mode 100644 index c8976afed0..0000000000 --- a/chip/npcx/espi.c +++ /dev/null @@ -1,704 +0,0 @@ -/* Copyright 2016 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. - */ - -/* ESPI module for Chrome EC */ - -#include "registers.h" -#include "system.h" -#include "task.h" -#include "chipset.h" -#include "console.h" -#include "uart.h" -#include "util.h" -#include "power.h" -#include "espi.h" -#include "lpc_chip.h" -#include "hooks.h" -#include "timer.h" - -/* Console output macros */ -#if !(DEBUG_ESPI) -#define CPUTS(...) -#define CPRINTS(...) -#else -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) -#endif - -/* Default eSPI configuration for VW events */ -struct vwevms_config_t { - uint8_t idx; /* VW index */ - uint8_t idx_en; /* Index enable */ - uint8_t pltrst_en; /* Enable reset by PLTRST assert */ - uint8_t espirst_en; /* Enable reset by eSPI_RST assert */ - uint8_t int_en; /* Interrupt/Wake-up enable */ -}; - -struct vwevsm_config_t { - uint8_t idx; /* VW index */ - uint8_t idx_en; /* Index enable */ - uint8_t pltrst_en; /* Enable reset by PLTRST assert */ - uint8_t cdrst_en; /* Enable cold reset */ - uint8_t valid; /* Valid VW mask */ -}; - -/* Default MIWU configurations for VW events */ -struct host_wui_item { - uint16_t table : 2; /* MIWU table 0-2 */ - uint16_t group : 3; /* MIWU group 0-7 */ - uint16_t num : 3; /* MIWU bit 0-7 */ - uint16_t edge : 4; /* MIWU edge trigger type rising/falling/any */ -}; - -/* Mapping item between VW signal, index and value */ -struct vw_event_t { - uint16_t name; /* Name of signal */ - uint8_t evt_idx; /* VW index of signal */ - uint8_t evt_val; /* VW value of signal */ -}; - -/* Default settings of VWEVMS registers (Please refer Table.43/44) */ -static const struct vwevms_config_t espi_in_list[] = { - /* IDX EN ENPL ENESP IE/WE VW Event Bit 0 - 3 (M->S) */ -#ifdef CONFIG_HOSTCMD_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST - {0x02, 1, 0, 1, 1}, /* SLP_S3#, SLP_S4#, SLP_S5#, Reserve */ -#else - {0x02, 1, 0, 0, 1}, /* SLP_S3#, SLP_S4#, SLP_S5#, Reserve */ -#endif - {0x03, 1, 0, 1, 1}, /* SUS_STAT#, PLTRST#, ORST_WARN, Reserve */ - {0x07, 1, 1, 1, 1}, /* HRST_WARN, SMIOUT#, NMIOUT#, Reserve */ - {0x41, 1, 0, 1, 1}, /* SUS_WARN#, SPWRDN_ACK, Reserve, SLP_A# */ - {0x42, 1, 0, 0, 1}, /* SLP_LAN#, SLP_WAN#, Reserve, Reserve */ - {0x47, 1, 1, 1, 1}, /* HOST_C10, Reserve, Reserve, Reserve */ -}; - -/* Default settings of VWEVSM registers (Please refer Table.43/44) */ -static const struct vwevsm_config_t espi_out_list[] = { - /* IDX EN ENPL ENCDR VDMASK VW Event Bit 0 - 3 (S->M) */ - {0x04, 1, 0, 0, 0x0D}, /* ORST_ACK, Reserve, WAKE#, PME# */ - {0x05, 1, 0, 0, 0x0F}, /* SLV_BL_DNE, ERR_F, ERR_NF, SLV_BL_STS */ -#ifdef CONFIG_SCI_GPIO - {0x06, 1, 1, 0, 0x0C}, /* SCI#, SMI#, RCIN#, HRST_ACK */ -#else - {0x06, 1, 1, 0, 0x0F}, /* SCI#, SMI#, RCIN#, HRST_ACK */ -#endif - {0x40, 1, 0, 0, 0x01}, /* SUS_ACK, Reserve, Reserve, Reserve */ -}; - -/* eSPI interrupts used in MIWU */ -static const struct host_wui_item espi_vw_int_list[] = { - /* ESPI_RESET */ - {MIWU_TABLE_0, MIWU_GROUP_5, 5, MIWU_EDGE_FALLING}, - /* SLP_S3 */ - {MIWU_TABLE_2, MIWU_GROUP_1, 0, MIWU_EDGE_ANYING}, - /* SLP_S4 */ - {MIWU_TABLE_2, MIWU_GROUP_1, 1, MIWU_EDGE_ANYING}, - /* SLP_S5 */ - {MIWU_TABLE_2, MIWU_GROUP_1, 2, MIWU_EDGE_ANYING}, - /* VW_WIRE_PLTRST */ - {MIWU_TABLE_2, MIWU_GROUP_1, 5, MIWU_EDGE_ANYING}, - /* VW_WIRE_OOB_RST_WARN */ - {MIWU_TABLE_2, MIWU_GROUP_1, 6, MIWU_EDGE_ANYING}, - /* VW_WIRE_HOST_RST_WARN */ - {MIWU_TABLE_2, MIWU_GROUP_2, 0, MIWU_EDGE_ANYING}, - /* VW_WIRE_SUS_WARN */ - {MIWU_TABLE_2, MIWU_GROUP_2, 4, MIWU_EDGE_ANYING}, -}; - -/* VW signals used in eSPI */ -static const struct vw_event_t vw_events_list[] = { - {VW_SLP_S3_L, 0x02, 0x01}, /* index 02h (In) */ - {VW_SLP_S4_L, 0x02, 0x02}, - {VW_SLP_S5_L, 0x02, 0x04}, - {VW_SUS_STAT_L, 0x03, 0x01}, /* index 03h (In) */ - {VW_PLTRST_L, 0x03, 0x02}, - {VW_OOB_RST_WARN, 0x03, 0x04}, - {VW_OOB_RST_ACK, 0x04, 0x01}, /* index 04h (Out) */ - {VW_WAKE_L, 0x04, 0x04}, - {VW_PME_L, 0x04, 0x08}, - {VW_ERROR_FATAL, 0x05, 0x02}, /* index 05h (Out) */ - {VW_ERROR_NON_FATAL, 0x05, 0x04}, - {VW_PERIPHERAL_BTLD_STATUS_DONE, 0x05, 0x09}, - {VW_SCI_L, 0x06, 0x01}, /* index 06h (Out) */ - {VW_SMI_L, 0x06, 0x02}, - {VW_RCIN_L, 0x06, 0x04}, - {VW_HOST_RST_ACK, 0x06, 0x08}, - {VW_HOST_RST_WARN, 0x07, 0x01}, /* index 07h (In) */ - {VW_SUS_ACK, 0x40, 0x01}, /* index 40h (Out) */ - {VW_SUS_WARN_L, 0x41, 0x01}, /* index 41h (In) */ - {VW_SUS_PWRDN_ACK_L, 0x41, 0x02}, - {VW_SLP_A_L, 0x41, 0x08}, - {VW_SLP_LAN, 0x42, 0x01}, /* index 42h (In) */ - {VW_SLP_WLAN, 0x42, 0x02}, -}; - -/* Flag for boot load signals */ -static uint8_t boot_load_done; - -/*****************************************************************************/ -/* eSPI internal utilities */ - -/* Recovery utility for eSPI reset */ -static void espi_reset_recovery(void) -{ - /* TODO: Put recovery stuff related to eSPI reset here */ - - /* Clear boot load flag */ - boot_load_done = 0; -} - -/* Configure Controller-to-Peripheral virtual wire inputs */ -static void espi_vw_config_in(const struct vwevms_config_t *config) -{ - uint32_t val; - uint8_t i, index; - - switch (VM_TYPE(config->idx)) { - case ESPI_VW_TYPE_SYS_EV: - case ESPI_VW_TYPE_PLT: - for (i = 0; i < ESPI_VWEVMS_NUM; i++) { - index = VWEVMS_IDX_GET(NPCX_VWEVMS(i)); - /* Set VW input register */ - if (index == config->idx) { - /* Get Wire field */ - val = NPCX_VWEVMS(i) & 0x0F; - val |= VWEVMS_FIELD(config->idx, - config->idx_en, - config->pltrst_en, - config->int_en, - config->espirst_en); - NPCX_VWEVMS(i) = val; - return; - } - } - CPRINTS("No match index of all VWEVMSs"); - break; - default: - CPRINTS("No support type of VWEVMS"); - break; - } -} - -/* Configure Peripheral-to-Controller virtual wire outputs */ -static void espi_vw_config_out(const struct vwevsm_config_t *config) -{ - uint32_t val; - uint8_t i, index; - - switch (VM_TYPE(config->idx)) { - case ESPI_VW_TYPE_SYS_EV: - case ESPI_VW_TYPE_PLT: - for (i = 0; i < ESPI_VWEVSM_NUM; i++) { - index = VWEVSM_IDX_GET(NPCX_VWEVSM(i)); - /* Set VW output register */ - if (index == config->idx) { - /* Preserve WIRE(3-0) and HW_WIRE (27-24). */ - val = NPCX_VWEVSM(i) & 0x0F00000F; - val |= VWEVSM_FIELD(config->idx, - config->idx_en, - config->valid, - config->pltrst_en, - config->cdrst_en); - NPCX_VWEVSM(i) = val; - return; - } - } - CPRINTS("No match index of all VWEVSMs"); - break; - default: - CPRINTS("No support type of VWEVSM"); - break; - } -} - -/* Config Controller-to-Peripheral VWire interrupt edge type and enable it */ -static void espi_enable_vw_int(const struct host_wui_item *vwire_int) -{ - uint8_t table = vwire_int->table; - uint8_t group = vwire_int->group; - uint8_t num = vwire_int->num; - uint8_t edge = vwire_int->edge; - - /* Set detection mode to edge */ - CLEAR_BIT(NPCX_WKMOD(table, group), num); - - if (edge != MIWU_EDGE_ANYING) { - /* Disable Any Edge */ - CLEAR_BIT(NPCX_WKAEDG(table, group), num); - /* Enable Rising Edge */ - if (edge == MIWU_EDGE_RISING) - CLEAR_BIT(NPCX_WKEDG(table, group), num); - /* Enable Falling Edge */ - else - SET_BIT(NPCX_WKEDG(table, group), num); - } else - /* enable Any Edge */ - SET_BIT(NPCX_WKAEDG(table, group), num); - - /* Clear the pending bit */ - NPCX_WKPCL(table, group) = BIT(num); - - /* Enable wake-up input sources */ - SET_BIT(NPCX_WKEN(table, group), num); -} - -/* Get vw index & value information by signal */ -static int espi_vw_get_signal_index(enum espi_vw_signal event) -{ - int index; - - /* Find the vw index by signal name first */ - for (index = 0; index < ARRAY_SIZE(vw_events_list); index++) { - if (vw_events_list[index].name == event) - break; - } - /* Cannot find the index */ - if (index == ARRAY_SIZE(vw_events_list)) - return -1; - - return index; -} - -/* The ISRs of VW signals which used for power sequences */ -void espi_vw_power_signal_interrupt(enum espi_vw_signal signal) -{ - if (IS_ENABLED(CONFIG_HOST_ESPI_VW_POWER_SIGNAL)) - /* TODO: Add VW handler in power/common.c */ - power_signal_interrupt((enum gpio_signal) signal); -} - -/*****************************************************************************/ -/* IC specific low-level driver */ - -/** - * Set eSPI Virtual-Wire signal to Host - * - * @param signal vw signal needs to set - * @param level level of vw signal - * @return EC_SUCCESS, or non-zero if error. - */ -int espi_vw_set_wire(enum espi_vw_signal signal, uint8_t level) -{ - uint8_t offset, value; - int sig_idx; - - /* Get index of vw signal list by signale name */ - sig_idx = espi_vw_get_signal_index(signal); - - /* Cannot find index by signal name */ - if (sig_idx < 0) - return EC_ERROR_PARAM1; - - /* Find the output register offset by vw index */ - for (offset = 0; offset < ESPI_VWEVSM_NUM; offset++) { - uint8_t vw_idx = VWEVSM_IDX_GET(NPCX_VWEVSM(offset)); - /* If index matches. break */ - if (vw_idx == vw_events_list[sig_idx].evt_idx) - break; - } - - /* Cannot match index */ - if (offset == ESPI_VWEVSM_NUM) - return EC_ERROR_PARAM1; - - value = GET_FIELD(NPCX_VWEVSM(offset), NPCX_VWEVSM_WIRE); - /* Set wire */ - if (level) - value |= vw_events_list[sig_idx].evt_val; - else /* Clear wire */ - value &= (~vw_events_list[sig_idx].evt_val); - - SET_FIELD(NPCX_VWEVSM(offset), NPCX_VWEVSM_WIRE, value); - - return EC_SUCCESS; -} - -/** - * Get eSPI Virtual-Wire signal from host - * - * @param signal vw signal needs to get - * @return 1: set by host, otherwise: no signal - */ -int espi_vw_get_wire(enum espi_vw_signal signal) -{ - uint8_t offset, value; - int sig_idx; - - /* Get index of vw signal list by signale name */ - sig_idx = espi_vw_get_signal_index(signal); - - /* Cannot find index by signal name */ - if (sig_idx < 0) - return -1; - - /* Find the input register offset by vw index */ - for (offset = 0; offset < ESPI_VWEVMS_NUM; offset++) { - uint8_t vw_idx = VWEVMS_IDX_GET(NPCX_VWEVMS(offset)); - /* If index matches. break */ - if (vw_idx == vw_events_list[sig_idx].evt_idx) - break; - } - - /* Cannot match index */ - if (offset == ESPI_VWEVMS_NUM) - return -1; - - /* Get wire & check with valid bits */ - value = GET_FIELD(NPCX_VWEVMS(offset), NPCX_VWEVMS_WIRE); - value &= GET_FIELD(NPCX_VWEVMS(offset), NPCX_VWEVMS_VALID); - - return !!(value & vw_events_list[sig_idx].evt_val); -} - -/** - * Enable VW interrupt of power sequence signal - * - * @param signal vw signal needs to enable interrupt - * @return EC_SUCCESS, or non-zero if error. - */ -int espi_vw_enable_wire_int(enum espi_vw_signal signal) -{ - if (signal == VW_SLP_S3_L) - SET_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 0); - else if (signal == VW_SLP_S4_L) - SET_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 1); - else if (signal == VW_SLP_S5_L) - SET_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 2); - else - return EC_ERROR_PARAM1; - - return EC_SUCCESS; -} - -/** - * Disable VW interrupt of power sequence signal - * - * @param signal vw signal needs to disable interrupt - * @return EC_SUCCESS, or non-zero if error. - */ -int espi_vw_disable_wire_int(enum espi_vw_signal signal) -{ - if (signal == VW_SLP_S3_L) - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 0); - else if (signal == VW_SLP_S4_L) - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 1); - else if (signal == VW_SLP_S5_L) - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_1), 2); - else - return EC_ERROR_PARAM1; - - return EC_SUCCESS; -} - -/*****************************************************************************/ -/* VW event handlers */ - -#ifdef CONFIG_CHIPSET_RESET_HOOK -static void espi_chipset_reset(void) -{ - hook_notify(HOOK_CHIPSET_RESET); -} -DECLARE_DEFERRED(espi_chipset_reset); -#endif - -/* PLTRST# event handler */ -void espi_vw_evt_pltrst(void) -{ - int pltrst = espi_vw_get_wire(VW_PLTRST_L); - - CPRINTS("VW PLTRST: %d", pltrst); - - if (pltrst) { - /* PLTRST# deasserted */ -#if defined(CHIP_FAMILY_NPCX5) - /* See errata 2.22 */ - - /* Disable eSPI peripheral channel support first */ - CLEAR_BIT(NPCX_ESPICFG, NPCX_ESPICFG_PCCHN_SUPP); - - /* Initialize host settings */ - host_register_init(); - - /* Enable eSPI peripheral channel */ - SET_BIT(NPCX_ESPICFG, NPCX_ESPICFG_PCHANEN); - - /* Re-enable eSPI peripheral channel support */ - SET_BIT(NPCX_ESPICFG, NPCX_ESPICFG_PCCHN_SUPP); -#else - /* Initialize host settings */ - host_register_init(); - - /* Enable eSPI peripheral channel */ - SET_BIT(NPCX_ESPICFG, NPCX_ESPICFG_PCHANEN); -#endif - } else { - /* PLTRST# asserted */ -#ifdef CONFIG_CHIPSET_RESET_HOOK - hook_call_deferred(&espi_chipset_reset_data, MSEC); -#endif - } -} - -/* SLP_Sx event handler */ -void espi_vw_evt_slp_s3(void) -{ - CPRINTS("VW SLP_S3: %d", espi_vw_get_wire(VW_SLP_S3_L)); - espi_vw_power_signal_interrupt(VW_SLP_S3_L); -} - -void espi_vw_evt_slp_s4(void) -{ - CPRINTS("VW SLP_S4: %d", espi_vw_get_wire(VW_SLP_S4_L)); - espi_vw_power_signal_interrupt(VW_SLP_S4_L); -} - -void espi_vw_evt_slp_s5(void) -{ - CPRINTS("VW SLP_S5: %d", espi_vw_get_wire(VW_SLP_S5_L)); - espi_vw_power_signal_interrupt(VW_SLP_S5_L); -} - -/* OOB Reset event handler */ -void espi_vw_evt_oobrst(void) -{ - CPRINTS("VW OOB_RST: %d", espi_vw_get_wire(VW_OOB_RST_WARN)); - - /* Send ACK to host by WARN#'s wire */ - espi_vw_set_wire(VW_OOB_RST_ACK, espi_vw_get_wire(VW_OOB_RST_WARN)); -} - -/* SUS_WARN# event handler */ -void espi_vw_evt_sus_warn(void) -{ - CPRINTS("VW SUS_WARN#: %d", espi_vw_get_wire(VW_SUS_WARN_L)); - - udelay(100); - - /* Send ACK to host by WARN#'s wire */ - espi_vw_set_wire(VW_SUS_ACK, espi_vw_get_wire(VW_SUS_WARN_L)); -} - -/* HOSTRST WARN event handler */ -void espi_vw_evt_hostrst_warn(void) -{ - CPRINTS("VW HOST_RST_WARN#: %d", espi_vw_get_wire(VW_HOST_RST_WARN)); - - /* Send ACK to host by WARN#'s wire */ - espi_vw_set_wire(VW_HOST_RST_ACK, espi_vw_get_wire(VW_HOST_RST_WARN)); -} - -/*****************************************************************************/ -/* Interrupt handlers */ - -/* eSPI reset assert/de-assert interrupt */ -void espi_espirst_handler(void) -{ - /* Clear pending bit of WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_5), 5); - - CPRINTS("eSPI RST issued!"); -} - -/* Handle eSPI virtual wire interrupt 1 */ -void __espi_wk2a_interrupt(void) -{ - uint8_t pending_bits = NPCX_WKPND(MIWU_TABLE_2, MIWU_GROUP_1); - - /* Clear pending bits of MIWU */ - NPCX_WKPCL(MIWU_TABLE_2, MIWU_GROUP_1) = pending_bits; - - /* Handle events of virtual-wire */ - if (IS_BIT_SET(pending_bits, 0)) - espi_vw_evt_slp_s3(); - if (IS_BIT_SET(pending_bits, 1)) - espi_vw_evt_slp_s4(); - if (IS_BIT_SET(pending_bits, 2)) - espi_vw_evt_slp_s5(); - if (IS_BIT_SET(pending_bits, 5)) - espi_vw_evt_pltrst(); - if (IS_BIT_SET(pending_bits, 6)) - espi_vw_evt_oobrst(); -} -DECLARE_IRQ(NPCX_IRQ_WKINTA_2, __espi_wk2a_interrupt, 3); - -/* Handle eSPI virtual wire interrupt 2 */ -void __espi_wk2b_interrupt(void) -{ - uint8_t pending_bits = NPCX_WKPND(MIWU_TABLE_2, MIWU_GROUP_2); - - /* Clear pending bits of MIWU */ - NPCX_WKPCL(MIWU_TABLE_2, MIWU_GROUP_2) = pending_bits; - - /* Handle events of virtual-wire */ - if (IS_BIT_SET(pending_bits, 4)) - espi_vw_evt_sus_warn(); - if (IS_BIT_SET(pending_bits, 0)) - espi_vw_evt_hostrst_warn(); -} -DECLARE_IRQ(NPCX_IRQ_WKINTB_2, __espi_wk2b_interrupt, 3); - -/* Interrupt handler for eSPI status changed */ -void espi_interrupt(void) -{ - int chan; - uint32_t mask, status; - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - /* - * Bit 17 of ESPIIE is reserved. We need to set the same bit in mask - * in case bit 17 in ESPISTS of npcx7 is not cleared in ISR. - */ - mask = NPCX_ESPIIE | BIT(NPCX_ESPISTS_VWUPDW); -#else - mask = NPCX_ESPIIE; -#endif - status = NPCX_ESPISTS & mask; - - while (status) { - /* Clear pending bits first */ - NPCX_ESPISTS = status; - - if (IS_BIT_SET(status, NPCX_ESPISTS_BERR)) - /* Always print eSPI Bus Errors */ - cprints(CC_LPC, "eSPI Bus Error"); - - /* eSPI inband reset(from VW) */ - if (IS_BIT_SET(status, NPCX_ESPISTS_IBRST)) { - CPRINTS("eSPI RST inband RST"); - espi_reset_recovery(); - - } /* eSPI reset (from eSPI_rst pin) */ - else if (IS_BIT_SET(status, NPCX_ESPISTS_ESPIRST)) { - CPRINTS("eSPI RST"); - chipset_handle_espi_reset_assert(); - espi_reset_recovery(); - } - - /* eSPI configuration is updated */ - if (IS_BIT_SET(status, NPCX_ESPISTS_CFGUPD)) { - /* - * If host enable/disable channel for VW/OOB/FLASH, EC - * should follow except Peripheral channel. It is - * handled by PLTRST separately. - */ - for (chan = NPCX_ESPI_CH_VW; chan < NPCX_ESPI_CH_COUNT; - chan++) { - if (!IS_PERIPHERAL_CHAN_ENABLE(chan) && - IS_HOST_CHAN_EN(chan)) - ENABLE_ESPI_CHAN(chan); - else if (IS_PERIPHERAL_CHAN_ENABLE(chan) && - !IS_HOST_CHAN_EN(chan)) - DISABLE_ESPI_CHAN(chan); - } - - /* - * Send BOOTLOAD_DONE and BOOTLOAD_STATUS - * events to host simultaneously. To indicate the - * completion of EC firmware code loading. - */ - if (boot_load_done == 0 && - IS_PERIPHERAL_CHAN_ENABLE(NPCX_ESPI_CH_VW)) { - - espi_vw_set_wire( - VW_PERIPHERAL_BTLD_STATUS_DONE, 1); - boot_load_done = 1; - } - } - - /* Any VW signal sent by Host - leave it, handle in MIWU ISR */ - if (IS_BIT_SET(status, NPCX_ESPISTS_VWUPD)) - CPRINTS("VW Updated INT"); - - /* Get status again */ - status = NPCX_ESPISTS & mask; - } -} -DECLARE_IRQ(NPCX_IRQ_ESPI, espi_interrupt, 4); - -/*****************************************************************************/ -/* eSPI Initialization functions */ -void espi_init(void) -{ - int i; - - /* Support all channels */ - NPCX_ESPICFG |= ESPI_SUPP_CH_ALL; - - /* Support all I/O modes */ - SET_FIELD(NPCX_ESPICFG, NPCX_ESPICFG_IOMODE_FIELD, - NPCX_ESPI_IO_MODE_ALL); - - /* Set eSPI speed to max supported */ - SET_FIELD(NPCX_ESPICFG, NPCX_ESPICFG_MAXFREQ_FIELD, - NPCX_ESPI_MAXFREQ_MAX); - - /* Configure Controller-to-Peripheral Virtual Wire indexes (Inputs) */ - for (i = 0; i < ARRAY_SIZE(espi_in_list); i++) - espi_vw_config_in(&espi_in_list[i]); - - /* Configure Peripheral-to-Controller Virtual Wire indexes (Outputs) */ - for (i = 0; i < ARRAY_SIZE(espi_out_list); i++) - espi_vw_config_out(&espi_out_list[i]); - - /* Configure MIWU for eSPI VW */ - for (i = 0; i < ARRAY_SIZE(espi_vw_int_list); i++) - espi_enable_vw_int(&espi_vw_int_list[i]); -} - -static int command_espi(int argc, char **argv) -{ - uint32_t chan; - char *e; - - if (argc == 1) { - return EC_ERROR_INVAL; - /* Get value of eSPI registers */ - } else if (argc == 2) { - int i; - - if (strcasecmp(argv[1], "cfg") == 0) { - ccprintf("ESPICFG [0x%08x]\n", NPCX_ESPICFG); - } else if (strcasecmp(argv[1], "vsm") == 0) { - for (i = 0; i < ESPI_VWEVSM_NUM; i++) { - uint32_t val = NPCX_VWEVSM(i); - uint8_t idx = VWEVSM_IDX_GET(val); - - ccprintf("VWEVSM%d: %02x [0x%08x]\n", i, idx, - val); - } - } else if (strcasecmp(argv[1], "vms") == 0) { - for (i = 0; i < ESPI_VWEVMS_NUM; i++) { - uint32_t val = NPCX_VWEVMS(i); - uint8_t idx = VWEVMS_IDX_GET(val); - - ccprintf("VWEVMS%d: %02x [0x%08x]\n", i, idx, - val); - } - } - /* Enable/Disable the channels of eSPI */ - } else if (argc == 3) { - uint32_t m = (uint32_t) strtoi(argv[2], &e, 0); - - if (*e) - return EC_ERROR_PARAM2; - if (m > 4) - return EC_ERROR_PARAM2; - else if (m == 4) - chan = 0x0F; - else - chan = 0x01 << m; - if (strcasecmp(argv[1], "en") == 0) - NPCX_ESPICFG = NPCX_ESPICFG | chan; - else if (strcasecmp(argv[1], "dis") == 0) - NPCX_ESPICFG = NPCX_ESPICFG & ~chan; - else - return EC_ERROR_PARAM1; - ccprintf("ESPICFG [0x%08x]\n", NPCX_ESPICFG); - } - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(espi, command_espi, - "cfg/vms/vsm/en/dis [channel]", - "eSPI configurations"); diff --git a/chip/npcx/fan.c b/chip/npcx/fan.c deleted file mode 100644 index f0b3215ce0..0000000000 --- a/chip/npcx/fan.c +++ /dev/null @@ -1,549 +0,0 @@ -/* Copyright 2014 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 fan control module. */ - -#include "clock.h" -#include "clock_chip.h" -#include "fan.h" -#include "fan_chip.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "util.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "console.h" -#include "timer.h" -#include "task.h" -#include "hooks.h" -#include "system.h" -#include "math_util.h" - -#if !(DEBUG_FAN) -#define CPRINTS(...) -#else -#define CPRINTS(format, args...) cprints(CC_PWM, format, ## args) -#endif - -/* Tacho measurement state */ -enum tacho_measure_state { - /* Tacho normal state */ - TACHO_NORMAL = 0, - /* Tacho underflow state */ - TACHO_UNDERFLOW -}; - -/* Fan mode */ -enum tacho_fan_mode { - /* FAN rpm mode */ - TACHO_FAN_RPM = 0, - /* FAN duty mode */ - TACHO_FAN_DUTY, -}; - -/* Fan status data structure */ -struct fan_status_t { - /* Current state of the measurement */ - enum tacho_measure_state cur_state; - /* Fan mode */ - enum tacho_fan_mode fan_mode; - /* MFT sampling freq*/ - uint32_t mft_freq; - /* Actual rpm */ - int rpm_actual; - /* Target rpm */ - int rpm_target; - /* Automatic fan status */ - enum fan_status auto_status; -}; - -/* Global variables */ -static volatile struct fan_status_t fan_status[FAN_CH_COUNT]; -static int rpm_pre[FAN_CH_COUNT]; - -/* - * Fan specifications. If they (PULSES_ROUND and RPM_DEVIATION) cannot meet - * the followings, please replace them with correct one in board-level driver. - */ - -/* Pulses per round */ -#ifndef PULSES_ROUND -#define PULSES_ROUND 2 /* 4-phases pwm-type fan. (2-phases should be 1) */ -#endif - -/* Rpm deviation (Unit:percent) */ -#ifndef RPM_DEVIATION -#define RPM_DEVIATION 7 -#endif - -/* - * RPM = 60 * f / (n * TACH) - * n = Pulses per round - * f = Tachometer (MFT) operation freq - * TACH = Counts of tachometer - */ -#define TACH_TO_RPM(ch, tach) \ - ((fan_status[ch].mft_freq * 60 / PULSES_ROUND) / MAX((tach), 1)) - -/* MFT TCNT default count */ -#define TACHO_MAX_CNT (BIT(16) - 1) - -/* Margin of target rpm */ -#define RPM_MARGIN(rpm_target) (((rpm_target) * RPM_DEVIATION) / 100) - -/** - * MFT get fan rpm value - * - * @param ch operation channel - * @return actual rpm - */ -static int mft_fan_rpm(int ch) -{ - volatile struct fan_status_t *p_status = fan_status + ch; - int mdl = mft_channels[ch].module; - int tacho; - - /* Check whether MFT underflow flag is occurred */ - if (IS_BIT_SET(NPCX_TECTRL(mdl), NPCX_TECTRL_TCPND)) { - /* Clear pending flags */ - SET_BIT(NPCX_TECLR(mdl), NPCX_TECLR_TCCLR); - - /* - * Flag TDPND means mft underflow happen, - * but let MFT still can re-measure actual rpm - * when user change pwm/fan duty during - * TACHO_UNDERFLOW state. - */ - p_status->cur_state = TACHO_UNDERFLOW; - p_status->auto_status = FAN_STATUS_STOPPED; - CPRINTS("Tacho is underflow !"); - - return 0; - } - - /* Check whether MFT capture flag is set, else return previous rpm */ - if (IS_BIT_SET(NPCX_TECTRL(mdl), NPCX_TECTRL_TAPND)) - /* Clear pending flags */ - SET_BIT(NPCX_TECLR(mdl), NPCX_TECLR_TACLR); - else - return p_status->rpm_actual; - - p_status->cur_state = TACHO_NORMAL; - /* - * Start of the last tacho cycle is detected - - * calculated tacho cycle duration - */ - tacho = TACHO_MAX_CNT - NPCX_TCRA(mdl); - /* Transfer tacho to actual rpm */ - return (tacho > 0) ? (TACH_TO_RPM(ch, tacho)) : 0; -} - -/** - * Set fan prescaler based on apb1 clock - * - * @param none - * @return none - * @notes changed when initial or HOOK_FREQ_CHANGE command - */ -void mft_set_apb1_prescaler(int ch) -{ - int mdl = mft_channels[ch].module; - uint16_t prescaler_divider = 0; - - /* Set clock prescaler divider to MFT module*/ - prescaler_divider = (uint16_t)(clock_get_apb1_freq() - / fan_status[ch].mft_freq); - if (prescaler_divider >= 1) - prescaler_divider = prescaler_divider - 1; - if (prescaler_divider > 0xFF) - prescaler_divider = 0xFF; - - NPCX_TPRSC(mdl) = (uint8_t) prescaler_divider; -} - -/** - * Fan configuration. - * - * @param ch operation channel - * @param enable_mft_read_rpm FAN_USE_RPM_MODE enable flag - * @return none - */ -static void fan_config(int ch, int enable_mft_read_rpm) -{ - int mdl = mft_channels[ch].module; - int pwm_id = mft_channels[ch].pwm_id; - enum npcx_mft_clk_src clk_src = mft_channels[ch].clk_src; - - volatile struct fan_status_t *p_status = fan_status + ch; - - /* Setup pwm with fan spec. */ - pwm_config(pwm_id); - - /* Need to initialize MFT or not */ - if (enable_mft_read_rpm) { - - /* Initialize tacho sampling rate */ - if (clk_src == TCKC_LFCLK) - p_status->mft_freq = INT_32K_CLOCK; - else if (clk_src == TCKC_PRESCALE_APB1_CLK) - p_status->mft_freq = clock_get_apb1_freq(); - else - p_status->mft_freq = 0; - - /* Set mode 5 to MFT module */ - SET_FIELD(NPCX_TMCTRL(mdl), NPCX_TMCTRL_MDSEL_FIELD, - NPCX_MFT_MDSEL_5); - - /* Set MFT operation frequency */ - if (clk_src == TCKC_PRESCALE_APB1_CLK) - mft_set_apb1_prescaler(ch); - - /* Set the low power mode or not. */ - UPDATE_BIT(NPCX_TCKC(mdl), NPCX_TCKC_LOW_PWR, - clk_src == TCKC_LFCLK); - - /* Set the default count-down timer. */ - NPCX_TCNT1(mdl) = TACHO_MAX_CNT; - NPCX_TCRA(mdl) = TACHO_MAX_CNT; - - /* Set the edge polarity to rising. */ - SET_BIT(NPCX_TMCTRL(mdl), NPCX_TMCTRL_TAEDG); - /* Enable capture TCNT1 into TCRA and preset TCNT1. */ - SET_BIT(NPCX_TMCTRL(mdl), NPCX_TMCTRL_TAEN); - /* Enable input debounce logic into TA. */ - SET_BIT(NPCX_TCFG(mdl), NPCX_TCFG_TADBEN); - - /* Set the clock source type and start capturing */ - SET_FIELD(NPCX_TCKC(mdl), NPCX_TCKC_C1CSEL_FIELD, clk_src); - } - - /* Set default fan states */ - p_status->cur_state = TACHO_NORMAL; - p_status->fan_mode = TACHO_FAN_DUTY; - p_status->auto_status = FAN_STATUS_STOPPED; -} - -/** - * Check all fans are stopped - * - * @return 1: all fans are stopped. 0: else. - */ -static int fan_all_disabled(void) -{ - int ch; - - for (ch = 0; ch < fan_get_count(); ch++) - if (fan_status[ch].auto_status != FAN_STATUS_STOPPED) - return 0; - return 1; -} - -/** - * Adjust fan duty by difference between target and actual rpm - * - * @param ch operation channel - * @param rpm_diff difference between target and actual rpm - * @param duty current fan duty - */ -static void fan_adjust_duty(int ch, int rpm_diff, int duty) -{ - int duty_step = 0; - - /* Find suitable duty step */ - if (ABS(rpm_diff) >= 2000) - duty_step = 20; - else if (ABS(rpm_diff) >= 1000) - duty_step = 10; - else if (ABS(rpm_diff) >= 500) - duty_step = 5; - else if (ABS(rpm_diff) >= 250) - duty_step = 3; - else - duty_step = 1; - - /* Adjust fan duty step by step */ - if (rpm_diff > 0) - duty = MIN(duty + duty_step, 100); - else - duty = MAX(duty - duty_step, 1); - - fan_set_duty(ch, duty); - - CPRINTS("fan%d: duty %d, rpm_diff %d", ch, duty, rpm_diff); -} - -/** - * Smart fan control function. - * - * @param ch operation channel - * @param rpm_actual actual operation rpm value - * @param rpm_target target operation rpm value - * @return current fan control status - */ -enum fan_status fan_smart_control(int ch, int rpm_actual, int rpm_target) -{ - int duty, rpm_diff; - - /* wait rpm is stable */ - if (ABS(rpm_actual - rpm_pre[ch]) > RPM_MARGIN(rpm_actual)) { - rpm_pre[ch] = rpm_actual; - return FAN_STATUS_CHANGING; - } - - /* Record previous rpm */ - rpm_pre[ch] = rpm_actual; - - /* Adjust PWM duty */ - rpm_diff = rpm_target - rpm_actual; - duty = fan_get_duty(ch); - if (duty == 0 && rpm_target == 0) - return FAN_STATUS_STOPPED; - - /* Increase PWM duty */ - if (rpm_diff > RPM_MARGIN(rpm_target)) { - if (duty == 100) - return FAN_STATUS_FRUSTRATED; - - fan_adjust_duty(ch, rpm_diff, duty); - return FAN_STATUS_CHANGING; - /* Decrease PWM duty */ - } else if (rpm_diff < -RPM_MARGIN(rpm_target)) { - if (duty == 1 && rpm_target != 0) - return FAN_STATUS_FRUSTRATED; - - fan_adjust_duty(ch, rpm_diff, duty); - return FAN_STATUS_CHANGING; - } - - return FAN_STATUS_LOCKED; -} - -/** - * Tick function for fan control. - * - * @return none - */ -void fan_tick_func(void) -{ - int ch; - - for (ch = 0; ch < FAN_CH_COUNT ; ch++) { - volatile struct fan_status_t *p_status = fan_status + ch; - /* Make sure rpm mode is enabled */ - if (p_status->fan_mode != TACHO_FAN_RPM) { - /* Fan in duty mode still want rpm_actual being updated. */ - p_status->rpm_actual = mft_fan_rpm(ch); - if (p_status->rpm_actual > 0) - p_status->auto_status = FAN_STATUS_LOCKED; - else - p_status->auto_status = FAN_STATUS_STOPPED; - continue; - } - if (!fan_get_enabled(ch)) - continue; - /* Get actual rpm */ - p_status->rpm_actual = mft_fan_rpm(ch); - /* Do smart fan stuff */ - p_status->auto_status = fan_smart_control(ch, - p_status->rpm_actual, p_status->rpm_target); - } -} -DECLARE_HOOK(HOOK_TICK, fan_tick_func, HOOK_PRIO_DEFAULT); - -/*****************************************************************************/ -/* IC specific low-level driver */ - -/** - * Set fan duty cycle. - * - * @param ch operation channel - * @param percent duty cycle percent - * @return none - */ -void fan_set_duty(int ch, int percent) -{ - int pwm_id = mft_channels[ch].pwm_id; - - /* duty is zero */ - if (!percent) { - fan_status[ch].auto_status = FAN_STATUS_STOPPED; - if (fan_all_disabled()) - enable_sleep(SLEEP_MASK_FAN); - } else - disable_sleep(SLEEP_MASK_FAN); - - /* Set the duty cycle of PWM */ - pwm_set_duty(pwm_id, percent); -} - -/** - * Get fan duty cycle. - * - * @param ch operation channel - * @return duty cycle - */ -int fan_get_duty(int ch) -{ - int pwm_id = mft_channels[ch].pwm_id; - - /* Return percent */ - return pwm_get_duty(pwm_id); -} -/** - * Check fan is rpm operation mode. - * - * @param ch operation channel - * @return rpm operation mode or not - */ -int fan_get_rpm_mode(int ch) -{ - return fan_status[ch].fan_mode == TACHO_FAN_RPM ? 1 : 0; -} - -/** - * Set fan to rpm operation mode. - * - * @param ch operation channel - * @param rpm_mode rpm operation mode flag - * @return none - */ -void fan_set_rpm_mode(int ch, int rpm_mode) -{ - if (rpm_mode) - fan_status[ch].fan_mode = TACHO_FAN_RPM; - else - fan_status[ch].fan_mode = TACHO_FAN_DUTY; -} - -/** - * Get fan actual operation rpm. - * - * @param ch operation channel - * @return actual operation rpm value - */ -int fan_get_rpm_actual(int ch) -{ - /* Check PWM is enabled first */ - if (fan_get_duty(ch) == 0) - return 0; - - CPRINTS("fan %d: get actual rpm = %d", ch, fan_status[ch].rpm_actual); - return fan_status[ch].rpm_actual; -} - -/** - * Check fan enabled. - * - * @param ch operation channel - * @return enabled or not - */ -int fan_get_enabled(int ch) -{ - int pwm_id = mft_channels[ch].pwm_id; - - return pwm_get_enabled(pwm_id); -} -/** - * Set fan enabled. - * - * @param ch operation channel - * @param enabled enabled flag - * @return none - */ -void fan_set_enabled(int ch, int enabled) -{ - int pwm_id = mft_channels[ch].pwm_id; - - if (!enabled) - fan_status[ch].auto_status = FAN_STATUS_STOPPED; - pwm_enable(pwm_id, enabled); -} - -/** - * Get fan setting rpm. - * - * @param ch operation channel - * @return setting rpm value - */ -int fan_get_rpm_target(int ch) -{ - return fan_status[ch].rpm_target; -} - -/** - * Set fan setting rpm. - * - * @param ch operation channel - * @param rpm setting rpm value - * @return none - */ -void fan_set_rpm_target(int ch, int rpm) -{ - if (rpm == 0) { - /* If rpm = 0, disable PWM immediately. Why?*/ - fan_set_duty(ch, 0); - } else { - /* This is the counterpart of disabling PWM above. */ - if (!fan_get_enabled(ch)) - fan_set_enabled(ch, 1); - if (rpm > fans[ch].rpm->rpm_max) - rpm = fans[ch].rpm->rpm_max; - else if (rpm < fans[ch].rpm->rpm_min) - rpm = fans[ch].rpm->rpm_min; - } - - /* Set target rpm */ - fan_status[ch].rpm_target = rpm; - CPRINTS("fan %d: set target rpm = %d", ch, fan_status[ch].rpm_target); -} - -/** - * Check fan operation status. - * - * @param ch operation channel - * @return fan_status fan operation status - */ -enum fan_status fan_get_status(int ch) -{ - return fan_status[ch].auto_status; -} - -/** - * Check fan is stall condition. - * - * @param ch operation channel - * @return non-zero if fan is enabled but stalled - */ -int fan_is_stalled(int ch) -{ - return fan_get_enabled(ch) && fan_get_duty(ch) && - fan_status[ch].cur_state == TACHO_UNDERFLOW; -} - -/** - * Fan channel setup. - * - * @param ch operation channel - * @param flags input flags - * @return none - */ -void fan_channel_setup(int ch, unsigned int flags) -{ - fan_config(ch, (flags & FAN_USE_RPM_MODE)); -} - -/** - * Fan initial. - * - * @param none - * @return none - */ -static void fan_init(void) -{ - /* Enable the fan module and delay a few clocks */ - clock_enable_peripheral(CGC_OFFSET_FAN, CGC_FAN_MASK, CGC_MODE_ALL); -} -DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_INIT_FAN); diff --git a/chip/npcx/fan_chip.h b/chip/npcx/fan_chip.h deleted file mode 100644 index 6fc228ec84..0000000000 --- a/chip/npcx/fan_chip.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2014 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-specific MFT module for Chrome EC */ - -#ifndef __CROS_EC_FAN_CHIP_H -#define __CROS_EC_FAN_CHIP_H - -/* MFT mode select */ -enum npcx_mft_mdsel { - NPCX_MFT_MDSEL_1, - NPCX_MFT_MDSEL_2, - NPCX_MFT_MDSEL_3, - NPCX_MFT_MDSEL_4, - NPCX_MFT_MDSEL_5, - /* Number of MFT modes */ - NPCX_MFT_MDSEL_COUNT -}; - -/* MFT module select */ -enum npcx_mft_module { - NPCX_MFT_MODULE_1, - NPCX_MFT_MODULE_2, - NPCX_MFT_MODULE_3, - /* Number of MFT modules */ - NPCX_MFT_MODULE_COUNT -}; - -/* MFT clock source */ -enum npcx_mft_clk_src { - TCKC_NOCLK = 0, - TCKC_PRESCALE_APB1_CLK = 1, - TCKC_LFCLK = 4, -}; - -/* Data structure to define MFT channels. */ -struct mft_t { - /* MFT module ID */ - enum npcx_mft_module module; - /* MFT clock source */ - enum npcx_mft_clk_src clk_src; - /* PWM id */ - int pwm_id; -}; - -extern const struct mft_t mft_channels[]; - -#endif /* __CROS_EC_FAN_CHIP_H */ diff --git a/chip/npcx/flash.c b/chip/npcx/flash.c deleted file mode 100644 index 507b83714c..0000000000 --- a/chip/npcx/flash.c +++ /dev/null @@ -1,832 +0,0 @@ -/* Copyright 2014 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. - */ - -/* Flash memory module for Chrome EC */ - -#include "flash.h" -#include "host_command.h" -#include "registers.h" -#include "spi_flash_reg.h" -#include "switch.h" -#include "system.h" -#include "timer.h" -#include "util.h" -#include "task.h" -#include "watchdog.h" -#include "console.h" -#include "hwtimer_chip.h" - -static int all_protected; /* Has all-flash protection been requested? */ -static int addr_prot_start; -static int addr_prot_length; -static uint8_t flag_prot_inconsistent; - -/* SR regs aren't readable when UMA lock is on, so save a copy */ -static uint8_t saved_sr1; -static uint8_t saved_sr2; - -#ifdef CONFIG_EXTERNAL_STORAGE -#define TRISTATE_FLASH(x) -#else -#define TRISTATE_FLASH(x) flash_tristate(x) -#endif - -/* Ensure only one task is accessing flash at a time. */ -static struct mutex flash_lock; - -/*****************************************************************************/ -/* flash internal functions */ -#if !defined(NPCX_INT_FLASH_SUPPORT) -static void flash_pinmux(int enable) -{ - /* Select pin-mux for FIU*/ - UPDATE_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI, !enable); - - /* 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); - } -} -#endif - -static void flash_execute_cmd(uint8_t code, uint8_t cts) -{ - /* - * Flash mutex must be held while executing UMA commands after - * task_start(). - */ - ASSERT(!task_start_called() || flash_lock.lock); - - /* 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)) - ; -} - -static void flash_cs_level(int level) -{ - /* Set chip select to high/low level */ - UPDATE_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1, level); -} - -static int flash_wait_ready(void) -{ - uint8_t mask = SPI_FLASH_SR1_BUSY; - const timestamp_t start = get_time(); - const uint32_t timeout_us = 10 * SECOND; - const timestamp_t deadline = { - .val = start.val + timeout_us, - }; - - /* Chip Select down. */ - flash_cs_level(0); - /* Command for Read status register */ - 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)) - ; - /* Busy bit is clear */ - if ((NPCX_UMA_DB0 & mask) == 0) - break; - usleep(10); - } while (!timestamp_expired(deadline, NULL)); /* Wait for Busy clear */ - - /* Chip Select high. */ - flash_cs_level(1); - - if (timestamp_expired(deadline, NULL)) - return EC_ERROR_TIMEOUT; - - return EC_SUCCESS; -} - -static int flash_write_enable(void) -{ - uint8_t mask = SPI_FLASH_SR1_WEL; - int rv; - /* Wait for previous operation to complete */ - rv = flash_wait_ready(); - if (rv) - return rv; - - /* Write enable command */ - flash_execute_cmd(CMD_WRITE_EN, MASK_CMD_ONLY); - - /* Wait for flash is not busy */ - rv = flash_wait_ready(); - if (rv) - return rv; - - if (NPCX_UMA_DB0 & mask) - return EC_SUCCESS; - else - return EC_ERROR_BUSY; -} - -static void 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]; -} - -static uint8_t flash_get_status1(void) -{ - uint8_t ret; - - if (all_protected) - return saved_sr1; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read status register1 */ - flash_execute_cmd(CMD_READ_STATUS_REG, MASK_CMD_RD_1BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - ret = NPCX_UMA_DB0; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return ret; -} - -static uint8_t flash_get_status2(void) -{ - uint8_t ret; - - if (all_protected) - return saved_sr2; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read status register2 */ - flash_execute_cmd(CMD_READ_STATUS_REG2, MASK_CMD_RD_1BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - ret = NPCX_UMA_DB0; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return ret; -} - -#ifdef NPCX_INT_FLASH_SUPPORT -static int is_int_flash_protected(void) -{ - return IS_BIT_SET(NPCX_DEV_CTL4, NPCX_DEV_CTL4_WP_IF); -} - -static void flash_protect_int_flash(int enable) -{ - /* - * Please notice the type of WP_IF bit is R/W1S. Once it's set, - * only rebooting EC can clear it. - */ - if (enable && !is_int_flash_protected()) - SET_BIT(NPCX_DEV_CTL4, NPCX_DEV_CTL4_WP_IF); -} -#endif - -#ifdef CONFIG_HOSTCMD_FLASH_SPI_INFO - -void flash_get_mfr_dev_id(uint8_t *dest) -{ - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read manufacturer and device ID. Send cmd=0x90 + 24-bit address=0 */ - flash_set_address(0); - flash_execute_cmd(CMD_READ_MAN_DEV_ID, - MASK_CMD_RD_2BYTE | MASK(A_SIZE)); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - dest[0] = NPCX_UMA_DB0; - dest[1] = NPCX_UMA_DB1; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); -} - -#endif /* CONFIG_HOSTCMD_FLASH_SPI_INFO */ - -void flash_get_jedec_id(uint8_t *dest) -{ - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read manufacturer and device ID */ - flash_execute_cmd(CMD_READ_ID, MASK_CMD_RD_3BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - dest[0] = NPCX_UMA_DB0; - dest[1] = NPCX_UMA_DB1; - dest[2] = NPCX_UMA_DB2; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); -} - -static void flash_uma_lock(int enable) -{ - if (enable && !all_protected) { - /* - * Store SR1 / SR2 for later use since we're about to lock - * out all access (including read access) to these regs. - */ - saved_sr1 = flash_get_status1(); - saved_sr2 = flash_get_status2(); - } - - all_protected = enable; - UPDATE_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_UMA_LOCK, enable); -} - -static int flash_set_status_for_prot(int reg1, int reg2) -{ - /* - * Writing SR regs will fail if our UMA lock is enabled. If WP - * is deasserted then remove the lock and allow the write. - */ - if (all_protected) { -#ifdef NPCX_INT_FLASH_SUPPORT - if (is_int_flash_protected()) - return EC_ERROR_ACCESS_DENIED; -#endif - - if (crec_flash_get_protect() & EC_FLASH_PROTECT_GPIO_ASSERTED) - return EC_ERROR_ACCESS_DENIED; - flash_uma_lock(0); - } - - /* - * If WP# is active and ec doesn't protect the status registers of - * internal spi-flash, protect it now before setting them. - */ -#ifdef NPCX_INT_FLASH_SUPPORT -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(!gpio_get_level(GPIO_WP_L)); -#endif /*_CONFIG_WP_ACTIVE_HIGH_*/ -#endif - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Enable write */ - flash_write_enable(); - - NPCX_UMA_DB0 = reg1; - NPCX_UMA_DB1 = reg2; - - /* Write status register 1/2 */ - flash_execute_cmd(CMD_WRITE_STATUS_REG, MASK_CMD_WR_2BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - spi_flash_reg_to_protect(reg1, reg2, - &addr_prot_start, &addr_prot_length); - - return EC_SUCCESS; -} - -static int flash_check_prot_range(unsigned int offset, unsigned int bytes) -{ - /* Invalid value */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - /* Check if ranges overlap */ - if (MAX(addr_prot_start, offset) < MIN(addr_prot_start + - addr_prot_length, offset + bytes)) - return EC_ERROR_ACCESS_DENIED; - - return EC_SUCCESS; -} - -static int flash_check_prot_reg(unsigned int offset, unsigned int bytes) -{ - unsigned int start; - unsigned int len; - uint8_t sr1, sr2; - int rv = EC_SUCCESS; - - /* - * If WP# is active and ec doesn't protect the status registers of - * internal spi-flash, protect it now. - */ -#ifdef NPCX_INT_FLASH_SUPPORT -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(!gpio_get_level(GPIO_WP_L)); -#endif /* CONFIG_WP_ACTIVE_HIGH */ -#endif - - sr1 = flash_get_status1(); - sr2 = flash_get_status2(); - - /* Invalid value */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - /* Compute current protect range */ - rv = spi_flash_reg_to_protect(sr1, sr2, &start, &len); - if (rv) - return rv; - - /* Check if ranges overlap */ - if (MAX(start, offset) < MIN(start + len, offset + bytes)) - return EC_ERROR_ACCESS_DENIED; - - return EC_SUCCESS; - -} - -static int flash_write_prot_reg(unsigned int offset, unsigned int bytes, - int hw_protect) -{ - int rv; - uint8_t sr1 = flash_get_status1(); - uint8_t sr2 = flash_get_status2(); - - /* Invalid values */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - /* Compute desired protect range */ - rv = spi_flash_protect_to_reg(offset, bytes, &sr1, &sr2); - if (rv) - return rv; - - if (hw_protect) - sr1 |= SPI_FLASH_SR1_SRP0; - - return flash_set_status_for_prot(sr1, sr2); -} - -static void flash_burst_write(unsigned int dest_addr, unsigned int bytes, - const char *data) -{ - unsigned int i; - /* Chip Select down */ - flash_cs_level(0); - /* Set write address */ - flash_set_address(dest_addr); - /* Start programming */ - flash_execute_cmd(CMD_FLASH_PROGRAM, MASK_CMD_WR_ADR); - for (i = 0; i < bytes; i++) { - flash_execute_cmd(*data, MASK_CMD_WR_ONLY); - data++; - } - /* Chip Select up */ - flash_cs_level(1); -} - -static int flash_program_bytes(uint32_t offset, uint32_t bytes, - const uint8_t *data) -{ - int write_size; - int rv; - - while (bytes > 0) { - /* Write length can not go beyond the end of the flash page */ - write_size = MIN(bytes, CONFIG_FLASH_WRITE_IDEAL_SIZE - - (offset & (CONFIG_FLASH_WRITE_IDEAL_SIZE - 1))); - - /* Enable write */ - rv = flash_write_enable(); - if (rv) - return rv; - - /* Burst UMA transaction */ - flash_burst_write(offset, write_size, data); - - /* Wait write completed */ - rv = flash_wait_ready(); - if (rv) - return rv; - - data += write_size; - offset += write_size; - bytes -= write_size; - } - - return rv; -} - -/*****************************************************************************/ - -int crec_flash_physical_read(int offset, int size, char *data) -{ - int dest_addr = offset; - uint32_t idx; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Chip Select down. */ - flash_cs_level(0); - - /* Set read address */ - flash_set_address(dest_addr); - /* Start fast read - 1110 1001 - EXEC, WR, CMD, ADDR */ - flash_execute_cmd(CMD_FAST_READ, MASK_CMD_ADR_WR); - - /* Burst read transaction */ - for (idx = 0; idx < size; idx++) { - /* 1101 0101 - EXEC, RD, NO CMD, NO ADDR, 4 bytes */ - NPCX_UMA_CTS = MASK_RD_1BYTE; - /* wait for UMA to complete */ - while (IS_BIT_SET(NPCX_UMA_CTS, EXEC_DONE)) - ; - /* Get read transaction results*/ - data[idx] = NPCX_UMA_DB0; - } - - /* Chip Select up */ - flash_cs_level(1); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return EC_SUCCESS; -} - -int crec_flash_physical_write(int offset, int size, const char *data) -{ - int dest_addr = offset; - int write_len; - int rv; - - /* Fail if offset, size, and data aren't at least word-aligned */ - if ((offset | size - | (uint32_t)(uintptr_t)data) & (CONFIG_FLASH_WRITE_SIZE - 1)) - return EC_ERROR_INVAL; - - /* check protection */ - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - - while (size > 0) { - /* First write multiples of 256, then (size % 256) last */ - write_len = ((size % CONFIG_FLASH_WRITE_IDEAL_SIZE) == size) ? - size : CONFIG_FLASH_WRITE_IDEAL_SIZE; - - /* check protection */ - if (flash_check_prot_range(dest_addr, write_len)) { - rv = EC_ERROR_ACCESS_DENIED; - break; - } - - rv = flash_program_bytes(dest_addr, write_len, data); - if (rv) - break; - - data += write_len; - dest_addr += write_len; - size -= write_len; - } - - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return rv; -} - -int crec_flash_physical_erase(int offset, int size) -{ - int rv = EC_SUCCESS; - /* check protection */ - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - - /* Alignment has been checked in upper layer */ - for (; size > 0; size -= CONFIG_FLASH_ERASE_SIZE, - offset += CONFIG_FLASH_ERASE_SIZE) { - /* check protection */ - if (flash_check_prot_range(offset, CONFIG_FLASH_ERASE_SIZE)) { - rv = EC_ERROR_ACCESS_DENIED; - break; - } - - /* - * Reload the watchdog timer, so that erasing many flash pages - * doesn't cause a watchdog reset. May not need this now that - * we're using msleep() below. - */ - watchdog_reload(); - - /* Enable write */ - rv = flash_write_enable(); - if (rv) - break; - - /* Set erase address */ - flash_set_address(offset); - /* Start erase */ - flash_execute_cmd(NPCX_ERASE_COMMAND, MASK_CMD_ADR); - - /* Wait erase completed */ - rv = flash_wait_ready(); - if (rv) - break; - } - - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return rv; -} - -int crec_flash_physical_get_protect(int bank) -{ - uint32_t addr = bank * CONFIG_FLASH_BANK_SIZE; - - return flash_check_prot_reg(addr, CONFIG_FLASH_BANK_SIZE); -} - -uint32_t crec_flash_physical_get_protect_flags(void) -{ - uint32_t flags = 0; - - /* Check if WP region is protected in status register */ - if (flash_check_prot_reg(WP_BANK_OFFSET*CONFIG_FLASH_BANK_SIZE, - WP_BANK_COUNT*CONFIG_FLASH_BANK_SIZE)) - flags |= EC_FLASH_PROTECT_RO_AT_BOOT; - - /* - * TODO: If status register protects a range, but SRP0 is not set, - * flags should indicate EC_FLASH_PROTECT_ERROR_INCONSISTENT. - */ - if (flag_prot_inconsistent) - flags |= EC_FLASH_PROTECT_ERROR_INCONSISTENT; - - /* Read all-protected state from our shadow copy */ - if (all_protected) - flags |= EC_FLASH_PROTECT_ALL_NOW; - - return flags; -} - -int crec_flash_physical_protect_now(int all) -{ - if (all) { - /* - * Set UMA_LOCK bit for locking all UMA transaction. - * But we still can read directly from flash mapping address - */ - flash_uma_lock(1); - } else { - /* TODO: Implement RO "now" protection */ - } - - return EC_SUCCESS; -} - - -int crec_flash_physical_protect_at_boot(uint32_t new_flags) -{ - int ret; - - if ((new_flags & (EC_FLASH_PROTECT_RO_AT_BOOT | - EC_FLASH_PROTECT_ALL_AT_BOOT)) == 0) { - /* Clear protection bits in status register */ - return flash_set_status_for_prot(0, 0); - } - - ret = flash_write_prot_reg(CONFIG_WP_STORAGE_OFF, - CONFIG_WP_STORAGE_SIZE, - 1); - - /* - * Set UMA_LOCK bit for locking all UMA transaction. - * But we still can read directly from flash mapping address - */ - if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT) - flash_uma_lock(1); - - return ret; -} - -uint32_t crec_flash_physical_get_valid_flags(void) -{ - return EC_FLASH_PROTECT_RO_AT_BOOT | - EC_FLASH_PROTECT_RO_NOW | - EC_FLASH_PROTECT_ALL_NOW; -} - -uint32_t crec_flash_physical_get_writable_flags(uint32_t cur_flags) -{ - uint32_t ret = 0; - - /* If RO protection isn't enabled, its at-boot state can be changed. */ - if (!(cur_flags & EC_FLASH_PROTECT_RO_NOW)) - ret |= EC_FLASH_PROTECT_RO_AT_BOOT; - - /* - * If entire flash isn't protected at this boot, it can be enabled if - * the WP GPIO is asserted. - */ - if (!(cur_flags & EC_FLASH_PROTECT_ALL_NOW) && - (cur_flags & EC_FLASH_PROTECT_GPIO_ASSERTED)) - ret |= EC_FLASH_PROTECT_ALL_NOW; - - return ret; -} - -/*****************************************************************************/ -/* High-level APIs */ - -int crec_flash_pre_init(void) -{ - /* - * Protect status registers of internal spi-flash if WP# is active - * during ec initialization. - */ -#ifdef NPCX_INT_FLASH_SUPPORT -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(!gpio_get_level(GPIO_WP_L)); -#endif /*CONFIG_WP_ACTIVE_HIGH */ -#endif - -#if !defined(NPCX_INT_FLASH_SUPPORT) - /* Enable FIU interface */ - flash_pinmux(1); -#endif - -#if defined(CONFIG_EXTERNAL_STORAGE) && !defined(NPCX_INT_FLASH_SUPPORT) - /* Disable tristate all the time */ - CLEAR_BIT(NPCX_DEVCNT, NPCX_DEVCNT_F_SPI_TRIS); -#endif - - /* Initialize UMA to unlocked */ - flash_uma_lock(0); - return EC_SUCCESS; -} - -void crec_flash_lock_mapped_storage(int lock) -{ - if (lock) - mutex_lock(&flash_lock); - else - mutex_unlock(&flash_lock); -} - -/*****************************************************************************/ -/* Host commands */ - -#if defined(CONFIG_HOSTCMD_FLASH_SPI_INFO) && !defined(BOARD_NPCX_EVB) -/* NPCX EVB uses implementation from spi_flash.c */ - -static enum ec_status flash_command_spi_info(struct host_cmd_handler_args *args) -{ - struct ec_response_flash_spi_info *r = args->response; - - flash_get_jedec_id(r->jedec); - r->reserved0 = 0; - flash_get_mfr_dev_id(r->mfr_dev_id); - r->sr1 = flash_get_status1(); - r->sr2 = flash_get_status2(); - - args->response_size = sizeof(*r); - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_FLASH_SPI_INFO, - flash_command_spi_info, - EC_VER_MASK(0)); - -#endif - -#ifdef CONFIG_CMD_FLASH_TRISTATE -#ifdef NPCX_INT_FLASH_SUPPORT -#error "Flash tristate is not relevant when internal flash is used." -#endif -static void flash_tristate(int enable) -{ - /* Enable/Disable FIU pins to tri-state */ - UPDATE_BIT(NPCX_DEVCNT, NPCX_DEVCNT_F_SPI_TRIS, enable); -} - -static int flash_spi_sel_lock(int enable) -{ - /* - * F_SPI_QUAD, F_SPI_CS1_1/2, F_SPI_TRIS become read-only - * if this bit is set - */ - UPDATE_BIT(NPCX_DEV_CTL4, NPCX_DEV_CTL4_F_SPI_SLLK, enable); - return IS_BIT_SET(NPCX_DEV_CTL4, NPCX_DEV_CTL4_F_SPI_SLLK); -} - -/*****************************************************************************/ -/* Console commands */ - -static int command_flash_spi_sel_lock(int argc, char **argv) -{ - int ena; - - if (argc > 1) { - if (!parse_bool(argv[1], &ena)) - return EC_ERROR_PARAM1; - ena = flash_spi_sel_lock(ena); - ccprintf("Enabled: %d\n", ena); - } - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(flash_spi_lock, command_flash_spi_sel_lock, - "[on | off]", - "Lock spi flash interface selection"); - -static int command_flash_tristate(int argc, char **argv) -{ - int ena; - - if (argc > 1) { - if (!parse_bool(argv[1], &ena)) - return EC_ERROR_PARAM1; - flash_tristate(ena); - ccprintf("Enabled: %d\n", ena); - } - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(flash_tristate, command_flash_tristate, - "[on | off]", - "Tristate spi flash pins"); -#endif /* CONFIG_CMD_FLASH_TRISTATE */ - -static int command_flash_chip(int argc, char **argv) -{ - uint8_t jedec_id[3]; - - ccprintf("Status 1: 0x%02x, Status 2: 0x%02x\n", flash_get_status1(), - flash_get_status2()); - - flash_get_jedec_id(jedec_id); - ccprintf("Manufacturer: 0x%02x, DID: 0x%02x%02x\n", jedec_id[0], - jedec_id[1], jedec_id[2]); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(flashchip, command_flash_chip, - NULL, - "Print flash chip info"); diff --git a/chip/npcx/gpio-npcx5.c b/chip/npcx/gpio-npcx5.c deleted file mode 100644 index e1d13c98d1..0000000000 --- a/chip/npcx/gpio-npcx5.c +++ /dev/null @@ -1,198 +0,0 @@ -/* Copyright 2020 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. - */ - -/* GPIO module for Chrome EC */ - -#include "clock.h" -#include "common.h" -#include "ec_commands.h" -#include "gpio_chip.h" -#include "hooks.h" -#include "host_command.h" -#include "lpc_chip.h" -#include "registers.h" -#include "task.h" - -/* - * List of GPIO IRQs to enable. Don't automatically enable interrupts for - * the keyboard input GPIO bank - that's handled separately. Of course the - * bank is different for different systems. - */ -static void gpio_init(void) -{ - /* Enable IRQs now that pins are set up */ - task_enable_irq(NPCX_IRQ_MTC_WKINTAD_0); - task_enable_irq(NPCX_IRQ_WKINTEFGH_0); - task_enable_irq(NPCX_IRQ_WKINTC_0); - task_enable_irq(NPCX_IRQ_TWD_WKINTB_0); - task_enable_irq(NPCX_IRQ_WKINTA_1); - task_enable_irq(NPCX_IRQ_WKINTB_1); -#ifndef HAS_TASK_KEYSCAN - task_enable_irq(NPCX_IRQ_KSI_WKINTC_1); -#endif - task_enable_irq(NPCX_IRQ_WKINTD_1); - task_enable_irq(NPCX_IRQ_WKINTE_1); - task_enable_irq(NPCX_IRQ_WKINTF_1); - task_enable_irq(NPCX_IRQ_WKINTG_1); - task_enable_irq(NPCX_IRQ_WKINTH_1); -#if defined(CHIP_FAMILY_NPCX7) - task_enable_irq(NPCX_IRQ_WKINTFG_2); -#endif -} -DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT); - -/** - * Handlers for each GPIO port. These read and clear the interrupt bits for - * the port, then call the master handler above. - */ - -#define GPIO_IRQ_FUNC(_irq_func, wui_int) \ -void _irq_func(void) \ -{ \ - gpio_interrupt(wui_int); \ -} - -/* If we need to handle the other type interrupts except GPIO, add code here */ -void __gpio_wk0efgh_interrupt(void) -{ - if (IS_ENABLED(CONFIG_HOSTCMD_X86)) { - /* Pending bit 7 or 6 or 5? */ - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6) && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 6)) { - /* Disable host wake-up */ - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6); - /* Clear pending bit of WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_5), 6); - return; - } - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) { - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 5) - && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 5)) { - espi_espirst_handler(); - return; - } - } else { - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 7) - && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 7)) { - lpc_lreset_pltrst_handler(); - return; - } - } - } - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_5)); - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_6)); - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_7)); - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_8)); -} - -#ifdef CONFIG_HOSTCMD_RTC -static void set_rtc_host_event(void) -{ - host_set_single_event(EC_HOST_EVENT_RTC); -} -DECLARE_DEFERRED(set_rtc_host_event); -#endif - -void __gpio_rtc_interrupt(void) -{ - /* Check pending bit 7 */ -#ifdef CONFIG_HOSTCMD_RTC - if (NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_4) & 0x80) { - /* Clear pending bit for WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_4), 7); - hook_call_deferred(&set_rtc_host_event_data, 0); - return; - } -#endif -#if defined(CHIP_FAMILY_NPCX7) && defined(CONFIG_LOW_POWER_IDLE) && \ - (CONFIG_CONSOLE_UART == 1) - /* Handle the interrupt from UART wakeup event */ - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_1), 6) && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_1), 6)) { - /* - * Disable WKEN bit to avoid the other unnecessary interrupts - * from the coming data bits after the start bit. (Pending bit - * of CR_SIN is set when a high-to-low transaction occurs.) - */ - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_1), 6); - /* Clear pending bit for WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_1), 6); - /* Notify the clock module that the console is in use. */ - clock_refresh_console_in_use(); - return; - } -#endif - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_1)); - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_4)); -} - -void __gpio_wk1h_interrupt(void) -{ -#if defined(CHIP_FAMILY_NPCX7) && defined(CONFIG_LOW_POWER_IDLE) && \ - (CONFIG_CONSOLE_UART == 0) - /* Handle the interrupt from UART wakeup event */ - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_1, MIWU_GROUP_8), 7) && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_1, MIWU_GROUP_8), 7)) { - /* - * Disable WKEN bit to avoid the other unnecessary interrupts - * from the coming data bits after the start bit. (Pending bit - * of CR_SIN is set when a high-to-low transaction occurs.) - */ - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_1, MIWU_GROUP_8), 7); - /* Clear pending bit for WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_1, MIWU_GROUP_8), 7); - /* Notify the clock module that the console is in use. */ - clock_refresh_console_in_use(); - } else -#endif - gpio_interrupt(WUI_INT(MIWU_TABLE_1, MIWU_GROUP_8)); -} - -GPIO_IRQ_FUNC(__gpio_wk0b_interrupt, WUI_INT(MIWU_TABLE_0, MIWU_GROUP_2)); -GPIO_IRQ_FUNC(__gpio_wk0c_interrupt, WUI_INT(MIWU_TABLE_0, MIWU_GROUP_3)); -GPIO_IRQ_FUNC(__gpio_wk1a_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_1)); -GPIO_IRQ_FUNC(__gpio_wk1b_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_2)); -#ifndef HAS_TASK_KEYSCAN -/* Declare GPIO irq functions for KSI pins if there's no keyboard scan task, */ -GPIO_IRQ_FUNC(__gpio_wk1c_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_3)); -#endif -GPIO_IRQ_FUNC(__gpio_wk1d_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_4)); -GPIO_IRQ_FUNC(__gpio_wk1e_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_5)); -GPIO_IRQ_FUNC(__gpio_wk1f_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_6)); -GPIO_IRQ_FUNC(__gpio_wk1g_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_7)); -#if defined(CHIP_FAMILY_NPCX7) -GPIO_IRQ_FUNC(__gpio_wk2fg_interrupt, WUI_INT(MIWU_TABLE_2, MIWU_GROUP_6)); -#endif - -DECLARE_IRQ(NPCX_IRQ_MTC_WKINTAD_0, __gpio_rtc_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_TWD_WKINTB_0, __gpio_wk0b_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTC_0, __gpio_wk0c_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTEFGH_0, __gpio_wk0efgh_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTA_1, __gpio_wk1a_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTB_1, __gpio_wk1b_interrupt, 3); -#ifndef HAS_TASK_KEYSCAN -DECLARE_IRQ(NPCX_IRQ_KSI_WKINTC_1, __gpio_wk1c_interrupt, 3); -#endif -DECLARE_IRQ(NPCX_IRQ_WKINTD_1, __gpio_wk1d_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTE_1, __gpio_wk1e_interrupt, 3); -#ifdef CONFIG_HOSTCMD_SHI -/* - * HACK: Make CS GPIO P2 to improve SHI reliability. - * TODO: Increase CS-assertion-to-transaction-start delay on host to - * accommodate P3 CS interrupt. - */ -DECLARE_IRQ(NPCX_IRQ_WKINTF_1, __gpio_wk1f_interrupt, 2); -#else -DECLARE_IRQ(NPCX_IRQ_WKINTF_1, __gpio_wk1f_interrupt, 3); -#endif -DECLARE_IRQ(NPCX_IRQ_WKINTG_1, __gpio_wk1g_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTH_1, __gpio_wk1h_interrupt, 3); -#if defined(CHIP_FAMILY_NPCX7) -DECLARE_IRQ(NPCX_IRQ_WKINTFG_2, __gpio_wk2fg_interrupt, 3); -#endif - -#undef GPIO_IRQ_FUNC diff --git a/chip/npcx/gpio-npcx7.c b/chip/npcx/gpio-npcx7.c deleted file mode 120000 index 39b939f44c..0000000000 --- a/chip/npcx/gpio-npcx7.c +++ /dev/null @@ -1 +0,0 @@ -gpio-npcx5.c
\ No newline at end of file diff --git a/chip/npcx/gpio-npcx9.c b/chip/npcx/gpio-npcx9.c deleted file mode 100644 index 2bb4ae085c..0000000000 --- a/chip/npcx/gpio-npcx9.c +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright 2020 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. - */ - -/* GPIO module for Chrome EC */ - -#include "clock.h" -#include "common.h" -#include "ec_commands.h" -#include "gpio_chip.h" -#include "hooks.h" -#include "host_command.h" -#include "lct_chip.h" -#include "lpc_chip.h" -#include "registers.h" -#include "task.h" - -/* - * List of GPIO IRQs to enable. Don't automatically enable interrupts for - * the keyboard input GPIO bank - that's handled separately. Of course the - * bank is different for different systems. - */ -static void gpio_init(void) -{ - /* Enable IRQs now that pins are set up */ - task_enable_irq(NPCX_IRQ_CR_SIN2_WKINTA_0); - task_enable_irq(NPCX_IRQ_TWD_WKINTB_0); - task_enable_irq(NPCX_IRQ_WKINTC_0); - task_enable_irq(NPCX_IRQ_MTC_WKINTD_0); - task_enable_irq(NPCX_IRQ_WKINTE_0); - task_enable_irq(NPCX_IRQ_WKINTF_0); - task_enable_irq(NPCX_IRQ_WKINTG_0); - task_enable_irq(NPCX_IRQ_WKINTH_0); - task_enable_irq(NPCX_IRQ_WKINTA_1); - task_enable_irq(NPCX_IRQ_WKINTB_1); -#ifndef HAS_TASK_KEYSCAN - task_enable_irq(NPCX_IRQ_KSI_WKINTC_1); -#endif - task_enable_irq(NPCX_IRQ_WKINTD_1); - task_enable_irq(NPCX_IRQ_WKINTE_1); - task_enable_irq(NPCX_IRQ_WKINTF_1); - task_enable_irq(NPCX_IRQ_WKINTG_1); - task_enable_irq(NPCX_IRQ_WKINTH_1); - task_enable_irq(NPCX_IRQ_LCT_WKINTF_2); -} -DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT); - -/** - * Handlers for each GPIO port. These read and clear the interrupt bits for - * the port, then call the master handler above. - */ - -#define GPIO_IRQ_FUNC(_irq_func, wui_int) \ -void _irq_func(void) \ -{ \ - gpio_interrupt(wui_int); \ -} - -/* If we need to handle the other type interrupts except GPIO, add code here */ -void __gpio_host_interrupt(void) -{ - if (IS_ENABLED(CONFIG_HOSTCMD_X86)) { - /* Pending bit 7 or 6 or 5? */ - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6) && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 6)) { - /* Disable host wake-up */ - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6); - /* Clear pending bit of WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_5), 6); - return; - } - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) { - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 5) - && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 5)) { - espi_espirst_handler(); - return; - } - } else { - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 7) - && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 7)) { - lpc_lreset_pltrst_handler(); - return; - } - } - } - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_5)); -} - -#ifdef CONFIG_HOSTCMD_RTC -static void set_rtc_host_event(void) -{ - host_set_single_event(EC_HOST_EVENT_RTC); -} -DECLARE_DEFERRED(set_rtc_host_event); -#endif - -void __gpio_rtc_interrupt(void) -{ - /* Check pending bit 7 */ -#ifdef CONFIG_HOSTCMD_RTC - if (NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_4) & 0x80) { - /* Clear pending bit for WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_4), 7); - hook_call_deferred(&set_rtc_host_event_data, 0); - return; - } -#endif - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_4)); -} -void __gpio_cr_sin2_interrupt(void) -{ -#if defined(CONFIG_LOW_POWER_IDLE) && (CONFIG_CONSOLE_UART == 1) - /* Handle the interrupt from UART wakeup event */ - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_1), 6) && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_1), 6)) { - /* - * Disable WKEN bit to avoid the other unnecessary interrupts - * from the coming data bits after the start bit. (Pending bit - * of CR_SIN is set when a high-to-low transaction occurs.) - */ - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_1), 6); - /* Clear pending bit for WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_1), 6); - /* Notify the clock module that the console is in use. */ - clock_refresh_console_in_use(); - return; - } -#endif - gpio_interrupt(WUI_INT(MIWU_TABLE_0, MIWU_GROUP_1)); - -} - -void __gpio_wk1h_interrupt(void) -{ -#if defined(CONFIG_LOW_POWER_IDLE) && (CONFIG_CONSOLE_UART == 0) - /* Handle the interrupt from UART wakeup event */ - if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_1, MIWU_GROUP_8), 7) && - IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_1, MIWU_GROUP_8), 7)) { - /* - * Disable WKEN bit to avoid the other unnecessary interrupts - * from the coming data bits after the start bit. (Pending bit - * of CR_SIN is set when a high-to-low transaction occurs.) - */ - CLEAR_BIT(NPCX_WKEN(MIWU_TABLE_1, MIWU_GROUP_8), 7); - /* Clear pending bit for WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_1, MIWU_GROUP_8), 7); - /* Notify the clock module that the console is in use. */ - clock_refresh_console_in_use(); - } else -#endif - gpio_interrupt(WUI_INT(MIWU_TABLE_1, MIWU_GROUP_8)); -} - -void __gpio_lct_interrupt(void) -{ - if (NPCX_WKPND(MIWU_TABLE_2, MIWU_GROUP_6) & LCT_WUI_MASK) { - NPCX_WKPCL(MIWU_TABLE_2, MIWU_GROUP_6) |= LCT_WUI_MASK; - npcx_lct_clear_event(); - return; - } - gpio_interrupt(WUI_INT(MIWU_TABLE_2, MIWU_GROUP_6)); -} - -GPIO_IRQ_FUNC(__gpio_wk0b_interrupt, WUI_INT(MIWU_TABLE_0, MIWU_GROUP_2)); -GPIO_IRQ_FUNC(__gpio_wk0c_interrupt, WUI_INT(MIWU_TABLE_0, MIWU_GROUP_3)); -GPIO_IRQ_FUNC(__gpio_wk0f_interrupt, WUI_INT(MIWU_TABLE_0, MIWU_GROUP_6)); -GPIO_IRQ_FUNC(__gpio_wk0g_interrupt, WUI_INT(MIWU_TABLE_0, MIWU_GROUP_7)); -GPIO_IRQ_FUNC(__gpio_wk0h_interrupt, WUI_INT(MIWU_TABLE_0, MIWU_GROUP_8)); -GPIO_IRQ_FUNC(__gpio_wk1a_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_1)); -GPIO_IRQ_FUNC(__gpio_wk1b_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_2)); -#ifndef HAS_TASK_KEYSCAN -/* Declare GPIO irq functions for KSI pins if there's no keyboard scan task, */ -GPIO_IRQ_FUNC(__gpio_wk1c_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_3)); -#endif -GPIO_IRQ_FUNC(__gpio_wk1d_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_4)); -GPIO_IRQ_FUNC(__gpio_wk1e_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_5)); -GPIO_IRQ_FUNC(__gpio_wk1f_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_6)); -GPIO_IRQ_FUNC(__gpio_wk1g_interrupt, WUI_INT(MIWU_TABLE_1, MIWU_GROUP_7)); -GPIO_IRQ_FUNC(__gpio_wk2fg_interrupt, WUI_INT(MIWU_TABLE_2, MIWU_GROUP_6)); - -DECLARE_IRQ(NPCX_IRQ_CR_SIN2_WKINTA_0, __gpio_cr_sin2_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_TWD_WKINTB_0, __gpio_wk0b_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTC_0, __gpio_wk0c_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_MTC_WKINTD_0, __gpio_rtc_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTE_0, __gpio_host_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTF_0, __gpio_wk0f_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTG_0, __gpio_wk0g_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTH_0, __gpio_wk0h_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTA_1, __gpio_wk1a_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTB_1, __gpio_wk1b_interrupt, 3); -#ifndef HAS_TASK_KEYSCAN -DECLARE_IRQ(NPCX_IRQ_KSI_WKINTC_1, __gpio_wk1c_interrupt, 3); -#endif -DECLARE_IRQ(NPCX_IRQ_WKINTD_1, __gpio_wk1d_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTE_1, __gpio_wk1e_interrupt, 3); -#ifdef CONFIG_HOSTCMD_SHI -/* - * HACK: Make CS GPIO P2 to improve SHI reliability. - * TODO: Increase CS-assertion-to-transaction-start delay on host to - * accommodate P3 CS interrupt. - */ -DECLARE_IRQ(NPCX_IRQ_WKINTF_1, __gpio_wk1f_interrupt, 2); -#else -DECLARE_IRQ(NPCX_IRQ_WKINTF_1, __gpio_wk1f_interrupt, 3); -#endif -DECLARE_IRQ(NPCX_IRQ_WKINTG_1, __gpio_wk1g_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_WKINTH_1, __gpio_wk1h_interrupt, 3); -DECLARE_IRQ(NPCX_IRQ_LCT_WKINTF_2, __gpio_lct_interrupt, 3); - -#undef GPIO_IRQ_FUNC diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c deleted file mode 100644 index e740f0aa9f..0000000000 --- a/chip/npcx/gpio.c +++ /dev/null @@ -1,765 +0,0 @@ -/* Copyright 2014 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. - */ - -/* GPIO module for Chrome EC */ - -#include "common.h" -#include "gpio.h" -#include "gpio_chip.h" -#include "i2c.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "system.h" -#include "system_chip.h" -#include "ec_commands.h" -#include "host_command.h" -#include "hwtimer_chip.h" - -#if !(DEBUG_GPIO) -#define CPUTS(...) -#define CPRINTS(...) -#else -#define CPUTS(outstr) cputs(CC_GPIO, outstr) -#define CPRINTS(format, args...) cprints(CC_GPIO, format, ## args) -#endif - -/* Constants for GPIO interrupt mapping */ -#define GPIO_INT(name, pin, flags, signal) NPCX_WUI_GPIO_##pin, -#ifdef CONFIG_LOW_POWER_IDLE -/* Extend gpio_wui_table for the bypass of better power consumption */ -#define GPIO(name, pin, flags) NPCX_WUI_GPIO_##pin, -#define UNIMPLEMENTED(name) WUI_NONE, -#else -/* Ignore GPIO and UNIMPLEMENTED definitions if not using lower power idle */ -#define GPIO(name, pin, flags) -#define UNIMPLEMENTED(name) -#endif -static const struct npcx_wui gpio_wui_table[] = { - #include "gpio.wrap" -}; - -struct npcx_gpio { - uint8_t port : 4; - uint8_t bit : 3; - uint8_t valid : 1; -}; - -BUILD_ASSERT(sizeof(struct npcx_gpio) == 1); - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 -struct npcx_alt { - uint8_t group; - uint8_t bit : 3; - uint8_t inverted : 1; - uint8_t reserved : 4; -}; -#else -struct npcx_alt { - uint8_t group : 4; - uint8_t bit : 3; - uint8_t inverted : 1; -}; -#endif - -struct gpio_alt_map { - struct npcx_gpio gpio; - struct npcx_alt alt; -}; - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 -BUILD_ASSERT(sizeof(struct gpio_alt_map) == 3); -#else -BUILD_ASSERT(sizeof(struct gpio_alt_map) == 2); -#endif - -/* Constants for GPIO alternative mapping */ -const __const_data struct gpio_alt_map gpio_alt_table[] = NPCX_ALT_TABLE; - -struct gpio_lvol_item { - struct npcx_gpio lvol_gpio[8]; -}; - -/* Constants for GPIO low-voltage mapping */ -const struct gpio_lvol_item gpio_lvol_table[] = NPCX_LVOL_TABLE; - -/*****************************************************************************/ -/* Internal functions */ - -static int gpio_match(uint8_t port, uint8_t bit, struct npcx_gpio gpio) -{ - return (gpio.valid && (gpio.port == port) && (gpio.bit == bit)); -} - -#ifdef CONFIG_CMD_GPIO_EXTENDED -static uint8_t gpio_is_alt_sel(uint8_t port, uint8_t bit) -{ - struct gpio_alt_map const *map; - uint8_t alt_mask, devalt; - - for (map = ARRAY_BEGIN(gpio_alt_table); - map < ARRAY_END(gpio_alt_table); - map++) { - if (gpio_match(port, bit, map->gpio)) { - alt_mask = 1 << map->alt.bit; - devalt = NPCX_DEVALT(map->alt.group); - /* - * alt.inverted == 0: - * !!(devalt & alt_mask) == 0 -> GPIO - * !!(devalt & alt_mask) == 1 -> Alternate - * alt.inverted == 1: - * !!(devalt & alt_mask) == 0 -> Alternate - * !!(devalt & alt_mask) == 1 -> GPIO - */ - return !!(devalt & alt_mask) ^ map->alt.inverted; - } - } - return 0; -} -#endif - -static int gpio_alt_sel(uint8_t port, uint8_t bit, - enum gpio_alternate_func func) -{ - struct gpio_alt_map const *map; - - for (map = ARRAY_BEGIN(gpio_alt_table); - map < ARRAY_END(gpio_alt_table); - map++) { - if (gpio_match(port, bit, map->gpio)) { - uint8_t alt_mask = 1 << map->alt.bit; - - /* - * func < GPIO_ALT_FUNC_DEFAULT -> GPIO functionality - * map->alt.inverted -> Set DEVALT bit for GPIO - */ - if ((func < GPIO_ALT_FUNC_DEFAULT) ^ map->alt.inverted) - NPCX_DEVALT(map->alt.group) &= ~alt_mask; - else - NPCX_DEVALT(map->alt.group) |= alt_mask; - - return 1; - } - } - - if (func > GPIO_ALT_FUNC_DEFAULT) - CPRINTS("Warn! No alter func in port%d, pin%d", port, bit); - - return -1; -} - -/* Set interrupt type for GPIO input */ -static void gpio_interrupt_type_sel(enum gpio_signal signal, uint32_t flags) -{ - uint8_t table, group, pmask; - - if (signal >= GPIO_IH_COUNT) - return; - - table = gpio_wui_table[signal].table; - group = gpio_wui_table[signal].group; - pmask = 1 << gpio_wui_table[signal].bit; - - ASSERT(flags & GPIO_INT_ANY); - - /* Handle interrupt for level trigger */ - if ((flags & GPIO_INT_F_HIGH) || (flags & GPIO_INT_F_LOW)) { - /* Set detection mode to level */ - NPCX_WKMOD(table, group) |= pmask; - /* Handle interrupting on level high */ - if (flags & GPIO_INT_F_HIGH) - NPCX_WKEDG(table, group) &= ~pmask; - /* Handle interrupting on level low */ - else if (flags & GPIO_INT_F_LOW) - NPCX_WKEDG(table, group) |= pmask; - } - /* Handle interrupt for edge trigger */ - else { - /* Set detection mode to edge */ - NPCX_WKMOD(table, group) &= ~pmask; - /* Handle interrupting on both edges */ - if ((flags & GPIO_INT_F_RISING) && - (flags & GPIO_INT_F_FALLING)) { - /* Enable any edge */ - NPCX_WKAEDG(table, group) |= pmask; - } - /* Handle interrupting on rising edge */ - else if (flags & GPIO_INT_F_RISING) { - /* Disable any edge */ - NPCX_WKAEDG(table, group) &= ~pmask; - NPCX_WKEDG(table, group) &= ~pmask; - } - /* Handle interrupting on falling edge */ - else if (flags & GPIO_INT_F_FALLING) { - /* Disable any edge */ - NPCX_WKAEDG(table, group) &= ~pmask; - NPCX_WKEDG(table, group) |= pmask; - } - } - - /* Enable wake-up input sources */ - NPCX_WKINEN(table, group) |= pmask; - /* - * Clear pending bit since it might be set - * if WKINEN bit is changed. - */ - NPCX_WKPCL(table, group) |= pmask; - - /* No support analog mode */ -} - -#ifdef CONFIG_CMD_GPIO_EXTENDED -static uint8_t gpio_is_low_voltage_level_sel(uint8_t port, uint8_t bit) -{ - int i, j; - - for (i = 0; i < ARRAY_SIZE(gpio_lvol_table); i++) { - const struct npcx_gpio *gpio = gpio_lvol_table[i].lvol_gpio; - - for (j = 0; j < ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio); j++) { - if (gpio_match(port, bit, gpio[j])) - return IS_BIT_SET(NPCX_LV_GPIO_CTL(i), j); - } - } - return 0; -} -#endif - -/* Select low voltage detection level */ -void gpio_low_voltage_level_sel(uint8_t port, uint8_t bit, uint8_t low_voltage) -{ - int i, j; - - for (i = 0; i < ARRAY_SIZE(gpio_lvol_table); i++) { - const struct npcx_gpio *gpio = gpio_lvol_table[i].lvol_gpio; - - for (j = 0; j < ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio); j++) { - if (gpio_match(port, bit, gpio[j])) { - if (low_voltage) - /* Select vol-detect level for 1.8V */ - SET_BIT(NPCX_LV_GPIO_CTL(i), j); - else - /* Select vol-detect level for 3.3V */ - CLEAR_BIT(NPCX_LV_GPIO_CTL(i), j); - return; - } - } - } - - if (low_voltage) - CPRINTS("Warn! No low voltage support in port:0x%x, bit:%d", - port, bit); -} - -/* Set the low voltage detection level by mask */ -static void gpio_low_vol_sel_by_mask(uint8_t p, uint8_t mask, uint8_t low_vol) -{ - int bit; - uint32_t lv_mask = mask; - - while (lv_mask) { - bit = get_next_bit(&lv_mask); - gpio_low_voltage_level_sel(p, bit, low_vol); - }; -} -/* The bypass of low voltage IOs for better power consumption */ -#ifdef CONFIG_LOW_POWER_IDLE -static int gpio_is_i2c_pin(enum gpio_signal signal) -{ - int i; - - for (i = 0; i < i2c_ports_used; i++) - if (i2c_ports[i].scl == signal || i2c_ports[i].sda == signal) - return 1; - - return 0; -} - -static void gpio_enable_wake_up_input(enum gpio_signal signal, int enable) -{ - const struct npcx_wui *wui = gpio_wui_table + signal; - - /* Is it a valid wui mapping item? */ - if (wui->table != MIWU_TABLE_COUNT) { - /* Turn on/off input io buffer by WKINENx registers */ - if (enable) - SET_BIT(NPCX_WKINEN(wui->table, wui->group), wui->bit); - else - CLEAR_BIT(NPCX_WKINEN(wui->table, wui->group), - wui->bit); - } -} - -void gpio_enable_1p8v_i2c_wake_up_input(int enable) -{ - int i; - - /* Set input buffer of 1.8V i2c ports. */ - for (i = 0; i < i2c_ports_used; i++) { - if (gpio_list[i2c_ports[i].scl].flags & GPIO_SEL_1P8V) - gpio_enable_wake_up_input(i2c_ports[i].scl, enable); - if (gpio_list[i2c_ports[i].sda].flags & GPIO_SEL_1P8V) - gpio_enable_wake_up_input(i2c_ports[i].sda, enable); - } -} -#endif - -/* - * Make sure the bit depth of low voltage register. - */ -BUILD_ASSERT(ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio) == 8); - -/*****************************************************************************/ -/* IC specific low-level driver */ - -void gpio_set_alternate_function(uint32_t port, uint32_t mask, - enum gpio_alternate_func func) -{ - /* Enable alternative pins by func */ - int pin; - - /* check each bit from mask */ - for (pin = 0; pin < 8; pin++) - if (mask & BIT(pin)) - gpio_alt_sel(port, pin, func); -} - -test_mockable int gpio_get_level(enum gpio_signal signal) -{ - ASSERT(signal_is_gpio(signal)); - - return !!(NPCX_PDIN(gpio_list[signal].port) & gpio_list[signal].mask); -} - -void gpio_set_level(enum gpio_signal signal, int value) -{ - ASSERT(signal_is_gpio(signal)); - - if (value) - NPCX_PDOUT(gpio_list[signal].port) |= gpio_list[signal].mask; - else - NPCX_PDOUT(gpio_list[signal].port) &= ~gpio_list[signal].mask; -} - -#ifdef CONFIG_GPIO_GET_EXTENDED -int gpio_get_flags_by_mask(uint32_t port, uint32_t mask) -{ - uint32_t flags = 0; - - if (NPCX_PDIR(port) & mask) - flags |= GPIO_OUTPUT; - else - flags |= GPIO_INPUT; - - if (NPCX_PDIN(port) & mask) - flags |= GPIO_HIGH; - else - flags |= GPIO_LOW; - - if (NPCX_PTYPE(port) & mask) - flags |= GPIO_OPEN_DRAIN; - - /* If internal pulling is enabled */ - if (NPCX_PPULL(port) & mask) { - if (NPCX_PPUD(port) & mask) - flags |= GPIO_PULL_DOWN; - else - flags |= GPIO_PULL_UP; - } - - if (gpio_is_alt_sel(port, GPIO_MASK_TO_NUM(mask))) - flags |= GPIO_ALTERNATE; - - if (gpio_is_low_voltage_level_sel(port, GPIO_MASK_TO_NUM(mask))) - flags |= GPIO_SEL_1P8V; - - if (NPCX_PLOCK_CTL(port) & mask) - flags |= GPIO_LOCKED; - - return flags; -} -#endif - -void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) -{ - /* If all GPIO pins are locked, return directly */ -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - if ((NPCX_PLOCK_CTL(port) & mask) == mask) - return; -#endif - - /* - * Configure pin as input, if requested. Output is configured only - * after setting all other attributes, so as not to create a - * temporary incorrect logic state 0:input 1:output - */ - if (!(flags & GPIO_OUTPUT)) - NPCX_PDIR(port) &= ~mask; - - /* Select open drain 0:push-pull 1:open-drain */ - if (flags & GPIO_OPEN_DRAIN) - NPCX_PTYPE(port) |= mask; - else - NPCX_PTYPE(port) &= ~mask; - - /* Select pull-up/down of GPIO 0:pull-up 1:pull-down */ - if (flags & GPIO_PULL_UP) { - if (flags & GPIO_SEL_1P8V) { - CPRINTS("Warn! enable internal PU and low voltage mode" - " at the same time is illegal. port 0x%x, mask 0x%x", - port, mask); - } else { - NPCX_PPUD(port) &= ~mask; - NPCX_PPULL(port) |= mask; /* enable pull down/up */ - } - } else if (flags & GPIO_PULL_DOWN) { - NPCX_PPUD(port) |= mask; - NPCX_PPULL(port) |= mask; /* enable pull down/up */ - } else { - /* No pull up/down */ - NPCX_PPULL(port) &= ~mask; /* disable pull down/up */ - } - - /* 1.8V low voltage select */ - if (flags & GPIO_SEL_1P8V) { - /* - * Set IO type to open-drain before selecting low-voltage level - */ - NPCX_PTYPE(port) |= mask; - gpio_low_vol_sel_by_mask(port, mask, 1); - } else - gpio_low_vol_sel_by_mask(port, mask, 0); - - /* Set up interrupt type */ - if (flags & GPIO_INT_ANY) { - const struct gpio_info *g = gpio_list; - enum gpio_signal gpio_int; - - /* Find gpio signal in GPIO_INTs by port and mask */ - for (gpio_int = 0; gpio_int < GPIO_IH_COUNT; gpio_int++, g++) - if ((g->port == port) && (g->mask & mask)) - gpio_interrupt_type_sel(gpio_int, flags); - } - - /* Set level 0:low 1:high*/ - if (flags & GPIO_HIGH) - NPCX_PDOUT(port) |= mask; - else if (flags & GPIO_LOW) - NPCX_PDOUT(port) &= ~mask; - - /* Configure pin as output, if requested 0:input 1:output */ - if (flags & GPIO_OUTPUT) - NPCX_PDIR(port) |= mask; - - /* Lock GPIO output and configuration if need */ -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - if (flags & GPIO_LOCKED) - NPCX_PLOCK_CTL(port) |= mask; -#endif -} - -int gpio_enable_interrupt(enum gpio_signal signal) -{ - struct npcx_wui wui; - - /* Fail if not an interrupt handler */ - if (signal >= GPIO_IH_COUNT) - return EC_ERROR_PARAM1; - - wui = gpio_wui_table[signal]; - /* Set MIWU enable bit */ - NPCX_WKEN(wui.table, wui.group) |= 1 << wui.bit; - - return EC_SUCCESS; -} - -int gpio_disable_interrupt(enum gpio_signal signal) -{ - struct npcx_wui wui; - - /* Fail if not an interrupt handler */ - if (signal >= GPIO_IH_COUNT) - return EC_ERROR_PARAM1; - - wui = gpio_wui_table[signal]; - NPCX_WKEN(wui.table, wui.group) &= ~(1 << wui.bit); - - return EC_SUCCESS; -} - -int gpio_clear_pending_interrupt(enum gpio_signal signal) -{ - struct npcx_wui wui; - - /* Fail if not an interrupt handler */ - if (signal >= GPIO_IH_COUNT) - return EC_ERROR_PARAM1; - - wui = gpio_wui_table[signal]; - NPCX_WKPCL(wui.table, wui.group) |= 1 << wui.bit; - - return EC_SUCCESS; -} - -void gpio_pre_init(void) -{ - const struct gpio_info *g = gpio_list; - const struct unused_pin_info *u = unused_pin_list; - int is_warm; - int flags; - int i, j; - - system_check_bbram_on_reset(); - is_warm = system_is_reboot_warm(); - - /* - * 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: (1) power-on reset, (2) reset-pin reset. If we add - * a delay between reset (1) and configuring GPIO output levels, then - * reset (2) will happen before the end of the delay so we avoid extra - * output toggles. - * - * Make sure to set up the timer before using udelay(). - */ - if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON) && - system_get_reset_flags() & EC_RESET_FLAG_INITIAL_PWR) { - __hw_early_init_hwtimer(0); - udelay(2 * SECOND); - /* Shouldn't get here, but proceeding anyway... */ - } - -#ifdef CHIP_FAMILY_NPCX7 - /* - * TODO: Set bit 7 of DEVCNT again for npcx7 series. Please see Errata - * for more information. It will be fixed in next chip. - */ - SET_BIT(NPCX_DEVCNT, 7); -#endif -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - /* Lock VCC_RST# alternative bit in case switch to GPO77 unexpectedly */ - SET_BIT(NPCX_DEV_CTL4, NPCX_DEV_CTL4_VCC1_RST_LK); -#endif - - /* Pin_Mux for FIU/SPI (set to GPIO) */ - SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_GPIO_NO_SPIP); -#if defined(NPCX_INT_FLASH_SUPPORT) - SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI); -#endif - - /* Pin_Mux for PWRGD */ - SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_NO_PWRGD); - - /* Pin_Mux for PECI */ -#ifndef CONFIG_PECI - SET_BIT(NPCX_DEVALT(0xA), NPCX_DEVALTA_NO_PECI_EN); -#endif - - /* Pin_Mux for LPC & SHI */ -#ifdef CONFIG_HOSTCMD_SHI - /* Switching to eSPI mode for SHI interface */ - NPCX_DEVCNT |= 0x08; - /* Alternate Intel bus interface LPC/eSPI to GPIOs first */ - SET_BIT(NPCX_DEVALT(ALT_GROUP_1), NPCX_DEVALT1_NO_LPC_ESPI); -#endif - - /* Clear all interrupt pending and enable bits of GPIOS */ - for (i = 0; i < 2; i++) { - for (j = 0; j < 8; j++) { - NPCX_WKPCL(i, j) = 0xFF; - NPCX_WKEN(i, j) = 0; - } - } - - /* No support enable clock for the GPIO port in run and sleep. */ - /* Set flag for each GPIO pin in gpio_list */ - for (i = 0; i < GPIO_COUNT; i++, g++) { - flags = g->flags; - - if (flags & GPIO_DEFAULT) - continue; - /* - * If this is a warm reboot, don't set the output levels or - * we'll shut off the AP. - */ - if (is_warm) - flags &= ~(GPIO_LOW | GPIO_HIGH); - - /* Set up GPIO based on flags */ - gpio_set_flags_by_mask(g->port, g->mask, flags); - - /* - * Ensure that any GPIO defined in gpio.inc is actually - * configured as a GPIO, and not left in its default state, - * which may or may not be as a GPIO. - */ - gpio_set_alternate_function(g->port, g->mask, - GPIO_ALT_FUNC_NONE); - } - - /* The bypass of low voltage IOs for better power consumption */ -#ifdef CONFIG_LOW_POWER_IDLE - /* Disable input buffer of 1.8V GPIOs without ISR */ - g = gpio_list + GPIO_IH_COUNT; - for (i = GPIO_IH_COUNT; i < GPIO_COUNT; i++, g++) { - /* - * I2c ports are both alternate mode and normal gpio pin, but - * the alternate mode needs the wake up input even though the - * normal gpio definition doesn't have an ISR. - */ - if ((g->flags & GPIO_SEL_1P8V) && !gpio_is_i2c_pin(i)) - gpio_enable_wake_up_input(i, 0); - } -#endif - - /* Configure unused pins as GPIO INPUT with PU to save power. */ - for (i = 0; i < unused_pin_count; i++, u++) { - gpio_set_flags_by_mask(u->port, u->mask, - GPIO_INPUT | GPIO_PULL_UP); - gpio_set_alternate_function(g->port, g->mask, - GPIO_ALT_FUNC_NONE); - } -} - -/*****************************************************************************/ -/* Interrupt handlers */ - -/** - * Handle a GPIO interrupt. - * - * @param wui_int wui table & group for GPIO interrupt no. - */ - -void gpio_interrupt(struct npcx_wui wui_int) -{ - int i; - uint8_t wui_mask; - uint8_t table = wui_int.table; - uint8_t group = wui_int.group; - - /* Get pending mask */ - wui_mask = NPCX_WKPND(table, group) & NPCX_WKEN(table, group); - - /* Find GPIOs and execute interrupt service routine */ - for (i = 0; i < GPIO_IH_COUNT && wui_mask; i++) { - uint8_t pin_mask = 1 << gpio_wui_table[i].bit; - - if ((gpio_wui_table[i].table == table) && - (gpio_wui_table[i].group == group) && - (wui_mask & pin_mask)) { - /* Clear pending bit of GPIO */ - NPCX_WKPCL(table, group) = pin_mask; - /* Execute GPIO's ISR */ - gpio_irq_handlers[i](i); - /* In case declare the same GPIO in gpio_wui_table */ - wui_mask &= ~pin_mask; - } - } - - if (wui_mask) - /* No ISR for this interrupt, just clear it */ - NPCX_WKPCL(table, group) = wui_mask; -} - -#undef GPIO_IRQ_FUNC -#if DEBUG_GPIO && defined(CONFIG_LOW_POWER_IDLE) -/* - * Command used to disable input buffer of gpios one by one to - * investigate power consumption - */ -static int command_gpiodisable(int argc, char **argv) -{ - uint8_t i; - uint8_t offset; - const uint8_t non_isr_gpio_num = GPIO_COUNT - GPIO_IH_COUNT; - const struct gpio_info *g_list; - int flags; - static uint8_t idx = 0; - int num = -1; - int enable; - char *e; - - if (argc == 2) { - if (!strcasecmp(argv[1], "info")) { - offset = idx + GPIO_IH_COUNT; - g_list = gpio_list + offset; - flags = g_list->flags; - - ccprintf("Total GPIO declaration: %d\n", GPIO_COUNT); - ccprintf("Total Non-ISR GPIO declaration: %d\n", - non_isr_gpio_num); - ccprintf("Next GPIO Num to check by "); - ccprintf("\"gpiodisable next\"\n"); - ccprintf(" offset: %d\n", offset); - ccprintf(" current GPIO name: %s\n", g_list->name); - ccprintf(" current GPIO flags: 0x%08x\n", flags); - return EC_SUCCESS; - } - /* List all non-ISR GPIOs in gpio.inc */ - if (!strcasecmp(argv[1], "list")) { - for (i = GPIO_IH_COUNT; i < GPIO_COUNT; i++) - ccprintf("%d: %s\n", i, gpio_get_name(i)); - return EC_SUCCESS; - } - - if (!strcasecmp(argv[1], "next")) { - while (1) { - if (idx == non_isr_gpio_num) - break; - - offset = idx + GPIO_IH_COUNT; - g_list = gpio_list + offset; - flags = g_list->flags; - ccprintf("current GPIO : %d %s --> ", - offset, g_list->name); - if (gpio_is_i2c_pin(offset)) { - ccprintf("Ignore I2C pin!\n"); - idx++; - continue; - } else if (flags & GPIO_SEL_1P8V) { - ccprintf("Ignore 1v8 pin!\n"); - idx++; - continue; - } else { - if ((flags & GPIO_INPUT) || - (flags & GPIO_OPEN_DRAIN)) { - ccprintf("Disable WKINEN!\n"); - gpio_enable_wake_up_input( - offset, 0); - idx++; - break; - } - ccprintf("Not Input or OpenDrain\n"); - idx++; - continue; - } - }; - if (idx == non_isr_gpio_num) { - ccprintf("End of GPIO list, reset index!\n"); - idx = 0; - }; - return EC_SUCCESS; - } - } - if (argc == 3) { - num = strtoi(argv[1], &e, 0); - if (*e || num < GPIO_IH_COUNT || num >= GPIO_COUNT) - return EC_ERROR_PARAM1; - - if (parse_bool(argv[2], &enable)) - gpio_enable_wake_up_input(num, enable ? 1 : 0); - else - return EC_ERROR_PARAM2; - - return EC_SUCCESS; - } - return EC_ERROR_INVAL; -} -DECLARE_CONSOLE_COMMAND(gpiodisable, command_gpiodisable, - "info/list/next/<num> on|off", - "Disable GPIO input buffer to investigate power consumption"); -#endif diff --git a/chip/npcx/gpio_chip-npcx5.h b/chip/npcx/gpio_chip-npcx5.h deleted file mode 100644 index 83916a421b..0000000000 --- a/chip/npcx/gpio_chip-npcx5.h +++ /dev/null @@ -1,384 +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. - */ - -#ifndef __CROS_EC_GPIO_CHIP_NPCX5_H -#define __CROS_EC_GPIO_CHIP_NPCX5_H - -/*****************************************************************************/ -/* Macro functions for MIWU mapping table */ - -/* MIWU0 */ -/* Group A: NPCX_IRQ_MTC_WKINTAD_0 */ -#define NPCX_WUI_GPIO_8_0 WUI(0, MIWU_GROUP_1, 0) -#define NPCX_WUI_GPIO_8_1 WUI(0, MIWU_GROUP_1, 1) -#define NPCX_WUI_GPIO_8_2 WUI(0, MIWU_GROUP_1, 2) -#define NPCX_WUI_GPIO_8_3 WUI(0, MIWU_GROUP_1, 3) -#define NPCX_WUI_GPIO_8_4 WUI(0, MIWU_GROUP_1, 4) -#define NPCX_WUI_GPIO_8_5 WUI(0, MIWU_GROUP_1, 5) -#define NPCX_WUI_GPIO_8_6 WUI(0, MIWU_GROUP_1, 6) -#define NPCX_WUI_GPIO_8_7 WUI(0, MIWU_GROUP_1, 7) - -/* Group B: NPCX_IRQ_TWD_WKINTB_0 */ -#define NPCX_WUI_GPIO_9_0 WUI(0, MIWU_GROUP_2, 0) -#define NPCX_WUI_GPIO_9_1 WUI(0, MIWU_GROUP_2, 1) -#define NPCX_WUI_GPIO_9_2 WUI(0, MIWU_GROUP_2, 2) -#define NPCX_WUI_GPIO_9_3 WUI(0, MIWU_GROUP_2, 3) -#define NPCX_WUI_GPIO_9_4 WUI(0, MIWU_GROUP_2, 4) -#define NPCX_WUI_GPIO_9_5 WUI(0, MIWU_GROUP_2, 5) - -/* Group C: NPCX_IRQ_WKINTC_0 */ -#define NPCX_WUI_GPIO_9_7 WUI(0, MIWU_GROUP_3, 1) -#define NPCX_WUI_GPIO_A_1 WUI(0, MIWU_GROUP_3, 3) -#define NPCX_WUI_GPIO_A_3 WUI(0, MIWU_GROUP_3, 5) -#define NPCX_WUI_GPIO_A_5 WUI(0, MIWU_GROUP_3, 7) - -/* Group D: NPCX_IRQ_MTC_WKINTAD_0 */ -#define NPCX_WUI_GPIO_A_6 WUI(0, MIWU_GROUP_4, 0) -#define NPCX_WUI_GPIO_A_7 WUI(0, MIWU_GROUP_4, 1) -#define NPCX_WUI_GPIO_B_0 WUI(0, MIWU_GROUP_4, 2) -#define NPCX_WUI_GPIO_B_1 WUI(0, MIWU_GROUP_4, 5) -#define NPCX_WUI_GPIO_B_2 WUI(0, MIWU_GROUP_4, 6) - -/* Group E: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_B_3 WUI(0, MIWU_GROUP_5, 0) -#define NPCX_WUI_GPIO_B_4 WUI(0, MIWU_GROUP_5, 1) -#define NPCX_WUI_GPIO_B_5 WUI(0, MIWU_GROUP_5, 2) -#define NPCX_WUI_GPIO_B_7 WUI(0, MIWU_GROUP_5, 4) - -/* Group F: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_C_0 WUI(0, MIWU_GROUP_6, 0) -#define NPCX_WUI_GPIO_C_1 WUI(0, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_C_2 WUI(0, MIWU_GROUP_6, 2) -#define NPCX_WUI_GPIO_C_3 WUI(0, MIWU_GROUP_6, 3) -#define NPCX_WUI_GPIO_C_4 WUI(0, MIWU_GROUP_6, 4) -#define NPCX_WUI_GPIO_C_5 WUI(0, MIWU_GROUP_6, 5) -#define NPCX_WUI_GPIO_C_6 WUI(0, MIWU_GROUP_6, 6) -#define NPCX_WUI_GPIO_C_7 WUI(0, MIWU_GROUP_6, 7) - -/* Group G: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_D_0 WUI(0, MIWU_GROUP_7, 0) -#define NPCX_WUI_GPIO_D_1 WUI(0, MIWU_GROUP_7, 1) -#define NPCX_WUI_GPIO_D_2 WUI(0, MIWU_GROUP_7, 2) -#define NPCX_WUI_GPIO_D_3 WUI(0, MIWU_GROUP_7, 3) - -/* Group H: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_E_7 WUI(0, MIWU_GROUP_8, 7) - -/* MIWU1 */ -/* Group A: NPCX_IRQ_WKINTA_1 */ -#define NPCX_WUI_GPIO_0_0 WUI(1, MIWU_GROUP_1, 0) -#define NPCX_WUI_GPIO_0_1 WUI(1, MIWU_GROUP_1, 1) -#define NPCX_WUI_GPIO_0_2 WUI(1, MIWU_GROUP_1, 2) -#define NPCX_WUI_GPIO_0_3 WUI(1, MIWU_GROUP_1, 3) -#define NPCX_WUI_GPIO_0_4 WUI(1, MIWU_GROUP_1, 4) -#define NPCX_WUI_GPIO_0_5 WUI(1, MIWU_GROUP_1, 5) -#define NPCX_WUI_GPIO_0_6 WUI(1, MIWU_GROUP_1, 6) -#define NPCX_WUI_GPIO_0_7 WUI(1, MIWU_GROUP_1, 7) - -/* Group B: NPCX_IRQ_WKINTB_1 */ -#define NPCX_WUI_GPIO_1_0 WUI(1, MIWU_GROUP_2, 0) -#define NPCX_WUI_GPIO_1_1 WUI(1, MIWU_GROUP_2, 1) -#define NPCX_WUI_GPIO_1_3 WUI(1, MIWU_GROUP_2, 3) -#define NPCX_WUI_GPIO_1_4 WUI(1, MIWU_GROUP_2, 4) -#define NPCX_WUI_GPIO_1_5 WUI(1, MIWU_GROUP_2, 5) -#define NPCX_WUI_GPIO_1_6 WUI(1, MIWU_GROUP_2, 6) -#define NPCX_WUI_GPIO_1_7 WUI(1, MIWU_GROUP_2, 7) - -/* Group C: NPCX_IRQ_KSI_WKINTC_1 */ -#define NPCX_WUI_GPIO_3_1 WUI(1, MIWU_GROUP_3, 0) -#define NPCX_WUI_GPIO_3_0 WUI(1, MIWU_GROUP_3, 1) -#define NPCX_WUI_GPIO_2_7 WUI(1, MIWU_GROUP_3, 2) -#define NPCX_WUI_GPIO_2_6 WUI(1, MIWU_GROUP_3, 3) -#define NPCX_WUI_GPIO_2_5 WUI(1, MIWU_GROUP_3, 4) -#define NPCX_WUI_GPIO_2_4 WUI(1, MIWU_GROUP_3, 5) -#define NPCX_WUI_GPIO_2_3 WUI(1, MIWU_GROUP_3, 6) -#define NPCX_WUI_GPIO_2_2 WUI(1, MIWU_GROUP_3, 7) - -/* Group D: NPCX_IRQ_WKINTD_1 */ -#define NPCX_WUI_GPIO_2_0 WUI(1, MIWU_GROUP_4, 0) -#define NPCX_WUI_GPIO_2_1 WUI(1, MIWU_GROUP_4, 1) -#define NPCX_WUI_GPIO_3_3 WUI(1, MIWU_GROUP_4, 3) -#define NPCX_WUI_GPIO_3_4 WUI(1, MIWU_GROUP_4, 4) -#define NPCX_WUI_GPIO_3_6 WUI(1, MIWU_GROUP_4, 6) -#define NPCX_WUI_GPIO_3_7 WUI(1, MIWU_GROUP_4, 7) - -/* Group E: NPCX_IRQ_WKINTE_1 */ -#define NPCX_WUI_GPIO_4_0 WUI(1, MIWU_GROUP_5, 0) -#define NPCX_WUI_GPIO_4_1 WUI(1, MIWU_GROUP_5, 1) -#define NPCX_WUI_GPIO_4_2 WUI(1, MIWU_GROUP_5, 2) -#define NPCX_WUI_GPIO_4_3 WUI(1, MIWU_GROUP_5, 3) -#define NPCX_WUI_GPIO_4_4 WUI(1, MIWU_GROUP_5, 4) -#define NPCX_WUI_GPIO_4_5 WUI(1, MIWU_GROUP_5, 5) -#define NPCX_WUI_GPIO_4_6 WUI(1, MIWU_GROUP_5, 6) -#define NPCX_WUI_GPIO_4_7 WUI(1, MIWU_GROUP_5, 7) - -/* Group F: NPCX_IRQ_WKINTF_1 */ -#define NPCX_WUI_GPIO_5_0 WUI(1, MIWU_GROUP_6, 0) -#define NPCX_WUI_GPIO_5_1 WUI(1, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_5_2 WUI(1, MIWU_GROUP_6, 2) -#define NPCX_WUI_GPIO_5_3 WUI(1, MIWU_GROUP_6, 3) -#define NPCX_WUI_GPIO_5_4 WUI(1, MIWU_GROUP_6, 4) -#define NPCX_WUI_GPIO_5_5 WUI(1, MIWU_GROUP_6, 5) -#define NPCX_WUI_GPIO_5_6 WUI(1, MIWU_GROUP_6, 6) -#define NPCX_WUI_GPIO_5_7 WUI(1, MIWU_GROUP_6, 7) - -/* Group G: NPCX_IRQ_WKINTG_1 */ -#define NPCX_WUI_GPIO_6_0 WUI(1, MIWU_GROUP_7, 0) -#define NPCX_WUI_GPIO_6_1 WUI(1, MIWU_GROUP_7, 1) -#define NPCX_WUI_GPIO_6_2 WUI(1, MIWU_GROUP_7, 2) -#define NPCX_WUI_GPIO_6_3 WUI(1, MIWU_GROUP_7, 3) -#define NPCX_WUI_GPIO_6_4 WUI(1, MIWU_GROUP_7, 4) -#define NPCX_WUI_GPIO_6_5 WUI(1, MIWU_GROUP_7, 5) -#define NPCX_WUI_GPIO_7_1 WUI(1, MIWU_GROUP_7, 7) - -/* Group H: NPCX_IRQ_WKINTH_1 */ -#define NPCX_WUI_GPIO_7_0 WUI(1, MIWU_GROUP_8, 0) -#define NPCX_WUI_GPIO_6_7 WUI(1, MIWU_GROUP_8, 1) -#define NPCX_WUI_GPIO_7_2 WUI(1, MIWU_GROUP_8, 2) -#define NPCX_WUI_GPIO_7_3 WUI(1, MIWU_GROUP_8, 3) -#define NPCX_WUI_GPIO_7_4 WUI(1, MIWU_GROUP_8, 4) -#define NPCX_WUI_GPIO_7_5 WUI(1, MIWU_GROUP_8, 5) -#define NPCX_WUI_GPIO_7_6 WUI(1, MIWU_GROUP_8, 6) - -/* Others GPO without MIWU functionality */ -#define NPCX_WUI_GPIO_1_2 WUI_NONE -#define NPCX_WUI_GPIO_3_2 WUI_NONE -#define NPCX_WUI_GPIO_3_5 WUI_NONE -#define NPCX_WUI_GPIO_6_6 WUI_NONE -#define NPCX_WUI_GPIO_7_7 WUI_NONE -#define NPCX_WUI_GPIO_B_6 WUI_NONE -#define NPCX_WUI_GPIO_D_6 WUI_NONE - -/* Others GPIO without MIWU functionality on npcx5 */ -#define NPCX_WUI_GPIO_D_4 WUI_NONE -#define NPCX_WUI_GPIO_D_5 WUI_NONE -#define NPCX_WUI_GPIO_D_7 WUI_NONE -#define NPCX_WUI_GPIO_E_0 WUI_NONE -#define NPCX_WUI_GPIO_E_1 WUI_NONE -#define NPCX_WUI_GPIO_E_2 WUI_NONE -#define NPCX_WUI_GPIO_E_3 WUI_NONE -#define NPCX_WUI_GPIO_E_4 WUI_NONE -#define NPCX_WUI_GPIO_E_5 WUI_NONE - -/*****************************************************************************/ -/* Macro functions for Alternative mapping table */ - -/* I2C Module */ -#define NPCX_ALT_GPIO_B_2 ALT(B, 2, NPCX_ALT(2, I2C0_1_SL)) /* SMB0SDA1 */ -#define NPCX_ALT_GPIO_B_3 ALT(B, 3, NPCX_ALT(2, I2C0_1_SL)) /* SMB0SCL1 */ -#define NPCX_ALT_GPIO_B_4 ALT(B, 4, NPCX_ALT(2, I2C0_0_SL)) /* SMB0SDA0 */ -#define NPCX_ALT_GPIO_B_5 ALT(B, 5, NPCX_ALT(2, I2C0_0_SL)) /* SMB0SCL0 */ -#define NPCX_ALT_GPIO_8_7 ALT(8, 7, NPCX_ALT(2, I2C1_0_SL)) /* SMB1SDA */ -#define NPCX_ALT_GPIO_9_0 ALT(9, 0, NPCX_ALT(2, I2C1_0_SL)) /* SMB1SCL */ -#define NPCX_ALT_GPIO_9_1 ALT(9, 1, NPCX_ALT(2, I2C2_0_SL)) /* SMB2SDA */ -#define NPCX_ALT_GPIO_9_2 ALT(9, 2, NPCX_ALT(2, I2C2_0_SL)) /* SMB2SCL */ -#define NPCX_ALT_GPIO_D_0 ALT(D, 0, NPCX_ALT(2, I2C3_0_SL)) /* SMB3SDA */ -#define NPCX_ALT_GPIO_D_1 ALT(D, 1, NPCX_ALT(2, I2C3_0_SL)) /* SMB3SCL */ - -/* ADC Module */ -#define NPCX_ALT_GPIO_4_5 ALT(4, 5, NPCX_ALT(6, ADC0_SL)) /* ADC0 */ -#define NPCX_ALT_GPIO_4_4 ALT(4, 4, NPCX_ALT(6, ADC1_SL)) /* ADC1 */ -#define NPCX_ALT_GPIO_4_3 ALT(4, 3, NPCX_ALT(6, ADC2_SL)) /* ADC2 */ -#define NPCX_ALT_GPIO_4_2 ALT(4, 2, NPCX_ALT(6, ADC3_SL)) /* ADC3 */ -#define NPCX_ALT_GPIO_4_1 ALT(4, 1, NPCX_ALT(6, ADC4_SL)) /* ADC4 */ - -/* UART Module */ -#define NPCX_ALT_GPIO_6_4 ALT(6, 4, NPCX_ALT(C, UART_SL2)) /* CR_SIN SEL2 */ -#define NPCX_ALT_GPIO_6_5 ALT(6, 5, NPCX_ALT(C, UART_SL2)) /* CR_SOUT SEL2 */ - -/* SPI Module */ -#define NPCX_ALT_GPIO_9_5 ALT(9, 5, NPCX_ALT(0, SPIP_SL)) /* SPIP_MISO */ -#define NPCX_ALT_GPIO_A_5 ALT(A, 5, NPCX_ALT(0, SPIP_SL)) /* SPIP_CS1 */ -#define NPCX_ALT_GPIO_A_3 ALT(A, 3, NPCX_ALT(0, SPIP_SL)) /* SPIP_MOSI */ -#define NPCX_ALT_GPIO_A_1 ALT(A, 1, NPCX_ALT(0, SPIP_SL)) /* SPIP_SCLK */ - -/* PWM Module */ -#define NPCX_ALT_GPIO_C_3 ALT(C, 3, NPCX_ALT(4, PWM0_SL)) /* PWM0 */ -#define NPCX_ALT_GPIO_C_2 ALT(C, 2, NPCX_ALT(4, PWM1_SL)) /* PWM1 */ -#define NPCX_ALT_GPIO_C_4 ALT(C, 4, NPCX_ALT(4, PWM2_SL)) /* PWM2 */ -#define NPCX_ALT_GPIO_8_0 ALT(8, 0, NPCX_ALT(4, PWM3_SL)) /* PWM3 */ -#define NPCX_ALT_GPIO_B_6 ALT(B, 6, NPCX_ALT(4, PWM4_SL)) /* PWM4 */ -#define NPCX_ALT_GPIO_B_7 ALT(B, 7, NPCX_ALT(4, PWM5_SL)) /* PWM5 */ -#define NPCX_ALT_GPIO_C_0 ALT(C, 0, NPCX_ALT(4, PWM6_SL)) /* PWM6 */ -#define NPCX_ALT_GPIO_6_0 ALT(6, 0, NPCX_ALT(4, PWM7_SL)) /* PWM7 */ - -/* MFT Module */ -#define NPCX_ALT_GPIO_9_3 ALT(9, 3, NPCX_ALT(C, TA1_SL2)) /* TA1_SEL2 */ -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3) -#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, PS2_3_SL2)) /* PS2_CLK3 */ -#else -#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, TA2_SL2)) /* TA2_SEL2 */ -#endif -#define NPCX_ALT_GPIO_4_0 ALT(4, 0, NPCX_ALT(3, TA1_SL1)) /* TA1_SEL1 */ -#define NPCX_ALT_GPIO_7_3 ALT(7, 3, NPCX_ALT(3, TA2_SL1)) /* TA2_SEL1 */ - -/* Keyboard Scan Module */ -#define NPCX_ALT_GPIO_3_1 ALT(3, 1, NPCX_ALT_INV(7, NO_KSI0_SL)) /* KSI0 */ -#define NPCX_ALT_GPIO_3_0 ALT(3, 0, NPCX_ALT_INV(7, NO_KSI1_SL)) /* KSI1 */ -#define NPCX_ALT_GPIO_2_7 ALT(2, 7, NPCX_ALT_INV(7, NO_KSI2_SL)) /* KSI2 */ -#define NPCX_ALT_GPIO_2_6 ALT(2, 6, NPCX_ALT_INV(7, NO_KSI3_SL)) /* KSI3 */ -#define NPCX_ALT_GPIO_2_5 ALT(2, 5, NPCX_ALT_INV(7, NO_KSI4_SL)) /* KSI4 */ -#define NPCX_ALT_GPIO_2_4 ALT(2, 4, NPCX_ALT_INV(7, NO_KSI5_SL)) /* KSI5 */ -#define NPCX_ALT_GPIO_2_3 ALT(2, 3, NPCX_ALT_INV(7, NO_KSI6_SL)) /* KSI6 */ -#define NPCX_ALT_GPIO_2_2 ALT(2, 2, NPCX_ALT_INV(7, NO_KSI7_SL)) /* KSI7 */ -#define NPCX_ALT_GPIO_2_1 ALT(2, 1, NPCX_ALT_INV(8, NO_KSO00_SL)) /* KSO00 */ -#define NPCX_ALT_GPIO_2_0 ALT(2, 0, NPCX_ALT_INV(8, NO_KSO01_SL)) /* KSO01 */ -#define NPCX_ALT_GPIO_1_7 ALT(1, 7, NPCX_ALT_INV(8, NO_KSO02_SL)) /* KSO02 */ -#define NPCX_ALT_GPIO_1_6 ALT(1, 6, NPCX_ALT_INV(8, NO_KSO03_SL)) /* KSO03 */ -#define NPCX_ALT_GPIO_1_5 ALT(1, 5, NPCX_ALT_INV(8, NO_KSO04_SL)) /* KSO04 */ -#define NPCX_ALT_GPIO_1_4 ALT(1, 4, NPCX_ALT_INV(8, NO_KSO05_SL)) /* KSO05 */ -#define NPCX_ALT_GPIO_1_3 ALT(1, 3, NPCX_ALT_INV(8, NO_KSO06_SL)) /* KSO06 */ -#define NPCX_ALT_GPIO_1_2 ALT(1, 2, NPCX_ALT_INV(8, NO_KSO07_SL)) /* KSO07 */ -/* KSO08 & CR_SIN */ -#define NPCX_ALT_GPIO_1_1 ALT(1, 1, NPCX_ALT_INV(9, NO_KSO08_SL)) -/* KSO09 & CR_SOUT */ -#define NPCX_ALT_GPIO_1_0 ALT(1, 0, NPCX_ALT_INV(9, NO_KSO09_SL)) -#define NPCX_ALT_GPIO_0_7 ALT(0, 7, NPCX_ALT_INV(9, NO_KSO10_SL)) /* KSO10 */ -#define NPCX_ALT_GPIO_0_6 ALT(0, 6, NPCX_ALT_INV(9, NO_KSO11_SL)) /* KSO11 */ -#define NPCX_ALT_GPIO_0_5 ALT(0, 5, NPCX_ALT_INV(9, NO_KSO12_SL)) /* KSO12 */ -#define NPCX_ALT_GPIO_0_4 ALT(0, 4, NPCX_ALT_INV(9, NO_KSO13_SL)) /* KSO13 */ -#define NPCX_ALT_GPIO_8_2 ALT(8, 2, NPCX_ALT_INV(9, NO_KSO14_SL)) /* KSO14 */ -#define NPCX_ALT_GPIO_8_3 ALT(8, 3, NPCX_ALT_INV(9, NO_KSO15_SL)) /* KSO15 */ -#define NPCX_ALT_GPIO_0_3 ALT(0, 3, NPCX_ALT_INV(A, NO_KSO16_SL)) /* KSO16 */ -#define NPCX_ALT_GPIO_B_1 ALT(B, 1, NPCX_ALT_INV(A, NO_KSO17_SL)) /* KSO17 */ - -/* Clock module */ -#define NPCX_ALT_GPIO_7_5 ALT(7, 5, NPCX_ALT(A, 32K_OUT_SL)) /* 32KHZ_OUT */ -#define NPCX_ALT_GPIO_E_7 ALT(E, 7, NPCX_ALT(A, 32KCLKIN_SL)) /* 32KCLKIN */ - -/* PS/2 module */ -#define NPCX_ALT_GPIO_6_7 ALT(6, 7, NPCX_ALT(3, PS2_0_SL)) /* PS2_CLK0 */ -#define NPCX_ALT_GPIO_7_0 ALT(7, 0, NPCX_ALT(3, PS2_0_SL)) /* PS2_DATA0 */ -#define NPCX_ALT_GPIO_6_2 ALT(6, 2, NPCX_ALT(3, PS2_1_SL)) /* PS2_CLK1 */ -#define NPCX_ALT_GPIO_6_3 ALT(6, 3, NPCX_ALT(3, PS2_1_SL)) /* PS2_DATA1 */ -#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(3, PS2_2_SL)) /* PS2_CLK2 */ -#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(3, PS2_2_SL)) /* PS2_DATA2 */ -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3) -#define NPCX_ALT_GPIO_A_7 ALT(A, 7, NPCX_ALT(C, PS2_3_SL2)) /* PS2_DAT3 */ -#else -#define NPCX_ALT_GPIO_A_7 -#endif - -#define NPCX_ALT_TABLE { \ - NPCX_ALT_GPIO_0_3 /* KSO16 */ \ - NPCX_ALT_GPIO_0_4 /* KSO13 */ \ - NPCX_ALT_GPIO_0_5 /* KSO12 */ \ - NPCX_ALT_GPIO_0_6 /* KSO11 */ \ - NPCX_ALT_GPIO_0_7 /* KSO10 */ \ - NPCX_ALT_GPIO_1_0 /* KSO09 & CR_SOUT */ \ - NPCX_ALT_GPIO_1_1 /* KSO08 & CR_SIN */ \ - NPCX_ALT_GPIO_1_2 /* KSO07 */ \ - NPCX_ALT_GPIO_1_3 /* KSO06 */ \ - NPCX_ALT_GPIO_1_4 /* KSO05 */ \ - NPCX_ALT_GPIO_1_5 /* KSO04 */ \ - NPCX_ALT_GPIO_1_6 /* KSO03 */ \ - NPCX_ALT_GPIO_1_7 /* KSO02 */ \ - NPCX_ALT_GPIO_2_0 /* KSO01 */ \ - NPCX_ALT_GPIO_2_1 /* KSO00 */ \ - NPCX_ALT_GPIO_2_2 /* KSI7 */ \ - NPCX_ALT_GPIO_2_3 /* KSI6 */ \ - NPCX_ALT_GPIO_2_4 /* KSI5 */ \ - NPCX_ALT_GPIO_2_5 /* KSI4 */ \ - NPCX_ALT_GPIO_2_6 /* KSI3 */ \ - NPCX_ALT_GPIO_2_7 /* KSI2 */ \ - NPCX_ALT_GPIO_3_0 /* KSI1 */ \ - NPCX_ALT_GPIO_3_1 /* KSI0 */ \ - NPCX_ALT_GPIO_3_4 /* PS2_DAT2 */ \ - NPCX_ALT_GPIO_3_7 /* PS2_CLK2 */ \ - NPCX_ALT_GPIO_4_0 /* TA1_SEL1 */ \ - NPCX_ALT_GPIO_4_1 /* ADC4 */ \ - NPCX_ALT_GPIO_4_2 /* ADC3 */ \ - NPCX_ALT_GPIO_4_4 /* ADC1 */ \ - NPCX_ALT_GPIO_4_5 /* ADC0 */ \ - NPCX_ALT_GPIO_4_3 /* ADC2 */ \ - NPCX_ALT_GPIO_6_0 /* PWM7 */ \ - NPCX_ALT_GPIO_6_2 /* PS2_CLK1 */ \ - NPCX_ALT_GPIO_6_3 /* PS2_DAT1 */ \ - NPCX_ALT_GPIO_6_4 /* CR_SIN2 */ \ - NPCX_ALT_GPIO_6_5 /* CR_SOUT2 */ \ - NPCX_ALT_GPIO_6_7 /* PS2_CLK0 */ \ - NPCX_ALT_GPIO_7_0 /* PS2_DAT0 */ \ - NPCX_ALT_GPIO_7_3 /* TA2_SEL1 */ \ - NPCX_ALT_GPIO_7_5 /* 32KHZ_OUT */ \ - NPCX_ALT_GPIO_8_0 /* PWM3 */ \ - NPCX_ALT_GPIO_8_2 /* KSO14 */ \ - NPCX_ALT_GPIO_8_3 /* KSO15 */ \ - NPCX_ALT_GPIO_8_7 /* SMB1SDA */ \ - NPCX_ALT_GPIO_9_0 /* SMB1SCL */ \ - NPCX_ALT_GPIO_9_1 /* SMB2SDA */ \ - NPCX_ALT_GPIO_9_2 /* SMB2SCL */ \ - NPCX_ALT_GPIO_9_3 /* TA1_SEL2 */ \ - NPCX_ALT_GPIO_9_5 /* SPIP_MISO */ \ - NPCX_ALT_GPIO_A_1 /* SPIP_SCLK */ \ - NPCX_ALT_GPIO_A_3 /* SPIP_MOSI */ \ - NPCX_ALT_GPIO_A_5 /* SPIP_CS1 */ \ - NPCX_ALT_GPIO_A_6 /* TA2_SEL2/PS2_CLK3 */ \ - NPCX_ALT_GPIO_A_7 /* PS2_DAT3 */ \ - NPCX_ALT_GPIO_B_1 /* KSO17 */ \ - NPCX_ALT_GPIO_B_2 /* SMB0SDA1 */ \ - NPCX_ALT_GPIO_B_3 /* SMB0SCL1 */ \ - NPCX_ALT_GPIO_B_4 /* SMB0SDA0 */ \ - NPCX_ALT_GPIO_B_5 /* SMB0SCL0 */ \ - NPCX_ALT_GPIO_B_6 /* PWM4 */ \ - NPCX_ALT_GPIO_B_7 /* PWM5 */ \ - NPCX_ALT_GPIO_C_0 /* PWM6 */ \ - NPCX_ALT_GPIO_C_2 /* PWM1 */ \ - NPCX_ALT_GPIO_C_3 /* PWM0 */ \ - NPCX_ALT_GPIO_C_4 /* PWM2 */ \ - NPCX_ALT_GPIO_D_0 /* SMB3SDA */ \ - NPCX_ALT_GPIO_D_1 /* SMB3SCL */ \ - NPCX_ALT_GPIO_E_7 /* 32KCLKIN */ \ -} - -/*****************************************************************************/ -/* Macro functions for Low-Voltage mapping table */ - -/* Low-Voltage GPIO Control 0 */ -#define NPCX_LVOL_CTRL_0_0 NPCX_GPIO(B, 5) -#define NPCX_LVOL_CTRL_0_1 NPCX_GPIO(B, 4) -#define NPCX_LVOL_CTRL_0_2 NPCX_GPIO(B, 3) -#define NPCX_LVOL_CTRL_0_3 NPCX_GPIO(B, 2) -#define NPCX_LVOL_CTRL_0_4 NPCX_GPIO(9, 0) -#define NPCX_LVOL_CTRL_0_5 NPCX_GPIO(8, 7) -#define NPCX_LVOL_CTRL_0_6 NPCX_GPIO(0, 0) -#define NPCX_LVOL_CTRL_0_7 NPCX_GPIO(3, 3) - -/* Low-Voltage GPIO Control 1 */ -#define NPCX_LVOL_CTRL_1_0 NPCX_GPIO(9, 2) -#define NPCX_LVOL_CTRL_1_1 NPCX_GPIO(9, 1) -#define NPCX_LVOL_CTRL_1_2 NPCX_GPIO(D, 1) -#define NPCX_LVOL_CTRL_1_3 NPCX_GPIO(D, 0) -#define NPCX_LVOL_CTRL_1_4 NPCX_GPIO(3, 6) -#define NPCX_LVOL_CTRL_1_5 NPCX_GPIO(6, 4) -#define NPCX_LVOL_CTRL_1_6 NPCX_GPIO(6, 5) -#define NPCX_LVOL_CTRL_1_7 NPCX_GPIO_NONE - -/* Low-Voltage GPIO Control 2 */ -#define NPCX_LVOL_CTRL_2_0 NPCX_GPIO(7, 4) -#define NPCX_LVOL_CTRL_2_1 NPCX_GPIO(8, 4) -#define NPCX_LVOL_CTRL_2_2 NPCX_GPIO(8, 5) -#define NPCX_LVOL_CTRL_2_3 NPCX_GPIO(7, 3) -#define NPCX_LVOL_CTRL_2_4 NPCX_GPIO(C, 1) -#define NPCX_LVOL_CTRL_2_5 NPCX_GPIO(C, 7) -#define NPCX_LVOL_CTRL_2_6 NPCX_GPIO(E, 7) -#define NPCX_LVOL_CTRL_2_7 NPCX_GPIO(3, 4) - -/* Low-Voltage GPIO Control 3 */ -#define NPCX_LVOL_CTRL_3_0 NPCX_GPIO(C, 6) -#define NPCX_LVOL_CTRL_3_1 NPCX_GPIO(3, 7) -#define NPCX_LVOL_CTRL_3_2 NPCX_GPIO(4, 0) -#define NPCX_LVOL_CTRL_3_3 NPCX_GPIO(7, 1) -#define NPCX_LVOL_CTRL_3_4 NPCX_GPIO(8, 2) -#define NPCX_LVOL_CTRL_3_5 NPCX_GPIO(7, 5) -#define NPCX_LVOL_CTRL_3_6 NPCX_GPIO(8, 0) -#define NPCX_LVOL_CTRL_3_7 NPCX_GPIO(C, 5) - -/* 4 Low-Voltage Control Groups on npcx5 */ -#define NPCX_LVOL_TABLE { { NPCX_LVOL_CTRL_ITEMS(0), }, \ - { NPCX_LVOL_CTRL_ITEMS(1), }, \ - { NPCX_LVOL_CTRL_ITEMS(2), }, \ - { NPCX_LVOL_CTRL_ITEMS(3), }, } - -#endif /* __CROS_EC_GPIO_CHIP_NPCX5_H */ diff --git a/chip/npcx/gpio_chip-npcx7.h b/chip/npcx/gpio_chip-npcx7.h deleted file mode 100644 index 7f815e6d30..0000000000 --- a/chip/npcx/gpio_chip-npcx7.h +++ /dev/null @@ -1,536 +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. - */ - -#ifndef __CROS_EC_GPIO_CHIP_NPCX7_H -#define __CROS_EC_GPIO_CHIP_NPCX7_H - -/*****************************************************************************/ -/* Macro functions for MIWU mapping table */ - -/* MIWU0 */ -/* Group A: NPCX_IRQ_MTC_WKINTAD_0 */ -#define NPCX_WUI_GPIO_8_0 WUI(0, MIWU_GROUP_1, 0) -#define NPCX_WUI_GPIO_8_1 WUI(0, MIWU_GROUP_1, 1) -#define NPCX_WUI_GPIO_8_2 WUI(0, MIWU_GROUP_1, 2) -#define NPCX_WUI_GPIO_8_3 WUI(0, MIWU_GROUP_1, 3) -#ifndef NPCX_PSL_MODE_SUPPORT -#define NPCX_WUI_GPIO_8_4 WUI(0, MIWU_GROUP_1, 4) /* Used as VSBY in PSL */ -#define NPCX_WUI_GPIO_8_5 WUI(0, MIWU_GROUP_1, 5) /* Used as PSL_OUT in PSL */ -#endif -#define NPCX_WUI_GPIO_8_6 WUI(0, MIWU_GROUP_1, 6) -#define NPCX_WUI_GPIO_8_7 WUI(0, MIWU_GROUP_1, 7) - -/* Group B: NPCX_IRQ_TWD_WKINTB_0 */ -#define NPCX_WUI_GPIO_9_0 WUI(0, MIWU_GROUP_2, 0) -#define NPCX_WUI_GPIO_9_1 WUI(0, MIWU_GROUP_2, 1) -#define NPCX_WUI_GPIO_9_2 WUI(0, MIWU_GROUP_2, 2) -#define NPCX_WUI_GPIO_9_3 WUI(0, MIWU_GROUP_2, 3) -#define NPCX_WUI_GPIO_9_4 WUI(0, MIWU_GROUP_2, 4) -#define NPCX_WUI_GPIO_9_5 WUI(0, MIWU_GROUP_2, 5) - -/* Group C: NPCX_IRQ_WKINTC_0 */ -#define NPCX_WUI_GPIO_9_6 WUI(0, MIWU_GROUP_3, 0) -#define NPCX_WUI_GPIO_9_7 WUI(0, MIWU_GROUP_3, 1) -#define NPCX_WUI_GPIO_A_0 WUI(0, MIWU_GROUP_3, 2) -#define NPCX_WUI_GPIO_A_1 WUI(0, MIWU_GROUP_3, 3) -#define NPCX_WUI_GPIO_A_2 WUI(0, MIWU_GROUP_3, 4) -#define NPCX_WUI_GPIO_A_3 WUI(0, MIWU_GROUP_3, 5) -#define NPCX_WUI_GPIO_A_4 WUI(0, MIWU_GROUP_3, 6) -#define NPCX_WUI_GPIO_A_5 WUI(0, MIWU_GROUP_3, 7) - -/* Group D: NPCX_IRQ_MTC_WKINTAD_0 */ -#define NPCX_WUI_GPIO_A_6 WUI(0, MIWU_GROUP_4, 0) -#define NPCX_WUI_GPIO_A_7 WUI(0, MIWU_GROUP_4, 1) -#define NPCX_WUI_GPIO_B_0 WUI(0, MIWU_GROUP_4, 2) -#define NPCX_WUI_GPIO_B_1 WUI(0, MIWU_GROUP_4, 5) -#define NPCX_WUI_GPIO_B_2 WUI(0, MIWU_GROUP_4, 6) - -/* Group E: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_B_3 WUI(0, MIWU_GROUP_5, 0) -#define NPCX_WUI_GPIO_B_4 WUI(0, MIWU_GROUP_5, 1) -#define NPCX_WUI_GPIO_B_5 WUI(0, MIWU_GROUP_5, 2) -#define NPCX_WUI_GPIO_B_7 WUI(0, MIWU_GROUP_5, 4) - -/* Group F: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_C_0 WUI(0, MIWU_GROUP_6, 0) -#define NPCX_WUI_GPIO_C_1 WUI(0, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_C_2 WUI(0, MIWU_GROUP_6, 2) -#define NPCX_WUI_GPIO_C_3 WUI(0, MIWU_GROUP_6, 3) -#define NPCX_WUI_GPIO_C_4 WUI(0, MIWU_GROUP_6, 4) -#define NPCX_WUI_GPIO_C_5 WUI(0, MIWU_GROUP_6, 5) -#define NPCX_WUI_GPIO_C_6 WUI(0, MIWU_GROUP_6, 6) -#define NPCX_WUI_GPIO_C_7 WUI(0, MIWU_GROUP_6, 7) - -/* Group G: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_D_0 WUI(0, MIWU_GROUP_7, 0) -#define NPCX_WUI_GPIO_D_1 WUI(0, MIWU_GROUP_7, 1) -#define NPCX_WUI_GPIO_D_2 WUI(0, MIWU_GROUP_7, 2) -#define NPCX_WUI_GPIO_D_3 WUI(0, MIWU_GROUP_7, 3) -#define NPCX_WUI_GPIO_D_4 WUI(0, MIWU_GROUP_7, 4) -#define NPCX_WUI_GPIO_D_5 WUI(0, MIWU_GROUP_7, 5) -#define NPCX_WUI_GPIO_D_7 WUI(0, MIWU_GROUP_7, 6) -#define NPCX_WUI_GPIO_E_0 WUI(0, MIWU_GROUP_7, 7) - -/* Group H: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_E_1 WUI(0, MIWU_GROUP_8, 0) -#define NPCX_WUI_GPIO_E_2 WUI(0, MIWU_GROUP_8, 1) -#define NPCX_WUI_GPIO_E_3 WUI(0, MIWU_GROUP_8, 2) -#define NPCX_WUI_GPIO_E_4 WUI(0, MIWU_GROUP_8, 3) -#define NPCX_WUI_GPIO_E_5 WUI(0, MIWU_GROUP_8, 4) -#define NPCX_WUI_GPIO_F_0 WUI(0, MIWU_GROUP_8, 5) -#define NPCX_WUI_GPIO_F_3 WUI(0, MIWU_GROUP_8, 6) -#ifndef NPCX_EXT32K_OSC_SUPPORT -#define NPCX_WUI_GPIO_E_7 WUI(0, MIWU_GROUP_8, 7) /* Used as CLKIN if support */ -#endif - -/* MIWU1 */ -/* Group A: NPCX_IRQ_WKINTA_1 */ -#define NPCX_WUI_GPIO_0_0 WUI(1, MIWU_GROUP_1, 0) -#define NPCX_WUI_GPIO_0_1 WUI(1, MIWU_GROUP_1, 1) -#define NPCX_WUI_GPIO_0_2 WUI(1, MIWU_GROUP_1, 2) -#define NPCX_WUI_GPIO_0_3 WUI(1, MIWU_GROUP_1, 3) -#define NPCX_WUI_GPIO_0_4 WUI(1, MIWU_GROUP_1, 4) -#define NPCX_WUI_GPIO_0_5 WUI(1, MIWU_GROUP_1, 5) -#define NPCX_WUI_GPIO_0_6 WUI(1, MIWU_GROUP_1, 6) -#define NPCX_WUI_GPIO_0_7 WUI(1, MIWU_GROUP_1, 7) - -/* Group B: NPCX_IRQ_WKINTB_1 */ -#define NPCX_WUI_GPIO_1_0 WUI(1, MIWU_GROUP_2, 0) -#define NPCX_WUI_GPIO_1_1 WUI(1, MIWU_GROUP_2, 1) -#define NPCX_WUI_GPIO_F_4 WUI(1, MIWU_GROUP_2, 2) -#define NPCX_WUI_GPIO_1_4 WUI(1, MIWU_GROUP_2, 4) -#define NPCX_WUI_GPIO_1_5 WUI(1, MIWU_GROUP_2, 5) -#define NPCX_WUI_GPIO_1_6 WUI(1, MIWU_GROUP_2, 6) -#define NPCX_WUI_GPIO_1_7 WUI(1, MIWU_GROUP_2, 7) - -/* Group C: NPCX_IRQ_KSI_WKINTC_1 */ -#define NPCX_WUI_GPIO_3_1 WUI(1, MIWU_GROUP_3, 0) -#define NPCX_WUI_GPIO_3_0 WUI(1, MIWU_GROUP_3, 1) -#define NPCX_WUI_GPIO_2_7 WUI(1, MIWU_GROUP_3, 2) -#define NPCX_WUI_GPIO_2_6 WUI(1, MIWU_GROUP_3, 3) -#define NPCX_WUI_GPIO_2_5 WUI(1, MIWU_GROUP_3, 4) -#define NPCX_WUI_GPIO_2_4 WUI(1, MIWU_GROUP_3, 5) -#define NPCX_WUI_GPIO_2_3 WUI(1, MIWU_GROUP_3, 6) -#define NPCX_WUI_GPIO_2_2 WUI(1, MIWU_GROUP_3, 7) - -/* Group D: NPCX_IRQ_WKINTD_1 */ -#define NPCX_WUI_GPIO_2_0 WUI(1, MIWU_GROUP_4, 0) -#define NPCX_WUI_GPIO_2_1 WUI(1, MIWU_GROUP_4, 1) -#define NPCX_WUI_GPIO_F_5 WUI(1, MIWU_GROUP_4, 2) -#define NPCX_WUI_GPIO_3_3 WUI(1, MIWU_GROUP_4, 3) -#define NPCX_WUI_GPIO_3_4 WUI(1, MIWU_GROUP_4, 4) -#define NPCX_WUI_GPIO_3_6 WUI(1, MIWU_GROUP_4, 6) -#define NPCX_WUI_GPIO_3_7 WUI(1, MIWU_GROUP_4, 7) - -/* Group E: NPCX_IRQ_WKINTE_1 */ -#define NPCX_WUI_GPIO_4_0 WUI(1, MIWU_GROUP_5, 0) -#define NPCX_WUI_GPIO_4_1 WUI(1, MIWU_GROUP_5, 1) -#define NPCX_WUI_GPIO_4_2 WUI(1, MIWU_GROUP_5, 2) -#define NPCX_WUI_GPIO_4_3 WUI(1, MIWU_GROUP_5, 3) -#define NPCX_WUI_GPIO_4_4 WUI(1, MIWU_GROUP_5, 4) -#define NPCX_WUI_GPIO_4_5 WUI(1, MIWU_GROUP_5, 5) -#define NPCX_WUI_GPIO_4_6 WUI(1, MIWU_GROUP_5, 6) -#define NPCX_WUI_GPIO_4_7 WUI(1, MIWU_GROUP_5, 7) - -/* Group F: NPCX_IRQ_WKINTF_1 */ -#define NPCX_WUI_GPIO_5_0 WUI(1, MIWU_GROUP_6, 0) -#define NPCX_WUI_GPIO_5_1 WUI(1, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_5_2 WUI(1, MIWU_GROUP_6, 2) -#define NPCX_WUI_GPIO_5_3 WUI(1, MIWU_GROUP_6, 3) -#define NPCX_WUI_GPIO_5_4 WUI(1, MIWU_GROUP_6, 4) -#define NPCX_WUI_GPIO_5_5 WUI(1, MIWU_GROUP_6, 5) -#define NPCX_WUI_GPIO_5_6 WUI(1, MIWU_GROUP_6, 6) -#define NPCX_WUI_GPIO_5_7 WUI(1, MIWU_GROUP_6, 7) - -/* Group G: NPCX_IRQ_WKINTG_1 */ -#define NPCX_WUI_GPIO_6_0 WUI(1, MIWU_GROUP_7, 0) -#define NPCX_WUI_GPIO_6_1 WUI(1, MIWU_GROUP_7, 1) -#define NPCX_WUI_GPIO_6_2 WUI(1, MIWU_GROUP_7, 2) -#define NPCX_WUI_GPIO_6_3 WUI(1, MIWU_GROUP_7, 3) -#define NPCX_WUI_GPIO_6_4 WUI(1, MIWU_GROUP_7, 4) -#ifndef NPCX_EXT32K_OSC_SUPPORT -#define NPCX_WUI_GPIO_7_1 WUI(1, MIWU_GROUP_7, 7) /* Used as CLKOUT if support*/ -#endif - -/* Group H: NPCX_IRQ_WKINTH_1 */ -#define NPCX_WUI_GPIO_7_0 WUI(1, MIWU_GROUP_8, 0) -#define NPCX_WUI_GPIO_6_7 WUI(1, MIWU_GROUP_8, 1) -#define NPCX_WUI_GPIO_7_2 WUI(1, MIWU_GROUP_8, 2) -#define NPCX_WUI_GPIO_7_3 WUI(1, MIWU_GROUP_8, 3) -#define NPCX_WUI_GPIO_7_4 WUI(1, MIWU_GROUP_8, 4) -#define NPCX_WUI_GPIO_7_5 WUI(1, MIWU_GROUP_8, 5) -#define NPCX_WUI_GPIO_7_6 WUI(1, MIWU_GROUP_8, 6) - -/* MIWU2 */ -/* Group F: NPCX_IRQ_WKINTFG_2 */ -#define NPCX_WUI_GPIO_F_1 WUI(2, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_F_2 WUI(2, MIWU_GROUP_6, 2) - -/* Others GPO without MIWU functionality */ -#define NPCX_WUI_GPIO_1_2 WUI_NONE -#define NPCX_WUI_GPIO_1_3 WUI_NONE /* Software strap pin GP_SEL1_L */ -#define NPCX_WUI_GPIO_3_2 WUI_NONE -#define NPCX_WUI_GPIO_3_5 WUI_NONE -#define NPCX_WUI_GPIO_6_5 WUI_NONE /* Software strap pin FLPRG_L */ -#define NPCX_WUI_GPIO_6_6 WUI_NONE -#define NPCX_WUI_GPIO_7_7 WUI_NONE -#define NPCX_WUI_GPIO_B_6 WUI_NONE /* Software strap pin GP_SEL0_L */ -#define NPCX_WUI_GPIO_D_6 WUI_NONE - -/*****************************************************************************/ -/* Macro functions for Alternative mapping table */ - -/* I2C Module */ -#define NPCX_ALT_GPIO_B_4 ALT(B, 4, NPCX_ALT(2, I2C0_0_SL)) /* SMB0SDA0 */ -#define NPCX_ALT_GPIO_B_5 ALT(B, 5, NPCX_ALT(2, I2C0_0_SL)) /* SMB0SCL0 */ -#define NPCX_ALT_GPIO_8_7 ALT(8, 7, NPCX_ALT(2, I2C1_0_SL)) /* SMB1SDA0 */ -#define NPCX_ALT_GPIO_9_0 ALT(9, 0, NPCX_ALT(2, I2C1_0_SL)) /* SMB1SCL0 */ -#define NPCX_ALT_GPIO_9_1 ALT(9, 1, NPCX_ALT(2, I2C2_0_SL)) /* SMB2SDA0 */ -#define NPCX_ALT_GPIO_9_2 ALT(9, 2, NPCX_ALT(2, I2C2_0_SL)) /* SMB2SCL0 */ -#define NPCX_ALT_GPIO_D_0 ALT(D, 0, NPCX_ALT(2, I2C3_0_SL)) /* SMB3SDA0 */ -#define NPCX_ALT_GPIO_D_1 ALT(D, 1, NPCX_ALT(2, I2C3_0_SL)) /* SMB3SCL0 */ -/* Pin-Mux for PSL/UART2/SMB4_0 */ -#ifdef NPCX_PSL_MODE_SUPPORT -#if defined(NPCX_SECOND_UART) && (CONFIG_CONSOLE_UART == 1) -#define NPCX_ALT_GPIO_8_6 ALT(8, 6, NPCX_ALT(A, UART2_SL)) /* CR_SOUT2 */ -#define NPCX_ALT_GPIO_8_5 /* Used as PSL_OUT */ -#else -#define NPCX_ALT_GPIO_8_6 /* No I2CSDA since GPIO85 used as PSL_OUT */ -#define NPCX_ALT_GPIO_8_5 /* Used as PSL_OUT */ -#endif -#else -#define NPCX_ALT_GPIO_8_6 ALT(8, 6, NPCX_ALT(2, I2C4_0_SL)) /* SMB4SDA0 */ -#define NPCX_ALT_GPIO_8_5 ALT(8, 5, NPCX_ALT(2, I2C4_0_SL)) /* SMB4SCL0 */ -#endif - -#define NPCX_ALT_GPIO_F_2 ALT(F, 2, NPCX_ALT(6, I2C4_1_SL)) /* SMB4SDA1 */ -#define NPCX_ALT_GPIO_F_3 ALT(F, 3, NPCX_ALT(6, I2C4_1_SL)) /* SMB4SCL1 */ -#define NPCX_ALT_GPIO_3_6 ALT(3, 6, NPCX_ALT(2, I2C5_0_SL)) /* SMB5SDA0 */ -#define NPCX_ALT_GPIO_3_3 ALT(3, 3, NPCX_ALT(2, I2C5_0_SL)) /* SMB5SCL0 */ -#define NPCX_ALT_GPIO_F_4 ALT(F, 4, NPCX_ALT(6, I2C5_1_SL)) /* SMB5SDA1 */ -#define NPCX_ALT_GPIO_F_5 ALT(F, 5, NPCX_ALT(6, I2C5_1_SL)) /* SMB5SCL1 */ -/* Pin-Mux for PWM1/SMB6_0 */ -#if NPCX7_PWM1_SEL -#define NPCX_ALT_GPIO_C_1 /* No I2CSDA since GPIOC2 used as PWM1 */ -#define NPCX_ALT_GPIO_C_2 ALT(C, 2, NPCX_ALT(4, PWM1_SL)) /* PWM1 */ -#else -#define NPCX_ALT_GPIO_C_1 ALT(C, 1, NPCX_ALT(2, I2C6_0_SL)) /* SMB6SDA0 */ -#define NPCX_ALT_GPIO_C_2 ALT(C, 2, NPCX_ALT(2, I2C6_0_SL)) /* SMB6SCL0 */ -#endif -#define NPCX_ALT_GPIO_E_3 ALT(E, 3, NPCX_ALT(6, I2C6_1_SL)) /* SMB6SDA1 */ -#define NPCX_ALT_GPIO_E_4 ALT(E, 4, NPCX_ALT(6, I2C6_1_SL)) /* SMB6SCL1 */ -#define NPCX_ALT_GPIO_B_2 ALT(B, 2, NPCX_ALT(2, I2C7_0_SL)) /* SMB7SDA0 */ -#define NPCX_ALT_GPIO_B_3 ALT(B, 3, NPCX_ALT(2, I2C7_0_SL)) /* SMB7SCL0 */ - -/* ADC Module */ -#define NPCX_ALT_GPIO_4_5 ALT(4, 5, NPCX_ALT(6, ADC0_SL)) /* ADC0 */ -#define NPCX_ALT_GPIO_4_4 ALT(4, 4, NPCX_ALT(6, ADC1_SL)) /* ADC1 */ -#define NPCX_ALT_GPIO_4_3 ALT(4, 3, NPCX_ALT(6, ADC2_SL)) /* ADC2 */ -#define NPCX_ALT_GPIO_4_2 ALT(4, 2, NPCX_ALT(6, ADC3_SL)) /* ADC3 */ -#define NPCX_ALT_GPIO_4_1 ALT(4, 1, NPCX_ALT(6, ADC4_SL)) /* ADC4 */ -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_2) -#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(3, PS2_2_SL)) /* PS2_CLK2 */ -#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(3, PS2_2_SL)) /* PS2_DATA2 */ -#else -#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(F, ADC5_SL)) /* ADC5 */ -#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(F, ADC6_SL)) /* ADC6 */ -#endif -#define NPCX_ALT_GPIO_E_1 ALT(E, 1, NPCX_ALT(F, ADC7_SL)) /* ADC7 */ -#define NPCX_ALT_GPIO_F_1 ALT(F, 1, NPCX_ALT(F, ADC8_SL)) /* ADC8 */ -#define NPCX_ALT_GPIO_F_0 ALT(F, 0, NPCX_ALT(F, ADC9_SL)) /* ADC9 */ - -/* PS/2 Module */ -#define NPCX_ALT_GPIO_6_2 ALT(6, 2, NPCX_ALT(3, PS2_1_SL)) /* PS2_CLK1 */ -#define NPCX_ALT_GPIO_6_3 ALT(6, 3, NPCX_ALT(3, PS2_1_SL)) /* PS2_DATA1 */ -#define NPCX_ALT_GPIO_6_7 ALT(6, 7, NPCX_ALT(3, PS2_0_SL)) /* PS2_CLK0 */ -#define NPCX_ALT_GPIO_7_0 ALT(7, 0, NPCX_ALT(3, PS2_0_SL)) /* PS2_DATA0 */ - -/* UART Module */ -#define NPCX_ALT_GPIO_6_4 ALT(6, 4, NPCX_ALT(C, UART_SL2)) /* CR_SIN SEL2 */ -#define NPCX_ALT_GPIO_6_5 ALT(6, 5, NPCX_ALT(C, UART_SL2)) /* CR_SOUT SEL2 */ - -/* PWM Module */ -#define NPCX_ALT_GPIO_C_3 ALT(C, 3, NPCX_ALT(4, PWM0_SL)) /* PWM0 */ -#define NPCX_ALT_GPIO_C_4 ALT(C, 4, NPCX_ALT(4, PWM2_SL)) /* PWM2 */ -#define NPCX_ALT_GPIO_8_0 ALT(8, 0, NPCX_ALT(4, PWM3_SL)) /* PWM3 */ -#define NPCX_ALT_GPIO_B_6 ALT(B, 6, NPCX_ALT(4, PWM4_SL)) /* PWM4 */ -#define NPCX_ALT_GPIO_B_7 ALT(B, 7, NPCX_ALT(4, PWM5_SL)) /* PWM5 */ -#define NPCX_ALT_GPIO_C_0 ALT(C, 0, NPCX_ALT(4, PWM6_SL)) /* PWM6 */ -#define NPCX_ALT_GPIO_6_0 ALT(6, 0, NPCX_ALT(4, PWM7_SL)) /* PWM7 */ - -/* MFT Module */ -#define NPCX_ALT_GPIO_4_0 ALT(4, 0, NPCX_ALT(3, TA1_SL1)) /* TA1_SEL1 */ -#define NPCX_ALT_GPIO_7_3 ALT(7, 3, NPCX_ALT(3, TA2_SL1)) /* TA2_SEL1 */ -#define NPCX_ALT_GPIO_9_3 ALT(9, 3, NPCX_ALT(C, TA1_SL2)) /* TA1_SEL2 */ -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3) -#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, PS2_3_SL2)) /* PS2_CLK3 */ -#else -#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, TA2_SL2)) /* TA2_SEL2 */ -#endif - -/* Keyboard Scan Module */ -#define NPCX_ALT_GPIO_3_1 ALT(3, 1, NPCX_ALT_INV(7, NO_KSI0_SL)) /* KSI0 */ -#define NPCX_ALT_GPIO_3_0 ALT(3, 0, NPCX_ALT_INV(7, NO_KSI1_SL)) /* KSI1 */ -#define NPCX_ALT_GPIO_2_7 ALT(2, 7, NPCX_ALT_INV(7, NO_KSI2_SL)) /* KSI2 */ -#define NPCX_ALT_GPIO_2_6 ALT(2, 6, NPCX_ALT_INV(7, NO_KSI3_SL)) /* KSI3 */ -#define NPCX_ALT_GPIO_2_5 ALT(2, 5, NPCX_ALT_INV(7, NO_KSI4_SL)) /* KSI4 */ -#define NPCX_ALT_GPIO_2_4 ALT(2, 4, NPCX_ALT_INV(7, NO_KSI5_SL)) /* KSI5 */ -#define NPCX_ALT_GPIO_2_3 ALT(2, 3, NPCX_ALT_INV(7, NO_KSI6_SL)) /* KSI6 */ -#define NPCX_ALT_GPIO_2_2 ALT(2, 2, NPCX_ALT_INV(7, NO_KSI7_SL)) /* KSI7 */ -#define NPCX_ALT_GPIO_2_1 ALT(2, 1, NPCX_ALT_INV(8, NO_KSO00_SL)) /* KSO00 */ -#define NPCX_ALT_GPIO_2_0 ALT(2, 0, NPCX_ALT_INV(8, NO_KSO01_SL)) /* KSO01 */ -#define NPCX_ALT_GPIO_1_7 ALT(1, 7, NPCX_ALT_INV(8, NO_KSO02_SL)) /* KSO02 */ -#define NPCX_ALT_GPIO_1_6 ALT(1, 6, NPCX_ALT_INV(8, NO_KSO03_SL)) /* KSO03 */ -#define NPCX_ALT_GPIO_1_5 ALT(1, 5, NPCX_ALT_INV(8, NO_KSO04_SL)) /* KSO04 */ -#define NPCX_ALT_GPIO_1_4 ALT(1, 4, NPCX_ALT_INV(8, NO_KSO05_SL)) /* KSO05 */ -#define NPCX_ALT_GPIO_1_3 ALT(1, 3, NPCX_ALT_INV(8, NO_KSO06_SL)) /* KSO06 */ -#define NPCX_ALT_GPIO_1_2 ALT(1, 2, NPCX_ALT_INV(8, NO_KSO07_SL)) /* KSO07 */ -/* KSO08 & CR_SOUT */ -#define NPCX_ALT_GPIO_1_1 ALT(1, 1, NPCX_ALT_INV(9, NO_KSO08_SL)) - /* KSO09 & CR_SIN */ -#define NPCX_ALT_GPIO_1_0 ALT(1, 0, NPCX_ALT_INV(9, NO_KSO09_SL)) -#define NPCX_ALT_GPIO_0_7 ALT(0, 7, NPCX_ALT_INV(9, NO_KSO10_SL)) /* KSO10 */ -#define NPCX_ALT_GPIO_0_6 ALT(0, 6, NPCX_ALT_INV(9, NO_KSO11_SL)) /* KSO11 */ -#define NPCX_ALT_GPIO_0_5 ALT(0, 5, NPCX_ALT_INV(9, NO_KSO12_SL)) /* KSO12 */ -#define NPCX_ALT_GPIO_0_4 ALT(0, 4, NPCX_ALT_INV(9, NO_KSO13_SL)) /* KSO13 */ -#define NPCX_ALT_GPIO_8_2 ALT(8, 2, NPCX_ALT_INV(9, NO_KSO14_SL)) /* KSO14 */ -#define NPCX_ALT_GPIO_8_3 ALT(8, 3, NPCX_ALT_INV(9, NO_KSO15_SL)) /* KSO15 */ -#define NPCX_ALT_GPIO_0_3 ALT(0, 3, NPCX_ALT_INV(A, NO_KSO16_SL)) /* KSO16 */ -#define NPCX_ALT_GPIO_B_1 ALT(B, 1, NPCX_ALT_INV(A, NO_KSO17_SL)) /* KSO17 */ - -/* Clock module (Optional) */ -#ifdef NPCX_EXT32K_OSC_SUPPORT -#define NPCX_ALT_GPIO_E_7 /* No 32KCLKIN */ -#else -#define NPCX_ALT_GPIO_E_7 ALT(E, 7, NPCX_ALT(A, 32KCLKIN_SL)) /* 32KCLKIN */ -#endif - -/* Pin-Mux for UART2/32KHZ_OUT */ -#if defined(NPCX_SECOND_UART) && (CONFIG_CONSOLE_UART == 1) -#define NPCX_ALT_GPIO_7_5 ALT(7, 5, NPCX_ALT(A, UART2_SL)) /* CR_SIN2 */ -#else -#define NPCX_ALT_GPIO_7_5 ALT(7, 5, NPCX_ALT(A, 32K_OUT_SL)) /* 32KHZ_OUT */ -#endif - -/* PSL module (Optional) */ -#ifdef NPCX_PSL_MODE_SUPPORT -#define NPCX_ALT_GPIO_D_2 ALT(D, 2, NPCX_ALT_INV(D, NPSL_IN1_SL)) /* PSL_IN1 */ -#define NPCX_ALT_GPIO_0_0 ALT(0, 0, NPCX_ALT_INV(D, NPSL_IN2_SL)) /* PSL_IN2 */ -#define NPCX_ALT_GPIO_0_1 ALT(0, 1, NPCX_ALT(D, PSL_IN3_SL)) /* PSL_IN3 */ -#define NPCX_ALT_GPIO_0_2 ALT(0, 2, NPCX_ALT(D, PSL_IN4_SL)) /* PSL_IN4 */ -#else -#define NPCX_ALT_GPIO_D_2 /* NO PSL in NPCX7mnG series */ -#define NPCX_ALT_GPIO_0_0 /* NO PSL in NPCX7mnG series */ -#define NPCX_ALT_GPIO_0_1 /* NO PSL in NPCX7mnG series */ -#define NPCX_ALT_GPIO_0_2 /* NO PSL in NPCX7mnG series */ -#endif - -/* WOV module (Optional) */ -#if defined(NPCX_WOV_SUPPORT) && \ - (defined(CONFIG_AUDIO_CODEC_I2S_RX) || defined(CONFIG_AUDIO_CODEC_WOV)) -#define NPCX_ALT_GPIO_9_5 /* Disable SPIP module if WOV is supported */ -#define NPCX_ALT_GPIO_A_3 /* Disable SPIP module if WOV is supported */ -#define NPCX_ALT_GPIO_A_1 /* Disable SPIP module if WOV is supported */ - -#define NPCX_ALT_GPIO_A_5 ALT(A, 5, NPCX_ALT(E, I2S_SL)) /* I2S_SYNC */ -#define NPCX_ALT_GPIO_A_7 ALT(A, 7, NPCX_ALT(E, I2S_SL)) /* I2S_SCLK */ -#define NPCX_ALT_GPIO_B_0 ALT(B, 0, NPCX_ALT(E, I2S_SL)) /* I2S_DATA */ -#define NPCX_ALT_GPIO_9_4 ALT(9, 4, NPCX_ALT(E, WOV_SL)) /* DMIC_CLK */ -#define NPCX_ALT_GPIO_9_7 ALT(9, 7, NPCX_ALT(E, WOV_SL)) /* DMIC_IN */ -#else -/* SPI Module */ -#define NPCX_ALT_GPIO_9_5 ALT(9, 5, NPCX_ALT(0, SPIP_SL)) /* SPIP_MISO */ -#define NPCX_ALT_GPIO_A_5 ALT(A, 5, NPCX_ALT(0, SPIP_SL)) /* SPIP_CS1 */ -#define NPCX_ALT_GPIO_A_3 ALT(A, 3, NPCX_ALT(0, SPIP_SL)) /* SPIP_MOSI */ -#define NPCX_ALT_GPIO_A_1 ALT(A, 1, NPCX_ALT(0, SPIP_SL)) /* SPIP_SCLK */ - -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3) -#define NPCX_ALT_GPIO_A_7 ALT(A, 7, NPCX_ALT(C, PS2_3_SL2)) /* PS2_DAT3 */ -#else -#define NPCX_ALT_GPIO_A_7 -#endif -#define NPCX_ALT_GPIO_B_0 -#define NPCX_ALT_GPIO_9_4 -#define NPCX_ALT_GPIO_9_7 -#endif - -#define NPCX_ALT_TABLE { \ - NPCX_ALT_GPIO_0_0 /* PSL_IN2 */ \ - NPCX_ALT_GPIO_0_1 /* PSL_IN3 */ \ - NPCX_ALT_GPIO_0_2 /* PSL_IN4 */ \ - NPCX_ALT_GPIO_0_3 /* KSO16 */ \ - NPCX_ALT_GPIO_0_4 /* KSO13 */ \ - NPCX_ALT_GPIO_0_5 /* KSO12 */ \ - NPCX_ALT_GPIO_0_6 /* KSO11 */ \ - NPCX_ALT_GPIO_0_7 /* KSO10 */ \ - NPCX_ALT_GPIO_1_0 /* KSO09 & CR_SIN */ \ - NPCX_ALT_GPIO_1_1 /* KSO08 & CR_SOUT */ \ - NPCX_ALT_GPIO_1_2 /* KSO07 */ \ - NPCX_ALT_GPIO_1_3 /* KSO06 */ \ - NPCX_ALT_GPIO_1_4 /* KSO05 */ \ - NPCX_ALT_GPIO_1_5 /* KSO04 */ \ - NPCX_ALT_GPIO_1_6 /* KSO03 */ \ - NPCX_ALT_GPIO_1_7 /* KSO02 */ \ - NPCX_ALT_GPIO_2_0 /* KSO01 */ \ - NPCX_ALT_GPIO_2_1 /* KSO00 */ \ - NPCX_ALT_GPIO_2_2 /* KSI7 */ \ - NPCX_ALT_GPIO_2_3 /* KSI6 */ \ - NPCX_ALT_GPIO_2_4 /* KSI5 */ \ - NPCX_ALT_GPIO_2_5 /* KSI4 */ \ - NPCX_ALT_GPIO_2_6 /* KSI3 */ \ - NPCX_ALT_GPIO_2_7 /* KSI2 */ \ - NPCX_ALT_GPIO_3_0 /* KSI1 */ \ - NPCX_ALT_GPIO_3_1 /* KSI0 */ \ - NPCX_ALT_GPIO_3_3 /* SMB5SCL0 */ \ - NPCX_ALT_GPIO_3_4 /* ADC6/PS2_DAT2 */ \ - NPCX_ALT_GPIO_3_6 /* SMB5SDA0 */ \ - NPCX_ALT_GPIO_3_7 /* ADC5/PS2_CLK2 */ \ - NPCX_ALT_GPIO_4_0 /* TA1_SEL1 */ \ - NPCX_ALT_GPIO_4_1 /* ADC4 */ \ - NPCX_ALT_GPIO_4_2 /* ADC3 */ \ - NPCX_ALT_GPIO_4_3 /* ADC2 */ \ - NPCX_ALT_GPIO_4_4 /* ADC1 */ \ - NPCX_ALT_GPIO_4_5 /* ADC0 */ \ - NPCX_ALT_GPIO_6_0 /* PWM7 */ \ - NPCX_ALT_GPIO_6_2 /* PS2_CLK1 */ \ - NPCX_ALT_GPIO_6_3 /* PS2_DAT1 */ \ - NPCX_ALT_GPIO_6_4 /* CR_SIN1 SEL2 */ \ - NPCX_ALT_GPIO_6_5 /* CR_SOUT1 SEL2 */ \ - NPCX_ALT_GPIO_6_7 /* PS2_CLK0 */ \ - NPCX_ALT_GPIO_7_0 /* PS2_DAT0 */ \ - NPCX_ALT_GPIO_7_3 /* TA2_SEL1 */ \ - NPCX_ALT_GPIO_7_5 /* CR_SIN2 & 32KHZ_OUT */ \ - NPCX_ALT_GPIO_8_0 /* PWM3 */ \ - NPCX_ALT_GPIO_8_2 /* KSO14 */ \ - NPCX_ALT_GPIO_8_3 /* KSO15 */ \ - NPCX_ALT_GPIO_8_5 /* SMB4SCL0 */ \ - NPCX_ALT_GPIO_8_6 /* CR_SOUT2 & SMB4SDA0 */ \ - NPCX_ALT_GPIO_8_7 /* SMB1SDA0 */ \ - NPCX_ALT_GPIO_9_0 /* SMB1SCL0 */ \ - NPCX_ALT_GPIO_9_1 /* SMB2SDA0 */ \ - NPCX_ALT_GPIO_9_2 /* SMB2SCL0 */ \ - NPCX_ALT_GPIO_9_3 /* TA1_SEL2 */ \ - NPCX_ALT_GPIO_9_4 /* DMIC_CLK */ \ - NPCX_ALT_GPIO_9_5 /* SPIP_MISO */ \ - NPCX_ALT_GPIO_9_7 /* DMIC_IN */ \ - NPCX_ALT_GPIO_A_1 /* SPIP_SCLK */ \ - NPCX_ALT_GPIO_A_3 /* SPIP_MOSI */ \ - NPCX_ALT_GPIO_A_5 /* SPIP_CS1 & I2S_SYNC */ \ - NPCX_ALT_GPIO_A_6 /* TA2_SEL2/PS2_CLK3 */ \ - NPCX_ALT_GPIO_A_7 /* I2S_SCLK/PS2_DAT3 */ \ - NPCX_ALT_GPIO_B_0 /* I2S_DATA */ \ - NPCX_ALT_GPIO_B_1 /* KSO17 */ \ - NPCX_ALT_GPIO_B_2 /* SMB7SDA0 */ \ - NPCX_ALT_GPIO_B_3 /* SMB7SCL0 */ \ - NPCX_ALT_GPIO_B_4 /* SMB0SDA0 */ \ - NPCX_ALT_GPIO_B_5 /* SMB0SCL0 */ \ - NPCX_ALT_GPIO_B_6 /* PWM4 */ \ - NPCX_ALT_GPIO_B_7 /* PWM5 */ \ - NPCX_ALT_GPIO_C_0 /* PWM6 */ \ - NPCX_ALT_GPIO_C_1 /* SMB6SDA0 */ \ - NPCX_ALT_GPIO_C_2 /* SMB6SCL0 & PWM1 */ \ - NPCX_ALT_GPIO_C_3 /* PWM0 */ \ - NPCX_ALT_GPIO_C_4 /* PWM2 */ \ - NPCX_ALT_GPIO_D_0 /* SMB3SDA0 */ \ - NPCX_ALT_GPIO_D_1 /* SMB3SCL0 */ \ - NPCX_ALT_GPIO_D_2 /* PSL_IN1 */ \ - NPCX_ALT_GPIO_E_1 /* ADC7 */ \ - NPCX_ALT_GPIO_E_3 /* SMB6SDA1 */ \ - NPCX_ALT_GPIO_E_4 /* SMB6SCL1 */ \ - NPCX_ALT_GPIO_E_7 /* 32KCLKIN */ \ - NPCX_ALT_GPIO_F_0 /* ADC9 */ \ - NPCX_ALT_GPIO_F_1 /* ADC8 */ \ - NPCX_ALT_GPIO_F_2 /* SMB4SDA1 */ \ - NPCX_ALT_GPIO_F_3 /* SMB4SCL1 */ \ - NPCX_ALT_GPIO_F_4 /* SMB5SDA1 */ \ - NPCX_ALT_GPIO_F_5 /* SMB5SCL1 */ \ -} - -/*****************************************************************************/ -/* Macro functions for Low-Voltage mapping table */ - -/* Low-Voltage GPIO Control 0 */ -#define NPCX_LVOL_CTRL_0_0 NPCX_GPIO(B, 5) -#define NPCX_LVOL_CTRL_0_1 NPCX_GPIO(B, 4) -#define NPCX_LVOL_CTRL_0_2 NPCX_GPIO(B, 3) -#define NPCX_LVOL_CTRL_0_3 NPCX_GPIO(B, 2) -#define NPCX_LVOL_CTRL_0_4 NPCX_GPIO(9, 0) -#define NPCX_LVOL_CTRL_0_5 NPCX_GPIO(8, 7) -#define NPCX_LVOL_CTRL_0_6 NPCX_GPIO(0, 0) -#define NPCX_LVOL_CTRL_0_7 NPCX_GPIO(3, 3) - -/* Low-Voltage GPIO Control 1 */ -#define NPCX_LVOL_CTRL_1_0 NPCX_GPIO(9, 2) -#define NPCX_LVOL_CTRL_1_1 NPCX_GPIO(9, 1) -#define NPCX_LVOL_CTRL_1_2 NPCX_GPIO(D, 1) -#define NPCX_LVOL_CTRL_1_3 NPCX_GPIO(D, 0) -#define NPCX_LVOL_CTRL_1_4 NPCX_GPIO(3, 6) -#define NPCX_LVOL_CTRL_1_5 NPCX_GPIO(6, 4) -#define NPCX_LVOL_CTRL_1_6 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_1_7 NPCX_GPIO_NONE - -/* Low-Voltage GPIO Control 2 */ -#define NPCX_LVOL_CTRL_2_0 NPCX_GPIO(7, 4) -#ifdef NPCX_PSL_MODE_SUPPORT -#define NPCX_LVOL_CTRL_2_1 NPCX_GPIO_NONE /* Remove 1.8V support since PSL */ -#define NPCX_LVOL_CTRL_2_2 NPCX_GPIO_NONE /* Remove 1.8V support since PSL */ -#else -#define NPCX_LVOL_CTRL_2_1 NPCX_GPIO(8, 4) -#define NPCX_LVOL_CTRL_2_2 NPCX_GPIO(8, 5) -#endif - -#define NPCX_LVOL_CTRL_2_3 NPCX_GPIO(7, 3) -#define NPCX_LVOL_CTRL_2_4 NPCX_GPIO(C, 1) -#define NPCX_LVOL_CTRL_2_5 NPCX_GPIO(C, 7) -#ifdef NPCX_EXT32K_OSC_SUPPORT -#define NPCX_LVOL_CTRL_2_6 NPCX_GPIO_NONE /* Remove 1.8V support since CLKIN */ -#else -#define NPCX_LVOL_CTRL_2_6 NPCX_GPIO(E, 7) -#endif -#define NPCX_LVOL_CTRL_2_7 NPCX_GPIO(3, 4) - -/* Low-Voltage GPIO Control 3 */ -#define NPCX_LVOL_CTRL_3_0 NPCX_GPIO(C, 6) -#define NPCX_LVOL_CTRL_3_1 NPCX_GPIO(3, 7) -#define NPCX_LVOL_CTRL_3_2 NPCX_GPIO(4, 0) -#ifdef NPCX_EXT32K_OSC_SUPPORT -#define NPCX_LVOL_CTRL_3_3 NPCX_GPIO_NONE /* Remove 1.8V support since CLKOUT*/ -#else -#define NPCX_LVOL_CTRL_3_3 NPCX_GPIO(7, 1) -#endif -#define NPCX_LVOL_CTRL_3_4 NPCX_GPIO(8, 2) -#define NPCX_LVOL_CTRL_3_5 NPCX_GPIO(7, 5) -#define NPCX_LVOL_CTRL_3_6 NPCX_GPIO(8, 0) -#define NPCX_LVOL_CTRL_3_7 NPCX_GPIO(C, 5) - -/* Low-Voltage GPIO Control 4 */ -#define NPCX_LVOL_CTRL_4_0 NPCX_GPIO(8, 6) -#define NPCX_LVOL_CTRL_4_1 NPCX_GPIO(C, 2) -#define NPCX_LVOL_CTRL_4_2 NPCX_GPIO(F, 3) -#define NPCX_LVOL_CTRL_4_3 NPCX_GPIO(F, 2) -#define NPCX_LVOL_CTRL_4_4 NPCX_GPIO(F, 5) -#define NPCX_LVOL_CTRL_4_5 NPCX_GPIO(F, 4) -#define NPCX_LVOL_CTRL_4_6 NPCX_GPIO(E, 4) -#define NPCX_LVOL_CTRL_4_7 NPCX_GPIO(E, 3) - -/* Low-Voltage GPIO Control 5 */ -#define NPCX_LVOL_CTRL_5_0 NPCX_GPIO(7, 2) -#define NPCX_LVOL_CTRL_5_1 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_2 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_3 NPCX_GPIO(5, 0) -#define NPCX_LVOL_CTRL_5_4 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_5 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_6 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_7 NPCX_GPIO_NONE - -/* 6 Low-Voltage Control Groups on npcx7 */ -#define NPCX_LVOL_TABLE { { NPCX_LVOL_CTRL_ITEMS(0), }, \ - { NPCX_LVOL_CTRL_ITEMS(1), }, \ - { NPCX_LVOL_CTRL_ITEMS(2), }, \ - { NPCX_LVOL_CTRL_ITEMS(3), }, \ - { NPCX_LVOL_CTRL_ITEMS(4), }, \ - { NPCX_LVOL_CTRL_ITEMS(5), }, } - -#endif /* __CROS_EC_GPIO_CHIP_NPCX7_H */ diff --git a/chip/npcx/gpio_chip-npcx9.h b/chip/npcx/gpio_chip-npcx9.h deleted file mode 100644 index 005a03d83e..0000000000 --- a/chip/npcx/gpio_chip-npcx9.h +++ /dev/null @@ -1,470 +0,0 @@ -/* Copyright 2020 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_GPIO_CHIP_NPCX9_H -#define __CROS_EC_GPIO_CHIP_NPCX9_H - -#ifndef NPCX9_PWM1_SEL -#define NPCX9_PWM1_SEL 0 -#endif /* NPCX9_PWM1_SEL */ - -/*****************************************************************************/ -/* Macro functions for MIWU mapping table */ - -/* MIWU0 */ -/* Group A: NPCX_IRQ_MTC_WKINTAD_0 */ -#define NPCX_WUI_GPIO_8_0 WUI(0, MIWU_GROUP_1, 0) -#define NPCX_WUI_GPIO_8_1 WUI(0, MIWU_GROUP_1, 1) -#define NPCX_WUI_GPIO_8_2 WUI(0, MIWU_GROUP_1, 2) -#define NPCX_WUI_GPIO_8_3 WUI(0, MIWU_GROUP_1, 3) -#define NPCX_WUI_GPIO_8_6 WUI(0, MIWU_GROUP_1, 6) -#define NPCX_WUI_GPIO_8_7 WUI(0, MIWU_GROUP_1, 7) - -/* Group B: NPCX_IRQ_TWD_WKINTB_0 */ -#define NPCX_WUI_GPIO_9_0 WUI(0, MIWU_GROUP_2, 0) -#define NPCX_WUI_GPIO_9_1 WUI(0, MIWU_GROUP_2, 1) -#define NPCX_WUI_GPIO_9_2 WUI(0, MIWU_GROUP_2, 2) -#define NPCX_WUI_GPIO_9_3 WUI(0, MIWU_GROUP_2, 3) -#define NPCX_WUI_GPIO_9_4 WUI(0, MIWU_GROUP_2, 4) -#define NPCX_WUI_GPIO_9_5 WUI(0, MIWU_GROUP_2, 5) - -/* Group C: NPCX_IRQ_WKINTC_0 */ -#define NPCX_WUI_GPIO_9_6 WUI(0, MIWU_GROUP_3, 0) -#define NPCX_WUI_GPIO_9_7 WUI(0, MIWU_GROUP_3, 1) -#define NPCX_WUI_GPIO_A_0 WUI(0, MIWU_GROUP_3, 2) -#define NPCX_WUI_GPIO_A_1 WUI(0, MIWU_GROUP_3, 3) -#define NPCX_WUI_GPIO_A_2 WUI(0, MIWU_GROUP_3, 4) -#define NPCX_WUI_GPIO_A_3 WUI(0, MIWU_GROUP_3, 5) -#define NPCX_WUI_GPIO_A_4 WUI(0, MIWU_GROUP_3, 6) -#define NPCX_WUI_GPIO_A_5 WUI(0, MIWU_GROUP_3, 7) - -/* Group D: NPCX_IRQ_MTC_WKINTAD_0 */ -#define NPCX_WUI_GPIO_A_6 WUI(0, MIWU_GROUP_4, 0) -#define NPCX_WUI_GPIO_A_7 WUI(0, MIWU_GROUP_4, 1) -#define NPCX_WUI_GPIO_B_0 WUI(0, MIWU_GROUP_4, 2) -#define NPCX_WUI_GPIO_B_1 WUI(0, MIWU_GROUP_4, 5) -#define NPCX_WUI_GPIO_B_2 WUI(0, MIWU_GROUP_4, 6) - -/* Group E: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_B_3 WUI(0, MIWU_GROUP_5, 0) -#define NPCX_WUI_GPIO_B_4 WUI(0, MIWU_GROUP_5, 1) -#define NPCX_WUI_GPIO_B_5 WUI(0, MIWU_GROUP_5, 2) -#define NPCX_WUI_GPIO_B_7 WUI(0, MIWU_GROUP_5, 4) - -/* Group F: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_C_0 WUI(0, MIWU_GROUP_6, 0) -#define NPCX_WUI_GPIO_C_1 WUI(0, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_C_2 WUI(0, MIWU_GROUP_6, 2) -#define NPCX_WUI_GPIO_C_3 WUI(0, MIWU_GROUP_6, 3) -#define NPCX_WUI_GPIO_C_4 WUI(0, MIWU_GROUP_6, 4) -#define NPCX_WUI_GPIO_C_5 WUI(0, MIWU_GROUP_6, 5) -#define NPCX_WUI_GPIO_C_6 WUI(0, MIWU_GROUP_6, 6) -#define NPCX_WUI_GPIO_C_7 WUI(0, MIWU_GROUP_6, 7) - -/* Group G: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_D_0 WUI(0, MIWU_GROUP_7, 0) -#define NPCX_WUI_GPIO_D_1 WUI(0, MIWU_GROUP_7, 1) -#define NPCX_WUI_GPIO_D_2 WUI(0, MIWU_GROUP_7, 2) -#define NPCX_WUI_GPIO_D_3 WUI(0, MIWU_GROUP_7, 3) -#define NPCX_WUI_GPIO_D_4 WUI(0, MIWU_GROUP_7, 4) -#define NPCX_WUI_GPIO_D_5 WUI(0, MIWU_GROUP_7, 5) -#define NPCX_WUI_GPIO_E_0 WUI(0, MIWU_GROUP_7, 7) - -/* Group H: NPCX_IRQ_WKINTEFGH_0 */ -#define NPCX_WUI_GPIO_E_1 WUI(0, MIWU_GROUP_8, 0) -#define NPCX_WUI_GPIO_E_2 WUI(0, MIWU_GROUP_8, 1) -#define NPCX_WUI_GPIO_E_3 WUI(0, MIWU_GROUP_8, 2) -#define NPCX_WUI_GPIO_E_4 WUI(0, MIWU_GROUP_8, 3) -#define NPCX_WUI_GPIO_E_5 WUI(0, MIWU_GROUP_8, 4) -#define NPCX_WUI_GPIO_F_0 WUI(0, MIWU_GROUP_8, 5) -#define NPCX_WUI_GPIO_F_3 WUI(0, MIWU_GROUP_8, 6) - -/* MIWU1 */ -/* Group A: NPCX_IRQ_WKINTA_1 */ -#define NPCX_WUI_GPIO_0_0 WUI(1, MIWU_GROUP_1, 0) -#define NPCX_WUI_GPIO_0_1 WUI(1, MIWU_GROUP_1, 1) -#define NPCX_WUI_GPIO_0_2 WUI(1, MIWU_GROUP_1, 2) -#define NPCX_WUI_GPIO_0_3 WUI(1, MIWU_GROUP_1, 3) -#define NPCX_WUI_GPIO_0_4 WUI(1, MIWU_GROUP_1, 4) -#define NPCX_WUI_GPIO_0_5 WUI(1, MIWU_GROUP_1, 5) -#define NPCX_WUI_GPIO_0_6 WUI(1, MIWU_GROUP_1, 6) -#define NPCX_WUI_GPIO_0_7 WUI(1, MIWU_GROUP_1, 7) - -/* Group B: NPCX_IRQ_WKINTB_1 */ -#define NPCX_WUI_GPIO_1_0 WUI(1, MIWU_GROUP_2, 0) -#define NPCX_WUI_GPIO_1_1 WUI(1, MIWU_GROUP_2, 1) -#define NPCX_WUI_GPIO_F_4 WUI(1, MIWU_GROUP_2, 2) -#define NPCX_WUI_GPIO_1_4 WUI(1, MIWU_GROUP_2, 4) -#define NPCX_WUI_GPIO_1_5 WUI(1, MIWU_GROUP_2, 5) -#define NPCX_WUI_GPIO_1_6 WUI(1, MIWU_GROUP_2, 6) -#define NPCX_WUI_GPIO_1_7 WUI(1, MIWU_GROUP_2, 7) - -/* Group C: NPCX_IRQ_KSI_WKINTC_1 */ -#define NPCX_WUI_GPIO_3_1 WUI(1, MIWU_GROUP_3, 0) -#define NPCX_WUI_GPIO_3_0 WUI(1, MIWU_GROUP_3, 1) -#define NPCX_WUI_GPIO_2_7 WUI(1, MIWU_GROUP_3, 2) -#define NPCX_WUI_GPIO_2_6 WUI(1, MIWU_GROUP_3, 3) -#define NPCX_WUI_GPIO_2_5 WUI(1, MIWU_GROUP_3, 4) -#define NPCX_WUI_GPIO_2_4 WUI(1, MIWU_GROUP_3, 5) -#define NPCX_WUI_GPIO_2_3 WUI(1, MIWU_GROUP_3, 6) -#define NPCX_WUI_GPIO_2_2 WUI(1, MIWU_GROUP_3, 7) - -/* Group D: NPCX_IRQ_WKINTD_1 */ -#define NPCX_WUI_GPIO_2_0 WUI(1, MIWU_GROUP_4, 0) -#define NPCX_WUI_GPIO_2_1 WUI(1, MIWU_GROUP_4, 1) -#define NPCX_WUI_GPIO_F_5 WUI(1, MIWU_GROUP_4, 2) -#define NPCX_WUI_GPIO_3_3 WUI(1, MIWU_GROUP_4, 3) -#define NPCX_WUI_GPIO_3_4 WUI(1, MIWU_GROUP_4, 4) -#define NPCX_WUI_GPIO_3_6 WUI(1, MIWU_GROUP_4, 6) -#define NPCX_WUI_GPIO_3_7 WUI(1, MIWU_GROUP_4, 7) - -/* Group E: NPCX_IRQ_WKINTE_1 */ -#define NPCX_WUI_GPIO_4_0 WUI(1, MIWU_GROUP_5, 0) -#define NPCX_WUI_GPIO_4_1 WUI(1, MIWU_GROUP_5, 1) -#define NPCX_WUI_GPIO_4_2 WUI(1, MIWU_GROUP_5, 2) -#define NPCX_WUI_GPIO_4_3 WUI(1, MIWU_GROUP_5, 3) -#define NPCX_WUI_GPIO_4_4 WUI(1, MIWU_GROUP_5, 4) -#define NPCX_WUI_GPIO_4_5 WUI(1, MIWU_GROUP_5, 5) -#define NPCX_WUI_GPIO_4_6 WUI(1, MIWU_GROUP_5, 6) -#define NPCX_WUI_GPIO_4_7 WUI(1, MIWU_GROUP_5, 7) - -/* Group F: NPCX_IRQ_WKINTF_1 */ -#define NPCX_WUI_GPIO_5_0 WUI(1, MIWU_GROUP_6, 0) -#define NPCX_WUI_GPIO_5_1 WUI(1, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_5_2 WUI(1, MIWU_GROUP_6, 2) -#define NPCX_WUI_GPIO_5_3 WUI(1, MIWU_GROUP_6, 3) -#define NPCX_WUI_GPIO_5_4 WUI(1, MIWU_GROUP_6, 4) -#define NPCX_WUI_GPIO_5_5 WUI(1, MIWU_GROUP_6, 5) -#define NPCX_WUI_GPIO_5_6 WUI(1, MIWU_GROUP_6, 6) -#define NPCX_WUI_GPIO_5_7 WUI(1, MIWU_GROUP_6, 7) - -/* Group G: NPCX_IRQ_WKINTG_1 */ -#define NPCX_WUI_GPIO_6_0 WUI(1, MIWU_GROUP_7, 0) -#define NPCX_WUI_GPIO_6_1 WUI(1, MIWU_GROUP_7, 1) -#define NPCX_WUI_GPIO_6_2 WUI(1, MIWU_GROUP_7, 2) -#define NPCX_WUI_GPIO_6_3 WUI(1, MIWU_GROUP_7, 3) -#define NPCX_WUI_GPIO_6_4 WUI(1, MIWU_GROUP_7, 4) - -/* Group H: NPCX_IRQ_WKINTH_1 */ -#define NPCX_WUI_GPIO_7_0 WUI(1, MIWU_GROUP_8, 0) -#define NPCX_WUI_GPIO_6_7 WUI(1, MIWU_GROUP_8, 1) -#define NPCX_WUI_GPIO_7_2 WUI(1, MIWU_GROUP_8, 2) -#define NPCX_WUI_GPIO_7_3 WUI(1, MIWU_GROUP_8, 3) -#define NPCX_WUI_GPIO_7_4 WUI(1, MIWU_GROUP_8, 4) -#define NPCX_WUI_GPIO_7_5 WUI(1, MIWU_GROUP_8, 5) -#define NPCX_WUI_GPIO_7_6 WUI(1, MIWU_GROUP_8, 6) - -/* MIWU2 */ -/* Group F: NPCX_IRQ_WKINTFG_2 */ -#define NPCX_WUI_GPIO_F_1 WUI(2, MIWU_GROUP_6, 1) -#define NPCX_WUI_GPIO_F_2 WUI(2, MIWU_GROUP_6, 2) -#define NPCX_WUI_GPIO_B_6 WUI(2, MIWU_GROUP_6, 6) - -/* Others GPO without MIWU functionality */ -#define NPCX_WUI_GPIO_1_2 WUI_NONE -#define NPCX_WUI_GPIO_1_3 WUI_NONE /* Software strap pin GP_SEL1_L */ -#define NPCX_WUI_GPIO_3_2 WUI_NONE -#define NPCX_WUI_GPIO_3_5 WUI_NONE -#define NPCX_WUI_GPIO_6_5 WUI_NONE /* Software strap pin FLPRG_L */ -#define NPCX_WUI_GPIO_6_6 WUI_NONE -#define NPCX_WUI_GPIO_7_7 WUI_NONE -#define NPCX_WUI_GPIO_8_5 WUI_NONE /* PSL_OUT/GPO85 */ -#define NPCX_WUI_GPIO_D_6 WUI_NONE /* strap pin SHDF_ESPI */ -#define NPCX_WUI_GPIO_D_7 WUI_NONE /* PSL_GPO/GPOD7 */ - -/*****************************************************************************/ -/* Macro functions for Alternative mapping table */ - -/* I2C Module */ -#define NPCX_ALT_GPIO_B_4 ALT(B, 4, NPCX_ALT(2, I2C0_0_SL)) /* SMB0SDA0 */ -#define NPCX_ALT_GPIO_B_5 ALT(B, 5, NPCX_ALT(2, I2C0_0_SL)) /* SMB0SCL0 */ -#define NPCX_ALT_GPIO_B_2 ALT(B, 2, NPCX_ALT(2, I2C7_0_SL)) /* SMB7SDA0 */ -#define NPCX_ALT_GPIO_B_3 ALT(B, 3, NPCX_ALT(2, I2C7_0_SL)) /* SMB7SCL0 */ -#define NPCX_ALT_GPIO_8_7 ALT(8, 7, NPCX_ALT(2, I2C1_0_SL)) /* SMB1SDA0 */ -#define NPCX_ALT_GPIO_9_0 ALT(9, 0, NPCX_ALT(2, I2C1_0_SL)) /* SMB1SCL0 */ -#define NPCX_ALT_GPIO_9_1 ALT(9, 1, NPCX_ALT(2, I2C2_0_SL)) /* SMB2SDA0 */ -#define NPCX_ALT_GPIO_9_2 ALT(9, 2, NPCX_ALT(2, I2C2_0_SL)) /* SMB2SCL0 */ -#define NPCX_ALT_GPIO_3_6 ALT(3, 6, NPCX_ALT(2, I2C5_0_SL)) /* SMB5SDA0 */ -#define NPCX_ALT_GPIO_3_3 ALT(3, 3, NPCX_ALT(2, I2C5_0_SL)) /* SMB5SCL0 */ -#define NPCX_ALT_GPIO_D_0 ALT(D, 0, NPCX_ALT(2, I2C3_0_SL)) /* SMB3SDA0 */ -#define NPCX_ALT_GPIO_D_1 ALT(D, 1, NPCX_ALT(2, I2C3_0_SL)) /* SMB3SCL0 */ - -#define NPCX_ALT_GPIO_F_2 ALT(F, 2, NPCX_ALT(6, I2C4_1_SL)) /* SMB4SDA1 */ -#define NPCX_ALT_GPIO_F_3 ALT(F, 3, NPCX_ALT(6, I2C4_1_SL)) /* SMB4SCL1 */ -#define NPCX_ALT_GPIO_F_4 ALT(F, 4, NPCX_ALT(6, I2C5_1_SL)) /* SMB5SDA1 */ -#define NPCX_ALT_GPIO_F_5 ALT(F, 5, NPCX_ALT(6, I2C5_1_SL)) /* SMB5SCL1 */ -#define NPCX_ALT_GPIO_E_3 ALT(E, 3, NPCX_ALT(6, I2C6_1_SL)) /* SMB6SDA1 */ -#define NPCX_ALT_GPIO_E_4 ALT(E, 4, NPCX_ALT(6, I2C6_1_SL)) /* SMB6SCL1 */ -/* Pin-Mux for PWM1/SMB6_0 */ -#if NPCX9_PWM1_SEL -#define NPCX_ALT_GPIO_C_1 /* No I2CSDA since GPIOC2 used as PWM1 */ -#define NPCX_ALT_GPIO_C_2 ALT(C, 2, NPCX_ALT(4, PWM1_SL)) /* PWM1 */ -#else -#define NPCX_ALT_GPIO_C_1 ALT(C, 1, NPCX_ALT(2, I2C6_0_SL)) /* SMB6SDA0 */ -#define NPCX_ALT_GPIO_C_2 ALT(C, 2, NPCX_ALT(2, I2C6_0_SL)) /* SMB6SCL0 */ -#endif - -/* ADC Module */ -#define NPCX_ALT_GPIO_4_5 ALT(4, 5, NPCX_ALT(6, ADC0_SL)) /* ADC0 */ -#define NPCX_ALT_GPIO_4_4 ALT(4, 4, NPCX_ALT(6, ADC1_SL)) /* ADC1 */ -#define NPCX_ALT_GPIO_4_3 ALT(4, 3, NPCX_ALT(6, ADC2_SL)) /* ADC2 */ -#define NPCX_ALT_GPIO_4_2 ALT(4, 2, NPCX_ALT(6, ADC3_SL)) /* ADC3 */ -#define NPCX_ALT_GPIO_4_1 ALT(4, 1, NPCX_ALT(6, ADC4_SL)) /* ADC4 */ -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_2) -#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(3, PS2_2_SL)) /* PS2_CLK2 */ -#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(3, PS2_2_SL)) /* PS2_DATA2 */ -#else -#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(F, ADC5_SL)) /* ADC5 */ -#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(F, ADC6_SL)) /* ADC6 */ -#endif -#define NPCX_ALT_GPIO_F_1 ALT(F, 1, NPCX_ALT(F, ADC8_SL)) /* ADC8 */ -#define NPCX_ALT_GPIO_E_1 ALT(E, 1, NPCX_ALT(F, ADC7_SL)) /* ADC7 */ -#define NPCX_ALT_GPIO_F_0 ALT(F, 0, NPCX_ALT(F, ADC9_SL)) /* ADC9 */ -#define NPCX_ALT_GPIO_E_0 ALT(E, 0, NPCX_ALT(F, ADC10_SL)) /* AD10 */ -#define NPCX_ALT_GPIO_C_7 ALT(C, 7, NPCX_ALT(F, ADC11_SL)) /* AD11 */ - -/* PS/2 Module */ -#define NPCX_ALT_GPIO_6_7 ALT(6, 7, NPCX_ALT(3, PS2_0_SL)) /* PS2_CLK0 */ -#define NPCX_ALT_GPIO_7_0 ALT(7, 0, NPCX_ALT(3, PS2_0_SL)) /* PS2_DATA0 */ -#define NPCX_ALT_GPIO_6_2 ALT(6, 2, NPCX_ALT(3, PS2_1_SL)) /* PS2_CLK1 */ -#define NPCX_ALT_GPIO_6_3 ALT(6, 3, NPCX_ALT(3, PS2_1_SL)) /* PS2_DATA1 */ -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3) -#define NPCX_ALT_GPIO_A_7 ALT(A, 7, NPCX_ALT(C, PS2_3_SL2)) /* PS2_DAT3 */ -#else -#define NPCX_ALT_GPIO_A_7 -#endif - -/* UART Module */ -#define NPCX_ALT_GPIO_6_4 ALT(6, 4, NPCX_ALT(J, CR_SIN1_SL2)) /* CR_SIN1_SL2 */ -#define NPCX_ALT_GPIO_6_5 ALT(6, 5, NPCX_ALT(J, CR_SOUT1_SL2))/* CR_SOUT1_SL2 */ -#define NPCX_ALT_GPIO_7_5 ALT(7, 5, NPCX_ALT(J, CR_SIN2_SL)) /* CR_SIN2_SL */ -#define NPCX_ALT_GPIO_8_6 ALT(8, 6, NPCX_ALT(J, CR_SOUT2_SL)) /* CR_SOUT2_SL */ -#define NPCX_ALT_GPIO_D_4 ALT(D, 4, NPCX_ALT(J, CR_SIN3_SL)) /* CR_SIN3_SL */ -#define NPCX_ALT_GPIO_D_6 ALT(D, 6, NPCX_ALT(J, CR_SOUT3_SL)) /* CR_SOUT3_SL */ - -/* PWM Module */ -#define NPCX_ALT_GPIO_C_3 ALT(C, 3, NPCX_ALT(4, PWM0_SL)) /* PWM0 */ -#define NPCX_ALT_GPIO_C_4 ALT(C, 4, NPCX_ALT(4, PWM2_SL)) /* PWM2 */ -#define NPCX_ALT_GPIO_8_0 ALT(8, 0, NPCX_ALT(4, PWM3_SL)) /* PWM3 */ -#define NPCX_ALT_GPIO_B_6 ALT(B, 6, NPCX_ALT(4, PWM4_SL)) /* PWM4 */ -#define NPCX_ALT_GPIO_B_7 ALT(B, 7, NPCX_ALT(4, PWM5_SL)) /* PWM5 */ -#define NPCX_ALT_GPIO_C_0 ALT(C, 0, NPCX_ALT(4, PWM6_SL)) /* PWM6 */ -#define NPCX_ALT_GPIO_6_0 ALT(6, 0, NPCX_ALT(4, PWM7_SL)) /* PWM7 */ - -/* MFT Module */ -#define NPCX_ALT_GPIO_4_0 ALT(4, 0, NPCX_ALT(3, TA1_SL1)) /* TA1_SEL1 */ -#define NPCX_ALT_GPIO_7_3 ALT(7, 3, NPCX_ALT(3, TA2_SL1)) /* TA2_SEL1 */ -#define NPCX_ALT_GPIO_9_3 ALT(9, 3, NPCX_ALT(C, TA1_SL2)) /* TA1_SEL2 */ -#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3) -#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, PS2_3_SL2)) /* PS2_CLK3 */ -#else -#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, TA2_SL2)) /* TA2_SEL2 */ -#endif - -/* Keyboard Scan Module */ -#define NPCX_ALT_GPIO_3_1 ALT(3, 1, NPCX_ALT_INV(7, NO_KSI0_SL)) /* KSI0 */ -#define NPCX_ALT_GPIO_3_0 ALT(3, 0, NPCX_ALT_INV(7, NO_KSI1_SL)) /* KSI1 */ -#define NPCX_ALT_GPIO_2_7 ALT(2, 7, NPCX_ALT_INV(7, NO_KSI2_SL)) /* KSI2 */ -#define NPCX_ALT_GPIO_2_6 ALT(2, 6, NPCX_ALT_INV(7, NO_KSI3_SL)) /* KSI3 */ -#define NPCX_ALT_GPIO_2_5 ALT(2, 5, NPCX_ALT_INV(7, NO_KSI4_SL)) /* KSI4 */ -#define NPCX_ALT_GPIO_2_4 ALT(2, 4, NPCX_ALT_INV(7, NO_KSI5_SL)) /* KSI5 */ -#define NPCX_ALT_GPIO_2_3 ALT(2, 3, NPCX_ALT_INV(7, NO_KSI6_SL)) /* KSI6 */ -#define NPCX_ALT_GPIO_2_2 ALT(2, 2, NPCX_ALT_INV(7, NO_KSI7_SL)) /* KSI7 */ -#define NPCX_ALT_GPIO_2_1 ALT(2, 1, NPCX_ALT_INV(8, NO_KSO00_SL)) /* KSO00 */ -#define NPCX_ALT_GPIO_2_0 ALT(2, 0, NPCX_ALT_INV(8, NO_KSO01_SL)) /* KSO01 */ -#define NPCX_ALT_GPIO_1_7 ALT(1, 7, NPCX_ALT_INV(8, NO_KSO02_SL)) /* KSO02 */ -#define NPCX_ALT_GPIO_1_6 ALT(1, 6, NPCX_ALT_INV(8, NO_KSO03_SL)) /* KSO03 */ -#define NPCX_ALT_GPIO_1_5 ALT(1, 5, NPCX_ALT_INV(8, NO_KSO04_SL)) /* KSO04 */ -#define NPCX_ALT_GPIO_1_4 ALT(1, 4, NPCX_ALT_INV(8, NO_KSO05_SL)) /* KSO05 */ -#define NPCX_ALT_GPIO_1_3 ALT(1, 3, NPCX_ALT_INV(8, NO_KSO06_SL)) /* KSO06 */ -#define NPCX_ALT_GPIO_1_2 ALT(1, 2, NPCX_ALT_INV(8, NO_KSO07_SL)) /* KSO07 */ -/* KSO08 & CR_SOUT */ -#define NPCX_ALT_GPIO_1_1 ALT(1, 1, NPCX_ALT_INV(9, NO_KSO08_SL)) - /* KSO09 & CR_SIN */ -#define NPCX_ALT_GPIO_1_0 ALT(1, 0, NPCX_ALT_INV(9, NO_KSO09_SL)) -#define NPCX_ALT_GPIO_0_7 ALT(0, 7, NPCX_ALT_INV(9, NO_KSO10_SL)) /* KSO10 */ -#define NPCX_ALT_GPIO_0_6 ALT(0, 6, NPCX_ALT_INV(9, NO_KSO11_SL)) /* KSO11 */ -#define NPCX_ALT_GPIO_0_5 ALT(0, 5, NPCX_ALT_INV(9, NO_KSO12_SL)) /* KSO12 */ -#define NPCX_ALT_GPIO_0_4 ALT(0, 4, NPCX_ALT_INV(9, NO_KSO13_SL)) /* KSO13 */ -#define NPCX_ALT_GPIO_8_2 ALT(8, 2, NPCX_ALT_INV(9, NO_KSO14_SL)) /* KSO14 */ -#define NPCX_ALT_GPIO_8_3 ALT(8, 3, NPCX_ALT_INV(9, NO_KSO15_SL)) /* KSO15 */ -#define NPCX_ALT_GPIO_0_3 ALT(0, 3, NPCX_ALT_INV(A, NO_KSO16_SL)) /* KSO16 */ -#define NPCX_ALT_GPIO_B_1 ALT(B, 1, NPCX_ALT_INV(A, NO_KSO17_SL)) /* KSO17 */ - -/* PSL module */ -#define NPCX_ALT_GPIO_D_2 ALT(D, 2, NPCX_ALT_INV(D, NPSL_IN1_SL)) /* PSL_IN1 */ -#define NPCX_ALT_GPIO_0_0 ALT(0, 0, NPCX_ALT_INV(D, NPSL_IN2_SL)) /* PSL_IN2 */ -#define NPCX_ALT_GPIO_0_1 ALT(0, 1, NPCX_ALT(D, PSL_IN3_SL)) /* PSL_IN3 */ -#define NPCX_ALT_GPIO_0_2 ALT(0, 2, NPCX_ALT(D, PSL_IN4_SL)) /* PSL_IN4 */ -#define NPCX_ALT_GPIO_D_7 ALT(D, 7, NPCX_ALT(G, PSL_GPO_SL)) /* PSL_GPO */ - -/* SPI Module */ -#define NPCX_ALT_GPIO_9_5 ALT(9, 5, NPCX_ALT(0, SPIP_SL)) /* SPIP_MISO */ -#define NPCX_ALT_GPIO_A_3 ALT(A, 3, NPCX_ALT(0, SPIP_SL)) /* SPIP_MOSI */ -#define NPCX_ALT_GPIO_A_1 ALT(A, 1, NPCX_ALT(0, SPIP_SL)) /* SPIP_SCLK */ - -#define NPCX_ALT_TABLE { \ - NPCX_ALT_GPIO_0_0 /* PSL_IN2 */ \ - NPCX_ALT_GPIO_0_1 /* PSL_IN3 */ \ - NPCX_ALT_GPIO_0_2 /* PSL_IN4 */ \ - NPCX_ALT_GPIO_0_3 /* KSO16 */ \ - NPCX_ALT_GPIO_0_4 /* KSO13 */ \ - NPCX_ALT_GPIO_0_5 /* KSO12 */ \ - NPCX_ALT_GPIO_0_6 /* KSO11 */ \ - NPCX_ALT_GPIO_0_7 /* KSO10 */ \ - NPCX_ALT_GPIO_1_0 /* KSO09 & CR_SIN */ \ - NPCX_ALT_GPIO_1_1 /* KSO08 & CR_SOUT */ \ - NPCX_ALT_GPIO_1_2 /* KSO07 */ \ - NPCX_ALT_GPIO_1_3 /* KSO06 */ \ - NPCX_ALT_GPIO_1_4 /* KSO05 */ \ - NPCX_ALT_GPIO_1_5 /* KSO04 */ \ - NPCX_ALT_GPIO_1_6 /* KSO03 */ \ - NPCX_ALT_GPIO_1_7 /* KSO02 */ \ - NPCX_ALT_GPIO_2_0 /* KSO01 */ \ - NPCX_ALT_GPIO_2_1 /* KSO00 */ \ - NPCX_ALT_GPIO_2_2 /* KSI7 */ \ - NPCX_ALT_GPIO_2_3 /* KSI6 */ \ - NPCX_ALT_GPIO_2_4 /* KSI5 */ \ - NPCX_ALT_GPIO_2_5 /* KSI4 */ \ - NPCX_ALT_GPIO_2_6 /* KSI3 */ \ - NPCX_ALT_GPIO_2_7 /* KSI2 */ \ - NPCX_ALT_GPIO_3_0 /* KSI1 */ \ - NPCX_ALT_GPIO_3_1 /* KSI0 */ \ - NPCX_ALT_GPIO_3_3 /* SMB5SCL0 */ \ - NPCX_ALT_GPIO_3_4 /* ADC6/PS2_DAT2 */ \ - NPCX_ALT_GPIO_3_6 /* SMB5SDA0 */ \ - NPCX_ALT_GPIO_3_7 /* ADC5/PS2_CLK2 */ \ - NPCX_ALT_GPIO_4_0 /* TA1_SEL1 */ \ - NPCX_ALT_GPIO_4_1 /* ADC4 */ \ - NPCX_ALT_GPIO_4_2 /* ADC3 */ \ - NPCX_ALT_GPIO_4_3 /* ADC2 */ \ - NPCX_ALT_GPIO_4_4 /* ADC1 */ \ - NPCX_ALT_GPIO_4_5 /* ADC0 */ \ - NPCX_ALT_GPIO_6_0 /* PWM7 */ \ - NPCX_ALT_GPIO_6_2 /* PS2_CLK1 */ \ - NPCX_ALT_GPIO_6_3 /* PS2_DAT1 */ \ - NPCX_ALT_GPIO_6_4 /* CR_SIN1_SL2 */ \ - NPCX_ALT_GPIO_6_5 /* CR_SOUT1_SL2 */ \ - NPCX_ALT_GPIO_6_7 /* PS2_CLK0 */ \ - NPCX_ALT_GPIO_7_0 /* PS2_DAT0 */ \ - NPCX_ALT_GPIO_7_3 /* TA2_SEL1 */ \ - NPCX_ALT_GPIO_7_5 /* CR_SIN2_SL */ \ - NPCX_ALT_GPIO_8_0 /* PWM3 */ \ - NPCX_ALT_GPIO_8_2 /* KSO14 */ \ - NPCX_ALT_GPIO_8_3 /* KSO15 */ \ - NPCX_ALT_GPIO_8_6 /* CR_SOUT2_SL */ \ - NPCX_ALT_GPIO_8_7 /* SMB1SDA0 */ \ - NPCX_ALT_GPIO_9_0 /* SMB1SCL0 */ \ - NPCX_ALT_GPIO_9_1 /* SMB2SDA0 */ \ - NPCX_ALT_GPIO_9_2 /* SMB2SCL0 */ \ - NPCX_ALT_GPIO_9_3 /* TA1_SEL2 */ \ - NPCX_ALT_GPIO_9_5 /* SPIP_MISO */ \ - NPCX_ALT_GPIO_A_1 /* SPIP_SCLK */ \ - NPCX_ALT_GPIO_A_3 /* SPIP_MOSI */ \ - NPCX_ALT_GPIO_A_6 /* TA2_SEL2/PS2_CLK3 */ \ - NPCX_ALT_GPIO_A_7 /* I2S_SCLK/PS2_DAT3 */ \ - NPCX_ALT_GPIO_B_1 /* KSO17 */ \ - NPCX_ALT_GPIO_B_2 /* SMB7SDA0 */ \ - NPCX_ALT_GPIO_B_3 /* SMB7SCL0 */ \ - NPCX_ALT_GPIO_B_4 /* SMB0SDA0 */ \ - NPCX_ALT_GPIO_B_5 /* SMB0SCL0 */ \ - NPCX_ALT_GPIO_B_6 /* PWM4 */ \ - NPCX_ALT_GPIO_B_7 /* PWM5 */ \ - NPCX_ALT_GPIO_C_0 /* PWM6 */ \ - NPCX_ALT_GPIO_C_1 /* SMB6SDA0 */ \ - NPCX_ALT_GPIO_C_2 /* SMB6SCL0 & PWM1 */ \ - NPCX_ALT_GPIO_C_3 /* PWM0 */ \ - NPCX_ALT_GPIO_C_4 /* PWM2 */ \ - NPCX_ALT_GPIO_C_7 /* ADC11 */ \ - NPCX_ALT_GPIO_D_0 /* SMB3SDA0 */ \ - NPCX_ALT_GPIO_D_1 /* SMB3SCL0 */ \ - NPCX_ALT_GPIO_D_2 /* PSL_IN1 */ \ - NPCX_ALT_GPIO_D_4 /* CR_SIN3_SL */ \ - NPCX_ALT_GPIO_D_6 /* CR_SOUT3_SL */ \ - NPCX_ALT_GPIO_D_7 /* PSL_GPO */ \ - NPCX_ALT_GPIO_E_0 /* ADC10 */ \ - NPCX_ALT_GPIO_E_1 /* ADC7 */ \ - NPCX_ALT_GPIO_E_3 /* SMB6SDA1 */ \ - NPCX_ALT_GPIO_E_4 /* SMB6SCL1 */ \ - NPCX_ALT_GPIO_F_0 /* ADC9 */ \ - NPCX_ALT_GPIO_F_1 /* ADC8 */ \ - NPCX_ALT_GPIO_F_2 /* SMB4SDA1 */ \ - NPCX_ALT_GPIO_F_3 /* SMB4SCL1 */ \ - NPCX_ALT_GPIO_F_4 /* SMB5SDA1 */ \ - NPCX_ALT_GPIO_F_5 /* SMB5SCL1 */ \ -} - -/*****************************************************************************/ -/* Macro functions for Low-Voltage mapping table */ - -/* Low-Voltage GPIO Control 0 */ -#define NPCX_LVOL_CTRL_0_0 NPCX_GPIO(B, 5) -#define NPCX_LVOL_CTRL_0_1 NPCX_GPIO(B, 4) -#define NPCX_LVOL_CTRL_0_2 NPCX_GPIO(B, 3) -#define NPCX_LVOL_CTRL_0_3 NPCX_GPIO(B, 2) -#define NPCX_LVOL_CTRL_0_4 NPCX_GPIO(9, 0) -#define NPCX_LVOL_CTRL_0_5 NPCX_GPIO(8, 7) -#define NPCX_LVOL_CTRL_0_6 NPCX_GPIO(0, 0) -#define NPCX_LVOL_CTRL_0_7 NPCX_GPIO(3, 3) - -/* Low-Voltage GPIO Control 1 */ -#define NPCX_LVOL_CTRL_1_0 NPCX_GPIO(9, 2) -#define NPCX_LVOL_CTRL_1_1 NPCX_GPIO(9, 1) -#define NPCX_LVOL_CTRL_1_2 NPCX_GPIO(D, 1) -#define NPCX_LVOL_CTRL_1_3 NPCX_GPIO(D, 0) -#define NPCX_LVOL_CTRL_1_4 NPCX_GPIO(3, 6) -#define NPCX_LVOL_CTRL_1_5 NPCX_GPIO(6, 4) -#define NPCX_LVOL_CTRL_1_6 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_1_7 NPCX_GPIO_NONE - -/* Low-Voltage GPIO Control 2 */ -#define NPCX_LVOL_CTRL_2_0 NPCX_GPIO(7, 4) -#define NPCX_LVOL_CTRL_2_1 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_2_2 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_2_3 NPCX_GPIO(7, 3) -#define NPCX_LVOL_CTRL_2_4 NPCX_GPIO(C, 1) -#define NPCX_LVOL_CTRL_2_5 NPCX_GPIO(C, 7) -#define NPCX_LVOL_CTRL_2_6 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_2_7 NPCX_GPIO(3, 4) - -/* Low-Voltage GPIO Control 3 */ -#define NPCX_LVOL_CTRL_3_0 NPCX_GPIO(C, 6) -#define NPCX_LVOL_CTRL_3_1 NPCX_GPIO(3, 7) -#define NPCX_LVOL_CTRL_3_2 NPCX_GPIO(4, 0) -#define NPCX_LVOL_CTRL_3_3 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_3_4 NPCX_GPIO(8, 2) -#define NPCX_LVOL_CTRL_3_5 NPCX_GPIO(7, 5) -#define NPCX_LVOL_CTRL_3_6 NPCX_GPIO(8, 0) -#define NPCX_LVOL_CTRL_3_7 NPCX_GPIO(C, 5) - -/* Low-Voltage GPIO Control 4 */ -#define NPCX_LVOL_CTRL_4_0 NPCX_GPIO(8, 6) -#define NPCX_LVOL_CTRL_4_1 NPCX_GPIO(C, 2) -#define NPCX_LVOL_CTRL_4_2 NPCX_GPIO(F, 3) -#define NPCX_LVOL_CTRL_4_3 NPCX_GPIO(F, 2) -#define NPCX_LVOL_CTRL_4_4 NPCX_GPIO(F, 5) -#define NPCX_LVOL_CTRL_4_5 NPCX_GPIO(F, 4) -#define NPCX_LVOL_CTRL_4_6 NPCX_GPIO(E, 4) -#define NPCX_LVOL_CTRL_4_7 NPCX_GPIO(E, 3) - -/* Low-Voltage GPIO Control 5 */ -#define NPCX_LVOL_CTRL_5_0 NPCX_GPIO(7, 2) -#define NPCX_LVOL_CTRL_5_1 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_2 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_3 NPCX_GPIO(5, 0) -#define NPCX_LVOL_CTRL_5_4 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_5 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_6 NPCX_GPIO_NONE -#define NPCX_LVOL_CTRL_5_7 NPCX_GPIO_NONE - -/* 6 Low-Voltage Control Groups on npcx7 */ -#define NPCX_LVOL_TABLE { { NPCX_LVOL_CTRL_ITEMS(0), }, \ - { NPCX_LVOL_CTRL_ITEMS(1), }, \ - { NPCX_LVOL_CTRL_ITEMS(2), }, \ - { NPCX_LVOL_CTRL_ITEMS(3), }, \ - { NPCX_LVOL_CTRL_ITEMS(4), }, \ - { NPCX_LVOL_CTRL_ITEMS(5), }, } - -#endif /* __CROS_EC_GPIO_CHIP_NPCX9_H */ diff --git a/chip/npcx/gpio_chip.h b/chip/npcx/gpio_chip.h deleted file mode 100644 index 2d0b2b4e9b..0000000000 --- a/chip/npcx/gpio_chip.h +++ /dev/null @@ -1,74 +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. - */ - -#ifndef __CROS_EC_GPIO_CHIP_H -#define __CROS_EC_GPIO_CHIP_H - -struct npcx_wui { - uint8_t table : 2; - uint8_t group : 3; - uint8_t bit : 3; -}; - -/* Macros to initialize the MIWU mapping table. */ -#define NPCX_WUI_GPIO_PIN(port, index) NPCX_WUI_GPIO_##port##_##index -#define WUI(tbl, grp, idx) ((struct npcx_wui) { .table = tbl, .group = grp, \ - .bit = idx }) -#define WUI_INT(tbl, grp) WUI(tbl, grp, 0) -#define WUI_NONE ((struct npcx_wui) { .table = MIWU_TABLE_COUNT, .group = 0, \ - .bit = 0 }) - -/* Macros to initialize the alternative and low voltage mapping table. */ -#define NPCX_GPIO_NONE ((struct npcx_gpio) {.port = 0, .bit = 0, .valid = 0}) -#define NPCX_GPIO(grp, pin) ((struct npcx_gpio) {.port = GPIO_PORT_##grp, \ - .bit = pin, .valid = 1}) - -#define NPCX_ALT(grp, pin) ((struct npcx_alt) {.group = ALT_GROUP_##grp, \ - .bit = NPCX_DEVALT##grp##_##pin, .inverted = 0 }) -#define NPCX_ALT_INV(grp, pin) ((struct npcx_alt) {.group = ALT_GROUP_##grp, \ - .bit = NPCX_DEVALT##grp##_##pin, .inverted = 1 }) -#define ALT(port, index, _alt) { .gpio = NPCX_GPIO(port, index), \ - .alt = (_alt) }, - -#define NPCX_LVOL_CTRL_ITEMS(ctrl) { NPCX_LVOL_CTRL_##ctrl##_0, \ - NPCX_LVOL_CTRL_##ctrl##_1, \ - NPCX_LVOL_CTRL_##ctrl##_2, \ - NPCX_LVOL_CTRL_##ctrl##_3, \ - NPCX_LVOL_CTRL_##ctrl##_4, \ - NPCX_LVOL_CTRL_##ctrl##_5, \ - NPCX_LVOL_CTRL_##ctrl##_6, \ - NPCX_LVOL_CTRL_##ctrl##_7, } - -/** - * Switch NPCX UART pins back to normal GPIOs. - */ -void npcx_uart2gpio(void); - -/** - * Switch NPCX UART pins to UART mode (depending on the currently selected - * pad, see uart.c). - */ -void npcx_gpio2uart(void); - -/* Set input buffer of all 1.8v i2c ports. */ -void gpio_enable_1p8v_i2c_wake_up_input(int enable); - -void gpio_interrupt(struct npcx_wui wui_int); - -/* - * Include the MIWU, alternative and low-Voltage macro functions for GPIOs - * depends on Nuvoton chip series. - */ -#if defined(CHIP_FAMILY_NPCX5) -#include "gpio_chip-npcx5.h" -#elif defined(CHIP_FAMILY_NPCX7) -#include "gpio_chip-npcx7.h" -#elif defined(CHIP_FAMILY_NPCX9) -#include "gpio_chip-npcx9.h" -#else -#error "Unsupported chip family" -#endif - -#endif /* __CROS_EC_GPIO_CHIP_H */ diff --git a/chip/npcx/header.c b/chip/npcx/header.c deleted file mode 100644 index 0ba3ee59d6..0000000000 --- a/chip/npcx/header.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2015 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. - */ - -/* - * Booter header for Chrome EC. - * - * This header is used by Nuvoton EC Booter. - */ - -#include <stdint.h> - -#include "config.h" -#include "registers.h" - -/* Signature used by fw header */ -#define SIG_FW_EC 0x2A3B4D5E - -/* Definition used by error detection configuration */ -#define CHECK_CRC 0x00 -#define CHECK_CHECKSUM 0x01 -#define ERROR_DETECTION_EN 0x02 -#define ERROR_DETECTION_DIS 0x00 - -/* Code RAM addresses use by header */ -/* Put FW at the begin of CODE RAM */ -#define FW_START_ADDR CONFIG_PROGRAM_MEMORY_BASE - -/* TODO: It will be filled automatically by ECST */ -/* The entry point of reset handler (filled by ECST tool)*/ -#define FW_ENTRY_ADDR 0x100A8169 - -/* Error detection addresses use by header (A offset relative to flash image) */ -#define ERRCHK_START_ADDR 0x0 -#define ERRCHK_END_ADDR 0x0 - -/* Firmware Size -> Booter loads RO region after hard reset (16 bytes aligned)*/ -#define FW_SIZE CONFIG_RO_SIZE - -/* FW Header used by NPCX5M5G Booter */ -struct __packed fw_header_t { - uint32_t anchor; /* A constant used to verify FW header */ - uint16_t ext_anchor; /* Enable/disable firmware header CRC check */ - uint8_t spi_max_freq; /* Spi maximum allowable clock frequency */ - uint8_t spi_read_mode; /* Spi read mode used for firmware loading */ - uint8_t cfg_err_detect; /* FW load error detection configuration */ - uint32_t fw_load_addr; /* Firmware load start address */ - uint32_t fw_entry; /* Firmware entry point */ - uint32_t err_detect_start_addr; /* FW error detect start address */ - uint32_t err_detect_end_addr; /* FW error detect end address */ - uint32_t fw_length; /* Firmware length in bytes */ - uint8_t flash_size; /* Indicate SPI flash size */ - uint8_t reserved[26]; /* Reserved bytes */ - uint32_t sig_header; /* The CRC signature of the firmware header */ - uint32_t sig_fw_image; /* The CRC or Checksum of the firmware image */ -} __aligned(1); - -__keep __attribute__ ((section(".header"))) -const struct fw_header_t fw_header = { - /* 00 */ SIG_FW_EC, - /* 04 */ 0x54E1, /* Header CRC check Enable/Disable -> AB1Eh/54E1h */ - /* 06 */ 0x04, /* 20/25/33/40/50 MHz -> 00/01/02/03/04h */ - /* 07 */ 0x03, /* Normal/Fast/Rev/D_IO/Q_IO Mode -> 00/01/02/03/04h */ - /* 08 */ 0x00, /* Disable CRC check functionality */ - /* 09 */ FW_START_ADDR, - /* 0D */ FW_ENTRY_ADDR,/* Filling by ECST tool with -usearmrst option */ - /* 11 */ ERRCHK_START_ADDR, - /* 15 */ ERRCHK_END_ADDR, - /* 19 */ FW_SIZE,/* Filling by ECST tool */ - /* 1D */ 0x0F, /* Flash Size 1/2/4/8/16 Mbytes -> 01/03/07/0F/1Fh */ - /* 1E-3F Other fields are filled by ECST tool or reserved */ -}; diff --git a/chip/npcx/hwtimer.c b/chip/npcx/hwtimer.c deleted file mode 100644 index 92f9843d09..0000000000 --- a/chip/npcx/hwtimer.c +++ /dev/null @@ -1,341 +0,0 @@ -/* Copyright 2014 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. - */ - -/* Hardware timers driver */ - -#include "clock.h" -#include "clock_chip.h" -#include "common.h" -#include "hooks.h" -#include "hwtimer.h" -#include "hwtimer_chip.h" -#include "math_util.h" -#include "registers.h" -#include "console.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Depth of event timer */ -#define TICK_EVT_DEPTH 16 /* Depth of event timer Unit: bits */ -#define TICK_EVT_INTERVAL BIT(TICK_EVT_DEPTH) /* Unit: us */ -#define TICK_EVT_INTERVAL_MASK (TICK_EVT_INTERVAL - 1) /* Mask of interval */ -#define TICK_EVT_MAX_CNT (TICK_EVT_INTERVAL - 1) /* Maximum event counter */ - -/* Time when event will be expired unit:us */ -static volatile uint32_t evt_expired_us; -/* 32-bits event counter */ -static volatile uint32_t evt_cnt; -/* Debugger information */ -#if DEBUG_TMR -static volatile uint32_t evt_cnt_us_dbg; -static volatile uint32_t cur_cnt_us_dbg; -#endif - -#if !(DEBUG_TMR) -#define CPUTS(...) -#define CPRINTS(...) -#else -#define CPUTS(outstr) cputs(CC_CLOCK, outstr) -#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args) -#endif - -/*****************************************************************************/ -/* Internal functions */ -void init_hw_timer(int itim_no, enum ITIM_SOURCE_CLOCK_T source) -{ - /* Select which clock to use for this timer */ - UPDATE_BIT(NPCX_ITCTS(itim_no), NPCX_ITCTS_CKSEL, - source != ITIM_SOURCE_CLOCK_APB2); - - /* Clear timeout status */ - SET_BIT(NPCX_ITCTS(itim_no), NPCX_ITCTS_TO_STS); - - /* ITIM timeout interrupt enable */ - SET_BIT(NPCX_ITCTS(itim_no), NPCX_ITCTS_TO_IE); - - /* ITIM timeout wake-up enable */ - SET_BIT(NPCX_ITCTS(itim_no), NPCX_ITCTS_TO_WUE); -} - -/*****************************************************************************/ -/* HWTimer event handlers */ -void __hw_clock_event_set(uint32_t deadline) -{ - fp_t inv_evt_tick = FLOAT_TO_FP(INT_32K_CLOCK/(float)SECOND); - int32_t evt_cnt_us; - /* Is deadline min value? */ - if (evt_expired_us != 0 && evt_expired_us < deadline) - return; - - /* mark min event value */ - evt_expired_us = deadline; - evt_cnt_us = deadline - __hw_clock_source_read(); -#if DEBUG_TMR - evt_cnt_us_dbg = deadline - __hw_clock_source_read(); -#endif - /* Deadline is behind current timer */ - if (evt_cnt_us < 0) - evt_cnt_us = 1; - - /* Event module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN); - - /* - * ITIM count down : event expired : Unit: 1/32768 sec - * It must exceed evt_expired_us for process_timers function - */ - evt_cnt = FP_TO_INT((fp_inter_t)(evt_cnt_us) * inv_evt_tick); - if (evt_cnt > TICK_EVT_MAX_CNT) { - CPRINTS("Event overflow! 0x%08x, us is %d", - evt_cnt, evt_cnt_us); - evt_cnt = TICK_EVT_MAX_CNT; - } - - /* Wait for module disable to take effect before updating count */ - while (IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN)) - ; - - NPCX_ITCNT(ITIM_EVENT_NO) = MAX(evt_cnt, 1); - - /* Event module enable */ - SET_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN); - - /* Wait for module enable */ - while (!IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN)) - ; - - /* Enable interrupt of ITIM */ - task_enable_irq(ITIM_INT(ITIM_EVENT_NO)); -} - -/* Returns the time-stamp of the next programmed event */ -uint32_t __hw_clock_event_get(void) -{ - if (evt_expired_us) - return evt_expired_us; - else /* No events. Give maximum deadline */ - return EVT_MAX_EXPIRED_US; -} - -/* Get current counter value of event timer */ -uint16_t __hw_clock_event_count(void) -{ - uint16_t cnt, cnt2; - - cnt = NPCX_ITCNT(ITIM_EVENT_NO); - /* Wait for two consecutive equal values are read */ - while ((cnt2 = NPCX_ITCNT(ITIM_EVENT_NO)) != cnt) - cnt = cnt2; - - return cnt; -} - -/* Returns time delay cause of deep idle */ -uint32_t __hw_clock_get_sleep_time(uint16_t pre_evt_cnt) -{ - fp_t evt_tick = FLOAT_TO_FP(SECOND/(float)INT_32K_CLOCK); - uint32_t sleep_time; - uint16_t cnt = __hw_clock_event_count(); - - /* Event has been triggered but timer ISR doesn't handle it */ - if (IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_TO_STS)) - sleep_time = FP_TO_INT((fp_inter_t)(pre_evt_cnt+1) * evt_tick); - /* Event hasn't been triggered */ - else - sleep_time = FP_TO_INT((fp_inter_t)(pre_evt_cnt+1 - cnt) * - evt_tick); - - return sleep_time; -} - -/* Cancel the next event programmed by __hw_clock_event_set */ -void __hw_clock_event_clear(void) -{ - /* ITIM event module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN); - - /* Disable interrupt of Event */ - task_disable_irq(ITIM_INT(ITIM_EVENT_NO)); - - /* Clear event parameters */ - evt_expired_us = 0; - evt_cnt = 0; -} - -/* Irq for hwtimer event */ -void __hw_clock_event_irq(void) -{ - /* ITIM event module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN); - - /* Disable interrupt of event */ - task_disable_irq(ITIM_INT(ITIM_EVENT_NO)); - - /* Clear timeout status for event */ - SET_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_TO_STS); - - /* Clear event parameters */ - evt_expired_us = 0; - evt_cnt = 0; - - /* handle upper driver */ - process_timers(0); - -#ifdef CONFIG_LOW_POWER_IDLE - /* - * Set event for ITIM32 after process_timers() since no events set if - * event's deadline is over 32 bits but current source clock isn't. - * ITIM32 is based on apb2 and ec won't wake-up in deep-idle even if it - * expires. - */ - if (evt_expired_us == 0) - __hw_clock_event_set(EVT_MAX_EXPIRED_US); -#endif - -} -DECLARE_IRQ(ITIM_INT(ITIM_EVENT_NO), __hw_clock_event_irq, 3); - -/*****************************************************************************/ -/* HWTimer tick handlers */ - -/* Modify preload counter of source clock. */ -void hw_clock_source_set_preload(uint32_t ts, uint8_t clear) -{ - /* ITIM32 module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_ITEN); - CLEAR_BIT(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_CKSEL); - - /* Set preload counter to current time */ - NPCX_ITCNT_SYSTEM = TICK_ITIM32_MAX_CNT - ts; - /* Clear timeout status or not */ - if (clear) - SET_BIT(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_TO_STS); - /* ITIM32 module enable */ - SET_BIT(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_ITEN); -} - -/* Returns the value of the free-running counter used as clock. */ -uint32_t __hw_clock_source_read(void) -{ - uint32_t cnt, cnt2; - - cnt = NPCX_ITCNT_SYSTEM; - /* - * Wait for two consecutive equal values are read no matter - * ITIM's source clock is APB2 or 32K since mux's delay. - */ - while ((cnt2 = NPCX_ITCNT_SYSTEM) != cnt) - cnt = cnt2; - -#if DEBUG_TMR - cur_cnt_us_dbg = TICK_ITIM32_MAX_CNT - cnt; -#endif - return TICK_ITIM32_MAX_CNT - cnt; -} - -/* Override the current value of the hardware counter */ -void __hw_clock_source_set(uint32_t ts) -{ -#if DEBUG_TMR - cur_cnt_us_dbg = TICK_ITIM32_MAX_CNT - ts; -#endif - hw_clock_source_set_preload(ts, 0); -} - -/* Irq for hwtimer tick */ -void __hw_clock_source_irq(void) -{ - /* Is timeout trigger trigger? */ - if (IS_BIT_SET(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_TO_STS)) { - /* Restore ITIM32 preload counter value to maximum value */ - hw_clock_source_set_preload(0, 1); - /* 32-bits timer count overflow */ - process_timers(1); - - } else { /* Handle soft trigger */ - process_timers(0); -#ifdef CONFIG_LOW_POWER_IDLE - /* Set event for ITIM32. Please see above for detail */ - if (evt_expired_us == 0) - __hw_clock_event_set(EVT_MAX_EXPIRED_US); -#endif - } -} -DECLARE_IRQ(ITIM_INT(ITIM_SYSTEM_NO), __hw_clock_source_irq, 3); - -/* Handle ITIM32 overflow if interrupt is disabled */ -void __hw_clock_handle_overflow(uint32_t clksrc_high) -{ - timestamp_t newtime; - - /* Overflow occurred? */ - if (!IS_BIT_SET(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_TO_STS)) - return; - - /* Clear timeout status */ - SET_BIT(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_TO_STS); - - /* - * Restore ITIM32 preload counter value to maximum and execute - * process_timers() later in ISR by trigger software interrupt in - * force_time(). - */ - newtime.le.hi = clksrc_high + 1; - newtime.le.lo = 0; - force_time(newtime); -} - -static void update_prescaler(void) -{ - /* - * prescaler to time tick - * Ttick_unit = (PRE_8+1) * Tapb2_clk - * PRE_8 = (Ttick_unit/Tapb2_clk) -1 - */ - NPCX_ITPRE(ITIM_SYSTEM_NO) = (clock_get_apb2_freq() / SECOND) - 1; - /* Set event tick unit = 1/32768 sec */ - NPCX_ITPRE(ITIM_EVENT_NO) = 0; - -} -DECLARE_HOOK(HOOK_FREQ_CHANGE, update_prescaler, HOOK_PRIO_DEFAULT); - -void __hw_early_init_hwtimer(uint32_t start_t) -{ - /* - * 1. Use ITIM16-1 as internal time reading - * 2. Use ITIM16-2 for event handling - */ - - /* Enable clock for ITIM peripheral */ - clock_enable_peripheral(CGC_OFFSET_TIMER, CGC_TIMER_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - - /* init tick & event timer first */ - init_hw_timer(ITIM_SYSTEM_NO, ITIM_SOURCE_CLOCK_APB2); - init_hw_timer(ITIM_EVENT_NO, ITIM_SOURCE_CLOCK_32K); - - /* Set initial prescaler */ - update_prescaler(); - - hw_clock_source_set_preload(start_t, 1); -} - -/* Note that early_init_hwtimer() has already executed by this point */ -int __hw_clock_source_init(uint32_t start_t) -{ - /* - * Override the count with the start value now that counting has - * started. Note that we may have already called this function from - * gpio_pre_init(), but only in the case where we expected a reset, so - * we should not get here in that case. - */ - __hw_early_init_hwtimer(start_t); - - /* Enable interrupt of ITIM */ - task_enable_irq(ITIM_INT(ITIM_SYSTEM_NO)); - - return ITIM_INT(ITIM_SYSTEM_NO); -} diff --git a/chip/npcx/hwtimer_chip.h b/chip/npcx/hwtimer_chip.h deleted file mode 100644 index 987f3b52bd..0000000000 --- a/chip/npcx/hwtimer_chip.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2014 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-specific hwtimer module for Chrome EC */ - -#ifndef __CROS_EC_HWTIMER_CHIP_H -#define __CROS_EC_HWTIMER_CHIP_H - -/* Use ITIM32 as main hardware timer */ -#define TICK_ITIM32_MAX_CNT 0xFFFFFFFF -/* Maximum deadline of event */ -#define EVT_MAX_EXPIRED_US TICK_ITIM32_MAX_CNT - -/* Clock source for ITIM16 */ -enum ITIM_SOURCE_CLOCK_T { - ITIM_SOURCE_CLOCK_APB2 = 0, - ITIM_SOURCE_CLOCK_32K = 1, -}; - -/** - * Initialise a hardware timer - * - * Select the source clock for a timer and prepare it for use. - * - * @param itim_no Timer number to init (enum ITIM_MODULE_T) - * @param source Source for timer clock (enum ITIM_SOURCE_CLOCK_T) - */ -void init_hw_timer(int itim_no, enum ITIM_SOURCE_CLOCK_T source); - -/* Returns the counter value of event timer */ -uint16_t __hw_clock_event_count(void); - -/* Returns time delay because of deep idle */ -uint32_t __hw_clock_get_sleep_time(uint16_t pre_evt_cnt); - -/* Handle ITIM32 overflow if interrupt is disabled */ -void __hw_clock_handle_overflow(uint32_t clksrc_high); - -/** - * Set up the timer for use before the task system is available - * - * @param start_t Value to assign to the counter - */ -void __hw_early_init_hwtimer(uint32_t start_t); - -#endif /* __CROS_EC_HWTIMER_CHIP_H */ diff --git a/chip/npcx/i2c-npcx5.c b/chip/npcx/i2c-npcx5.c deleted file mode 100644 index 6b78fd53f9..0000000000 --- a/chip/npcx/i2c-npcx5.c +++ /dev/null @@ -1,47 +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. - */ - -/* I2C module driver depends on chip series for Chrome EC */ - -#include "i2c.h" -#include "i2c_chip.h" -#include "registers.h" -#include "util.h" - -/*****************************************************************************/ -/* IC specific low-level driver depends on chip series */ - -int i2c_port_to_controller(int port) -{ - if (port < 0 || port >= I2C_PORT_COUNT) - return -1; - - return (port == NPCX_I2C_PORT0_0) ? 0 : port - 1; -} - -void i2c_select_port(int port) -{ - /* - * I2C0_1 uses port 1 of controller 0. All other I2C pin sets - * use port 0. - */ - if (port > NPCX_I2C_PORT0_1) - return; - - /* Select IO pins for multi-ports I2C controllers */ - UPDATE_BIT(NPCX_GLUE_SMBSEL, NPCX_SMBSEL_SMB0SEL, - (port == NPCX_I2C_PORT0_1)); -} - -int i2c_is_raw_mode(int port) -{ - int bit = (port > NPCX_I2C_PORT0_1) ? ((port - 1) * 2) : port; - - if (IS_BIT_SET(NPCX_DEVALT(2), bit)) - return 0; - else - return 1; -} - diff --git a/chip/npcx/i2c-npcx7.c b/chip/npcx/i2c-npcx7.c deleted file mode 100644 index 3f27aff49e..0000000000 --- a/chip/npcx/i2c-npcx7.c +++ /dev/null @@ -1,70 +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. - */ - -/* I2C module driver depends on chip series for Chrome EC */ - -#include "common.h" -#include "i2c.h" -#include "i2c_chip.h" -#include "registers.h" -#include "util.h" - -/*****************************************************************************/ -/* IC specific low-level driver depends on chip series */ - -int i2c_port_to_controller(int port) -{ - if (port < 0 || port >= I2C_PORT_COUNT) - return -1; - - if (port <= NPCX_I2C_PORT3_0) - return port; -#ifndef NPCX_PSL_MODE_SUPPORT - else if (port == NPCX_I2C_PORT4_0) - return 4; -#endif - else /* If port >= NPCX_I2C_PORT4_1 */ - return 4 + ((port - NPCX_I2C_PORT4_1 + 1) / 2); -} - -void i2c_select_port(int port) -{ - /* Only I2C 4/5/6 have multiple ports in series npcx7 */ - if (port <= NPCX_I2C_PORT3_0 || port >= NPCX_I2C_PORT7_0) - return; - /* Select I2C ports for the same controller */ - else if (port <= NPCX_I2C_PORT4_1) { - UPDATE_BIT(NPCX_GLUE_SMBSEL, NPCX_SMBSEL_SMB4SEL, - (port == NPCX_I2C_PORT4_1)); - } else if (port <= NPCX_I2C_PORT5_1) { - UPDATE_BIT(NPCX_GLUE_SMBSEL, NPCX_SMBSEL_SMB5SEL, - (port == NPCX_I2C_PORT5_1)); - } else { - UPDATE_BIT(NPCX_GLUE_SMBSEL, NPCX_SMBSEL_SMB6SEL, - (port == NPCX_I2C_PORT6_1)); - } -} - -int i2c_is_raw_mode(int port) -{ - int group, bit; - - if (port == NPCX_I2C_PORT4_1 || port == NPCX_I2C_PORT5_1 || - port == NPCX_I2C_PORT6_1) { - group = 6; - bit = 7 - (port - NPCX_I2C_PORT4_1) / 2; - } else { - group = 2; - if (port <= NPCX_I2C_PORT3_0) - bit = 2 * port; - else - bit = I2C_PORT_COUNT - port; - } - - if (IS_BIT_SET(NPCX_DEVALT(group), bit)) - return 0; - else - return 1; -} diff --git a/chip/npcx/i2c-npcx9.c b/chip/npcx/i2c-npcx9.c deleted file mode 120000 index b1b16a3198..0000000000 --- a/chip/npcx/i2c-npcx9.c +++ /dev/null @@ -1 +0,0 @@ -i2c-npcx7.c
\ No newline at end of file diff --git a/chip/npcx/i2c.c b/chip/npcx/i2c.c deleted file mode 100644 index 26935f778f..0000000000 --- a/chip/npcx/i2c.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* Copyright 2014 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. - */ - -/* I2C port module for Chrome EC */ - -#include "clock.h" -#include "clock_chip.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "i2c_chip.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#if !(DEBUG_I2C) -#define CPUTS(...) -#define CPRINTS(...) -#define CPRINTF(...) -#else -#define CPUTS(outstr) cputs(CC_I2C, outstr) -#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_I2C, format, ## args) -#endif - -/* Timeout for device should be available after reset (SMBus spec. unit:ms) */ -#define I2C_MAX_TIMEOUT 35 -/* - * Timeout for SCL held to low by peripheral device. (SMBus spec. unit:ms). - * Some I2C devices may violate this timing and clock stretch for longer. - * TODO: Consider increasing this timeout. - */ -#define I2C_MIN_TIMEOUT 25 - -/* - * I2C module that supports FIFO mode has 32 bytes Tx FIFO and - * 32 bytes Rx FIFO. - */ -#define NPCX_I2C_FIFO_MAX_SIZE 32 - -/* Macro functions of I2C */ -#define I2C_START(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_START) -#define I2C_STOP(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_STOP) -#define I2C_NACK(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_ACK) -/* I2C module automatically stall bus after sending peripheral address */ -#define I2C_STALL(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_STASTRE) -#define I2C_WRITE_BYTE(ctrl, data) (NPCX_SMBSDA(ctrl) = data) -#define I2C_READ_BYTE(ctrl, data) (data = NPCX_SMBSDA(ctrl)) -#define I2C_TX_FIFO_OCCUPIED(ctrl) (NPCX_SMBTXF_STS(ctrl) & 0x3F) -#define I2C_TX_FIFO_AVAILABLE(ctrl) \ - (NPCX_I2C_FIFO_MAX_SIZE - I2C_TX_FIFO_OCCUPIED(ctrl)) - -#define I2C_RX_FIFO_OCCUPIED(ctrl) (NPCX_SMBRXF_STS(ctrl) & 0x3F) -#define I2C_RX_FIFO_AVAILABLE(ctrl) \ - (NPCX_I2C_FIFO_MAX_SIZE - I2C_RX_FIFO_OCCUPIED(ctrl)) -/* Drive the SCL signal to low */ -#define I2C_SCL_STALL(ctrl) \ - (NPCX_SMBCTL3(ctrl) = \ - (NPCX_SMBCTL3(ctrl) & ~BIT(NPCX_SMBCTL3_SCL_LVL)) | \ - BIT(NPCX_SMBCTL3_SDA_LVL)) -/* - * Release the SCL signal to be pulled up to high level. - * Note: The SCL might be still driven low either by I2C module or external - * devices connected to ths bus. - */ -#define I2C_SCL_FREE(ctrl) \ - (NPCX_SMBCTL3(ctrl) |= BIT(NPCX_SMBCTL3_SCL_LVL) | \ - BIT(NPCX_SMBCTL3_SDA_LVL)) - -/* Error values that functions can return */ -enum smb_error { - SMB_OK = 0, /* No error */ - SMB_CH_OCCUPIED, /* Channel is already occupied */ - SMB_MEM_POOL_INIT_ERROR, /* Memory pool initialization error */ - SMB_BUS_FREQ_ERROR, /* SMbus freq was not valid */ - SMB_INVLAID_REGVALUE, /* Invalid SMbus register value */ - SMB_UNEXIST_CH_ERROR, /* Channel does not exist */ - SMB_NO_SUPPORT_PTL, /* Not support SMBus Protocol */ - SMB_BUS_ERROR, /* Encounter bus error */ - SMB_NO_ADDRESS_MATCH, /* No peripheral address match */ - /* (Controller Mode) */ - SMB_READ_DATA_ERROR, /* Read data for SDA error */ - SMB_READ_OVERFLOW_ERROR, /* Read data over than we predict */ - SMB_TIMEOUT_ERROR, /* Timeout expired */ - SMB_MODULE_ISBUSY, /* Module is occupied by other device */ - SMB_BUS_BUSY, /* SMBus is occupied by other device */ -}; - -/* - * Internal SMBus Interface driver states values, which reflect events - * which occurred on the bus - */ -enum smb_oper_state_t { - SMB_IDLE, - SMB_CONTROLLER_START, - SMB_WRITE_OPER, - SMB_READ_OPER, - SMB_FAKE_READ_OPER, - SMB_REPEAT_START, - SMB_WRITE_SUSPEND, - SMB_READ_SUSPEND, -}; - -/* I2C controller state data */ -struct i2c_status { - int flags; /* Flags (I2C_XFER_*) */ - const uint8_t *tx_buf; /* Entry pointer of transmit buffer */ - uint8_t *rx_buf; /* Entry pointer of receive buffer */ - uint16_t sz_txbuf; /* Size of Tx buffer in bytes */ - uint16_t sz_rxbuf; /* Size of rx buffer in bytes */ - uint16_t idx_buf; /* Current index of Tx/Rx buffer */ - uint16_t addr_flags;/* Target address */ - enum smb_oper_state_t oper_state;/* Smbus operation state */ - enum smb_error err_code; /* Error code */ - int task_waiting; /* Task waiting on controller */ - uint32_t timeout_us;/* Transaction timeout */ - uint16_t kbps; /* Speed */ -}; -/* I2C controller state data array */ -static struct i2c_status i2c_stsobjs[I2C_CONTROLLER_COUNT]; - -/* I2C timing setting */ -struct i2c_timing { - uint8_t clock; /* I2C source clock. (Unit: MHz)*/ - uint8_t HLDT; /* I2C hold-time. (Unit: clocks) */ - uint8_t k1; /* k1 = SCL low-time (Unit: clocks) */ - uint8_t k2; /* k2 = SCL high-time (Unit: clocks) */ -}; - -/* I2C timing setting array of 400K & 1M Hz */ -static const struct i2c_timing i2c_400k_timings[] = { - {20, 7, 32, 22}, - {15, 7, 24, 18},}; -const unsigned int i2c_400k_timing_used = ARRAY_SIZE(i2c_400k_timings); - -static const struct i2c_timing i2c_1m_timings[] = { - {20, 7, 16, 10}, - {15, 7, 14, 10},}; -const unsigned int i2c_1m_timing_used = ARRAY_SIZE(i2c_1m_timings); - -/* IRQ for each port */ -const uint32_t i2c_irqs[I2C_CONTROLLER_COUNT] = { - NPCX_IRQ_SMB1, NPCX_IRQ_SMB2, NPCX_IRQ_SMB3, NPCX_IRQ_SMB4, -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - NPCX_IRQ_SMB5, NPCX_IRQ_SMB6, NPCX_IRQ_SMB7, NPCX_IRQ_SMB8, -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(i2c_irqs) == I2C_CONTROLLER_COUNT); - -static void i2c_init_bus(int controller) -{ - /* Enable FIFO mode */ - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) - SET_BIT(NPCX_SMBFIF_CTL(controller), NPCX_SMBFIF_CTL_FIFO_EN); - - /* Enable module - before configuring CTL1 */ - SET_BIT(NPCX_SMBCTL2(controller), NPCX_SMBCTL2_ENABLE); - - /* Enable SMB interrupt and New Address Match interrupt source */ - SET_BIT(NPCX_SMBCTL1(controller), NPCX_SMBCTL1_NMINTE); - SET_BIT(NPCX_SMBCTL1(controller), NPCX_SMBCTL1_INTEN); -} - -int i2c_bus_busy(int controller) -{ - return IS_BIT_SET(NPCX_SMBCST(controller), NPCX_SMBCST_BB) ? 1 : 0; -} - -static int i2c_wait_stop_completed(int controller, int timeout) -{ - if (timeout <= 0) - return EC_ERROR_INVAL; - - /* Wait till STOP condition is generated. ie. I2C bus is idle. */ - while (timeout > 0) { - if (!IS_BIT_SET(NPCX_SMBCTL1(controller), NPCX_SMBCTL1_STOP)) - break; - if (--timeout > 0) - msleep(1); - } - - if (timeout) - return EC_SUCCESS; - else - return EC_ERROR_TIMEOUT; -} - -static void i2c_abort_data(int controller) -{ - /* Clear NEGACK, STASTR and BER bits */ - SET_BIT(NPCX_SMBST(controller), NPCX_SMBST_BER); - SET_BIT(NPCX_SMBST(controller), NPCX_SMBST_STASTR); - SET_BIT(NPCX_SMBST(controller), NPCX_SMBST_NEGACK); - - /* Wait till STOP condition is generated */ - if (i2c_wait_stop_completed(controller, I2C_MAX_TIMEOUT) - != EC_SUCCESS) { - cprintf(CC_I2C, "Abort i2c %02x fail!\n", controller); - /* Clear BB (BUS BUSY) bit */ - SET_BIT(NPCX_SMBCST(controller), NPCX_SMBCST_BB); - return; - } - - /* Clear BB (BUS BUSY) bit */ - SET_BIT(NPCX_SMBCST(controller), NPCX_SMBCST_BB); -} - -static int i2c_reset(int controller) -{ - uint16_t timeout = I2C_MAX_TIMEOUT; - - /* Disable the SMB module */ - CLEAR_BIT(NPCX_SMBCTL2(controller), NPCX_SMBCTL2_ENABLE); - - while (--timeout) { - /* WAIT FOR SCL & SDA IS HIGH */ - if (IS_BIT_SET(NPCX_SMBCTL3(controller), NPCX_SMBCTL3_SCL_LVL) - && IS_BIT_SET(NPCX_SMBCTL3(controller), NPCX_SMBCTL3_SDA_LVL)) - break; - msleep(1); - } - - if (timeout == 0) { - cprintf(CC_I2C, "Reset i2c %02x fail!\n", controller); - return 0; - } - - /* Init the SMB module again */ - i2c_init_bus(controller); - return 1; -} - -static void i2c_select_bank(int controller, int bank) -{ - if (bank) - SET_BIT(NPCX_SMBCTL3(controller), NPCX_SMBCTL3_BNK_SEL); - else - CLEAR_BIT(NPCX_SMBCTL3(controller), NPCX_SMBCTL3_BNK_SEL); -} - -static void i2c_stall_bus(int controller, int stall) -{ - i2c_select_bank(controller, 0); - /* - * Enable the writing to SCL_LVL and SDA_LVL bit in - * SMBnCTL3 register. Then, firmware can set SCL_LVL to 0 to - * stall the bus when needed. Note: this register should be - * accessed when bank = 0. - */ - SET_BIT(NPCX_SMBCTL4(controller), NPCX_SMBCTL4_LVL_WE); - if (stall) - I2C_SCL_STALL(controller); - else - I2C_SCL_FREE(controller); - /* - * Disable the writing to SCL_LVL and SDA_LVL bit in - * SMBnCTL3 register. It will prevent form changing the level of - * SCL/SDA when touching other bits in SMBnCTL3 register. - */ - CLEAR_BIT(NPCX_SMBCTL4(controller), NPCX_SMBCTL4_LVL_WE); - i2c_select_bank(controller, 1); -} - -static void i2c_recovery(int controller, volatile struct i2c_status *p_status) -{ - cprintf(CC_I2C, - "i2c %d recovery! error code is %d, current state is %d\n", - controller, p_status->err_code, p_status->oper_state); - - /* Make sure the bus is not stalled before exit. */ - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) - i2c_stall_bus(controller, 0); - - /* Abort data, wait for STOP condition completed. */ - i2c_abort_data(controller); - - /* Reset i2c controller by re-enable i2c controller*/ - if (!i2c_reset(controller)) - return; - - /* Restore to idle status */ - p_status->oper_state = SMB_IDLE; -} - -/* - * This function can be called in either single-byte mode or FIFO mode. - * In single-byte mode - it always write 1 byte to SMBSDA register at one time. - * In FIFO mode - write as many as available bytes in FIFO at one time. - */ -static void i2c_fifo_write_data(int controller) -{ - int len, fifo_avail, i; - - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - - len = 1; - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) { - len = p_status->sz_txbuf - p_status->idx_buf; - fifo_avail = I2C_TX_FIFO_AVAILABLE(controller); - len = MIN(len, fifo_avail); - } - for (i = 0; i < len; i++) { - I2C_WRITE_BYTE(controller, - p_status->tx_buf[p_status->idx_buf++]); - CPRINTF("%02x ", - p_status->tx_buf[p_status->idx_buf - 1]); - } - CPRINTF("\n"); -} - -enum smb_error i2c_controller_transaction(int controller) -{ - /* Set i2c mode to object */ - int events = 0; - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - - /* Switch to bank 1 to access I2C FIO registers */ - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) - i2c_select_bank(controller, 1); - - /* Assign current SMB status of controller */ - if (p_status->oper_state == SMB_IDLE) { - /* New transaction */ - p_status->oper_state = SMB_CONTROLLER_START; - /* Clear FIFO and status bit */ - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) { - NPCX_SMBFIF_CTS(controller) = - BIT(NPCX_SMBFIF_CTS_RXF_TXE) | - BIT(NPCX_SMBFIF_CTS_CLR_FIFO); - } - } else if (p_status->oper_state == SMB_WRITE_SUSPEND) { - if (p_status->sz_txbuf == 0) { - /* Read bytes from next transaction */ - p_status->oper_state = SMB_REPEAT_START; - CPUTS("R"); - } else { - /* Continue to write the other bytes */ - p_status->oper_state = SMB_WRITE_OPER; - CPRINTS("-W"); - /* - * This function can be called in either single-byte - * mode or FIFO mode. - */ - i2c_fifo_write_data(controller); - } - } else if (p_status->oper_state == SMB_READ_SUSPEND) { - if (!IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) { - /* - * Do extra read if read length is 1 and I2C_XFER_STOP - * is set simultaneously. - */ - if (p_status->sz_rxbuf == 1 && - (p_status->flags & I2C_XFER_STOP)) { - /* - * Since SCL is released after reading last - * byte from previous transaction, adding a - * extra byte for next transaction which let - * ec sets NACK bit in time is necessary. - * Or i2c controller cannot generate STOP - * when the last byte is ACK during receiving. - */ - p_status->sz_rxbuf++; - p_status->oper_state = SMB_FAKE_READ_OPER; - } else - /* - * Need to read the other bytes from - * next transaction - */ - p_status->oper_state = SMB_READ_OPER; - } - } else - cprintf(CC_I2C, "Unexpected i2c state machine! %d\n", - p_status->oper_state); - - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) { - if (p_status->sz_rxbuf > 0) { - if (p_status->sz_rxbuf > NPCX_I2C_FIFO_MAX_SIZE) { - /* Set RX threshold = FIFO_MAX_SIZE */ - SET_FIELD(NPCX_SMBRXF_CTL(controller), - NPCX_SMBRXF_CTL_RX_THR, - NPCX_I2C_FIFO_MAX_SIZE); - } else { - /* - * set RX threshold = remaining data bytes - * (it should be <= FIFO_MAX_SIZE) - */ - SET_FIELD(NPCX_SMBRXF_CTL(controller), - NPCX_SMBRXF_CTL_RX_THR, - p_status->sz_rxbuf); - /* - * Set LAST bit generate the NACK at the - * last byte of the data group in FIFO - */ - if (p_status->flags & I2C_XFER_STOP) { - SET_BIT(NPCX_SMBRXF_CTL(controller), - NPCX_SMBRXF_CTL_LAST); - } - } - - /* Free the stalled SCL signal */ - if (p_status->oper_state == SMB_READ_SUSPEND) { - p_status->oper_state = SMB_READ_OPER; - i2c_stall_bus(controller, 0); - } - } - } - - /* Generate a START condition */ - if (p_status->oper_state == SMB_CONTROLLER_START || - p_status->oper_state == SMB_REPEAT_START) { - I2C_START(controller); - CPUTS("ST"); - } - - /* Enable event and error interrupts */ - task_enable_irq(i2c_irqs[controller]); - - /* Wait for transfer complete or timeout */ - events = task_wait_event_mask(TASK_EVENT_I2C_IDLE, - p_status->timeout_us); - - /* Disable event and error interrupts */ - task_disable_irq(i2c_irqs[controller]); - - /* - * Accessing FIFO register is only needed during transaction. - * Switch back to bank 0 at the end of transaction - */ - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) - i2c_select_bank(controller, 0); - - /* - * If Stall-After-Start mode is still enabled since NACK or BUS error - * occurs, disable it. - */ - if (IS_BIT_SET(NPCX_SMBCTL1(controller), NPCX_SMBCTL1_STASTRE)) - CLEAR_BIT(NPCX_SMBCTL1(controller), NPCX_SMBCTL1_STASTRE); - - /* Handle bus timeout */ - if ((events & TASK_EVENT_I2C_IDLE) == 0) { - p_status->err_code = SMB_TIMEOUT_ERROR; - /* Recovery I2C controller */ - i2c_recovery(controller, p_status); - } - /* Recovery bus if we encounter bus error */ - else if (p_status->err_code == SMB_BUS_ERROR) - i2c_recovery(controller, p_status); - - /* Wait till STOP condition is generated for normal transaction */ - if (p_status->err_code == SMB_OK && i2c_wait_stop_completed(controller, - I2C_MIN_TIMEOUT) != EC_SUCCESS) { - cprintf(CC_I2C, - "STOP fail! scl %02x is held by slave device!\n", - controller); - p_status->err_code = SMB_TIMEOUT_ERROR; - } - - return p_status->err_code; -} - -/* Issue stop condition if necessary and end transaction */ -void i2c_done(int controller) -{ - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - - /* need to STOP or not */ - if (p_status->flags & I2C_XFER_STOP) { - /* Issue a STOP condition on the bus */ - I2C_STOP(controller); - CPUTS("-SP"); - /* Clear RXF_TXE bit (RX FIFO full/TX FIFO empty) */ - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) - NPCX_SMBFIF_CTS(controller) = - BIT(NPCX_SMBFIF_CTS_RXF_TXE); - - /* Clear SDAST by writing mock byte */ - I2C_WRITE_BYTE(controller, 0xFF); - } - - /* Set error code */ - p_status->err_code = SMB_OK; - /* Set SMB status if we need stall bus */ - p_status->oper_state = (p_status->flags & I2C_XFER_STOP) - ? SMB_IDLE : SMB_WRITE_SUSPEND; - /* - * Disable interrupt for i2c controller stall SCL - * and forbid SDAST generate interrupt - * until common layer start other transactions - */ - if (p_status->oper_state == SMB_WRITE_SUSPEND) - task_disable_irq(i2c_irqs[controller]); - - /* Notify upper layer */ - task_set_event(p_status->task_waiting, TASK_EVENT_I2C_IDLE); - CPUTS("-END"); -} - -static void i2c_handle_receive(int controller) -{ - uint8_t data; - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - - /* last byte is about to be read - end of transaction */ - if (p_status->idx_buf == (p_status->sz_rxbuf - 1)) { - /* need to STOP or not */ - if (p_status->flags & I2C_XFER_STOP) { - /* Stop should set before reading last byte */ - I2C_STOP(controller); - CPUTS("-SP"); - } else { - /* - * Disable interrupt before i2c controller read SDA - * reg (stall SCL) and forbid SDAST generate - * interrupt until starting other transactions - */ - task_disable_irq(i2c_irqs[controller]); - } - } - /* Check if byte-before-last is about to be read */ - else if (p_status->idx_buf == (p_status->sz_rxbuf - 2)) { - /* - * Set nack before reading byte-before-last, - * so that nack will be generated after receive - * of last byte - */ - if (p_status->flags & I2C_XFER_STOP) { - I2C_NACK(controller); - CPUTS("-GNA"); - } - } - - /* Read data for SMBSDA */ - I2C_READ_BYTE(controller, data); - CPRINTS("-R(%02x)", data); - - /* Read to buf. Skip last byte if meet SMB_FAKE_READ_OPER */ - if (p_status->oper_state == SMB_FAKE_READ_OPER && - p_status->idx_buf == (p_status->sz_rxbuf - 1)) - p_status->idx_buf++; - else - p_status->rx_buf[p_status->idx_buf++] = data; - - /* last byte is read - end of transaction */ - if (p_status->idx_buf == p_status->sz_rxbuf) { - /* Set current status */ - p_status->oper_state = (p_status->flags & I2C_XFER_STOP) - ? SMB_IDLE : SMB_READ_SUSPEND; - /* Set error code */ - p_status->err_code = SMB_OK; - /* Notify upper layer of missing data */ - task_set_event(p_status->task_waiting, TASK_EVENT_I2C_IDLE); - CPUTS("-END"); - } -} - -static void i2c_fifo_read_data(int controller, uint8_t bytes_in_fifo) -{ - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - - while (bytes_in_fifo--) { - uint8_t data; - - data = NPCX_SMBSDA(controller); - p_status->rx_buf[p_status->idx_buf++] = data; - CPRINTF("%02x ", data); - } - CPRINTF("\n"); -} - -static void i2c_fifo_handle_receive(int controller) -{ - uint8_t bytes_in_fifo, remaining_bytes; - - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - - /* - * Clear RX_THST bit (RX-FIFO Threshold Status). - * It is set when RX_BYTES = RX_THR after being RX_BYTES < RX_THR - */ - SET_BIT(NPCX_SMBRXF_STS(controller), NPCX_SMBRXF_STS_RX_THST); - SET_BIT(NPCX_SMBFIF_CTS(controller), NPCX_SMBFIF_CTS_RXF_TXE); - - bytes_in_fifo = I2C_RX_FIFO_OCCUPIED(controller); - remaining_bytes = p_status->sz_rxbuf - p_status->idx_buf; - if (remaining_bytes - bytes_in_fifo <= 0) { - /* - * Last byte is about to be read - end of transaction. - * Stop should be set before reading last byte. - */ - if (p_status->flags & I2C_XFER_STOP) { - I2C_STOP(controller); - CPUTS("-FSP"); - } else { - task_disable_irq(i2c_irqs[controller]); - /* - * The I2C bus will be freed from stalled and continue - * to recevie data when reading data from FIFO. - * Pull SCL signal down to stall the bus manually. - * SCL signal will be freed when it gets a new I2C - * transaction call from common layer. - */ - i2c_stall_bus(controller, 1); - } - - CPRINTS("-LFR"); - i2c_fifo_read_data(controller, remaining_bytes); - } else { - CPRINTS("-FR"); - /* - * The I2C bus will be freed from stalled and continue to - * recevie data when reading data from FIFO. - * This may caue driver cannot set the new Rx threshold in time. - * Manually stall SCL signal until the new Rx threshold is set. - */ - i2c_stall_bus(controller, 1); - i2c_fifo_read_data(controller, bytes_in_fifo); - remaining_bytes = p_status->sz_rxbuf - p_status->idx_buf; - if (remaining_bytes > 0) { - if (remaining_bytes > NPCX_I2C_FIFO_MAX_SIZE) { - SET_FIELD(NPCX_SMBRXF_CTL(controller), - NPCX_SMBRXF_CTL_RX_THR, - NPCX_I2C_FIFO_MAX_SIZE); - } else { - SET_FIELD(NPCX_SMBRXF_CTL(controller), - NPCX_SMBRXF_CTL_RX_THR, - remaining_bytes); - if (p_status->flags & I2C_XFER_STOP) { - SET_BIT(NPCX_SMBRXF_CTL(controller), - NPCX_SMBRXF_CTL_LAST); - CPRINTS("-FGNA"); - } - } - - } - i2c_stall_bus(controller, 0); - - } - /* last byte is read - end of transaction */ - if (p_status->idx_buf == p_status->sz_rxbuf) { - /* Set current status */ - p_status->oper_state = (p_status->flags & I2C_XFER_STOP) - ? SMB_IDLE : SMB_READ_SUSPEND; - /* Set error code */ - p_status->err_code = SMB_OK; - /* Notify upper layer of missing data */ - task_set_event(p_status->task_waiting, TASK_EVENT_I2C_IDLE); - CPUTS("-END"); - } - -} - -static void i2c_handle_sda_irq(int controller) -{ - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - uint8_t addr_8bit = I2C_STRIP_FLAGS(p_status->addr_flags) << 1; - - /* 1 Issue Start is successful ie. write address byte */ - if (p_status->oper_state == SMB_CONTROLLER_START - || p_status->oper_state == SMB_REPEAT_START) { - /* Prepare address byte */ - if (p_status->sz_txbuf == 0) {/* Receive mode */ - p_status->oper_state = SMB_READ_OPER; - /* - * Receiving one or zero bytes - stall bus after - * START condition. If there's no peripheral - * devices on bus, FW needn't to set ACK bit. - */ - if (p_status->sz_rxbuf < 2) - I2C_STALL(controller); - - /* Write the address to the bus R bit*/ - I2C_WRITE_BYTE(controller, (addr_8bit | 0x1)); - CPRINTS("-ARR-0x%02x", addr_8bit); - } else {/* Transmit mode */ - p_status->oper_state = SMB_WRITE_OPER; - /* Write the address to the bus W bit*/ - I2C_WRITE_BYTE(controller, addr_8bit); - CPRINTS("-ARW-0x%02x", addr_8bit); - } - /* Completed handling START condition */ - return; - } - /* 2 Handle controller write operation */ - else if (p_status->oper_state == SMB_WRITE_OPER) { - /* all bytes have been written, in a pure write operation */ - if (p_status->idx_buf == p_status->sz_txbuf) { - /* no more message */ - if (p_status->sz_rxbuf == 0) - i2c_done(controller); - /* - * need to restart & send peripheral address - * immediately - */ - else { - /* - * Prepare address byte - * and start to receive bytes - */ - p_status->oper_state = SMB_READ_OPER; - /* Reset index of buffer */ - p_status->idx_buf = 0; - - /* - * Generate (Repeated) Start - * upon next write to SDA - */ - I2C_START(controller); - CPUTS("-RST"); - /* - * Receiving one byte only - set NACK just - * before writing address byte. - * Set NACK (ACK bit in the SMBnCTL1 register) - * only in the single-byte mode. - * In FIFO mode, NACK is set via LAST bit - * in the SMBnTXF_CTL register. - */ - if (p_status->sz_rxbuf == 1 && - (p_status->flags & I2C_XFER_STOP) && - !IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) { - I2C_NACK(controller); - CPUTS("-GNA"); - } - /* Write the address to the bus R bit*/ - I2C_WRITE_BYTE(controller, - (addr_8bit | 0x1)); - CPUTS("-ARR"); - } - } - /* - * write next byte (not last byte and not peripheral - * address) - */ - else { - /* - * This function can be called in either single-byte - * mode or FIFO mode. - */ - CPRINTS("-W"); - i2c_fifo_write_data(controller); - } - } - /* - * 3 Handle controller read operation (read or after a write - * operation) - */ - else if (p_status->oper_state == SMB_READ_OPER || - p_status->oper_state == SMB_FAKE_READ_OPER) { - if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) - i2c_fifo_handle_receive(controller); - else - i2c_handle_receive(controller); - } -} - -static void i2c_controller_int_handler(int controller) -{ - volatile struct i2c_status *p_status = i2c_stsobjs + controller; - - /* Condition 1 : A Bus Error has been identified */ - if (IS_BIT_SET(NPCX_SMBST(controller), NPCX_SMBST_BER)) { - uint8_t __attribute__((unused)) data; - /* Generate a STOP condition */ - I2C_STOP(controller); - CPUTS("-SP"); - /* Clear BER Bit */ - SET_BIT(NPCX_SMBST(controller), NPCX_SMBST_BER); - /* Make sure peripheral doesn't hold bus by reading */ - I2C_READ_BYTE(controller, data); - - /* Set error code */ - p_status->err_code = SMB_BUS_ERROR; - /* Notify upper layer */ - p_status->oper_state = SMB_IDLE; - task_set_event(p_status->task_waiting, TASK_EVENT_I2C_IDLE); - CPUTS("-BER"); - - /* - * Disable smb's interrupts to forbid ec to enter ISR again - * before executing error recovery. - */ - task_disable_irq(i2c_irqs[controller]); - - /* return for executing error recovery immediately */ - return; - } - - /* Condition 2: A negative acknowledge has occurred */ - if (IS_BIT_SET(NPCX_SMBST(controller), NPCX_SMBST_NEGACK)) { - /* Generate a STOP condition */ - I2C_STOP(controller); - CPUTS("-SP"); - /* Clear NEGACK Bit */ - SET_BIT(NPCX_SMBST(controller), NPCX_SMBST_NEGACK); - /* Set error code */ - p_status->err_code = SMB_NO_ADDRESS_MATCH; - /* Notify upper layer */ - p_status->oper_state = SMB_IDLE; - task_set_event(p_status->task_waiting, TASK_EVENT_I2C_IDLE); - CPUTS("-NA"); - } - - /* Condition 3: A Stall after START has occurred for READ-BYTE */ - if (IS_BIT_SET(NPCX_SMBST(controller), NPCX_SMBST_STASTR)) { - CPUTS("-STL"); - - /* Disable Stall-After-Start mode first */ - CLEAR_BIT(NPCX_SMBCTL1(controller), NPCX_SMBCTL1_STASTRE); - - /* - * Generate stop condition and return success status since - * ACK received on zero-byte transaction. - */ - if (p_status->sz_rxbuf == 0) - i2c_done(controller); - /* - * Otherwise we have a one-byte transaction, so NACK after - * receiving next byte, if requested. - * Set NACK (ACK bit in the SMBnCTL1 register) only in the - * single-byte mode. - * In FIFO mode, NACK is set via LAST bit in the SMBnTXF_CTL - * register. - */ - else if ((p_status->flags & I2C_XFER_STOP) && - !IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) { - I2C_NACK(controller); - } - - /* Clear STASTR to release SCL after setting NACK/STOP bits */ - SET_BIT(NPCX_SMBST(controller), NPCX_SMBST_STASTR); - } - - /* Condition 4: SDA status is set - transmit or receive */ - if (IS_BIT_SET(NPCX_SMBST(controller), NPCX_SMBST_SDAST)) { - i2c_handle_sda_irq(controller); -#if DEBUG_I2C - /* SDAST still issued with unexpected state machine */ - if (IS_BIT_SET(NPCX_SMBST(controller), NPCX_SMBST_SDAST) && - p_status->oper_state != SMB_WRITE_SUSPEND) { - cprints(CC_I2C, "i2c %d unknown state %d, error %d\n", - controller, p_status->oper_state, p_status->err_code); - } -#endif - } -} - -/** - * Handle an interrupt on the specified controller. - * - * @param controller I2C controller generating interrupt - */ -void handle_interrupt(int controller) -{ - i2c_controller_int_handler(controller); -} - -void i2c0_interrupt(void) { handle_interrupt(0); } -void i2c1_interrupt(void) { handle_interrupt(1); } -void i2c2_interrupt(void) { handle_interrupt(2); } -void i2c3_interrupt(void) { handle_interrupt(3); } -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 -void i2c4_interrupt(void) { handle_interrupt(4); } -void i2c5_interrupt(void) { handle_interrupt(5); } -void i2c6_interrupt(void) { handle_interrupt(6); } -void i2c7_interrupt(void) { handle_interrupt(7); } -#endif - -DECLARE_IRQ(NPCX_IRQ_SMB1, i2c0_interrupt, 4); -DECLARE_IRQ(NPCX_IRQ_SMB2, i2c1_interrupt, 4); -DECLARE_IRQ(NPCX_IRQ_SMB3, i2c2_interrupt, 4); -DECLARE_IRQ(NPCX_IRQ_SMB4, i2c3_interrupt, 4); -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 -DECLARE_IRQ(NPCX_IRQ_SMB5, i2c4_interrupt, 4); -DECLARE_IRQ(NPCX_IRQ_SMB6, i2c5_interrupt, 4); -DECLARE_IRQ(NPCX_IRQ_SMB7, i2c6_interrupt, 4); -DECLARE_IRQ(NPCX_IRQ_SMB8, i2c7_interrupt, 4); -#endif - -/*****************************************************************************/ -/* IC specific low-level driver */ - -void i2c_set_timeout(int port, uint32_t timeout) -{ - int ctrl = i2c_port_to_controller(port); - - /* Return if i2c_port_to_controller() returned an error */ - if (ctrl < 0) - return; - - /* Param is port, but timeout is stored by-controller. */ - i2c_stsobjs[ctrl].timeout_us = - timeout ? timeout : I2C_TIMEOUT_DEFAULT_US; -} - -int chip_i2c_xfer(const int port, - const uint16_t addr_flags, - const uint8_t *out, int out_size, - uint8_t *in, int in_size, int flags) -{ - volatile struct i2c_status *p_status; - int ctrl = i2c_port_to_controller(port); - - /* Return error if i2c_port_to_controller() returned an error */ - if (ctrl < 0) - return EC_ERROR_INVAL; - - /* Skip unnecessary transaction */ - if (out_size == 0 && in_size == 0) - return EC_SUCCESS; - - p_status = i2c_stsobjs + ctrl; - - /* Assign current task ID */ - p_status->task_waiting = task_get_current(); - - /* Select port for multi-ports i2c controller */ - i2c_select_port(port); - - /* Copy data to controller struct */ - p_status->flags = flags; - p_status->tx_buf = out; - p_status->sz_txbuf = out_size; - p_status->rx_buf = in; - p_status->sz_rxbuf = in_size; - p_status->addr_flags = addr_flags; - - /* Reset index & error */ - p_status->idx_buf = 0; - p_status->err_code = SMB_OK; - - /* Make sure we're in a good state to start */ - if ((flags & I2C_XFER_START) && - /* Ignore busy bus for repeated start */ - p_status->oper_state != SMB_WRITE_SUSPEND && - (i2c_bus_busy(ctrl) - || (i2c_get_line_levels(port) != I2C_LINE_IDLE))) { - int ret; - - /* Attempt to unwedge the i2c port */ - ret = i2c_unwedge(port); - if (ret) - return ret; - p_status->err_code = SMB_BUS_BUSY; - /* recover i2c controller */ - i2c_recovery(ctrl, p_status); - /* Select port again for recovery */ - i2c_select_port(port); - } - - CPUTS("\n"); - - /* Start controller transaction */ - i2c_controller_transaction(ctrl); - - /* Reset task ID */ - p_status->task_waiting = TASK_ID_INVALID; - - CPRINTS("-Err:0x%02x", p_status->err_code); - - return (p_status->err_code == SMB_OK) ? EC_SUCCESS : EC_ERROR_UNKNOWN; -} - -/** - * Return raw I/O line levels (I2C_LINE_*) for a port when port is in alternate - * function mode. - * - * @param port Port to check - * @return State of SCL/SDA bit 0/1 - */ -int i2c_get_line_levels(int port) -{ - return (i2c_raw_get_sda(port) ? I2C_LINE_SDA_HIGH : 0) | - (i2c_raw_get_scl(port) ? I2C_LINE_SCL_HIGH : 0); -} - -int i2c_raw_get_scl(int port) -{ - enum gpio_signal g; - - /* - * Check do we support this port of i2c and return gpio number of scl. - * Please notice we cannot read voltage level from GPIO in M4 EC - */ - if (get_scl_from_i2c_port(port, &g) == EC_SUCCESS) { - if (i2c_is_raw_mode(port)) - return gpio_get_level(g); - else - return IS_BIT_SET(NPCX_SMBCTL3( - i2c_port_to_controller(port)), NPCX_SMBCTL3_SCL_LVL); - } - - /* If no SCL pin defined for this port, then return 1 to appear idle */ - return 1; -} - -int i2c_raw_get_sda(int port) -{ - enum gpio_signal g; - - /* - * Check do we support this port of i2c and return gpio number of scl. - * Please notice we cannot read voltage level from GPIO in M4 EC - */ - if (get_sda_from_i2c_port(port, &g) == EC_SUCCESS) { - if (i2c_is_raw_mode(port)) - return gpio_get_level(g); - else - return IS_BIT_SET(NPCX_SMBCTL3( - i2c_port_to_controller(port)), NPCX_SMBCTL3_SDA_LVL); - } - - - /* If no SDA pin defined for this port, then return 1 to appear idle */ - return 1; -} - -/*****************************************************************************/ - -static void i2c_port_set_freq(const int ctrl, const int bus_freq_kbps) -{ - int freq, j; - int scl_freq; - const struct i2c_timing *pTiming; - int i2c_timing_used; - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - /* - * SMB0/1/4/5/6/7 use APB3 clock - * SMB2/3 use APB2 clock - */ - freq = (ctrl < 2 || ctrl > 3) ? - clock_get_apb3_freq() : clock_get_apb2_freq(); -#else /* CHIP_FAMILY_NPCX5 */ - /* - * SMB0/1 use core clock - * SMB2/3 use APB2 clock - */ - freq = (ctrl < 2) ? clock_get_freq() : clock_get_apb2_freq(); -#endif - - if (bus_freq_kbps == i2c_stsobjs[ctrl].kbps) - return; - - /* - * Set SCL frequency by formula: - * tSCL = 4 * SCLFRQ * tCLK - * fSCL = fCLK / (4*SCLFRQ) - * SCLFRQ = ceil(fCLK/(4*fSCL)) - */ - scl_freq = DIV_ROUND_UP(freq, bus_freq_kbps*4000); /* Unit in bps */ - - /* Normal mode if I2C freq is under 100kHz */ - if (bus_freq_kbps <= 100) { - i2c_stsobjs[ctrl].kbps = bus_freq_kbps; - /* Set divider value of SCL */ - SET_FIELD(NPCX_SMBCTL2(ctrl), NPCX_SMBCTL2_SCLFRQ7_FIELD, - (scl_freq & 0x7F)); - SET_FIELD(NPCX_SMBCTL3(ctrl), NPCX_SMBCTL3_SCLFRQ2_FIELD, - (scl_freq >> 7)); - return; - } - - /* use Fast Mode */ - SET_BIT(NPCX_SMBCTL3(ctrl), NPCX_SMBCTL3_400K); - /* - * Set SCLH(L)T and hold-time directly for best I2C - * timing condition for all source clocks. Please refer - * Section 7.5.9 "SMBus Timing - Fast Mode" for detail. - */ - if (bus_freq_kbps == 400) { - pTiming = i2c_400k_timings; - i2c_timing_used = i2c_400k_timing_used; - } else if (bus_freq_kbps == 1000) { - pTiming = i2c_1m_timings; - i2c_timing_used = i2c_1m_timing_used; - } else { - i2c_stsobjs[ctrl].kbps = bus_freq_kbps; - /* Set value from formula */ - NPCX_SMBSCLLT(ctrl) = scl_freq; - NPCX_SMBSCLHT(ctrl) = scl_freq; - cprints(CC_I2C, - "Warning: I2C %d: Use 400kHz or 1MHz for better timing", - ctrl); - return; - } - - for (j = 0; j < i2c_timing_used; j++, pTiming++) { - if (pTiming->clock == (freq/SECOND)) { - i2c_stsobjs[ctrl].kbps = bus_freq_kbps; - /* Set SCLH(L)T and hold-time */ - NPCX_SMBSCLLT(ctrl) = pTiming->k1/2; - NPCX_SMBSCLHT(ctrl) = pTiming->k2/2; - SET_FIELD(NPCX_SMBCTL4(ctrl), - NPCX_SMBCTL4_HLDT_FIELD, pTiming->HLDT); - break; - } - } - if (j == i2c_timing_used) - cprints(CC_I2C, "Error: I2C %d: src clk %d not supported", - ctrl, freq / SECOND); -} - -/* Hooks */ - -static void i2c_freq_changed(void) -{ - int i; - - for (i = 0; i < I2C_CONTROLLER_COUNT; ++i) { - /* No bus speed configured */ - i2c_stsobjs[i].kbps = 0; - } - - for (i = 0; i < i2c_ports_used; i++) { - const struct i2c_port_t *p; - int ctrl; - - p = &i2c_ports[i]; - ctrl = i2c_port_to_controller(p->port); - if (ctrl < 0) - continue; - i2c_port_set_freq(ctrl, p->kbps); - } -} - -DECLARE_HOOK(HOOK_FREQ_CHANGE, i2c_freq_changed, HOOK_PRIO_DEFAULT); - -enum i2c_freq chip_i2c_get_freq(int chip_i2c_port) -{ - int ctrl; - int kbps; - - ctrl = i2c_port_to_controller(chip_i2c_port); - if (ctrl < 0) - return I2C_FREQ_COUNT; - - kbps = i2c_stsobjs[ctrl].kbps; - - if (kbps > 400) - return I2C_FREQ_1000KHZ; - if (kbps > 100) - return I2C_FREQ_400KHZ; - - if (kbps == 100) - return I2C_FREQ_100KHZ; - - return I2C_FREQ_COUNT; -} - -int chip_i2c_set_freq(int chip_i2c_port, enum i2c_freq freq) -{ - int ctrl; - int bus_freq_kbps; - - ctrl = i2c_port_to_controller(chip_i2c_port); - if (ctrl < 0) - return EC_ERROR_INVAL; - - switch (freq) { - case I2C_FREQ_100KHZ: - bus_freq_kbps = 100; - break; - case I2C_FREQ_400KHZ: - bus_freq_kbps = 400; - break; - case I2C_FREQ_1000KHZ: - bus_freq_kbps = 1000; - break; - default: - return EC_ERROR_INVAL; - } - - i2c_port_set_freq(ctrl, bus_freq_kbps); - return EC_SUCCESS; -} - -void i2c_init(void) -{ - int i; - - /* Configure pins from GPIOs to I2Cs */ - gpio_config_module(MODULE_I2C, 1); - - /* Enable clock for I2C peripheral */ - clock_enable_peripheral(CGC_OFFSET_I2C, CGC_I2C_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - clock_enable_peripheral(CGC_OFFSET_I2C2, CGC_I2C_MASK2, - CGC_MODE_RUN | CGC_MODE_SLEEP); -#endif - - /* Set I2C freq */ - i2c_freq_changed(); - /* - * initialize smb status and register - */ - for (i = 0; i < i2c_ports_used; i++) { - volatile struct i2c_status *p_status; - int port = i2c_ports[i].port; - int ctrl = i2c_port_to_controller(port); - - /* ignore the port if i2c_port_to_controller() failed */ - if (ctrl < 0) - continue; - - p_status = i2c_stsobjs + ctrl; - - /* status init */ - p_status->oper_state = SMB_IDLE; - - /* Reset task ID */ - p_status->task_waiting = TASK_ID_INVALID; - - /* Use default timeout. */ - i2c_set_timeout(port, 0); - - /* Init the SMB module */ - i2c_init_bus(ctrl); - } -} diff --git a/chip/npcx/i2c_chip.h b/chip/npcx/i2c_chip.h deleted file mode 100644 index 014e6cddf2..0000000000 --- a/chip/npcx/i2c_chip.h +++ /dev/null @@ -1,28 +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. - */ - -/* NPCX-specific I2C module for Chrome EC */ - -#ifndef __CROS_EC_I2C_CHIP_H -#define __CROS_EC_I2C_CHIP_H - -/** - * Select specific i2c port connected to i2c controller. - * - * @parm port I2C port - */ -void i2c_select_port(int port); - -/* - * Due to we couldn't support GPIO reading when IO is selected I2C, we need - * to distingulish which mode we used currently. - * - * @parm port I2C port - * - * @return 0: i2c ports are selected to pins. 1: GPIOs are selected to pins. - */ -int i2c_is_raw_mode(int port); - -#endif /* __CROS_EC_I2C_CHIP_H */ diff --git a/chip/npcx/keyboard_raw.c b/chip/npcx/keyboard_raw.c deleted file mode 100644 index e6b8cad7bd..0000000000 --- a/chip/npcx/keyboard_raw.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright 2014 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. - */ - -/* Functions needed by keyboard scanner module for Chrome EC */ - -#include "common.h" -#include "keyboard_raw.h" -#include "keyboard_scan.h" -#include "clock.h" -#include "gpio.h" -#include "registers.h" -#include "task.h" - -/** - * Initialize the raw keyboard interface. - */ -void keyboard_raw_init(void) -{ - /* Enable clock for KBS peripheral */ - clock_enable_peripheral(CGC_OFFSET_KBS, CGC_KBS_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - - /* Ensure top-level interrupt is disabled */ - keyboard_raw_enable_interrupt(0); - - /* - * Select quasi-bidirectional buffers for KSO pins. It reduces the - * low-to-high transition time. This feature only supports in npcx7. - */ -#ifdef CONFIG_KEYBOARD_KSO_HIGH_DRIVE - SET_FIELD(NPCX_KBSCTL, NPCX_KBHDRV_FIELD, 0x01); -#endif - - /* pull-up KBSIN 0-7 internally */ - NPCX_KBSINPU = 0xFF; - - /* Disable automatic scan mode */ - CLEAR_BIT(NPCX_KBSCTL, NPCX_KBSMODE); - - /* Disable automatic interrupt enable */ - CLEAR_BIT(NPCX_KBSCTL, NPCX_KBSIEN); - - /* Disable increment enable */ - CLEAR_BIT(NPCX_KBSCTL, NPCX_KBSINC); - - /* Set KBSOUT to zero to detect key-press */ - NPCX_KBSOUT0 = 0x00; - NPCX_KBSOUT1 = 0x00; - - gpio_config_module(MODULE_KEYBOARD_SCAN, 1); - - /* - * Enable interrupts for the inputs. The top-level interrupt is still - * masked off, so this won't trigger interrupts yet. - */ - - /* Clear pending input sources used by scanner */ - NPCX_WKPCL(MIWU_TABLE_WKKEY, MIWU_GROUP_WKKEY) = 0xFF; - - /* Enable Wake-up Button */ - NPCX_WKEN(MIWU_TABLE_WKKEY, MIWU_GROUP_WKKEY) = 0xFF; - - /* Select high to low transition (falling edge) */ - NPCX_WKEDG(MIWU_TABLE_WKKEY, MIWU_GROUP_WKKEY) = 0xFF; - - /* Enable interrupt of WK KBS */ - keyboard_raw_enable_interrupt(1); -} - -/** - * Finish initialization after task scheduling has started. - */ -void keyboard_raw_task_start(void) -{ - /* Enable MIWU to trigger KBS interrupt */ - task_enable_irq(NPCX_IRQ_KSI_WKINTC_1); -} - -/** - * Drive the specified column low. - */ -test_mockable void keyboard_raw_drive_column(int col) -{ - /* - * Nuvoton Keyboard Scan IP supports 18x8 Matrix - * It also support automatic scan functionality - */ - uint32_t mask, col_out; - - /* Add support for CONFIG_KEYBOARD_KSO_BASE shifting */ - col_out = col + CONFIG_KEYBOARD_KSO_BASE; - - /* Drive all lines to high */ - if (col == KEYBOARD_COLUMN_NONE) { - mask = ~0; -#if defined(CONFIG_KEYBOARD_CUSTOMIZATION) - board_keyboard_drive_col(col); -#elif defined(CONFIG_KEYBOARD_COL2_INVERTED) - gpio_set_level(GPIO_KBD_KSO2, 0); -#endif - } - /* Set KBSOUT to zero to detect key-press */ - else if (col == KEYBOARD_COLUMN_ALL) { - mask = ~(BIT(keyboard_cols) - 1); -#if defined(CONFIG_KEYBOARD_CUSTOMIZATION) - board_keyboard_drive_col(col); -#elif defined(CONFIG_KEYBOARD_COL2_INVERTED) - gpio_set_level(GPIO_KBD_KSO2, 1); -#endif - } - /* Drive one line for detection */ - else { -#if defined(CONFIG_KEYBOARD_CUSTOMIZATION) - board_keyboard_drive_col(col); -#elif defined(CONFIG_KEYBOARD_COL2_INVERTED) - if (col == 2) - gpio_set_level(GPIO_KBD_KSO2, 1); - else - gpio_set_level(GPIO_KBD_KSO2, 0); -#endif - mask = ~BIT(col_out); - } - - /* Set KBSOUT */ - NPCX_KBSOUT0 = (mask & 0xFFFF); - NPCX_KBSOUT1 = ((mask >> 16) & 0x03); -} - -/** - * Read raw row state. - * Bits are 1 if signal is present, 0 if not present. - */ -test_mockable int keyboard_raw_read_rows(void) -{ - /* Bits are active-low, so invert returned levels */ - return (~NPCX_KBSIN) & KB_ROW_MASK; -} - -/** - * Enable or disable keyboard interrupts. - */ -void keyboard_raw_enable_interrupt(int enable) -{ - if (enable) - task_enable_irq(NPCX_IRQ_KSI_WKINTC_1); - else - task_disable_irq(NPCX_IRQ_KSI_WKINTC_1); -} - -/* - * Interrupt handler for the entire GPIO bank of keyboard rows. - */ -void keyboard_raw_interrupt(void) -{ - /* Clear pending input sources used by scanner */ - NPCX_WKPCL(MIWU_TABLE_WKKEY, MIWU_GROUP_WKKEY) = 0xFF; - - /* Wake the scan task */ - task_wake(TASK_ID_KEYSCAN); -} -DECLARE_IRQ(NPCX_IRQ_KSI_WKINTC_1, keyboard_raw_interrupt, 5); - -int keyboard_raw_is_input_low(int port, int id) -{ - return (NPCX_PDIN(port) & BIT(id)) == 0; -} - diff --git a/chip/npcx/lct.c b/chip/npcx/lct.c deleted file mode 100644 index e23fa3bf6a..0000000000 --- a/chip/npcx/lct.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright 2020 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. - */ - -/* LCT (Long Countdown Timer) module for Chrome EC */ -#include "lct_chip.h" -#include "console.h" -#include "hooks.h" -#include "registers.h" -#include "rtc.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#define LCT_CLK_ENABLE_DELAY_USEC 150 - -#define CPRINTF(format, args...) cprintf(CC_CLOCK, format, ## args) -#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args) - -void npcx_lct_sel_power_src(enum NPCX_LCT_PWR_SRC pwr_src) -{ - if (IS_BIT_SET(NPCX_LCTCONT, NPCX_LCTCONT_EN)) { - CPRINTS("Don't set power source when LCT is enabled"); - return; - } - - if (pwr_src == NPCX_LCT_PWR_SRC_VSBY) - SET_BIT(NPCX_LCTCONT, NPCX_LCTCONT_VSBY_PWR); - else - CLEAR_BIT(NPCX_LCTCONT, NPCX_LCTCONT_VSBY_PWR); -} - -void npcx_lct_enable_clk(uint8_t enable) -{ - if (IS_BIT_SET(NPCX_LCTCONT, NPCX_LCTCONT_EN)) { - CPRINTS("Don't set/unset clock when LCT is enabled"); - return; - } - - if (enable) { - SET_BIT(NPCX_LCTCONT, NPCX_LCTCONT_CLK_EN); - /* - * This bit must be set to 1 at least tLCTCKEN (150 us) - * before the LCT is enabled. - */ - udelay(LCT_CLK_ENABLE_DELAY_USEC); - } else { - CLEAR_BIT(NPCX_LCTCONT, NPCX_LCTCONT_CLK_EN); - } -} - -void npcx_lct_enable(uint8_t enable) -{ - enable = !!enable; - SET_FIELD(NPCX_LCTCONT, NPCX_LCTCONT_EN_FIELD, enable); - /* Wait until the bit value equals to what is set */ - while (IS_BIT_SET(NPCX_LCTCONT, NPCX_LCTCONT_EN) != enable) - ; -} - -void npcx_lct_config(int seconds, int psl_ena, int int_ena) -{ - if (IS_BIT_SET(NPCX_LCTCONT, NPCX_LCTCONT_EN)) { - CPRINTS("Don't config LCT when LCT is enabled"); - return; - } - - /* LCT can count max to (16 weeks - 1 second) */ - if (seconds > NPCX_LCT_MAX) { - CPRINTS("LCT time is out of range"); - return; - } - - /* Clear pending LCT event first */ - NPCX_LCTSTAT = BIT(NPCX_LCTSTAT_EVST); - - NPCX_LCTWEEK = seconds / SECS_PER_WEEK; - seconds %= SECS_PER_WEEK; - NPCX_LCTDAY = seconds / SECS_PER_DAY; - seconds %= SECS_PER_DAY; - NPCX_LCTHOUR = seconds / SECS_PER_HOUR; - seconds %= SECS_PER_HOUR; - NPCX_LCTMINUTE = seconds / SECS_PER_MINUTE; - NPCX_LCTSECOND = seconds % SECS_PER_MINUTE; - - if (psl_ena) { - if (IS_BIT_SET(NPCX_LCTCONT, NPCX_LCTCONT_VSBY_PWR)) - SET_BIT(NPCX_LCTCONT, NPCX_LCTCONT_PSL_EN); - else - CPRINTS("LCT must source VSBY to support PSL wakeup"); - } - - if (int_ena) - SET_BIT(NPCX_LCTCONT, NPCX_LCTCONT_EVEN); - -} - -uint32_t npcx_lct_get_time(void) -{ - uint32_t second; - uint8_t week, day, hour, minute; - - do { - week = NPCX_LCTWEEK; - day = NPCX_LCTDAY; - hour = NPCX_LCTHOUR; - minute = NPCX_LCTMINUTE; - second = NPCX_LCTSECOND; - } while (week != NPCX_LCTWEEK || - day != NPCX_LCTDAY || - hour != NPCX_LCTHOUR || - minute != NPCX_LCTMINUTE || - second != NPCX_LCTSECOND); - - second += minute * SECS_PER_MINUTE + - hour * SECS_PER_HOUR + - day * SECS_PER_DAY + - week * SECS_PER_WEEK; - - return second; -} - -void npcx_lct_clear_event(void) -{ - NPCX_LCTSTAT = BIT(NPCX_LCTSTAT_EVST); -} - -int npcx_lct_is_event_set(void) -{ - return IS_BIT_SET(NPCX_LCTSTAT, NPCX_LCTSTAT_EVST); -} - -static void npcx_lct_init(void) -{ - /* Disable LCT */ - npcx_lct_enable(0); - /* Clear control and status registers */ - NPCX_LCTCONT = 0x0; - npcx_lct_clear_event(); - /* Clear all timer registers */ - NPCX_LCTSECOND = 0x0; - NPCX_LCTMINUTE = 0x0; - NPCX_LCTHOUR = 0x0; - NPCX_LCTDAY = 0x0; - NPCX_LCTWEEK = 0x0; -} -DECLARE_HOOK(HOOK_INIT, npcx_lct_init, HOOK_PRIO_DEFAULT); - -#ifdef CONFIG_CMD_RTC_ALARM -static int command_lctalarm(int argc, char **argv) -{ - char *e; - int seconds; - - seconds = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - - npcx_lct_enable(0); - npcx_lct_sel_power_src(NPCX_LCT_PWR_SRC_VSBY); - npcx_lct_enable_clk(1); - /* Enable LCT event interrupt and MIWU */ - npcx_lct_config(seconds, 0, 1); - task_disable_irq(NPCX_IRQ_LCT_WKINTF_2); - /* Enable wake-up input sources & clear pending bit */ - NPCX_WKPCL(MIWU_TABLE_2, LCT_WUI_GROUP) |= LCT_WUI_MASK; - NPCX_WKINEN(MIWU_TABLE_2, LCT_WUI_GROUP) |= LCT_WUI_MASK; - NPCX_WKEN(MIWU_TABLE_2, LCT_WUI_GROUP) |= LCT_WUI_MASK; - task_enable_irq(NPCX_IRQ_LCT_WKINTF_2); - npcx_lct_enable(1); - - return 0; -} -DECLARE_CONSOLE_COMMAND(lctalarm, command_lctalarm, "", ""); -#endif diff --git a/chip/npcx/lct_chip.h b/chip/npcx/lct_chip.h deleted file mode 100644 index 197c189f43..0000000000 --- a/chip/npcx/lct_chip.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2020 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_LCT_CHIP_H -#define __CROS_EC_LCT_CHIP_H -#include "registers.h" -#include "rtc.h" - -#define NPCX_LCT_MAX (16 * SECS_PER_WEEK - 1) - -enum NPCX_LCT_PWR_SRC { - NPCX_LCT_PWR_SRC_VCC1, - NPCX_LCT_PWR_SRC_VSBY -}; - -void npcx_lct_config(int seconds, int psl_ena, int int_ena); -void npcx_lct_enable(uint8_t enable); -void npcx_lct_enable_clk(uint8_t enable); -void npcx_lct_sel_power_src(enum NPCX_LCT_PWR_SRC pwr_src); -void npcx_lct_clear_event(void); -int npcx_lct_is_event_set(void); - -/* return the current time of LCT in second */ -uint32_t npcx_lct_get_time(void); - -#endif /* __CROS_EC_LCT_CHIP_H */ diff --git a/chip/npcx/lfw/ec_lfw.h b/chip/npcx/lfw/ec_lfw.h deleted file mode 100644 index 88c0a9ed83..0000000000 --- a/chip/npcx/lfw/ec_lfw.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2014 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. - * - * NPCX5M5G SoC little FW used by booter - */ - -#ifndef __CROS_EC_EC_LFW_H -#define __CROS_EC_EC_LFW_H - -/* Begin address for the .iram section; defined in linker script */ -extern unsigned int __iram_fw_start; -/* End address for the .iram section; defined in linker script */ -extern unsigned int __iram_fw_end; -/* Begin address for the iram codes; defined in linker script */ -extern unsigned int __flash_fw_start; - -#endif /* __CROS_EC_EC_LFW_H */ diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c deleted file mode 100644 index adf78b642d..0000000000 --- a/chip/npcx/lpc.c +++ /dev/null @@ -1,991 +0,0 @@ -/* Copyright 2014 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. - */ - -/* LPC module for Chrome EC */ - -#include "acpi.h" -#include "chipset.h" -#include "clock.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "i8042_protocol.h" -#include "keyboard_protocol.h" -#include "lpc.h" -#include "lpc_chip.h" -#include "port80.h" -#include "registers.h" -#include "system.h" -#include "sib_chip.h" -#include "task.h" -#include "uart.h" -#include "util.h" -#include "system_chip.h" - -/* Console output macros */ -#if !(DEBUG_LPC) -#define CPUTS(...) -#define CPRINTS(...) -#else -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) -#endif - -/* PM channel definitions */ -#define PMC_ACPI PM_CHAN_1 -#define PMC_HOST_CMD PM_CHAN_2 - -#define PORT80_MAX_BUF_SIZE 16 -static uint16_t port80_buf[PORT80_MAX_BUF_SIZE]; - -static struct host_packet lpc_packet; -static struct host_cmd_handler_args host_cmd_args; -static uint8_t host_cmd_flags; /* Flags from host command */ -static uint8_t shm_mem_host_cmd[256] __aligned(8); -static uint8_t shm_memmap[256] __aligned(8); -/* Params must be 32-bit aligned */ -static uint8_t params_copy[EC_LPC_HOST_PACKET_SIZE] __aligned(4); -static int init_done; - -static struct ec_lpc_host_args * const lpc_host_args = - (struct ec_lpc_host_args *)shm_mem_host_cmd; - -/*****************************************************************************/ -/* IC specific low-level driver */ -static void keyboard_irq_assert(void) -{ -#ifdef CONFIG_KEYBOARD_IRQ_GPIO - /* - * Enforce signal-high for long enough for the signal to be pulled high - * by the external pullup resistor. This ensures the host will see the - * following falling edge, regardless of the line state before this - * function call. - */ - gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1); - udelay(4); - /* Generate a falling edge */ - gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 0); - udelay(4); - /* Set signal high, now that we've generated the edge */ - gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1); -#else - /* - * SERIRQ is automatically sent by KBC - */ -#endif -} - -static void lpc_task_enable_irq(void) -{ -#ifdef HAS_TASK_KEYPROTO - task_enable_irq(NPCX_IRQ_KBC_IBF); -#endif - task_enable_irq(NPCX_IRQ_PM_CHAN_IBF); - task_enable_irq(NPCX_IRQ_PORT80); -#ifdef CONFIG_HOSTCMD_ESPI - task_enable_irq(NPCX_IRQ_ESPI); - /* Virtual Wire: SLP_S3/4/5, SUS_STAT, PLTRST, OOB_RST_WARN */ - task_enable_irq(NPCX_IRQ_WKINTA_2); - /* Virtual Wire: HOST_RST_WARN, SUS_WARN, SUS_PWRDN_ACK, SLP_A */ - task_enable_irq(NPCX_IRQ_WKINTB_2); - /* Enable eSPI module interrupts and wake-up functionalities */ - NPCX_ESPIIE |= (ESPIIE_GENERIC | ESPIIE_VW); - NPCX_ESPIWE |= (ESPIWE_GENERIC | ESPIWE_VW); -#endif -} - -static void lpc_task_disable_irq(void) -{ -#ifdef HAS_TASK_KEYPROTO - task_disable_irq(NPCX_IRQ_KBC_IBF); -#endif - task_disable_irq(NPCX_IRQ_PM_CHAN_IBF); - task_disable_irq(NPCX_IRQ_PORT80); -#ifdef CONFIG_HOSTCMD_ESPI - task_disable_irq(NPCX_IRQ_ESPI); - /* Virtual Wire: SLP_S3/4/5, SUS_STAT, PLTRST, OOB_RST_WARN */ - task_disable_irq(NPCX_IRQ_WKINTA_2); - /* Virtual Wire: HOST_RST_WARN,SUS_WARN, SUS_PWRDN_ACK, SLP_A */ - task_disable_irq(NPCX_IRQ_WKINTB_2); - /* Disable eSPI module interrupts and wake-up functionalities */ - NPCX_ESPIIE &= ~(ESPIIE_GENERIC | ESPIIE_VW); - NPCX_ESPIWE &= ~(ESPIWE_GENERIC | ESPIWE_VW); -#endif -} -/** - * Generate SMI pulse to the host chipset via GPIO. - * - * If the x86 is in S0, SMI# is sampled at 33MHz, so minimum pulse length is - * 60ns. If the x86 is in S3, SMI# is sampled at 32.768KHz, so we need pulse - * length >61us. Both are short enough and events are infrequent, so just - * delay for 65us. - */ -static void lpc_generate_smi(void) -{ - host_event_t smi; - -#ifdef CONFIG_SCI_GPIO - /* Enforce signal-high for long enough to debounce high */ - gpio_set_level(GPIO_PCH_SMI_L, 1); - udelay(65); - /* Generate a falling edge */ - gpio_set_level(GPIO_PCH_SMI_L, 0); - udelay(65); - /* Set signal high, now that we've generated the edge */ - gpio_set_level(GPIO_PCH_SMI_L, 1); -#elif defined(CONFIG_HOSTCMD_ESPI) - /* - * Don't use SET_BIT/CLEAR_BIT macro to toggle SMIB/SCIB to generate - * virtual wire. Use NPCX_VW_SMI/NPCX_VW_SCI macro instead. - * The reason is - if GPIOC6/CPIO76 are not selected as SMI/SCI, reading - * from SMIB/SCIB doesn't really reflect the SMI/SCI status. SMI/SCI - * status should be read from bit 1/0 in eSPI VMEVSM(2) register. - */ - NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SMI(1); - udelay(65); - /* Generate a falling edge */ - NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SMI(0); - udelay(65); - /* Set signal high */ - NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SMI(1); -#else - /* SET SMIB bit to pull SMI_L to high.*/ - SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIB); - udelay(65); - /* Generate a falling edge */ - CLEAR_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIB); - udelay(65); - /* Set signal high */ - SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIB); -#endif - smi = lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI); - if (smi) - HOST_EVENT_CPRINTS("smi", smi); -} - -/** - * Generate SCI pulse to the host chipset via LPC0SCI. - */ -static void lpc_generate_sci(void) -{ - host_event_t sci; - -#ifdef CONFIG_SCI_GPIO - /* Enforce signal-high for long enough to debounce high */ - gpio_set_level(CONFIG_SCI_GPIO, 1); - udelay(65); - /* Generate a falling edge */ - gpio_set_level(CONFIG_SCI_GPIO, 0); - udelay(65); - /* Set signal high, now that we've generated the edge */ - gpio_set_level(CONFIG_SCI_GPIO, 1); -#elif defined(CONFIG_HOSTCMD_ESPI) - /* - * Don't use SET_BIT/CLEAR_BIT macro to toggle SMIB/SCIB to generate - * virtual wire. Use NPCX_VW_SMI/NPCX_VW_SCI macro instead. - * The reason is - if GPIOC6/CPIO76 are not selected as SMI/SCI, reading - * from SMIB/SCIB doesn't really reflect the SMI/SCI status. SMI/SCI - * status should be read from bit 1/0 in eSPI VMEVSM(2) register. - */ - NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SCI(1); - udelay(65); - /* Generate a falling edge */ - NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SCI(0); - udelay(65); - /* Set signal high */ - NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SCI(1); -#else - /* Set SCIB bit to pull SCI_L to high.*/ - SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SCIB); - udelay(65); - /* Generate a falling edge */ - CLEAR_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SCIB); - udelay(65); - /* Set signal high */ - SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SCIB); -#endif - - sci = lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI); - if (sci) - HOST_EVENT_CPRINTS("sci", sci); -} - -/** - * Update the level-sensitive wake signal to the AP. - * - * @param wake_events Currently asserted wake events - */ -static void lpc_update_wake(host_event_t wake_events) -{ - /* - * Mask off power button event, since the AP gets that through a - * separate dedicated GPIO. - */ - wake_events &= ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON); - - /* Signal is asserted low when wake events is non-zero */ - gpio_set_level(GPIO_PCH_WAKE_L, !wake_events); -} - -uint8_t *lpc_get_memmap_range(void) -{ - return (uint8_t *)shm_memmap; -} - -static void lpc_send_response(struct host_cmd_handler_args *args) -{ - uint8_t *out; - int size = args->response_size; - int csum; - int i; - - /* Ignore in-progress on LPC since interface is synchronous anyway */ - if (args->result == EC_RES_IN_PROGRESS) - return; - - /* Handle negative size */ - if (size < 0) { - args->result = EC_RES_INVALID_RESPONSE; - size = 0; - } - - /* New-style response */ - lpc_host_args->flags = - (host_cmd_flags & ~EC_HOST_ARGS_FLAG_FROM_HOST) | - EC_HOST_ARGS_FLAG_TO_HOST; - - lpc_host_args->data_size = size; - - csum = args->command + lpc_host_args->flags + - lpc_host_args->command_version + - lpc_host_args->data_size; - - for (i = 0, out = (uint8_t *)args->response; i < size; i++, out++) - csum += *out; - - lpc_host_args->checksum = (uint8_t)csum; - - /* Fail if response doesn't fit in the param buffer */ - if (size > EC_PROTO2_MAX_PARAM_SIZE) - args->result = EC_RES_INVALID_RESPONSE; - - /* Write result to the data byte. This sets the TOH status bit. */ - NPCX_HIPMDO(PMC_HOST_CMD) = args->result; - /* Clear processing flag */ - CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), NPCX_HIPMST_F0); -} - -static void lpc_send_response_packet(struct host_packet *pkt) -{ - /* Ignore in-progress on LPC since interface is synchronous anyway */ - if (pkt->driver_result == EC_RES_IN_PROGRESS) - return; - - /* Write result to the data byte. This sets the TOH status bit. */ - NPCX_HIPMDO(PMC_HOST_CMD) = pkt->driver_result; - /* Clear processing flag */ - CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), NPCX_HIPMST_F0); -} - -int lpc_keyboard_has_char(void) -{ - /* if OBF bit is '1', that mean still have a data in DBBOUT */ - return (NPCX_HIKMST&0x01) ? 1 : 0; -} - -int lpc_keyboard_input_pending(void) -{ - /* if IBF bit is '1', that mean still have a data in DBBIN */ - return (NPCX_HIKMST&0x02) ? 1 : 0; -} - -/* Put a char to host buffer by HIKDO and send IRQ if specified. */ -void lpc_keyboard_put_char(uint8_t chr, int send_irq) -{ - NPCX_HIKDO = chr; - CPRINTS("KB put %02x", chr); - - /* Enable OBE interrupt to detect host read data out */ - SET_BIT(NPCX_HICTRL, NPCX_HICTRL_OBECIE); - task_enable_irq(NPCX_IRQ_KBC_OBE); - if (send_irq) { - keyboard_irq_assert(); - } -} - -/* Put an aux char to host buffer by HIMDO and assert status bit 5. */ -void lpc_aux_put_char(uint8_t chr, int send_irq) -{ - if (send_irq) - SET_BIT(NPCX_HICTRL, NPCX_HICTRL_OBFMIE); - else - CLEAR_BIT(NPCX_HICTRL, NPCX_HICTRL_OBFMIE); - - NPCX_HIKMST |= I8042_AUX_DATA; - NPCX_HIMDO = chr; - CPRINTS("AUX put %02x", chr); - - /* Enable OBE interrupt to detect host read data out */ - SET_BIT(NPCX_HICTRL, NPCX_HICTRL_OBECIE); - task_enable_irq(NPCX_IRQ_KBC_OBE); -} - -void lpc_keyboard_clear_buffer(void) -{ - /* - * Only npcx5 series need this bypass. The bug of FW_OBF is fixed in - * npcx7 series and later npcx ec. - */ -#ifdef CHIP_FAMILY_NPCX5 - /* Clear OBF flag in host STATUS and HIKMST regs */ - if (IS_BIT_SET(NPCX_HIKMST, NPCX_HIKMST_OBF)) { - /* - * Setting HICTRL.FW_OBF clears the HIKMST.OBF and STATUS.OBF - * but it does not deassert IRQ1 when it was already asserted. - * Emulate a host read to clear these two flags and also - * deassert IRQ1 - */ - sib_read_kbc_reg(0x0); - } -#else - /* Make sure the previous TOH and IRQ has been sent out. */ - udelay(4); - /* Clear OBE flag in host STATUS and HIKMST regs*/ - SET_BIT(NPCX_HICTRL, NPCX_HICTRL_FW_OBF); - /* Ensure there is no TOH set in this period. */ - udelay(4); -#endif -} - -void lpc_keyboard_resume_irq(void) -{ - if (lpc_keyboard_has_char()) - keyboard_irq_assert(); -} - -/** - * Update the host event status. - * - * Sends a pulse if masked event status becomes non-zero: - * - SMI pulse via EC_SMI_L GPIO - * - SCI pulse via LPC0SCI - */ -void lpc_update_host_event_status(void) -{ - int need_sci = 0; - int need_smi = 0; - - if (!init_done) - return; - - /* Disable LPC interrupt while updating status register */ - lpc_task_disable_irq(); - if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI)) { - /* Only generate SMI for first event */ - if (!(NPCX_HIPMST(PMC_ACPI) & NPCX_HIPMST_ST2)) - need_smi = 1; - SET_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST2); - } else - CLEAR_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST2); - - if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI)) { - /* Generate SCI for every event */ - need_sci = 1; - SET_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST1); - } else - CLEAR_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST1); - - /* Copy host events to mapped memory */ - *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = - lpc_get_host_events(); - - lpc_task_enable_irq(); - - /* Process the wake events. */ - lpc_update_wake(lpc_get_host_events_by_type(LPC_HOST_EVENT_WAKE)); - - /* Send pulse on SMI signal if needed */ - if (need_smi) - lpc_generate_smi(); - - /* ACPI 5.0-12.6.1: Generate SCI for SCI_EVT=1. */ - if (need_sci) - lpc_generate_sci(); -} - -void lpc_set_acpi_status_mask(uint8_t mask) -{ - NPCX_HIPMST(PMC_ACPI) |= mask; -} - -void lpc_clear_acpi_status_mask(uint8_t mask) -{ - NPCX_HIPMST(PMC_ACPI) &= ~mask; -} - -/* Enable LPC ACPI-EC interrupts */ -void lpc_enable_acpi_interrupts(void) -{ - SET_BIT(NPCX_HIPMCTL(PMC_ACPI), NPCX_HIPMCTL_IBFIE); -} - -/* Disable LPC ACPI-EC interrupts */ -void lpc_disable_acpi_interrupts(void) -{ - CLEAR_BIT(NPCX_HIPMCTL(PMC_ACPI), NPCX_HIPMCTL_IBFIE); -} - -/** - * Handle write to ACPI I/O port - * - * @param is_cmd Is write command (is_cmd=1) or data (is_cmd=0) - */ -static void handle_acpi_write(int is_cmd) -{ - uint8_t value, result; - - /* Set processing flag before reading command byte */ - SET_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_F0); - - /* Read command/data; this clears the FRMH status bit. */ - value = NPCX_HIPMDI(PMC_ACPI); - - /* Handle whatever this was. */ - if (acpi_ap_to_ec(is_cmd, value, &result)) - NPCX_HIPMDO(PMC_ACPI) = result; - - /* Clear processing flag */ - CLEAR_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_F0); - - /* - * ACPI 5.0-12.6.1: Generate SCI for Input Buffer Empty / Output Buffer - * Full condition on the kernel channel. - */ - lpc_generate_sci(); -} - -/** - * Handle write to host command I/O ports. - * - * @param is_cmd Is write command (1) or data (0)? - */ -static void handle_host_write(int is_cmd) -{ - /* Set processing flag before reading command byte */ - SET_BIT(NPCX_HIPMST(PMC_HOST_CMD), NPCX_HIPMST_F0); - /* - * Read the command byte. This clears the FRMH bit in - * the status byte. - */ - host_cmd_args.command = NPCX_HIPMDI(PMC_HOST_CMD); - - host_cmd_args.result = EC_RES_SUCCESS; - host_cmd_args.send_response = lpc_send_response; - host_cmd_flags = lpc_host_args->flags; - - /* See if we have an old or new style command */ - if (host_cmd_args.command == EC_COMMAND_PROTOCOL_3) { - lpc_packet.send_response = lpc_send_response_packet; - - lpc_packet.request = (const void *)shm_mem_host_cmd; - lpc_packet.request_temp = params_copy; - lpc_packet.request_max = sizeof(params_copy); - /* Don't know the request size so pass in the entire buffer */ - lpc_packet.request_size = EC_LPC_HOST_PACKET_SIZE; - - lpc_packet.response = (void *)shm_mem_host_cmd; - lpc_packet.response_max = EC_LPC_HOST_PACKET_SIZE; - lpc_packet.response_size = 0; - - lpc_packet.driver_result = EC_RES_SUCCESS; - - host_packet_receive(&lpc_packet); - return; - - } else { - /* Old style command, now unsupported */ - host_cmd_args.result = EC_RES_INVALID_COMMAND; - } - - /* Hand off to host command handler */ - host_command_received(&host_cmd_args); -} - -/*****************************************************************************/ -/* Interrupt handlers */ -#ifdef HAS_TASK_KEYPROTO -/* KB controller input buffer full ISR */ -void lpc_kbc_ibf_interrupt(void) -{ - uint8_t status; - uint8_t ibf; - /* If "command" input 0, else 1*/ - if (lpc_keyboard_input_pending()) { - /* - * Reading HIKMDI causes the IBF flag to deassert and allows - * the host to write a new byte into the input buffer. So if we - * don't capture the status before reading HIKMDI we will race - * with the host and get an invalid value for HIKMST.A20. - */ - status = NPCX_HIKMST; - ibf = NPCX_HIKMDI; - keyboard_host_write(ibf, (status & 0x08) ? 1 : 0); - CPRINTS("ibf isr %02x", ibf); - task_wake(TASK_ID_KEYPROTO); - } else { - CPRINTS("ibf isr spurious"); - } -} -DECLARE_IRQ(NPCX_IRQ_KBC_IBF, lpc_kbc_ibf_interrupt, 4); - -/* KB controller output buffer empty ISR */ -void lpc_kbc_obe_interrupt(void) -{ - /* Disable KBC OBE interrupt */ - CLEAR_BIT(NPCX_HICTRL, NPCX_HICTRL_OBECIE); - task_disable_irq(NPCX_IRQ_KBC_OBE); - - CPRINTS("obe isr %02x", NPCX_HIKMST); - - NPCX_HIKMST &= ~I8042_AUX_DATA; - - task_wake(TASK_ID_KEYPROTO); -} -DECLARE_IRQ(NPCX_IRQ_KBC_OBE, lpc_kbc_obe_interrupt, 4); -#endif - -/* PM channel input buffer full ISR */ -void lpc_pmc_ibf_interrupt(void) -{ - /* Channel-1 for ACPI usage*/ - /* Channel-2 for Host Command usage , so the argument data had been - * put on the share memory firstly*/ - if (NPCX_HIPMST(PMC_ACPI) & 0x02) - handle_acpi_write((NPCX_HIPMST(PMC_ACPI)&0x08) ? 1 : 0); - else if (NPCX_HIPMST(PMC_HOST_CMD) & 0x02) - handle_host_write((NPCX_HIPMST(PMC_HOST_CMD)&0x08) ? 1 : 0); -} -DECLARE_IRQ(NPCX_IRQ_PM_CHAN_IBF, lpc_pmc_ibf_interrupt, 4); - -/* PM channel output buffer empty ISR */ -void lpc_pmc_obe_interrupt(void) -{ -} -DECLARE_IRQ(NPCX_IRQ_PM_CHAN_OBE, lpc_pmc_obe_interrupt, 4); - -void lpc_port80_interrupt(void) -{ - uint8_t i; - uint8_t count = 0; - uint32_t code = 0; - - /* buffer Port80 data to the local buffer if FIFO is not empty */ - while (IS_BIT_SET(NPCX_DP80STS, NPCX_DP80STS_FNE)) - port80_buf[count++] = NPCX_DP80BUF; - - for (i = 0; i < count; i++) { - uint8_t offset; - uint32_t buf_data; - - buf_data = port80_buf[i]; - offset = GET_FIELD(buf_data, NPCX_DP80BUF_OFFS_FIELD); - code |= (buf_data & 0xFF) << (8 * offset); - - if (i == count - 1) { - port_80_write(code); - break; - } - - /* peek the offset of the next byte */ - buf_data = port80_buf[i + 1]; - offset = GET_FIELD(buf_data, NPCX_DP80BUF_OFFS_FIELD); - /* - * If the peeked next byte's offset is 0 means it is the start - * of the new code. Pass the current code to Port80 - * common layer. - */ - if (offset == 0) { - port_80_write(code); - code = 0; - } - } - - /* If FIFO is overflow */ - if (IS_BIT_SET(NPCX_DP80STS, NPCX_DP80STS_FOR)) { - SET_BIT(NPCX_DP80STS, NPCX_DP80STS_FOR); - CPRINTS("DP80 FIFO Overflow!"); - } - - /* Clear pending bit of host writing */ - SET_BIT(NPCX_DP80STS, NPCX_DP80STS_FWR); -} -DECLARE_IRQ(NPCX_IRQ_PORT80, lpc_port80_interrupt, 4); - -/** - * Preserve event masks across a sysjump. - */ -static void lpc_sysjump(void) -{ - lpc_task_disable_irq(); - - /* Disable protect for Win 1 and 2. */ - NPCX_WIN_WR_PROT(0) = 0; - NPCX_WIN_WR_PROT(1) = 0; - NPCX_WIN_RD_PROT(0) = 0; - NPCX_WIN_RD_PROT(1) = 0; - - /* Reset base address for Win 1 and 2. */ - NPCX_WIN_BASE(0) = 0xfffffff8; - NPCX_WIN_BASE(1) = 0xfffffff8; -} -DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump, HOOK_PRIO_DEFAULT); - -/* For LPC host register initial via SIB module */ -void host_register_init(void) -{ - /* Enable Core-to-Host Modules Access */ - SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSAE); - - /* enable ACPI*/ - sib_write_reg(SIO_OFFSET, 0x07, 0x11); - sib_write_reg(SIO_OFFSET, 0x30, 0x01); - - /* Enable kbc and mouse */ -#ifdef HAS_TASK_KEYPROTO - /* LDN = 0x06 : keyboard */ - sib_write_reg(SIO_OFFSET, 0x07, 0x06); - sib_write_reg(SIO_OFFSET, 0x30, 0x01); - - /* LDN = 0x05 : mouse */ - if (IS_ENABLED(CONFIG_PS2)) { - sib_write_reg(SIO_OFFSET, 0x07, 0x05); - sib_write_reg(SIO_OFFSET, 0x30, 0x01); - } -#endif - - /* Setting PMC2 */ - /* LDN register = 0x12(PMC2) */ - sib_write_reg(SIO_OFFSET, 0x07, 0x12); - /* CMD port is 0x200 */ - sib_write_reg(SIO_OFFSET, 0x60, 0x02); - sib_write_reg(SIO_OFFSET, 0x61, 0x00); - /* Data port is 0x204 */ - sib_write_reg(SIO_OFFSET, 0x62, 0x02); - sib_write_reg(SIO_OFFSET, 0x63, 0x04); - /* enable PMC2 */ - sib_write_reg(SIO_OFFSET, 0x30, 0x01); - - /* Setting SHM */ - /* LDN register = 0x0F(SHM) */ - sib_write_reg(SIO_OFFSET, 0x07, 0x0F); - /* WIN1&2 mapping to IO */ - sib_write_reg(SIO_OFFSET, 0xF1, - sib_read_reg(SIO_OFFSET, 0xF1) | 0x30); - /* WIN1 as Host Command on the IO:0x0800 */ - sib_write_reg(SIO_OFFSET, 0xF5, 0x08); - sib_write_reg(SIO_OFFSET, 0xF4, 0x00); - /* WIN2 as MEMMAP on the IO:0x900 */ - sib_write_reg(SIO_OFFSET, 0xF9, 0x09); - sib_write_reg(SIO_OFFSET, 0xF8, 0x00); - - /* - * eSPI allows sending 4 bytes of Port80 code in a single PUT_IOWR_SHORT - * transaction. When setting OFS0_SEL~OFS3_SEL in DPAR1 register to 1, - * EC hardware will put those 4 bytes of Port80 code to DP80BUF FIFO. - * This is only supported when CHIP_FAMILY >= NPCX9. - */ - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) - sib_write_reg(SIO_OFFSET, 0xFD, 0x0F); - /* enable SHM */ - sib_write_reg(SIO_OFFSET, 0x30, 0x01); - - CPRINTS("Host settings are done!"); - -} - -#ifdef CONFIG_CHIPSET_RESET_HOOK -static void lpc_chipset_reset(void) -{ - hook_notify(HOOK_CHIPSET_RESET); -} -DECLARE_DEFERRED(lpc_chipset_reset); -#endif - -int lpc_get_pltrst_asserted(void) -{ - /* Read current PLTRST status */ - return IS_BIT_SET(NPCX_MSWCTL1, NPCX_MSWCTL1_PLTRST_ACT); -} - -#ifndef CONFIG_HOSTCMD_ESPI -/* Initialize host settings by interrupt */ -void lpc_lreset_pltrst_handler(void) -{ - int pltrst_asserted; - - /* Clear pending bit of WUI */ - SET_BIT(NPCX_WKPCL(MIWU_TABLE_0 , MIWU_GROUP_5), 7); - - /* Ignore PLTRST# from SOC if it is not valid */ - if (chipset_pltrst_is_valid && !chipset_pltrst_is_valid()) - return; - - pltrst_asserted = lpc_get_pltrst_asserted(); - - CPRINTS("LPC RESET# %sasserted", pltrst_asserted ? "" : "de"); - - /* - * Once LRESET is de-asserted (low -> high), we need to initialize lpc - * settings once. If RSTCTL_LRESET_PLTRST_MODE is active, LPC registers - * won't be reset by Host domain reset but Core domain does. - */ - if (!pltrst_asserted) - host_register_init(); - else { - /* Clear processing flag when LRESET is asserted */ - CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), NPCX_HIPMST_F0); -#ifdef CONFIG_CHIPSET_RESET_HOOK - /* Notify HOOK_CHIPSET_RESET */ - hook_call_deferred(&lpc_chipset_reset_data, MSEC); -#endif - } -} -#endif - -/*****************************************************************************/ -/* LPC/eSPI Initialization functions */ - -static void lpc_init(void) -{ - /* Enable clock for LPC peripheral */ - clock_enable_peripheral(CGC_OFFSET_LPC, CGC_LPC_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - /* - * In npcx5/7, the host interface type (HIF_TYP_SEL in the DEVCNT - * register) is updated by booter after VCC1 Power-Up reset according to - * VHIF voltage. - * In npcx9, the booter will not do this anymore. The HIF_TYP_SEL - * field should be set by firmware. - */ -#ifdef CONFIG_HOSTCMD_ESPI - /* Initialize eSPI module */ - NPCX_DEVCNT |= 0x08; - espi_init(); -#else - /* Switching to LPC interface */ - NPCX_DEVCNT |= 0x04; -#endif - /* Enable 4E/4F */ - if (!IS_BIT_SET(NPCX_MSWCTL1, NPCX_MSWCTL1_VHCFGA)) { - NPCX_HCBAL = 0x4E; - NPCX_HCBAH = 0x0; - } - /* Clear Host Access Hold state */ - NPCX_SMC_CTL = 0xC0; - -#ifndef CONFIG_HOSTCMD_ESPI - /* - * Set alternative pin from GPIO to CLKRUN no matter SERIRQ is under - * continuous or quiet mode. - */ - SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_CLKRN_SL); -#endif - - /* - * Set pin-mux from GPIOs to SCL/SMI to make sure toggling SCIB/SMIB is - * valid if CONFIG_SCI_GPIO isn't defined. eSPI sends SMI/SCI through VW - * automatically by toggling them, too. It's unnecessary to set pin mux. - */ -#if !defined(CONFIG_SCI_GPIO) && !defined(CONFIG_HOSTCMD_ESPI) - SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_EC_SCI_SL); - SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_SMI_SL); -#endif - - /* Initialize Hardware for UART Host */ -#ifdef CONFIG_UART_HOST - /* Init COMx LPC UART */ - /* FMCLK have to using 50MHz */ - NPCX_DEVALT(0xB) = 0xFF; - /* Make sure Host Access unlock */ - CLEAR_BIT(NPCX_LKSIOHA, 2); - /* Clear Host Access Lock Violation */ - SET_BIT(NPCX_SIOLV, 2); -#endif - - /* Don't stall SHM transactions */ - NPCX_SHM_CTL = NPCX_SHM_CTL & ~0x40; - /* Disable Protect Win1&2*/ - NPCX_WIN_WR_PROT(0) = 0; - NPCX_WIN_WR_PROT(1) = 0; - NPCX_WIN_RD_PROT(0) = 0; - NPCX_WIN_RD_PROT(1) = 0; - /* Open Win1 256 byte for Host CMD, Win2 256 for MEMMAP*/ - NPCX_WIN_SIZE = 0x88; - NPCX_WIN_BASE(0) = (uint32_t)shm_mem_host_cmd; - NPCX_WIN_BASE(1) = (uint32_t)shm_memmap; - /* Write protect of Share memory */ - NPCX_WIN_WR_PROT(1) = 0xFF; - - /* We support LPC args and version 3 protocol */ - *(lpc_get_memmap_range() + EC_MEMMAP_HOST_CMD_FLAGS) = - EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED | - EC_HOST_CMD_FLAG_VERSION_3; - - /* - * Clear processing flag before enabling lpc's interrupts in case - * it's set by the other command during sysjump. - */ - CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), NPCX_HIPMST_F0); - - /* Turn on PMC2 for Host Command usage */ - SET_BIT(NPCX_HIPMCTL(PMC_HOST_CMD), 0); - - /* - * Set required control value (avoid setting HOSTWAIT bit at this stage) - */ - NPCX_SMC_CTL = NPCX_SMC_CTL&~0x7F; - /* Clear status */ - NPCX_SMC_STS = NPCX_SMC_STS; - - /* Create mailbox */ - - /* - * Init KBC - * Clear OBF status flag, - * IBF(K&M) INT enable, - * OBF Mouse Full INT enable and OBF KB Full INT enable - */ -#ifdef HAS_TASK_KEYPROTO - lpc_keyboard_clear_buffer(); - NPCX_HICTRL = 0x0B; -#endif - - /* - * Turn on enhance mode on PM channel-1, - * enable IBF core interrupt - */ - NPCX_HIPMCTL(PMC_ACPI) |= 0x81; - /* Normally Polarity IRQ1,12 type (level + high) setting */ - NPCX_HIIRQC = 0x00; - - /* - * Init PORT80 - * Enable Port80, Enable Port80 function & Interrupt & Read auto - */ -#ifdef CONFIG_HOSTCMD_ESPI - NPCX_DP80CTL = 0x2b; -#else - NPCX_DP80CTL = 0x29; -#endif - SET_BIT(NPCX_GLUE_SDP_CTS, 3); -#if SUPPORT_P80_SEG - SET_BIT(NPCX_GLUE_SDP_CTS, 0); -#endif - - /* - * Use SMI/SCI postive polarity as default. - * Negative polarity must be enabled in the case that SMI/SCI is - * generated automatically by hardware. In current design, - * SMI/SCI is conntrolled by FW. Use postive polarity is more - * intuitive. - */ - CLEAR_BIT(NPCX_HIPMCTL(PMC_ACPI), NPCX_HIPMCTL_SCIPOL); - CLEAR_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIPOL); - /* Set SMIB/SCIB to make sure SMI/SCI are high at init */ - NPCX_HIPMIC(PMC_ACPI) = NPCX_HIPMIC(PMC_ACPI) - | BIT(NPCX_HIPMIC_SMIB) | BIT(NPCX_HIPMIC_SCIB); -#ifndef CONFIG_SCI_GPIO - /* - * Allow SMI/SCI generated from PM module. - * Either hardware autimatically generates, - * or set SCIB/SMIB bit in HIPMIC register. - */ - SET_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SCIE); - SET_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SMIE); -#endif - lpc_task_enable_irq(); - - /* Sufficiently initialized */ - init_done = 1; - - /* Update host events now that we can copy them to memmap */ - lpc_update_host_event_status(); - - /* - * TODO: For testing LPC with Chromebox, please make sure LPC_CLK is - * generated before executing this function. EC needs LPC_CLK to access - * LPC register through SIB module. For Chromebook platform, this - * functionality should be done by BIOS or executed in hook function of - * HOOK_CHIPSET_STARTUP - */ -#ifdef BOARD_NPCX_EVB - /* initial IO port address via SIB-write modules */ - host_register_init(); -#else -#ifndef CONFIG_HOSTCMD_ESPI - /* - * Initialize LRESET# interrupt only in case of LPC. For eSPI, there is - * no dedicated GPIO pin for LRESET/PLTRST. PLTRST is indicated as a VW - * signal instead. WUI57 of table 0 is set when EC receives - * LRESET/PLTRST from either VW or GPIO. Since WUI57 of table 0 and - * WUI15 of table 2 are issued at the same time in case of eSPI, there - * is no need to indicate LRESET/PLTRST via two sources. Thus, do not - * initialize LRESET# interrupt in case of eSPI. - */ - /* Set detection mode to edge */ - CLEAR_BIT(NPCX_WKMOD(MIWU_TABLE_0, MIWU_GROUP_5), 7); - /* Handle interrupting on any edge */ - SET_BIT(NPCX_WKAEDG(MIWU_TABLE_0, MIWU_GROUP_5), 7); - /* Enable wake-up input sources */ - SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 7); -#endif -#endif -} -/* - * Set prio to higher than default; this way LPC memory mapped data is ready - * before other inits try to initialize their memmap data. - */ -DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_INIT_LPC); - -/* Get protocol information */ -static enum ec_status lpc_get_protocol_info(struct host_cmd_handler_args *args) -{ - struct ec_response_get_protocol_info *r = args->response; - - memset(r, 0, sizeof(*r)); - r->protocol_versions = BIT(3); - r->max_request_packet_size = EC_LPC_HOST_PACKET_SIZE; - r->max_response_packet_size = EC_LPC_HOST_PACKET_SIZE; - r->flags = 0; - - args->response_size = sizeof(*r); - - return EC_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_GET_PROTOCOL_INFO, - lpc_get_protocol_info, - EC_VER_MASK(0)); - -#if DEBUG_LPC -static int command_lpc(int argc, char **argv) -{ - if (argc == 1) - return EC_ERROR_PARAM1; - - if (!strcasecmp(argv[1], "sci")) - lpc_generate_sci(); - else if (!strcasecmp(argv[1], "smi")) - lpc_generate_smi(); - else if (!strcasecmp(argv[1], "wake")) - lpc_update_wake(-1); - else - return EC_ERROR_PARAM1; - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(lpc, command_lpc, "[sci|smi|wake]", "Trigger SCI/SMI"); - -#endif diff --git a/chip/npcx/lpc_chip.h b/chip/npcx/lpc_chip.h deleted file mode 100644 index 607fdde5fa..0000000000 --- a/chip/npcx/lpc_chip.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright 2015 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-specific hwtimer module for Chrome EC */ - -#ifndef __CROS_EC_LPC_CHIP_H -#define __CROS_EC_LPC_CHIP_H - -/* For host registers initialization via SIB module */ -void host_register_init(void); - -/* eSPI Initialization functions */ -void espi_init(void); -/* eSPI reset assert/de-assert interrupt */ -void espi_espirst_handler(void); -/* LPC PLTRST assert/de-assert interrupt */ -void lpc_lreset_pltrst_handler(void); -#endif /* __CROS_EC_LPC_CHIP_H */ diff --git a/chip/npcx/peci.c b/chip/npcx/peci.c deleted file mode 100644 index badfbd87d9..0000000000 --- a/chip/npcx/peci.c +++ /dev/null @@ -1,298 +0,0 @@ -/* Copyright 2014 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. - */ - -/* PECI interface for Chrome EC */ - -#include "chipset.h" -#include "clock.h" -#include "clock_chip.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "peci.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "temp_sensor.h" -#include "util.h" - - -/* Initial PECI baud rate */ -#define PECI_BAUD_RATE 750000 - -#define TEMP_AVG_LENGTH 4 /* Should be power of 2 */ - - -/* PECI Time-out */ -#define PECI_DONE_TIMEOUT_US (10*MSEC) - -#define NULL_PENDING_TASK_ID 0xFFFFFFFF -#define PECI_MAX_FIFO_SIZE 16 -#define PROC_SOCKET 0x30 -/* PECI Command Code */ -enum peci_command_t { - PECI_COMMAND_PING = 0x00, - PECI_COMMAND_GET_DIB = 0xF7, - PECI_COMMAND_GET_TEMP = 0x01, - PECI_COMMAND_RD_PKG_CFG = 0xA1, - PECI_COMMAND_WR_PKG_CFG = 0xA5, - PECI_COMMAND_RD_IAMSR = 0xB1, - PECI_COMMAND_RD_PCI_CFG = 0x61, - PECI_COMMAND_RD_PCI_CFG_LOCAL = 0xE1, - PECI_COMMAND_WR_PCI_CFG_LOCAL = 0xE5, - PECI_COMMAND_NONE = 0xFF -}; - -#define PECI_COMMAND_GET_TEMP_WR_LENS 0x00 -#define PECI_COMMAND_GET_TEMP_RD_LENS 0x02 - -/* PECI Domain Number */ -static int temp_vals[TEMP_AVG_LENGTH]; -static int temp_idx; -static uint8_t peci_sts; -/* For PECI Done interrupt usage */ -static int peci_pending_task_id; - -/*****************************************************************************/ -/* Internal functions */ - -/** - * This routine initiates the parameters of a PECI transaction - * - * @param wr_length How many byte of *wr_data went to be send - * @param rd_length How many byte went to received (not include FCS) - * @param cmd_code Command code - * @param *wr_data Buffer pointer of write data - * @return TASK_EVENT_PECI_DONE that mean slave had a response - */ -static uint32_t peci_trans( - uint8_t wr_length, - uint8_t rd_length, - enum peci_command_t cmd_code, - uint8_t *wr_data -) -{ - uint32_t events; - /* Ensure no PECI transaction is in progress */ - if (IS_BIT_SET(NPCX_PECI_CTL_STS, NPCX_PECI_CTL_STS_START_BUSY)) { - /* - * PECI transaction is in progress - - * can not initiate a new one - */ - return 0; - } - /* Set basic transaction parameters */ - NPCX_PECI_ADDR = PROC_SOCKET; - NPCX_PECI_CMD = cmd_code; - /* Aviod over space */ - if (rd_length > PECI_MAX_FIFO_SIZE) - rd_length = PECI_MAX_FIFO_SIZE; - /* Read-Length */ - NPCX_PECI_RD_LENGTH = rd_length; - if (wr_length > PECI_MAX_FIFO_SIZE) - wr_length = PECI_MAX_FIFO_SIZE; - /* copy of data */ - for (events = 0; events < wr_length; events++) - NPCX_PECI_DATA_OUT(events) = wr_data[events]; - /* Write-Length */ - if (cmd_code != PECI_COMMAND_PING) { - if ((cmd_code == PECI_COMMAND_WR_PKG_CFG) || - (cmd_code == PECI_COMMAND_WR_PCI_CFG_LOCAL)) { - /*CMD+AWFCS*/ - NPCX_PECI_WR_LENGTH = wr_length + 2; - /* Enable AWFCS */ - SET_BIT(NPCX_PECI_CTL_STS, NPCX_PECI_CTL_STS_AWFCS_EN); - } else { - /*CMD*/ - NPCX_PECI_WR_LENGTH = wr_length + 1; - /* Enable AWFCS */ - CLEAR_BIT(NPCX_PECI_CTL_STS, - NPCX_PECI_CTL_STS_AWFCS_EN); - } - } - - /* Start the PECI transaction */ - SET_BIT(NPCX_PECI_CTL_STS, NPCX_PECI_CTL_STS_START_BUSY); - - /* It should be using a interrupt , don't waste cpu computing power */ - peci_pending_task_id = task_get_current(); - return task_wait_event_mask(TASK_EVENT_PECI_DONE, - PECI_DONE_TIMEOUT_US); - -} - -/** - * PECI transaction error status. - * - * @return Bit3 - CRC error Bit4 - ABRT error - */ -static uint8_t peci_check_error_state(void) -{ - return peci_sts; -} - -/*****************************************************************************/ -/* PECI drivers */ -int peci_get_cpu_temp(void) -{ - uint32_t events; - int16_t cpu_temp = -1; - - /* Start PECI trans */ - events = peci_trans(PECI_COMMAND_GET_TEMP_WR_LENS, - PECI_COMMAND_GET_TEMP_RD_LENS, - PECI_COMMAND_GET_TEMP, NULL); - /* if return DONE , that mean slave had a PECI response */ - if ((events & TASK_EVENT_PECI_DONE) == TASK_EVENT_PECI_DONE) { - /* check CRC & ABRT */ - events = peci_check_error_state(); - if (events) { - ; - } else { - uint16_t *ptr; - ptr = (uint16_t *)&cpu_temp; - ptr[0] = (NPCX_PECI_DATA_IN(1) << 8) | - (NPCX_PECI_DATA_IN(0) << 0); - } - } - return (int)cpu_temp; -} - -int peci_temp_sensor_get_val(int idx, int *temp_ptr) -{ - int sum = 0; - int success_cnt = 0; - int i; - - if (!chipset_in_state(CHIPSET_STATE_ON)) - return EC_ERROR_NOT_POWERED; - - for (i = 0; i < TEMP_AVG_LENGTH; ++i) { - if (temp_vals[i] >= 0) { - success_cnt++; - sum += temp_vals[i]; - } - } - - /* - * Require at least two valid samples. When the AP transitions into S0, - * it is possible, depending on the timing of the PECI sample, to read - * an invalid temperature. This is very rare, but when it does happen - * the temperature returned is CONFIG_PECI_TJMAX. Requiring two valid - * samples here assures us that one bad maximum temperature reading - * when entering S0 won't cause us to trigger an over temperature. - */ - if (success_cnt < 2) - return EC_ERROR_UNKNOWN; - - *temp_ptr = sum / success_cnt; - return EC_SUCCESS; -} - -static void peci_temp_sensor_poll(void) -{ - int val; - - val = peci_get_cpu_temp(); - if (val != -1) { - temp_vals[temp_idx] = val; - temp_idx = (temp_idx + 1) & (TEMP_AVG_LENGTH - 1); - } -} -DECLARE_HOOK(HOOK_TICK, peci_temp_sensor_poll, HOOK_PRIO_TEMP_SENSOR); - -static void peci_freq_changed(void) -{ - /* PECI's clock source is FMCLK */ - int freq = clock_get_fm_freq(); - int baud = 0xF; - - /* Disable polling while reconfiguring */ - NPCX_PECI_CTL_STS = 0; - - /* - * Set the maximum bit rate used by the PECI module during both - * Address Timing Negotiation and Data Timing Negotiation. - * The resulting maximum bit rate MAX_BIT_RATE in decimal is - * according to the following formula: - * - * MAX_BIT_RATE [d] = (freq / (4 * baudrate)) - 1 - * Maximum bit rate should not extend the field's boundaries. - */ - if (freq != 0) { - baud = (uint8_t)(freq / (4 * PECI_BAUD_RATE)) - 1; - /* Set maximum PECI baud rate (bit0 - bit4) */ - if (baud > 0x1F) - baud = 0x1F; - } - /* Enhanced High-Speed */ - if (baud >= 7) { - CLEAR_BIT(NPCX_PECI_RATE, 6); - CLEAR_BIT(NPCX_PECI_CFG, 3); - } else { - SET_BIT(NPCX_PECI_RATE, 6); - SET_BIT(NPCX_PECI_CFG, 3); - } - /* Setting Rate */ - NPCX_PECI_RATE = baud; -} -DECLARE_HOOK(HOOK_FREQ_CHANGE, peci_freq_changed, HOOK_PRIO_DEFAULT); - -static void peci_init(void) -{ - int i; - - /* Enable clock for PECI peripheral */ - clock_enable_peripheral(CGC_OFFSET_PECI, CGC_PECI_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - /* Set PECI freq */ - peci_freq_changed(); - - /* make sure PECI_DATA function pin enable */ - CLEAR_BIT(NPCX_DEVALT(0x0A), 6); - /* Set initial clock frequency */ - peci_freq_changed(); - /* Initialize temperature reading buffer to a valid value. */ - for (i = 0; i < TEMP_AVG_LENGTH; ++i) - temp_vals[i] = 300; /* 27 C */ - - /* init Pending task id */ - peci_pending_task_id = NULL_PENDING_TASK_ID; - /* Enable PECI Done interrupt */ - SET_BIT(NPCX_PECI_CTL_STS, NPCX_PECI_CTL_STS_DONE_EN); - - task_enable_irq(NPCX_IRQ_PECI); -} -DECLARE_HOOK(HOOK_INIT, peci_init, HOOK_PRIO_DEFAULT); - -/* If received a PECI DONE interrupt, post the event to PECI task */ -void peci_done_interrupt(void){ - if (peci_pending_task_id != NULL_PENDING_TASK_ID) - task_set_event(peci_pending_task_id, TASK_EVENT_PECI_DONE); - peci_sts = NPCX_PECI_CTL_STS & 0x18; - /* no matter what, clear status bit again */ - SET_BIT(NPCX_PECI_CTL_STS, NPCX_PECI_CTL_STS_DONE); - SET_BIT(NPCX_PECI_CTL_STS, NPCX_PECI_CTL_STS_CRC_ERR); - SET_BIT(NPCX_PECI_CTL_STS, NPCX_PECI_CTL_STS_ABRT_ERR); -} -DECLARE_IRQ(NPCX_IRQ_PECI, peci_done_interrupt, 4); - -/*****************************************************************************/ -/* Console commands */ - -static int command_peci_temp(int argc, char **argv) -{ - int t = peci_get_cpu_temp(); - if (t == -1) { - ccprintf("PECI response timeout\n"); - return EC_ERROR_UNKNOWN; - } - ccprintf("CPU temp = %d K = %d\n", t, K_TO_C(t)); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(pecitemp, command_peci_temp, - NULL, - "Print CPU temperature"); diff --git a/chip/npcx/ps2.c b/chip/npcx/ps2.c deleted file mode 100644 index 7b8086cbcd..0000000000 --- a/chip/npcx/ps2.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2019 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. - */ - -/* PS/2 module for Chrome EC */ -#include "atomic.h" -#include "clock.h" -#include "console.h" -#include "hooks.h" -#include "gpio.h" -#include "ps2_chip.h" -#include "task.h" -#include "registers.h" -#include "timer.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_PS2, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_PS2, format, ## args) - -#if !(DEBUG_PS2) -#define DEBUG_CPRINTS(...) -#define DEBUG_CPRINTF(...) -#else -#define DEBUG_CPRINTS(format, args...) cprints(CC_PS2, format, ## args) -#define DEBUG_CPRINTF(format, args...) cprintf(CC_PS2, format, ## args) -#endif - -/* - * Set WDAT3-0 and clear CLK3-0 in the PSOSIG register to - * reset the shift mechanism. - */ -#define PS2_SHIFT_MECH_RESET 0x47 - -#define PS2_TRANSACTION_TIMEOUT (20 * MSEC) -#define PS2_BUSY_RETRY 10 - -enum ps2_input_debounce_cycle { - PS2_IDB_1_CYCLE, - PS2_IDB_2_CYCLE, - PS2_IDB_4_CYCLE, - PS2_IDB_8_CYCLE, - PS2_IDB_16_CYCLE, - PS2_IDB_32_CYCLE, -}; - -enum ps2_opr_mode { - PS2_TX_MODE, - PS2_RX_MODE, -}; - -struct ps2_data { - /* PS/2 module operation mode */ - uint8_t opr_mode; - /* - * The callback function to process data received from PS/2 device. - * Note: this is called in the PS/2 interrupt handler - */ - void (*rx_handler_cb)(uint8_t data); -}; -static struct ps2_data ps2_ch_data[NPCX_PS2_CH_COUNT] = { - [0 ... (NPCX_PS2_CH_COUNT - 1)] = { PS2_RX_MODE, NULL } -}; - -/* - * Bitmap to record the enabled PS/2 channel by upper layer. - * Only bit[7 and bit[5:3] are used - * (i.e. the bit position of CLK3-0 in the PS2_PSOSIG register) - */ -static uint32_t channel_enabled_mask; -static struct mutex ps2_lock; -static volatile task_id_t task_waiting = TASK_ID_INVALID; - -static void ps2_init(void) -{ - /* Disable the power down bit of PS/2 */ - clock_enable_peripheral(CGC_OFFSET_PS2, CGC_PS2_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - - /* Disable shift mechanism and configure PS/2 to received mode. */ - NPCX_PS2_PSCON = 0x0; - /* Set WDAT3-0 and clear CLK3-0 before enabling shift mechanism */ - NPCX_PS2_PSOSIG = PS2_SHIFT_MECH_RESET; - - /* - * PS/2 interrupt enable register - * [0] - : SOTIE = 1: Start Of Transaction Interrupt Enable - * [1] - : EOTIE = 1: End Of Transaction Interrupt Enable - * [4] - : WUE = 1: Wake-Up Enable - * [7] - : CLK_SEL = 1: Select Free-Run clock as the basic clock - */ - NPCX_PS2_PSIEN = BIT(NPCX_PS2_PSIEN_SOTIE) | - BIT(NPCX_PS2_PSIEN_EOTIE) | - BIT(NPCX_PS2_PSIEN_PS2_WUE) | - BIT(NPCX_PS2_PSIEN_PS2_CLK_SEL); - - /* Enable weak internal pull-up */ - SET_BIT(NPCX_PS2_PSCON, NPCX_PS2_PSCON_WPUED); - /* Enable shift mechanism */ - SET_BIT(NPCX_PS2_PSCON, NPCX_PS2_PSCON_EN); - - /* Configure pins from GPIOs to PS/2 interface */ - gpio_config_module(MODULE_PS2, 1); - task_enable_irq(NPCX_IRQ_PS2); -} -DECLARE_HOOK(HOOK_INIT, ps2_init, HOOK_PRIO_DEFAULT); - -void ps2_enable_channel(int channel, int enable, - void (*callback)(uint8_t data)) -{ - if (channel >= NPCX_PS2_CH_COUNT) { - CPRINTS("Err:PS/2 CH exceed %d", NPCX_PS2_CH_COUNT); - return; - } - - /* - * Disable the interrupt during changing the enabled channel mask to - * prevent from preemption - */ - interrupt_disable(); - if (enable) { - ps2_ch_data[channel].rx_handler_cb = callback; - channel_enabled_mask |= BIT(NPCX_PS2_PSOSIG_CLK(channel)); - /* Enable the relevant channel clock */ - SET_BIT(NPCX_PS2_PSOSIG, NPCX_PS2_PSOSIG_CLK(channel)); - } else { - channel_enabled_mask &= ~BIT(NPCX_PS2_PSOSIG_CLK(channel)); - /* Disable the relevant channel clock */ - CLEAR_BIT(NPCX_PS2_PSOSIG, NPCX_PS2_PSOSIG_CLK(channel)); - ps2_ch_data[channel].rx_handler_cb = NULL; - } - interrupt_enable(); -} - -/* Check if the shift mechanism is busy */ -static int ps2_is_busy(void) -{ - /* - * The driver pulls the CLK for non-active channels to low when Start - * bit is detected and pull the CLK of the active channel low after - * Stop bit detected. The EOT bit is set when Stop bit is detected, - * but both SOT and EOT are cleared when all CLKs are pull low - * (due to Shift Mechanism is reset) - */ - return (IS_BIT_SET(NPCX_PS2_PSTAT, NPCX_PS2_PSTAT_SOT) | - IS_BIT_SET(NPCX_PS2_PSTAT, NPCX_PS2_PSTAT_EOT)) ? 1 : 0; -} - -int ps2_transmit_byte(int channel, uint8_t data) -{ - int event; - - uint8_t busy_retry = PS2_BUSY_RETRY; - - if (channel >= NPCX_PS2_CH_COUNT) { - CPRINTS("Err:PS/2 CH exceed %d", NPCX_PS2_CH_COUNT); - return EC_ERROR_INVAL; - } - - if (!(BIT(NPCX_PS2_PSOSIG_CLK(channel)) & channel_enabled_mask)) { - CPRINTS("Err: PS/2 Tx w/o enabling CH"); - return EC_ERROR_INVAL; - } - - mutex_lock(&ps2_lock); - while (ps2_is_busy()) { - usleep(PS2_TRANSACTION_TIMEOUT); - if (busy_retry == 0) { - mutex_unlock(&ps2_lock); - return EC_ERROR_BUSY; - } - busy_retry--; - } - - task_waiting = task_get_current(); - ps2_ch_data[channel].opr_mode = PS2_TX_MODE; - - /* Set PS/2 in transmit mode */ - SET_BIT(NPCX_PS2_PSCON, NPCX_PS2_PSCON_XMT); - /* Enable Start Of Transaction interrupt */ - SET_BIT(NPCX_PS2_PSIEN, NPCX_PS2_PSIEN_SOTIE); - - /* Reset the shift mechanism */ - NPCX_PS2_PSOSIG = PS2_SHIFT_MECH_RESET; - /* Inhibit communication should last at least 100 micro-seconds */ - udelay(100); - - /* Write the data to be transmitted */ - NPCX_PS2_PSDAT = data; - /* Apply the Request-to-send */ - CLEAR_BIT(NPCX_PS2_PSOSIG, NPCX_PS2_PSOSIG_WDAT(channel)); - SET_BIT(NPCX_PS2_PSOSIG, NPCX_PS2_PSOSIG_CLK(channel)); - - /* Wait for interrupt */ - event = task_wait_event_mask(TASK_EVENT_PS2_DONE, - PS2_TRANSACTION_TIMEOUT); - task_waiting = TASK_ID_INVALID; - - if (event == TASK_EVENT_TIMER) { - task_disable_irq(NPCX_IRQ_PS2); - CPRINTS("PS/2 Tx timeout"); - /* Reset the shift mechanism */ - NPCX_PS2_PSOSIG = PS2_SHIFT_MECH_RESET; - /* Change the PS/2 module to receive mode */ - CLEAR_BIT(NPCX_PS2_PSCON, NPCX_PS2_PSCON_XMT); - /* Restore the channel to Receive mode */ - ps2_ch_data[channel].opr_mode = PS2_RX_MODE; - /* - * Restore the enabled channel according to channel_enabled_mask - */ - NPCX_PS2_PSOSIG |= channel_enabled_mask; - task_enable_irq(NPCX_IRQ_PS2); - } - mutex_unlock(&ps2_lock); - - DEBUG_CPRINTF("Evt:0x%08x\n", event); - return (event == TASK_EVENT_PS2_DONE) ? EC_SUCCESS : EC_ERROR_TIMEOUT; - -} - -static void ps2_stop_inactive_ch_clk(uint8_t active_ch) -{ - uint8_t mask; - - mask = ~NPCX_PS2_PSOSIG_CLK_MASK_ALL | - BIT(NPCX_PS2_PSOSIG_CLK(active_ch)); - NPCX_PS2_PSOSIG &= mask; - -} - -static int ps2_is_rx_error(uint8_t ch) -{ - uint8_t status; - - status = NPCX_PS2_PSTAT & - (BIT(NPCX_PS2_PSTAT_PERR) | - BIT(NPCX_PS2_PSTAT_RFERR)); - if (status) { - - if (status & BIT(NPCX_PS2_PSTAT_PERR)) - CPRINTF("PS2 CH %d RX parity error\n", ch); - if (status & BIT(NPCX_PS2_PSTAT_RFERR)) - CPRINTF("PS2 CH %d RX Frame error\n", ch); - return 1; - } else - return 0; -} - -void ps2_int_handler(void) -{ - uint8_t active_ch; - - DEBUG_CPRINTS("PS2 INT"); - /* - * ACH = 1 : CHannel 0 - * ACH = 2 : CHannel 1 - * ACH = 4 : CHannel 2 - * ACH = 5 : CHannel 3 - */ - active_ch = GET_FIELD(NPCX_PS2_PSTAT, NPCX_PS2_PSTAT_ACH); - active_ch = active_ch > 2 ? (active_ch - 2) : (active_ch - 1); - DEBUG_CPRINTF("ACH:%0d-", active_ch); - - /* - * Inhibit PS/2 transaction of the other non-active channels by - * pulling down the clock signal - */ - ps2_stop_inactive_ch_clk(active_ch); - - /* PS/2 Start of Transaction */ - if (IS_BIT_SET(NPCX_PS2_PSTAT, NPCX_PS2_PSTAT_SOT) && - IS_BIT_SET(NPCX_PS2_PSIEN, NPCX_PS2_PSIEN_SOTIE)) { - DEBUG_CPRINTF("SOT-"); - /* - * Once set, SOT is not cleared until the shift mechanism - * is reset. Therefore, SOTIE should be cleared on the - * first occurrence of an SOT interrupt. - */ - CLEAR_BIT(NPCX_PS2_PSIEN, NPCX_PS2_PSIEN_SOTIE); - /* PS/2 End of Transaction */ - } else if (IS_BIT_SET(NPCX_PS2_PSTAT, NPCX_PS2_PSTAT_EOT)) { - DEBUG_CPRINTF("EOT-"); - CLEAR_BIT(NPCX_PS2_PSIEN, NPCX_PS2_PSIEN_EOTIE); - - /* - * Clear the CLK of active channel to reset - * the shift mechanism - */ - CLEAR_BIT(NPCX_PS2_PSOSIG, NPCX_PS2_PSOSIG_CLK(active_ch)); - - if (ps2_ch_data[active_ch].opr_mode == PS2_TX_MODE) { - /* Change the PS/2 module to receive mode */ - CLEAR_BIT(NPCX_PS2_PSCON, NPCX_PS2_PSCON_XMT); - ps2_ch_data[active_ch].opr_mode = PS2_RX_MODE; - task_set_event(task_waiting, TASK_EVENT_PS2_DONE); - } else { - if (!ps2_is_rx_error(active_ch)) { - uint8_t data_read = NPCX_PS2_PSDAT; - struct ps2_data *ps2_ptr = - &ps2_ch_data[active_ch]; - - DEBUG_CPRINTF("Recv:0x%02x", data_read); - if (ps2_ptr->rx_handler_cb) - ps2_ptr->rx_handler_cb(data_read); - } - } - - /* Restore the enabled channel */ - NPCX_PS2_PSOSIG |= channel_enabled_mask; - /* - * Re-enable the Start Of Transaction interrupt when - * the shift mechanism is reset - */ - SET_BIT(NPCX_PS2_PSIEN, NPCX_PS2_PSIEN_SOTIE); - SET_BIT(NPCX_PS2_PSIEN, NPCX_PS2_PSIEN_EOTIE); - } - DEBUG_CPRINTF("\n"); - -} -DECLARE_IRQ(NPCX_IRQ_PS2, ps2_int_handler, 5); - -#ifdef CONFIG_CMD_PS2 -static int command_ps2ench(int argc, char **argv) -{ - uint8_t ch; - uint8_t enable; - char *e; - - ch = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - - enable = strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - if (enable) - ps2_enable_channel(ch, 1, NULL); - else - ps2_enable_channel(ch, 0, NULL); - - return 0; -} -DECLARE_CONSOLE_COMMAND(ps2ench, command_ps2ench, - "ps2_ench channel 1|0", - "Enable/Disable PS/2 channel"); - -static int command_ps2write(int argc, char **argv) -{ - uint8_t ch, data; - char *e; - - ch = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - data = strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - - ps2_transmit_byte(ch, data); - return 0; -} -DECLARE_CONSOLE_COMMAND(ps2write, command_ps2write, - "ps2_write channel data", - "Write data byte to PS/2 channel "); -#endif diff --git a/chip/npcx/ps2_chip.h b/chip/npcx/ps2_chip.h deleted file mode 100644 index d88e6791ad..0000000000 --- a/chip/npcx/ps2_chip.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2019 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_PS2_CHIP_H -#define __CROS_EC_PS2_CHIP_H - -#include "common.h" - -enum npcx_ps2_channel { - NPCX_PS2_CH0, - NPCX_PS2_CH1, - NPCX_PS2_CH2, - NPCX_PS2_CH3, - NPCX_PS2_CH_COUNT -}; - -void ps2_enable_channel(int channel, int enable, - void (*callback)(uint8_t data)); -int ps2_transmit_byte(int channel, uint8_t data); - -#endif /* __CROS_EC_PS2_CHIP_H */ diff --git a/chip/npcx/pwm.c b/chip/npcx/pwm.c deleted file mode 100644 index b2016906b3..0000000000 --- a/chip/npcx/pwm.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Copyright 2014 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. - */ - -/* PWM control module for NPCX. - * - * On this chip, the PWM logic is implemented by the hardware FAN modules. - */ - -#include "assert.h" -#include "clock.h" -#include "clock_chip.h" -#include "console.h" -#include "ec_commands.h" -#include "gpio.h" -#include "hooks.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "registers.h" -#include "util.h" - -#if !(DEBUG_PWM) -#define CPRINTS(...) -#else -#define CPRINTS(format, args...) cprints(CC_PWM, format, ## args) -#endif - -/* pwm resolution for each channel */ -static uint32_t pwm_res[PWM_CH_COUNT]; - -/* PWM clock source */ -enum npcx_pwm_source_clock { - NPCX_PWM_CLOCK_APB2_LFCLK = 0, - NPCX_PWM_CLOCK_FX = 1, - NPCX_PWM_CLOCK_FR = 2, - NPCX_PWM_CLOCK_RESERVED = 3, - NPCX_PWM_CLOCK_UNDEF = 0xFF -}; - -/* PWM heartbeat mode */ -enum npcx_pwm_heartbeat_mode { - NPCX_PWM_HBM_NORMAL = 0, - NPCX_PWM_HBM_25 = 1, - NPCX_PWM_HBM_50 = 2, - NPCX_PWM_HBM_100 = 3, - NPCX_PWM_HBM_UNDEF = 0xFF -}; - -/** - * Set PWM operation clock. - * - * @param ch operation channel - * @param freq desired PWM frequency - * @notes changed when initialization - */ -static void pwm_set_freq(enum pwm_channel ch, uint32_t freq) -{ - int mdl = pwm_channels[ch].channel; - uint32_t clock; - uint32_t pre; - - assert(freq != 0); - - /* Disable PWM for module configuration */ - pwm_enable(ch, 0); - - /* - * Get PWM clock frequency. Use internal 32K as PWM clock source if - * the PWM must be active during low-power idle. - */ - if (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) - clock = INT_32K_CLOCK; - else - clock = clock_get_apb2_freq(); - - /* Calculate prescaler */ - pre = DIV_ROUND_UP(clock, (0xffff * freq)); - - /* - * Calculate maximum resolution for the given freq. and prescaler. And - * prevent it exceed the resolution of CTR/DCR registers. - */ - pwm_res[ch] = MIN((clock / pre) / freq, NPCX_PWM_MAX_RAW_DUTY); - - /* Set PWM prescaler. */ - NPCX_PRSC(mdl) = pre - 1; - - /* Set PWM cycle time */ - NPCX_CTR(mdl) = pwm_res[ch]; - - /* Set the duty cycle to 100% since DCR == CTR */ - NPCX_DCR(mdl) = pwm_res[ch]; -} - -/** - * Set PWM enabled. - * - * @param ch operation channel - * @param enabled enabled flag - */ -void pwm_enable(enum pwm_channel ch, int enabled) -{ - int mdl = pwm_channels[ch].channel; - - /* Start or close PWM module */ - UPDATE_BIT(NPCX_PWMCTL(mdl), NPCX_PWMCTL_PWR, enabled); -} - -/** - * Check PWM enabled. - * - * @param ch operation channel - * @return enabled or not - */ -int pwm_get_enabled(enum pwm_channel ch) -{ - int mdl = pwm_channels[ch].channel; - return IS_BIT_SET(NPCX_PWMCTL(mdl), NPCX_PWMCTL_PWR); -} - -/** - * Set PWM duty cycle. - * - * @param ch operation channel - * @param percent duty cycle percent - */ -void pwm_set_duty(enum pwm_channel ch, int percent) -{ - /* Convert percent on [0, 100] to 16 bit duty */ - pwm_set_raw_duty(ch, (percent * EC_PWM_MAX_DUTY) / 100); -} - -/** - * Set PWM duty cycle. - * - * @param ch operation channel - * @param duty cycle duty - */ -void pwm_set_raw_duty(enum pwm_channel ch, uint16_t duty) -{ - int mdl = pwm_channels[ch].channel; - uint32_t sd; - - CPRINTS("pwm%d, set duty=%d", mdl, duty); - - /* Assume the fan control is active high and invert it ourselves */ - UPDATE_BIT(NPCX_PWMCTL(mdl), NPCX_PWMCTL_INVP, - (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW)); - - CPRINTS("initial freq=0x%x", pwm_channels[ch].freq); - CPRINTS("duty_cycle_cnt=%d", duty); - - /* duty ranges from 0 - 0xffff, so scale down to 0 - pwm_res[ch] */ - sd = DIV_ROUND_NEAREST(duty * pwm_res[ch], EC_PWM_MAX_DUTY); - - /* Set the duty cycle. If it is zero, set DCR > CTR */ - NPCX_DCR(mdl) = sd ? sd : NPCX_PWM_MAX_RAW_DUTY + 1; -} - -/** - * Get PWM duty cycle. - * - * @param ch operation channel - * @return duty cycle percent - */ -int pwm_get_duty(enum pwm_channel ch) -{ - /* duty ranges from 0 - 0xffff, so scale to 0 - 100 */ - return DIV_ROUND_NEAREST(pwm_get_raw_duty(ch) * 100, EC_PWM_MAX_DUTY); -} - -/** - * Get PWM duty cycle. - * - * @param ch operation channel - * @return duty cycle - */ -uint16_t pwm_get_raw_duty(enum pwm_channel ch) -{ - int mdl = pwm_channels[ch].channel; - - /* Return duty */ - if (NPCX_DCR(mdl) > NPCX_CTR(mdl)) - return 0; - else - /* - * NPCX_DCR ranges from 0 - pwm_res[ch], - * so scale to 0 - 0xffff - */ - return DIV_ROUND_NEAREST(NPCX_DCR(mdl) * EC_PWM_MAX_DUTY, - pwm_res[ch]); -} - -/** - * PWM configuration. - * - * @param ch operation channel - */ -void pwm_config(enum pwm_channel ch) -{ - int mdl = pwm_channels[ch].channel; - - /* Disable PWM for module configuration */ - pwm_enable(ch, 0); - - /* Set PWM heartbeat mode is no heartbeat */ - SET_FIELD(NPCX_PWMCTL(mdl), NPCX_PWMCTL_HB_DC_CTL_FIELD, - NPCX_PWM_HBM_NORMAL); - - /* Select default CLK or LFCLK clock input to PWM module */ - SET_FIELD(NPCX_PWMCTLEX(mdl), NPCX_PWMCTLEX_FCK_SEL_FIELD, - NPCX_PWM_CLOCK_APB2_LFCLK); - - /* Set PWM polarity normal first */ - CLEAR_BIT(NPCX_PWMCTL(mdl), NPCX_PWMCTL_INVP); - - /* Select PWM clock source */ - UPDATE_BIT(NPCX_PWMCTL(mdl), NPCX_PWMCTL_CKSEL, - (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP)); - - /* Select PWM IO type */ - UPDATE_BIT(NPCX_PWMCTLEX(mdl), NPCX_PWMCTLEX_OD_OUT, - (pwm_channels[ch].flags & PWM_CONFIG_OPEN_DRAIN)); - - /* Set PWM operation frequency */ - pwm_set_freq(ch, pwm_channels[ch].freq); -} - -/** - * PWM initial. - */ -static void pwm_init(void) -{ - int i; - uint8_t pd_mask = 0; - - /* Take enabled PWMs out of power-down state */ - for (i = 0; i < PWM_CH_COUNT; i++) { - pd_mask |= (1 << pwm_channels[i].channel); - pwm_res[i] = 0; - } - - clock_enable_peripheral(CGC_OFFSET_PWM, pd_mask, CGC_MODE_ALL); - - for (i = 0; i < PWM_CH_COUNT; i++) - pwm_config(i); -} - -/* The chip-specific fan module initializes before this. */ -DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_INIT_PWM); diff --git a/chip/npcx/pwm_chip.h b/chip/npcx/pwm_chip.h deleted file mode 100644 index 7acfef81e5..0000000000 --- a/chip/npcx/pwm_chip.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2014 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-specific PWM module for Chrome EC */ - -#ifndef __CROS_EC_PWM_CHIP_H -#define __CROS_EC_PWM_CHIP_H - -/* Data structure to define PWM channels. */ -struct pwm_t { - /* PWM channel ID */ - int channel; - /* PWM channel flags. See include/pwm.h */ - uint32_t flags; - /* PWM freq. */ - uint32_t freq; -}; - -extern const struct pwm_t pwm_channels[]; -void pwm_config(enum pwm_channel ch); - -/* Npcx PWM maximum duty cycle value */ -#define NPCX_PWM_MAX_RAW_DUTY (UINT16_MAX - 1) - -#endif /* __CROS_EC_PWM_CHIP_H */ diff --git a/chip/npcx/registers-npcx5.h b/chip/npcx/registers-npcx5.h deleted file mode 100644 index c441c1c926..0000000000 --- a/chip/npcx/registers-npcx5.h +++ /dev/null @@ -1,388 +0,0 @@ -/* Copyright 2020 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. - */ - -/* - * Specific register map for NPCX5 family of chips. - * - * Support chip variant: - * - npcx5m5g - * - npcx5m6g - * - * This header file should not be included directly. - * Please include registers.h instead. - */ - -#ifndef __CROS_EC_REGISTERS_H -#error "This header file should not be included directly." -#endif - -/* NPCX-IRQ numbers */ -#define NPCX_IRQ0_NOUSED NPCX_IRQ_0 -#define NPCX_IRQ1_NOUSED NPCX_IRQ_1 -#define NPCX_IRQ_KBSCAN NPCX_IRQ_2 -#define NPCX_IRQ_PM_CHAN_OBE NPCX_IRQ_3 -#define NPCX_IRQ_PECI NPCX_IRQ_4 -#define NPCX_IRQ5_NOUSED NPCX_IRQ_5 -#define NPCX_IRQ_PORT80 NPCX_IRQ_6 -#define NPCX_IRQ_MTC_WKINTAD_0 NPCX_IRQ_7 -#define NPCX_IRQ_MTC NPCX_IRQ_MTC_WKINTAD_0 -#define NPCX_IRQ8_NOUSED NPCX_IRQ_8 -#define NPCX_IRQ_MFT_1 NPCX_IRQ_9 -#define NPCX_IRQ_ADC NPCX_IRQ_10 -#define NPCX_IRQ_WKINTEFGH_0 NPCX_IRQ_11 -#define NPCX_IRQ_GDMA NPCX_IRQ_12 -#define NPCX_IRQ_SMB1 NPCX_IRQ_13 -#define NPCX_IRQ_SMB2 NPCX_IRQ_14 -#define NPCX_IRQ_WKINTC_0 NPCX_IRQ_15 -#define NPCX_IRQ16_NOUSED NPCX_IRQ_16 -#define NPCX_IRQ_ITIM16_3 NPCX_IRQ_17 -#define NPCX_IRQ_SHI NPCX_IRQ_18 -#define NPCX_IRQ_ESPI NPCX_IRQ_18 -#define NPCX_IRQ19_NOUSED NPCX_IRQ_19 -#define NPCX_IRQ20_NOUSED NPCX_IRQ_20 -#define NPCX_IRQ_PS2 NPCX_IRQ_21 -#define NPCX_IRQ22_NOUSED NPCX_IRQ_22 -#define NPCX_IRQ_MFT_2 NPCX_IRQ_23 -#define NPCX_IRQ_SHM NPCX_IRQ_24 -#define NPCX_IRQ_KBC_IBF NPCX_IRQ_25 -#define NPCX_IRQ_PM_CHAN_IBF NPCX_IRQ_26 -#define NPCX_IRQ_ITIM16_2 NPCX_IRQ_27 -#define NPCX_IRQ_ITIM16_1 NPCX_IRQ_28 -#define NPCX_IRQ29_NOUSED NPCX_IRQ_29 -#define NPCX_IRQ30_NOUSED NPCX_IRQ_30 -#define NPCX_IRQ_TWD_WKINTB_0 NPCX_IRQ_31 -#define NPCX_IRQ32_NOUSED NPCX_IRQ_32 -#define NPCX_IRQ_UART NPCX_IRQ_33 -#define NPCX_IRQ34_NOUSED NPCX_IRQ_34 -#define NPCX_IRQ35_NOUSED NPCX_IRQ_35 -#define NPCX_IRQ_SMB3 NPCX_IRQ_36 -#define NPCX_IRQ_SMB4 NPCX_IRQ_37 -#define NPCX_IRQ38_NOUSED NPCX_IRQ_38 -#define NPCX_IRQ39_NOUSED NPCX_IRQ_39 -#define NPCX_IRQ40_NOUSED NPCX_IRQ_40 -#define NPCX_IRQ_MFT_3 NPCX_IRQ_41 -#define NPCX_IRQ42_NOUSED NPCX_IRQ_42 -#define NPCX_IRQ_ITIM16_4 NPCX_IRQ_43 -#define NPCX_IRQ_ITIM16_5 NPCX_IRQ_44 -#define NPCX_IRQ_ITIM16_6 NPCX_IRQ_45 -#define NPCX_IRQ_ITIM32 NPCX_IRQ_46 -#define NPCX_IRQ_WKINTA_1 NPCX_IRQ_47 -#define NPCX_IRQ_WKINTB_1 NPCX_IRQ_48 -#define NPCX_IRQ_KSI_WKINTC_1 NPCX_IRQ_49 -#define NPCX_IRQ_WKINTD_1 NPCX_IRQ_50 -#define NPCX_IRQ_WKINTE_1 NPCX_IRQ_51 -#define NPCX_IRQ_WKINTF_1 NPCX_IRQ_52 -#define NPCX_IRQ_WKINTG_1 NPCX_IRQ_53 -#define NPCX_IRQ_WKINTH_1 NPCX_IRQ_54 -#define NPCX_IRQ55_NOUSED NPCX_IRQ_55 -#define NPCX_IRQ_KBC_OBE NPCX_IRQ_56 -#define NPCX_IRQ_SPI NPCX_IRQ_57 -#define NPCX_IRQ58_NOUSED NPCX_IRQ_58 -#define NPCX_IRQ_WKINTFG_2 NPCX_IRQ_59 -#define NPCX_IRQ_WKINTA_2 NPCX_IRQ_60 -#define NPCX_IRQ_WKINTB_2 NPCX_IRQ_61 -#define NPCX_IRQ_WKINTC_2 NPCX_IRQ_62 -#define NPCX_IRQ_WKINTD_2 NPCX_IRQ_63 - -/* Modules Map */ - -/* Miscellaneous Device Control (MDC) registers */ -#define NPCX_FWCTRL REG8(NPCX_MDC_BASE_ADDR + 0x007) - -/* MDC register fields */ -#define NPCX_FWCTRL_RO_REGION 0 -#define NPCX_FWCTRL_FW_SLOT 1 - -#define NPCX_ITIM32_BASE_ADDR 0x400BC000 -#define NPCX_CR_UART_BASE_ADDR(mdl) (0x400C4000 + ((mdl) * 0x2000L)) -#define NPCX_SMB_BASE_ADDR(mdl) (((mdl) < 2) ? \ - (0x40009000 + ((mdl) * 0x2000L)) : \ - (0x400C0000 + (((mdl) - 2) * 0x2000L))) - -enum { - NPCX_UART_PORT0 = 0, /* UART port 0 */ - NPCX_UART_COUNT -}; - -/* System Configuration (SCFG) Registers */ - -/* SCFG enumeration */ -enum { - ALT_GROUP_0, - ALT_GROUP_1, - ALT_GROUP_2, - ALT_GROUP_3, - ALT_GROUP_4, - ALT_GROUP_5, - ALT_GROUP_6, - ALT_GROUP_7, - ALT_GROUP_8, - ALT_GROUP_9, - ALT_GROUP_A, - ALT_GROUP_B, - ALT_GROUP_C, - ALT_GROUP_D, - ALT_GROUP_E, - ALT_GROUP_F, - ALT_GROUP_COUNT -}; - -#define NPCX_DEVALT(n) REG8(NPCX_SCFG_BASE_ADDR + 0x010 + (n)) - -#define NPCX_LV_GPIO_CTL(n) REG8(NPCX_SCFG_BASE_ADDR + 0x02A + (n)) - -/* pin-mux for JTAG */ -#define NPCX_DEVALT5_NJEN1_EN 1 -#define NPCX_DEVALT5_NJEN0_EN 2 - -/* pin-mux for I2C */ -#define NPCX_DEVALT2_I2C0_0_SL 0 -#define NPCX_DEVALT2_I2C0_1_SL 1 -#define NPCX_DEVALT2_I2C1_0_SL 2 -#define NPCX_DEVALT2_I2C2_0_SL 4 -#define NPCX_DEVALT2_I2C3_0_SL 6 - -/* pin-mux for UART */ -#define NPCX_DEVALTA_UART_SL1 7 -#define NPCX_DEVALTC_UART_SL2 0 - -/* pin-mux for Misc. */ -/* External 32KHz crytal osc. input support */ -#define NPCX_DEVALTA_32KCLKIN_SL 3 - -/* SMBus register fields */ -#define NPCX_SMBSEL_SMB0SEL 0 - -/* SMB enumeration: I2C port definitions. */ -enum { - NPCX_I2C_PORT0_0 = 0, /* I2C port 0, bus 0 */ - NPCX_I2C_PORT0_1, /* I2C port 0, bus 1 */ - NPCX_I2C_PORT1, /* I2C port 1 */ - NPCX_I2C_PORT2, /* I2C port 2 */ - NPCX_I2C_PORT3, /* I2C port 3 */ - NPCX_I2C_COUNT, -}; - -/* - * PMC enumeration: - * Offsets from CGC_BASE registers for each peripheral. - */ -enum { - CGC_OFFSET_KBS = 0, - CGC_OFFSET_UART = 0, - CGC_OFFSET_FAN = 0, - CGC_OFFSET_FIU = 0, - CGC_OFFSET_PS2 = 0, - CGC_OFFSET_PWM = 1, - CGC_OFFSET_I2C = 2, - CGC_OFFSET_ADC = 3, - CGC_OFFSET_PECI = 3, - CGC_OFFSET_SPI = 3, - CGC_OFFSET_TIMER = 3, - CGC_OFFSET_LPC = 4, - CGC_OFFSET_ESPI = 5, -}; - -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_CNT, -}; - -#define CGC_I2C_MASK (BIT(NPCX_PWDWN_CTL3_SMB0_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB1_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB2_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB3_PD)) - -/* BBRAM register fields */ -#define NPCX_BKUP_STS_ALL_MASK BIT(NPCX_BKUP_STS_IBBR) -#define NPCX_BBRAM_SIZE 64 /* Size of BBRAM */ - -/* ITIM registers */ -#define NPCX_ITCNT8(n) REG8(NPCX_ITIM_BASE_ADDR(n) + 0x000) -#define NPCX_ITCNT16(n) REG16(NPCX_ITIM_BASE_ADDR(n) + 0x002) -/* ITIM32 registers */ -#define NPCX_ITCNT32 REG32(NPCX_ITIM32_BASE_ADDR + 0x008) - -/* Timer counter register used for 1 micro-second system tick */ -#define NPCX_ITCNT_SYSTEM NPCX_ITCNT32 -/* Timer counter register used for others */ -#define NPCX_ITCNT NPCX_ITCNT16 - -/* ITIM module No. used for event */ -#define ITIM_EVENT_NO ITIM16_1 -/* ITIM module No. used for watchdog */ -#define ITIM_WDG_NO ITIM16_5 -/* ITIM module No. used for 1 micro-second system tick */ -#define ITIM_SYSTEM_NO ITIM32 - -/* ITIM enumeration */ -enum ITIM_MODULE_T { - ITIM16_1, - ITIM16_2, - ITIM16_3, - ITIM16_4, - ITIM16_5, - ITIM16_6, - ITIM32, - ITIM_MODULE_COUNT, -}; - -/* Serial Host Interface (SHI) Registers */ -#define NPCX_OBUF(n) REG8(NPCX_SHI_BASE_ADDR + 0x020 + (n)) -#define NPCX_IBUF(n) REG8(NPCX_SHI_BASE_ADDR + 0x060 + (n)) - -/* Bit field manipulation for VWEVMS Value */ -#define VWEVMS_INTWK_EN VWEVMS_INT_EN - -/* eSPI max supported frequency */ -enum { - NPCX_ESPI_MAXFREQ_20 = 0, - NPCX_ESPI_MAXFREQ_25 = 1, - NPCX_ESPI_MAXFREQ_33 = 2, - NPCX_ESPI_MAXFREQ_50 = 3, - NPCX_ESPI_MAXFREQ_66 = 4, - NPCX_ESPI_MAXFREQ_NONE = 0xFF -}; - -/* eSPI max frequency support per FMCLK */ -#if (FMCLK <= 33000000) -#define NPCX_ESPI_MAXFREQ_MAX NPCX_ESPI_MAXFREQ_33 -#elif (FMCLK <= 48000000) -#define NPCX_ESPI_MAXFREQ_MAX NPCX_ESPI_MAXFREQ_50 -#else -#define NPCX_ESPI_MAXFREQ_MAX NPCX_ESPI_MAXFREQ_66 -#endif - -/* MIWU registers */ -#define NPCX_WKEDG_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x00 + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x1E)) -#define NPCX_WKAEDG_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x01 + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x1E)) -#define NPCX_WKPND_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x0A + \ - ((n) * 4L) + ((n) < 5 ? 0 : 0x10)) -#define NPCX_WKPCL_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x0C + \ - ((n) * 4L) + ((n) < 5 ? 0 : 0x10)) -#define NPCX_WKEN_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x1E + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x12)) -#define NPCX_WKINEN_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x1F + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x12)) -#define NPCX_WKMOD_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x70 + (n)) - -#define NPCX_WKEDG(port, n) REG8(NPCX_WKEDG_ADDR(port, n)) -#define NPCX_WKAEDG(port, n) REG8(NPCX_WKAEDG_ADDR(port, n)) -#define NPCX_WKPND(port, n) REG8(NPCX_WKPND_ADDR(port, n)) -#define NPCX_WKPCL(port, n) REG8(NPCX_WKPCL_ADDR(port, n)) -#define NPCX_WKEN(port, n) REG8(NPCX_WKEN_ADDR(port, n)) -#define NPCX_WKINEN(port, n) REG8(NPCX_WKINEN_ADDR(port, n)) -#define NPCX_WKMOD(port, n) REG8(NPCX_WKMOD_ADDR(port, n)) - -/* UART registers and functions */ -#if NPCX_UART_MODULE2 -/* - * To be used as 2nd parameter to NPCX_WK*() macro, table (1st parameter) is - * always 1 == MIWU_TABLE_1. - */ -#define NPCX_UART_WK_GROUP 6 -#define NPCX_UART_WK_BIT 4 -#define NPCX_UART_MIWU_IRQ NPCX_IRQ_WKINTG_1 -#define NPCX_UART_DEVALT NPCX_DEVALT(0x0C) -#define NPCX_UART_DEVALT_SL NPCX_DEVALTC_UART_SL2 -#define NPCX_UART_ALT_DEVALT NPCX_DEVALT(0x0A) -#define NPCX_UART_ALT_DEVALT_SL NPCX_DEVALTA_UART_SL1 -#else /* !NPCX_UART_MODULE2 */ - -#define NPCX_UART_WK_GROUP 1 -#define NPCX_UART_WK_BIT 0 -#define NPCX_UART_MIWU_IRQ NPCX_IRQ_WKINTB_1 -#define NPCX_UART_DEVALT NPCX_DEVALT(0x0A) -#define NPCX_UART_DEVALT_SL NPCX_DEVALTA_UART_SL1 -#define NPCX_UART_ALT_DEVALT NPCX_DEVALT(0x0C) -#define NPCX_UART_ALT_DEVALT_SL NPCX_DEVALTC_UART_SL2 -#endif /* NPCX_UART_MODULE2 */ - -/* This routine checks pending bit of GPIO wake-up functionality */ -static inline int uart_is_wakeup_from_gpio(void) -{ - return IS_BIT_SET(NPCX_WKPND(1, NPCX_UART_WK_GROUP), NPCX_UART_WK_BIT); -} - -/* This routine checks wake-up functionality from GPIO is enabled or not */ -static inline int uart_is_enable_wakeup(void) -{ - return IS_BIT_SET(NPCX_WKEN(1, NPCX_UART_WK_GROUP), NPCX_UART_WK_BIT); -} - -/* This routine clears the pending wake-up from GPIO on UART rx pin */ -static inline void uart_clear_pending_wakeup(void) -{ - SET_BIT(NPCX_WKPCL(1, NPCX_UART_WK_GROUP), NPCX_UART_WK_BIT); -} - -/* This routine enables wake-up functionality from GPIO on UART rx pin */ -static inline void uart_enable_wakeup(int enable) -{ - UPDATE_BIT(NPCX_WKEN(1, NPCX_UART_WK_GROUP), NPCX_UART_WK_BIT, - enable); -} - -/* This routine checks functionality is UART rx or not */ -static inline int npcx_is_uart(void) -{ - return IS_BIT_SET(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SL); -} - -/* ADC Registers */ -#define NPCX_ADCSTS REG16(NPCX_ADC_BASE_ADDR + 0x000) -#define NPCX_ADCCNF REG16(NPCX_ADC_BASE_ADDR + 0x002) -#define NPCX_ATCTL REG16(NPCX_ADC_BASE_ADDR + 0x004) -#define NPCX_ASCADD REG16(NPCX_ADC_BASE_ADDR + 0x006) -#define NPCX_ADCCS REG16(NPCX_ADC_BASE_ADDR + 0x008) -/* NOTE: These are 1-based for the threshold detectors. */ -#define NPCX_THRCTL(n) REG16(NPCX_ADC_BASE_ADDR + 0x012 + (2L*(n))) -#define NPCX_THRCTS REG16(NPCX_ADC_BASE_ADDR + 0x01A) -#define NPCX_THR_DCTL(n) REG16(NPCX_ADC_BASE_ADDR + 0x038 + (2L*(n))) -/* NOTE: This is 0-based for the ADC channels. */ -#define NPCX_CHNDAT(n) REG16(NPCX_ADC_BASE_ADDR + 0x040 + (2L*(n))) -#define NPCX_ADCCNF2 REG16(NPCX_ADC_BASE_ADDR + 0x020) -#define NPCX_GENDLY REG16(NPCX_ADC_BASE_ADDR + 0x022) -#define NPCX_MEAST REG16(NPCX_ADC_BASE_ADDR + 0x026) - -/* ADC register fields */ -#define NPCX_ATCTL_SCLKDIV_FIELD FIELD(0, 6) -#define NPCX_ATCTL_DLY_FIELD FIELD(8, 3) -#define NPCX_ASCADD_SADDR_FIELD FIELD(0, 5) -#define NPCX_ADCSTS_EOCEV 0 -#define NPCX_ADCCNF_ADCMD_FIELD FIELD(1, 2) -#define NPCX_ADCCNF_ADCRPTC 3 -#define NPCX_ADCCNF_INTECEN 6 -#define NPCX_ADCCNF_START 4 -#define NPCX_ADCCNF_ADCEN 0 -#define NPCX_ADCCNF_STOP 11 -#define NPCX_CHNDAT_CHDAT_FIELD FIELD(0, 10) -#define NPCX_CHNDAT_NEW 15 -#define NPCX_THRCTL_THEN 15 -#define NPCX_THRCTL_L_H 14 -#define NPCX_THRCTL_CHNSEL FIELD(10, 4) -#define NPCX_THRCTL_THRVAL FIELD(0, 10) -#define NPCX_THRCTS_ADC_WKEN 15 -#define NPCX_THRCTS_THR3_IEN 10 -#define NPCX_THRCTS_THR2_IEN 9 -#define NPCX_THRCTS_THR1_IEN 8 -#define NPCX_THRCTS_ADC_EVENT 7 -#define NPCX_THRCTS_THR3_STS 2 -#define NPCX_THRCTS_THR2_STS 1 -#define NPCX_THRCTS_THR1_STS 0 -#define NPCX_THR_DCTL_THRD_EN 15 -#define NPCX_THR_DCTL_THR_DVAL FIELD(0, 10) - -#define NPCX_ADC_THRESH1 1 -#define NPCX_ADC_THRESH2 2 -#define NPCX_ADC_THRESH3 3 -#define NPCX_ADC_THRESH_CNT 3 diff --git a/chip/npcx/registers-npcx7.h b/chip/npcx/registers-npcx7.h deleted file mode 100644 index 535abfbf0f..0000000000 --- a/chip/npcx/registers-npcx7.h +++ /dev/null @@ -1,571 +0,0 @@ -/* Copyright 2020 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. - */ - -/* - * Specific register map for NPCX7 family of chips. - * - * Support chip variant: - * - npcx7m6g - * - npcx7m6f - * - npcx7m6fb - * - npcx7m6fc - * - npcx7m7fc - * - npcx7m7wb - * - npcx7m7wc - * - * This header file should not be included directly. - * Please include registers.h instead. - */ - -#ifndef __CROS_EC_REGISTERS_H -#error "This header file should not be included directly." -#endif - -/* NPCX-IRQ numbers */ -#define NPCX_IRQ0_NOUSED NPCX_IRQ_0 -#define NPCX_IRQ1_NOUSED NPCX_IRQ_1 -#define NPCX_IRQ_KBSCAN NPCX_IRQ_2 -#define NPCX_IRQ_PM_CHAN_OBE NPCX_IRQ_3 -#ifdef NPCX_WOV_SUPPORT -#define NPCX_IRQ4_NOUSED NPCX_IRQ_4 -#else -#define NPCX_IRQ_PECI NPCX_IRQ_4 -#endif -#define NPCX_IRQ5_NOUSED NPCX_IRQ_5 -#define NPCX_IRQ_PORT80 NPCX_IRQ_6 -#define NPCX_IRQ_MTC_WKINTAD_0 NPCX_IRQ_7 -#define NPCX_IRQ_MTC NPCX_IRQ_MTC_WKINTAD_0 -#define NPCX_IRQ_SMB8 NPCX_IRQ_8 -#define NPCX_IRQ_MFT_1 NPCX_IRQ_9 -#define NPCX_IRQ_ADC NPCX_IRQ_10 -#define NPCX_IRQ_WKINTEFGH_0 NPCX_IRQ_11 -#define NPCX_IRQ_GDMA NPCX_IRQ_12 -#define NPCX_IRQ_SMB1 NPCX_IRQ_13 -#define NPCX_IRQ_SMB2 NPCX_IRQ_14 -#define NPCX_IRQ_WKINTC_0 NPCX_IRQ_15 -#define NPCX_IRQ_SMB7 NPCX_IRQ_16 -#define NPCX_IRQ_ITIM16_3 NPCX_IRQ_17 -#define NPCX_IRQ_SHI NPCX_IRQ_18 -#define NPCX_IRQ_ESPI NPCX_IRQ_18 -#define NPCX_IRQ_SMB5 NPCX_IRQ_19 -#define NPCX_IRQ_SMB6 NPCX_IRQ_20 -#define NPCX_IRQ_PS2 NPCX_IRQ_21 -#ifdef NPCX_WOV_SUPPORT -#define NPCX_IRQ_WOV NPCX_IRQ_22 -#else -#define NPCX_IRQ22_NOUSED NPCX_IRQ_22 -#endif -#define NPCX_IRQ_MFT_2 NPCX_IRQ_23 -#define NPCX_IRQ_SHM NPCX_IRQ_24 -#define NPCX_IRQ_KBC_IBF NPCX_IRQ_25 -#define NPCX_IRQ_PM_CHAN_IBF NPCX_IRQ_26 -#define NPCX_IRQ_ITIM16_2 NPCX_IRQ_27 -#define NPCX_IRQ_ITIM16_1 NPCX_IRQ_28 -#define NPCX_IRQ29_NOUSED NPCX_IRQ_29 -#define NPCX_IRQ30_NOUSED NPCX_IRQ_30 -#define NPCX_IRQ_TWD_WKINTB_0 NPCX_IRQ_31 -#define NPCX_IRQ_UART2 NPCX_IRQ_32 -#define NPCX_IRQ_UART NPCX_IRQ_33 -#define NPCX_IRQ34_NOUSED NPCX_IRQ_34 -#define NPCX_IRQ35_NOUSED NPCX_IRQ_35 -#define NPCX_IRQ_SMB3 NPCX_IRQ_36 -#define NPCX_IRQ_SMB4 NPCX_IRQ_37 -#define NPCX_IRQ38_NOUSED NPCX_IRQ_38 -#define NPCX_IRQ39_NOUSED NPCX_IRQ_39 -#define NPCX_IRQ40_NOUSED NPCX_IRQ_40 -#define NPCX_IRQ_MFT_3 NPCX_IRQ_41 -#define NPCX_IRQ42_NOUSED NPCX_IRQ_42 -#define NPCX_IRQ_ITIM16_4 NPCX_IRQ_43 -#define NPCX_IRQ_ITIM16_5 NPCX_IRQ_44 -#define NPCX_IRQ_ITIM16_6 NPCX_IRQ_45 -#define NPCX_IRQ_ITIM32 NPCX_IRQ_46 -#define NPCX_IRQ_WKINTA_1 NPCX_IRQ_47 -#define NPCX_IRQ_WKINTB_1 NPCX_IRQ_48 -#define NPCX_IRQ_KSI_WKINTC_1 NPCX_IRQ_49 -#define NPCX_IRQ_WKINTD_1 NPCX_IRQ_50 -#define NPCX_IRQ_WKINTE_1 NPCX_IRQ_51 -#define NPCX_IRQ_WKINTF_1 NPCX_IRQ_52 -#define NPCX_IRQ_WKINTG_1 NPCX_IRQ_53 -#define NPCX_IRQ_WKINTH_1 NPCX_IRQ_54 -#define NPCX_IRQ55_NOUSED NPCX_IRQ_55 -#define NPCX_IRQ_KBC_OBE NPCX_IRQ_56 -#define NPCX_IRQ_SPI NPCX_IRQ_57 -#ifdef NPCX_ITIM64_SUPPORT -#define NPCX_IRQ_ITIM64 NPCX_IRQ_58 -#else -#define NPCX_IRQ58_NOUSED NPCX_IRQ_58 -#endif -#define NPCX_IRQ_WKINTFG_2 NPCX_IRQ_59 -#define NPCX_IRQ_WKINTA_2 NPCX_IRQ_60 -#define NPCX_IRQ_WKINTB_2 NPCX_IRQ_61 -#define NPCX_IRQ_WKINTC_2 NPCX_IRQ_62 -#define NPCX_IRQ_WKINTD_2 NPCX_IRQ_63 - -/* Modules Map */ - -/* Miscellaneous Device Control (MDC) registers */ -#define NPCX_FWCTRL REG8(NPCX_MDC_BASE_ADDR + 0x007) - -/* MDC register fields */ -#define NPCX_FWCTRL_RO_REGION 0 -#define NPCX_FWCTRL_FW_SLOT 1 - -#define NPCX_ITIM32_BASE_ADDR 0x400BC000 -#define NPCX_CR_UART_BASE_ADDR(mdl) (0x400C4000 + ((mdl) * 0x2000L)) -#define NPCX_SMB_BASE_ADDR(mdl) (((mdl) < 2) ? \ - (0x40009000 + ((mdl) * 0x2000L)) : \ - ((mdl) < 4) ? \ - (0x400C0000 + (((mdl) - 2) * 0x2000L)) : \ - ((mdl) == 4) ? \ - (0x40008000) : \ - (0x40017000 + (((mdl) - 5) * 0x1000L))) - -#define NPCX_HFCBCD1 REG8(NPCX_HFCG_BASE_ADDR + 0x012) -#define NPCX_HFCBCD2 REG8(NPCX_HFCG_BASE_ADDR + 0x014) - -enum { - NPCX_UART_PORT0 = 0, /* UART port 0 */ -#ifdef NPCX_SECOND_UART - NPCX_UART_PORT1 = 1, /* UART port 1 */ -#endif - NPCX_UART_COUNT -}; - -#ifdef NPCX_UART_FIFO_SUPPORT -/* UART registers only used for FIFO mode */ -#define NPCX_UFTSTS(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x020) -#define NPCX_UFRSTS(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x022) -#define NPCX_UFTCTL(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x024) -#define NPCX_UFRCTL(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x026) - -/* UART FIFO register fields */ -#define NPCX_UMDSL_FIFO_MD 0 - -#define NPCX_UFTSTS_TEMPTY_LVL FIELD(0, 5) -#define NPCX_UFTSTS_TEMPTY_LVL_STS 5 -#define NPCX_UFTSTS_TFIFO_EMPTY_STS 6 -#define NPCX_UFTSTS_NXMIP 7 - -#define NPCX_UFRSTS_RFULL_LVL_STS 5 -#define NPCX_UFRSTS_RFIFO_NEMPTY_STS 6 -#define NPCX_UFRSTS_ERR 7 - -#define NPCX_UFTCTL_TEMPTY_LVL_SEL FIELD(0, 5) -#define NPCX_UFTCTL_TEMPTY_LVL_EN 5 -#define NPCX_UFTCTL_TEMPTY_EN 6 -#define NPCX_UFTCTL_NXMIPEN 7 - -#define NPCX_UFRCTL_RFULL_LVL_SEL FIELD(0, 5) -#define NPCX_UFRCTL_RFULL_LVL_EN 5 -#define NPCX_UFRCTL_RNEMPTY_EN 6 -#define NPCX_UFRCTL_ERR_EN 7 -#endif - -/* KBSCAN register fields */ -#define NPCX_KBHDRV_FIELD FIELD(6, 2) - -/* GLUE registers */ -#ifdef NPCX_PSL_MODE_SUPPORT -#define NPCX_GLUE_PSL_CTS REG8(NPCX_GLUE_REGS_BASE + 0x027) -#endif - -/* GPIO registers */ -#define NPCX_PLOCK_CTL(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x007) - -/* System Configuration (SCFG) Registers */ - -/* SCFG enumeration */ -enum { - ALT_GROUP_0, - ALT_GROUP_1, - ALT_GROUP_2, - ALT_GROUP_3, - ALT_GROUP_4, - ALT_GROUP_5, - ALT_GROUP_6, - ALT_GROUP_7, - ALT_GROUP_8, - ALT_GROUP_9, - ALT_GROUP_A, - ALT_GROUP_B, - ALT_GROUP_C, - ALT_GROUP_D, - ALT_GROUP_E, - ALT_GROUP_F, - ALT_GROUP_COUNT -}; - -#define NPCX_DEVALT(n) REG8(NPCX_SCFG_BASE_ADDR + 0x010 + (n)) - -#define NPCX_LV_GPIO_CTL_ADDR(n) (((n) < 5) ? \ - (NPCX_SCFG_BASE_ADDR + 0x02A + (n)) :\ - (NPCX_SCFG_BASE_ADDR + 0x026)) -#define NPCX_LV_GPIO_CTL(n) REG8(NPCX_LV_GPIO_CTL_ADDR(n)) - -/* pin-mux for I2C */ -#define NPCX_DEVALT2_I2C0_0_SL 0 -#define NPCX_DEVALT2_I2C7_0_SL 1 -#define NPCX_DEVALT2_I2C1_0_SL 2 -#define NPCX_DEVALT2_I2C6_0_SL 3 -#define NPCX_DEVALT2_I2C2_0_SL 4 -#define NPCX_DEVALT2_I2C5_0_SL 5 -#define NPCX_DEVALT2_I2C3_0_SL 6 -#define NPCX_DEVALT2_I2C4_0_SL 7 -#define NPCX_DEVALT6_I2C6_1_SL 5 -#define NPCX_DEVALT6_I2C5_1_SL 6 -#define NPCX_DEVALT6_I2C4_1_SL 7 - -/* pin-mux for JTAG */ -#define NPCX_DEVALT5_NJEN1_EN 1 -#define NPCX_DEVALT5_NJEN0_EN 2 - -/* pin-mux for ADC */ -#define NPCX_DEVALTF_ADC5_SL 0 -#define NPCX_DEVALTF_ADC6_SL 1 -#define NPCX_DEVALTF_ADC7_SL 2 -#define NPCX_DEVALTF_ADC8_SL 3 -#define NPCX_DEVALTF_ADC9_SL 4 - -/* pin-mux for PSL */ -#ifdef NPCX_PSL_MODE_SUPPORT -#define NPCX_DEVALTD_PSL_IN1_AHI 0 -#define NPCX_DEVALTD_NPSL_IN1_SL 1 -#define NPCX_DEVALTD_PSL_IN2_AHI 2 -#define NPCX_DEVALTD_NPSL_IN2_SL 3 -#define NPCX_DEVALTD_PSL_IN3_AHI 4 -#define NPCX_DEVALTD_PSL_IN3_SL 5 -#define NPCX_DEVALTD_PSL_IN4_AHI 6 -#define NPCX_DEVALTD_PSL_IN4_SL 7 -#endif - -#ifdef CHIP_VARIANT_NPCX7M6G -/* External 32KHz crytal osc. input support */ -#define NPCX_DEVALTA_32KCLKIN_SL 3 -#endif - -/* pin-mux for UART */ -#define NPCX_DEVALTA_UART_SL1 7 -#define NPCX_DEVALTC_UART_SL2 0 -#ifdef NPCX_SECOND_UART -/* Secondary UART selection */ -#define NPCX_DEVALTA_UART2_SL 5 -#endif - -/* SHI module version 2 enable bit */ -#define NPCX_DEVALTF_SHI_NEW 7 - -#ifdef NPCX_WOV_SUPPORT -/* pin-mux for WoV */ -#define NPCX_DEVALTE_WOV_SL 0 -#define NPCX_DEVALTE_I2S_SL 1 -#define NPCX_DEVALTE_DMCLK_FAST 2 -#endif - -/* SMBus register fields */ -#define NPCX_SMBSEL_SMB4SEL 4 -#define NPCX_SMBSEL_SMB5SEL 5 -#define NPCX_SMBSEL_SMB6SEL 6 - -/* SMB enumeration: I2C port definitions */ -enum { - NPCX_I2C_PORT0_0 = 0, /* I2C port 0, bus 0 */ - NPCX_I2C_PORT1_0, /* I2C port 1, bus 0 */ - NPCX_I2C_PORT2_0, /* I2C port 2, bus 0 */ - NPCX_I2C_PORT3_0, /* I2C port 3, bus 0 */ -#ifdef CHIP_VARIANT_NPCX7M6G - NPCX_I2C_PORT4_0, /* I2C port 4, bus 0 */ -#endif - NPCX_I2C_PORT4_1, /* I2C port 4, bus 1 */ - NPCX_I2C_PORT5_0, /* I2C port 5, bus 0 */ - NPCX_I2C_PORT5_1, /* I2C port 5, bus 1 */ - NPCX_I2C_PORT6_0, /* I2C port 6, bus 0 */ - NPCX_I2C_PORT6_1, /* I2C port 6, bus 1 */ - NPCX_I2C_PORT7_0, /* I2C port 7, bus 0 */ - NPCX_I2C_COUNT, -}; - -/* Power Management Controller (PMC) Registers */ -#define NPCX_FMUL_WIN_DLY REG8(NPCX_PMC_BASE_ADDR + 0x010) -#define NPCX_RAM_PD(offset) REG8(NPCX_PMC_BASE_ADDR + 0x020 + (offset)) - -/* PMC register fields */ -#define NPCX_PWDWN_CTL3_SMB4_PD 4 -#define NPCX_PWDWN_CTL7_SMB5_PD 0 -#define NPCX_PWDWN_CTL7_SMB6_PD 1 -#define NPCX_PWDWN_CTL7_SMB7_PD 2 -#ifdef NPCX_ITIM64_SUPPORT -#define NPCX_PWDWN_CTL7_ITIM64_PD 5 -#endif -#ifdef NPCX_SECOND_UART -#define NPCX_PWDWN_CTL7_UART2_PD 6 -#endif -#ifdef NPCX_WOV_SUPPORT -#define NPCX_PWDWN_CTL7_WOV_PD 7 -#endif - -/* - * PMC enumeration: - * Offsets from CGC_BASE registers for each peripheral. - */ -enum { - CGC_OFFSET_KBS = 0, - CGC_OFFSET_UART = 0, - CGC_OFFSET_FAN = 0, - CGC_OFFSET_FIU = 0, - CGC_OFFSET_PS2 = 0, - CGC_OFFSET_PWM = 1, - CGC_OFFSET_I2C = 2, - CGC_OFFSET_ADC = 3, - CGC_OFFSET_PECI = 3, - CGC_OFFSET_SPI = 3, - CGC_OFFSET_TIMER = 3, - CGC_OFFSET_LPC = 4, - CGC_OFFSET_ESPI = 5, - CGC_OFFSET_I2C2 = 6, -#ifdef NPCX_SECOND_UART - CGC_OFFSET_UART2 = 6, -#endif -#ifdef NPCX_WOV_SUPPORT - CGC_OFFSET_WOV = 6, -#endif -}; - -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, -}; - -#define CGC_I2C_MASK (BIT(NPCX_PWDWN_CTL3_SMB0_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB1_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB2_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB3_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB4_PD)) -#define CGC_I2C_MASK2 (BIT(NPCX_PWDWN_CTL7_SMB5_PD) | \ - BIT(NPCX_PWDWN_CTL7_SMB6_PD) | \ - BIT(NPCX_PWDWN_CTL7_SMB7_PD)) -#ifdef NPCX_SECOND_UART -#define CGC_UART2_MASK BIT(NPCX_PWDWN_CTL7_UART2_PD) -#endif -#ifdef NPCX_WOV_SUPPORT -#define CGC_WOV_MASK BIT(NPCX_PWDWN_CTL7_WOV_PD) -#endif - -/* BBRAM register fields */ -#if defined(CHIP_VARIANT_NPCX7M6FB) || defined(CHIP_VARIANT_NPCX7M6FC) || \ - defined(CHIP_VARIANT_NPCX7M7FC) || defined(CHIP_VARIANT_NPCX7M7WB) || \ - defined(CHIP_VARIANT_NPCX7M7WC) -#define NPCX_BKUP_STS_VSBY_STS 1 -#define NPCX_BKUP_STS_VCC1_STS 0 -#define NPCX_BKUP_STS_ALL_MASK \ - (BIT(NPCX_BKUP_STS_IBBR) | BIT(NPCX_BKUP_STS_VSBY_STS) | \ - BIT(NPCX_BKUP_STS_VCC1_STS)) -#define NPCX_BBRAM_SIZE 128 /* Size of BBRAM */ -#else -#define NPCX_BKUP_STS_ALL_MASK BIT(NPCX_BKUP_STS_IBBR) -#define NPCX_BBRAM_SIZE 64 /* Size of BBRAM */ -#endif - -/* ITIM16 registers */ -#define NPCX_ITCNT8(n) REG8(NPCX_ITIM_BASE_ADDR(n) + 0x000) -#define NPCX_ITCNT16(n) REG16(NPCX_ITIM_BASE_ADDR(n) + 0x002) -/* ITIM32 registers */ -#define NPCX_ITCNT32 REG32(NPCX_ITIM32_BASE_ADDR + 0x008) - -/* Timer counter register used for 1 micro-second system tick */ -#define NPCX_ITCNT_SYSTEM NPCX_ITCNT32 -/* Timer counter register used for others */ -#define NPCX_ITCNT NPCX_ITCNT16 - -/* ITIM module No. used for event */ -#define ITIM_EVENT_NO ITIM16_1 -/* ITIM module No. used for watchdog */ -#define ITIM_WDG_NO ITIM16_5 -/* ITIM module No. used for 1 micro-second system tick */ -#define ITIM_SYSTEM_NO ITIM32 - -/* ITIM enumeration */ -enum ITIM_MODULE_T { - ITIM16_1, - ITIM16_2, - ITIM16_3, - ITIM16_4, - ITIM16_5, - ITIM16_6, - ITIM32, - ITIM_MODULE_COUNT, -}; - -/* Serial Host Interface (SHI) Registers - only available on SHI Version 2 */ -#define NPCX_SHICFG3 REG8(NPCX_SHI_BASE_ADDR + 0x00C) -#define NPCX_SHICFG4 REG8(NPCX_SHI_BASE_ADDR + 0x00D) -#define NPCX_SHICFG5 REG8(NPCX_SHI_BASE_ADDR + 0x00E) -#define NPCX_EVSTAT2 REG8(NPCX_SHI_BASE_ADDR + 0x00F) -#define NPCX_EVENABLE2 REG8(NPCX_SHI_BASE_ADDR + 0x010) -#define NPCX_OBUF(n) REG8(NPCX_SHI_BASE_ADDR + 0x020 + (n)) -#define NPCX_IBUF(n) REG8(NPCX_SHI_BASE_ADDR + 0x0A0 + (n)) - -/* SHI register fields */ -#define NPCX_SHICFG3_OBUFLVLDIS 7 -#define NPCX_SHICFG4_IBUFLVLDIS 7 -#define NPCX_SHICFG5_IBUFLVL2 FIELD(0, 6) -#define NPCX_SHICFG5_IBUFLVL2DIS 7 -#define NPCX_EVSTAT2_IBHF2 0 -#define NPCX_EVSTAT2_CSNRE 1 -#define NPCX_EVSTAT2_CSNFE 2 -#define NPCX_EVENABLE2_IBHF2EN 0 -#define NPCX_EVENABLE2_CSNREEN 1 -#define NPCX_EVENABLE2_CSNFEEN 2 - -/* eSPI register fields */ -#define NPCX_ESPIIE_BMTXDONEIE 19 -#define NPCX_ESPIIE_PBMRXIE 20 -#define NPCX_ESPIIE_PMSGRXIE 21 -#define NPCX_ESPIIE_BMBURSTERRIE 22 -#define NPCX_ESPIIE_BMBURSTDONEIE 23 - -#define NPCX_ESPIWE_PBMRXWE 20 -#define NPCX_ESPIWE_PMSGRXWE 21 - -#define NPCX_ESPISTS_VWUPDW 17 -#define NPCX_ESPISTS_BMTXDONE 19 -#define NPCX_ESPISTS_PBMRX 20 -#define NPCX_ESPISTS_PMSGRX 21 -#define NPCX_ESPISTS_BMBURSTERR 22 -#define NPCX_ESPISTS_BMBURSTDONE 23 -#define NPCX_ESPISTS_ESPIRST_LVL 24 - -#define ESPIIE_BMTXDONE BIT(NPCX_ESPIIE_BMTXDONEIE) -#define ESPIIE_PBMRX BIT(NPCX_ESPIIE_PBMRXIE) -#define ESPIIE_PMSGRX BIT(NPCX_ESPIIE_PMSGRXIE) -#define ESPIIE_BMBURSTERR BIT(NPCX_ESPIIE_BMBURSTERRIE) -#define ESPIIE_BMBURSTDONE BIT(NPCX_ESPIIE_BMBURSTDONEIE) - -#define ESPIWE_PBMRX BIT(NPCX_ESPIWE_PBMRXWE) -#define ESPIWE_PMSGRX BIT(NPCX_ESPIWE_PMSGRXWE) - -/* Bit field manipulation for VWEVMS Value */ -#define VWEVMS_WK_EN(e) (((e)<<20) & 0x00100000) -#define VWEVMS_INTWK_EN(e) (VWEVMS_INT_EN(e) | VWEVMS_WK_EN(e)) - -/* eSPI max supported frequency */ -enum { - NPCX_ESPI_MAXFREQ_20 = 0, - NPCX_ESPI_MAXFREQ_25 = 1, - NPCX_ESPI_MAXFREQ_33 = 2, - NPCX_ESPI_MAXFREQ_50 = 3, - NPCX_ESPI_MAXFREQ_NONE = 0xFF -}; - -/* eSPI max frequency support per FMCLK */ -#if (FMCLK <= 33000000) -#define NPCX_ESPI_MAXFREQ_MAX NPCX_ESPI_MAXFREQ_33 -#else -#define NPCX_ESPI_MAXFREQ_MAX NPCX_ESPI_MAXFREQ_50 -#endif - -/* UART registers */ -#define NPCX_UART_WK_GROUP MIWU_GROUP_8 -#define NPCX_UART_WK_BIT 7 -#ifdef NPCX_SECOND_UART -#define NPCX_UART2_WK_GROUP MIWU_GROUP_1 -#define NPCX_UART2_WK_BIT 6 -#endif - -/* MIWU registers */ -#define NPCX_WKEDG_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x00 + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x1E)) -#define NPCX_WKAEDG_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x01 + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x1E)) -#define NPCX_WKPND_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x0A + \ - ((n) * 4L) + ((n) < 5 ? 0 : 0x10)) -#define NPCX_WKPCL_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x0C + \ - ((n) * 4L) + ((n) < 5 ? 0 : 0x10)) -#define NPCX_WKEN_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x1E + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x12)) -#define NPCX_WKINEN_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x1F + \ - ((n) * 2L) + ((n) < 5 ? 0 : 0x12)) -#define NPCX_WKMOD_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x70 + (n)) - -#define NPCX_WKEDG(port, n) REG8(NPCX_WKEDG_ADDR(port, n)) -#define NPCX_WKAEDG(port, n) REG8(NPCX_WKAEDG_ADDR(port, n)) -#define NPCX_WKPND(port, n) REG8(NPCX_WKPND_ADDR(port, n)) -#define NPCX_WKPCL(port, n) REG8(NPCX_WKPCL_ADDR(port, n)) -#define NPCX_WKEN(port, n) REG8(NPCX_WKEN_ADDR(port, n)) -#define NPCX_WKINEN(port, n) REG8(NPCX_WKINEN_ADDR(port, n)) -#define NPCX_WKMOD(port, n) REG8(NPCX_WKMOD_ADDR(port, n)) - -/* UART registers and functions */ -#if NPCX_UART_MODULE2 -/* - * To be used as 2nd parameter to NPCX_WK*() macro, table (1st parameter) is - * always 1 == MIWU_TABLE_1. - */ -#define NPCX_UART_MIWU_IRQ NPCX_IRQ_WKINTG_1 -#define NPCX_UART_DEVALT NPCX_DEVALT(0x0C) -#define NPCX_UART_DEVALT_SL NPCX_DEVALTC_UART_SL2 -#define NPCX_UART_ALT_DEVALT NPCX_DEVALT(0x0A) -#define NPCX_UART_ALT_DEVALT_SL NPCX_DEVALTA_UART_SL1 -#else /* !NPCX_UART_MODULE2 */ -#define NPCX_UART_MIWU_IRQ NPCX_IRQ_WKINTB_1 -#define NPCX_UART_DEVALT NPCX_DEVALT(0x0A) -#define NPCX_UART_DEVALT_SL NPCX_DEVALTA_UART_SL1 -#define NPCX_UART_ALT_DEVALT NPCX_DEVALT(0x0C) -#define NPCX_UART_ALT_DEVALT_SL NPCX_DEVALTC_UART_SL2 -#endif /* NPCX_UART_MODULE2 */ - -/* ADC Registers */ -#define NPCX_ADCSTS REG16(NPCX_ADC_BASE_ADDR + 0x000) -#define NPCX_ADCCNF REG16(NPCX_ADC_BASE_ADDR + 0x002) -#define NPCX_ATCTL REG16(NPCX_ADC_BASE_ADDR + 0x004) -#define NPCX_ASCADD REG16(NPCX_ADC_BASE_ADDR + 0x006) -#define NPCX_ADCCS REG16(NPCX_ADC_BASE_ADDR + 0x008) -/* NOTE: These are 1-based for the threshold detectors. */ -#define NPCX_THRCTL(n) REG16(NPCX_ADC_BASE_ADDR + 0x012 + (2L*(n))) -#define NPCX_THRCTS REG16(NPCX_ADC_BASE_ADDR + 0x01A) -#define NPCX_THR_DCTL(n) REG16(NPCX_ADC_BASE_ADDR + 0x038 + (2L*(n))) -/* NOTE: This is 0-based for the ADC channels. */ -#define NPCX_CHNDAT(n) REG16(NPCX_ADC_BASE_ADDR + 0x040 + (2L*(n))) -#define NPCX_ADCCNF2 REG16(NPCX_ADC_BASE_ADDR + 0x020) -#define NPCX_GENDLY REG16(NPCX_ADC_BASE_ADDR + 0x022) -#define NPCX_MEAST REG16(NPCX_ADC_BASE_ADDR + 0x026) - -/* ADC register fields */ -#define NPCX_ATCTL_SCLKDIV_FIELD FIELD(0, 6) -#define NPCX_ATCTL_DLY_FIELD FIELD(8, 3) -#define NPCX_ASCADD_SADDR_FIELD FIELD(0, 5) -#define NPCX_ADCSTS_EOCEV 0 -#define NPCX_ADCCNF_ADCMD_FIELD FIELD(1, 2) -#define NPCX_ADCCNF_ADCRPTC 3 -#define NPCX_ADCCNF_INTECEN 6 -#define NPCX_ADCCNF_START 4 -#define NPCX_ADCCNF_ADCEN 0 -#define NPCX_ADCCNF_STOP 11 -#define NPCX_CHNDAT_CHDAT_FIELD FIELD(0, 10) -#define NPCX_CHNDAT_NEW 15 -#define NPCX_THRCTL_THEN 15 -#define NPCX_THRCTL_L_H 14 -#define NPCX_THRCTL_CHNSEL FIELD(10, 4) -#define NPCX_THRCTL_THRVAL FIELD(0, 10) -#define NPCX_THRCTS_ADC_WKEN 15 -#define NPCX_THRCTS_THR3_IEN 10 -#define NPCX_THRCTS_THR2_IEN 9 -#define NPCX_THRCTS_THR1_IEN 8 -#define NPCX_THRCTS_ADC_EVENT 7 -#define NPCX_THRCTS_THR3_STS 2 -#define NPCX_THRCTS_THR2_STS 1 -#define NPCX_THRCTS_THR1_STS 0 -#define NPCX_THR_DCTL_THRD_EN 15 -#define NPCX_THR_DCTL_THR_DVAL FIELD(0, 10) - -#define NPCX_ADC_THRESH1 1 -#define NPCX_ADC_THRESH2 2 -#define NPCX_ADC_THRESH3 3 -#define NPCX_ADC_THRESH_CNT 3 diff --git a/chip/npcx/registers-npcx9.h b/chip/npcx/registers-npcx9.h deleted file mode 100644 index 1d2a02084c..0000000000 --- a/chip/npcx/registers-npcx9.h +++ /dev/null @@ -1,583 +0,0 @@ -/* Copyright 2020 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. - */ - -/* - * Specific register map for NPCX9 family of chips. - * - * Support chip variant: - * - npcx993f - * - npcx996f - * - * This header file should not be included directly. - * Please include registers.h instead. - */ - -#ifndef __CROS_EC_REGISTERS_H -#error "This header file should not be included directly." -#endif - -/* NPCX-IRQ numbers */ -#define NPCX_IRQ0_NOUSED NPCX_IRQ_0 -#define NPCX_IRQ1_NOUSED NPCX_IRQ_1 -#define NPCX_IRQ_KBSCAN NPCX_IRQ_2 -#define NPCX_IRQ_PM_CHAN_OBE NPCX_IRQ_3 -#define NPCX_IRQ_PECI NPCX_IRQ_4 -#define NPCX_IRQ_MTC_WKINTD_0 NPCX_IRQ_5 -#define NPCX_IRQ_MTC NPCX_IRQ_MTC_WKINTD_0 -#define NPCX_IRQ_PORT80 NPCX_IRQ_6 -#define NPCX_IRQ_CR_SIN2_WKINTA_0 NPCX_IRQ_7 -#define NPCX_IRQ_SMB8 NPCX_IRQ_8 -#define NPCX_IRQ_MFT_1 NPCX_IRQ_9 -#define NPCX_IRQ_ADC NPCX_IRQ_10 -#define NPCX_IRQ_WKINTE_0 NPCX_IRQ_11 -#define NPCX_IRQ_GDMA NPCX_IRQ_12 -#define NPCX_IRQ_SMB1 NPCX_IRQ_13 -#define NPCX_IRQ_SMB2 NPCX_IRQ_14 -#define NPCX_IRQ_WKINTC_0 NPCX_IRQ_15 -#define NPCX_IRQ_SMB7 NPCX_IRQ_16 -#define NPCX_IRQ_ITIM32_3 NPCX_IRQ_17 -#define NPCX_IRQ_SHI NPCX_IRQ_18 -#define NPCX_IRQ_ESPI NPCX_IRQ_18 -#define NPCX_IRQ_SMB5 NPCX_IRQ_19 -#define NPCX_IRQ_SMB6 NPCX_IRQ_20 -#define NPCX_IRQ_PS2 NPCX_IRQ_21 -#define NPCX_IRQ22_NOUSED NPCX_IRQ_22 -#define NPCX_IRQ_MFT_2 NPCX_IRQ_23 -#define NPCX_IRQ_SHM NPCX_IRQ_24 -#define NPCX_IRQ_KBC_IBF NPCX_IRQ_25 -#define NPCX_IRQ_PM_CHAN_IBF NPCX_IRQ_26 -#define NPCX_IRQ_ITIM32_2 NPCX_IRQ_27 -#define NPCX_IRQ_ITIM32_1 NPCX_IRQ_28 -#define NPCX_I3C_MDMA5 NPCX_IRQ_29 -#define NPCX_IRQ30_NOUSED NPCX_IRQ_30 -#define NPCX_IRQ_TWD_WKINTB_0 NPCX_IRQ_31 -#define NPCX_IRQ_UART2 NPCX_IRQ_32 -#define NPCX_IRQ_UART NPCX_IRQ_33 -#define NPCX_IRQ34_NOUSED NPCX_IRQ_34 -#define NPCX_IRQ_WKINTF_0 NPCX_IRQ_35 -#define NPCX_IRQ_SMB3 NPCX_IRQ_36 -#define NPCX_IRQ_SMB4 NPCX_IRQ_37 -#define NPCX_IRQ_UART3 NPCX_IRQ_38 -#define NPCX_IRQ_UART4 NPCX_IRQ_39 -#define NPCX_IRQ40_NOUSED NPCX_IRQ_40 -#define NPCX_IRQ_MFT_3 NPCX_IRQ_41 -#define NPCX_IRQ_WKINTG_0 NPCX_IRQ_42 -#define NPCX_IRQ_ITIM32_4 NPCX_IRQ_43 -#define NPCX_IRQ_ITIM32_5 NPCX_IRQ_44 -#define NPCX_IRQ_ITIM32_6 NPCX_IRQ_45 -#define NPCX_IRQ_WKINTH_0 NPCX_IRQ_46 -#define NPCX_IRQ_WKINTA_1 NPCX_IRQ_47 -#define NPCX_IRQ_WKINTB_1 NPCX_IRQ_48 -#define NPCX_IRQ_KSI_WKINTC_1 NPCX_IRQ_49 -#define NPCX_IRQ_WKINTD_1 NPCX_IRQ_50 -#define NPCX_IRQ_WKINTE_1 NPCX_IRQ_51 -#define NPCX_IRQ_WKINTF_1 NPCX_IRQ_52 -#define NPCX_IRQ_WKINTG_1 NPCX_IRQ_53 -#define NPCX_IRQ_WKINTH_1 NPCX_IRQ_54 -#define NPCX_WKINTG_2 NPCX_IRQ_55 -#define NPCX_IRQ_KBC_OBE NPCX_IRQ_56 -#define NPCX_IRQ_SPI NPCX_IRQ_57 -#define NPCX_IRQ_ITIM64 NPCX_IRQ_58 -#define NPCX_IRQ_LCT_WKINTF_2 NPCX_IRQ_59 -#define NPCX_IRQ_WKINTA_2 NPCX_IRQ_60 -#define NPCX_IRQ_WKINTB_2 NPCX_IRQ_61 -#define NPCX_IRQ_WKINTC_2 NPCX_IRQ_62 -#define NPCX_IRQ_WKINTD_2 NPCX_IRQ_63 -/* MIWU definition */ -#define LCT_WUI_GROUP MIWU_GROUP_6 -#define LCT_WUI_MASK MASK_PIN7 - -/* Modules Map */ - -/* Miscellaneous Device Control (MDC) registers */ -#define NPCX_FWCTRL REG8(NPCX_MDC_BASE_ADDR + 0x009) - -/* MDC register fields */ -#define NPCX_FWCTRL_RO_REGION 6 -#define NPCX_FWCTRL_FW_SLOT 7 - -#define NPCX_CR_UART_BASE_ADDR(mdl) (0x400E0000 + ((mdl) * 0x2000L)) -#define NPCX_LCT_BASE_ADDR 0x400D7000 -#define NPCX_SMB_BASE_ADDR(mdl) (((mdl) < 2) ? \ - (0x40009000 + ((mdl) * 0x2000L)) : \ - ((mdl) < 4) ? \ - (0x400C0000 + (((mdl) - 2) * 0x2000L)) : \ - ((mdl) == 4) ? \ - (0x40008000) : \ - (0x40017000 + (((mdl) - 5) * 0x1000L))) - -#define NPCX_HFCBCD1 REG8(NPCX_HFCG_BASE_ADDR + 0x012) -#define NPCX_HFCBCD2 REG8(NPCX_HFCG_BASE_ADDR + 0x014) - -enum { - NPCX_UART_PORT0 = 0, /* UART port 0 */ - NPCX_UART_PORT1 = 1, /* UART port 1 */ - NPCX_UART_PORT2 = 2, /* UART port 2 */ - NPCX_UART_PORT3 = 3, /* UART port 3 */ - NPCX_UART_COUNT -}; - - /* UART registers only used for FIFO mode */ -#define NPCX_UFTSTS(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x020) -#define NPCX_UFRSTS(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x022) -#define NPCX_UFTCTL(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x024) -#define NPCX_UFRCTL(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x026) - -/* UART FIFO register fields */ -#define NPCX_UMDSL_FIFO_MD 0 - -#define NPCX_UFTSTS_TEMPTY_LVL FIELD(0, 5) -#define NPCX_UFTSTS_TEMPTY_LVL_STS 5 -#define NPCX_UFTSTS_TFIFO_EMPTY_STS 6 -#define NPCX_UFTSTS_NXMIP 7 - -#define NPCX_UFRSTS_RFULL_LVL_STS 5 -#define NPCX_UFRSTS_RFIFO_NEMPTY_STS 6 -#define NPCX_UFRSTS_ERR 7 - -#define NPCX_UFTCTL_TEMPTY_LVL_SEL FIELD(0, 5) -#define NPCX_UFTCTL_TEMPTY_LVL_EN 5 -#define NPCX_UFTCTL_TEMPTY_EN 6 -#define NPCX_UFTCTL_NXMIPEN 7 - -#define NPCX_UFRCTL_RFULL_LVL_SEL FIELD(0, 5) -#define NPCX_UFRCTL_RFULL_LVL_EN 5 -#define NPCX_UFRCTL_RNEMPTY_EN 6 -#define NPCX_UFRCTL_ERR_EN 7 - -/* KBSCAN register fields */ -#define NPCX_KBHDRV_FIELD FIELD(6, 2) - -/* GLUE registers */ -#define NPCX_GLUE_PSL_CTS REG8(NPCX_GLUE_REGS_BASE + 0x027) -#define NPCX_GLUE_PSL_MCTL1 REG8(NPCX_GLUE_REGS_BASE + 0x034) -#define NPCX_GLUE_PSL_MCTL2 REG8(NPCX_GLUE_REGS_BASE + 0x038) - -/* PSL register fields */ -#define NPCX_GLUE_PSL_MCTL1_VCC1_RST_PSL 7 -#define NPCX_GLUE_PSL_MCTL1_PSL_GPO_CTL 6 -#define NPCX_GLUE_PSL_MCTL1_LCT_EV 4 -#define NPCX_GLUE_PSL_MCTL1_VCC1_RST_EV 3 -#define NPCX_GLUE_PSL_MCTL1_PLS_EN 1 -#define NPCX_GLUE_PSL_MCTL1_OD_EN 0 - -#define NPCX_GLUE_PSL_MCTL2_VCC1_RST_PSL_LK 7 -#define NPCX_GLUE_PSL_MCTL2_PSL_GP_EN 6 -#define NPCX_GLUE_PSL_MCTL2_AC_IN_BLOCK_EN 3 -#define NPCX_GLUE_PSL_MCTL2_AC_IN_SEL FIELD(0, 1) - -/* GPIO registers */ -#define NPCX_PLOCK_CTL(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x007) - -/* System Configuration (SCFG) Registers */ - -/* SCFG enumeration */ -enum { - ALT_GROUP_0, - ALT_GROUP_1, - ALT_GROUP_2, - ALT_GROUP_3, - ALT_GROUP_4, - ALT_GROUP_5, - ALT_GROUP_6, - ALT_GROUP_7, - ALT_GROUP_8, - ALT_GROUP_9, - ALT_GROUP_A, - ALT_GROUP_B, - ALT_GROUP_C, - ALT_GROUP_D, - ALT_GROUP_E, - ALT_GROUP_F, - ALT_GROUP_G, - ALT_GROUP_H, - ALT_GROUP_J, - ALT_GROUP_COUNT -}; - -#define NPCX_DEVALT(n) REG8(NPCX_SCFG_BASE_ADDR + 0x010 + (n)) - -#define NPCX_LV_GPIO_CTL_ADDR(n) (((n) < 5) ? \ - (NPCX_SCFG_BASE_ADDR + 0x02A + (n)) :\ - (NPCX_SCFG_BASE_ADDR + 0x026)) -#define NPCX_LV_GPIO_CTL(n) REG8(NPCX_LV_GPIO_CTL_ADDR(n)) -/* Device Alternate Function Lock */ -#define NPCX_DEVALT_LK(n) REG8(NPCX_SCFG_BASE_ADDR + 0x210 + (n)) - -/* pin-mux for I2C */ -#define NPCX_DEVALT2_I2C0_0_SL 0 -#define NPCX_DEVALT2_I2C7_0_SL 1 -#define NPCX_DEVALT2_I2C1_0_SL 2 -#define NPCX_DEVALT2_I2C6_0_SL 3 -#define NPCX_DEVALT2_I2C2_0_SL 4 -#define NPCX_DEVALT2_I2C5_0_SL 5 -#define NPCX_DEVALT2_I2C3_0_SL 6 -#define NPCX_DEVALT6_I2C6_1_SL 5 -#define NPCX_DEVALT6_I2C5_1_SL 6 -#define NPCX_DEVALT6_I2C4_1_SL 7 - -/* pin-mux for ADC */ -#define NPCX_DEVALTF_ADC5_SL 0 -#define NPCX_DEVALTF_ADC6_SL 1 -#define NPCX_DEVALTF_ADC7_SL 2 -#define NPCX_DEVALTF_ADC8_SL 3 -#define NPCX_DEVALTF_ADC9_SL 4 -#define NPCX_DEVALTF_ADC10_SL 5 -#define NPCX_DEVALTF_ADC11_SL 6 - -/* pin-mux for PSL */ -#define NPCX_DEVALTD_PSL_IN1_AHI 0 -#define NPCX_DEVALTD_NPSL_IN1_SL 1 -#define NPCX_DEVALTD_PSL_IN2_AHI 2 -#define NPCX_DEVALTD_NPSL_IN2_SL 3 -#define NPCX_DEVALTD_PSL_IN3_AHI 4 -#define NPCX_DEVALTD_PSL_IN3_SL 5 -#define NPCX_DEVALTD_PSL_IN4_AHI 6 -#define NPCX_DEVALTD_PSL_IN4_SL 7 - -/* pin-mux for Misc. */ - -/* pin-mux for UART */ -#define NPCX_DEVALTJ_CR_SIN1_SL1 0 -#define NPCX_DEVALTJ_CR_SOUT1_SL1 1 -#define NPCX_DEVALTJ_CR_SIN1_SL2 2 -#define NPCX_DEVALTJ_CR_SOUT1_SL2 3 -#define NPCX_DEVALTJ_CR_SIN2_SL 4 -#define NPCX_DEVALTJ_CR_SOUT2_SL 5 -#define NPCX_DEVALTJ_CR_SIN3_SL 6 -#define NPCX_DEVALTJ_CR_SOUT3_SL 7 -#define NPCX_DEVALTE_CR_SIN4_SL 6 -#define NPCX_DEVALTE_CR_SOUT4_SL 7 - -/* SHI module version 2 enable bit */ -#define NPCX_DEVALTF_SHI_NEW 7 - -/* VCC_RST Pull-Up Disable */ -#define NPCX_DEVALTG_VCC1_RST_PUD 5 -#define NPCX_DEVALTG_PSL_OUT_SL 6 -#define NPCX_DEVALTG_PSL_GPO_SL 7 - -/* SMBus register fields */ -#define NPCX_SMBSEL_SMB4SEL 4 -#define NPCX_SMBSEL_SMB5SEL 5 -#define NPCX_SMBSEL_SMB6SEL 6 - -/* pin-mux for JTAG */ -#define NPCX_JEN_CTL1 REG8(NPCX_SCFG_BASE_ADDR + 0x120) -#define NPCX_JEN_CTL1_JEN_EN_FIELD FIELD(0, 4) -#define NPCX_JEN_CTL1_JEN_EN_DIS 0x06 -#define NPCX_JEN_CTL1_JEN_EN_ENA 0x09 - -/* SMB enumeration: I2C port definitions. */ -enum { - NPCX_I2C_PORT0_0 = 0, /* I2C port 0, bus 0 */ - NPCX_I2C_PORT1_0, /* I2C port 1, bus 0 */ - NPCX_I2C_PORT2_0, /* I2C port 2, bus 0 */ - NPCX_I2C_PORT3_0, /* I2C port 3, bus 0 */ - NPCX_I2C_PORT4_1, /* I2C port 4, bus 1 */ - NPCX_I2C_PORT5_0, /* I2C port 5, bus 0 */ - NPCX_I2C_PORT5_1, /* I2C port 5, bus 1 */ - NPCX_I2C_PORT6_0, /* I2C port 6, bus 0 */ - NPCX_I2C_PORT6_1, /* I2C port 6, bus 1 */ - NPCX_I2C_PORT7_0, /* I2C port 7, bus 0 */ - NPCX_I2C_COUNT, -}; - -/* Power Management Controller (PMC) Registers */ -#define NPCX_FMUL_WIN_DLY REG8(NPCX_PMC_BASE_ADDR + 0x010) -#define NPCX_RAM_PD(offset) REG8(NPCX_PMC_BASE_ADDR + 0x020 + (offset)) - -/* PMC register fields */ -#define NPCX_PWDWN_CTL3_SMB4_PD 4 -#define NPCX_PWDWN_CTL7_SMB5_PD 0 -#define NPCX_PWDWN_CTL7_SMB6_PD 1 -#define NPCX_PWDWN_CTL7_SMB7_PD 2 -#define NPCX_PWDWN_CTL7_ITIM64_PD 5 -#define NPCX_PWDWN_CTL7_UART2_PD 6 - -/* - * PMC enumeration: - * Offsets from CGC_BASE registers for each peripheral. - */ -enum { - CGC_OFFSET_KBS = 0, - CGC_OFFSET_UART = 0, - CGC_OFFSET_FAN = 0, - CGC_OFFSET_FIU = 0, - CGC_OFFSET_PS2 = 0, - CGC_OFFSET_PWM = 1, - CGC_OFFSET_I2C = 2, - CGC_OFFSET_ADC = 3, - CGC_OFFSET_PECI = 3, - CGC_OFFSET_SPI = 3, - CGC_OFFSET_TIMER = 3, - CGC_OFFSET_LPC = 4, - CGC_OFFSET_ESPI = 5, - CGC_OFFSET_I2C2 = 6, - CGC_OFFSET_UART2 = 6, -}; - -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, -}; - -#define CGC_I2C_MASK (BIT(NPCX_PWDWN_CTL3_SMB0_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB1_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB2_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB3_PD) | \ - BIT(NPCX_PWDWN_CTL3_SMB4_PD)) -#define CGC_I2C_MASK2 (BIT(NPCX_PWDWN_CTL7_SMB5_PD) | \ - BIT(NPCX_PWDWN_CTL7_SMB6_PD) | \ - BIT(NPCX_PWDWN_CTL7_SMB7_PD)) -#define CGC_UART2_MASK BIT(NPCX_PWDWN_CTL7_UART2_PD) - -/* BBRAM register fields */ -#define NPCX_BKUP_STS_VSBY_STS 1 -#define NPCX_BKUP_STS_VCC1_STS 0 -#define NPCX_BKUP_STS_ALL_MASK \ - (BIT(NPCX_BKUP_STS_IBBR) | BIT(NPCX_BKUP_STS_VSBY_STS) | \ - BIT(NPCX_BKUP_STS_VCC1_STS)) -#define NPCX_BBRAM_SIZE 128 /* Size of BBRAM */ - -/* ITIM registers */ -#define NPCX_ITCNT32(n) REG32(NPCX_ITIM_BASE_ADDR(n) + 0x008) - -/* Timer counter register used for 1 micro-second system tick */ -#define NPCX_ITCNT_SYSTEM NPCX_ITCNT32(ITIM32_6) -/* Timer counter register used for others */ -#define NPCX_ITCNT NPCX_ITCNT32 - -/* ITIM module No. used for event */ -#define ITIM_EVENT_NO ITIM32_1 -/* ITIM module No. used for watchdog */ -#define ITIM_WDG_NO ITIM32_5 -/* ITIM module No. used for 1 micro-second system tick */ -#define ITIM_SYSTEM_NO ITIM32_6 - -/* ITIM enumeration */ -enum ITIM_MODULE_T { - ITIM32_1, - ITIM32_2, - ITIM32_3, - ITIM32_4, - ITIM32_5, - ITIM32_6, - ITIM_MODULE_COUNT, -}; - -/* Serial Host Interface (SHI) Registers - only available on SHI Version 2 */ -#define NPCX_SHICFG3 REG8(NPCX_SHI_BASE_ADDR + 0x00C) -#define NPCX_SHICFG4 REG8(NPCX_SHI_BASE_ADDR + 0x00D) -#define NPCX_SHICFG5 REG8(NPCX_SHI_BASE_ADDR + 0x00E) -#define NPCX_EVSTAT2 REG8(NPCX_SHI_BASE_ADDR + 0x00F) -#define NPCX_EVENABLE2 REG8(NPCX_SHI_BASE_ADDR + 0x010) -#define NPCX_OBUF(n) REG8(NPCX_SHI_BASE_ADDR + 0x020 + (n)) -#define NPCX_IBUF(n) REG8(NPCX_SHI_BASE_ADDR + 0x0A0 + (n)) - -/* SHI register fields */ -#define NPCX_SHICFG3_OBUFLVLDIS 7 -#define NPCX_SHICFG4_IBUFLVLDIS 7 -#define NPCX_SHICFG5_IBUFLVL2 FIELD(0, 6) -#define NPCX_SHICFG5_IBUFLVL2DIS 7 -#define NPCX_EVSTAT2_IBHF2 0 -#define NPCX_EVSTAT2_CSNRE 1 -#define NPCX_EVSTAT2_CSNFE 2 -#define NPCX_EVENABLE2_IBHF2EN 0 -#define NPCX_EVENABLE2_CSNREEN 1 -#define NPCX_EVENABLE2_CSNFEEN 2 - -/* eSPI register fields */ -#define NPCX_ESPIIE_BMTXDONEIE 19 -#define NPCX_ESPIIE_PBMRXIE 20 -#define NPCX_ESPIIE_PMSGRXIE 21 -#define NPCX_ESPIIE_BMBURSTERRIE 22 -#define NPCX_ESPIIE_BMBURSTDONEIE 23 - -#define NPCX_ESPIWE_PBMRXWE 20 -#define NPCX_ESPIWE_PMSGRXWE 21 - -#define NPCX_ESPISTS_VWUPDW 17 -#define NPCX_ESPISTS_BMTXDONE 19 -#define NPCX_ESPISTS_PBMRX 20 -#define NPCX_ESPISTS_PMSGRX 21 -#define NPCX_ESPISTS_BMBURSTERR 22 -#define NPCX_ESPISTS_BMBURSTDONE 23 -#define NPCX_ESPISTS_ESPIRST_LVL 24 - -#define ESPIIE_BMTXDONE BIT(NPCX_ESPIIE_BMTXDONEIE) -#define ESPIIE_PBMRX BIT(NPCX_ESPIIE_PBMRXIE) -#define ESPIIE_PMSGRX BIT(NPCX_ESPIIE_PMSGRXIE) -#define ESPIIE_BMBURSTERR BIT(NPCX_ESPIIE_BMBURSTERRIE) -#define ESPIIE_BMBURSTDONE BIT(NPCX_ESPIIE_BMBURSTDONEIE) - -#define ESPIWE_PBMRX BIT(NPCX_ESPIWE_PBMRXWE) -#define ESPIWE_PMSGRX BIT(NPCX_ESPIWE_PMSGRXWE) - -/* Bit field manipulation for VWEVMS Value */ -#define VWEVMS_WK_EN(e) (((e)<<20) & 0x00100000) -#define VWEVMS_INTWK_EN(e) (VWEVMS_INT_EN(e) | VWEVMS_WK_EN(e)) - -/* eSPI max supported frequency */ -enum { - NPCX_ESPI_MAXFREQ_20 = 0, - NPCX_ESPI_MAXFREQ_25 = 1, - NPCX_ESPI_MAXFREQ_33 = 2, - NPCX_ESPI_MAXFREQ_50 = 3, - NPCX_ESPI_MAXFREQ_66 = 4, - NPCX_ESPI_MAXFREQ_NONE = 0xFF -}; - -/* eSPI Operating Frequency */ -enum { - NPCX_ESPI_OPFREQ_20 = 0, - NPCX_ESPI_OPFREQ_25 = 1, - NPCX_ESPI_OPFREQ_33 = 2, - NPCX_ESPI_OPFREQ_50 = 3, - NPCX_ESPI_OPFREQ_66 = 4, - NPCX_ESPI_OPFREQ_NONE = 0xFF -}; - -/* eSPI max frequency support per FMCLK */ -#if (FMCLK <= 33000000) -#define NPCX_ESPI_MAXFREQ_MAX NPCX_ESPI_MAXFREQ_33 -#else -#define NPCX_ESPI_MAXFREQ_MAX NPCX_ESPI_MAXFREQ_50 -#endif - -/* UART registers */ -#define NPCX_UART_WK_GROUP MIWU_GROUP_8 -#define NPCX_UART_WK_BIT 7 -#define NPCX_UART2_WK_GROUP MIWU_GROUP_1 -#define NPCX_UART2_WK_BIT 6 - -/* MIWU registers */ -#define NPCX_WKEDG_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x00 + \ - ((n) * 0x10)) -#define NPCX_WKAEDG_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x01 + \ - ((n) * 0x10)) -#define NPCX_WKMOD_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x02 + \ - ((n) * 0x10)) -#define NPCX_WKPND_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x03 + \ - ((n) * 0x10)) -#define NPCX_WKPCL_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x04 + \ - ((n) * 0x10)) -#define NPCX_WKEN_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x05 + \ - ((n) * 0x10)) -#define NPCX_WKST_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x06 + \ - ((n) * 0x10)) -#define NPCX_WKINEN_ADDR(port, n) (NPCX_MIWU_BASE_ADDR(port) + 0x07 + \ - ((n) * 0x10)) - -#define NPCX_WKEDG(port, n) REG8(NPCX_WKEDG_ADDR(port, n)) -#define NPCX_WKAEDG(port, n) REG8(NPCX_WKAEDG_ADDR(port, n)) -#define NPCX_WKPND(port, n) REG8(NPCX_WKPND_ADDR(port, n)) -#define NPCX_WKPCL(port, n) REG8(NPCX_WKPCL_ADDR(port, n)) -#define NPCX_WKEN(port, n) REG8(NPCX_WKEN_ADDR(port, n)) -#define NPCX_WKST(port, n) REG8(NPCX_WKST_ADDR(port, n)) -#define NPCX_WKINEN(port, n) REG8(NPCX_WKINEN_ADDR(port, n)) -#define NPCX_WKMOD(port, n) REG8(NPCX_WKMOD_ADDR(port, n)) - -/* LCT register */ -#define NPCX_LCTCONT REG8(NPCX_LCT_BASE_ADDR + 0x002) -#define NPCX_LCTSTAT REG8(NPCX_LCT_BASE_ADDR + 0x004) -#define NPCX_LCTSECOND REG8(NPCX_LCT_BASE_ADDR + 0x005) -#define NPCX_LCTMINUTE REG8(NPCX_LCT_BASE_ADDR + 0x006) -#define NPCX_LCTHOUR REG8(NPCX_LCT_BASE_ADDR + 0x008) -#define NPCX_LCTDAY REG8(NPCX_LCT_BASE_ADDR + 0x00A) -#define NPCX_LCTWEEK REG8(NPCX_LCT_BASE_ADDR + 0x00C) -/* LCTCONT fields */ -#define NPCX_LCTCONT_EN 0 -#define NPCX_LCTCONT_EN_FIELD FIELD(0, 1) -#define NPCX_LCTCONT_EVEN 1 -#define NPCX_LCTCONT_PSL_EN 2 -#define NPCX_LCTCONT_CLK_EN 6 -#define NPCX_LCTCONT_VSBY_PWR 7 -/* LCTSTAT fields */ -#define NPCX_LCTSTAT_EVST 0 - -/* UART registers and functions */ -#if NPCX_UART_MODULE2 -/* - * To be used as 2nd parameter to NPCX_WK*() macro, table (1st parameter) is - * always 1 == MIWU_TABLE_1. - */ -#define NPCX_UART_MIWU_IRQ NPCX_IRQ_WKINTG_1 -#define NPCX_UART_DEVALT NPCX_DEVALT(ALT_GROUP_J) -#define NPCX_UART_DEVALT_SIN_SL NPCX_DEVALTJ_CR_SIN1_SL2 -#define NPCX_UART_DEVALT_SOUT_SL NPCX_DEVALTJ_CR_SOUT1_SL2 -#define NPCX_UART_ALT_DEVALT NPCX_DEVALT(ALT_GROUP_J) -#define NPCX_UART_ALT_DEVALT_SIN_SL NPCX_DEVALTJ_CR_SIN1_SL1 -#define NPCX_UART_ALT_DEVALT_SOUT_SL NPCX_DEVALTJ_CR_SOUT1_SL1 -#else /* !NPCX_UART_MODULE2 */ -#define NPCX_UART_MIWU_IRQ NPCX_IRQ_WKINTB_1 -#define NPCX_UART_DEVALT NPCX_DEVALT(ALT_GROUP_J) -#define NPCX_UART_DEVALT_SIN_SL NPCX_DEVALTJ_CR_SIN1_SL1 -#define NPCX_UART_DEVALT_SOUT_SL NPCX_DEVALTJ_CR_SOUT1_SL1 -#define NPCX_UART_ALT_DEVALT NPCX_DEVALT(ALT_GROUP_J) -#define NPCX_UART_ALT_DEVALT_SIN_SL NPCX_DEVALTJ_CR_SIN1_SL2 -#define NPCX_UART_ALT_DEVALT_SOUT_SL NPCX_DEVALTJ_CR_SOUT1_SL2 -#endif /* NPCX_UART_MODULE2 */ - -/* ADC register */ -#define NPCX_ADCSTS REG16(NPCX_ADC_BASE_ADDR + 0x000) -#define NPCX_ADCCNF REG16(NPCX_ADC_BASE_ADDR + 0x002) -#define NPCX_ATCTL REG16(NPCX_ADC_BASE_ADDR + 0x004) -#define NPCX_ASCADD REG16(NPCX_ADC_BASE_ADDR + 0x006) -#define NPCX_ADCCS REG16(NPCX_ADC_BASE_ADDR + 0x008) -#define NPCX_THRCTS REG16(NPCX_ADC_BASE_ADDR + 0x01A) -#define NPCX_ADCCNF2 REG16(NPCX_ADC_BASE_ADDR + 0x020) -#define NPCX_GENDLY REG16(NPCX_ADC_BASE_ADDR + 0x022) -#define NPCX_MEAST REG16(NPCX_ADC_BASE_ADDR + 0x026) -/* NOTE: This is 0-based for the ADC channels. */ -#define NPCX_CHNDAT(n) REG16(NPCX_ADC_BASE_ADDR + 0x040 + (2L*(n))) -/* NOTE: These are 1-based for the threshold detectors. */ -#define NPCX_THRCTL(n) REG16(NPCX_ADC_BASE_ADDR + 0x05E + (2L*(n))) - -/* ADC register fields */ -#define NPCX_ADCSTS_EOCEV 0 -#define NPCX_ADCCNF_ADCMD_FIELD FIELD(1, 2) -#define NPCX_ADCCNF_ADCRPTC 3 -#define NPCX_ADCCNF_INTECEN 6 -#define NPCX_ADCCNF_START 4 -#define NPCX_ADCCNF_ADCEN 0 -#define NPCX_ADCCNF_STOP 11 -#define NPCX_ATCTL_SCLKDIV_FIELD FIELD(0, 6) -#define NPCX_ATCTL_DLY_FIELD FIELD(8, 3) -#define NPCX_ASCADD_SADDR_FIELD FIELD(0, 5) -#define NPCX_THRCTS_ADC_WKEN 15 -#define NPCX_THRCTS_THR6_IEN 13 -#define NPCX_THRCTS_THR5_IEN 12 -#define NPCX_THRCTS_THR4_IEN 11 -#define NPCX_THRCTS_THR3_IEN 10 -#define NPCX_THRCTS_THR2_IEN 9 -#define NPCX_THRCTS_THR1_IEN 8 -#define NPCX_THRCTS_ADC_EVENT 7 -#define NPCX_THRCTS_THR6_STS 5 -#define NPCX_THRCTS_THR5_STS 4 -#define NPCX_THRCTS_THR4_STS 3 -#define NPCX_THRCTS_THR3_STS 2 -#define NPCX_THRCTS_THR2_STS 1 -#define NPCX_THRCTS_THR1_STS 0 -#define NPCX_CHNDAT_CHDAT_FIELD FIELD(0, 10) -#define NPCX_CHNDAT_NEW 15 -#define NPCX_THRCTL_THEN 15 -#define NPCX_THRCTL_L_H 14 -#define NPCX_THRCTL_CHNSEL FIELD(10, 4) -#define NPCX_THRCTL_THRVAL FIELD(0, 10) - -#define NPCX_ADC_THRESH1 1 -#define NPCX_ADC_THRESH2 2 -#define NPCX_ADC_THRESH3 3 -#define NPCX_ADC_THRESH4 4 -#define NPCX_ADC_THRESH5 5 -#define NPCX_ADC_THRESH6 6 -#define NPCX_ADC_THRESH_CNT 6 diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h deleted file mode 100644 index f0c241e7f9..0000000000 --- a/chip/npcx/registers.h +++ /dev/null @@ -1,1693 +0,0 @@ -/* Copyright 2014 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 - */ - -#ifndef __CROS_EC_REGISTERS_H -#define __CROS_EC_REGISTERS_H - -#include "common.h" -#include "compile_time_macros.h" -#include "clock_chip.h" - -/******************************************************************************/ -/* - * 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))) - -/******************************************************************************/ -/* - * NPCX (Nuvoton M4 EC) Register Definitions - */ - -/* Global Definition */ -#define I2C_7BITS_ADDR 0 -/* Switcher of features */ -#define SUPPORT_LCT 1 -#define SUPPORT_WDG 1 -#define SUPPORT_P80_SEG 0 /* Note: it uses KSO10 & KSO11 */ -/* Switcher of debugging */ -#define DEBUG_GPIO 0 -#define DEBUG_I2C 0 -#define DEBUG_TMR 0 -#define DEBUG_WDG 0 -#define DEBUG_FAN 0 -#define DEBUG_PWM 0 -#define DEBUG_SPI 0 -#define DEBUG_FLH 0 -#define DEBUG_PECI 0 -#define DEBUG_SHI 0 -#define DEBUG_CLK 0 -#define DEBUG_LPC 0 -#define DEBUG_ESPI 0 -#define DEBUG_CEC 0 -#define DEBUG_SIB 0 -#define DEBUG_PS2 0 - -/* 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)) - -/* - * NPCX-IRQ numbers - */ -#define NPCX_IRQ_0 0 -#define NPCX_IRQ_1 1 -#define NPCX_IRQ_2 2 -#define NPCX_IRQ_3 3 -#define NPCX_IRQ_4 4 -#define NPCX_IRQ_5 5 -#define NPCX_IRQ_6 6 -#define NPCX_IRQ_7 7 -#define NPCX_IRQ_8 8 -#define NPCX_IRQ_9 9 -#define NPCX_IRQ_10 10 -#define NPCX_IRQ_11 11 -#define NPCX_IRQ_12 12 -#define NPCX_IRQ_13 13 -#define NPCX_IRQ_14 14 -#define NPCX_IRQ_15 15 -#define NPCX_IRQ_16 16 -#define NPCX_IRQ_17 17 -#define NPCX_IRQ_18 18 -#define NPCX_IRQ_19 19 -#define NPCX_IRQ_20 20 -#define NPCX_IRQ_21 21 -#define NPCX_IRQ_22 22 -#define NPCX_IRQ_23 23 -#define NPCX_IRQ_24 24 -#define NPCX_IRQ_25 25 -#define NPCX_IRQ_26 26 -#define NPCX_IRQ_27 27 -#define NPCX_IRQ_28 28 -#define NPCX_IRQ_29 29 -#define NPCX_IRQ_30 30 -#define NPCX_IRQ_31 31 -#define NPCX_IRQ_32 32 -#define NPCX_IRQ_33 33 -#define NPCX_IRQ_34 34 -#define NPCX_IRQ_35 35 -#define NPCX_IRQ_36 36 -#define NPCX_IRQ_37 37 -#define NPCX_IRQ_38 38 -#define NPCX_IRQ_39 39 -#define NPCX_IRQ_40 40 -#define NPCX_IRQ_41 41 -#define NPCX_IRQ_42 42 -#define NPCX_IRQ_43 43 -#define NPCX_IRQ_44 44 -#define NPCX_IRQ_45 45 -#define NPCX_IRQ_46 46 -#define NPCX_IRQ_47 47 -#define NPCX_IRQ_48 48 -#define NPCX_IRQ_49 49 -#define NPCX_IRQ_50 50 -#define NPCX_IRQ_51 51 -#define NPCX_IRQ_52 52 -#define NPCX_IRQ_53 53 -#define NPCX_IRQ_54 54 -#define NPCX_IRQ_55 55 -#define NPCX_IRQ_56 56 -#define NPCX_IRQ_57 57 -#define NPCX_IRQ_58 58 -#define NPCX_IRQ_59 59 -#define NPCX_IRQ_60 60 -#define NPCX_IRQ_61 61 -#define NPCX_IRQ_62 62 -#define NPCX_IRQ_63 63 - -#define NPCX_IRQ_COUNT 64 - -/******************************************************************************/ -/* High Frequency Clock Generator (HFCG) registers */ -#define NPCX_HFCGCTRL REG8(NPCX_HFCG_BASE_ADDR + 0x000) -#define NPCX_HFCGML REG8(NPCX_HFCG_BASE_ADDR + 0x002) -#define NPCX_HFCGMH REG8(NPCX_HFCG_BASE_ADDR + 0x004) -#define NPCX_HFCGN REG8(NPCX_HFCG_BASE_ADDR + 0x006) -#define NPCX_HFCGP REG8(NPCX_HFCG_BASE_ADDR + 0x008) -#define NPCX_HFCBCD REG8(NPCX_HFCG_BASE_ADDR + 0x010) - -/* HFCG register fields */ -#define NPCX_HFCGCTRL_LOAD 0 -#define NPCX_HFCGCTRL_LOCK 2 -#define NPCX_HFCGCTRL_CLK_CHNG 7 - -/******************************************************************************/ -/* Low Frequency Clock Generator (LFCG) registers */ -#define NPCX_LFCGCTL REG8(NPCX_LFCG_BASE_ADDR + 0x000) -#define NPCX_HFRDI REG16(NPCX_LFCG_BASE_ADDR + 0x002) -#define NPCX_HFRDF REG16(NPCX_LFCG_BASE_ADDR + 0x004) -#define NPCX_FRCDIV REG16(NPCX_LFCG_BASE_ADDR + 0x006) -#define NPCX_DIVCOR1 REG16(NPCX_LFCG_BASE_ADDR + 0x008) -#define NPCX_DIVCOR2 REG16(NPCX_LFCG_BASE_ADDR + 0x00A) -#define NPCX_LFCGCTL2 REG8(NPCX_LFCG_BASE_ADDR + 0x014) - -/* LFCG register fields */ -#define NPCX_LFCGCTL_XTCLK_VAL 7 -#define NPCX_LFCGCTL2_XT_OSC_SL_EN 6 - -/******************************************************************************/ -/* CR UART Register */ -#define NPCX_UTBUF(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x000) -#define NPCX_URBUF(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x002) -#define NPCX_UICTRL(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x004) -#define NPCX_USTAT(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x006) -#define NPCX_UFRS(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x008) -#define NPCX_UMDSL(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x00A) -#define NPCX_UBAUD(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x00C) -#define NPCX_UPSR(n) REG8(NPCX_CR_UART_BASE_ADDR(n) + 0x00E) - -/******************************************************************************/ -/* KBSCAN registers */ -#define NPCX_KBSIN REG8(NPCX_KBSCAN_REGS_BASE + 0x04) -#define NPCX_KBSINPU REG8(NPCX_KBSCAN_REGS_BASE + 0x05) -#define NPCX_KBSOUT0 REG16(NPCX_KBSCAN_REGS_BASE + 0x06) -#define NPCX_KBSOUT1 REG16(NPCX_KBSCAN_REGS_BASE + 0x08) -#define NPCX_KBS_BUF_INDX REG8(NPCX_KBSCAN_REGS_BASE + 0x0A) -#define NPCX_KBS_BUF_DATA REG8(NPCX_KBSCAN_REGS_BASE + 0x0B) -#define NPCX_KBSEVT REG8(NPCX_KBSCAN_REGS_BASE + 0x0C) -#define NPCX_KBSCTL REG8(NPCX_KBSCAN_REGS_BASE + 0x0D) -#define NPCX_KBS_CFG_INDX REG8(NPCX_KBSCAN_REGS_BASE + 0x0E) -#define NPCX_KBS_CFG_DATA REG8(NPCX_KBSCAN_REGS_BASE + 0x0F) - -/* KBSCAN register fields */ -#define NPCX_KBSBUFINDX 0 -#define NPCX_KBSDONE 0 -#define NPCX_KBSERR 1 -#define NPCX_KBSSTART 0 -#define NPCX_KBSMODE 1 -#define NPCX_KBSIEN 2 -#define NPCX_KBSINC 3 -#define NPCX_KBSCFGINDX 0 - -/* KBSCAN definitions */ -#define KB_ROW_NUM 8 /* Rows numbers of keyboard matrix */ -#define KB_COL_NUM 18 /* Columns numbers of keyboard matrix */ -#define KB_ROW_MASK ((1<<KB_ROW_NUM) - 1) /* Mask of rows of keyboard matrix */ - -/******************************************************************************/ -/* GLUE registers */ -#define NPCX_GLUE_SDPD0 REG8(NPCX_GLUE_REGS_BASE + 0x010) -#define NPCX_GLUE_SDPD1 REG8(NPCX_GLUE_REGS_BASE + 0x012) -#define NPCX_GLUE_SDP_CTS REG8(NPCX_GLUE_REGS_BASE + 0x014) -#define NPCX_GLUE_SMBSEL REG8(NPCX_GLUE_REGS_BASE + 0x021) -/******************************************************************************/ - -/* MIWU enumeration */ -enum { - MIWU_TABLE_0, - MIWU_TABLE_1, - MIWU_TABLE_2, - MIWU_TABLE_COUNT -}; - -enum { - MIWU_GROUP_1, - MIWU_GROUP_2, - MIWU_GROUP_3, - MIWU_GROUP_4, - MIWU_GROUP_5, - MIWU_GROUP_6, - MIWU_GROUP_7, - MIWU_GROUP_8, - MIWU_GROUP_COUNT -}; - -enum { - MIWU_EDGE_RISING, - MIWU_EDGE_FALLING, - MIWU_EDGE_ANYING, -}; - -/* MIWU utilities */ -#define MIWU_TABLE_WKKEY MIWU_TABLE_1 -#define MIWU_GROUP_WKKEY MIWU_GROUP_3 - -/******************************************************************************/ -/* GPIO registers */ -#define NPCX_PDOUT(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x000) -#define NPCX_PDIN(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x001) -#define NPCX_PDIR(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x002) -#define NPCX_PPULL(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x003) -#define NPCX_PPUD(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x004) -#define NPCX_PENVDD(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x005) -#define NPCX_PTYPE(n) REG8(NPCX_GPIO_BASE_ADDR(n) + 0x006) - -/* GPIO enumeration */ -enum { - GPIO_PORT_0, - GPIO_PORT_1, - GPIO_PORT_2, - GPIO_PORT_3, - GPIO_PORT_4, - GPIO_PORT_5, - GPIO_PORT_6, - GPIO_PORT_7, - GPIO_PORT_8, - GPIO_PORT_9, - GPIO_PORT_A, - GPIO_PORT_B, - GPIO_PORT_C, - GPIO_PORT_D, - GPIO_PORT_E, - GPIO_PORT_F, - GPIO_PORT_COUNT -}; - -enum { - MASK_PIN0 = BIT(0), - MASK_PIN1 = BIT(1), - MASK_PIN2 = BIT(2), - MASK_PIN3 = BIT(3), - MASK_PIN4 = BIT(4), - MASK_PIN5 = BIT(5), - MASK_PIN6 = BIT(6), - MASK_PIN7 = BIT(7), -}; - -/* Chip-independent aliases for port base group */ -#define GPIO_0 GPIO_PORT_0 -#define GPIO_1 GPIO_PORT_1 -#define GPIO_2 GPIO_PORT_2 -#define GPIO_3 GPIO_PORT_3 -#define GPIO_4 GPIO_PORT_4 -#define GPIO_5 GPIO_PORT_5 -#define GPIO_6 GPIO_PORT_6 -#define GPIO_7 GPIO_PORT_7 -#define GPIO_8 GPIO_PORT_8 -#define GPIO_9 GPIO_PORT_9 -#define GPIO_A GPIO_PORT_A -#define GPIO_B GPIO_PORT_B -#define GPIO_C GPIO_PORT_C -#define GPIO_D GPIO_PORT_D -#define GPIO_E GPIO_PORT_E -#define GPIO_F GPIO_PORT_F -#define UNIMPLEMENTED_GPIO_BANK GPIO_PORT_0 - -/******************************************************************************/ -/* MSWC Registers */ -#define NPCX_MSWCTL1 REG8(NPCX_MSWC_BASE_ADDR + 0x000) -#define NPCX_MSWCTL2 REG8(NPCX_MSWC_BASE_ADDR + 0x002) -#define NPCX_HCBAL REG8(NPCX_MSWC_BASE_ADDR + 0x008) -#define NPCX_HCBAH REG8(NPCX_MSWC_BASE_ADDR + 0x00A) -#define NPCX_SRID_CR REG8(NPCX_MSWC_BASE_ADDR + 0x01C) -#define NPCX_SID_CR REG8(NPCX_MSWC_BASE_ADDR + 0x020) -#define NPCX_DEVICE_ID_CR REG8(NPCX_MSWC_BASE_ADDR + 0x022) - -/* MSWC register fields */ -#define NPCX_MSWCTL1_HRSTOB 0 -#define NPCS_MSWCTL1_HWPRON 1 -#define NPCX_MSWCTL1_PLTRST_ACT 2 -#define NPCX_MSWCTL1_VHCFGA 3 -#define NPCX_MSWCTL1_HCFGLK 4 -#define NPCX_MSWCTL1_PWROFFB 6 -#define NPCX_MSWCTL1_A20MB 7 - -/******************************************************************************/ -/* 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 - -/* pin-mux for LPC/eSPI */ -#define NPCX_DEVALT1_KBRST_SL 0 -#define NPCX_DEVALT1_A20M_SL 1 -#define NPCX_DEVALT1_SMI_SL 2 -#define NPCX_DEVALT1_EC_SCI_SL 3 -#define NPCX_DEVALT1_NO_PWRGD 4 -#define NPCX_DEVALT1_RST_OUT_SL 5 -#define NPCX_DEVALT1_CLKRN_SL 6 -#define NPCX_DEVALT1_NO_LPC_ESPI 7 - -/* pin-mux for PS2 */ -#define NPCX_DEVALT3_PS2_0_SL 0 -#define NPCX_DEVALT3_PS2_1_SL 1 -#define NPCX_DEVALT3_PS2_2_SL 2 -#define NPCX_DEVALT3_PS2_3_SL 3 -#define NPCX_DEVALTC_PS2_3_SL2 3 - -/* pin-mux for Tacho */ -#define NPCX_DEVALT3_TA1_SL1 4 -#define NPCX_DEVALT3_TB1_SL1 5 -#define NPCX_DEVALT3_TA2_SL1 6 -#define NPCX_DEVALT3_TB2_SL1 7 -#define NPCX_DEVALTC_TA1_SL2 4 -#define NPCX_DEVALTC_TB1_SL2 5 -#define NPCX_DEVALTC_TA2_SL2 6 -#define NPCX_DEVALTC_TB2_SL2 7 - -/* pin-mux for PWM */ -#define NPCX_DEVALT4_PWM0_SL 0 -#define NPCX_DEVALT4_PWM1_SL 1 -#define NPCX_DEVALT4_PWM2_SL 2 -#define NPCX_DEVALT4_PWM3_SL 3 -#define NPCX_DEVALT4_PWM4_SL 4 -#define NPCX_DEVALT4_PWM5_SL 5 -#define NPCX_DEVALT4_PWM6_SL 6 -#define NPCX_DEVALT4_PWM7_SL 7 - -/* pin-mux for JTAG */ -#define NPCX_DEVALT5_TRACE_EN 0 - -/* pin-mux for ADC */ -#define NPCX_DEVALT6_ADC0_SL 0 -#define NPCX_DEVALT6_ADC1_SL 1 -#define NPCX_DEVALT6_ADC2_SL 2 -#define NPCX_DEVALT6_ADC3_SL 3 -#define NPCX_DEVALT6_ADC4_SL 4 - -/* pin-mux for Keyboard */ -#define NPCX_DEVALT7_NO_KSI0_SL 0 -#define NPCX_DEVALT7_NO_KSI1_SL 1 -#define NPCX_DEVALT7_NO_KSI2_SL 2 -#define NPCX_DEVALT7_NO_KSI3_SL 3 -#define NPCX_DEVALT7_NO_KSI4_SL 4 -#define NPCX_DEVALT7_NO_KSI5_SL 5 -#define NPCX_DEVALT7_NO_KSI6_SL 6 -#define NPCX_DEVALT7_NO_KSI7_SL 7 -#define NPCX_DEVALT8_NO_KSO00_SL 0 -#define NPCX_DEVALT8_NO_KSO01_SL 1 -#define NPCX_DEVALT8_NO_KSO02_SL 2 -#define NPCX_DEVALT8_NO_KSO03_SL 3 -#define NPCX_DEVALT8_NO_KSO04_SL 4 -#define NPCX_DEVALT8_NO_KSO05_SL 5 -#define NPCX_DEVALT8_NO_KSO06_SL 6 -#define NPCX_DEVALT8_NO_KSO07_SL 7 -#define NPCX_DEVALT9_NO_KSO08_SL 0 -#define NPCX_DEVALT9_NO_KSO09_SL 1 -#define NPCX_DEVALT9_NO_KSO10_SL 2 -#define NPCX_DEVALT9_NO_KSO11_SL 3 -#define NPCX_DEVALT9_NO_KSO12_SL 4 -#define NPCX_DEVALT9_NO_KSO13_SL 5 -#define NPCX_DEVALT9_NO_KSO14_SL 6 -#define NPCX_DEVALT9_NO_KSO15_SL 7 -#define NPCX_DEVALTA_NO_KSO16_SL 0 -#define NPCX_DEVALTA_NO_KSO17_SL 1 - -/* pin-mux for Others */ -#define NPCX_DEVALTA_32K_OUT_SL 2 -#define NPCX_DEVALTA_NO_VCC1_RST 4 -#define NPCX_DEVALTA_NO_PECI_EN 6 -#define NPCX_DEVALTC_SHI_SL 1 - -/* Others bit definitions */ -#define NPCX_LFCGCALCNT_LPREG_CTL_EN 1 - -/******************************************************************************/ -/* Development and Debug Support (DBG) Registers */ -#define NPCX_DBGCTRL REG8(NPCX_SCFG_BASE_ADDR + 0x074) -#define NPCX_DBGFRZEN1 REG8(NPCX_SCFG_BASE_ADDR + 0x076) -#define NPCX_DBGFRZEN2 REG8(NPCX_SCFG_BASE_ADDR + 0x077) -#define NPCX_DBGFRZEN3 REG8(NPCX_SCFG_BASE_ADDR + 0x078) -/* DBG register fields */ -#define NPCX_DBGFRZEN3_GLBL_FRZ_DIS 7 - -/******************************************************************************/ -/* SMBus Registers */ -#define NPCX_SMBSDA(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x000) -#define NPCX_SMBST(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x002) -#define NPCX_SMBCST(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x004) -#define NPCX_SMBCTL1(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x006) -#define NPCX_SMBADDR1(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x008) -#define NPCX_SMBTMR_ST(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x009) -#define NPCX_SMBCTL2(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x00A) -#define NPCX_SMBTMR_EN(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x00B) -#define NPCX_SMBADDR2(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x00C) -#define NPCX_SMBCTL3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x00E) -/* SMB Registers in bank 0 */ -#define NPCX_SMBADDR3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x010) -#define NPCX_SMBADDR7(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x011) -#define NPCX_SMBADDR4(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x012) -#define NPCX_SMBADDR8(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x013) -#define NPCX_SMBADDR5(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x014) -#define NPCX_SMBADDR6(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x016) -#define NPCX_SMBCST2(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x018) -#define NPCX_SMBCST3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x019) -#define NPCX_SMBCTL4(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01A) -#define NPCX_SMBSCLLT(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01C) -#define NPCX_SMBFIF_CTL(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01D) -#define NPCX_SMBSCLHT(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01E) -/* SMB Registers in bank 1 */ -#define NPCX_SMBFIF_CTS(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x010) -#define NPCX_SMBTXF_CTL(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x012) -#define NPCX_SMB_T_OUT(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x014) -/* - * These two registers are the same as in bank 0 - * #define NPCX_SMBCST2(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x018) - * #define NPCX_SMBCST3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x019) - */ -#define NPCX_SMBTXF_STS(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01A) -#define NPCX_SMBRXF_STS(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01C) -#define NPCX_SMBRXF_CTL(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01E) - -/* SMBus register fields */ -#define NPCX_SMBST_XMIT 0 -#define NPCX_SMBST_MASTER 1 -#define NPCX_SMBST_NMATCH 2 -#define NPCX_SMBST_STASTR 3 -#define NPCX_SMBST_NEGACK 4 -#define NPCX_SMBST_BER 5 -#define NPCX_SMBST_SDAST 6 -#define NPCX_SMBST_SLVSTP 7 -#define NPCX_SMBCST_BUSY 0 -#define NPCX_SMBCST_BB 1 -#define NPCX_SMBCST_MATCH 2 -#define NPCX_SMBCST_GCMATCH 3 -#define NPCX_SMBCST_TSDA 4 -#define NPCX_SMBCST_TGSCL 5 -#define NPCX_SMBCST_MATCHAF 6 -#define NPCX_SMBCST_ARPMATCH 7 -#define NPCX_SMBCST2_MATCHA1F 0 -#define NPCX_SMBCST2_MATCHA2F 1 -#define NPCX_SMBCST2_MATCHA3F 2 -#define NPCX_SMBCST2_MATCHA4F 3 -#define NPCX_SMBCST2_MATCHA5F 4 -#define NPCX_SMBCST2_MATCHA6F 5 -#define NPCX_SMBCST2_MATCHA7F 6 -#define NPCX_SMBCST2_INTSTS 7 -#define NPCX_SMBCST3_MATCHA8F 0 -#define NPCX_SMBCST3_MATCHA9F 1 -#define NPCX_SMBCST3_MATCHA10F 2 -#define NPCX_SMBCTL1_START 0 -#define NPCX_SMBCTL1_STOP 1 -#define NPCX_SMBCTL1_INTEN 2 -#define NPCX_SMBCTL1_ACK 4 -#define NPCX_SMBCTL1_GCMEN 5 -#define NPCX_SMBCTL1_NMINTE 6 -#define NPCX_SMBCTL1_STASTRE 7 -#define NPCX_SMBCTL2_ENABLE 0 -#define NPCX_SMBCTL2_SCLFRQ7_FIELD FIELD(1, 7) -#define NPCX_SMBCTL3_ARPMEN 2 -#define NPCX_SMBCTL3_SCLFRQ2_FIELD FIELD(0, 2) -#define NPCX_SMBCTL3_IDL_START 3 -#define NPCX_SMBCTL3_400K 4 -#define NPCX_SMBCTL3_BNK_SEL 5 -#define NPCX_SMBCTL3_SDA_LVL 6 -#define NPCX_SMBCTL3_SCL_LVL 7 -#define NPCX_SMBCTL4_HLDT_FIELD FIELD(0, 6) -#define NPCX_SMBCTL4_LVL_WE 7 -#define NPCX_SMBADDR1_SAEN 7 -#define NPCX_SMBADDR2_SAEN 7 -#define NPCX_SMBADDR3_SAEN 7 -#define NPCX_SMBADDR4_SAEN 7 -#define NPCX_SMBADDR5_SAEN 7 -#define NPCX_SMBADDR6_SAEN 7 -#define NPCX_SMBADDR7_SAEN 7 -#define NPCX_SMBADDR8_SAEN 7 -#define NPCX_SMBFIF_CTS_RXF_TXE 1 -#define NPCX_SMBFIF_CTS_CLR_FIFO 6 - -#define NPCX_SMBFIF_CTL_FIFO_EN 4 - -#define NPCX_SMBRXF_STS_RX_THST 6 - -/* RX FIFO threshold */ -#define NPCX_SMBRXF_CTL_RX_THR FIELD(0, 6) -/* - * In controller receiving mode, last byte in FIFO should send ACK or NACK - */ -#define NPCX_SMBRXF_CTL_LAST 7 - -/******************************************************************************/ -/* Power Management Controller (PMC) Registers */ -#define NPCX_PMCSR REG8(NPCX_PMC_BASE_ADDR + 0x000) -#define NPCX_ENIDL_CTL REG8(NPCX_PMC_BASE_ADDR + 0x003) -#define NPCX_DISIDL_CTL REG8(NPCX_PMC_BASE_ADDR + 0x004) -#define NPCX_DISIDL_CTL1 REG8(NPCX_PMC_BASE_ADDR + 0x005) -#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 register fields */ -#define NPCX_PMCSR_DI_INSTW 0 -#define NPCX_PMCSR_DHF 1 -#define NPCX_PMCSR_IDLE 2 -#define NPCX_PMCSR_NWBI 3 -#define NPCX_PMCSR_OHFC 6 -#define NPCX_PMCSR_OLFC 7 -#define NPCX_DISIDL_CTL_RAM_DID 5 -#define NPCX_ENIDL_CTL_ADC_LFSL 7 -#define NPCX_ENIDL_CTL_LP_WK_CTL 6 -#define NPCX_ENIDL_CTL_PECI_ENI 2 -#define NPCX_ENIDL_CTL_ADC_ACC_DIS 1 -#define NPCX_PWDWN_CTL1_KBS_PD 0 -#define NPCX_PWDWN_CTL1_SDP_PD 1 -#define NPCX_PWDWN_CTL1_FIU_PD 2 -#define NPCX_PWDWN_CTL1_PS2_PD 3 -#define NPCX_PWDWN_CTL1_UART_PD 4 -#define NPCX_PWDWN_CTL1_MFT1_PD 5 -#define NPCX_PWDWN_CTL1_MFT2_PD 6 -#define NPCX_PWDWN_CTL1_MFT3_PD 7 -#define NPCX_PWDWN_CTL2_PWM0_PD 0 -#define NPCX_PWDWN_CTL2_PWM1_PD 1 -#define NPCX_PWDWN_CTL2_PWM2_PD 2 -#define NPCX_PWDWN_CTL2_PWM3_PD 3 -#define NPCX_PWDWN_CTL2_PWM4_PD 4 -#define NPCX_PWDWN_CTL2_PWM5_PD 5 -#define NPCX_PWDWN_CTL2_PWM6_PD 6 -#define NPCX_PWDWN_CTL2_PWM7_PD 7 -#define NPCX_PWDWN_CTL3_SMB0_PD 0 -#define NPCX_PWDWN_CTL3_SMB1_PD 1 -#define NPCX_PWDWN_CTL3_SMB2_PD 2 -#define NPCX_PWDWN_CTL3_SMB3_PD 3 -#define NPCX_PWDWN_CTL3_GMDA_PD 7 -#define NPCX_PWDWN_CTL4_ITIM1_PD 0 -#define NPCX_PWDWN_CTL4_ITIM2_PD 1 -#define NPCX_PWDWN_CTL4_ITIM3_PD 2 -#define NPCX_PWDWN_CTL4_ADC_PD 4 -#define NPCX_PWDWN_CTL4_PECI_PD 5 -#define NPCX_PWDWN_CTL4_PWM6_PD 6 -#define NPCX_PWDWN_CTL4_SPIP_PD 7 -#define NPCX_PWDWN_CTL5_SHI_PD 1 -#define NPCX_PWDWN_CTL5_MRFSH_DIS 2 -#define NPCX_PWDWN_CTL5_C2HACC_PD 3 -#define NPCX_PWDWN_CTL5_SHM_REG_PD 4 -#define NPCX_PWDWN_CTL5_SHM_PD 5 -#define NPCX_PWDWN_CTL5_DP80_PD 6 -#define NPCX_PWDWN_CTL5_MSWC_PD 7 -#define NPCX_PWDWN_CTL6_ITIM4_PD 0 -#define NPCX_PWDWN_CTL6_ITIM5_PD 1 -#define NPCX_PWDWN_CTL6_ITIM6_PD 2 -#define NPCX_PWDWN_CTL6_ESPI_PD 7 - -/* TODO: set PD masks based upon actual peripheral usage */ -#define CGC_KBS_MASK BIT(NPCX_PWDWN_CTL1_KBS_PD) -#define CGC_UART_MASK BIT(NPCX_PWDWN_CTL1_UART_PD) -#define CGC_FAN_MASK (BIT(NPCX_PWDWN_CTL1_MFT1_PD) | \ - BIT(NPCX_PWDWN_CTL1_MFT2_PD)) -#define CGC_FIU_MASK BIT(NPCX_PWDWN_CTL1_FIU_PD) -#define CGC_PS2_MASK BIT(NPCX_PWDWN_CTL1_PS2_PD) -#define CGC_ADC_MASK BIT(NPCX_PWDWN_CTL4_ADC_PD) -#define CGC_PECI_MASK BIT(NPCX_PWDWN_CTL4_PECI_PD) -#define CGC_SPI_MASK BIT(NPCX_PWDWN_CTL4_SPIP_PD) -#define CGC_TIMER_MASK (BIT(NPCX_PWDWN_CTL4_ITIM1_PD) | \ - BIT(NPCX_PWDWN_CTL4_ITIM2_PD) | \ - BIT(NPCX_PWDWN_CTL4_ITIM3_PD)) -#define CGC_LPC_MASK (BIT(NPCX_PWDWN_CTL5_C2HACC_PD) | \ - BIT(NPCX_PWDWN_CTL5_SHM_REG_PD) | \ - BIT(NPCX_PWDWN_CTL5_SHM_PD) | \ - BIT(NPCX_PWDWN_CTL5_DP80_PD) | \ - BIT(NPCX_PWDWN_CTL5_MSWC_PD)) -#define CGC_ESPI_MASK BIT(NPCX_PWDWN_CTL6_ESPI_PD) - -/******************************************************************************/ -/* 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 - -/******************************************************************************/ -/* Shared Memory (SHM) Registers */ -#define NPCX_SMC_STS REG8(NPCX_SHM_BASE_ADDR + 0x000) -#define NPCX_SMC_CTL REG8(NPCX_SHM_BASE_ADDR + 0x001) -#define NPCX_SHM_CTL REG8(NPCX_SHM_BASE_ADDR + 0x002) -#define NPCX_IMA_WIN_SIZE REG8(NPCX_SHM_BASE_ADDR + 0x005) -#define NPCX_WIN_SIZE REG8(NPCX_SHM_BASE_ADDR + 0x007) -#define NPCX_SHAW_SEM(win) REG8(NPCX_SHM_BASE_ADDR + 0x008 + (win)) -#define NPCX_IMA_SEM REG8(NPCX_SHM_BASE_ADDR + 0x00B) -#define NPCX_SHCFG REG8(NPCX_SHM_BASE_ADDR + 0x00E) -#define NPCX_WIN_WR_PROT(win) REG8(NPCX_SHM_BASE_ADDR + 0x010 + (win*2L)) -#define NPCX_WIN_RD_PROT(win) REG8(NPCX_SHM_BASE_ADDR + 0x011 + (win*2L)) -#define NPCX_IMA_WR_PROT REG8(NPCX_SHM_BASE_ADDR + 0x016) -#define NPCX_IMA_RD_PROT REG8(NPCX_SHM_BASE_ADDR + 0x017) -#define NPCX_WIN_BASE(win) REG32(NPCX_SHM_BASE_ADDR + 0x020 + (win*4L)) - -#define NPCX_PWIN_BASEI(win) REG16(NPCX_SHM_BASE_ADDR + 0x020 + (win*4L)) -#define NPCX_PWIN_SIZEI(win) REG16(NPCX_SHM_BASE_ADDR + 0x022 + (win*4L)) - -#define NPCX_IMA_BASE REG32(NPCX_SHM_BASE_ADDR + 0x02C) -#define NPCX_RST_CFG REG8(NPCX_SHM_BASE_ADDR + 0x03A) -#define NPCX_DP80BUF REG16(NPCX_SHM_BASE_ADDR + 0x040) -#define NPCX_DP80STS REG8(NPCX_SHM_BASE_ADDR + 0x042) -#define NPCX_DP80CTL REG8(NPCX_SHM_BASE_ADDR + 0x044) -#define NPCX_HOFS_STS REG8(NPCX_SHM_BASE_ADDR + 0x048) -#define NPCX_HOFS_CTL REG8(NPCX_SHM_BASE_ADDR + 0x049) -#define NPCX_COFS2 REG16(NPCX_SHM_BASE_ADDR + 0x04A) -#define NPCX_COFS1 REG16(NPCX_SHM_BASE_ADDR + 0x04C) -#define NPCX_IHOFS2 REG16(NPCX_SHM_BASE_ADDR + 0x050) -#define NPCX_IHOFS1 REG16(NPCX_SHM_BASE_ADDR + 0x052) -#define NPCX_SHM_VER REG8(NPCX_SHM_BASE_ADDR + 0x07F) - -/* SHM register fields */ -#define NPCX_SMC_STS_HRERR 0 -#define NPCX_SMC_STS_HWERR 1 -#define NPCX_SMC_STS_HSEM1W 4 -#define NPCX_SMC_STS_HSEM2W 5 -#define NPCX_SMC_STS_SHM_ACC 6 -#define NPCX_SMC_CTL_HERR_IE 2 -#define NPCX_SMC_CTL_HSEM1_IE 3 -#define NPCX_SMC_CTL_HSEM2_IE 4 -#define NPCX_SMC_CTL_ACC_IE 5 -#define NPCX_SMC_CTL_PREF_EN 6 -#define NPCX_SMC_CTL_HOSTWAIT 7 -#define NPCX_FLASH_SIZE_STALL_HOST 6 -#define NPCX_FLASH_SIZE_RD_BURST 7 -#define NPCX_WIN_PROT_RW1L_RP 0 -#define NPCX_WIN_PROT_RW1L_WP 1 -#define NPCX_WIN_PROT_RW1H_RP 2 -#define NPCX_WIN_PROT_RW1H_WP 3 -#define NPCX_WIN_PROT_RW2L_RP 4 -#define NPCX_WIN_PROT_RW2L_WP 5 -#define NPCX_WIN_PROT_RW2H_RP 6 -#define NPCX_WIN_PROT_RW2H_WP 7 -#define NPCX_PWIN_SIZEI_RPROT 13 -#define NPCX_PWIN_SIZEI_WPROT 14 -#define NPCX_CSEM2 6 -#define NPCX_CSEM3 7 -#define NPCX_DP80BUF_OFFS_FIELD FIELD(8, 3) -#define NPCX_DP80STS_FWR 5 -#define NPCX_DP80STS_FNE 6 -#define NPCX_DP80STS_FOR 7 -#define NPCX_DP80CTL_DP80EN 0 -#define NPCX_DP80CTL_SYNCEN 1 -#define NPCX_DP80CTL_RFIFO 4 -#define NPCX_DP80CTL_CIEN 5 - -/******************************************************************************/ -/* 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 */ -/******************************************************************************/ -/* PM Channel Registers */ -#define NPCX_HIPMST(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x000) -#define NPCX_HIPMDO(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x002) -#define NPCX_HIPMDI(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x004) -#define NPCX_SHIPMDI(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x005) -#define NPCX_HIPMDOC(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x006) -#define NPCX_HIPMDOM(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x008) -#define NPCX_HIPMDIC(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x00A) -#define NPCX_HIPMCTL(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x00C) -#define NPCX_HIPMCTL2(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x00D) -#define NPCX_HIPMIC(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x00E) -#define NPCX_HIPMIE(n) REG8(NPCX_PM_CH_BASE_ADDR(n) + 0x010) - -/* PM Channel register field */ - -/* NPCX_HIPMIE */ -#define NPCX_HIPMIE_SCIE 1 -#define NPCX_HIPMIE_SMIE 2 - -/* NPCX_HIPMCTL */ -#define NPCX_HIPMCTL_IBFIE 0 -#define NPCX_HIPMCTL_SCIPOL 6 - -/* NPCX_HIPMST */ -#define NPCX_HIPMST_F0 2 /* EC_LPC_CMDR_BUSY */ -#define NPCX_HIPMST_ST0 4 /* EC_LPC_CMDR_ACPI_BRST */ -#define NPCX_HIPMST_ST1 5 /* EC_LPC_CMDR_SCI */ -#define NPCX_HIPMST_ST2 6 /* EC_LPC_CMDR_SMI */ - -/* NPCX_HIPMIC */ -#define NPCX_HIPMIC_SMIB 1 -#define NPCX_HIPMIC_SCIB 2 -#define NPCX_HIPMIC_SMIPOL 6 - -/* - * PM Channel enumeration - */ -enum PM_CHANNEL_T { - PM_CHAN_1, - PM_CHAN_2, - PM_CHAN_3, - PM_CHAN_4 -}; - -/******************************************************************************/ -/* SuperI/O Internal Bus (SIB) Registers */ -#define NPCX_IHIOA REG16(NPCX_SIB_BASE_ADDR + 0x000) -#define NPCX_IHD REG8(NPCX_SIB_BASE_ADDR + 0x002) -#define NPCX_LKSIOHA REG16(NPCX_SIB_BASE_ADDR + 0x004) -#define NPCX_SIOLV REG16(NPCX_SIB_BASE_ADDR + 0x006) -#define NPCX_CRSMAE REG16(NPCX_SIB_BASE_ADDR + 0x008) -#define NPCX_SIBCTRL REG8(NPCX_SIB_BASE_ADDR + 0x00A) -#define NPCX_C2H_VER REG8(NPCX_SIB_BASE_ADDR + 0x00E) -/* SIB register fields */ -#define NPCX_SIBCTRL_CSAE 0 -#define NPCX_SIBCTRL_CSRD 1 -#define NPCX_SIBCTRL_CSWR 2 -#define NPCX_LKSIOHA_LKCFG 0 -#define NPCX_LKSIOHA_LKHIKBD 11 -#define NPCX_CRSMAE_CFGAE 0 -#define NPCX_CRSMAE_HIKBDAE 11 - -/******************************************************************************/ -/* Battery-Backed RAM (BBRAM) Registers */ -#define NPCX_BKUP_STS REG8(NPCX_BBRAM_BASE_ADDR + 0x100) -#define NPCX_BBRAM(offset) REG8(NPCX_BBRAM_BASE_ADDR + offset) - -/* BBRAM register fields */ -#define NPCX_BKUP_STS_IBBR 7 - -/******************************************************************************/ -/* 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 - -/******************************************************************************/ -/* PECI Registers */ - -#define NPCX_PECI_CTL_STS REG8(NPCX_PECI_BASE_ADDR + 0x000) -#define NPCX_PECI_RD_LENGTH REG8(NPCX_PECI_BASE_ADDR + 0x001) -#define NPCX_PECI_ADDR REG8(NPCX_PECI_BASE_ADDR + 0x002) -#define NPCX_PECI_CMD REG8(NPCX_PECI_BASE_ADDR + 0x003) -#define NPCX_PECI_CTL2 REG8(NPCX_PECI_BASE_ADDR + 0x004) -#define NPCX_PECI_INDEX REG8(NPCX_PECI_BASE_ADDR + 0x005) -#define NPCX_PECI_IDATA REG8(NPCX_PECI_BASE_ADDR + 0x006) -#define NPCX_PECI_WR_LENGTH REG8(NPCX_PECI_BASE_ADDR + 0x007) -#define NPCX_PECI_CFG REG8(NPCX_PECI_BASE_ADDR + 0x009) -#define NPCX_PECI_RATE REG8(NPCX_PECI_BASE_ADDR + 0x00F) -#define NPCX_PECI_DATA_IN(i) REG8(NPCX_PECI_BASE_ADDR + 0x010 + (i)) -#define NPCX_PECI_DATA_OUT(i) REG8(NPCX_PECI_BASE_ADDR + 0x010 + (i)) - -/* PECI register fields */ -#define NPCX_PECI_CTL_STS_START_BUSY 0 -#define NPCX_PECI_CTL_STS_DONE 1 -#define NPCX_PECI_CTL_STS_AVL_ERR 2 -#define NPCX_PECI_CTL_STS_CRC_ERR 3 -#define NPCX_PECI_CTL_STS_ABRT_ERR 4 -#define NPCX_PECI_CTL_STS_AWFCS_EN 5 -#define NPCX_PECI_CTL_STS_DONE_EN 6 -#define NPCX_ESTRPST_PECIST 0 -#define SFT_STRP_CFG_CK50 5 - -/******************************************************************************/ -/* PWM Registers */ -#define NPCX_PRSC(n) REG16(NPCX_PWM_BASE_ADDR(n) + 0x000) -#define NPCX_CTR(n) REG16(NPCX_PWM_BASE_ADDR(n) + 0x002) -#define NPCX_PWMCTL(n) REG8(NPCX_PWM_BASE_ADDR(n) + 0x004) -#define NPCX_DCR(n) REG16(NPCX_PWM_BASE_ADDR(n) + 0x006) -#define NPCX_PWMCTLEX(n) REG8(NPCX_PWM_BASE_ADDR(n) + 0x00C) - -/* PWM register fields */ -#define NPCX_PWMCTL_INVP 0 -#define NPCX_PWMCTL_CKSEL 1 -#define NPCX_PWMCTL_HB_DC_CTL_FIELD FIELD(2, 2) -#define NPCX_PWMCTL_PWR 7 -#define NPCX_PWMCTLEX_FCK_SEL_FIELD FIELD(4, 2) -#define NPCX_PWMCTLEX_OD_OUT 7 -/******************************************************************************/ -/* MFT Registers */ -#define NPCX_TCNT1(n) REG16(NPCX_MFT_BASE_ADDR(n) + 0x000) -#define NPCX_TCRA(n) REG16(NPCX_MFT_BASE_ADDR(n) + 0x002) -#define NPCX_TCRB(n) REG16(NPCX_MFT_BASE_ADDR(n) + 0x004) -#define NPCX_TCNT2(n) REG16(NPCX_MFT_BASE_ADDR(n) + 0x006) -#define NPCX_TPRSC(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x008) -#define NPCX_TCKC(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x00A) -#define NPCX_TMCTRL(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x00C) -#define NPCX_TECTRL(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x00E) -#define NPCX_TECLR(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x010) -#define NPCX_TIEN(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x012) -#define NPCX_TWUEN(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x01A) -#define NPCX_TCFG(n) REG8(NPCX_MFT_BASE_ADDR(n) + 0x01C) - -/* MFT register fields */ -#define NPCX_TMCTRL_MDSEL_FIELD FIELD(0, 3) -#define NPCX_TCKC_LOW_PWR 7 -#define NPCX_TCKC_PLS_ACC_CLK 6 -#define NPCX_TCKC_C1CSEL_FIELD FIELD(0, 3) -#define NPCX_TCKC_C2CSEL_FIELD FIELD(3, 3) -#define NPCX_TMCTRL_TAEN 5 -#define NPCX_TMCTRL_TBEN 6 -#define NPCX_TMCTRL_TAEDG 3 -#define NPCX_TMCTRL_TBEDG 4 -#define NPCX_TCFG_TADBEN 6 -#define NPCX_TCFG_TBDBEN 7 -#define NPCX_TECTRL_TAPND 0 -#define NPCX_TECTRL_TBPND 1 -#define NPCX_TECTRL_TCPND 2 -#define NPCX_TECTRL_TDPND 3 -#define NPCX_TECLR_TACLR 0 -#define NPCX_TECLR_TBCLR 1 -#define NPCX_TECLR_TCCLR 2 -#define NPCX_TECLR_TDCLR 3 -#define NPCX_TIEN_TAIEN 0 -#define NPCX_TIEN_TBIEN 1 -#define NPCX_TIEN_TCIEN 2 -#define NPCX_TIEN_TDIEN 3 -#define NPCX_TWUEN_TAWEN 0 -#define NPCX_TWUEN_TBWEN 1 -#define NPCX_TWUEN_TCWEN 2 -#define NPCX_TWUEN_TDWEN 3 -/******************************************************************************/ -/* ITIM16/32 Define */ -#define ITIM_INT(module) CONCAT2(NPCX_IRQ_, module) - -/* ITIM16/32 register */ -#define NPCX_ITPRE(n) REG8(NPCX_ITIM_BASE_ADDR(n) + 0x001) -#define NPCX_ITCTS(n) REG8(NPCX_ITIM_BASE_ADDR(n) + 0x004) - -/* ITIM16 register fields */ -#define NPCX_ITCTS_TO_STS 0 -#define NPCX_ITCTS_TO_IE 2 -#define NPCX_ITCTS_TO_WUE 3 -#define NPCX_ITCTS_CKSEL 4 -#define NPCX_ITCTS_ITEN 7 - -/******************************************************************************/ -/* Serial Host Interface (SHI) Registers */ -#define NPCX_SHICFG1 REG8(NPCX_SHI_BASE_ADDR + 0x001) -#define NPCX_SHICFG2 REG8(NPCX_SHI_BASE_ADDR + 0x002) -#define NPCX_I2CADDR1 REG8(NPCX_SHI_BASE_ADDR + 0x003) -#define NPCX_I2CADDR2 REG8(NPCX_SHI_BASE_ADDR + 0x004) -#define NPCX_EVENABLE REG8(NPCX_SHI_BASE_ADDR + 0x005) -#define NPCX_EVSTAT REG8(NPCX_SHI_BASE_ADDR + 0x006) -#define NPCX_SHI_CAPABILITY REG8(NPCX_SHI_BASE_ADDR + 0x007) -#define NPCX_STATUS REG8(NPCX_SHI_BASE_ADDR + 0x008) -#define NPCX_IBUFSTAT REG8(NPCX_SHI_BASE_ADDR + 0x00A) -#define NPCX_OBUFSTAT REG8(NPCX_SHI_BASE_ADDR + 0x00B) - -/* SHI register fields */ -#define NPCX_SHICFG1_EN 0 -#define NPCX_SHICFG1_MODE 1 -#define NPCX_SHICFG1_WEN 2 -#define NPCX_SHICFG1_AUTIBF 3 -#define NPCX_SHICFG1_AUTOBE 4 -#define NPCX_SHICFG1_DAS 5 -#define NPCX_SHICFG1_CPOL 6 -#define NPCX_SHICFG1_IWRAP 7 -#define NPCX_SHICFG2_SIMUL 0 -#define NPCX_SHICFG2_BUSY 1 -#define NPCX_SHICFG2_ONESHOT 2 -#define NPCX_SHICFG2_SLWU 3 -#define NPCX_SHICFG2_REEN 4 -#define NPCX_SHICFG2_RESTART 5 -#define NPCX_SHICFG2_REEVEN 6 -#define NPCX_EVENABLE_OBEEN 0 -#define NPCX_EVENABLE_OBHEEN 1 -#define NPCX_EVENABLE_IBFEN 2 -#define NPCX_EVENABLE_IBHFEN 3 -#define NPCX_EVENABLE_EOREN 4 -#define NPCX_EVENABLE_EOWEN 5 -#define NPCX_EVENABLE_STSREN 6 -#define NPCX_EVENABLE_IBOREN 7 -#define NPCX_EVSTAT_OBE 0 -#define NPCX_EVSTAT_OBHE 1 -#define NPCX_EVSTAT_IBF 2 -#define NPCX_EVSTAT_IBHF 3 -#define NPCX_EVSTAT_EOR 4 -#define NPCX_EVSTAT_EOW 5 -#define NPCX_EVSTAT_STSR 6 -#define NPCX_EVSTAT_IBOR 7 -#define NPCX_STATUS_OBES 6 -#define NPCX_STATUS_IBFS 7 - -/******************************************************************************/ -/* Monotonic Counter (MTC) Registers */ -#define NPCX_TTC REG32(NPCX_MTC_BASE_ADDR + 0x000) -#define NPCX_WTC REG32(NPCX_MTC_BASE_ADDR + 0x004) -#define NPCX_MTCTST REG8(NPCX_MTC_BASE_ADDR + 0x008) -#define NPCX_MTCVER REG8(NPCX_MTC_BASE_ADDR + 0x00C) - -/* MTC register fields */ -#define NPCX_WTC_PTO 30 -#define NPCX_WTC_WIE 31 - -/******************************************************************************/ -/* Low Power RAM definitions */ -#define NPCX_LPRAM_CTRL REG32(0x40001044) - -/******************************************************************************/ -/* eSPI Registers */ -#define NPCX_ESPIID REG32(NPCX_ESPI_BASE_ADDR + 0X00) -#define NPCX_ESPICFG REG32(NPCX_ESPI_BASE_ADDR + 0X04) -#define NPCX_ESPISTS REG32(NPCX_ESPI_BASE_ADDR + 0X08) -#define NPCX_ESPIIE REG32(NPCX_ESPI_BASE_ADDR + 0X0C) -#define NPCX_ESPIWE REG32(NPCX_ESPI_BASE_ADDR + 0X10) -#define NPCX_VWREGIDX REG32(NPCX_ESPI_BASE_ADDR + 0X14) -#define NPCX_VWREGDATA REG32(NPCX_ESPI_BASE_ADDR + 0X18) -#define NPCX_OOBCTL REG32(NPCX_ESPI_BASE_ADDR + 0X24) -#define NPCX_FLASHRXRDHEAD REG32(NPCX_ESPI_BASE_ADDR + 0X28) -#define NPCX_FLASHTXWRHEAD REG32(NPCX_ESPI_BASE_ADDR + 0X2C) -#define NPCX_FLASHCFG REG32(NPCX_ESPI_BASE_ADDR + 0X34) -#define NPCX_FLASHCTL REG32(NPCX_ESPI_BASE_ADDR + 0X38) -#define NPCX_ESPIERR REG32(NPCX_ESPI_BASE_ADDR + 0X3C) - -/* eSPI Virtual Wire channel registers */ -#define NPCX_VWEVSM(n) REG32(NPCX_ESPI_BASE_ADDR + 0x100 + (4*(n))) -#define NPCX_VWEVMS(n) REG32(NPCX_ESPI_BASE_ADDR + 0x140 + (4*(n))) -#define NPCX_VWCTL REG32(NPCX_ESPI_BASE_ADDR + 0x2FC) - -/* eSPI register fields */ -#define NPCX_ESPICFG_PCHANEN 0 -#define NPCX_ESPICFG_VWCHANEN 1 -#define NPCX_ESPICFG_OOBCHANEN 2 -#define NPCX_ESPICFG_FLASHCHANEN 3 -#define NPCX_ESPICFG_HPCHANEN 4 -#define NPCX_ESPICFG_HVWCHANEN 5 -#define NPCX_ESPICFG_HOOBCHANEN 6 -#define NPCX_ESPICFG_HFLASHCHANEN 7 -#define NPCX_ESPICFG_IOMODE_FIELD FIELD(8, 2) -#define NPCX_ESPICFG_MAXFREQ_FIELD FIELD(10, 3) -#define NPCX_ESPICFG_OPFREQ_FIELD FIELD(17, 3) -#define NPCX_ESPICFG_IOMODESEL_FIELD FIELD(20, 2) -#define NPCX_ESPICFG_ALERT_MODE 22 -#define NPCX_ESPICFG_CRC_CHK 23 -#define NPCX_ESPICFG_PCCHN_SUPP 24 -#define NPCX_ESPICFG_VWCHN_SUPP 25 -#define NPCX_ESPICFG_OOBCHN_SUPP 26 -#define NPCX_ESPICFG_FLASHCHN_SUPP 27 -#define NPCX_ESPIERR_INVCMD 0 /* Invalid Command Type */ -#define NPCX_ESPIERR_INVCYC 1 /* Invalid Cycle Type */ -#define NPCX_ESPIERR_CRCERR 2 /* Transaction CRC Error */ -#define NPCX_ESPIERR_ABCOMP 3 /* Abnormal Completion */ -#define NPCX_ESPIERR_PROTERR 4 /* Protocol Error */ -#define NPCX_ESPIERR_BADSIZE 5 /* Bad Size */ -#define NPCX_ESPIERR_NPBADALN 6 /* NPPC Bad Address Alignment */ -#define NPCX_ESPIERR_PCBADALN 7 /* PPC Bad Address Alignment */ -#define NPCX_ESPIERR_UNCMD 9 /* Unsupported Command */ -#define NPCX_ESPIERR_EXTRACYC 10 /* Extra eSPI Clock Cycles */ -#define NPCX_ESPIERR_VWERR 11 /* Virtual Channel Access Error */ -#define NPCX_ESPIERR_UNPBM 14 /* Unsuccessful Bus Completion */ -#define NPCX_ESPIERR_UNFLASH 15 /* Unsuccessful Flash Completion */ -#define NPCX_ESPIIE_IBRSTIE 0 -#define NPCX_ESPIIE_CFGUPDIE 1 -#define NPCX_ESPIIE_BERRIE 2 -#define NPCX_ESPIIE_OOBRXIE 3 -#define NPCX_ESPIIE_FLASHRXIE 4 -#define NPCX_ESPIIE_SFLASHRDIE 5 -#define NPCX_ESPIIE_PERACCIE 6 -#define NPCX_ESPIIE_DFRDIE 7 -#define NPCX_ESPIIE_VWUPDIE 8 -#define NPCX_ESPIIE_ESPIRSTIE 9 -#define NPCX_ESPIIE_PLTRSTIE 10 -#define NPCX_ESPIIE_AMERRIE 15 -#define NPCX_ESPIIE_AMDONEIE 16 -#define NPCX_ESPIWE_IBRSTWE 0 -#define NPCX_ESPIWE_CFGUPDWE 1 -#define NPCX_ESPIWE_BERRWE 2 -#define NPCX_ESPIWE_OOBRXWE 3 -#define NPCX_ESPIWE_FLASHRXWE 4 -#define NPCX_ESPIWE_PERACCWE 6 -#define NPCX_ESPIWE_DFRDWE 7 -#define NPCX_ESPIWE_VWUPDWE 8 -#define NPCX_ESPIWE_ESPIRSTWE 9 -#define NPCX_ESPISTS_IBRST 0 -#define NPCX_ESPISTS_CFGUPD 1 -#define NPCX_ESPISTS_BERR 2 -#define NPCX_ESPISTS_OOBRX 3 -#define NPCX_ESPISTS_FLASHRX 4 -#define NPCX_ESPISTS_SFLASHRD 5 -#define NPCX_ESPISTS_PERACC 6 -#define NPCX_ESPISTS_DFRD 7 -#define NPCX_ESPISTS_VWUPD 8 -#define NPCX_ESPISTS_ESPIRST 9 -#define NPCX_ESPISTS_PLTRST 10 -#define NPCX_ESPISTS_AMERR 15 -#define NPCX_ESPISTS_AMDONE 16 -/* eSPI Virtual Wire channel register fields */ -#define NPCX_VWEVSM_WIRE FIELD(0, 4) -#define NPCX_VWEVMS_WIRE FIELD(0, 4) -#define NPCX_VWEVSM_VALID FIELD(4, 4) -#define NPCX_VWEVMS_VALID FIELD(4, 4) - -/* Macro functions for eSPI CFG & IE */ -#define IS_PERIPHERAL_CHAN_ENABLE(ch) IS_BIT_SET(NPCX_ESPICFG, ch) -#define IS_HOST_CHAN_EN(ch) IS_BIT_SET(NPCX_ESPICFG, (ch+4)) -#define ENABLE_ESPI_CHAN(ch) SET_BIT(NPCX_ESPICFG, ch) -#define DISABLE_ESPI_CHAN(ch) CLEAR_BIT(NPCX_ESPICFG, ch) -/* ESPI Peripheral Channel Support Definitions */ -#define ESPI_SUPP_CH_PC BIT(NPCX_ESPICFG_PCCHN_SUPP) -#define ESPI_SUPP_CH_VM BIT(NPCX_ESPICFG_VWCHN_SUPP) -#define ESPI_SUPP_CH_OOB BIT(NPCX_ESPICFG_OOBCHN_SUPP) -#define ESPI_SUPP_CH_FLASH BIT(NPCX_ESPICFG_FLASHCHN_SUPP) -#define ESPI_SUPP_CH_ALL (ESPI_SUPP_CH_PC | ESPI_SUPP_CH_VM | \ - ESPI_SUPP_CH_OOB | ESPI_SUPP_CH_FLASH) -/* ESPI Interrupts Enable Definitions */ -#define ESPIIE_IBRST BIT(NPCX_ESPIIE_IBRSTIE) -#define ESPIIE_CFGUPD BIT(NPCX_ESPIIE_CFGUPDIE) -#define ESPIIE_BERR BIT(NPCX_ESPIIE_BERRIE) -#define ESPIIE_OOBRX BIT(NPCX_ESPIIE_OOBRXIE) -#define ESPIIE_FLASHRX BIT(NPCX_ESPIIE_FLASHRXIE) -#define ESPIIE_SFLASHRD BIT(NPCX_ESPIIE_SFLASHRDIE) -#define ESPIIE_PERACC BIT(NPCX_ESPIIE_PERACCIE) -#define ESPIIE_DFRD BIT(NPCX_ESPIIE_DFRDIE) -#define ESPIIE_VWUPD BIT(NPCX_ESPIIE_VWUPDIE) -#define ESPIIE_ESPIRST BIT(NPCX_ESPIIE_ESPIRSTIE) -#define ESPIIE_PLTRST BIT(NPCX_ESPIIE_PLTRSTIE) -#define ESPIIE_AMERR BIT(NPCX_ESPIIE_AMERRIE) -#define ESPIIE_AMDONE BIT(NPCX_ESPIIE_AMDONEIE) -/* eSPI Interrupts for VW */ -#define ESPIIE_VW (ESPIIE_VWUPD | ESPIIE_PLTRST) -/* eSPI Interrupts for Generic */ -#define ESPIIE_GENERIC (ESPIIE_IBRST | ESPIIE_CFGUPD | \ - ESPIIE_BERR | ESPIIE_ESPIRST) -/* ESPI Wake-up Enable Definitions */ -#define ESPIWE_IBRST BIT(NPCX_ESPIWE_IBRSTWE) -#define ESPIWE_CFGUPD BIT(NPCX_ESPIWE_CFGUPDWE) -#define ESPIWE_BERR BIT(NPCX_ESPIWE_BERRWE) -#define ESPIWE_OOBRX BIT(NPCX_ESPIWE_OOBRXWE) -#define ESPIWE_FLASHRX BIT(NPCX_ESPIWE_FLASHRXWE) -#define ESPIWE_PERACC BIT(NPCX_ESPIWE_PERACCWE) -#define ESPIWE_DFRD BIT(NPCX_ESPIWE_DFRDWE) -#define ESPIWE_VWUPD BIT(NPCX_ESPIWE_VWUPDWE) -#define ESPIWE_ESPIRST BIT(NPCX_ESPIWE_ESPIRSTWE) -/* eSPI Wake-up enable for VW */ -#define ESPIWE_VW ESPIWE_VWUPD -/* eSPI Wake-up enable for Generic */ -#define ESPIWE_GENERIC (ESPIWE_IBRST | ESPIWE_CFGUPD | \ - ESPIWE_BERR) -/* Macro functions for eSPI VW */ -#define ESPI_VWEVMS_NUM 12 -#define ESPI_VWEVSM_NUM 10 -#define ESPI_VW_IDX_WIRE_NUM 4 -/* Determine Virtual Wire type */ -#define VM_TYPE(i) ((i >= 0 && i <= 1) ? ESPI_VW_TYPE_INT_EV : \ - (i >= 2 && i <= 7) ? ESPI_VW_TYPE_SYS_EV : \ - (i >= 64 && i <= 127) ? ESPI_VW_TYPE_PLT : \ - (i >= 128 && i <= 255) ? ESPI_VW_TYPE_GPIO : \ - ESPI_VW_TYPE_NONE) - -/* Bit field manipulation for VWEVMS Value */ -#define VWEVMS_INX(i) ((i<<8) & 0x00007F00) -#define VWEVMS_INX_EN(n) ((n<<15) & 0x00008000) -#define VWEVMS_PLTRST_EN(p) ((p<<17) & 0x00020000) -#define VWEVMS_INT_EN(e) ((e<<18) & 0x00040000) -#define VWEVMS_ESPIRST_EN(r) ((r<<19) & 0x00080000) -#define VWEVMS_FIELD(i, n, p, e, r) (VWEVMS_INX(i) | VWEVMS_INX_EN(n) | \ - VWEVMS_PLTRST_EN(p) | VWEVMS_INTWK_EN(e) | \ - VWEVMS_ESPIRST_EN(r)) -#define VWEVMS_IDX_GET(reg) (((reg & 0x00007F00)>>8)) - -/* Bit field manipulation for VWEVSM Value */ -#define VWEVSM_VALID_N(v) ((v<<4) & 0x000000F0) -#define VWEVSM_INX(i) ((i<<8) & 0x00007F00) -#define VWEVSM_INX_EN(n) ((n<<15) & 0x00008000) -#define VWEVSM_DIRTY(d) ((d<<16) & 0x00010000) -#define VWEVSM_PLTRST_EN(p) ((p<<17) & 0x00020000) -#define VWEVSM_CDRST_EN(c) ((c<<19) & 0x00080000) -#define VWEVSM_FIELD(i, n, v, p, c) (VWEVSM_INX(i) | VWEVSM_INX_EN(n) | \ - VWEVSM_VALID_N(v) | VWEVSM_PLTRST_EN(p) |\ - VWEVSM_CDRST_EN(c)) -#define VWEVSM_IDX_GET(reg) (((reg & 0x00007F00)>>8)) - -/* define macro to handle SMI/SCI Virtual Wire */ -/* Read SMI VWire status from VWEVSM(offset 2) register. */ -#define SMI_STATUS_MASK ((uint8_t) (NPCX_VWEVSM(2) & 0x00000002)) -/* - * Read SCI VWire status from VWEVSM(offset 2) register. - * Left shift 2 to meet the SCIB field in HIPMIC register. - */ -#define SCI_STATUS_MASK (((uint8_t) (NPCX_VWEVSM(2) & 0x00000001)) << 2) -#define SCIB_MASK(v) (v << NPCX_HIPMIC_SCIB) -#define SMIB_MASK(v) (v << NPCX_HIPMIC_SMIB) -#define NPCX_VW_SCI(level) ((NPCX_HIPMIC(PM_CHAN_1) & 0xF9) | \ - SMI_STATUS_MASK | SCIB_MASK(level)) -#define NPCX_VW_SMI(level) ((NPCX_HIPMIC(PM_CHAN_1) & 0xF9) | \ - SCI_STATUS_MASK | SMIB_MASK(level)) - -/* eSPI enumeration */ -/* eSPI channels */ -enum { - NPCX_ESPI_CH_PC = 0, - NPCX_ESPI_CH_VW, - NPCX_ESPI_CH_OOB, - NPCX_ESPI_CH_FLASH, - NPCX_ESPI_CH_COUNT, - NPCX_ESPI_CH_GENERIC, - NPCX_ESPI_CH_NONE = 0xFF -}; - -/* eSPI IO modes */ -enum { - NPCX_ESPI_IO_MODE_SINGLE = 0, - NPCX_ESPI_IO_MODE_DUAL = 1, - NPCX_ESPI_IO_MODE_QUAD = 2, - NPCX_ESPI_IO_MODE_ALL = 3, - NPCX_ESPI_IO_MODE_NONE = 0xFF -}; - -/* eSPI IO mode selected */ -enum { - NPCX_ESPI_IO_MODE_SEL_SINGLE = 0, - NPCX_ESPI_IO_MODE_SEL_DUAL = 1, - NPCX_ESPI_IO_MODE_SEL_QUARD = 2, - NPCX_ESPI_IO_MODE_SEL_NONE = 0xFF -}; - -/* VW types */ -enum { - ESPI_VW_TYPE_INT_EV, /* Interrupt event */ - ESPI_VW_TYPE_SYS_EV, /* System Event */ - ESPI_VW_TYPE_PLT, /* Platform specific */ - ESPI_VW_TYPE_GPIO, /* General Purpose I/O Expander */ - ESPI_VW_TYPE_NUM, - ESPI_VW_TYPE_NONE = 0xFF -}; - -/******************************************************************************/ -/* GDMA (General DMA) Registers */ -#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) -#define NPCX_GDMA_CSRC REG32(NPCX_GDMA_BASE_ADDR + 0x010) -#define NPCX_GDMA_CDST REG32(NPCX_GDMA_BASE_ADDR + 0x014) -#define NPCX_GDMA_CTCNT REG32(NPCX_GDMA_BASE_ADDR + 0x018) - - -/******************************************************************************/ -/* GDMA register fields */ -#define NPCX_GDMA_CTL_GDMAEN 0 -#define NPCX_GDMA_CTL_GDMAMS FIELD(2, 2) -#define NPCX_GDMA_CTL_DADIR 4 -#define NPCX_GDMA_CTL_SADIR 5 -#define NPCX_GDMA_CTL_SAFIX 7 -#define NPCX_GDMA_CTL_SIEN 8 -#define NPCX_GDMA_CTL_BME 9 -#define NPCX_GDMA_CTL_SBMS 11 -#define NPCX_GDMA_CTL_TWS FIELD(12, 2) -#define NPCX_GDMA_CTL_DM 15 -#define NPCX_GDMA_CTL_SOFTREQ 16 -#define NPCX_GDMA_CTL_TC 18 -#define NPCX_GDMA_CTL_GDMAERR 20 -#define NPCX_GDMA_CTL_BLOCK_BUG_CORRECTION_DISABLE 26 - -/******************************************************************************/ -/* Nuvoton internal used only registers */ -#define NPCX_INTERNAL_CTRL1 REG8(0x400DB000) -#define NPCX_INTERNAL_CTRL2 REG8(0x400DD000) -#define NPCX_INTERNAL_CTRL3 REG8(0x400DF000) - -/******************************************************************************/ -/* Optional M4 Registers */ -#define CPU_DHCSR REG32(0xE000EDF0) -#define CPU_MPU_CTRL REG32(0xE000ED94) -#define CPU_MPU_RNR REG32(0xE000ED98) -#define CPU_MPU_RBAR REG32(0xE000ED9C) -#define CPU_MPU_RASR REG32(0xE000EDA0) - - -/******************************************************************************/ -/* 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)) - -/******************************************************************************/ -/* APM (Audio Processing Module) Registers */ -#define NPCX_APM_SR REG8(NPCX_APM_BASE_ADDR + 0x000) -#define NPCX_APM_SR2 REG8(NPCX_APM_BASE_ADDR + 0x004) -#define NPCX_APM_ICR REG8(NPCX_APM_BASE_ADDR + 0x008) -#define NPCX_APM_IMR REG8(NPCX_APM_BASE_ADDR + 0x00C) -#define NPCX_APM_IFR REG8(NPCX_APM_BASE_ADDR + 0x010) -#define NPCX_APM_CR_APM REG8(NPCX_APM_BASE_ADDR + 0x014) -#define NPCX_APM_CR_CK REG8(NPCX_APM_BASE_ADDR + 0x018) -#define NPCX_APM_AICR_ADC REG8(NPCX_APM_BASE_ADDR + 0x01C) -#define NPCX_APM_FCR_ADC REG8(NPCX_APM_BASE_ADDR + 0x020) -#define NPCX_APM_CR_DMIC REG8(NPCX_APM_BASE_ADDR + 0x02C) -#define NPCX_APM_CR_ADC REG8(NPCX_APM_BASE_ADDR + 0x030) -#define NPCX_APM_CR_MIX REG8(NPCX_APM_BASE_ADDR + 0x034) -#define NPCX_APM_DR_MIX REG8(NPCX_APM_BASE_ADDR + 0x038) -#define NPCX_APM_GCR_ADCL REG8(NPCX_APM_BASE_ADDR + 0x03C) -#define NPCX_APM_GCR_ADCR REG8(NPCX_APM_BASE_ADDR + 0x040) -#define NPCX_APM_GCR_MIXADCL REG8(NPCX_APM_BASE_ADDR + 0x044) -#define NPCX_APM_GCR_MIXADCR REG8(NPCX_APM_BASE_ADDR + 0x048) -#define NPCX_APM_CR_ADC_AGC REG8(NPCX_APM_BASE_ADDR + 0x04C) -#define NPCX_APM_DR_ADC_AGC REG8(NPCX_APM_BASE_ADDR + 0x050) -#define NPCX_APM_SR_ADC_AGCDGL REG8(NPCX_APM_BASE_ADDR + 0x054) -#define NPCX_APM_SR_ADC_AGCDGR REG8(NPCX_APM_BASE_ADDR + 0x058) -#define NPCX_APM_CR_VAD REG8(NPCX_APM_BASE_ADDR + 0x05C) -#define NPCX_APM_DR_VAD REG8(NPCX_APM_BASE_ADDR + 0x060) -#define NPCX_APM_CR_VAD_CMD REG8(NPCX_APM_BASE_ADDR + 0x064) -#define NPCX_APM_CR_TR REG8(NPCX_APM_BASE_ADDR + 0x068) -#define NPCX_APM_DR_TR REG8(NPCX_APM_BASE_ADDR + 0x06C) -#define NPCX_APM_SR_TR1 REG8(NPCX_APM_BASE_ADDR + 0x070) -#define NPCX_APM_SR_TR_SRCADC REG8(NPCX_APM_BASE_ADDR + 0x074) - -/******************************************************************************/ -/* APM register fields */ -#define NPCX_APM_SR_IRQ_PEND 6 -#define NPCX_APM_SR2_SMUTEIP 6 -#define NPCX_APM_ICR_INTR_MODE FIELD(6, 2) -#define NPCX_APM_IMR_VAD_DTC_MASK 6 -#define NPCX_APM_IFR_VAD_DTC 6 -#define NPCX_APM_CR_APM_PD 0 -#define NPCX_APM_CR_APM_AGC_DIS FIELD(1, 2) -#define NPCX_APM_CR_CK_MCLK_FREQ FIELD(0, 2) -#define NPCX_APM_AICR_ADC_ADC_AUDIOIF FIELD(0, 2) -#define NPCX_APM_AICR_ADC_PD_AICR_ADC 4 -#define NPCX_APM_AICR_ADC_ADC_ADWL FIELD(6, 2) -#define NPCX_APM_FCR_ADC_ADC_FREQ FIELD(0, 4) -#define NPCX_APM_FCR_ADC_ADC_WNF FIELD(4, 2) -#define NPCX_APM_FCR_ADC_ADC_HPF 6 -#define NPCX_APM_CR_DMIC_ADC_DMIC_SEL_RIGHT FIELD(0, 2) -#define NPCX_APM_CR_DMIC_ADC_DMIC_SEL_LEFT FIELD(2, 2) -#define NPCX_APM_CR_DMIC_ADC_DMIC_RATE FIELD(4, 3) -#define NPCX_APM_CR_DMIC_PD_DMIC 7 -#define NPCX_APM_CR_ADC_ADC_SOFT_MUTE 7 -#define NPCX_APM_CR_MIX_MIX_ADD FIELD(0, 6) -#define NPCX_APM_CR_MIX_MIX_LOAD 6 -#define NPCX_APM_DR_MIX_MIX_DATA FIELD(0, 8) -#define NPCX_APM_MIX_2_AIADCR_SEL FIELD(4, 2) -#define NPCX_APM_MIX_2_AIADCL_SEL FIELD(6, 2) -#define NPCX_APM_GCR_ADCL_GIDL FIELD(0, 6) -#define NPCX_APM_GCR_ADCL_LRGID 7 -#define NPCX_APM_GCR_ADCR_GIDR FIELD(0, 6) -#define NPCX_APM_GCR_MIXADCL_GIMIXL FIELD(0, 6) -#define NPCX_APM_GCR_MIXADCR_GIMIXR FIELD(0, 6) -#define NPCX_APM_CR_ADC_AGC_ADC_AGC_ADD FIELD(0, 6) -#define NPCX_APM_CR_ADC_AGC_ADC_AGC_LOAD 6 -#define NPCX_APM_CR_ADC_AGC_ADC_AGC_EN 7 -#define NPCX_APM_DR_ADC_AGC_ADC_AGC_DATA FIELD(0, 8) -#define NPCX_ADC_AGC_0_AGC_TARGET FIELD(2, 4) -#define NPCX_ADC_AGC_0_AGC_STEREO 6 -#define NPCX_ADC_AGC_1_HOLD FIELD(0, 4) -#define NPCX_ADC_AGC_1_NG_THR FIELD(4, 3) -#define NPCX_ADC_AGC_1_NG_EN 7 -#define NPCX_ADC_AGC_2_DCY FIELD(0, 4) -#define NPCX_ADC_AGC_2_ATK FIELD(4, 4) -#define NPCX_ADC_AGC_3_AGC_MAX FIELD(0, 5) -#define NPCX_ADC_AGC_4_AGC_MIN FIELD(0, 5) -#define NPCX_APM_CR_VAD_VAD_ADD FIELD(0, 6) -#define NPCX_APM_CR_VAD_VAD_LOAD 6 -#define NPCX_APM_CR_VAD_VAD_EN 7 -#define NPCX_APM_DR_VAD_VAD_DATA FIELD(0, 8) -#define NPCX_APM_CR_VAD_CMD_VAD_RESTART 0 -#define NPCX_APM_CR_TR_FAST_ON 7 -#define NPCX_VAD_0_VAD_INSEL FIELD(0, 2) -#define NPCX_VAD_0_VAD_DMIC_FREQ FIELD(2, 3) -#define NPCX_VAD_0_VAD_ADC_WAKEUP 5 -#define NPCX_VAD_0_ZCD_EN 6 -#define NPCX_VAD_1_VAD_POWER_SENS FIELD(0, 5) -#define NPCX_APM_CONTROL_ADD FIELD(0, 6) -#define NPCX_APM_CONTROL_LOAD 6 - -/******************************************************************************/ -/* FMUL2 (Frequency Multiplier Module 2) Registers */ -#define NPCX_FMUL2_FM2CTRL REG8(NPCX_FMUL2_BASE_ADDR + 0x000) -#define NPCX_FMUL2_FM2ML REG8(NPCX_FMUL2_BASE_ADDR + 0x002) -#define NPCX_FMUL2_FM2MH REG8(NPCX_FMUL2_BASE_ADDR + 0x004) -#define NPCX_FMUL2_FM2N REG8(NPCX_FMUL2_BASE_ADDR + 0x006) -#define NPCX_FMUL2_FM2P REG8(NPCX_FMUL2_BASE_ADDR + 0x008) -#define NPCX_FMUL2_FM2_VER REG8(NPCX_FMUL2_BASE_ADDR + 0x00A) - -/******************************************************************************/ -/* FMUL2 register fields */ -#define NPCX_FMUL2_FM2CTRL_LOAD2 0 -#define NPCX_FMUL2_FM2CTRL_LOCK2 2 -#define NPCX_FMUL2_FM2CTRL_FMUL2_DIS 5 -#define NPCX_FMUL2_FM2CTRL_TUNE_DIS 6 -#define NPCX_FMUL2_FM2CTRL_CLK2_CHNG 7 -#define NPCX_FMUL2_FM2N_FM2N FIELD(0, 6) -#define NPCX_FMUL2_FM2P_WFPRED FIELD(4, 4) - -/******************************************************************************/ -/* WOV (Wake-on-Voice) Registers */ -#define NPCX_WOV_CLOCK_CNTL REG32(NPCX_WOV_BASE_ADDR + 0x000) -#define NPCX_WOV_PLL_CNTL1 REG32(NPCX_WOV_BASE_ADDR + 0x004) -#define NPCX_WOV_PLL_CNTL2 REG32(NPCX_WOV_BASE_ADDR + 0x008) -#define NPCX_WOV_FIFO_CNT REG32(NPCX_WOV_BASE_ADDR + 0x00C) -#define NPCX_WOV_FIFO_OUT REG32(NPCX_WOV_BASE_ADDR + 0x010) -#define NPCX_WOV_STATUS REG32(NPCX_WOV_BASE_ADDR + 0x014) -#define NPCX_WOV_WOV_INTEN REG32(NPCX_WOV_BASE_ADDR + 0x018) -#define NPCX_WOV_APM_CTRL REG32(NPCX_WOV_BASE_ADDR + 0x01C) -#define NPCX_WOV_I2S_CNTL(n) REG32(NPCX_WOV_BASE_ADDR + 0x020 + (4*n)) -#define NPCX_WOV_VERSION REG32(NPCX_WOV_BASE_ADDR + 0x030) - -/******************************************************************************/ -/* WOV register fields */ -#define NPCX_WOV_CLOCK_CNT_CLK_SEL 0 -#define NPCX_WOV_CLOCK_CNT_DMIC_EN 3 -#define NPCX_WOV_CLOCK_CNT_PLL_EDIV_SEL 7 -#define NPCX_WOV_CLOCK_CNT_PLL_EDIV FIELD(8, 7) -#define NPCX_WOV_CLOCK_CNT_PLL_EDIV_DC FIELD(16, 7) -#define NPCX_WOV_CLOCK_CNT_DMIC_CKDIV_EN 24 -#define NPCX_WOV_CLOCK_CNT_DMIC_CKDIV_SEL 25 -#define NPCX_WOV_FIFO_CNT_FIFO_ITHRSH FIELD(0, 6) -#define NPCX_WOV_FIFO_CNT_FIFO_WTHRSH FIELD(6, 6) -#define NPCX_WOV_FIFO_CNT_I2S_FFRST 13 -#define NPCX_WOV_FIFO_CNT_CORE_FFRST 14 -#define NPCX_WOV_FIFO_CNT_CFIFO_ISEL FIELD(16, 3) -#define NPCX_WOV_STATUS_CFIFO_CNT FIELD(0, 8) -#define NPCX_WOV_STATUS_CFIFO_NE 8 -#define NPCX_WOV_STATUS_CFIFO_OIT 9 -#define NPCX_WOV_STATUS_CFIFO_OWT 10 -#define NPCX_WOV_STATUS_CFIFO_OVRN 11 -#define NPCX_WOV_STATUS_I2S_FIFO_OVRN 12 -#define NPCX_WOV_STATUS_I2S_FIFO_UNDRN 13 -#define NPCX_WOV_STATUS_BITS FIELD(9, 6) -#define NPCX_WOV_INTEN_VAD_INTEN 0 -#define NPCX_WOV_INTEN_VAD_WKEN 1 -#define NPCX_WOV_INTEN_CFIFO_NE_IE 8 -#define NPCX_WOV_INTEN_CFIFO_OIT_IE 9 -#define NPCX_WOV_INTEN_CFIFO_OWT_WE 10 -#define NPCX_WOV_INTEN_CFIFO_OVRN_IE 11 -#define NPCX_WOV_INTEN_I2S_FIFO_OVRN_IE 12 -#define NPCX_WOV_INTEN_I2S_FIFO_UNDRN_IE 13 -#define NPCX_WOV_APM_CTRL_APM_RST 0 -#define NPCX_WOV_PLL_CNTL1_PLL_PWDEN 0 -#define NPCX_WOV_PLL_CNTL1_PLL_OTDV1 FIELD(4, 4) -#define NPCX_WOV_PLL_CNTL1_PLL_OTDV2 FIELD(8, 4) -#define NPCX_WOV_PLL_CNTL1_PLL_LOCKI 15 -#define NPCX_WOV_PLL_CNTL2_PLL_FBDV FIELD(0, 12) -#define NPCX_WOV_PLL_CNTL2_PLL_INDV FIELD(12, 4) -#define NPCX_WOV_I2S_CNTL_I2S_BCNT FIELD(0, 5) -#define NPCX_WOV_I2S_CNTL_I2S_TRIG 5 -#define NPCX_WOV_I2S_CNTL_I2S_LBHIZ 6 -#define NPCX_WOV_I2S_CNTL_I2S_ST_DEL FIELD(7, 9) -#define NPCX_WOV_I2S_CNTL_I2S_CHAN FIELD(0, 16) -#define NPCX_WOV_I2S_CNTL0_I2S_HIZD 16 -#define NPCX_WOV_I2S_CNTL0_I2S_HIZ 17 -#define NPCX_WOV_I2S_CNTL0_I2S_SCLK_INV 18 -#define NPCX_WOV_I2S_CNTL0_I2S_OPS 19 -#define NPCX_WOV_I2S_CNTL0_I2S_OPE 20 -#define NPCX_WOV_I2S_CNTL0_I2S_IPS 21 -#define NPCX_WOV_I2S_CNTL0_I2S_IPE 22 -#define NPCX_WOV_I2S_CNTL0_I2S_TST 23 -#define NPCX_WOV_I2S_CNTL1_I2S_CHN1_DIS 24 - -/******************************************************************************/ -/* PS/2 registers */ -#define NPCX_PS2_PSDAT REG8(NPCX_PS2_BASE_ADDR + 0x000) -#define NPCX_PS2_PSTAT REG8(NPCX_PS2_BASE_ADDR + 0x002) -#define NPCX_PS2_PSCON REG8(NPCX_PS2_BASE_ADDR + 0x004) -#define NPCX_PS2_PSOSIG REG8(NPCX_PS2_BASE_ADDR + 0x006) -#define NPCX_PS2_PSISIG REG8(NPCX_PS2_BASE_ADDR + 0x008) -#define NPCX_PS2_PSIEN REG8(NPCX_PS2_BASE_ADDR + 0x00A) - -/* PS/2 register field */ -#define NPCX_PS2_PSTAT_SOT 0 -#define NPCX_PS2_PSTAT_EOT 1 -#define NPCX_PS2_PSTAT_PERR 2 -#define NPCX_PS2_PSTAT_ACH FIELD(3, 3) -#define NPCX_PS2_PSTAT_RFERR 6 - -#define NPCX_PS2_PSCON_EN 0 -#define NPCX_PS2_PSCON_XMT 1 -#define NPCX_PS2_PSCON_HDRV FIELD(2, 2) -#define NPCX_PS2_PSCON_IDB FIELD(4, 3) -#define NPCX_PS2_PSCON_WPUED 7 - -#define NPCX_PS2_PSOSIG_WDAT0 0 -#define NPCX_PS2_PSOSIG_WDAT1 1 -#define NPCX_PS2_PSOSIG_WDAT2 2 -#define NPCX_PS2_PSOSIG_CLK0 3 -#define NPCX_PS2_PSOSIG_CLK1 4 -#define NPCX_PS2_PSOSIG_CLK2 5 -#define NPCX_PS2_PSOSIG_WDAT3 6 -#define NPCX_PS2_PSOSIG_CLK3 7 -#define NPCX_PS2_PSOSIG_CLK(n) (((n) < NPCX_PS2_CH3) ? \ - ((n) + 3) : 7) -#define NPCX_PS2_PSOSIG_WDAT(n) (((n) < NPCX_PS2_CH3) ? \ - ((n) + 0) : 6) -#define NPCX_PS2_PSOSIG_CLK_MASK_ALL \ - (BIT(NPCX_PS2_PSOSIG_CLK0) | \ - BIT(NPCX_PS2_PSOSIG_CLK1) | \ - BIT(NPCX_PS2_PSOSIG_CLK2) | \ - BIT(NPCX_PS2_PSOSIG_CLK3)) - -#define NPCX_PS2_PSISIG_RDAT0 0 -#define NPCX_PS2_PSISIG_RDAT1 1 -#define NPCX_PS2_PSISIG_RDAT2 2 -#define NPCX_PS2_PSISIG_RCLK0 3 -#define NPCX_PS2_PSISIG_RCLK1 4 -#define NPCX_PS2_PSISIG_RCLK2 5 -#define NPCX_PS2_PSISIG_RDAT3 6 -#define NPCX_PS2_PSISIG_RCLK3 7 -#define NPCX_PS2_PSIEN_SOTIE 0 -#define NPCX_PS2_PSIEN_EOTIE 1 -#define NPCX_PS2_PSIEN_PS2_WUE 4 -#define NPCX_PS2_PSIEN_PS2_CLK_SEL 7 - -#ifndef CONFIG_HIBERNATE_WAKE_PINS_DYNAMIC -extern const enum gpio_signal hibernate_wake_pins[]; -extern const int hibernate_wake_pins_used; -#else -extern enum gpio_signal hibernate_wake_pins[]; -extern int hibernate_wake_pins_used; -#endif - -#ifndef NPCX_UART_MODULE2 -#define NPCX_UART_MODULE2 0 -#endif /* NPCX_UART_MODULE2 */ - -#if defined(CHIP_FAMILY_NPCX5) -#include "registers-npcx5.h" -#elif defined(CHIP_FAMILY_NPCX7) -#include "registers-npcx7.h" -#elif defined(CHIP_FAMILY_NPCX9) -#include "registers-npcx9.h" -#else -#error "Unsupported chip family" -#endif - -#endif /* __CROS_EC_REGISTERS_H */ diff --git a/chip/npcx/rom_chip.h b/chip/npcx/rom_chip.h deleted file mode 100644 index bb66f95e88..0000000000 --- a/chip/npcx/rom_chip.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2015 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_ROM_CHIP_H_ -#define __CROS_EC_ROM_CHIP_H_ - -/******************************************************************************/ -/* - * Enumerations of ROM api functions - */ -enum API_SIGN_OPTIONS_T { - SIGN_NO_CHECK = 0, - SIGN_CRC_CHECK = 1, -}; - -enum API_RETURN_STATUS_T { - /* Successful download */ - API_RET_STATUS_OK = 0, - /* Address is outside of flash or not 4 bytes aligned. */ - API_RET_STATUS_INVALID_SRC_ADDR = 1, - /* Address is outside of RAM or not 4 bytes aligned. */ - API_RET_STATUS_INVALID_DST_ADDR = 2, - /* Size is 0 or not 4 bytes aligned. */ - API_RET_STATUS_INVALID_SIZE = 3, - /* Flash Address + Size is out of flash. */ - API_RET_STATUS_INVALID_SIZE_OUT_OF_FLASH = 4, - /* RAM Address + Size is out of RAM. */ - API_RET_STATUS_INVALID_SIZE_OUT_OF_RAM = 5, - /* Wrong sign option. */ - API_RET_STATUS_INVALID_SIGN = 6, - /* Error during Code copy. */ - API_RET_STATUS_COPY_FAILED = 7, - /* Execution Address is outside of RAM */ - API_RET_STATUS_INVALID_EXE_ADDR = 8, - /* Bad CRC value */ - API_RET_STATUS_INVALID_SIGNATURE = 9, -}; - -/******************************************************************************/ -/* - * Macro functions of ROM api functions - */ -#define ADDR_DOWNLOAD_FROM_FLASH (*(volatile uint32_t *) 0x40) -#define download_from_flash(src_offset, dest_addr, size, sign, exe_addr, \ - status) \ - (((download_from_flash_ptr) ADDR_DOWNLOAD_FROM_FLASH) \ - (src_offset, dest_addr, size, sign, exe_addr, status)) - -/******************************************************************************/ -/* - * Declarations of ROM api functions - */ -typedef void (*download_from_flash_ptr) ( - uint32_t src_offset, /* The offset of the data to be downloaded */ - uint32_t dest_addr, /* The address of the downloaded data in the RAM*/ - uint32_t size, /* Number of bytes to download */ - enum API_SIGN_OPTIONS_T sign, /* Need CRC check or not */ - uint32_t exe_addr, /* jump to this address after download if not zero */ - enum API_RETURN_STATUS_T *status /* Status fo download */ -); - - - -#endif /* __CROS_EC_ROM_CHIP_H_ */ diff --git a/chip/npcx/sha256_chip.c b/chip/npcx/sha256_chip.c deleted file mode 100644 index 6d2d938895..0000000000 --- a/chip/npcx/sha256_chip.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2020 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. - */ - -/* SHA256 module for Chrome EC */ -#include "common.h" -#include "sha256.h" -#include "util.h" - -enum ncl_status { - NCL_STATUS_OK, - NCL_STATUS_FAIL, - NCL_STATUS_INVALID_PARAM, - NCL_STATUS_PARAM_NOT_SUPPORTED, - NCL_STATUS_SYSTEM_BUSY, - NCL_STATUS_AUTHENTICATION_FAIL, - NCL_STATUS_NO_RESPONSE, - NCL_STATUS_HARDWARE_ERROR, -}; - -enum ncl_sha_type { - NCL_SHA_TYPE_2_256 = 0, - NCL_SHA_TYPE_2_384 = 1, - NCL_SHA_TYPE_2_512 = 2, - NCL_SHA_TYPE_NUM -}; - -/* - * The base address of the table that holds the function pointer for each - * SHA256 API in ROM. - */ -#define NCL_SHA_BASE_ADDR 0x00000100UL -struct ncl_sha { - /* Get the SHA context size required by SHA APIs. */ - uint32_t (*get_context_size)(void); - /* Initial SHA context. */ - enum ncl_status (*init_context)(void *ctx); - /* Finalize SHA context. */ - enum ncl_status (*finalize_context)(void *ctx); - /* Initiate the SHA hardware module and setups needed parameters. */ - enum ncl_status (*init)(void *ctx); - /* - * Prepare the context buffer for a SHA calculation - by loading the - * initial SHA-256/384/512 parameters. - */ - enum ncl_status (*start)(void *ctx, enum ncl_sha_type type); - /* - * Updates the SHA calculation with the additional data. When the - * function returns, the hardware and memory buffer shall be ready to - * accept new data * buffers for SHA calculation and changes to the data - * in data buffer should no longer effect the SHA calculation. - */ - enum ncl_status (*update)(void *ctx, const uint8_t *data, uint32_t Len); - /* Return the SHA result (digest.) */ - enum ncl_status (*finish)(void *ctx, uint8_t *hashDigest); - /* Perform a complete SHA calculation */ - enum ncl_status (*calc)(void *ctx, enum ncl_sha_type type, - const uint8_t *data, uint32_t Len, uint8_t *hashDigest); - /* Power on/off the SHA module. */ - enum ncl_status (*power)(void *ctx, uint8_t enable); - /* Reset the SHA hardware and terminate any in-progress operations. */ - enum ncl_status (*reset)(void *ctx); -}; - -#define NCL_SHA ((const struct ncl_sha *)NCL_SHA_BASE_ADDR) - -void SHA256_init(struct sha256_ctx *ctx) -{ - NCL_SHA->init_context(ctx->handle); - NCL_SHA->power(ctx->handle, 1); - NCL_SHA->init(ctx->handle); - NCL_SHA->reset(ctx->handle); - NCL_SHA->start(ctx->handle, NCL_SHA_TYPE_2_256); -} - -void SHA256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len) -{ - NCL_SHA->update(ctx->handle, data, len); -} - -void SHA256_abort(struct sha256_ctx *ctx) -{ - NCL_SHA->reset(ctx->handle); - NCL_SHA->power(ctx->handle, 0); - NCL_SHA->finalize_context(ctx->handle); -} - -uint8_t *SHA256_final(struct sha256_ctx *ctx) -{ - NCL_SHA->finish(ctx->handle, ctx->buf); - NCL_SHA->power(ctx->handle, 0); - NCL_SHA->finalize_context(ctx->handle); - return ctx->buf; -} - -static void hmac_SHA256_step(uint8_t *output, uint8_t mask, - const uint8_t *key, const int key_len, - const uint8_t *data, const int data_len) -{ - struct sha256_ctx hmac_ctx; - uint8_t *key_pad = hmac_ctx.buf; - uint8_t *tmp; - int i; - - memset(key_pad, mask, SHA256_BLOCK_SIZE); - for (i = 0; i < key_len; i++) - key_pad[i] ^= key[i]; - - SHA256_init(&hmac_ctx); - SHA256_update(&hmac_ctx, key_pad, SHA256_BLOCK_SIZE); - SHA256_update(&hmac_ctx, data, data_len); - tmp = SHA256_final(&hmac_ctx); - memcpy(output, tmp, SHA256_DIGEST_SIZE); -} -/* - * Note: When the API is called, it will consume about half of TASK_STACK_SIZE - * because a variable of structure sha256_ctx is declared in the function - * hmac_SHA256_step. - */ -void hmac_SHA256(uint8_t *output, const uint8_t *key, const int key_len, - const uint8_t *message, const int message_len) -{ - /* This code does not support key_len > block_size. */ - ASSERT(key_len <= SHA256_BLOCK_SIZE); - - /* - * i_key_pad = key (zero-padded) ^ 0x36 - * output = hash(i_key_pad || message) - * (Use output as temporary buffer) - */ - hmac_SHA256_step(output, 0x36, key, key_len, message, message_len); - - /* - * o_key_pad = key (zero-padded) ^ 0x5c - * output = hash(o_key_pad || output) - */ - hmac_SHA256_step(output, 0x5c, key, key_len, output, - SHA256_DIGEST_SIZE); -} diff --git a/chip/npcx/sha256_chip.h b/chip/npcx/sha256_chip.h deleted file mode 100644 index 3b9586d962..0000000000 --- a/chip/npcx/sha256_chip.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2020 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_SHA256_CHIP_H -#define __CROS_EC_SHA256_CHIP_H - -#include "common.h" - -#define NPCX_SHA256_HANDLE_SIZE 212 -struct sha256_ctx { - /* the context handle required for SHA256 API */ - uint8_t handle[NPCX_SHA256_HANDLE_SIZE]; - /* - * This is used to buffer: - * 1. the result (digest) of the SHA256 computation. - * 2. the 1st block input data (the key padding) for hmac_SHA256_step. - */ - uint8_t buf[SHA256_BLOCK_SIZE]; -} __aligned(4); - -void SHA256_abort(struct sha256_ctx *ctx); - -#endif /* __CROS_EC_SHA256_CHIP_H */ diff --git a/chip/npcx/shi.c b/chip/npcx/shi.c deleted file mode 100644 index 503a52807e..0000000000 --- a/chip/npcx/shi.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* - * Copyright 2015 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. - */ - -/* - * SHI driver for Chrome EC. - * - * This uses Input/Output buffer to handle SPI transmission and reception. - */ - -#include "chipset.h" -#include "clock.h" -#include "console.h" -#include "gpio.h" -#include "task.h" -#include "hooks.h" -#include "host_command.h" -#include "registers.h" -#include "spi.h" -#include "system.h" -#include "timer.h" -#include "util.h" - -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SPI, format, ## args) - -#if !(DEBUG_SHI) -#define DEBUG_CPUTS(...) -#define DEBUG_CPRINTS(...) -#define DEBUG_CPRINTF(...) -#else -#define DEBUG_CPUTS(outstr) cputs(CC_SPI, outstr) -#define DEBUG_CPRINTS(format, args...) cprints(CC_SPI, format, ## args) -#define DEBUG_CPRINTF(format, args...) cprintf(CC_SPI, format, ## args) -#endif - -/* SHI Bus definition */ -#ifdef NPCX_SHI_V2 -#define SHI_OBUF_FULL_SIZE 128 /* Full output buffer size */ -#define SHI_IBUF_FULL_SIZE 128 /* Full input buffer size */ -/* Configure the IBUFLVL2 = the size of V3 protocol header */ -#define SHI_IBUFLVL2_THRESHOLD (sizeof(struct ec_host_request)) -#else -#define SHI_OBUF_FULL_SIZE 64 /* Full output buffer size */ -#define SHI_IBUF_FULL_SIZE 64 /* Full input buffer size */ -#endif -#define SHI_OBUF_HALF_SIZE (SHI_OBUF_FULL_SIZE/2) /* Half output buffer size */ -#define SHI_IBUF_HALF_SIZE (SHI_IBUF_FULL_SIZE/2) /* Half input buffer size */ - -/* Start address of SHI output buffer */ -#define SHI_OBUF_START_ADDR (volatile uint8_t *)(NPCX_SHI_BASE_ADDR + 0x020) -/* Middle address of SHI output buffer */ -#define SHI_OBUF_HALF_ADDR (SHI_OBUF_START_ADDR + SHI_OBUF_HALF_SIZE) -/* Top address of SHI output buffer */ -#define SHI_OBUF_FULL_ADDR (SHI_OBUF_START_ADDR + SHI_IBUF_FULL_SIZE) -/* - * Valid offset of SHI output buffer to write. - * When SIMUL bit is set, IBUFPTR can be used instead of OBUFPTR - */ -#define SHI_OBUF_VALID_OFFSET ((shi_read_buf_pointer() + \ - SHI_OUT_PREAMBLE_LENGTH) % SHI_OBUF_FULL_SIZE) -/* Start address of SHI input buffer */ -#define SHI_IBUF_START_ADDR (&NPCX_IBUF(0)) -/* Current address of SHI input buffer */ -#define SHI_IBUF_CUR_ADDR (SHI_IBUF_START_ADDR + shi_read_buf_pointer()) - -/* - * Timeout to wait for SHI request packet - * - * This affects the slowest SPI clock we can support. A delay of 8192 - * us permits a 512-byte request at 500 KHz, assuming the controller - * starts sending bytes as soon as it asserts chip select. That's as - * slow as we would practically want to run the SHI interface, since - * running it slower significantly impacts firmware update times. - */ -#define SHI_CMD_RX_TIMEOUT_US 8192 - -/* Timeout for glitch case. Make sure it will exceed 8 SPI clocks */ -#define SHI_GLITCH_TIMEOUT_US 10000 - -/* - * The AP blindly clocks back bytes over the SPI interface looking for a - * framing byte. So this preamble must always precede the actual response - * packet. - */ - -#define SHI_OUT_PREAMBLE_LENGTH 2 -/* - * Space allocation of the past-end status byte (EC_SPI_PAST_END) in the out_msg - * buffer. - */ -#define EC_SPI_PAST_END_LENGTH 1 -/* - * Space allocation of the frame status byte (EC_SPI_FRAME_START) in the out_msg - * buffer. - */ -#define EC_SPI_FRAME_START_LENGTH 1 - -/* - * Offset of output parameters needs to account for pad and framing bytes and - * one last past-end byte at the end so any additional bytes clocked out by - * the AP will have a known and identifiable value. - */ -#define SHI_PROTO3_OVERHEAD (EC_SPI_PAST_END_LENGTH + EC_SPI_FRAME_START_LENGTH) - - -#ifdef NPCX_SHI_BYPASS_OVER_256B -/* The boundary which SHI will output invalid data on MISO. */ -#define SHI_BYPASS_BOUNDARY 256 -/* Increase FRAME_START_LENGTH in case shi outputs invalid FRAME_START byte */ -#undef EC_SPI_FRAME_START_LENGTH -#define EC_SPI_FRAME_START_LENGTH 2 -#endif - -/* - * Max data size for a version 3 request/response packet. This is big enough - * to handle a request/response header, flash write offset/size, and 512 bytes - * of flash data: - * sizeof(ec_host_request): 8 - * sizoef(ec_params_flash_write): 8 - * payload 512 - * - */ -#define SHI_MAX_REQUEST_SIZE 0x220 - -#ifdef NPCX_SHI_BYPASS_OVER_256B -/* Make sure SHI_MAX_RESPONSE_SIZE won't exceed 256 bytes */ -#define SHI_MAX_RESPONSE_SIZE (160 + sizeof(struct ec_host_response)) -BUILD_ASSERT(SHI_MAX_RESPONSE_SIZE <= SHI_BYPASS_BOUNDARY); -#else -#define SHI_MAX_RESPONSE_SIZE 0x220 -#endif - -/* - * Our input and output msg buffers. These must be large enough for our largest - * message, including protocol overhead. The pointers after the protocol - * overhead, as passed to the host command handler, must be 32-bit aligned. - */ -#define SHI_OUT_START_PAD (4 * (EC_SPI_FRAME_START_LENGTH / 4 + 1)) -#define SHI_OUT_END_PAD (4 * (EC_SPI_PAST_END_LENGTH / 4 + 1)) -static uint8_t out_msg_padded[SHI_OUT_START_PAD + - SHI_MAX_RESPONSE_SIZE + - SHI_OUT_END_PAD] __aligned(4); -static uint8_t * const out_msg = - out_msg_padded + SHI_OUT_START_PAD - EC_SPI_FRAME_START_LENGTH; -static uint8_t in_msg[SHI_MAX_REQUEST_SIZE] __aligned(4); - -/* Parameters used by host protocols */ -static struct host_packet shi_packet; - -enum shi_state { - /* SHI not enabled (initial state, and when chipset is off) */ - SHI_STATE_DISABLED = 0, - /* Ready to receive next request */ - SHI_STATE_READY_TO_RECV, - /* Receiving request */ - SHI_STATE_RECEIVING, - /* Processing request */ - SHI_STATE_PROCESSING, - /* Canceling response since CS deasserted and output NOT_READY byte */ - SHI_STATE_CNL_RESP_NOT_RDY, -#ifdef NPCX_SHI_BYPASS_OVER_256B - /* Keep output buffer as PROCESSING byte until reaching 256B boundary */ - SHI_STATE_WAIT_ALIGNMENT, -#endif - /* Sending response */ - SHI_STATE_SENDING, - /* Received data is valid. */ - SHI_STATE_BAD_RECEIVED_DATA, -}; - -volatile enum shi_state state; - -/* SHI bus parameters */ -struct shi_bus_parameters { - uint8_t *rx_msg; /* Entry pointer of msg rx buffer */ - uint8_t *tx_msg; /* Entry pointer of msg tx buffer */ - volatile uint8_t *rx_buf; /* Entry pointer of receive buffer */ - volatile uint8_t *tx_buf; /* Entry pointer of transmit buffer */ - uint16_t sz_received; /* Size of received data in bytes */ - uint16_t sz_sending; /* Size of sending data in bytes */ - uint16_t sz_request; /* request bytes need to receive */ - uint16_t sz_response; /* response bytes need to receive */ - timestamp_t rx_deadline; /* deadline of receiving */ - uint8_t pre_ibufstat; /* Previous IBUFSTAT value */ -#ifdef NPCX_SHI_BYPASS_OVER_256B - uint16_t bytes_in_256b; /* Sent bytes in 256 bytes boundary */ -#endif -} shi_params; - -/* Forward declaration */ -static void shi_reset_prepare(void); -static void shi_bad_received_data(void); -static void shi_fill_out_status(uint8_t status); -static void shi_write_half_outbuf(void); -static void shi_write_first_pkg_outbuf(uint16_t szbytes); -static int shi_read_inbuf_wait(uint16_t szbytes); -static uint8_t shi_read_buf_pointer(void); - -/*****************************************************************************/ -/* V3 protocol layer functions */ - -/** - * Called to send a response back to the host. - * - * Some commands can continue for a while. This function is called by - * host_command when it completes. - * - */ -static void shi_send_response_packet(struct host_packet *pkt) -{ - /* - * Disable interrupts. This routine is not called from interrupt - * context and buffer underrun will likely occur if it is - * preempted after writing its initial reply byte. Also, we must be - * sure our state doesn't unexpectedly change, in case we're expected - * to take RESP_NOT_RDY actions. - */ - interrupt_disable(); - if (state == SHI_STATE_PROCESSING) { - /* Append our past-end byte, which we reserved space for. */ - ((uint8_t *) pkt->response)[pkt->response_size + 0] = - EC_SPI_PAST_END; - - /* Computing sending bytes of response */ - shi_params.sz_response = - pkt->response_size + SHI_PROTO3_OVERHEAD; - - /* Start to fill output buffer with msg buffer */ - shi_write_first_pkg_outbuf(shi_params.sz_response); -#ifdef NPCX_SHI_BYPASS_OVER_256B - /* - * If response package is over 256B boundary, - * keep sending PROCESSING byte - */ - if (state != SHI_STATE_WAIT_ALIGNMENT) { -#endif - /* Transmit the reply */ - state = SHI_STATE_SENDING; - DEBUG_CPRINTF("SND-"); -#ifdef NPCX_SHI_BYPASS_OVER_256B - } -#endif - } - /* - * If we're not processing, then the AP has already terminated the - * transaction, and won't be listening for a response. - * Reset state machine for next transaction. - */ - else if (state == SHI_STATE_CNL_RESP_NOT_RDY) { - shi_reset_prepare(); - DEBUG_CPRINTF("END\n"); - } else - DEBUG_CPRINTS("Unexpected state %d in response handler", state); - interrupt_enable(); -} - -void shi_handle_host_package(void) -{ - uint16_t sz_inbuf_int = shi_params.sz_request / SHI_IBUF_HALF_SIZE; - uint16_t cnt_inbuf_int = shi_params.sz_received / SHI_IBUF_HALF_SIZE; - if (sz_inbuf_int - cnt_inbuf_int) - /* Need to receive data from buffer */ - return; - else { - uint16_t remain_bytes = shi_params.sz_request - - shi_params.sz_received; - - /* Read remaining bytes from input buffer directly */ - if (!shi_read_inbuf_wait(remain_bytes)) - return shi_bad_received_data(); - /* Move to processing state immediately */ - state = SHI_STATE_PROCESSING; - DEBUG_CPRINTF("PRC-"); - } - /* Fill output buffer to indicate we`re processing request */ - shi_fill_out_status(EC_SPI_PROCESSING); - - /* Set up parameters for host request */ - shi_packet.send_response = shi_send_response_packet; - - shi_packet.request = in_msg; - shi_packet.request_temp = NULL; - shi_packet.request_max = sizeof(in_msg); - shi_packet.request_size = shi_params.sz_request; - - -#ifdef NPCX_SHI_BYPASS_OVER_256B - /* Move FRAME_START to second byte */ - out_msg[0] = EC_SPI_PROCESSING; - out_msg[1] = EC_SPI_FRAME_START; -#else - /* Put FRAME_START in first byte */ - out_msg[0] = EC_SPI_FRAME_START; -#endif - shi_packet.response = out_msg + EC_SPI_FRAME_START_LENGTH; - - /* Reserve space for frame start and trailing past-end byte */ - shi_packet.response_max = SHI_MAX_RESPONSE_SIZE; - shi_packet.response_size = 0; - shi_packet.driver_result = EC_RES_SUCCESS; - - /* Go to common-layer to handle request */ - host_packet_receive(&shi_packet); -} - -/* Parse header for version of spi-protocol */ -static void shi_parse_header(void) -{ - /* We're now inside a transaction */ - state = SHI_STATE_RECEIVING; - DEBUG_CPRINTF("RV-"); - - /* Setup deadline time for receiving */ - shi_params.rx_deadline = get_time(); - shi_params.rx_deadline.val += SHI_CMD_RX_TIMEOUT_US; - - /* Wait for version, command, length bytes */ - if (!shi_read_inbuf_wait(3)) - return shi_bad_received_data(); - - if (in_msg[0] == EC_HOST_REQUEST_VERSION) { - /* Protocol version 3 */ - struct ec_host_request *r = (struct ec_host_request *) in_msg; - int pkt_size; - /* - * If request is over 32 bytes, - * we need to modified the algorithm again. - */ - ASSERT(sizeof(*r) < SHI_IBUF_HALF_SIZE); - - /* Wait for the rest of the command header */ - if (!shi_read_inbuf_wait(sizeof(*r) - 3)) - return shi_bad_received_data(); - - /* Check how big the packet should be */ - pkt_size = host_request_expected_size(r); - if (pkt_size == 0 || pkt_size > sizeof(in_msg)) - return shi_bad_received_data(); - - /* Computing total bytes need to receive */ - shi_params.sz_request = pkt_size; - - shi_handle_host_package(); - } else { - /* Invalid version number */ - return shi_bad_received_data(); - } -} - -/*****************************************************************************/ -/* IC specific low-level driver */ - -/* This routine fills out all SHI output buffer with status byte */ -static void shi_fill_out_status(uint8_t status) -{ - uint8_t start, end; - uint8_t *fill_ptr; - uint8_t *fill_end; - uint8_t *obuf_end; - - /* Disable interrupts in case the interfere by the other interrupts */ - interrupt_disable(); - - /* - * Fill out output buffer with status byte and leave a gap for PREAMBLE. - * The gap guarantees the synchronization. The critical section should - * be done within this gap. No racing happens. - */ - start = SHI_OBUF_VALID_OFFSET; - end = ((start + SHI_OBUF_FULL_SIZE - SHI_OUT_PREAMBLE_LENGTH) - % SHI_OBUF_FULL_SIZE); - - fill_ptr = (uint8_t *)SHI_OBUF_START_ADDR + start; - fill_end = (uint8_t *)SHI_OBUF_START_ADDR + end; - obuf_end = (uint8_t *)SHI_OBUF_START_ADDR + SHI_OBUF_FULL_SIZE; - while (fill_ptr != fill_end) { - *(fill_ptr++) = status; - if (fill_ptr == obuf_end) - fill_ptr = (uint8_t *)SHI_OBUF_START_ADDR; - } - - /* End of critical section */ - interrupt_enable(); -} - -#ifdef NPCX_SHI_V2 - /* - * This routine configures at which level the Input Buffer Half Full 2(IBHF2)) - * event triggers an interrupt to core. - */ -static void shi_sec_ibf_int_enable(int enable) -{ - if (enable) { - /* Setup IBUFLVL2 threshold and enable it */ - SET_BIT(NPCX_SHICFG5, NPCX_SHICFG5_IBUFLVL2DIS); - SET_FIELD(NPCX_SHICFG5, NPCX_SHICFG5_IBUFLVL2, - SHI_IBUFLVL2_THRESHOLD); - CLEAR_BIT(NPCX_SHICFG5, NPCX_SHICFG5_IBUFLVL2DIS); - /* Enable IBHF2 event */ - SET_BIT(NPCX_EVENABLE2, NPCX_EVENABLE2_IBHF2EN); - } else { - /* Disable IBHF2 event first */ - CLEAR_BIT(NPCX_EVENABLE2, NPCX_EVENABLE2_IBHF2EN); - /* Disable IBUFLVL2 and set threshold back to zero */ - SET_BIT(NPCX_SHICFG5, NPCX_SHICFG5_IBUFLVL2DIS); - SET_FIELD(NPCX_SHICFG5, NPCX_SHICFG5_IBUFLVL2, 0); - } -} -#else -/* - * This routine makes sure it's valid transaction or glitch on CS bus. - */ -static int shi_is_cs_glitch(void) -{ - timestamp_t deadline; - - deadline.val = get_time().val + SHI_GLITCH_TIMEOUT_US; - /* - * If input buffer pointer is no changed after timeout, it will - * return true - */ - while (shi_params.pre_ibufstat == shi_read_buf_pointer()) - if (timestamp_expired(deadline, NULL)) - return 1; - /* valid package */ - return 0; -} -#endif - -/* - * This routine write SHI next half output buffer from msg buffer - */ -static void shi_write_half_outbuf(void) -{ - const uint8_t size = MIN(SHI_OBUF_HALF_SIZE, - shi_params.sz_response - - shi_params.sz_sending); - uint8_t *obuf_ptr = (uint8_t *)shi_params.tx_buf; - const uint8_t *obuf_end = obuf_ptr + size; - uint8_t *msg_ptr = shi_params.tx_msg; - - /* Fill half output buffer */ - while (obuf_ptr != obuf_end) - *(obuf_ptr++) = *(msg_ptr++); - - shi_params.sz_sending += size; - shi_params.tx_buf = obuf_ptr; - shi_params.tx_msg = msg_ptr; -} - -/* - * This routine write SHI output buffer from msg buffer over halt of it. - * It make sure we have enought time to handle next operations. - */ -static void shi_write_first_pkg_outbuf(uint16_t szbytes) -{ - uint8_t size, offset; - uint8_t *obuf_ptr; - uint8_t *obuf_end; - uint8_t *msg_ptr; - -#ifdef NPCX_SHI_BYPASS_OVER_256B - /* - * If response package is across 256 bytes boundary, - * bypass needs to extend PROCESSING bytes after reaching the boundary. - */ - if (shi_params.bytes_in_256b + SHI_OBUF_FULL_SIZE + szbytes - > SHI_BYPASS_BOUNDARY) { - state = SHI_STATE_WAIT_ALIGNMENT; - /* Set pointer of output buffer to the start address */ - shi_params.tx_buf = SHI_OBUF_START_ADDR; - DEBUG_CPRINTF("WAT-"); - return; - } -#endif - - /* Start writing at our current OBUF position */ - offset = SHI_OBUF_VALID_OFFSET; - obuf_ptr = (uint8_t *)SHI_OBUF_START_ADDR + offset; - msg_ptr = shi_params.tx_msg; - - /* Fill up to OBUF mid point, or OBUF end */ - size = MIN(SHI_OBUF_HALF_SIZE - (offset % SHI_OBUF_HALF_SIZE), - szbytes - shi_params.sz_sending); - obuf_end = obuf_ptr + size; - while (obuf_ptr != obuf_end) - *(obuf_ptr++) = *(msg_ptr++); - - /* Track bytes sent for later accounting */ - shi_params.sz_sending += size; - - /* Write data to beginning of OBUF if we've reached the end */ - if (obuf_ptr == SHI_OBUF_FULL_ADDR) - obuf_ptr = (uint8_t *)SHI_OBUF_START_ADDR; - - /* Fill next half output buffer */ - size = MIN(SHI_OBUF_HALF_SIZE, szbytes - shi_params.sz_sending); - obuf_end = obuf_ptr + size; - while (obuf_ptr != obuf_end) - *(obuf_ptr++) = *(msg_ptr++); - - /* Track bytes sent / last OBUF position written for later accounting */ - shi_params.sz_sending += size; - shi_params.tx_buf = obuf_ptr; - shi_params.tx_msg = msg_ptr; -} - -/* This routine copies SHI half input buffer data to msg buffer */ -static void shi_read_half_inbuf(void) -{ - /* - * Copy to read buffer until reaching middle/top address of - * input buffer or completing receiving data - */ - do { - /* Restore data to msg buffer */ - *(shi_params.rx_msg++) = *(shi_params.rx_buf++); - shi_params.sz_received++; - } while (shi_params.sz_received % SHI_IBUF_HALF_SIZE - && shi_params.sz_received != shi_params.sz_request); -} - -/* - * This routine read SHI input buffer to msg buffer until - * we have received a certain number of bytes - */ -static int shi_read_inbuf_wait(uint16_t szbytes) -{ - uint16_t i; - - /* Copy data to msg buffer from input buffer */ - for (i = 0; i < szbytes; i++, shi_params.sz_received++) { - /* - * If input buffer pointer equals pointer which wants to read, - * it means data is not ready. - */ - while (shi_params.rx_buf == SHI_IBUF_CUR_ADDR) - if (timestamp_expired(shi_params.rx_deadline, NULL)) - return 0; - /* Restore data to msg buffer */ - *(shi_params.rx_msg++) = *(shi_params.rx_buf++); - } - return 1; -} - -/* Read pointer of input or output buffer by consecutive reading */ -static uint8_t shi_read_buf_pointer(void) -{ - uint8_t stat; - /* Wait for two consecutive equal values are read */ - do { - stat = NPCX_IBUFSTAT; - } while (stat != NPCX_IBUFSTAT); - - return stat; -} - -/* This routine handles shi recevied unexcepted data */ -static void shi_bad_received_data(void) -{ - uint16_t i; - - /* State machine mismatch, timeout, or protocol we can't handle. */ - shi_fill_out_status(EC_SPI_RX_BAD_DATA); - state = SHI_STATE_BAD_RECEIVED_DATA; - - CPRINTF("BAD-"); - CPRINTF("in_msg=["); - for (i = 0; i < shi_params.sz_received; i++) - CPRINTF("%02x ", in_msg[i]); - CPRINTF("]\n"); - - /* Reset shi's state machine for error recovery */ - shi_reset_prepare(); - - DEBUG_CPRINTF("END\n"); -} - -/* - * Avoid spamming the console with prints every IBF / IBHF interrupt, if - * we find ourselves in an unexpected state. - */ -static int last_error_state = -1; - -static void log_unexpected_state(char *isr_name) -{ -#if !(DEBUG_SHI) - if (state != last_error_state) - CPRINTS("Unexpected state %d in %s ISR", state, isr_name); -#endif - last_error_state = state; -} - -static void shi_handle_cs_assert(void) -{ - /* If not enabled, ignore glitches on SHI_CS_L */ - if (state == SHI_STATE_DISABLED) - return; - - /* SHI V2 module filters cs glitch by hardware automatically */ -#ifndef NPCX_SHI_V2 - /* - * IBUFSTAT resets on the 7th clock cycle after CS assertion, which - * may not have happened yet. We use NPCX_IBUFSTAT for calculating - * buffer fill depth, so make sure it's valid before proceeding. - */ - if (shi_is_cs_glitch()) { - CPRINTS("ERR-GTH"); - shi_reset_prepare(); - DEBUG_CPRINTF("END\n"); - return; - } -#endif - - /* NOT_READY should be sent and there're no spi transaction now. */ - if (state == SHI_STATE_CNL_RESP_NOT_RDY) - return; - - /* Chip select is low = asserted */ - if (state != SHI_STATE_READY_TO_RECV) { - /* State machine should be reset in EVSTAT_EOR ISR */ - CPRINTS("Unexpected state %d in CS ISR", state); - return; - } - - DEBUG_CPRINTF("CSL-"); - - /* - * Clear possible EOR event from previous transaction since it's - * irrelevant now that CS is re-asserted. - */ - NPCX_EVSTAT = 1 << NPCX_EVSTAT_EOR; - - /* Do not deep sleep during SHI transaction */ - disable_sleep(SLEEP_MASK_SPI); - -#ifndef NPCX_SHI_V2 - /* - * Enable SHI interrupt - we will either succeed to parse our host - * command or reset on failure from here. - */ - task_enable_irq(NPCX_IRQ_SHI); - - /* Read first three bytes to parse which protocol is receiving */ - shi_parse_header(); -#endif -} - -/* This routine handles all interrupts of this module */ -void shi_int_handler(void) -{ - uint8_t stat_reg; -#ifdef NPCX_SHI_V2 - uint8_t stat2_reg; -#endif - - /* Read status register and clear interrupt status early */ - stat_reg = NPCX_EVSTAT; - NPCX_EVSTAT = stat_reg; -#ifdef NPCX_SHI_V2 - stat2_reg = NPCX_EVSTAT2; - - /* SHI CS pin is asserted in EVSTAT2 */ - if (IS_BIT_SET(stat2_reg, NPCX_EVSTAT2_CSNFE)) { - /* clear CSNFE bit */ - NPCX_EVSTAT2 = BIT(NPCX_EVSTAT2_CSNFE); - DEBUG_CPRINTF("CSNFE-"); - /* - * BUSY bit is set when SHI_CS is asserted. If not, leave it for - * SHI_CS de-asserted event. - */ - if (!IS_BIT_SET(NPCX_SHICFG2, NPCX_SHICFG2_BUSY)) { - DEBUG_CPRINTF("CSNB-"); - return; - } - shi_handle_cs_assert(); - } -#endif - - /* - * End of data for read/write transaction. ie SHI_CS is deasserted. - * Host completed or aborted transaction - */ -#ifdef NPCX_SHI_V2 - /* - * EOR has the limitation that it will not be set even if the SHI_CS is - * deasserted without SPI clocks. The new SHI module introduce the - * CSNRE bit which will be set when SHI_CS is deasserted regardless of - * SPI clocks. - */ - if (IS_BIT_SET(stat2_reg, NPCX_EVSTAT2_CSNRE)) { - /* Clear pending bit of CSNRE */ - NPCX_EVSTAT2 = BIT(NPCX_EVSTAT2_CSNRE); -#else - if (IS_BIT_SET(stat_reg, NPCX_EVSTAT_EOR)) { -#endif - /* - * We're not in proper state. - * Mark not ready to abort next transaction - */ - DEBUG_CPRINTF("CSH-"); - /* - * If the buffer is still used by the host command. - * Change state machine for response handler. - */ - if (state == SHI_STATE_PROCESSING) { - /* - * Mark not ready to prevent the other - * transaction immediately - */ - shi_fill_out_status(EC_SPI_NOT_READY); - - state = SHI_STATE_CNL_RESP_NOT_RDY; - - /* - * Disable SHI interrupt, it will remain disabled - * until shi_send_response_packet() is called and - * CS is asserted for a new transaction. - */ - task_disable_irq(NPCX_IRQ_SHI); - - DEBUG_CPRINTF("CNL-"); - return; - /* Next transaction but we're not ready */ - } else if (state == SHI_STATE_CNL_RESP_NOT_RDY) - return; - - /* Error state for checking*/ - if (state != SHI_STATE_SENDING) -#ifdef NPCX_SHI_V2 - log_unexpected_state("CSNRE"); -#else - log_unexpected_state("IBEOR"); -#endif - - /* reset SHI and prepare to next transaction again */ - shi_reset_prepare(); - DEBUG_CPRINTF("END\n"); - return; - } - - /* - * Indicate input/output buffer pointer reaches the half buffer size. - * Transaction is processing. - */ - if (IS_BIT_SET(stat_reg, NPCX_EVSTAT_IBHF)) { - if (state == SHI_STATE_RECEIVING) { - /* Read data from input to msg buffer */ - shi_read_half_inbuf(); - return shi_handle_host_package(); - } else if (state == SHI_STATE_SENDING) { - /* Write data from msg buffer to output buffer */ - if (shi_params.tx_buf == SHI_OBUF_START_ADDR + - SHI_OBUF_FULL_SIZE) { - /* Write data from bottom address again */ - shi_params.tx_buf = SHI_OBUF_START_ADDR; - return shi_write_half_outbuf(); - } else /* ignore it */ - return; - } else if (state == SHI_STATE_PROCESSING) { - /* Wait for host to handle request */ - } -#ifdef NPCX_SHI_BYPASS_OVER_256B - else if (state == SHI_STATE_WAIT_ALIGNMENT) { - /* - * If pointer of output buffer will reach 256 bytes - * boundary soon, start to fill response data. - */ - if (shi_params.bytes_in_256b == SHI_BYPASS_BOUNDARY - - SHI_OBUF_FULL_SIZE) { - state = SHI_STATE_SENDING; - DEBUG_CPRINTF("SND-"); - return shi_write_half_outbuf(); - } - } -#endif - else - /* Unexpected status */ - log_unexpected_state("IBHF"); - } - -#ifdef NPCX_SHI_V2 - /* - * The size of input buffer reaches the size of - * protocol V3 header(=8) after CS asserted. - */ - if (IS_BIT_SET(stat2_reg, NPCX_EVSTAT2_IBHF2)) { - /* Clear IBHF2 */ - NPCX_EVSTAT2 = BIT(NPCX_EVSTAT2_IBHF2); - DEBUG_CPRINTF("HDR-"); - /* Disable second IBF interrupt and start to parse header */ - shi_sec_ibf_int_enable(0); - shi_parse_header(); - } -#endif - - /* - * Indicate input/output buffer pointer reaches the full buffer size. - * Transaction is processing. - */ - if (IS_BIT_SET(stat_reg, NPCX_EVSTAT_IBF)) { -#ifdef NPCX_SHI_BYPASS_OVER_256B - /* Record the sent bytes within 256B boundary */ - shi_params.bytes_in_256b = (shi_params.bytes_in_256b + - SHI_OBUF_FULL_SIZE) % SHI_BYPASS_BOUNDARY; -#endif - if (state == SHI_STATE_RECEIVING) { - /* read data from input to msg buffer */ - shi_read_half_inbuf(); - /* Read to bottom address again */ - shi_params.rx_buf = SHI_IBUF_START_ADDR; - return shi_handle_host_package(); - } else if (state == SHI_STATE_SENDING) - /* Write data from msg buffer to output buffer */ - if (shi_params.tx_buf == SHI_OBUF_START_ADDR + - SHI_OBUF_HALF_SIZE) - return shi_write_half_outbuf(); - else /* ignore it */ - return; - else if (state == SHI_STATE_PROCESSING -#ifdef NPCX_SHI_BYPASS_OVER_256B - || state == SHI_STATE_WAIT_ALIGNMENT -#endif - ) - /* Wait for host handles request */ - return; - else - /* Unexpected status */ - log_unexpected_state("IBF"); - } -} -DECLARE_IRQ(NPCX_IRQ_SHI, shi_int_handler, 2); - -/* Handle an CS assert event on the SHI_CS_L pin */ -void shi_cs_event(enum gpio_signal signal) -{ -#ifdef NPCX_SHI_V2 - /* - * New SHI module handles the CS low event in the SHI module interrupt - * handler (checking CSNFE bit) instead of in GPIO(MIWU) interrupt - * handler. But there is still a need to configure the MIWU to generate - * event to wake up EC from deep sleep. Immediately return to bypass - * the CS low interrupt event from MIWU module. - */ - return; -#else - shi_handle_cs_assert(); -#endif - -} - -/*****************************************************************************/ -/* Hook functions for chipset and initialization */ - -/* - * Reset SHI bus and prepare next transaction - * Please make sure it is executed when there're no spi transactions - */ -static void shi_reset_prepare(void) -{ - uint16_t i; - - /* We no longer care about SHI interrupts, so disable them. */ - task_disable_irq(NPCX_IRQ_SHI); - - /* Disable SHI unit to clear all status bits */ - CLEAR_BIT(NPCX_SHICFG1, NPCX_SHICFG1_EN); - - /* Initialize parameters of next transaction */ - shi_params.rx_msg = in_msg; - shi_params.tx_msg = out_msg; - shi_params.rx_buf = SHI_IBUF_START_ADDR; - shi_params.tx_buf = SHI_OBUF_HALF_ADDR; - shi_params.sz_received = 0; - shi_params.sz_sending = 0; - shi_params.sz_request = 0; - shi_params.sz_response = 0; -#ifdef NPCX_SHI_BYPASS_OVER_256B - shi_params.bytes_in_256b = 0; -#endif - /* Record last IBUFSTAT for glitch case */ - shi_params.pre_ibufstat = shi_read_buf_pointer(); - - /* - * Fill output buffer to indicate we`re - * ready to receive next transaction. - */ - for (i = 1; i < SHI_OBUF_FULL_SIZE; i++) - NPCX_OBUF(i) = EC_SPI_RECEIVING; - NPCX_OBUF(0) = EC_SPI_OLD_READY; - - /* Enable SHI & WEN functionality */ - NPCX_SHICFG1 = 0x85; - - /* Ready to receive */ - state = SHI_STATE_READY_TO_RECV; - last_error_state = -1; - - /* Setup second IBF interrupt and enable SHI's interrupt */ -#ifdef NPCX_SHI_V2 - shi_sec_ibf_int_enable(1); - task_enable_irq(NPCX_IRQ_SHI); -#endif - - /* Allow deep sleep at the end of SHI transaction */ - enable_sleep(SLEEP_MASK_SPI); - - DEBUG_CPRINTF("RDY-"); -} - -static void shi_enable(void) -{ - int gpio_flags; - - shi_reset_prepare(); - - /* Ensure SHI_CS_L interrupt is disabled */ - gpio_disable_interrupt(GPIO_SHI_CS_L); - - /* Enable PU, if requested */ - gpio_flags = GPIO_INPUT | GPIO_INT_F_FALLING; -#ifdef NPCX_SHI_CS_PU - gpio_flags |= GPIO_PULL_UP; -#endif - gpio_set_flags(GPIO_SHI_CS_L, gpio_flags); - - /* - * Mux SHI related pins - * SHI_SDI SHI_SDO SHI_CS# SHI_SCLK are selected to device pins - */ - SET_BIT(NPCX_DEVALT(ALT_GROUP_C), NPCX_DEVALTC_SHI_SL); - - task_clear_pending_irq(NPCX_IRQ_SHI); - - /* Enable SHI_CS_L interrupt */ - gpio_enable_interrupt(GPIO_SHI_CS_L); - - /* - * If CS is already asserted prior to enabling our GPIO interrupt then - * we have missed the falling edge and we need to handle the - * deassertion interrupt. - */ - task_enable_irq(NPCX_IRQ_SHI); -} -#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK -DECLARE_HOOK(HOOK_CHIPSET_RESUME_INIT, shi_enable, HOOK_PRIO_DEFAULT); -#else -DECLARE_HOOK(HOOK_CHIPSET_RESUME, shi_enable, HOOK_PRIO_DEFAULT); -#endif - -static void shi_reenable_on_sysjump(void) -{ -#if !(DEBUG_SHI) - if (system_jumped_late() && chipset_in_state(CHIPSET_STATE_ON)) -#endif - shi_enable(); -} -/* Call hook after chipset sets initial power state */ -DECLARE_HOOK(HOOK_INIT, - shi_reenable_on_sysjump, - HOOK_PRIO_INIT_CHIPSET + 1); - -/* Disable SHI bus */ -static void shi_disable(void) -{ - state = SHI_STATE_DISABLED; - - task_disable_irq(NPCX_IRQ_SHI); - - /* Disable SHI_CS_L interrupt */ - gpio_disable_interrupt(GPIO_SHI_CS_L); - - /* Restore SHI_CS_L back to default state */ - gpio_reset(GPIO_SHI_CS_L); - - /* - * Mux SHI related pins - * SHI_SDI SHI_SDO SHI_CS# SHI_SCLK are selected to GPIO - */ - CLEAR_BIT(NPCX_DEVALT(ALT_GROUP_C), NPCX_DEVALTC_SHI_SL); - - /* - * Allow deep sleep again in case CS dropped before ec was - * informed in hook function and turn off SHI's interrupt in time. - */ - enable_sleep(SLEEP_MASK_SPI); -} -#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND_COMPLETE, shi_disable, HOOK_PRIO_DEFAULT); -#else -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, shi_disable, HOOK_PRIO_DEFAULT); -#endif -DECLARE_HOOK(HOOK_SYSJUMP, shi_disable, HOOK_PRIO_DEFAULT); - -static void shi_init(void) -{ - /* Power on SHI module first */ - CLEAR_BIT(NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_5), NPCX_PWDWN_CTL5_SHI_PD); - -#ifdef NPCX_SHI_V2 - /* Enable SHI module Version 2 */ - SET_BIT(NPCX_DEVALT(ALT_GROUP_F), NPCX_DEVALTF_SHI_NEW); -#endif - - /* - * SHICFG1 (SHI Configuration 1) setting - * [7] - IWRAP = 1: Wrap input buffer to the first address - * [6] - CPOL = 0: Sampling on rising edge and output on falling edge - * [5] - DAS = 0: return STATUS reg data after Status command - * [4] - AUTOBE = 0: Automatically update the OBES bit in STATUS reg - * [3] - AUTIBF = 0: Automatically update the IBFS bit in STATUS reg - * [2] - WEN = 0: Enable host write to input buffer - * [1] - Reserved 0 - * [0] - ENABLE = 0: Disable SHI at the beginning - */ - NPCX_SHICFG1 = 0x80; - - /* - * SHICFG2 (SHI Configuration 2) setting - * [7] - Reserved 0 - * [6] - REEVEN = 0: Restart events are not used - * [5] - Reserved 0 - * [4] - REEN = 0: Restart transactions are not used - * [3] - SLWU = 0: Seem-less wake-up is enabled by default - * [2] - ONESHOT= 0: WEN is cleared at the end of a write transaction - * [1] - BUSY = 0: SHI bus is busy 0: idle. - * [0] - SIMUL = 1: Turn on simultaneous Read/Write - */ - NPCX_SHICFG2 = 0x01; - - /* - * EVENABLE (Event Enable) setting - * [7] - IBOREN = 0: Input buffer overrun interrupt enable - * [6] - STSREN = 0: status read interrupt disable - * [5] - EOWEN = 0: End-of-Data for Write Transaction Interrupt Enable - * [4] - EOREN = 1: End-of-Data for Read Transaction Interrupt Enable - * [3] - IBHFEN = 1: Input Buffer Half Full Interrupt Enable - * [2] - IBFEN = 1: Input Buffer Full Interrupt Enable - * [1] - OBHEEN = 0: Output Buffer Half Empty Interrupt Enable - * [0] - OBEEN = 0: Output Buffer Empty Interrupt Enable - */ - NPCX_EVENABLE = 0x1C; - -#ifdef NPCX_SHI_V2 - /* - * EVENABLE2 (Event Enable 2) setting - * [2] - CSNFEEN = 1: SHI_CS Falling Edge Interrupt Enable - * [1] - CSNREEN = 1: SHI_CS Rising Edge Interrupt Enable - * [0] - IBHF2EN = 0: Input Buffer Half Full 2 Interrupt Enable - */ - NPCX_EVENABLE2 = 0x06; -#endif - - /* Clear SHI events status register */ - NPCX_EVSTAT = 0XFF; -} -/* Call hook before chipset sets initial power state and calls resume hooks */ -DECLARE_HOOK(HOOK_INIT, shi_init, HOOK_PRIO_INIT_CHIPSET - 1); - -/** - * Get protocol information - */ -static enum ec_status shi_get_protocol_info(struct host_cmd_handler_args *args) -{ - struct ec_response_get_protocol_info *r = args->response; - - memset(r, 0, sizeof(*r)); - r->protocol_versions = BIT(3); - r->max_request_packet_size = SHI_MAX_REQUEST_SIZE; - r->max_response_packet_size = SHI_MAX_RESPONSE_SIZE; - r->flags = EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED; - - args->response_size = sizeof(*r); - - return EC_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_GET_PROTOCOL_INFO, shi_get_protocol_info, -EC_VER_MASK(0)); diff --git a/chip/npcx/shi_chip.h b/chip/npcx/shi_chip.h deleted file mode 100644 index c14aec196e..0000000000 --- a/chip/npcx/shi_chip.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2015 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-specific SHI module for Chrome EC */ - -#ifndef SHI_CHIP_H_ -#define SHI_CHIP_H_ - -#ifdef CONFIG_HOSTCMD_SHI -/** - * Called when the NSS level changes, signalling the start of a SHI - * transaction. - * - * @param signal GPIO signal that changed - */ -void shi_cs_event(enum gpio_signal signal); -#ifdef NPCX_SHI_V2 -void shi_cs_gpio_int(enum gpio_signal signal); -#endif -#endif - -#endif /* SHI_CHIP_H_ */ diff --git a/chip/npcx/sib.c b/chip/npcx/sib.c deleted file mode 100644 index b8e2e17955..0000000000 --- a/chip/npcx/sib.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2019 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-specific SIB module for Chrome EC */ - -#include "console.h" -#include "hwtimer_chip.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* - * Timeout to wait for host transaction to be completed. - * - * For eSPI - it is 200 us. - * For LPC - it is 5 us. - */ -#ifdef CONFIG_HOSTCMD_ESPI -#define HOST_TRANSACTION_TIMEOUT_US 200 -#else -#define HOST_TRANSACTION_TIMEOUT_US 5 -#endif - -/* Console output macros */ -#ifdef DEBUG_SIB -#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#else -#define CPUTS(...) -#define CPRINTS(...) -#endif - -/* - * Check host read is not in-progress and no timeout - */ -static void sib_wait_host_read_done(void) -{ - timestamp_t deadline, start; - - start = get_time(); - deadline.val = start.val + HOST_TRANSACTION_TIMEOUT_US; - while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD)) { - if (timestamp_expired(deadline, NULL)) { - CPRINTS("Unexpected time of host read transaction"); - break; - } - /* Handle ITIM32 overflow condition */ - __hw_clock_handle_overflow(start.le.hi); - } -} - -/* - * Check host write is not in-progress and no timeout - */ -static void sib_wait_host_write_done(void) -{ - timestamp_t deadline, start; - - start = get_time(); - deadline.val = start.val + HOST_TRANSACTION_TIMEOUT_US; - while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSWR)) { - if (timestamp_expired(deadline, NULL)) { - CPRINTS("Unexpected time of host write transaction"); - break; - } - /* Handle ITIM32 overflow condition */ - __hw_clock_handle_overflow(start.le.hi); - } -} - -/* Emulate host to read Keyboard I/O */ -uint8_t sib_read_kbc_reg(uint8_t io_offset) -{ - uint8_t data_value; - - /* Disable interrupts */ - interrupt_disable(); - - /* Lock host keyboard module */ - SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKHIKBD); - /* Verify Core read/write to host modules is not in progress */ - sib_wait_host_read_done(); - sib_wait_host_write_done(); - /* Enable Core access to keyboard module */ - SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_HIKBDAE); - - /* Specify the io_offset A0 = 0. the index register is accessed */ - NPCX_IHIOA = io_offset; - - /* Start a Core read from host module */ - SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD); - /* Wait while Core read operation is in progress */ - sib_wait_host_read_done(); - /* Read the data */ - data_value = NPCX_IHD; - - /* Disable Core access to keyboard module */ - CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_HIKBDAE); - /* unlock host keyboard module */ - CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKHIKBD); - - /* Enable interrupts */ - interrupt_enable(); - - return data_value; -} - -/* Super-IO read/write function */ -void sib_write_reg(uint8_t io_offset, uint8_t index_value, - uint8_t io_data) -{ - /* Disable interrupts */ - interrupt_disable(); - - /* Lock host CFG module */ - SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG); - /* Enable Core access to CFG module */ - SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE); - /* Verify Core read/write to host modules is not in progress */ - sib_wait_host_read_done(); - sib_wait_host_write_done(); - - /* Specify the io_offset A0 = 0. the index register is accessed */ - NPCX_IHIOA = io_offset; - /* Write the data. This starts the write access to the host module */ - NPCX_IHD = index_value; - /* Wait while Core write operation is in progress */ - sib_wait_host_write_done(); - - /* Specify the io_offset A0 = 1. the data register is accessed */ - NPCX_IHIOA = io_offset+1; - /* Write the data. This starts the write access to the host module */ - NPCX_IHD = io_data; - /* Wait while Core write operation is in progress */ - sib_wait_host_write_done(); - - /* Disable Core access to CFG module */ - CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE); - /* unlock host CFG module */ - CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG); - - /* Enable interrupts */ - interrupt_enable(); -} - -uint8_t sib_read_reg(uint8_t io_offset, uint8_t index_value) -{ - uint8_t data_value; - - /* Disable interrupts */ - interrupt_disable(); - - /* Lock host CFG module */ - SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG); - /* Enable Core access to CFG module */ - SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE); - /* Verify Core read/write to host modules is not in progress */ - sib_wait_host_read_done(); - sib_wait_host_write_done(); - - /* Specify the io_offset A0 = 0. the index register is accessed */ - NPCX_IHIOA = io_offset; - /* Write the data. This starts the write access to the host module */ - NPCX_IHD = index_value; - /* Wait while Core write operation is in progress */ - sib_wait_host_write_done(); - - /* Specify the io_offset A0 = 1. the data register is accessed */ - NPCX_IHIOA = io_offset+1; - /* Start a Core read from host module */ - SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD); - /* Wait while Core read operation is in progress */ - sib_wait_host_read_done(); - /* Read the data */ - data_value = NPCX_IHD; - - /* Disable Core access to CFG module */ - CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE); - /* unlock host CFG module */ - CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG); - - /* Enable interrupts */ - interrupt_enable(); - - return data_value; -} - diff --git a/chip/npcx/sib_chip.h b/chip/npcx/sib_chip.h deleted file mode 100644 index 2341f219b4..0000000000 --- a/chip/npcx/sib_chip.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2019 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-specific SIB module for Chrome EC */ - -/* Super-IO index and register definitions */ -#define INDEX_SID 0x20 -#define INDEX_CHPREV 0x24 -#define INDEX_SRID 0x27 - -#define SIO_OFFSET 0x4E - -/* Super-IO register write function */ -void sib_write_reg(uint8_t io_offset, uint8_t index_value, - uint8_t io_data); -/* Super-IO register read function */ -uint8_t sib_read_reg(uint8_t io_offset, uint8_t index_value); -/* Emulate host to read Keyboard I/O */ -uint8_t sib_read_kbc_reg(uint8_t io_offset); - diff --git a/chip/npcx/spi.c b/chip/npcx/spi.c deleted file mode 100644 index 55fa8f85ab..0000000000 --- a/chip/npcx/spi.c +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright 2014 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. - */ - -/* SPI module for Chrome EC */ - -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "clock.h" -#include "clock_chip.h" -#include "registers.h" -#include "spi.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Console output macros */ -#if !DEBUG_SPI -#define CPUTS(...) -#define CPRINTS(...) -#else -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) -#endif - -/* SPI IP as SPI controller */ -#define SPI_CLK 8000000 -/** - * Clear SPI data buffer. - * - * @param none - * @return none. - */ -static void clear_databuf(void) -{ - volatile uint8_t unused __attribute__((unused)); - while (IS_BIT_SET(NPCX_SPI_STAT, NPCX_SPI_STAT_RBF)) - unused = NPCX_SPI_DATA; -} - -/** - * Preset SPI operation clock. - * - * @param none - * @return none - * @notes changed when initial or HOOK_FREQ_CHANGE command - */ -void spi_freq_changed(void) -{ - uint8_t prescaler_divider = 0; - - /* Set clock prescaler divider to SPI module*/ - prescaler_divider = (uint8_t)((uint32_t)clock_get_apb2_freq() - / 2 / SPI_CLK); - if (prescaler_divider >= 1) - prescaler_divider = prescaler_divider - 1; - if (prescaler_divider > 0x7F) - prescaler_divider = 0x7F; - - /* Set core clock division factor in order to obtain the SPI clock */ - NPCX_SPI_CTL1 = (NPCX_SPI_CTL1&(~(((1<<7)-1)<<NPCX_SPI_CTL1_SCDV))) - |(prescaler_divider<<NPCX_SPI_CTL1_SCDV); -} -DECLARE_HOOK(HOOK_FREQ_CHANGE, spi_freq_changed, HOOK_PRIO_FIRST); - -/** - * Set SPI enabled. - * - * @spi_device SPI device to act on. - * @param enable enabled flag - * @return success - */ -int spi_enable(const struct spi_device_t *spi_device, int enable) -{ - enum gpio_signal gpio; - - if (enable) { - /* Enabling spi module for gpio configuration */ - gpio_config_module(MODULE_SPI, 1); - /* GPIO No SPI Select */ - CLEAR_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_GPIO_NO_SPIP); - - gpio = spi_device->gpio_cs; - /* Make sure CS# is in GPIO output mode. */ - gpio_set_flags(gpio, GPIO_OUTPUT); - /* Make sure CS# is deselected */ - gpio_set_level(gpio, 1); - - /* Enabling spi module */ - SET_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_SPIEN); - } else { - /* Disabling spi module */ - CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_SPIEN); - gpio = spi_device->gpio_cs; - /* Make sure CS# is deselected */ - gpio_set_level(gpio, 1); - gpio_set_flags(gpio, GPIO_ODR_HIGH); - /* Disabling spi module for gpio configuration */ - gpio_config_module(MODULE_SPI, 0); - /* GPIO No SPI Select */ - SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_GPIO_NO_SPIP); - } - return EC_SUCCESS; -} - - -/** - * Flush an SPI transaction and receive data from peripheral. - * - * @param spi_device device to talk to - * @param txdata transfer data - * @param txlen transfer length - * @param rxdata receive data - * @param rxlen receive length - * @return success - * @notes set controller transaction mode in npcx chip - */ -int spi_transaction(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - int i = 0; - enum gpio_signal gpio = spi_device->gpio_cs; - static struct mutex spi_lock; - - mutex_lock(&spi_lock); - /* Make sure CS# is a GPIO output mode. */ - gpio_set_flags(gpio, GPIO_OUTPUT); - /* Make sure CS# is deselected */ - gpio_set_level(gpio, 1); - /* Cleaning junk data in the buffer */ - clear_databuf(); - /* Assert CS# to start transaction */ - gpio_set_level(gpio, 0); - CPRINTS("NPCX_SPI_DATA=%x", NPCX_SPI_DATA); - CPRINTS("NPCX_SPI_CTL1=%x", NPCX_SPI_CTL1); - CPRINTS("NPCX_SPI_STAT=%x", NPCX_SPI_STAT); - /* Writing the data */ - for (i = 0; i < txlen; ++i) { - /* Making sure we can write */ - while (IS_BIT_SET(NPCX_SPI_STAT, NPCX_SPI_STAT_BSY)) - ; - /* Write the data */ - NPCX_SPI_DATA = txdata[i]; - CPRINTS("txdata[i]=%x", txdata[i]); - /* Waiting till reading is finished */ - while (!IS_BIT_SET(NPCX_SPI_STAT, NPCX_SPI_STAT_RBF)) - ; - /* Reading the (unused) data */ - clear_databuf(); - } - CPRINTS("write end"); - /* Reading the data */ - for (i = 0; i < rxlen; ++i) { - /* Making sure we can write */ - while (IS_BIT_SET(NPCX_SPI_STAT, NPCX_SPI_STAT_BSY)) - ; - /* Write the (unused) data */ - NPCX_SPI_DATA = 0; - /* Wait till reading is finished */ - while (!IS_BIT_SET(NPCX_SPI_STAT, NPCX_SPI_STAT_RBF)) - ; - /* Reading the data */ - rxdata[i] = (uint8_t)NPCX_SPI_DATA; - CPRINTS("rxdata[i]=%x", rxdata[i]); - } - /* Deassert CS# (high) to end transaction */ - gpio_set_level(gpio, 1); - mutex_unlock(&spi_lock); - - return EC_SUCCESS; -} - -/** - * SPI initial. - * - * @param none - * @return none - */ -static void spi_init(void) -{ - int i; - /* Enable clock for SPI peripheral */ - clock_enable_peripheral(CGC_OFFSET_SPI, CGC_SPI_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - - /* Disabling spi module */ - for (i = 0; i < spi_devices_used; i++) - spi_enable(&spi_devices[i], 0); - - /* Disabling spi irq */ - CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_EIR); - CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_EIW); - - /* Setting clocking mode to normal mode */ - CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_SCM); - /* Setting 8bit mode transfer */ - CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_MOD); - /* Set core clock division factor in order to obtain the spi clock */ - spi_freq_changed(); - - /* We emit zeros in idle (default behaivor) */ - CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_SCIDL); - - CPRINTS("nSPI_COMP=%x", IS_BIT_SET(NPCX_STRPST, NPCX_STRPST_SPI_COMP)); - CPRINTS("SPI_SP_SEL=%x", IS_BIT_SET(NPCX_DEV_CTL4, - NPCX_DEV_CTL4_SPI_SP_SEL)); - /* Cleaning junk data in the buffer */ - clear_databuf(); -} -DECLARE_HOOK(HOOK_INIT, spi_init, HOOK_PRIO_INIT_SPI); - -/*****************************************************************************/ -/* Console commands */ -#ifdef CONFIG_CMD_SPI_FLASH -static int printrx(const char *desc, const uint8_t *txdata, int txlen, - int rxlen) -{ - uint8_t rxdata[32]; - int rv; - int i; - - rv = spi_transaction(SPI_FLASH_DEVICE, txdata, txlen, rxdata, rxlen); - if (rv) - return rv; - - CPRINTS("%-12s:", desc); - for (i = 0; i < rxlen; i++) - CPRINTS(" 0x%02x", rxdata[i]); - CPUTS("\n"); - return EC_SUCCESS; -} - -static int command_spirom(int argc, char **argv) -{ - uint8_t txmandev[] = {0x90, 0x00, 0x00, 0x00}; - uint8_t txjedec[] = {0x9f}; - uint8_t txunique[] = {0x4b, 0x00, 0x00, 0x00, 0x00}; - uint8_t txsr1[] = {0x05}; - uint8_t txsr2[] = {0x35}; - - spi_enable(SPI_FLASH_DEVICE, 1); - - printrx("Man/Dev ID", txmandev, sizeof(txmandev), 2); - printrx("JEDEC ID", txjedec, sizeof(txjedec), 3); - printrx("Unique ID", txunique, sizeof(txunique), 8); - printrx("Status reg 1", txsr1, sizeof(txsr1), 1); - printrx("Status reg 2", txsr2, sizeof(txsr2), 1); - - spi_enable(SPI_FLASH_DEVICE, 0); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(spirom, command_spirom, - NULL, - "Test reading SPI EEPROM"); -#endif diff --git a/chip/npcx/spiflashfw/monitor_hdr.c b/chip/npcx/spiflashfw/monitor_hdr.c deleted file mode 100644 index 219a037d27..0000000000 --- a/chip/npcx/spiflashfw/monitor_hdr.c +++ /dev/null @@ -1,37 +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. - * - * NPCX SoC spi flash update tool - monitor firmware header - */ - -#include "config.h" -#include "npcx_monitor.h" - -const struct monitor_header_tag monitor_hdr = { - /* 0x00: TAG = 0xA5075001 */ - NPCX_MONITOR_UUT_TAG, - /* 0x04: Size·of·the·EC image·be·programmed. - * Default = code RAM size - */ - NPCX_PROGRAM_MEMORY_SIZE, - /* - * 0x08: The start of RAM address to store the EC image, which will be - * programed into the SPI flash. - */ - CONFIG_PROGRAM_MEMORY_BASE, - /* 0x0C:The Flash start address to be programmed*/ -#ifdef SECTION_IS_RO - /* Default: RO image is programed from the start of SPI flash */ - CONFIG_EC_PROTECTED_STORAGE_OFF, -#else - /* Default: RW image is programed from the half of SPI flash */ - CONFIG_EC_WRITABLE_STORAGE_OFF, -#endif - /* 0x10: Maximum allowable flash clock frequency */ - 0, - /* 0x11: SPI Flash read mode */ - 0, - /* 0x12: Reserved */ - 0, -}; diff --git a/chip/npcx/spiflashfw/npcx_monitor.c b/chip/npcx/spiflashfw/npcx_monitor.c deleted file mode 100644 index cd52e7a80f..0000000000 --- a/chip/npcx/spiflashfw/npcx_monitor.c +++ /dev/null @@ -1,338 +0,0 @@ -/* Copyright 2014 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 "config.h" -#include "npcx_monitor.h" -#include "registers.h" -#include "util.h" - -/*****************************************************************************/ -/* 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/chip/npcx/spiflashfw/npcx_monitor.h b/chip/npcx/spiflashfw/npcx_monitor.h deleted file mode 100644 index f4f30454d2..0000000000 --- a/chip/npcx/spiflashfw/npcx_monitor.h +++ /dev/null @@ -1,33 +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. - */ -#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/chip/npcx/spiflashfw/npcx_monitor.ld b/chip/npcx/spiflashfw/npcx_monitor.ld deleted file mode 100644 index 03e38b0609..0000000000 --- a/chip/npcx/spiflashfw/npcx_monitor.ld +++ /dev/null @@ -1,52 +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. - * - * 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/chip/npcx/system-npcx5.c b/chip/npcx/system-npcx5.c deleted file mode 100644 index 4dd12fbae2..0000000000 --- a/chip/npcx/system-npcx5.c +++ /dev/null @@ -1,261 +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 "gpio.h" -#include "hwtimer_chip.h" -#include "mpu.h" -#include "registers.h" -#include "rom_chip.h" -#include "system.h" -#include "system_chip.h" -#include "task.h" -#include "util.h" - -/* Begin address of Suspend RAM for hibernate utility */ -uintptr_t __lpram_fw_start = CONFIG_LPRAM_BASE; -/* Offset of little FW in Suspend Ram for GDMA bypass */ -#define LFW_OFFSET 0x160 -/* Begin address of Suspend RAM for little FW (GDMA utilities). */ -uintptr_t __lpram_lfw_start = CONFIG_LPRAM_BASE + LFW_OFFSET; - -/*****************************************************************************/ -/* 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) -{ - /* 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; -} - -/** - * hibernate function in low power ram for npcx5 series. - */ -noreturn void __keep __attribute__ ((section(".lowpower_ram"))) -__enter_hibernate_in_lpram(void) -{ - /* - * TODO (ML): Set stack pointer to upper 512B of Suspend RAM. - * Our bypass needs stack instructions but FW will turn off main ram - * later for better power consumption. - */ - asm ( - "ldr r0, =0x40001800\n" - "mov sp, r0\n" - ); - - /* Disable Code RAM first */ - SET_BIT(NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_5), NPCX_PWDWN_CTL5_MRFSH_DIS); - SET_BIT(NPCX_DISIDL_CTL, NPCX_DISIDL_CTL_RAM_DID); - - /* Set deep idle mode*/ - NPCX_PMCSR = 0x6; - - /* Enter deep idle, wake-up by GPIOs or RTC */ - /* - * TODO (ML): Although the probability is small, it still has chance - * to meet the same symptom that CPU's behavior is abnormal after - * wake-up from deep idle. - * Workaround: Apply the same bypass of idle but don't enable interrupt. - */ - asm ( - "push {r0-r5}\n" /* Save needed registers */ - "ldr r0, =0x40001600\n" /* Set r0 to Suspend RAM addr */ - "wfi\n" /* Wait for int to enter idle */ - "ldm r0, {r0-r5}\n" /* Add a delay after WFI */ - "pop {r0-r5}\n" /* Restore regs before enabling ints */ - "isb\n" /* Flush the cpu pipeline */ - ); - - /* 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 - * executing in low-power ram - */ - NPCX_BBRAM(BBRM_DATA_INDEX_WAKE) = HIBERNATE_WAKE_MTC; - 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) - ; -} - -/** - * Hibernate function for different Nuvoton chip series. - */ -void __hibernate_npcx_series(void) -{ - int i; - void (*__hibernate_in_lpram)(void) = - (void(*)(void))(__lpram_fw_start | 0x01); - - /* 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; - - /* Copy the __enter_hibernate_in_lpram instructions to LPRAM */ - for (i = 0; i < &__flash_lpfw_end - &__flash_lpfw_start; i++) - *((uint32_t *)__lpram_fw_start + i) = - *(&__flash_lpfw_start + i); - - /* execute hibernate func in LPRAM */ - __hibernate_in_lpram(); -} - -#ifdef CONFIG_EXTERNAL_STORAGE -/* Sysjump utilities in low power ram for npcx5 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 */ 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 diff --git a/chip/npcx/system-npcx9.c b/chip/npcx/system-npcx9.c deleted file mode 120000 index 48088614a0..0000000000 --- a/chip/npcx/system-npcx9.c +++ /dev/null @@ -1 +0,0 @@ -system-npcx7.c
\ No newline at end of file diff --git a/chip/npcx/system.c b/chip/npcx/system.c deleted file mode 100644 index ac7056330f..0000000000 --- a/chip/npcx/system.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* Copyright 2014 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 : NPCX hardware specific implementation */ - -#include "clock.h" -#include "clock_chip.h" -#include "common.h" -#include "console.h" -#include "cpu.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "hwtimer_chip.h" -#include "lct_chip.h" -#include "registers.h" -#include "rom_chip.h" -#include "sib_chip.h" -#include "system.h" -#include "system_chip.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "watchdog.h" - -/* Delay after writing TTC for value to latch */ -#define MTC_TTC_LOAD_DELAY_US 250 -#define MTC_ALARM_MASK (BIT(25) - 1) -#define MTC_WUI_GROUP MIWU_GROUP_4 -#define MTC_WUI_MASK MASK_PIN7 - -/* ROM address of chip revision */ -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 -#define CHIP_REV_ADDR 0x0000FFFC -#define CHIP_REV_STR_SIZE 12 -#else -#define CHIP_REV_ADDR 0x00007FFC -#define CHIP_REV_STR_SIZE 6 -#endif - -/* Legacy SuperI/O Configuration D register offset */ -#define SIOCFD_REG_OFFSET 0x2D - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) - -#if defined(NPCX_LCT_SUPPORT) -/* A flag for waking up from hibernate mode by RTC overflow event */ -static int is_rtc_overflow_event; -#endif - -/*****************************************************************************/ -/* Internal functions */ - -void system_watchdog_reset(void) -{ - /* Unlock & stop watchdog registers */ - watchdog_stop_and_unlock(); - - /* Reset TWCFG */ - NPCX_TWCFG = 0; - /* Select T0IN clock as watchdog prescaler clock */ - SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDCT0I); - - /* Clear watchdog reset status initially*/ - SET_BIT(NPCX_T0CSR, NPCX_T0CSR_WDRST_STS); - - /* Keep prescaler ratio timer0 clock to 1:1 */ - NPCX_TWCP = 0x00; - - /* Set internal counter and prescaler */ - NPCX_TWDT0 = 0x00; - NPCX_WDCNT = 0x01; - - /* Disable interrupt */ - interrupt_disable(); - /* 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)) - ; - /* Enable interrupt */ - interrupt_enable(); -} - -/* Return true if index is stored as a single byte in bbram */ -static int bbram_is_byte_access(enum bbram_data_index index) -{ - return index == BBRM_DATA_INDEX_PD0 || - index == BBRM_DATA_INDEX_PD1 || - index == BBRM_DATA_INDEX_PD2 || - index == BBRM_DATA_INDEX_PANIC_FLAGS; -} - -/* Check and clear BBRAM status on any reset */ -void system_check_bbram_on_reset(void) -{ - if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR)) { - /* - * If the reset cause is not power-on reset and VBAT has ever - * dropped, print a warning message. - */ - if (IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_SCRATCH) || - IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_STS)) - CPRINTF("VBAT drop!\n"); - - /* - * npcx5/npcx7m6g/npcx7m6f: - * Clear IBBR bit - * npcx7m6fb/npcx7m6fc/npcx7m7fc/npcx7m7wb/npcx7m7wc: - * Clear IBBR/VSBY_STS/VCC1_STS bit - */ - NPCX_BKUP_STS = NPCX_BKUP_STS_ALL_MASK; - } -} - -/* Check index is within valid BBRAM range and IBBR is not set */ -static int bbram_valid(enum bbram_data_index index, int bytes) -{ - /* Check index */ - if (index < 0 || index + bytes > NPCX_BBRAM_SIZE) - return 0; - - /* Check BBRAM is valid */ - if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR)) { - NPCX_BKUP_STS = BIT(NPCX_BKUP_STS_IBBR); - panic_printf("IBBR set: BBRAM corrupted!\n"); - return 0; - } - return 1; -} - -/** - * Read battery-backed ram (BBRAM) at specified index. - * - * @return The value of the register or 0 if invalid index. - */ -static uint32_t bbram_data_read(enum bbram_data_index index) -{ - uint32_t value = 0; - int bytes = bbram_is_byte_access(index) ? 1 : 4; - - if (!bbram_valid(index, bytes)) - return 0; - - /* Read BBRAM */ - if (bytes == 4) { - value += NPCX_BBRAM(index + 3); - value = value << 8; - value += NPCX_BBRAM(index + 2); - value = value << 8; - value += NPCX_BBRAM(index + 1); - value = value << 8; - } - value += NPCX_BBRAM(index); - - return value; -} - -/** - * Write battery-backed ram (BBRAM) at specified index. - * - * @return nonzero if error. - */ -static int bbram_data_write(enum bbram_data_index index, uint32_t value) -{ - int bytes = bbram_is_byte_access(index) ? 1 : 4; - - if (!bbram_valid(index, bytes)) - return EC_ERROR_INVAL; - - /* Write BBRAM */ - NPCX_BBRAM(index) = value & 0xFF; - if (bytes == 4) { - NPCX_BBRAM(index + 1) = (value >> 8) & 0xFF; - NPCX_BBRAM(index + 2) = (value >> 16) & 0xFF; - NPCX_BBRAM(index + 3) = (value >> 24) & 0xFF; - } - - /* Wait for write-complete */ - return EC_SUCCESS; -} - -/* Map idx to a returned BBRM_DATA_INDEX_*, or return -1 on invalid idx */ -static int bbram_idx_lookup(enum system_bbram_idx idx) -{ - if (idx == SYSTEM_BBRAM_IDX_PD0) - return BBRM_DATA_INDEX_PD0; - if (idx == SYSTEM_BBRAM_IDX_PD1) - return BBRM_DATA_INDEX_PD1; - if (idx == SYSTEM_BBRAM_IDX_PD2) - return BBRM_DATA_INDEX_PD2; - if (idx == SYSTEM_BBRAM_IDX_TRY_SLOT) - return BBRM_DATA_INDEX_TRY_SLOT; - return -1; -} - -int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) -{ - int bbram_idx = bbram_idx_lookup(idx); - - if (bbram_idx < 0) - return EC_ERROR_INVAL; - - *value = bbram_data_read(bbram_idx); - return EC_SUCCESS; -} - -int system_set_bbram(enum system_bbram_idx idx, uint8_t value) -{ - int bbram_idx = bbram_idx_lookup(idx); - - if (bbram_idx < 0) - return EC_ERROR_INVAL; - - return bbram_data_write(bbram_idx, value); -} - -/* MTC functions */ -uint32_t system_get_rtc_sec(void) -{ - /* Get MTC counter unit:seconds */ - uint32_t sec = NPCX_TTC; - return sec; -} - -void system_set_rtc(uint32_t seconds) -{ - /* - * Set MTC counter unit:seconds, write twice to ensure values - * latch to NVMem. - */ - NPCX_TTC = seconds; - udelay(MTC_TTC_LOAD_DELAY_US); - NPCX_TTC = seconds; - udelay(MTC_TTC_LOAD_DELAY_US); -} - -#ifdef CONFIG_CHIP_PANIC_BACKUP -/* - * Following information from panic data is stored in BBRAM: - * - * index | data - * ==========|============= - * 36 | CFSR - * 40 | HFSR - * 44 | BFAR - * 48 | LREG1 - * 52 | LREG3 - * 56 | LREG4 - * 60 | reserved - * - * Above registers are chosen to be saved in case of panic because: - * 1. CFSR, HFSR and BFAR seem to provide more information about the fault. - * 2. LREG1, LREG3 and LREG4 store exception, reason and info in case of - * software panic. - */ -#define BKUP_CFSR (BBRM_DATA_INDEX_PANIC_BKUP + 0) -#define BKUP_HFSR (BBRM_DATA_INDEX_PANIC_BKUP + 4) -#define BKUP_BFAR (BBRM_DATA_INDEX_PANIC_BKUP + 8) -#define BKUP_LREG1 (BBRM_DATA_INDEX_PANIC_BKUP + 12) -#define BKUP_LREG3 (BBRM_DATA_INDEX_PANIC_BKUP + 16) -#define BKUP_LREG4 (BBRM_DATA_INDEX_PANIC_BKUP + 20) - -#define BKUP_PANIC_DATA_VALID BIT(0) - -void chip_panic_data_backup(void) -{ - struct panic_data *d = panic_get_data(); - - if (!d) - return; - - bbram_data_write(BKUP_CFSR, d->cm.cfsr); - bbram_data_write(BKUP_HFSR, d->cm.hfsr); - bbram_data_write(BKUP_BFAR, d->cm.dfsr); - bbram_data_write(BKUP_LREG1, d->cm.regs[1]); - bbram_data_write(BKUP_LREG3, d->cm.regs[3]); - bbram_data_write(BKUP_LREG4, d->cm.regs[4]); - bbram_data_write(BBRM_DATA_INDEX_PANIC_FLAGS, BKUP_PANIC_DATA_VALID); -} - -static void chip_panic_data_restore(void) -{ - struct panic_data *d; - - /* Ensure BBRAM is valid. */ - if (!bbram_valid(BKUP_CFSR, 4)) - return; - - /* Ensure Panic data in BBRAM is valid. */ - if (!(bbram_data_read(BBRM_DATA_INDEX_PANIC_FLAGS) & - BKUP_PANIC_DATA_VALID)) - return; - - d = get_panic_data_write(); - - memset(d, 0, CONFIG_PANIC_DATA_SIZE); - d->magic = PANIC_DATA_MAGIC; - d->struct_size = CONFIG_PANIC_DATA_SIZE; - d->struct_version = 2; - d->arch = PANIC_ARCH_CORTEX_M; - - d->cm.cfsr = bbram_data_read(BKUP_CFSR); - d->cm.hfsr = bbram_data_read(BKUP_HFSR); - d->cm.dfsr = bbram_data_read(BKUP_BFAR); - - d->cm.regs[1] = bbram_data_read(BKUP_LREG1); - d->cm.regs[3] = bbram_data_read(BKUP_LREG3); - d->cm.regs[4] = bbram_data_read(BKUP_LREG4); - - /* Reset panic data in BBRAM. */ - bbram_data_write(BBRM_DATA_INDEX_PANIC_FLAGS, 0); -} -#endif /* CONFIG_CHIP_PANIC_BACKUP */ - -void chip_save_reset_flags(uint32_t flags) -{ - bbram_data_write(BBRM_DATA_INDEX_SAVED_RESET_FLAGS, flags); -} - -uint32_t chip_read_reset_flags(void) -{ - return bbram_data_read(BBRM_DATA_INDEX_SAVED_RESET_FLAGS); -} - -static void chip_set_hib_flag(uint32_t *flags, uint32_t hib_wake_flags) -{ - /* Hibernate via PSL */ - if (hib_wake_flags & HIBERNATE_WAKE_PSL) { -#ifdef NPCX_LCT_SUPPORT - if (npcx_lct_is_event_set()) { - *flags |= EC_RESET_FLAG_RTC_ALARM | - EC_RESET_FLAG_HIBERNATE; - /* Is RTC overflow event? */ - if (bbram_data_read(BBRM_DATA_INDEX_LCT_TIME) == - NPCX_LCT_MAX) { - /* - * Mark it as RTC overflow event and handle it - * in hook init function later for logging info. - */ - is_rtc_overflow_event = 1; - } - npcx_lct_clear_event(); - return; - } -#endif - *flags |= EC_RESET_FLAG_WAKE_PIN | - EC_RESET_FLAG_HIBERNATE; - } else { /* Hibernate via non-PSL */ -#ifdef NPCX_LCT_SUPPORT - if (hib_wake_flags & HIBERNATE_WAKE_LCT) { - *flags |= EC_RESET_FLAG_RTC_ALARM | - EC_RESET_FLAG_HIBERNATE; - return; - } -#endif - if (hib_wake_flags & HIBERNATE_WAKE_PIN) { - *flags |= EC_RESET_FLAG_WAKE_PIN | - EC_RESET_FLAG_HIBERNATE; - } else if (hib_wake_flags & HIBERNATE_WAKE_MTC) { - *flags |= EC_RESET_FLAG_RTC_ALARM | - EC_RESET_FLAG_HIBERNATE; - } - } -} - -static void check_reset_cause(void) -{ - uint32_t hib_wake_flags = bbram_data_read(BBRM_DATA_INDEX_WAKE); - uint32_t chip_flags = chip_read_reset_flags(); - uint32_t flags = chip_flags; - - /* Clear saved reset flags in bbram */ -#ifdef CONFIG_POWER_BUTTON_INIT_IDLE - /* - * We're not sure whether we're booting or not. AP_IDLE will be cleared - * on S5->S3 transition. - */ - chip_flags &= EC_RESET_FLAG_AP_IDLE; -#else - chip_flags = 0; -#endif - /* Clear saved hibernate wake flag in bbram , too */ - bbram_data_write(BBRM_DATA_INDEX_WAKE, 0); - - chip_set_hib_flag(&flags, hib_wake_flags); - - /* Use scratch bit to check power on reset or VCC1_RST reset */ - if (!IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_SCRATCH)) { -#ifdef CONFIG_BOARD_FORCE_RESET_PIN - /* Treat all resets as RESET_PIN */ - flags |= EC_RESET_FLAG_RESET_PIN; -#else - /* Check for VCC1 reset */ - int reset = IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_STS); - - /* - * If configured, check the saved flags to see whether - * the previous restart was a power-on, in which case - * treat this restart as a power-on as well. - * This is to workaround the fact that the H1 will - * reset the EC at power up. - */ - if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON)) { - /* - * Reset pin restart rather than power-on, so check - * for any flag set from a previous power-on. - */ - if (reset) { - if (flags & EC_RESET_FLAG_INITIAL_PWR) - /* - * The previous restart was a power-on - * so treat this restart as that, and - * clear the flag so later code will - * not wait for the second reset. - */ - flags = - (flags & ~EC_RESET_FLAG_INITIAL_PWR) - | EC_RESET_FLAG_POWER_ON; - else - /* - * No previous power-on flag, - * so this is a subsequent restart - * i.e any restarts after the - * second restart caused by the H1. - */ - flags |= EC_RESET_FLAG_RESET_PIN; - } else { - flags |= EC_RESET_FLAG_POWER_ON; - - /* - * Power-on restart, so set a flag and save it - * for the next imminent reset. Later code - * will check for this flag and wait for the - * second reset. Waking from PSL hibernate is - * power-on for EC but not for H1, so do not - * wait for the second reset. - */ - if (!(flags & EC_RESET_FLAG_HIBERNATE)) { - flags |= EC_RESET_FLAG_INITIAL_PWR; - chip_flags |= EC_RESET_FLAG_INITIAL_PWR; - } - } - } else - /* - * No second reset after power-on, so - * set the flags according to the restart reason. - */ - flags |= reset ? EC_RESET_FLAG_RESET_PIN - : EC_RESET_FLAG_POWER_ON; -#endif - } - chip_save_reset_flags(chip_flags); - - /* - * Set scratch bit to distinguish VCC1RST# is asserted again - * or not. This bit will be clear automatically when VCC1RST# - * is asserted or power-on reset occurs - */ - SET_BIT(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_SCRATCH); - - /* Software debugger reset */ - if (IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_DBGRST_STS)) { - flags |= EC_RESET_FLAG_SOFT; - /* Clear debugger reset status initially*/ - SET_BIT(NPCX_RSTCTL, NPCX_RSTCTL_DBGRST_STS); - } - - /* Watchdog Reset */ - if (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_WDRST_STS)) { - /* - * Don't set EC_RESET_FLAG_WATCHDOG flag if watchdog is issued - * by system_reset or hibernate in order to distinguish reset - * cause is panic reason or not. - */ - if (!(flags & (EC_RESET_FLAG_SOFT | EC_RESET_FLAG_HARD | - EC_RESET_FLAG_HIBERNATE))) - flags |= EC_RESET_FLAG_WATCHDOG; - - /* Clear watchdog reset status initially*/ - SET_BIT(NPCX_T0CSR, NPCX_T0CSR_WDRST_STS); - } - - system_set_reset_flags(flags); -} - -/** - * Chip-level function to set GPIOs and wake-up inputs for hibernate. - */ -#ifdef CONFIG_SUPPORT_CHIP_HIBERNATION -static void system_set_gpios_and_wakeup_inputs_hibernate(void) -{ - int table, i; - - /* Disable all MIWU inputs before entering hibernate */ - for (table = MIWU_TABLE_0 ; table < MIWU_TABLE_2 ; table++) { - for (i = 0 ; i < 8 ; i++) { - /* Disable all wake-ups */ - NPCX_WKEN(table, i) = 0x00; - /* Clear all pending bits of wake-ups */ - NPCX_WKPCL(table, i) = 0xFF; - /* - * Disable all inputs of wake-ups to prevent leakage - * caused by input floating. - */ - NPCX_WKINEN(table, i) = 0x00; - } - } - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - /* Disable MIWU 2 group 6 inputs which used for the additional GPIOs */ - NPCX_WKEN(MIWU_TABLE_2, MIWU_GROUP_6) = 0x00; - NPCX_WKPCL(MIWU_TABLE_2, MIWU_GROUP_6) = 0xFF; - NPCX_WKINEN(MIWU_TABLE_2, MIWU_GROUP_6) = 0x00; -#endif - - /* Enable wake-up inputs of hibernate_wake_pins array */ - for (i = 0; i < hibernate_wake_pins_used; i++) { - gpio_reset(hibernate_wake_pins[i]); - /* Re-enable interrupt for wake-up inputs */ - gpio_enable_interrupt(hibernate_wake_pins[i]); -#if defined(CONFIG_HIBERNATE_PSL) - /* Config PSL pins setting for wake-up inputs */ - if (!system_config_psl_mode(hibernate_wake_pins[i])) - ccprintf("Invalid PSL setting in wake-up pin %d\n", i); -#endif - } -} - -#ifdef NPCX_LCT_SUPPORT -static void system_set_lct_alarm(uint32_t seconds, uint32_t microseconds) -{ - /* The min resolution of LCT is 1 seconds */ - if ((seconds == 0) && (microseconds != 0)) - seconds = 1; - - npcx_lct_enable(0); - npcx_lct_sel_power_src(NPCX_LCT_PWR_SRC_VSBY); -#ifdef CONFIG_HIBERNATE_PSL - /* Enable LCT event to PSL */ - npcx_lct_config(seconds, 1, 0); - /* save the start time of LCT */ - if (IS_ENABLED(CONFIG_HOSTCMD_RTC) || IS_ENABLED(CONFIG_CMD_RTC)) - bbram_data_write(BBRM_DATA_INDEX_LCT_TIME, seconds); -#else - /* Enable LCT event interrupt and MIWU */ - npcx_lct_config(seconds, 0, 1); - task_disable_irq(NPCX_IRQ_LCT_WKINTF_2); - /* Enable wake-up input sources & clear pending bit */ - NPCX_WKPCL(MIWU_TABLE_2, LCT_WUI_GROUP) |= LCT_WUI_MASK; - NPCX_WKINEN(MIWU_TABLE_2, LCT_WUI_GROUP) |= LCT_WUI_MASK; - NPCX_WKEN(MIWU_TABLE_2, LCT_WUI_GROUP) |= LCT_WUI_MASK; - task_enable_irq(NPCX_IRQ_LCT_WKINTF_2); -#endif - npcx_lct_enable(1); -} -#endif - -/** - * hibernate function for npcx ec. - * - * @param seconds Number of seconds to sleep before LCT alarm - * @param microseconds Number of microseconds to sleep before LCT alarm - */ -void __enter_hibernate(uint32_t seconds, uint32_t microseconds) -{ - int i; - - /* Disable ADC */ - NPCX_ADCCNF = 0; - usleep(1000); - -#ifdef NPCX_LCT_SUPPORT - /* - * This function must be called before the ITIM (system tick) - * is disabled because it calls udelay inside this function - */ - npcx_lct_enable_clk(1); -#endif - - /* Set SPI pins to be in Tri-State */ - SET_BIT(NPCX_DEVCNT, NPCX_DEVCNT_F_SPI_TRIS); - - /* Disable instant wake up mode for better power consumption */ - CLEAR_BIT(NPCX_ENIDL_CTL, NPCX_ENIDL_CTL_LP_WK_CTL); - - /* Disable interrupt */ - interrupt_disable(); - - /* Unlock & stop watchdog */ - watchdog_stop_and_unlock(); - - /* ITIM event module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN); - /* ITIM time module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_SYSTEM_NO), NPCX_ITCTS_ITEN); - /* ITIM watchdog warn module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - - /* Initialize watchdog */ - NPCX_TWCFG = 0; /* Select T0IN clock as watchdog prescaler clock */ - SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDCT0I); - NPCX_TWCP = 0x00; /* Keep prescaler ratio timer0 clock to 1:1 */ - NPCX_TWDT0 = 0x00; /* Set internal counter and prescaler */ - - /* Disable interrupt */ - interrupt_disable(); - - /* - * Set gpios and wake-up input for better power consumption before - * entering hibernate. - */ - system_set_gpios_and_wakeup_inputs_hibernate(); - - /* - * Give the board a chance to do any late stage hibernation work. This - * is likely going to configure GPIOs for hibernation. On some boards, - * it's possible that this may not return at all. On those boards, - * power to the EC is likely being turn off entirely. - */ - if (board_hibernate_late) - board_hibernate_late(); - - /* Clear all pending IRQ otherwise wfi will have no affect */ - for (i = NPCX_IRQ_0 ; i < NPCX_IRQ_COUNT ; i++) - task_clear_pending_irq(i); - - /* Set the timer interrupt for wake up. */ -#ifdef NPCX_LCT_SUPPORT - if (seconds || microseconds) { - system_set_lct_alarm(seconds, microseconds); - } else if (IS_ENABLED(CONFIG_HIBERNATE_PSL_COMPENSATE_RTC)) { - system_set_lct_alarm(NPCX_LCT_MAX, 0); - } -#else - if (seconds || microseconds) - system_set_rtc_alarm(seconds, microseconds); -#endif - - /* execute hibernate func depend on chip series */ - __hibernate_npcx_series(); -} - -#ifdef CONFIG_HIBERNATE_PSL_COMPENSATE_RTC -#ifndef NPCX_LCT_SUPPORT -#error "Do not enable CONFIG_HIBERNATE_PSL_COMPENSATE_RTC if npcx ec doesn't \ -support LCT!" -#endif -/* - * The function uses the LCT counter value to compensate for RTC after hibernate - * wake-up. Because system_set_rtc() will invoke udelay(), the function should - * execute after timer_init(). The function also should execute before - * npcx_lct_init() which will clear all LCT register. - */ -void system_compensate_rtc(void) -{ - uint32_t rtc_time, ltc_start_time; - - ltc_start_time = bbram_data_read(BBRM_DATA_INDEX_LCT_TIME); - if (ltc_start_time == 0) - return; - - rtc_time = system_get_rtc_sec(); - rtc_time += ltc_start_time - npcx_lct_get_time(); - system_set_rtc(rtc_time); - /* Clear BBRAM data to avoid compensating again. */ - bbram_data_write(BBRM_DATA_INDEX_LCT_TIME, 0); -} -#endif -#endif /* CONFIG_SUPPORT_CHIP_HIBERNATION */ - -static char system_to_hex(uint8_t val) -{ - uint8_t x = val & 0x0F; - - if (x <= 9) - return '0' + x; - return 'a' + x - 10; -} - -/*****************************************************************************/ -/* IC specific low-level driver */ - -/* - * Microseconds will be ignored. The WTC register only - * stores wakeup time in seconds. - * Set seconds = 0 to disable the alarm - */ -void system_set_rtc_alarm(uint32_t seconds, uint32_t microseconds) -{ - uint32_t cur_secs, alarm_secs; - - if (seconds == EC_RTC_ALARM_CLEAR && !microseconds) { - CLEAR_BIT(NPCX_WTC, NPCX_WTC_WIE); - SET_BIT(NPCX_WTC, NPCX_WTC_PTO); - - return; - } - - /* Get current clock */ - cur_secs = NPCX_TTC; - - /* If alarm clock is not sequential or not in range */ - alarm_secs = cur_secs + seconds; - alarm_secs = alarm_secs & MTC_ALARM_MASK; - - /* - * We should set new alarm (first 25 bits of clock value) first before - * clearing PTO in case issue rtc interrupt immediately. - */ - NPCX_WTC = alarm_secs; - - /* Reset alarm first */ - system_reset_rtc_alarm(); - - /* Enable interrupt mode alarm */ - SET_BIT(NPCX_WTC, NPCX_WTC_WIE); - - /* Enable MTC interrupt */ - task_enable_irq(NPCX_IRQ_MTC); - - /* Enable wake-up input sources & clear pending bit */ - NPCX_WKPCL(MIWU_TABLE_0, MTC_WUI_GROUP) |= MTC_WUI_MASK; - NPCX_WKINEN(MIWU_TABLE_0, MTC_WUI_GROUP) |= MTC_WUI_MASK; - NPCX_WKEN(MIWU_TABLE_0, MTC_WUI_GROUP) |= MTC_WUI_MASK; -} - -void system_reset_rtc_alarm(void) -{ - /* - * Clear interrupt & Disable alarm interrupt - * Update alarm value to zero - */ - CLEAR_BIT(NPCX_WTC, NPCX_WTC_WIE); - SET_BIT(NPCX_WTC, NPCX_WTC_PTO); - - /* Disable MTC interrupt */ - task_disable_irq(NPCX_IRQ_MTC); -} - -/* - * Return the seconds remaining before the RTC alarm goes off. - * Returns 0 if alarm is not set. - */ -uint32_t system_get_rtc_alarm(void) -{ - /* - * Return 0: - * 1. If alarm is not set to go off, OR - * 2. If alarm is set and has already gone off - */ - if (!IS_BIT_SET(NPCX_WTC, NPCX_WTC_WIE) || - IS_BIT_SET(NPCX_WTC, NPCX_WTC_PTO)) { - return 0; - } - /* Get seconds before alarm goes off */ - return (NPCX_WTC - NPCX_TTC) & MTC_ALARM_MASK; -} - -/** - * Enable hibernate interrupt - */ -void system_enable_hib_interrupt(void) -{ - task_enable_irq(NPCX_IRQ_MTC); -} - -void system_hibernate(uint32_t seconds, uint32_t microseconds) -{ - /* Flush console before hibernating */ - cflush(); - - if (board_hibernate) - board_hibernate(); - -#ifdef CONFIG_SUPPORT_CHIP_HIBERNATION - /* Add additional hibernate operations here */ - __enter_hibernate(seconds, microseconds); -#endif -} - -#ifndef CONFIG_ENABLE_JTAG_SELECTION -static void system_disable_host_sel_jtag(void) -{ - int data; - - /* Enable Core-to-Host Modules Access */ - SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSAE); - /* Clear SIOCFD.JEN0_HSL to disable JTAG0 */ - data = sib_read_reg(SIO_OFFSET, SIOCFD_REG_OFFSET); - data &= ~0x80; - sib_write_reg(SIO_OFFSET, SIOCFD_REG_OFFSET, data); - /* Disable Core-to-Host Modules Access */ - CLEAR_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSAE); -} -#endif - -void chip_pre_init(void) -{ - /* Setting for fixing JTAG issue */ - NPCX_DBGCTRL = 0x04; - /* Enable automatic freeze mode */ - CLEAR_BIT(NPCX_DBGFRZEN3, NPCX_DBGFRZEN3_GLBL_FRZ_DIS); - - /* - * Enable JTAG functionality by SW without pulling down strap-pin - * nJEN0 or nJEN1 during ec POWERON or VCCRST reset occurs. - * Please notice it will change pinmux to JTAG directly. - */ -#ifdef NPCX_ENABLE_JTAG -#if NPCX_JTAG_MODULE2 - CLEAR_BIT(NPCX_DEVALT(ALT_GROUP_5), NPCX_DEVALT5_NJEN1_EN); -#else - CLEAR_BIT(NPCX_DEVALT(ALT_GROUP_5), NPCX_DEVALT5_NJEN0_EN); -#endif -#endif - -#ifndef CONFIG_ENABLE_JTAG_SELECTION - /* - * (b/129908668) - * This is the workaround to disable the JTAG0 which is enabled - * accidentally by a special key combination. - */ -#if NPCX_FAMILY_VERSION < NPCX_FAMILY_NPCX9 - if (!IS_BIT_SET(NPCX_DEVALT(5), NPCX_DEVALT5_NJEN0_EN)) { - /* Set DEVALT5.nJEN0_EN to disable JTAG0 */ - SET_BIT(NPCX_DEVALT(5), NPCX_DEVALT5_NJEN0_EN); - system_disable_host_sel_jtag(); - } -#else - if (GET_FIELD(NPCX_JEN_CTL1, NPCX_JEN_CTL1_JEN_EN_FIELD) == - NPCX_JEN_CTL1_JEN_EN_ENA) { - SET_FIELD(NPCX_JEN_CTL1, NPCX_JEN_CTL1_JEN_EN_FIELD, - NPCX_JEN_CTL1_JEN_EN_DIS); - system_disable_host_sel_jtag(); - } -#endif -#endif -} - -void system_pre_init(void) -{ - uint8_t pwdwn6; - - /* - * Add additional initialization here - * EC should be initialized in Booter - */ - - /* Power-down the modules we don't need */ - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_1) = 0xF9; /* Skip SDP_PD FIU_PD */ - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_2) = 0xFF; -#if defined(CHIP_FAMILY_NPCX5) - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_3) = 0x0F; /* Skip GDMA */ -#elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_3) = 0x3F; /* Skip GDMA */ -#endif - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_4) = 0xF4; /* Skip ITIM2/1_PD */ - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_5) = 0xF8; - - pwdwn6 = 0x70 | -#if NPCX_FAMILY_VERSION <= NPCX_FAMILY_NPCX7 - /* - * Don't set PD of ITIM6 for NPCX9 and later chips because - * they use it as the system timer. - */ - BIT(NPCX_PWDWN_CTL6_ITIM6_PD) | -#endif - BIT(NPCX_PWDWN_CTL6_ITIM4_PD); /* Skip ITIM5_PD */ -#if !defined(CONFIG_HOSTCMD_ESPI) - pwdwn6 |= 1 << NPCX_PWDWN_CTL6_ESPI_PD; -#endif - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_6) = pwdwn6; - -#if defined(CHIP_FAMILY_NPCX7) -#if defined(CHIP_VARIANT_NPCX7M6FB) || defined(CHIP_VARIANT_NPCX7M6FC) || \ - defined(CHIP_VARIANT_NPCX7M7FC) || defined(CHIP_VARIANT_NPCX7M7WB) || \ - defined(CHIP_VARIANT_NPCX7M7WC) - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_7) = 0xE7; -#else - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_7) = 0x07; -#endif -#endif -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_7) = 0xFF; -#endif - - /* Following modules can be powered down automatically in npcx7 */ -#if defined(CHIP_FAMILY_NPCX5) - /* Power down the modules of npcx5 used internally */ - NPCX_INTERNAL_CTRL1 = 0x03; - NPCX_INTERNAL_CTRL2 = 0x03; - NPCX_INTERNAL_CTRL3 = 0x03; - - /* Enable low-power regulator */ - CLEAR_BIT(NPCX_LFCGCALCNT, NPCX_LFCGCALCNT_LPREG_CTL_EN); - SET_BIT(NPCX_LFCGCALCNT, NPCX_LFCGCALCNT_LPREG_CTL_EN); -#endif - - /* - * Configure LPRAM in the MPU as a regular memory - * and DATA RAM to prevent code execution - */ - system_mpu_config(); - - /* - * Change FMUL_WIN_DLY from 0x8A to 0x81 for better WoV - * audio quality. - */ -#ifdef CHIP_FAMILY_NPCX7 - NPCX_FMUL_WIN_DLY = 0x81; -#endif - -#ifdef CONFIG_CHIP_PANIC_BACKUP - chip_panic_data_restore(); -#endif - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - if (IS_ENABLED(CONFIG_HIBERNATE_PSL)) { - uint8_t opt_flag = CONFIG_HIBERNATE_PSL_OUT_FLAGS; - - /* PSL Glitch Protection */ - SET_BIT(NPCX_GLUE_PSL_MCTL2, NPCX_GLUE_PSL_MCTL2_PSL_GP_EN); - - /* - * TODO: Remove this when NPCX9 A2 chip is available because A2 - * chip will enable VCC1_RST to PSL wakeup source and lock it in - * the booter. - */ - if (IS_ENABLED(CONFIG_HIBERNATE_PSL_VCC1_RST_WAKEUP)) { - /* - * Enable VCC1_RST as the wake-up source from - * hibernation. - */ - SET_BIT(NPCX_GLUE_PSL_MCTL1, - NPCX_GLUE_PSL_MCTL1_VCC1_RST_PSL); - /* Disable VCC_RST Pull-Up */ - SET_BIT(NPCX_DEVALT(ALT_GROUP_G), - NPCX_DEVALTG_VCC1_RST_PUD); - /* - * Lock this bit itself and VCC1_RST_PSL in the - * PSL_MCTL1 register to read-only. - */ - SET_BIT(NPCX_GLUE_PSL_MCTL2, - NPCX_GLUE_PSL_MCTL2_VCC1_RST_PSL_LK); - } - - /* Don't set PSL_OUT to open-drain if it is the level mode */ - ASSERT((opt_flag & NPCX_PSL_CFG_PSL_OUT_PULSE) || - !(opt_flag & NPCX_PSL_CFG_PSL_OUT_OD)); - - if (opt_flag & NPCX_PSL_CFG_PSL_OUT_OD) - SET_BIT(NPCX_GLUE_PSL_MCTL1, NPCX_GLUE_PSL_MCTL1_OD_EN); - else - CLEAR_BIT(NPCX_GLUE_PSL_MCTL1, - NPCX_GLUE_PSL_MCTL1_OD_EN); - - if (opt_flag & NPCX_PSL_CFG_PSL_OUT_PULSE) - SET_BIT(NPCX_GLUE_PSL_MCTL1, - NPCX_GLUE_PSL_MCTL1_PLS_EN); - else - CLEAR_BIT(NPCX_GLUE_PSL_MCTL1, - NPCX_GLUE_PSL_MCTL1_PLS_EN); - } -#endif -} - -void system_reset(int flags) -{ - uint32_t save_flags; - - /* Disable interrupts to avoid task swaps during reboot */ - interrupt_disable(); - - /* Get flags to be saved in BBRAM */ - system_encode_save_flags(flags, &save_flags); - - /* 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); - } - } - - /* Ask the watchdog to trigger a hard reboot */ - system_watchdog_reset(); - - /* Spin and wait for reboot; should never return */ - while (1) - ; -} - -/** - * Return the chip vendor/name/revision string. - */ -const char *system_get_chip_vendor(void) -{ - static char str[15] = "Unknown-"; - char *p = str + 8; - - /* Read Vendor ID in core register */ - uint8_t fam_id = NPCX_SID_CR; - switch (fam_id) { - case 0x20: - return "Nuvoton"; - default: - *p = system_to_hex(fam_id >> 4); - *(p + 1) = system_to_hex(fam_id); - *(p + 2) = '\0'; - return str; - } -} - -const char *system_get_chip_name(void) -{ - static char str[15] = "Unknown-"; - char *p = str + 8; - - /* Read Chip ID in core register */ - uint8_t chip_id = NPCX_DEVICE_ID_CR; - - switch (chip_id) { -#if defined(CHIP_FAMILY_NPCX5) - case NPCX585G_CHIP_ID: - return "NPCX585G"; - case NPCX575G_CHIP_ID: - return "NPCX575G"; - case NPCX586G_CHIP_ID: - return "NPCX586G"; - case NPCX576G_CHIP_ID: - return "NPCX576G"; -#elif defined(CHIP_FAMILY_NPCX7) - case NPCX787G_CHIP_ID: - return "NPCX787G"; - case NPCX797F_C_CHIP_ID: - return "NPCX797F"; - case NPCX796F_A_B_CHIP_ID: - case NPCX796F_C_CHIP_ID: - return "NPCX796F"; - case NPCX797W_B_CHIP_ID: - case NPCX797W_C_CHIP_ID: - return "NPCX797W"; -#elif defined(CHIP_FAMILY_NPCX9) - case NPCX996F_CHIP_ID: - return "NPCX996F"; - case NPCX993F_CHIP_ID: - return "NPCX993F"; -#endif - default: - *p = system_to_hex(chip_id >> 4); - *(p + 1) = system_to_hex(chip_id); - *(p + 2) = '\0'; - return str; - } -} - -const char *system_get_chip_revision(void) -{ - static char rev[CHIP_REV_STR_SIZE]; - char *p = rev; - /* Read chip generation from SRID_CR */ - uint8_t chip_gen = NPCX_SRID_CR; - /* Read ROM data for chip revision directly */ -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - uint32_t rev_num = *((uint32_t *)CHIP_REV_ADDR); -#else - uint8_t rev_num = *((uint8_t *)CHIP_REV_ADDR); -#endif - -#ifdef CHIP_FAMILY_NPCX7 - uint8_t chip_id = NPCX_DEVICE_ID_CR; -#endif - int s; - - switch (chip_gen) { -#if defined(CHIP_FAMILY_NPCX5) - case 0x05: - *p++ = 'A'; - break; -#elif defined(CHIP_FAMILY_NPCX7) - case 0x06: - *p++ = 'A'; - break; - case 0x07: - if (chip_id == NPCX796F_A_B_CHIP_ID || - chip_id == NPCX797W_B_CHIP_ID) - *p++ = 'B'; - else - *p++ = 'C'; - break; -#elif defined(CHIP_FAMILY_NPCX9) - case 0x09: - *p++ = 'A'; - break; -#endif - default: - *p++ = system_to_hex(chip_gen >> 4); - *p++ = system_to_hex(chip_gen); - break; - } - - *p++ = '.'; - /* - * For npcx5/npcx7, the revision number is 1 byte. - * For NPCX9 and later chips, the revision number is 4 bytes. - */ - for (s = sizeof(rev_num) - 1; s >= 0; s--) { - uint8_t r = rev_num >> (s * 8); - - *p++ = system_to_hex(r >> 4); - *p++ = system_to_hex(r); - } - *p++ = '\0'; - - return rev; -} - -/** - * Set a scratchpad register to the specified value. - * - * The scratchpad register must maintain its contents across a - * software-requested warm reset. - * - * @param value Value to store. - * @return EC_SUCCESS, or non-zero if error. - */ -int system_set_scratchpad(uint32_t value) -{ - return bbram_data_write(BBRM_DATA_INDEX_SCRATCHPAD, value); -} - -int system_get_scratchpad(uint32_t *value) -{ - *value = bbram_data_read(BBRM_DATA_INDEX_SCRATCHPAD); - return EC_SUCCESS; -} - -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; -} - -#if defined(CONFIG_HIBERNATE_PSL) && defined(NPCX_LCT_SUPPORT) -static void system_init_check_rtc_wakeup_event(void) -{ - /* - * If platform uses PSL (Power Switch Logic) for hibernating and RTC is - * also supported, determine whether ec is woken up by RTC with overflow - * event (16 weeks). If so, let it go to hibernate mode immediately. - */ - if (is_rtc_overflow_event){ - CPRINTS("Hibernate due to RTC overflow event"); - system_hibernate(0, 0); - } -} -DECLARE_HOOK(HOOK_INIT, system_init_check_rtc_wakeup_event, - HOOK_PRIO_DEFAULT - 1); -#endif - -/*****************************************************************************/ -/* Console commands */ -void print_system_rtc(enum console_channel ch) -{ - uint32_t sec = system_get_rtc_sec(); - - cprintf(ch, "RTC: 0x%08x (%d.00 s)\n", sec, sec); -} - -#ifdef CONFIG_CMD_RTC -static int command_system_rtc(int argc, char **argv) -{ - if (argc == 3 && !strcasecmp(argv[1], "set")) { - char *e; - uint32_t t = strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - - system_set_rtc(t); - } else if (argc > 1) { - return EC_ERROR_INVAL; - } - - print_system_rtc(CC_COMMAND); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(rtc, command_system_rtc, - "[set <seconds>]", - "Get/set real-time clock"); - -#ifdef CONFIG_CMD_RTC_ALARM -/** - * Test the RTC alarm by setting an interrupt on RTC match. - */ -static int command_rtc_alarm_test(int argc, char **argv) -{ - int s = 1, us = 0; - char *e; - - ccprintf("Setting RTC alarm\n"); - system_enable_hib_interrupt(); - - if (argc > 1) { - s = strtoi(argv[1], &e, 10); - if (*e) - return EC_ERROR_PARAM1; - - } - if (argc > 2) { - us = strtoi(argv[2], &e, 10); - if (*e) - return EC_ERROR_PARAM2; - - } - - system_set_rtc_alarm(s, us); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(rtc_alarm, command_rtc_alarm_test, - "[seconds [microseconds]]", - "Test alarm"); -#endif /* CONFIG_CMD_RTC_ALARM */ -#endif /* CONFIG_CMD_RTC */ - -/*****************************************************************************/ -/* Host commands */ - -#ifdef CONFIG_HOSTCMD_RTC -static enum ec_status system_rtc_get_value(struct host_cmd_handler_args *args) -{ - struct ec_response_rtc *r = args->response; - - r->time = system_get_rtc_sec(); - args->response_size = sizeof(*r); - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_RTC_GET_VALUE, - system_rtc_get_value, - EC_VER_MASK(0)); - -static enum ec_status system_rtc_set_value(struct host_cmd_handler_args *args) -{ - const struct ec_params_rtc *p = args->params; - - system_set_rtc(p->time); - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_RTC_SET_VALUE, - system_rtc_set_value, - EC_VER_MASK(0)); - -static enum ec_status system_rtc_set_alarm(struct host_cmd_handler_args *args) -{ - const struct ec_params_rtc *p = args->params; - - system_set_rtc_alarm(p->time, 0); - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_RTC_SET_ALARM, - system_rtc_set_alarm, - EC_VER_MASK(0)); - -static enum ec_status system_rtc_get_alarm(struct host_cmd_handler_args *args) -{ - struct ec_response_rtc *r = args->response; - - r->time = system_get_rtc_alarm(); - args->response_size = sizeof(*r); - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_RTC_GET_ALARM, - system_rtc_get_alarm, - EC_VER_MASK(0)); - -#endif /* CONFIG_HOSTCMD_RTC */ -#ifdef CONFIG_EXTERNAL_STORAGE -void system_jump_to_booter(void) -{ - enum API_RETURN_STATUS_T status __attribute__((unused)); - static uint32_t flash_offset; - static uint32_t flash_used; - static uint32_t addr_entry; - - /* - * Get memory offset and size for RO/RW regions. - * Both of them need 16-bytes alignment since GDMA burst mode. - */ - switch (system_get_shrspi_image_copy()) { - 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; - break; -#endif - case EC_IMAGE_RO: - default: /* Jump to RO by default */ - flash_offset = CONFIG_EC_PROTECTED_STORAGE_OFF + - CONFIG_RO_STORAGE_OFF; - flash_used = CONFIG_RO_SIZE; - break; - } - - /* Make sure the reset vector is inside the destination image */ - addr_entry = *(uintptr_t *)(flash_offset + - CONFIG_MAPPED_STORAGE_BASE + 4); - - /* - * Speed up FW download time by increasing clock freq of EC. It will - * restore to default in clock_init() later. - */ - clock_turbo(); - -/* - * 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. - */ - /* Bypass for GMDA issue of ROM api utilities */ -#if defined(CHIP_FAMILY_NPCX5) || defined(CONFIG_WORKAROUND_FLASH_DOWNLOAD_API) - system_download_from_flash( - flash_offset, /* The offset of the data in spi flash */ - CONFIG_PROGRAM_MEMORY_BASE, /* RAM Addr of downloaded data */ - flash_used, /* Number of bytes to download */ - addr_entry /* jump to this address after download */ - ); -#else - download_from_flash( - flash_offset, /* The offset of the data in spi flash */ - CONFIG_PROGRAM_MEMORY_BASE, /* RAM Addr of downloaded data */ - flash_used, /* Number of bytes to download */ - SIGN_NO_CHECK, /* Need CRC check or not */ - addr_entry, /* jump to this address after download */ - &status /* Status fo download */ - ); -#endif -} - -uint32_t system_get_lfw_address() -{ - /* - * In A3 version, we don't use little FW anymore - * We provide the alternative function in ROM - */ - uint32_t jump_addr = (uint32_t)system_jump_to_booter; - return jump_addr; -} - -/* - * Set and clear image copy flags in MDC register. - * - * NPCX_FWCTRL_RO_REGION: 1 - RO, 0 - RW - * NPCX_FWCTRL_FW_SLOT: 1 - SLOT_A, 0 - SLOT_B - */ -void system_set_image_copy(enum ec_image copy) -{ - switch (copy) { - case EC_IMAGE_RW: - CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION); - SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT); - break; -#ifdef CONFIG_RW_B - case EC_IMAGE_RW_B: - CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION); - CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT); - break; -#endif - default: - CPRINTS("Invalid copy (%d) is requested as a jump destination. " - "Change it to %d.", copy, EC_IMAGE_RO); - /* Fall through to EC_IMAGE_RO */ - case EC_IMAGE_RO: - SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION); - SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT); - break; - } -} - -enum ec_image system_get_shrspi_image_copy(void) -{ - if (IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION)) { - /* RO image */ -#ifdef CHIP_HAS_RO_B - if (!IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT)) - return EC_IMAGE_RO_B; -#endif - return EC_IMAGE_RO; - } else { -#ifdef CONFIG_RW_B - /* RW image */ - if (!IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT)) - /* Slot A */ - return EC_IMAGE_RW_B; -#endif - return EC_IMAGE_RW; - } -} - -#endif diff --git a/chip/npcx/system_chip.h b/chip/npcx/system_chip.h deleted file mode 100644 index e3cc2a8865..0000000000 --- a/chip/npcx/system_chip.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright 2014 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-specific SIB module for Chrome EC */ - -#ifndef __CROS_EC_SYSTEM_CHIP_H -#define __CROS_EC_SYSTEM_CHIP_H - -/* Flags for BBRM_DATA_INDEX_WAKE */ -#define HIBERNATE_WAKE_MTC BIT(0) /* MTC alarm */ -#define HIBERNATE_WAKE_PIN BIT(1) /* Wake pin */ -#define HIBERNATE_WAKE_LCT BIT(2) /* LCT alarm */ -/* - * Indicate that EC enters hibernation via PSL. When EC wakes up from - * hibernation and this flag is set, it will check the related status bit to - * know the actual wake up source. (From LCT or physical wakeup pins) - */ -#define HIBERNATE_WAKE_PSL BIT(3) - -/* Indices for battery-backed ram (BBRAM) data position */ -enum bbram_data_index { - BBRM_DATA_INDEX_SCRATCHPAD = 0, /* General-purpose scratchpad */ - BBRM_DATA_INDEX_SAVED_RESET_FLAGS = 4, /* Saved reset flags */ - BBRM_DATA_INDEX_WAKE = 8, /* Wake reasons for hibernate */ - BBRM_DATA_INDEX_PD0 = 12, /* USB-PD saved port0 state */ - BBRM_DATA_INDEX_PD1 = 13, /* USB-PD saved port1 state */ - BBRM_DATA_INDEX_TRY_SLOT = 14, /* Vboot EC try slot */ - BBRM_DATA_INDEX_PD2 = 15, /* USB-PD saved port2 state */ - /* Index 16-31 available for future use */ - BBRM_DATA_INDEX_RAMLOG = 32, /* RAM log for Booter */ - BBRM_DATA_INDEX_PANIC_FLAGS = 35, /* Flag to indicate validity of - * panic data starting at index - * 36. - */ - BBRM_DATA_INDEX_PANIC_BKUP = 36, /* Panic data (index 35-63)*/ - BBRM_DATA_INDEX_LCT_TIME = 64, /* The start time of LCT(4 bytes) - */ -}; - -enum psl_pin_t { - PSL_IN1, - PSL_IN2, - PSL_IN3, - PSL_IN4, - PSL_NONE, -}; - -/* Issue a watchdog reset */ -void system_watchdog_reset(void); - -/* Stops the watchdog timer and unlocks configuration. */ -void watchdog_stop_and_unlock(void); - -/* - * Configure the specific memory addresses in the the MPU - * (Memory Protection Unit) for Nuvoton different chip series. - */ -void system_mpu_config(void); - -/* Hibernate function for different Nuvoton chip series. */ -void __hibernate_npcx_series(void); - -/* Check and clear BBRAM status on power-on reset */ -void system_check_bbram_on_reset(void); - -/* The utilities and variables depend on npcx chip family */ -#if defined(CHIP_FAMILY_NPCX5) || defined(CONFIG_WORKAROUND_FLASH_DOWNLOAD_API) -/* 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); - -/* Begin address for hibernate utility; defined in linker script */ -extern unsigned int __flash_lpfw_start; - -/* End address for hibernate utility; defined in linker script */ -extern unsigned int __flash_lpfw_end; - -/* Begin address for little FW; defined in linker script */ -extern unsigned int __flash_lplfw_start; - -/* End address for little FW; defined in linker script */ -extern unsigned int __flash_lplfw_end; -#endif - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 -/* Configure PSL mode setting for the wake-up pins. */ -int system_config_psl_mode(enum gpio_signal signal); - -/* Configure PSL pins and enter PSL mode. */ -void system_enter_psl_mode(void); - -/* End address for hibernate utility; defined in linker script */ -extern unsigned int __after_init_end; - -#endif - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 -void system_set_psl_gpo(int level); -#endif - -#endif /* __CROS_EC_SYSTEM_CHIP_H */ diff --git a/chip/npcx/uart.c b/chip/npcx/uart.c deleted file mode 100644 index efe991ec0b..0000000000 --- a/chip/npcx/uart.c +++ /dev/null @@ -1,387 +0,0 @@ -/* Copyright 2014 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. - */ - -/* UART module for Chrome EC */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hwtimer.h" -#include "hwtimer_chip.h" -#include "lpc.h" -#include "registers.h" -#include "clock_chip.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "uart.h" -#include "uartn.h" -#include "util.h" - -#define CONSOLE_UART CONFIG_CONSOLE_UART - -#if CONSOLE_UART -#define CONSOLE_UART_IRQ NPCX_IRQ_UART2 -#else -#define CONSOLE_UART_IRQ NPCX_IRQ_UART -#endif - -static int init_done; - -#ifdef CONFIG_UART_PAD_SWITCH - -/* Current pad: 0 for default pad, 1 for alternate. */ -static volatile enum uart_pad pad; - -/* - * When switched to alternate pad, read/write data according to the parameters - * below. - */ -static uint8_t *altpad_rx_buf; -static volatile int altpad_rx_pos; -static int altpad_rx_len; -static uint8_t *altpad_tx_buf; -static volatile int altpad_tx_pos; -static int altpad_tx_len; - -/* - * Time we last received a byte on default UART, we do not allow use of - * alternate pad for block_alt_timeout_us after that, to make sure input - * characters are not lost (either interactively, or though servod/FAFT). - */ -static timestamp_t last_default_pad_rx_time; - -static const uint32_t block_alt_timeout_us = 500*MSEC; - -#else - -/* Default pad is always selected. */ -static const enum uart_pad pad = UART_DEFAULT_PAD; - -#endif /* CONFIG_UART_PAD_SWITCH */ - -#if defined(CHIP_FAMILY_NPCX5) -/* This routine switches the functionality from UART rx to GPIO */ -void npcx_uart2gpio(void) -{ - /* Switch both pads back to GPIO mode. */ - CLEAR_BIT(NPCX_DEVALT(0x0C), NPCX_DEVALTC_UART_SL2); - CLEAR_BIT(NPCX_DEVALT(0x0A), NPCX_DEVALTA_UART_SL1); -} -#endif /* CHIP_FAMILY_NPCX5 */ - -/* - * This routine switches the functionality from GPIO to UART rx, depending - * on the global variable "pad". It also deactivates the previous pad. - * - * Note that, when switching pad, we first configure the new pad, then switch - * off the old one, to avoid having no pad selected at a given time, see - * b/65526215#c26. - */ -void npcx_gpio2uart(void) -{ -#ifdef CONFIG_UART_PAD_SWITCH - if (pad == UART_ALTERNATE_PAD) { -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - SET_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SIN__SL); - SET_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SOUT_SL); - CLEAR_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SIN_SL); - CLEAR_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SOUT_SL); -#else - SET_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SL); - CLEAR_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SL); -#endif - return; - } -#endif - -#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9 - SET_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SIN_SL); - SET_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SOUT_SL); - CLEAR_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SIN_SL); - CLEAR_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SOUT_SL); -#else - SET_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SL); - CLEAR_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SL); -#endif - -#if !NPCX_UART_MODULE2 && (NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7) - /* - * UART module 1 belongs to KSO since wake-up functionality in npcx7 - * and later chips. - */ - CLEAR_BIT(NPCX_DEVALT(0x09), NPCX_DEVALT9_NO_KSO09_SL); -#endif -} - -int uart_init_done(void) -{ - return init_done; -} - -void uart_tx_start(void) -{ -#if defined(CHIP_FAMILY_NPCX5) - if (uart_is_enable_wakeup() && pad == UART_DEFAULT_PAD) { - /* disable MIWU */ - uart_enable_wakeup(0); - /* Set pin-mask for UART */ - npcx_gpio2uart(); - /* enable uart again from MIWU mode */ - task_enable_irq(NPCX_IRQ_UART); - } -#endif - - uartn_tx_start(CONSOLE_UART); -} - -void uart_tx_stop(void) -{ -#ifdef NPCX_UART_FIFO_SUPPORT - uartn_tx_stop(CONSOLE_UART, 0); -#else - uint8_t sleep_ena; - - sleep_ena = (pad == UART_DEFAULT_PAD) ? 1 : 0; - uartn_tx_stop(CONSOLE_UART, sleep_ena); -#endif -} - -void uart_tx_flush(void) -{ - uartn_tx_flush(CONSOLE_UART); -} - -int uart_tx_ready(void) -{ - return uartn_tx_ready(CONSOLE_UART); -} - -int uart_tx_in_progress(void) -{ - return uartn_tx_in_progress(CONSOLE_UART); -} - -int uart_rx_available(void) -{ - int rx_available = uartn_rx_available(CONSOLE_UART); - - if (rx_available && pad == UART_DEFAULT_PAD) { -#ifdef CONFIG_LOW_POWER_IDLE - /* - * Activity seen on UART RX pin while UART was disabled for deep - * sleep. The console won't see that character because the UART - * is disabled, so we need to inform the clock module of UART - * activity ourselves. - */ - clock_refresh_console_in_use(); -#endif -#ifdef CONFIG_UART_PAD_SWITCH - last_default_pad_rx_time = get_time(); -#endif - } - return rx_available; /* If RX FIFO is empty return '0'. */ -} - -void uart_write_char(char c) -{ - uartn_write_char(CONSOLE_UART, c); -} - -int uart_read_char(void) -{ - return uartn_read_char(CONSOLE_UART); -} - -/* Interrupt handler for Console UART */ -void uart_ec_interrupt(void) -{ -#ifdef CONFIG_UART_PAD_SWITCH - if (pad == UART_ALTERNATE_PAD) { - if (uartn_rx_available(NPCX_UART_PORT0)) { - uint8_t c = uartn_read_char(NPCX_UART_PORT0); - - if (altpad_rx_pos < altpad_rx_len) - altpad_rx_buf[altpad_rx_pos++] = c; - } - if (uartn_tx_ready(NPCX_UART_PORT0)) { - if (altpad_tx_pos < altpad_tx_len) - uartn_write_char(NPCX_UART_PORT0, - altpad_tx_buf[altpad_tx_pos++]); - else - uart_tx_stop(); - } - return; - } -#endif -#ifdef NPCX_UART_FIFO_SUPPORT - if (!uartn_tx_in_progress(CONSOLE_UART)) { - if (uart_buffer_empty()) { - uartn_enable_tx_complete_int(CONSOLE_UART, 0); - enable_sleep(SLEEP_MASK_UART); - } - } -#endif - - /* Default pad. */ - /* Read input FIFO until empty, then fill output FIFO */ - uart_process_input(); - uart_process_output(); -} -#ifdef NPCX_UART_FIFO_SUPPORT -DECLARE_IRQ(CONSOLE_UART_IRQ, uart_ec_interrupt, 4); -#else -DECLARE_IRQ(CONSOLE_UART_IRQ, uart_ec_interrupt, 1); -#endif - -#ifdef CONFIG_UART_PAD_SWITCH -/* - * Switch back to default UART pad, without flushing RX/TX buffers: If we are - * about to panic, we just want to switch immmediately, and we don't care if we - * output a bit of garbage. - */ -void uart_reset_default_pad_panic(void) -{ - pad = UART_DEFAULT_PAD; - - /* Configure new pad. */ - npcx_gpio2uart(); - - /* Wait for ~2 bytes, to help the receiver resync. */ - udelay(200); -} - -static void uart_set_pad(enum uart_pad newpad) -{ -#ifdef NPCX_UART_FIFO_SUPPORT - NPCX_UFTCTL(NPCX_UART_PORT0) &= ~0xE0; - NPCX_UFRCTL(NPCX_UART_PORT0) &= ~0xE0; -#else - NPCX_UICTRL(NPCX_UART_PORT0) = 0x00; -#endif - task_disable_irq(NPCX_IRQ_UART); - - /* Flush the last byte */ - uartn_tx_flush(NPCX_UART_PORT0); - uart_tx_stop(); - - /* - * Allow deep sleep when default pad is selected (sleep is inhibited - * during TX). Disallow deep sleep when alternate pad is selected. - */ - if (newpad == UART_DEFAULT_PAD) - enable_sleep(SLEEP_MASK_UART); - else - disable_sleep(SLEEP_MASK_UART); - - pad = newpad; - - /* Configure new pad. */ - npcx_gpio2uart(); - - /* Re-enable receive interrupt. */ - uartn_rx_int_en(NPCX_UART_PORT0); - - /* - * If pad is switched while a byte is being received, the last byte may - * be corrupted, let's wait for ~1 byte (9/115200 = 78 us + margin), - * then flush the FIFO. See b/65526215. - */ - udelay(100); - uartn_clear_rx_fifo(NPCX_UART_PORT0); - - task_enable_irq(NPCX_IRQ_UART); -} - -/* TODO(b:67026316): Remove this and replace with software flow control. */ -void uart_default_pad_rx_interrupt(enum gpio_signal signal) -{ - /* - * We received an interrupt on the primary pad, give up on the - * transaction and switch back. - */ - gpio_disable_interrupt(GPIO_UART_MAIN_RX); - -#ifdef CONFIG_LOW_POWER_IDLE - clock_refresh_console_in_use(); -#endif - last_default_pad_rx_time = get_time(); - - uart_set_pad(UART_DEFAULT_PAD); -} - -int uart_alt_pad_write_read(uint8_t *tx, int tx_len, uint8_t *rx, int rx_len, - int timeout_us) -{ - uint32_t start = __hw_clock_source_read(); - int ret = 0; - - if ((get_time().val - last_default_pad_rx_time.val) - < block_alt_timeout_us) - return -EC_ERROR_BUSY; - - cflush(); - - altpad_rx_buf = rx; - altpad_rx_pos = 0; - altpad_rx_len = rx_len; - altpad_tx_buf = tx; - altpad_tx_pos = 0; - altpad_tx_len = tx_len; - - /* - * Turn on additional pull-up during transaction: that prevents the line - * from going low in case the base gets disconnected during the - * transaction. See b/68954760. - */ - gpio_set_flags(GPIO_EC_COMM_PU, GPIO_OUTPUT | GPIO_HIGH); - - uart_set_pad(UART_ALTERNATE_PAD); - gpio_clear_pending_interrupt(GPIO_UART_MAIN_RX); - gpio_enable_interrupt(GPIO_UART_MAIN_RX); - uartn_tx_start(NPCX_UART_PORT0); - - do { - usleep(100); - - /* Pad switched during transaction. */ - if (pad != UART_ALTERNATE_PAD) { - ret = -EC_ERROR_BUSY; - goto out; - } - - if (altpad_rx_pos == altpad_rx_len && - altpad_tx_pos == altpad_tx_len) - break; - } while ((__hw_clock_source_read() - start) < timeout_us); - - gpio_disable_interrupt(GPIO_UART_MAIN_RX); - uart_set_pad(UART_DEFAULT_PAD); - - if (altpad_tx_pos == altpad_tx_len) - ret = altpad_rx_pos; - else - ret = -EC_ERROR_TIMEOUT; - -out: - gpio_set_flags(GPIO_EC_COMM_PU, GPIO_INPUT); - - altpad_rx_len = 0; - altpad_rx_pos = 0; - altpad_rx_buf = NULL; - altpad_tx_len = 0; - altpad_tx_pos = 0; - altpad_tx_buf = NULL; - - return ret; -} -#endif -void uart_init(void) -{ - - uartn_init(CONSOLE_UART); - init_done = 1; -} diff --git a/chip/npcx/uartn.c b/chip/npcx/uartn.c deleted file mode 100644 index 2269e11e7c..0000000000 --- a/chip/npcx/uartn.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright 2018 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. - */ - -/* UART module for Chrome EC */ - -#include <clock.h> -#include "common.h" -#include <gpio.h> -#include <gpio_chip.h> -#include "registers.h" -#include "system.h" -#include "task.h" -#include "util.h" - -#ifdef NPCX_UART_FIFO_SUPPORT -/* Enable UART Tx FIFO empty interrupt */ -#define NPCX_UART_TX_EMPTY_INT_EN(n) \ - (SET_BIT(NPCX_UFTCTL(n), NPCX_UFTCTL_TEMPTY_EN)) -/* True if UART Tx FIFO empty interrupt is enabled */ -#define NPCX_UART_TX_EMPTY_INT_IS_EN(n) \ - (IS_BIT_SET(NPCX_UFTCTL(n), NPCX_UFTCTL_TEMPTY_EN)) -/* Disable UART Tx FIFO empty interrupt */ -#define NPCX_UART_TX_EMPTY_INT_DIS(n) \ - (CLEAR_BIT(NPCX_UFTCTL(n), NPCX_UFTCTL_TEMPTY_EN)) -/* True if the Tx FIFO is not completely full */ -#define NPCX_UART_TX_IS_READY(n) \ - (!(GET_FIELD(NPCX_UFTSTS(n), NPCX_UFTSTS_TEMPTY_LVL) == 0)) - -/* Enable UART Tx "not" in transmission interrupt */ -#define NPCX_UART_TX_NXMIP_INT_EN(n) \ - (SET_BIT(NPCX_UFTCTL(n), NPCX_UFTCTL_NXMIPEN)) -/* Disable UART Tx "not" in transmission interrupt */ -#define NPCX_UART_TX_NXMIP_INT_DIS(n) \ - (CLEAR_BIT(NPCX_UFTCTL(n), NPCX_UFTCTL_NXMIPEN)) -/* - * True if Tx is in progress - * (i.e. FIFO is not empty or last byte in TSFT (Transmit Shift register) - * is not sent) - */ -#define NPCX_UART_TX_IN_XMIT(n) \ - (!IS_BIT_SET(NPCX_UFTSTS(n), NPCX_UFTSTS_NXMIP)) - -/* - * Enable to generate interrupt when there is at least one byte - * in the receive FIFO - */ -#define NPCX_UART_RX_INT_EN(n) \ - (SET_BIT(NPCX_UFRCTL(n), NPCX_UFRCTL_RNEMPTY_EN)) -/* True if at least one byte is in the receive FIFO */ -#define NPCX_UART_RX_IS_AVAILABLE(n) \ - (IS_BIT_SET(NPCX_UFRSTS(n), NPCX_UFRSTS_RFIFO_NEMPTY_STS)) -#else -/* Enable UART Tx buffer empty interrupt */ -#define NPCX_UART_TX_EMPTY_INT_EN(n) (NPCX_UICTRL(n) |= 0x20) -/* True if UART Tx buffer empty interrupt is enabled */ -#define NPCX_UART_TX_EMPTY_INT_IS_EN(n) (NPCX_UICTRL(n) & 0x20) -/* Disable UART Tx buffer empty interrupt */ -#define NPCX_UART_TX_EMPTY_INT_DIS(n) (NPCX_UICTRL(n) &= ~0x20) -/* True if 1-byte Tx buffer is empty */ -#define NPCX_UART_TX_IS_READY(n) (NPCX_UICTRL(n) & 0x01) -/* - * True if Tx is in progress - * (i.e. Tx buffer is not empty or last byte in TSFT (Transmit Shift register) - * is not sent) - */ -#define NPCX_UART_TX_IN_XMIT(n) (NPCX_USTAT(n) & 0x40) - /* Enable to generate interrupt when there is data in the receive buffer */ -#define NPCX_UART_RX_INT_EN(n) (NPCX_UICTRL(n) = 0x40) -/* True if there is data in the 1-byte Receive buffer */ -#define NPCX_UART_RX_IS_AVAILABLE(n) (NPCX_UICTRL(n) & 0x02) -#endif - -struct uart_configs { - uint32_t irq; - uint32_t clk_en_offset; - uint32_t clk_en_msk; -}; -static const struct uart_configs uart_cfg[] = { - {NPCX_IRQ_UART, CGC_OFFSET_UART, CGC_UART_MASK}, -#ifdef NPCX_SECOND_UART - {NPCX_IRQ_UART2, CGC_OFFSET_UART2, CGC_UART2_MASK}, -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(uart_cfg) == UART_MODULE_COUNT); - -#ifdef CONFIG_LOW_POWER_IDLE -static const struct npcx_wui uart_wui[] = { - WUI(1, NPCX_UART_WK_GROUP, NPCX_UART_WK_BIT), -#ifdef NPCX_SECOND_UART - WUI(0, NPCX_UART2_WK_GROUP, NPCX_UART2_WK_BIT), -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(uart_wui) == UART_MODULE_COUNT); - -void uartn_wui_en(uint8_t uart_num) -{ - struct npcx_wui wui; - - wui = uart_wui[uart_num]; - /* Clear pending bit before enable uart wake-up */ - SET_BIT(NPCX_WKPCL(wui.table, wui.group), wui.bit); - /* Enable UART1 wake-up and interrupt request */ - SET_BIT(NPCX_WKEN(wui.table, wui.group), wui.bit); -} -#endif - -void uartn_rx_int_en(uint8_t uart_num) -{ - NPCX_UART_RX_INT_EN(uart_num); -} - -void uartn_tx_start(uint8_t uart_num) -{ - /* If interrupt is already enabled, nothing to do */ - if (NPCX_UART_TX_EMPTY_INT_IS_EN(uart_num)) - return; - - /* Do not allow deep sleep while transmit in progress */ - disable_sleep(SLEEP_MASK_UART); - -#ifdef NPCX_UART_FIFO_SUPPORT - /* - * For FIFO mode, enable the NXMIP interrupt. This generates an - * interrupt when Tx (both FIFO and shift register) is empty - */ - NPCX_UART_TX_NXMIP_INT_EN(uart_num); -#else - /* - * Re-enable the transmit interrupt, then forcibly trigger the - * interrupt. This works around a hardware problem with the - * UART where the FIFO only triggers the interrupt when its - * threshold is _crossed_, not just met. - */ - NPCX_UART_TX_EMPTY_INT_EN(uart_num); -#endif - - task_trigger_irq(uart_cfg[uart_num].irq); -} - -#ifdef NPCX_UART_FIFO_SUPPORT -void uartn_enable_tx_complete_int(uint8_t uart_num, uint8_t enable) -{ - enable ? NPCX_UART_TX_NXMIP_INT_EN(uart_num) : - NPCX_UART_TX_NXMIP_INT_DIS(uart_num); -} -#endif - -void uartn_tx_stop(uint8_t uart_num, uint8_t sleep_ena) -{ - /* Disable TX interrupt */ - NPCX_UART_TX_EMPTY_INT_DIS(uart_num); - /* - * Re-allow deep sleep when transmiting on the default pad (deep sleep - * is always disabled when alternate pad is selected). - */ - if (sleep_ena == 1) - enable_sleep(SLEEP_MASK_UART); -} - -void uartn_tx_flush(uint8_t uart_num) -{ - /* Wait for transmit FIFO empty and last byte is sent */ - while (NPCX_UART_TX_IN_XMIT(uart_num)) - ; -} - -int uartn_tx_ready(uint8_t uart_num) -{ - return NPCX_UART_TX_IS_READY(uart_num); -} - -int uartn_tx_in_progress(uint8_t uart_num) -{ - return NPCX_UART_TX_IN_XMIT(uart_num); -} - -int uartn_rx_available(uint8_t uart_num) -{ - return NPCX_UART_RX_IS_AVAILABLE(uart_num); -} - -void uartn_write_char(uint8_t uart_num, char c) -{ - /* Wait for space in transmit FIFO. */ - while (!uartn_tx_ready(uart_num)) - ; - - NPCX_UTBUF(uart_num) = c; -} - -int uartn_read_char(uint8_t uart_num) -{ - return NPCX_URBUF(uart_num); -} - -void uartn_clear_rx_fifo(int channel) -{ - int scratch __attribute__ ((unused)); - - /* If '1', that means there is RX data on the FIFO register */ - while (NPCX_UART_RX_IS_AVAILABLE(channel)) - scratch = NPCX_URBUF(channel); -} - -#ifdef NPCX_UART_FIFO_SUPPORT -static void uartn_set_fifo_mode(uint8_t uart_num) -{ - /* Enable the UART FIFO mode */ - SET_BIT(NPCX_UMDSL(uart_num), NPCX_UMDSL_FIFO_MD); - /* Disable all Tx interrupts */ - NPCX_UFTCTL(uart_num) &= ~(BIT(NPCX_UFTCTL_TEMPTY_LVL_EN) | - BIT(NPCX_UFTCTL_TEMPTY_EN) | - BIT(NPCX_UFTCTL_NXMIPEN)); -} - -#endif - -static void uartn_config(uint8_t uart_num) -{ -#ifdef CONFIG_LOW_POWER_IDLE - struct npcx_wui wui; -#endif - - /* Configure pins from GPIOs to CR_UART */ - gpio_config_module(MODULE_UART, 1); - -#ifdef CONFIG_LOW_POWER_IDLE - /* - * Configure the UART wake-up event triggered from a falling edge - * on CR_SIN pin. - */ - wui = uart_wui[uart_num]; - SET_BIT(NPCX_WKEDG(wui.table, wui.group), wui.bit); -#endif - /* - * If apb2's clock is not 15MHz, we need to find the other optimized - * values of UPSR and UBAUD for baud rate 115200. - */ -#if (NPCX_APB_CLOCK(2) != 15000000) -#error "Unsupported apb2 clock for UART!" -#endif - - /* - * Fix baud rate to 115200. If this value is modified, please also - * modify the delay in uart_set_pad and uart_reset_default_pad_panic. - */ - NPCX_UPSR(uart_num) = 0x38; - NPCX_UBAUD(uart_num) = 0x01; - - /* - * 8-N-1, FIFO enabled. Must be done after setting - * the divisor for the new divisor to take effect. - */ - NPCX_UFRS(uart_num) = 0x00; -#ifdef NPCX_UART_FIFO_SUPPORT - uartn_set_fifo_mode(uart_num); -#endif - NPCX_UART_RX_INT_EN(uart_num); -} - -void uartn_init(uint8_t uart_num) -{ - uint32_t offset, mask; - - offset = uart_cfg[uart_num].clk_en_offset; - mask = uart_cfg[uart_num].clk_en_msk; - clock_enable_peripheral(offset, mask, CGC_MODE_ALL); - - if (uart_num == NPCX_UART_PORT0) - npcx_gpio2uart(); - - /* Configure UARTs (identically) */ - uartn_config(uart_num); - - /* - * Enable interrupts for UART0 only. Host UART will have to wait - * until the LPC bus is initialized. - */ - uartn_clear_rx_fifo(uart_num); - task_enable_irq(uart_cfg[uart_num].irq); -} diff --git a/chip/npcx/uartn.h b/chip/npcx/uartn.h deleted file mode 100644 index e5326f72b8..0000000000 --- a/chip/npcx/uartn.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2018 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_UARTN_H -#define __CROS_EC_UARTN_H - -#include "common.h" - -/* - * Initialize the UART module. - */ -void uartn_init(uint8_t uart_num); - -/* - * Re-enable the UART transmit interrupt. - * - * This also forces triggering a UART interrupt, if the transmit interrupt was - * disabled. - */ -void uartn_tx_start(uint8_t uart_num); - - /* Disable the UART transmit interrupt. */ -void uartn_tx_stop(uint8_t uart_num, uint8_t sleep_ena); - -/* Flush the transmit FIFO. */ -void uartn_tx_flush(uint8_t uart_num); - -/* Return non-zero if there is room to transmit a character immediately. */ -int uartn_tx_ready(uint8_t uart_num); - -/* Return non-zero if a transmit is in progress. */ -int uartn_tx_in_progress(uint8_t uart_num); - -/* Return non-zero if the UART has a character available to read. */ -int uartn_rx_available(uint8_t uart_num); - -/* - * Send a character to the UART data register. - * - * If the transmit FIFO is full, blocks until there is space. - * - * @param c Character to send. - */ -void uartn_write_char(uint8_t uart_num, char c); - -/* - * Read one char from the UART data register. - * - * @return The character read. - */ -int uartn_read_char(uint8_t uart_num); - -/* Clear all data in the UART Rx FIFO */ -void uartn_clear_rx_fifo(int channel); - -/* Enable the UART Rx interrupt */ -void uartn_rx_int_en(uint8_t uart_num); -/* Enable the UART Wake-up */ -void uartn_wui_en(uint8_t uart_num); -/* Enable/disable Tx NXMIP (No Transmit In Progress) interrupt */ -void uartn_enable_tx_complete_int(uint8_t uart_num, uint8_t enable); -#endif /* __CROS_EC_UARTN_H */ diff --git a/chip/npcx/watchdog.c b/chip/npcx/watchdog.c deleted file mode 100644 index 55b8df8c1c..0000000000 --- a/chip/npcx/watchdog.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright 2014 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. - */ - -/* Watchdog driver */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "registers.h" -#include "hwtimer_chip.h" -#include "gpio.h" -#include "hooks.h" -#include "timer.h" -#include "task.h" -#include "util.h" -#include "system_chip.h" -#include "watchdog.h" - -/* WDCNT value for watchdog period */ -#define WDCNT_VALUE \ - ((CONFIG_WATCHDOG_PERIOD_MS * INT_32K_CLOCK) / (1024 * 1000)) - -void watchdog_init_warning_timer(void) -{ - /* init watchdog timer first */ - init_hw_timer(ITIM_WDG_NO, ITIM_SOURCE_CLOCK_32K); - - /* - * prescaler to TIMER_TICK - * Ttick_unit = (PRE_8+1) * T32k - * PRE_8 = (Ttick_unit/T32K) - 1 - * Unit: 1 msec - */ - NPCX_ITPRE(ITIM_WDG_NO) = - DIV_ROUND_NEAREST(1000 * INT_32K_CLOCK, SECOND) - 1; - - /* Event module disable */ - CLEAR_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* ITIM count down : event expired */ - NPCX_ITCNT(ITIM_WDG_NO) = CONFIG_AUX_TIMER_PERIOD_MS; - /* Event module enable */ - SET_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* Enable interrupt of ITIM */ - task_enable_irq(ITIM_INT(ITIM_WDG_NO)); -} - -static timestamp_t last_watchdog_touch; -void watchdog_stop_and_unlock(void) -{ - /* - * Ensure we have waited at least 3 watchdog ticks since touching WD - * timer. 3 / (32768 / 1024) HZ = 93.75ms - */ - while (time_since32(last_watchdog_touch) < (100 * MSEC)) - continue; - - NPCX_WDSDM = 0x87; - NPCX_WDSDM = 0x61; - NPCX_WDSDM = 0x63; -} - -static void touch_watchdog_count(void) -{ - NPCX_WDSDM = 0x5C; - last_watchdog_touch = get_time(); -} - -static void watchdog_reload_warning_timer(void) -{ - /* Disable warning timer module */ - CLEAR_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* Wait for module disable to take effect before updating count */ - while (IS_BIT_SET(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN)) - ; - - /* Reload the warning timer count */ - NPCX_ITCNT(ITIM_WDG_NO) = CONFIG_AUX_TIMER_PERIOD_MS; - - /* enable warning timer module */ - SET_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN); - /* Wait for module enable */ - while (!IS_BIT_SET(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_ITEN)) - ; -} - -void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) -{ -#ifdef CONFIG_TASK_PROFILING - /* - * Perform IRQ profiling accounting. This is normally done by - * DECLARE_IRQ(), but we are not using that for ITIM_WDG_NO. - */ - task_start_irq_handler((void *)excep_lr); -#endif - - /* Clear timeout status for event */ - SET_BIT(NPCX_ITCTS(ITIM_WDG_NO), NPCX_ITCTS_TO_STS); - - /* Print panic info */ - watchdog_trace(excep_lr, excep_sp); -} - -/* ISR for watchdog warning naked will keep SP & LR */ -void IRQ_HANDLER(ITIM_INT(ITIM_WDG_NO))(void) __attribute__((naked)); -void IRQ_HANDLER(ITIM_INT(ITIM_WDG_NO))(void) -{ - /* Naked call so we can extract raw LR and SP */ - asm volatile("mov r0, lr\n" - "mov r1, sp\n" - /* Must push registers in pairs to keep 64-bit aligned - * stack for ARM EABI. This also conveninently saves - * R0=LR so we can pass it to task_resched_if_needed. */ - "push {r0, lr}\n" - "bl watchdog_check\n" - "pop {r0, lr}\n" - "b task_resched_if_needed\n"); -} -const struct irq_priority __keep IRQ_PRIORITY(ITIM_INT(ITIM_WDG_NO)) -__attribute__((section(".rodata.irqprio"))) -= {ITIM_INT(ITIM_WDG_NO), 0}; -/* put the watchdog at the highest priority */ - -void watchdog_reload(void) -{ - /* Disable watchdog interrupt */ - task_disable_irq(ITIM_INT(ITIM_WDG_NO)); - - watchdog_reload_warning_timer(); - -#if 1 /* mark this for testing watchdog */ - /* Touch watchdog & reset software counter */ - touch_watchdog_count(); -#endif - - /* Enable watchdog interrupt */ - task_enable_irq(ITIM_INT(ITIM_WDG_NO)); -} -DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); - -int watchdog_init(void) -{ -#if SUPPORT_WDG - /* Touch watchdog before init if it is already running */ - if (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_WD_RUN)) - touch_watchdog_count(); - - /* Keep prescaler ratio timer0 clock to 1:1024 */ - NPCX_TWCP = 0x0A; - /* Keep prescaler ratio watchdog clock to 1:1 */ - NPCX_WDCP = 0; - - /* Clear watchdog reset status initially*/ - SET_BIT(NPCX_T0CSR, NPCX_T0CSR_WDRST_STS); - - /* Reset TWCFG */ - NPCX_TWCFG = 0; - /* Watchdog touch by writing 5Ch to WDSDM */ - SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDSDME); - /* Select T0IN clock as watchdog prescaler clock */ - SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDCT0I); - /* Disable early touch functionality */ - SET_BIT(NPCX_T0CSR, NPCX_T0CSR_TESDIS); - - /* - * Set WDCNT initial reload value and T0OUT timeout period - * WDCNT = 0 will generate watchdog reset - */ - NPCX_WDCNT = WDCNT_VALUE; - - /* Disable interrupt */ - interrupt_disable(); - /* Reload TWDT0/WDCNT */ - SET_BIT(NPCX_T0CSR, NPCX_T0CSR_RST); - /* Wait for timer is loaded and restart */ - while (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_RST)) - ; - /* Enable interrupt */ - interrupt_enable(); - - /* Init watchdog warning timer */ - watchdog_init_warning_timer(); -#endif - return EC_SUCCESS; -} diff --git a/chip/npcx/wov.c b/chip/npcx/wov.c deleted file mode 100644 index c4f68f5369..0000000000 --- a/chip/npcx/wov.c +++ /dev/null @@ -1,2071 +0,0 @@ -/* Copyright 2018 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-specific WOV module for Chrome EC */ - -#include "apm_chip.h" -#include "clock.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "wov_chip.h" - -#ifndef NPCX_WOV_SUPPORT -#error "Do not enable CONFIG_AUDIO_CODEC_* if npcx ec doesn't support WOV !" -#endif - -/* Console output macros */ -#ifndef DEBUG_AUDIO_CODEC -#define CPUTS(...) -#define CPRINTS(...) -#else -#define CPUTS(outstr) cputs(CC_AUDIO_CODEC, outstr) -#define CPRINTS(format, args...) cprints(CC_AUDIO_CODEC, format, ## args) -#endif - -/* WOV FIFO status. */ -#define WOV_STATUS_OFFSET NPCX_WOV_STATUS_CFIFO_OIT -#define WOV_IS_CFIFO_INT_THRESHOLD(sts) \ - IS_BIT_SET(sts, (NPCX_WOV_STATUS_CFIFO_OIT - WOV_STATUS_OFFSET)) -#define WOV_IS_CFIFO_WAKE_THRESHOLD(sts) \ - IS_BIT_SET(sts, (NPCX_WOV_STATUS_CFIFO_OWT - WOV_STATUS_OFFSET)) -#define WOV_IS_CFIFO_OVERRUN(sts) \ - IS_BIT_SET(sts, (NPCX_WOV_STATUS_CFIFO_OVRN - WOV_STATUS_OFFSET)) -#define WOV_IS_I2S_FIFO_OVERRUN(sts) \ - IS_BIT_SET(sts, (NPCX_WOV_STATUS_I2S_FIFO_OVRN - WOV_STATUS_OFFSET)) -#define WOV_IS_I2S_FIFO_UNDERRUN(sts) \ - IS_BIT_SET(sts, (NPCX_WOV_STATUS_I2S_FIFO_UNDRN - WOV_STATUS_OFFSET)) - -/* Core FIFO threshold. */ -#define WOV_SET_FIFO_WAKE_THRESHOLD(n) \ - SET_FIELD(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_FIFO_WTHRSH, n) - -#define WOV_SET_FIFO_INT_THRESHOLD(n) \ - SET_FIELD(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_FIFO_ITHRSH, n) -#define WOV_GET_FIFO_INT_THRESHOLD \ - GET_FIELD(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_FIFO_ITHRSH) - -#define WOV_PLL_IS_NOT_LOCK \ - (!IS_BIT_SET(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_LOCKI)) - -/* mask definitions that clear reserved fields for WOV registers.*/ -#define WOV_CLK_CTRL_REG_RESERVED_MASK 0x037F7FFF - -#define WOV_GET_FIFO_WAKE_THRESHOLD \ - GET_FIELD(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_FIFO_WTHRSH) - -/* Wait time 4ms for FMUL2 enabled and for configuration tuning sequence. */ -#define WOV_FMUL2_CLK_TUNING_DELAY_TIME (4 * 1000) - -/* The size of RAM buffer to store the voice data */ -#define VOICE_BUF_SIZE 16000 - -/* PLL setting options. */ -struct wov_pll_set_options_val { - uint8_t pll_indv; /* Input Divider */ - uint16_t pll_fbdv; /* Feedback Divider */ - uint8_t pll_otdv1; /* Output devide 1. */ - uint8_t pll_otdv2; /* Output devide 2. */ - uint32_t pll_ext_div; /* Index for the table pll_ext_div */ -}; - -/* PLL External Divider Load Values. */ -struct wov_pll_ext_div_val { - uint8_t pll_ediv; /* Required PLL external divider */ - uint8_t pll_ediv_dc; /* Required PLL external divider DC */ -}; - -static const struct wov_pll_ext_div_val pll_ext_div[] = { - {0x2F, 0x78}, /* 12 */ - {0x57, 0x7C}, /* 13 */ - {0x2B, 0x7C}, /* 14 */ - {0x55, 0x7E}, /* 15 */ - {0x2A, 0x7E}, /* 16 */ - {0x15, 0x7F}, /* 17 */ - {0x4A, 0x7F}, /* 18 */ - {0x65, 0x3F}, /* 19 */ - {0x32, 0x3F}, /* 20 */ - {0x19, 0x5F}, /* 21 */ - {0x4C, 0x5F}, /* 22 */ - {0x66, 0x2F}, /* 23 */ - {0x73, 0x2F}, /* 24 */ - {0x39, 0x57}, /* 25 */ - {0x5C, 0x57}, /* 26 */ - {0x6E, 0x2B}, /* 27 */ - {0x77, 0x2B}, /* 28 */ - {0x3B, 0x55}, /* 29 */ - {0x5D, 0x55}, /* 30 */ - {0x2E, 0x2A}, /* 31 */ - {0x17, 0x2A}, /* 32 */ - {0x4B, 0x15}, /* 33 */ - {0x25, 0x15}, /* 34 */ - {0x52, 0x4A}, /* 35 */ - {0x69, 0x4A}, /* 36 */ - {0x34, 0x65}, /* 37 */ - {0x1A, 0x65}, /* 38 */ - {0x0D, 0x32}, /* 39 */ - {0x46, 0x32}, /* 40 */ - {0x63, 0x19}, /* 41 */ - {0x31, 0x19}, /* 42 */ - {0x58, 0x4C}, /* 43 */ - {0x6C, 0x4C}, /* 44 */ - {0x76, 0x66}, /* 45 */ - {0x7B, 0x66}, /* 46 */ - {0x3D, 0x73}, /* 47 */ - {0x5E, 0x73}, /* 48 */ - {0x6F, 0x39}, /* 49 */ - {0x37, 0x39}, /* 50 */ - {0x5B, 0x5C}, /* 51 */ - {0x2D, 0x5C}, /* 52 */ - {0x56, 0x6E}, /* 53 */ - {0x6B, 0x6E}, /* 54 */ - {0x35, 0x77}, /* 55 */ - {0x5A, 0x77}, /* 56 */ - {0x6D, 0x3B}, /* 57 */ - {0x36, 0x3B}, /* 58 */ - {0x1B, 0x5D}, /* 59 */ - {0x4D, 0x5D}, /* 60 */ - {0x26, 0x2E}, /* 61 */ - {0x13, 0x2E}, /* 62 */ - {0x49, 0x17}, /* 63 */ - {0x24, 0x17}, /* 64 */ - {0x12, 0x4B}, /* 65 */ - {0x09, 0x4B}, /* 66 */ - {0x44, 0x25} /* 67 */ -}; - -/* WOV interrupts */ -static const uint8_t wov_interupts[] = { - 0, /* VAD_INTEN */ - 1, /* VAD_WKEN */ - 8, /* CFIFO_NE_IE */ - 9, /* CFIFO_OIT_IE */ - 10, /* CFIFO_OWT_WE */ - 11, /* CFIFO_OVRN_IE */ - 12, /* I2S_FIFO_OVRN_IE */ - 13 /* I2S_FIFO_UNDRN_IE */ -}; - -struct wov_ppl_divider { - uint16_t pll_frame_len; /* PLL frame length. */ - uint16_t pll_fbdv; /* PLL feedback divider. */ - uint8_t pll_indv; /* PLL Input Divider. */ - uint8_t pll_otdv1; /* PLL Output Divider 1. */ - uint8_t pll_otdv2; /* PLL Output Divider 2. */ - uint8_t pll_ediv; /* PLL External Divide Factor. */ -}; - -struct wov_cfifo_buf { - uint32_t *buf; /* Pointer to a buffer. */ - int size; /* Buffer size in words. */ -}; - -struct wov_config wov_conf; - -static struct wov_cfifo_buf cfifo_buf; -static wov_call_back_t callback_fun; - -#define WOV_RATE_ERROR_THRESH_MSEC 10 -#define WOV_RATE_ERROR_THRESH 5 - -static int irq_underrun_count; -static int irq_overrun_count; -static uint32_t wov_i2s_underrun_tstamp; -static uint32_t wov_i2s_overrun_tstamp; - -#define WOV_CALLBACK(event) \ - { \ - if (callback_fun != NULL) \ - callback_fun(event); \ - } - -#define CONFIG_WOV_FIFO_THRESH_WORDS WOV_FIFO_THRESHOLD_80_DATA_WORDS - -/** - * Reads data from the core fifo. - * - * @param num_elements - Number of elements (Dword) to read. - * - * @return None - */ -void wov_cfifo_read_handler_l(uint32_t num_elements) -{ - uint32_t index; - - for (index = 0; index < num_elements; index++) - cfifo_buf.buf[index] = NPCX_WOV_FIFO_OUT; - - cfifo_buf.buf = &cfifo_buf.buf[index]; - cfifo_buf.size -= num_elements; -} - -static enum ec_error_list wov_calc_pll_div_s(int32_t d_in, - int32_t total_div, int32_t vco_freq, - struct wov_ppl_divider *pll_div) -{ - int32_t d_1, d_2, d_e; - - /* - * Please see comments in wov_calc_pll_div_l function below. - */ - for (d_e = 4; d_e < 75; d_e++) { - for (d_2 = 1; d_2 < 7; d_2++) { - for (d_1 = 1; d_1 < 7; d_1++) { - if ((vco_freq / (d_1 * d_2)) > 900) - continue; - - if (total_div == (d_in * d_e * d_1 * d_2)) { - pll_div->pll_indv = d_in; - pll_div->pll_otdv1 = d_1; - pll_div->pll_otdv2 = d_2; - pll_div->pll_ediv = d_e; - return EC_SUCCESS; - } - } - } - } - return EC_ERROR_INVAL; -} - -/** - * Gets the PLL divider value accordingly to the i2S clock frequency. - * - * @param i2s_clk_freq - i2S clock frequency - * @param sample_rate - Sample rate in KHz (16KHz or 48KHz) - * @param pll_div - PLL dividers. - * - * @return None - */ -static enum ec_error_list wov_calc_pll_div_l(uint32_t i2s_clk_freq, - uint32_t sample_rate, struct wov_ppl_divider *pll_div) -{ - int32_t d_f; - int32_t total_div; - int32_t d_in; - int32_t n; - int32_t vco_freq; - int32_t i2s_clk_freq_khz; - - n = i2s_clk_freq / sample_rate; - if (i2s_clk_freq != (sample_rate * n)) - return EC_ERROR_INVAL; - - if ((n < 32) || (n >= 257)) - return EC_ERROR_INVAL; - - pll_div->pll_frame_len = n; - - i2s_clk_freq_khz = i2s_clk_freq / 1000; - - /* - * The code below implemented the “PLL setting option” table as - * describe in the NPCX7m7wb specification document. - * - Total_div is VCO frequency in MHz / 12 MHz - * - d_f is the Feedback Divider - * - d_in is the Input Divider (PLL_INDV) - * - d_e is the PLL Ext Divider - * - d_2 is the Output Divide 2 (PLL_OTDV2) - * - d_1 is the Output Divide 1 (PLL_OTDV1) - * It is preferred that d_f will be as smaller as possible, after that - * the d_in will be as smaller as possible and so on, this is the - * reason that d_f (calculated from total_div) is in the external loop - * and d-1 is in the internal loop (as it may contain the bigger value). - * The “PLL setting option” code divided to 2 function in order to - * fulfil the coding style indentation rule. - */ - - /* total div is min_vco/12 400/12=33. */ - for (total_div = 33; total_div < 1500; total_div++) { - d_f = (total_div * 12000) / i2s_clk_freq_khz; - if ((total_div * 12000) == (d_f * i2s_clk_freq_khz)) { - for (d_in = 1; d_in < 10; d_in++) { - if (((i2s_clk_freq / 1000) / d_in) <= 500) - continue; - - vco_freq = total_div * 12 / d_in; - if ((vco_freq < 500) || (vco_freq > 1600)) - continue; - if (wov_calc_pll_div_s(d_in, total_div, - vco_freq, pll_div) == - EC_SUCCESS) { - pll_div->pll_fbdv = d_f; - return EC_SUCCESS; - } - - } - } - } - - return EC_ERROR_INVAL; -} - -/** - * Check if PLL is locked. - * - * @param None - * - * @return EC_SUCCESS if PLL is locked, EC_ERROR_UNKNOWN otherwise . - */ -enum ec_error_list wov_wait_for_pll_lock_l(void) -{ - volatile uint32_t index; - - for (index = 0; WOV_PLL_IS_NOT_LOCK; index++) { - /* PLL doesn't reach to lock state. */ - if (index > 0xFFFF) - return EC_ERROR_UNKNOWN; - } - - return EC_SUCCESS; -} - -/** - * Configure I2S bus. (Parameters determined via common config functions.) - * - * @param None. - * - * @return none. - */ -static enum ec_error_list wov_set_i2s_config_l(void) -{ - struct wov_ppl_divider pll_div; - enum ec_error_list ret_code; - enum wov_i2s_chan_trigger trigger_0, trigger_1; - int32_t start_delay_0, start_delay_1; - - ret_code = wov_calc_pll_div_l(wov_conf.i2s_clock, - wov_conf.sample_per_sec, &pll_div); - if (ret_code == EC_SUCCESS) { - /* Configure the PLL. */ - ret_code = wov_pll_clk_div_config( - pll_div.pll_otdv1, pll_div.pll_otdv2, pll_div.pll_fbdv, - pll_div.pll_indv); - if (ret_code != EC_SUCCESS) - return ret_code; - - ret_code = wov_pll_clk_ext_div_config( - (enum wov_pll_ext_div_sel)(pll_div.pll_ediv > 15), - pll_div.pll_ediv); - if (ret_code != EC_SUCCESS) - return ret_code; - - wov_i2s_global_config( - (enum wov_floating_mode)(wov_conf.dai_format == - WOV_DAI_FMT_PCM_TDM), - WOV_FLOATING_DRIVEN, WOV_CLK_NORMAL, 0, WOV_PULL_DOWN, - 0, WOV_PULL_DOWN, WOV_NORMAL_MODE); - - /* Configure DAI format. */ - switch (wov_conf.dai_format) { - case WOV_DAI_FMT_I2S: - trigger_0 = WOV_I2S_SAMPLED_0_AFTER_1; - trigger_1 = WOV_I2S_SAMPLED_1_AFTER_0; - start_delay_0 = 1; - start_delay_1 = 1; - break; - - case WOV_DAI_FMT_RIGHT_J: - trigger_0 = WOV_I2S_SAMPLED_1_AFTER_0; - trigger_1 = WOV_I2S_SAMPLED_0_AFTER_1; - start_delay_0 = (pll_div.pll_frame_len / 2) - - wov_conf.bit_depth; - start_delay_1 = (pll_div.pll_frame_len / 2) - - wov_conf.bit_depth; - break; - - case WOV_DAI_FMT_LEFT_J: - trigger_0 = WOV_I2S_SAMPLED_1_AFTER_0; - trigger_1 = WOV_I2S_SAMPLED_0_AFTER_1; - start_delay_0 = 0; - start_delay_1 = 0; - break; - - case WOV_DAI_FMT_PCM_A: - trigger_0 = WOV_I2S_SAMPLED_1_AFTER_0; - trigger_1 = WOV_I2S_SAMPLED_1_AFTER_0; - start_delay_0 = 1; - start_delay_1 = wov_conf.bit_depth + 1; - break; - - case WOV_DAI_FMT_PCM_B: - trigger_0 = WOV_I2S_SAMPLED_1_AFTER_0; - trigger_1 = WOV_I2S_SAMPLED_1_AFTER_0; - start_delay_0 = 0; - start_delay_1 = wov_conf.bit_depth; - break; - - case WOV_DAI_FMT_PCM_TDM: - trigger_0 = WOV_I2S_SAMPLED_1_AFTER_0; - trigger_1 = WOV_I2S_SAMPLED_1_AFTER_0; - start_delay_0 = wov_conf.i2s_start_delay_0; - start_delay_1 = wov_conf.i2s_start_delay_1; - break; - - default: - return EC_ERROR_INVALID_CONFIG; - } - - udelay(100); - - ret_code = wov_i2s_channel_config(0, wov_conf.bit_depth, - trigger_0, start_delay_0); - - ret_code = wov_i2s_channel_config(1, wov_conf.bit_depth, - trigger_1, start_delay_1); - } - - return EC_SUCCESS; -} - -/** - * wov_i2s_channel1_disable - * - * @param disable - disabled flag, 1 means disable - * - * @return None - */ -static void wov_i2s_channel1_disable(int disable) -{ - if (disable) - SET_BIT(NPCX_WOV_I2S_CNTL(1), NPCX_WOV_I2S_CNTL1_I2S_CHN1_DIS); - else - CLEAR_BIT(NPCX_WOV_I2S_CNTL(1), - NPCX_WOV_I2S_CNTL1_I2S_CHN1_DIS); -} - -/** - * Sets microphone source. - * - * | Left | Right | Mono | Stereo - *------------------|-----------|---------------|---------------|-------------- - *FIFO_CNT. |0x0 or 0x2 | 0x0 or 0x2 | 0x1 or 0x3 |0x1 or 0x3 - *CFIFI_ISEL | (left) |(left) |(left & Right) |(left & right) - *------------------|-----------|---------------|---------------|-------------- - *CR_DMIC. | 0x1 | 0x1 | 0x2 | 0x1 - *ADC_DMIC_SEL_LEFT | (left) | (left) | (average) | (left) - *------------------|-----------|---------------|---------------|-------------- - *CR_DMIC. | 0x1 | 0x1 | 0x2 | 0x1 - *ADC_DMIC_SEL_RIGHT| (right) | (right) | (average) | (right) - *------------------|-----------|---------------|---------------|-------------- - *MIX_2. | 0x0 | 0x1 | 0x0 | 0x0 - *AIADCL_SEL | (normal) |(cross inputs) | (normal) | (normal) - *------------------|-----------|---------------|---------------|-------------- - *MIX_2. | 0x3 | 0x3 | 0x0 | 0x0 - *AIADCR_SEL |(no input) | (no input) | (normal) | (normal) - *------------------|-----------|---------------|---------------|-------------- - *VAD_0. | 0x0 | 0x1 | 0x2 | Not - *VAD_INSEL | (left) | (right) | (average) | applicable - * - * @param None. - * @return return EC_SUCCESS if mic source valid othewise return error code. - */ -static enum ec_error_list wov_set_mic_source_l(void) -{ - switch (wov_conf.mic_src) { - case WOV_SRC_LEFT: - if (wov_conf.bit_depth == 16) - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x00); - else - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x02); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_LEFT, - 0x01); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_RIGHT, - 0x01); - apm_digital_mixer_config(APM_OUT_MIX_NORMAL_INPUT, - APM_OUT_MIX_NO_INPUT); - apm_set_vad_input_channel(APM_IN_LEFT); - wov_i2s_channel1_disable(1); - break; - - case WOV_SRC_RIGHT: - if (wov_conf.bit_depth == 16) - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x00); - else - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x02); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_LEFT, - 0x01); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_RIGHT, - 0x01); - apm_digital_mixer_config(APM_OUT_MIX_CROSS_INPUT, - APM_OUT_MIX_NO_INPUT); - apm_set_vad_input_channel(APM_IN_RIGHT); - wov_i2s_channel1_disable(1); - break; - - case WOV_SRC_MONO: - if (wov_conf.bit_depth == 16) - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x01); - else - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x03); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_LEFT, - 0x02); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_RIGHT, - 0x02); - apm_digital_mixer_config(APM_OUT_MIX_NORMAL_INPUT, - APM_OUT_MIX_NORMAL_INPUT); - apm_set_vad_input_channel(APM_IN_AVERAGE_LEFT_RIGHT); - wov_i2s_channel1_disable(0); - break; - - case WOV_SRC_STEREO: - if (wov_conf.bit_depth == 16) - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x01); - else - SET_FIELD(NPCX_WOV_FIFO_CNT, - NPCX_WOV_FIFO_CNT_CFIFO_ISEL, 0x03); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_LEFT, - 0x01); - SET_FIELD(NPCX_APM_CR_DMIC, NPCX_APM_CR_DMIC_ADC_DMIC_SEL_RIGHT, - 0x01); - apm_digital_mixer_config(APM_OUT_MIX_NORMAL_INPUT, - APM_OUT_MIX_NORMAL_INPUT); - wov_i2s_channel1_disable(0); - break; - - default: - return EC_ERROR_INVAL; - } - - return EC_SUCCESS; -} - -static void wov_over_under_deferred(void) -{ - CPRINTS("wov: Under/Over run error: under = %d, over = %d", - irq_underrun_count, irq_overrun_count); -} -DECLARE_DEFERRED(wov_over_under_deferred); - -static void wov_under_over_error_handler(int *count, uint32_t *last_time) -{ - uint32_t time_delta_msec; - uint32_t current_time = get_time().le.lo; - - if (!(*count)) { - *last_time = current_time; - (*count)++; - } else { - time_delta_msec = (current_time - *last_time) / MSEC; - *last_time = current_time; - if (time_delta_msec < WOV_RATE_ERROR_THRESH_MSEC) - (*count)++; - else - *count = 0; - - if (*count >= WOV_RATE_ERROR_THRESH) { - wov_stop_i2s_capture(); - hook_call_deferred(&wov_over_under_deferred_data, 0); - } - } -} - -/** - * WoV interrupt handler. - * - * @param None - * - * @return None - */ -void wov_interrupt_handler(void) -{ - uint32_t wov_status; - uint32_t wov_inten; - - wov_inten = GET_FIELD(NPCX_WOV_WOV_INTEN, NPCX_WOV_STATUS_BITS); - wov_status = wov_inten & - GET_FIELD(NPCX_WOV_STATUS, NPCX_WOV_STATUS_BITS); - - /* - * Voice activity detected. - */ - if (APM_IS_VOICE_ACTIVITY_DETECTED) { - apm_enable_vad_interrupt(0); - APM_CLEAR_VAD_INTERRUPT; - WOV_CALLBACK(WOV_EVENT_VAD); - } - - /* Core FIFO is overrun. Reset the Core FIFO and inform the FW */ - if (WOV_IS_CFIFO_OVERRUN(wov_status)) { - WOV_CALLBACK(WOV_EVENT_ERROR_CORE_FIFO_OVERRUN); - wov_core_fifo_reset(); - } else if (WOV_IS_CFIFO_INT_THRESHOLD(wov_status) && - (cfifo_buf.buf != NULL)) { - /* - * Core FIFO threshold or FIFO not empty event occurred. - * - Read data from core FIFO to the buffer. - * - In case data ready or no space for data, inform the FW. - */ - - /* Copy data from CFIFO to RAM. */ - wov_cfifo_read_handler_l((WOV_GET_CORE_FIFO_THRESHOLD * 2)); - - if (cfifo_buf.size < (WOV_GET_CORE_FIFO_THRESHOLD * 2)) { - cfifo_buf.buf = NULL; - cfifo_buf.size = 0; - WOV_CALLBACK(WOV_EVENT_DATA_READY); - } - } - - /* I2S FIFO is overrun. Reset the I2S FIFO and inform the FW. */ - if (WOV_IS_I2S_FIFO_OVERRUN(wov_status)) { - WOV_CALLBACK(WOV_EVENT_ERROR_I2S_FIFO_OVERRUN); - wov_under_over_error_handler(&irq_overrun_count, - &wov_i2s_overrun_tstamp); - wov_i2s_fifo_reset(); - } - - /* I2S FIFO is underrun. Reset the I2S FIFO and inform the FW. */ - if (WOV_IS_I2S_FIFO_UNDERRUN(wov_status)) { - WOV_CALLBACK(WOV_EVENT_ERROR_I2S_FIFO_UNDERRUN); - wov_under_over_error_handler(&irq_underrun_count, - &wov_i2s_underrun_tstamp); - wov_i2s_fifo_reset(); - } - - - /* Clear the WoV status register. */ - SET_FIELD(NPCX_WOV_STATUS, NPCX_WOV_STATUS_BITS, wov_status); -} - -DECLARE_IRQ(NPCX_IRQ_WOV, wov_interrupt_handler, 4); - -/** - * Enable FMUL2. - * - * @param enable - enabled flag, true for enable - * @return None - */ -static void wov_fmul2_enable(int enable) -{ - if (enable) { - - /* If clock disabled, then enable it. */ - if (IS_BIT_SET(NPCX_FMUL2_FM2CTRL, - NPCX_FMUL2_FM2CTRL_FMUL2_DIS)) { - /* Enable clock tuning. */ - CLEAR_BIT(NPCX_FMUL2_FM2CTRL, - NPCX_FMUL2_FM2CTRL_TUNE_DIS); - /* Enable clock. */ - CLEAR_BIT(NPCX_FMUL2_FM2CTRL, - NPCX_FMUL2_FM2CTRL_FMUL2_DIS); - - udelay(WOV_FMUL2_CLK_TUNING_DELAY_TIME); - - } - } else - SET_BIT(NPCX_FMUL2_FM2CTRL, NPCX_FMUL2_FM2CTRL_FMUL2_DIS); -} - -#define WOV_FMUL2_MAX_RETRIES 0x000FFFFF - -/* FMUL2 clock multipliers values. */ -struct wov_fmul2_multiplier_setting_val { - uint8_t fm2mh; - uint8_t fm2ml; - uint8_t fm2n; -}; - -/** - * Configure FMUL2 clock tunning. - * - * @param None - * @return None - */ -void wov_fmul2_conf_tuning(void) -{ - /* Check if FMUL2 is enabled, then do nothing. */ - if (IS_BIT_SET(NPCX_FMUL2_FM2CTRL, NPCX_FMUL2_FM2CTRL_FMUL2_DIS) == - 0x00) - return; - - /* Enable clock tuning. */ - CLEAR_BIT(NPCX_FMUL2_FM2CTRL, NPCX_FMUL2_FM2CTRL_TUNE_DIS); - - udelay(WOV_FMUL2_CLK_TUNING_DELAY_TIME); - - /* Disable clock tuning. */ - SET_BIT(NPCX_FMUL2_FM2CTRL, NPCX_FMUL2_FM2CTRL_TUNE_DIS); -} - -static int wov_get_cfifo_threshold_l(void) -{ - int fifo_threshold; - - fifo_threshold = WOV_GET_FIFO_INT_THRESHOLD; - - if (fifo_threshold == 0) - return 1; - else - return (fifo_threshold * 2); -} - -/** - * Gets clock source FMUL2 or PLL. - * - * @param None. - * - * NOTE: - * - * @return The clock source FMUL2 (WOV_FMUL2_CLK_SRC) and - * PLL (WOV_PLL_CLK_SRC) - */ -static enum wov_clk_src_sel wov_get_clk_selection(void) -{ - if (IS_BIT_SET(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_CLK_SEL)) - return WOV_PLL_CLK_SRC; - else - return WOV_FMUL2_CLK_SRC; -} - -/*************************************************************************** - * - * Exported function. - * - **************************************************************************/ - -/** - * Set FMUL2 clock divider. - * - * @param None - * @return None - */ -void wov_fmul2_set_clk_divider(enum fmul2_clk_divider clk_div) -{ - SET_FIELD(NPCX_FMUL2_FM2P, NPCX_FMUL2_FM2P_WFPRED, clk_div); -} - -/** - * Configure DMIC clock. - * - * @param enable - DMIC enabled , 1 means enable - * @param clk_div - DMIC clock division factor (disable, divide by 2 - * divide by 4) - * @return None - */ -void wov_dmic_clk_config(int enable, enum wov_dmic_clk_div_sel clk_div) -{ - /* If DMIC enabled then configured its clock.*/ - if (enable) { - if (clk_div != WOV_DMIC_DIV_DISABLE) { - SET_BIT(NPCX_WOV_CLOCK_CNTL, - NPCX_WOV_CLOCK_CNT_DMIC_CKDIV_EN); - if (clk_div == WOV_DMIC_DIV_BY_2) - CLEAR_BIT(NPCX_WOV_CLOCK_CNTL, - NPCX_WOV_CLOCK_CNT_DMIC_CKDIV_SEL); - else - SET_BIT(NPCX_WOV_CLOCK_CNTL, - NPCX_WOV_CLOCK_CNT_DMIC_CKDIV_SEL); - } else - CLEAR_BIT(NPCX_WOV_CLOCK_CNTL, - NPCX_WOV_CLOCK_CNT_DMIC_CKDIV_EN); - - SET_BIT(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_DMIC_EN); - } else - CLEAR_BIT(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_DMIC_EN); -} - -/** - * Sets WoV mode - * - * @param wov_mode - WoV mode - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_set_mode(enum wov_modes wov_mode) -{ - enum ec_error_list ret_code; - enum wov_clk_src_sel prev_clock; - - /* If mode is OFF, then power down and exit. */ - if (wov_mode == WOV_MODE_OFF) { - wov_stop_i2s_capture(); - wov_stop_ram_capture(); - wov_set_clk_selection(WOV_FMUL2_CLK_SRC); - wov_dmic_clk_config(0, WOV_DMIC_DIV_DISABLE); - wov_mute(1); - apm_set_mode(WOV_MODE_OFF); - wov_fmul2_enable(0); - wov_conf.mode = WOV_MODE_OFF; - return EC_SUCCESS; - } - - switch (wov_mode) { - case WOV_MODE_VAD: - if (apm_get_vad_dmic_rate() == APM_DMIC_RATE_0_75) - wov_dmic_clk_config(1, WOV_DMIC_DIV_BY_4); - else if (apm_get_vad_dmic_rate() == APM_DMIC_RATE_1_2) - wov_dmic_clk_config(1, WOV_DMIC_DIV_BY_2); - else - wov_dmic_clk_config(1, WOV_DMIC_DIV_DISABLE); - wov_stop_i2s_capture(); - wov_stop_ram_capture(); - wov_set_clk_selection(WOV_FMUL2_CLK_SRC); - apm_set_mode(wov_mode); - ret_code = wov_set_mic_source_l(); - if (ret_code != EC_SUCCESS) - return ret_code; - break; - case WOV_MODE_RAM: - if ((wov_conf.bit_depth != 16) && (wov_conf.bit_depth != 24)) - return EC_ERROR_INVAL; - - if (apm_get_adc_ram_dmic_rate() == APM_DMIC_RATE_0_75) - wov_dmic_clk_config(1, WOV_DMIC_DIV_BY_4); - else if (apm_get_adc_ram_dmic_rate() == APM_DMIC_RATE_1_2) - wov_dmic_clk_config(1, WOV_DMIC_DIV_BY_2); - else - wov_dmic_clk_config(1, WOV_DMIC_DIV_DISABLE); - wov_stop_i2s_capture(); - wov_set_clk_selection(WOV_FMUL2_CLK_SRC); - apm_set_mode(wov_mode); - ret_code = wov_set_mic_source_l(); - if (ret_code != EC_SUCCESS) - return ret_code; - wov_start_ram_capture(); - break; - case WOV_MODE_RAM_AND_I2S: - if ((wov_conf.bit_depth != 16) && (wov_conf.bit_depth != 24)) - return EC_ERROR_INVAL; - case WOV_MODE_I2S: - if (apm_get_adc_i2s_dmic_rate() == APM_DMIC_RATE_0_75) - wov_dmic_clk_config(1, WOV_DMIC_DIV_BY_4); - else if (apm_get_adc_i2s_dmic_rate() == APM_DMIC_RATE_1_2) - wov_dmic_clk_config(1, WOV_DMIC_DIV_BY_2); - else - wov_dmic_clk_config(1, WOV_DMIC_DIV_DISABLE); - prev_clock = wov_get_clk_selection(); - if (prev_clock != WOV_PLL_CLK_SRC) { - wov_set_i2s_config_l(); - wov_set_clk_selection(WOV_PLL_CLK_SRC); - } - apm_set_mode(wov_mode); - ret_code = wov_set_mic_source_l(); - if (ret_code != EC_SUCCESS) - return ret_code; - wov_start_i2s_capture(); - if (wov_mode == WOV_MODE_RAM_AND_I2S) - wov_start_ram_capture(); - else - wov_stop_ram_capture(); - break; - default: - wov_dmic_clk_config(0, WOV_DMIC_DIV_DISABLE); - wov_fmul2_enable(0); - wov_mute(1); - return EC_ERROR_INVAL; - } - - wov_mute(0); - - wov_conf.mode = wov_mode; - - return EC_SUCCESS; -} - -/** - * Gets WoV mode - * - * @param None - * @return WoV mode - */ -enum wov_modes wov_get_mode(void) -{ - return wov_conf.mode; -} - -/** - * Initiates WoV. - * - * @param callback - Pointer to callback function. - * - * @return None - */ -void wov_init(void) -{ - apm_init(); - - wov_apm_active(1); - wov_mute(1); - - wov_conf.mode = WOV_MODE_OFF; - wov_conf.sample_per_sec = 16000; - wov_conf.bit_depth = 16; - wov_conf.mic_src = WOV_SRC_LEFT; - wov_conf.left_chan_gain = 0; - wov_conf.right_chan_gain = 0; - wov_conf.i2s_start_delay_0 = 0; - wov_conf.i2s_start_delay_1 = 0; - wov_conf.i2s_clock = 0; - wov_conf.dai_format = WOV_DAI_FMT_I2S; - wov_conf.sensitivity_db = 5; - - /* Set DMIC clock signal output to use fast transitions. */ - SET_BIT(NPCX_DEVALT(0xE), NPCX_DEVALTE_DMCLK_FAST); - - callback_fun = wov_handle_event; - - wov_cfifo_config(WOV_CFIFO_IN_LEFT_CHAN_2_CONS_16_BITS, - WOV_FIFO_THRESHOLD_80_DATA_WORDS); - - apm_set_vad_dmic_rate(APM_DMIC_RATE_0_75); - apm_set_adc_ram_dmic_config(APM_DMIC_RATE_0_75); - apm_set_adc_i2s_dmic_config(APM_DMIC_RATE_3_0); -} - -/** - * Select clock source FMUL2 or PLL. - * - * @param clk_src - select between FMUL2 (WOV_FMUL2_CLK_SRC) and - * PLL (WOV_PLL_CLK_SRC) - * - * NOTE: THIS FUNCTION RESETS THE APM and RETURN ITS REGISSTERS TO THEIR - * DEFAULT VALUES !!!!!!! - * - * @return None - */ -void wov_set_clk_selection(enum wov_clk_src_sel clk_src) -{ - int is_apm_disable; - - /* - * Be sure that both clocks are active, as both of them need to - * be active when modify the CLK_SEL bit. - */ - if (IS_BIT_SET(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_PWDEN)) - wov_pll_enable(1); - - if (IS_BIT_SET(NPCX_FMUL2_FM2CTRL, NPCX_FMUL2_FM2CTRL_FMUL2_DIS)) - wov_fmul2_enable(1); - - is_apm_disable = IS_BIT_SET(NPCX_APM_CR_APM, NPCX_APM_CR_APM_PD); - - apm_enable(0); - - if (clk_src == WOV_FMUL2_CLK_SRC) - CLEAR_BIT(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_CLK_SEL); - else if (wov_wait_for_pll_lock_l() == EC_SUCCESS) - SET_BIT(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_CLK_SEL); - - udelay(100); - - if (!is_apm_disable) - apm_enable(1); - - /* Disable the unneeded clock. */ - if (clk_src == WOV_PLL_CLK_SRC) - wov_fmul2_enable(0); - else - wov_pll_enable(0); - -} - -/** - * Configure PLL clock. - * - * @param ext_div_sel - PLL external divider selector. - * @param div_factor - When ext_div_sel is WOV_PLL_EXT_DIV_BIN_CNT - * then it is the 4 LSBits of this field, - * otherwise this field is an index to - * PLL External Divider Load Values table. - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_pll_clk_ext_div_config( - enum wov_pll_ext_div_sel ext_div_sel, - uint32_t div_factor) -{ - /* Sets the clock division factor for the PLL external divider. - * The divide factor should be in the range of 2 to 67. - * When ext_div_sel is WOV_PLL_EXT_DIV_BIN_CNT, then the 4 least - * significant bits of div_factor are used to set the divide - * ratio. - * In this case the divide ration legal values are from 2 to 15 - * For WOV_PLL_EXT_DIV_LFSR, this parameter is used as index for - * pll_ext_div table. - */ - if (ext_div_sel == WOV_PLL_EXT_DIV_BIN_CNT) - CLEAR_BIT(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_PLL_EDIV_SEL); - else - SET_BIT(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_PLL_EDIV_SEL); - - if (ext_div_sel == WOV_PLL_EXT_DIV_BIN_CNT) { - if ((div_factor > 15) || (div_factor < 2)) - return EC_ERROR_INVAL; - - SET_FIELD(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_PLL_EDIV, - (div_factor)); - } else { - if ((div_factor > 67) || (div_factor < 12)) - return EC_ERROR_INVAL; - - SET_FIELD(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_PLL_EDIV, - pll_ext_div[div_factor - 12].pll_ediv); - - SET_FIELD(NPCX_WOV_CLOCK_CNTL, NPCX_WOV_CLOCK_CNT_PLL_EDIV_DC, - pll_ext_div[div_factor - 12].pll_ediv_dc); - } - - return EC_SUCCESS; -} - -/** - * PLL power down. - * - * @param enable - 1 enable the PLL or 0 PLL disable - * @return None - */ -void wov_pll_enable(int enable) -{ - if (enable) - CLEAR_BIT(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_PWDEN); - else - SET_BIT(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_PWDEN); - - udelay(100); -} - -/** - * Configures PLL clock dividers.. - * - * @param out_div_1 - PLL output divider #1, valid values 1-7 - * @param out_div_2 - PLL output divider #2, valid values 1-7 - * @param feedback_div - PLL feadback divider (Default is 375 decimal) - * @param in_div - PLL input divider - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_pll_clk_div_config(uint32_t out_div_1, - uint32_t out_div_2, - uint32_t feedback_div, - uint32_t in_div) -{ - /* Parameter check. */ - if ((out_div_1 < 1) || (out_div_1 > 7) || - (out_div_2 < 1) || (out_div_2 > 7)) - return EC_ERROR_INVAL; - - /* - * PLL configuration sequence: - * 1. Set PLL_PWDEN bit to 1. - * 2. Set PLL divider values. - * 3. Wait 1usec. - * 4. Clear PLL_PWDEN bit to 0 while not changing other PLL parameters. - */ - SET_BIT(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_PWDEN); - - SET_FIELD(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_OTDV1, out_div_1); - SET_FIELD(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_OTDV2, out_div_2); - - SET_FIELD(NPCX_WOV_PLL_CNTL2, NPCX_WOV_PLL_CNTL2_PLL_FBDV, - feedback_div); - - SET_FIELD(NPCX_WOV_PLL_CNTL2, NPCX_WOV_PLL_CNTL2_PLL_INDV, in_div); - - udelay(100); - - CLEAR_BIT(NPCX_WOV_PLL_CNTL1, NPCX_WOV_PLL_CNTL1_PLL_PWDEN); - - udelay(100); - - return EC_SUCCESS; -} - -/** - * Enables/Disables WoV interrupt. - * - * @param int_index - Interrupt ID. - * @param enable - enabled flag, 1 means enable - * - * @return None. - */ -void wov_interrupt_enable(enum wov_interrupt_index int_index, int enable) -{ - if (enable) - SET_BIT(NPCX_WOV_WOV_INTEN, wov_interupts[int_index]); - else - CLEAR_BIT(NPCX_WOV_WOV_INTEN, wov_interupts[int_index]); -} - -/** - * Sets core FIFO threshold. - * - * @param in_sel - Core FIFO input select - * @param threshold - Core FIFO threshold - * - * @return None - */ -void wov_cfifo_config(enum wov_core_fifo_in_sel in_sel, - enum wov_fifo_threshold threshold) -{ - /* Set core FIFO input selection. */ - SET_FIELD(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_CFIFO_ISEL, in_sel); - - /* Set wake & interrupt core FIFO threshold. */ - WOV_SET_FIFO_WAKE_THRESHOLD(threshold); - WOV_SET_FIFO_INT_THRESHOLD(threshold); -} - -/** - * Start the actual capturing of the Voice data to the RAM. - * Note that the pointer to the RAM buffer must be precisely - * set by calling wov_set_buffer(); - * - * @param None - * - * @return None - */ -void wov_start_ram_capture(void) -{ - /* Clear the CFIFO status bits in WoV status register. */ - SET_FIELD(NPCX_WOV_STATUS, NPCX_WOV_STATUS_BITS, 0x27); - - CLEAR_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_CORE_FFRST); - - wov_interrupt_enable(WOV_CFIFO_OVERRUN_INT_INDX, 1); - wov_interrupt_enable(WOV_CFIFO_THRESHOLD_INT_INDX, 1); - wov_interrupt_enable(WOV_CFIFO_THRESHOLD_WAKE_INDX, 1); -} - -/** - * Stop the capturing of the Voice data to the RAM. - * - * @param none - * - * @return None - */ -void wov_stop_ram_capture(void) -{ - SET_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_CORE_FFRST); - - wov_interrupt_enable(WOV_CFIFO_OVERRUN_INT_INDX, 0); - wov_interrupt_enable(WOV_CFIFO_THRESHOLD_INT_INDX, 0); - wov_interrupt_enable(WOV_CFIFO_THRESHOLD_WAKE_INDX, 0); - - udelay(100); -} - -/** - * Rests the Core FIFO. - * - * @param None - * - * @return None - */ -void wov_core_fifo_reset(void) -{ - SET_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_CORE_FFRST); - - udelay(1000); - - /* Clear the CFIFO status bits in WoV status register. */ - SET_FIELD(NPCX_WOV_STATUS, NPCX_WOV_STATUS_BITS, 0x27); - - CLEAR_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_CORE_FFRST); -} - -/** - * Rests the I2S FIFO. - * - * @param None - * - * @return None - */ -void wov_i2s_fifo_reset(void) -{ - int disable; - - disable = IS_BIT_SET(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_I2S_FFRST); - - SET_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_I2S_FFRST); - - udelay(1000); - - /* Clear the I2S status bits in WoV status register. */ - SET_FIELD(NPCX_WOV_STATUS, NPCX_WOV_STATUS_BITS, 0x18); - - if (!disable) - CLEAR_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_I2S_FFRST); -} - -/** - * Start the capturing of the Voice data via I2S. - * - * @param None - * - * @return None - */ -void wov_start_i2s_capture(void) -{ - /* Clear counters used to track for underrun/overrun errors */ - irq_underrun_count = 0; - irq_overrun_count = 0; - - /* Clear the I2S status bits in WoV status register. */ - SET_FIELD(NPCX_WOV_STATUS, NPCX_WOV_STATUS_BITS, 0x18); - - CLEAR_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_I2S_FFRST); - - wov_interrupt_enable(WOV_I2SFIFO_OVERRUN_INT_INDX, 1); - wov_interrupt_enable(WOV_I2SFIFO_UNDERRUN_INT_INDX, 1); -} - -/** - * Stop the capturing of the Voice data via I2S. - * - * @param none - * - * @return None - */ -void wov_stop_i2s_capture(void) -{ - SET_BIT(NPCX_WOV_FIFO_CNT, NPCX_WOV_FIFO_CNT_I2S_FFRST); - - wov_interrupt_enable(WOV_I2SFIFO_OVERRUN_INT_INDX, 0); - wov_interrupt_enable(WOV_I2SFIFO_UNDERRUN_INT_INDX, 0); - - udelay(100); -} - -/** - * Sets data buffer for reading from core FIFO - * - * @param buff - Pointer to the read buffer, buffer must be 32 bits - * aligned. - * @param size_in_words - Size must be a multiple of CONFIG_WOV_THRESHOLD_WORDS - * (defaulte = 80 words) - * - * @return None - * - * Note - When the data buffer will be full the FW will be notifyed - * about it, and the FW will need to recall to this function. - */ -int wov_set_buffer(uint32_t *buf, int size_in_words) -{ - int cfifo_threshold; - - cfifo_threshold = wov_get_cfifo_threshold_l(); - if (size_in_words != - ((size_in_words / cfifo_threshold) * cfifo_threshold)) - return EC_ERROR_INVAL; - - cfifo_buf.buf = buf; - cfifo_buf.size = size_in_words; - - return EC_SUCCESS; -} - -/** - * Resets the APM. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void wov_apm_active(int enable) -{ - /* For APM it is negativ logic. */ - if (enable) - CLEAR_BIT(NPCX_WOV_APM_CTRL, NPCX_WOV_APM_CTRL_APM_RST); - else - SET_BIT(NPCX_WOV_APM_CTRL, NPCX_WOV_APM_CTRL_APM_RST); -} - -/** - * I2S golobal configuration - * - * @param i2s_hiz_data - Defines when the I2S data output is floating. - * @param i2s_hiz - Defines if the I2S data output is always floating. - * @param clk_invert - Defines the I2S bit clock edge sensitivity - * @param out_pull_en - Enable a pull-up or a pull-down resistor on - * I2S output - * @param out_pull_mode - Select a pull-up or a pull-down resistor on - * I2S output - * @param in_pull_en - Enable a pull-up or a pull-down resistor on - * I2S input - * @param in_pull_mode - Select a pull-up or a pull-down resistor on - * I2S intput - * @param test_mode - Selects I2S test mode - * - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_i2s_global_config( - enum wov_floating_mode i2s_hiz_data, - enum wov_floating_mode i2s_hiz, - enum wov_clk_inverted_mode clk_invert, - int out_pull_en, - enum wov_pull_upd_down_sel out_pull_mode, - int in_pull_en, - enum wov_pull_upd_down_sel in_pull_mode, - enum wov_test_mode test_mode) -{ - /* Check the parameters correctness. */ - if ((i2s_hiz_data == WOV_FLOATING) && - ((GET_FIELD(NPCX_WOV_I2S_CNTL(0), - NPCX_WOV_I2S_CNTL_I2S_ST_DEL) == 0) || - (GET_FIELD(NPCX_WOV_I2S_CNTL(1), - NPCX_WOV_I2S_CNTL_I2S_ST_DEL) == 0))) - return EC_ERROR_INVAL; - - /* Set the parameters. */ - if (i2s_hiz_data == WOV_FLOATING_DRIVEN) - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_HIZD); - else - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_HIZD); - - if (i2s_hiz == WOV_FLOATING_DRIVEN) - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_HIZ); - else - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_HIZ); - - if (clk_invert == WOV_CLK_NORMAL) - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), - NPCX_WOV_I2S_CNTL0_I2S_SCLK_INV); - else - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_SCLK_INV); - - if (out_pull_en) - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_OPE); - else - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_OPE); - - if (out_pull_mode == WOV_PULL_DOWN) - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_OPS); - else - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_OPS); - - if (in_pull_en) - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_IPE); - else - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_IPE); - - if (in_pull_mode == WOV_PULL_DOWN) - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_IPS); - else - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_IPS); - - if (test_mode == WOV_NORMAL_MODE) - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_TST); - else - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL0_I2S_TST); - - /* I2S should be reset in order I2S interface to function correctly. */ - wov_i2s_fifo_reset(); - - return EC_SUCCESS; -} - -/** - * I2S channel configuration - * - * @param channel_num - I2S channel number, 0 or 1. - * @param bit_count - I2S channel bit count. - * @param trigger - Define the I2S chanel trigger 1->0 or 0->1 - * @param start_delay - Defines the delay from the trigger defined for - * the channel till the first bit (MSB) of the data. - * - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_i2s_channel_config(uint32_t channel_num, - uint32_t bit_count, - enum wov_i2s_chan_trigger trigger, - int32_t start_delay) -{ - /* Check the parameters correctnes. */ - if ((channel_num != 0) && (channel_num != 1)) - return EC_ERROR_INVAL; - - if ((start_delay < 0) || (start_delay > 496)) - return EC_ERROR_INVAL; - - if ((bit_count != 16) && (bit_count != 18) && (bit_count != 20) && - (bit_count != 24)) - return EC_ERROR_INVAL; - - /* Set the parameters. */ - SET_FIELD(NPCX_WOV_I2S_CNTL(channel_num), NPCX_WOV_I2S_CNTL_I2S_BCNT, - (bit_count - 1)); - - if (trigger == WOV_I2S_SAMPLED_1_AFTER_0) - CLEAR_BIT(NPCX_WOV_I2S_CNTL(channel_num), - NPCX_WOV_I2S_CNTL_I2S_TRIG); - else - SET_BIT(NPCX_WOV_I2S_CNTL(channel_num), - NPCX_WOV_I2S_CNTL_I2S_TRIG); - - SET_FIELD(NPCX_WOV_I2S_CNTL(channel_num), NPCX_WOV_I2S_CNTL_I2S_ST_DEL, - start_delay); - - /* I2S should be reset in order I2S interface to function correctly. */ - wov_i2s_fifo_reset(); - - return EC_SUCCESS; -} - -/** - * Sets sampling rate. - * - * @param samples_per_second - Valid sample rate. - * @return In case sample rate is valid return EC_SUCCESS othewise return - * error code. - */ -int wov_set_sample_rate(uint32_t samples_per_second) -{ - if (wov_conf.mode != WOV_MODE_OFF) - return EC_ERROR_INVALID_CONFIG; - - switch (samples_per_second) { - case 8000: - case 12000: - case 16000: - case 24000: - case 32000: - case 48000: - wov_conf.sample_per_sec = samples_per_second; - return EC_SUCCESS; - default: - return EC_ERROR_INVAL; - } -} - -/** - * Gets sampling rate. - * - * @param None - * @return the current sampling rate. - */ -uint32_t wov_get_sample_rate(void) -{ - return wov_conf.sample_per_sec; -} - -/** - * Sets sampling depth. - * - * @param bits_num - Valid sample depth in bits. - * @return In case sample depth is valid return EC_SUCCESS othewise return - * error code. - */ -int wov_set_sample_depth(int bits_num) -{ - if (wov_conf.mode != WOV_MODE_OFF) - return EC_ERROR_INVALID_CONFIG; - - if ((bits_num != 16) && (bits_num != 18) && - (bits_num != 20) && (bits_num != 24)) - return EC_ERROR_INVAL; - - wov_conf.bit_depth = bits_num; - - return EC_SUCCESS; -} - -/** - * Gets sampling depth. - * - * @param None. - * @return sample depth in bits. - */ -int wov_get_sample_depth(void) -{ - return wov_conf.bit_depth; -} - -/** - * Sets microphone source. - * - * @param mic_src - Valid microphone source - * @return return EC_SUCCESS if mic source valid othewise return error code. - */ -int wov_set_mic_source(enum wov_mic_source mic_src) -{ - wov_conf.mic_src = mic_src; - - return wov_set_mic_source_l(); -} - -/** - * Gets microphone source. - * - * @param None. - * @return sample depth in bits. - */ -enum wov_mic_source wov_get_mic_source(void) -{ - return wov_conf.mic_src; -} - -/** - * Mutes the WoV. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void wov_mute(int enable) -{ - if (enable) - SET_BIT(NPCX_APM_CR_ADC, NPCX_APM_CR_ADC_ADC_SOFT_MUTE); - else - CLEAR_BIT(NPCX_APM_CR_ADC, NPCX_APM_CR_ADC_ADC_SOFT_MUTE); -} - -/** - * Sets gain - * - * @param left_chan_gain - Left channel gain. - * @param right_chan_gain - Right channel gain - * @return None - */ -void wov_set_gain(int left_chan_gain, int right_chan_gain) -{ - wov_conf.left_chan_gain = left_chan_gain; - wov_conf.right_chan_gain = right_chan_gain; - - (void) apm_adc_gain_config(APM_ADC_CHAN_GAINS_INDEPENDENT, - left_chan_gain, right_chan_gain); -} - -/** - * Gets gain values - * - * @param left_chan_gain - address of left channel gain response. - * @param right_chan_gain - address of right channel gain response. - * @return None - */ -void wov_get_gain(int *left_chan_gain, int *right_chan_gain) -{ - *left_chan_gain = wov_conf.left_chan_gain; - *right_chan_gain = wov_conf.right_chan_gain; -} - -/** - * Enables/Disables ADC. - * - * @param enable - enabled flag, 1 means enable - * @return None - */ -void wov_enable_agc(int enable) -{ - apm_auto_gain_cntrl_enable(enable); -} - -/** - * Enables/Disables the automatic gain. - * - * @param stereo - Stereo enabled flag, 1 means enable. - * @param target - Target output level of the ADC. - * @param noise_gate_threshold - Noise Gate system select. 1 means enable. - * @param hold_time - Hold time before starting AGC adjustment to - * the TARGET value. - * @param attack_time - Attack time - gain ramp down. - * @param decay_time - Decay time - gain ramp up. - * @param max_applied_gain - Maximum Gain Value to apply to the ADC path. - * @param min_applied_gain - Minimum Gain Value to apply to the ADC path. - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_set_agc_config(int stereo, float target, - int noise_gate_threshold, uint8_t hold_time, - uint16_t attack_time, uint16_t decay_time, - float max_applied_gain, float min_applied_gain) -{ - int target_code; - int ngth_code; - int attack_time_code; - int decay_time_code; - int max_applied_gain_code; - int min_applied_gain_code; - enum ec_error_list ret_code; - struct apm_auto_gain_config gain_cfg; - - for (target_code = 0; target_code < 16; target_code++) { - if (((float)target_code * (-1.5)) == target) - break; - } - if (target_code == 16) - return EC_ERROR_INVAL; - - if (noise_gate_threshold == 0) - ngth_code = 0; - else { - for (ngth_code = 0; ngth_code <= 0x07; ngth_code++) { - if ((-68 + ngth_code * 6) == noise_gate_threshold) - break; - } - if (ngth_code * 6 > 42) - return EC_ERROR_INVAL; - } - - if (hold_time > 15) - return EC_ERROR_INVAL; - - for (attack_time_code = 0; attack_time_code <= 0x0F; - attack_time_code++) { - if (((attack_time_code + 1) * 32) == attack_time) - break; - } - if (attack_time_code > 0x0F) - return EC_ERROR_INVAL; - - for (decay_time_code = 0; decay_time_code <= 0x0F; decay_time_code++) { - if (((decay_time_code + 1) * 32) == decay_time) - break; - } - if (decay_time_code > 0x0F) - return EC_ERROR_INVAL; - - for (max_applied_gain_code = 0; max_applied_gain_code < 16; - max_applied_gain_code++) { - if ((max_applied_gain_code * 1.5) == max_applied_gain) - break; - } - if (max_applied_gain_code == 16) { - for (max_applied_gain_code = 18; max_applied_gain_code < 32; - max_applied_gain_code++) { - if (((max_applied_gain_code * 1.5) - 4) == - max_applied_gain) - break; - } - } - if (max_applied_gain_code >= 32) - return EC_ERROR_INVAL; - - for (min_applied_gain_code = 0; min_applied_gain_code < 16; - min_applied_gain_code++) { - if ((min_applied_gain_code * 1.5) == min_applied_gain) - break; - } - if (min_applied_gain_code == 16) { - for (min_applied_gain_code = 18; min_applied_gain_code < 32; - min_applied_gain_code++) { - if (((min_applied_gain_code * 1.5) - 4) == - min_applied_gain) - break; - } - } - if (min_applied_gain_code > 32) - return EC_ERROR_INVAL; - - gain_cfg.stereo_enable = stereo, - gain_cfg.agc_target = (enum apm_adc_target_out_level) target_code; - gain_cfg.nois_gate_en = (noise_gate_threshold != 0); - gain_cfg.nois_gate_thold = (enum apm_noise_gate_threshold) ngth_code; - gain_cfg.hold_time = (enum apm_agc_adj_hold_time) hold_time; - gain_cfg.attack_time = (enum apm_gain_ramp_time) attack_time_code; - gain_cfg.decay_time = (enum apm_gain_ramp_time) decay_time_code; - gain_cfg.gain_max = (enum apm_gain_values) max_applied_gain_code; - gain_cfg.gain_min = (enum apm_gain_values) min_applied_gain_code; - - ret_code = apm_adc_auto_gain_config(&gain_cfg); - - return ret_code; -} - -/** - * Sets VAD sensitivity. - * - * @param sensitivity_db - VAD sensitivity in db. - * @return None - */ -int wov_set_vad_sensitivity(int sensitivity_db) -{ - - if ((sensitivity_db < 0) || (sensitivity_db > 31)) - return EC_ERROR_INVAL; - - wov_conf.sensitivity_db = sensitivity_db; - - apm_set_vad_sensitivity(sensitivity_db); - - return EC_SUCCESS; -} - -/** - * Gets VAD sensitivity. - * - * @param None. - * @return VAD sensitivity in db - */ -int wov_get_vad_sensitivity(void) -{ - return wov_conf.sensitivity_db; -} - -/** - * Configure I2S bus format. (Sample rate and size are determined via common - * config functions.) - * - * @param format - one of the following: I2S mode, Right Justified mode, - * Left Justified mode, PCM A Audio, PCM B Audio and - * Time Division Multiplexing - * @return EC error code. - */ -void wov_set_i2s_fmt(enum wov_dai_format format) -{ - if (wov_conf.mode != WOV_MODE_OFF) - return; - - wov_conf.dai_format = format; -} - -/** - * Configure I2S bus clock. (Sample rate and size are determined via common - * config functions.) - * - * @param i2s_clock - I2S clock frequency in Hz (needed in order to - * configure the internal PLL for 12MHz) - * @return EC error code. - */ -void wov_set_i2s_bclk(uint32_t i2s_clock) -{ - if (wov_conf.mode != WOV_MODE_OFF) - return; - - wov_conf.i2s_clock = i2s_clock; -} - -/** - * Configure I2S bus. (Sample rate and size are determined via common - * config functions.) - * - * @param ch0_delay - 0 to 496. Defines the delay from the SYNC till the - * first bit (MSB) of channel 0 (left channel) - * @param ch1_delay - -1 to 496. Defines the delay from the SYNC till the - * first bit (MSB) of channel 1 (right channel). - * If channel 1 is not used set this field to -1. - * - * @param flags - WOV_TDM_ADJACENT_TO_CH0 = BIT(0). There is a - * channel adjacent to channel 0, so float SDAT when - * driving the last bit (LSB) of the channel during the - * second half of the clock cycle to avoid bus contention. - * - * WOV_TDM_ADJACENT_TO_CH1 = BIT(1). There is a channel - * adjacent to channel 1. - * - * @return EC error code. - */ -enum ec_error_list wov_set_i2s_tdm_config(int ch0_delay, int ch1_delay, - uint32_t flags) -{ - if (wov_conf.mode != WOV_MODE_OFF) - return EC_ERROR_INVALID_CONFIG; - - if ((ch0_delay < 0) || (ch0_delay > 496) || - (ch1_delay < -1) || (ch1_delay > 496)) - return EC_ERROR_INVAL; - - wov_conf.i2s_start_delay_0 = ch0_delay; - wov_conf.i2s_start_delay_1 = ch1_delay; - - SET_FIELD(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL_I2S_ST_DEL, - ch0_delay); - - if (ch1_delay == -1) - wov_i2s_channel1_disable(1); - else { - wov_i2s_channel1_disable(0); - SET_FIELD(NPCX_WOV_I2S_CNTL(1), NPCX_WOV_I2S_CNTL_I2S_ST_DEL, - ch1_delay); - } - - if (flags & 0x0001) - SET_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL_I2S_LBHIZ); - else - CLEAR_BIT(NPCX_WOV_I2S_CNTL(0), NPCX_WOV_I2S_CNTL_I2S_LBHIZ); - - if (flags & 0x0002) - SET_BIT(NPCX_WOV_I2S_CNTL(1), NPCX_WOV_I2S_CNTL_I2S_LBHIZ); - else - CLEAR_BIT(NPCX_WOV_I2S_CNTL(1), NPCX_WOV_I2S_CNTL_I2S_LBHIZ); - - /* I2S should be reset in order I2S interface to function correctly. */ - wov_i2s_fifo_reset(); - - return EC_SUCCESS; -} - -static void wov_system_init(void) -{ - /* Set WoV module to be operational. */ - clock_enable_peripheral(CGC_OFFSET_WOV, CGC_WOV_MASK, - CGC_MODE_RUN | CGC_MODE_SLEEP); - /* Configure pins from GPIOs to WOV */ - gpio_config_module(MODULE_WOV, 1); - wov_init(); - - task_enable_irq(NPCX_IRQ_WOV); - - CPRINTS("WoV init done"); -} -DECLARE_HOOK(HOOK_INIT, wov_system_init, HOOK_PRIO_DEFAULT); - -void wov_handle_event(enum wov_events event) -{ - if (event == WOV_EVENT_DATA_READY) { - CPRINTS("ram data ready and stop ram capture"); - /* just capture one times on RAM*/ - wov_stop_ram_capture(); - } - if (event == WOV_EVENT_VAD) - CPRINTS("got vad"); - if (event == WOV_EVENT_ERROR_CORE_FIFO_OVERRUN) - CPRINTS("error: cfifo overrun"); -} - -#ifdef DEBUG_AUDIO_CODEC -static uint32_t voice_buffer[VOICE_BUF_SIZE] = {0}; - -/* voice data 16Khz 2ch 16bit 1s */ -static int command_wov(int argc, char **argv) -{ - static int bit_clk; - static enum wov_dai_format i2s_fmt; - - if (argc == 2) { - if (strcasecmp(argv[1], "init") == 0) { - wov_system_init(); - return EC_SUCCESS; - } - if (strcasecmp(argv[1], "cfgget") == 0) { - CPRINTS("mode:%d", wov_get_mode()); - CPRINTS("sample rate:%d", wov_get_sample_rate()); - CPRINTS("sample bits:%d", wov_get_sample_depth()); - CPRINTS("mic source:%d", wov_get_mic_source()); - CPRINTS("vad sensitivity :%d", - wov_get_vad_sensitivity()); - return EC_SUCCESS; - } - /* Start to capature voice data and store in RAM buffer */ - if (strcasecmp(argv[1], "capram") == 0) { - if (wov_set_buffer((uint32_t *)voice_buffer, - sizeof(voice_buffer) / sizeof(uint32_t)) - == EC_SUCCESS) { - CPRINTS("Start RAM Catpure..."); - wov_start_ram_capture(); - return EC_SUCCESS; - } - CPRINTS("Init fail: voice buffer size"); - return EC_ERROR_INVAL; - } - } else if (argc == 3) { - if (strcasecmp(argv[1], "cfgsrc") == 0) { - if (strcasecmp(argv[2], "mono") == 0) - wov_set_mic_source(WOV_SRC_MONO); - else if (strcasecmp(argv[2], "stereo") == 0) - wov_set_mic_source(WOV_SRC_STEREO); - else if (strcasecmp(argv[2], "left") == 0) - wov_set_mic_source(WOV_SRC_LEFT); - else if (strcasecmp(argv[2], "right") == 0) - wov_set_mic_source(WOV_SRC_RIGHT); - else - return EC_ERROR_INVAL; - - wov_i2s_fifo_reset(); - return EC_SUCCESS; - } - if (strcasecmp(argv[1], "cfgbit") == 0) { - int bits; - - bits = atoi(argv[2]); - if ((bits == 16) || (bits == 18) || (bits == 20) || - (bits == 24)) { - return wov_set_sample_depth(bits); - } - } - if (strcasecmp(argv[1], "cfgsfs") == 0) { - int fs; - - fs = atoi(argv[2]); - return wov_set_sample_rate(fs); - } - if (strcasecmp(argv[1], "cfgbck") == 0) { - int fs; - - fs = wov_get_sample_rate(); - if (strcasecmp(argv[2], "32fs") == 0) - bit_clk = fs * 32; - else if (strcasecmp(argv[2], "48fs") == 0) - bit_clk = fs * 48; - else if (strcasecmp(argv[2], "64fs") == 0) - bit_clk = fs * 64; - else if (strcasecmp(argv[2], "128fs") == 0) - bit_clk = fs * 128; - else if (strcasecmp(argv[2], "256fs") == 0) - bit_clk = fs * 256; - else - return EC_ERROR_INVAL; - - wov_set_i2s_fmt(i2s_fmt); - wov_set_i2s_bclk(bit_clk); - return EC_SUCCESS; - } - if (strcasecmp(argv[1], "cfgfmt") == 0) { - if (strcasecmp(argv[2], "i2s") == 0) - i2s_fmt = WOV_DAI_FMT_I2S; - else if (strcasecmp(argv[2], "right") == 0) - i2s_fmt = WOV_DAI_FMT_RIGHT_J; - else if (strcasecmp(argv[2], "left") == 0) - i2s_fmt = WOV_DAI_FMT_LEFT_J; - else if (strcasecmp(argv[2], "pcma") == 0) - i2s_fmt = WOV_DAI_FMT_PCM_A; - else if (strcasecmp(argv[2], "pcmb") == 0) - i2s_fmt = WOV_DAI_FMT_PCM_B; - else if (strcasecmp(argv[2], "tdm") == 0) - i2s_fmt = WOV_DAI_FMT_PCM_TDM; - else - return EC_ERROR_INVAL; - - wov_set_i2s_fmt(i2s_fmt); - wov_set_i2s_bclk(bit_clk); - return EC_SUCCESS; - } - if (strcasecmp(argv[1], "cfgdckV") == 0) { - if (strcasecmp(argv[2], "1.0") == 0) - apm_set_vad_dmic_rate(APM_DMIC_RATE_1_0); - else if (strcasecmp(argv[2], "1.2") == 0) - apm_set_vad_dmic_rate(APM_DMIC_RATE_1_2); - else if (strcasecmp(argv[2], "2.4") == 0) - apm_set_vad_dmic_rate(APM_DMIC_RATE_2_4); - else if (strcasecmp(argv[2], "3.0") == 0) - apm_set_vad_dmic_rate(APM_DMIC_RATE_3_0); - else if (strcasecmp(argv[2], "0.75") == 0) - apm_set_vad_dmic_rate(APM_DMIC_RATE_0_75); - else - return EC_ERROR_INVAL; - return EC_SUCCESS; - } - if (strcasecmp(argv[1], "cfgdckR") == 0) { - if (strcasecmp(argv[2], "1.0") == 0) - apm_set_adc_ram_dmic_config(APM_DMIC_RATE_1_0); - else if (strcasecmp(argv[2], "1.2") == 0) - apm_set_adc_ram_dmic_config(APM_DMIC_RATE_1_2); - else if (strcasecmp(argv[2], "2.4") == 0) - apm_set_adc_ram_dmic_config(APM_DMIC_RATE_2_4); - else if (strcasecmp(argv[2], "3.0") == 0) - apm_set_adc_ram_dmic_config(APM_DMIC_RATE_3_0); - else if (strcasecmp(argv[2], "0.75") == 0) - apm_set_adc_ram_dmic_config(APM_DMIC_RATE_0_75); - else - return EC_ERROR_INVAL; - return EC_SUCCESS; - } - if (strcasecmp(argv[1], "cfgdckI") == 0) { - if (strcasecmp(argv[2], "1.0") == 0) - apm_set_adc_i2s_dmic_config(APM_DMIC_RATE_1_0); - else if (strcasecmp(argv[2], "1.2") == 0) - apm_set_adc_i2s_dmic_config(APM_DMIC_RATE_1_2); - else if (strcasecmp(argv[2], "2.4") == 0) - apm_set_adc_i2s_dmic_config(APM_DMIC_RATE_2_4); - else if (strcasecmp(argv[2], "3.0") == 0) - apm_set_adc_i2s_dmic_config(APM_DMIC_RATE_3_0); - else if (strcasecmp(argv[2], "0.75") == 0) - apm_set_adc_i2s_dmic_config(APM_DMIC_RATE_0_75); - else - return EC_ERROR_INVAL; - return EC_SUCCESS; - } - - if (strcasecmp(argv[1], "cfgmod") == 0) { - if (strcasecmp(argv[2], "off") == 0) { - wov_set_mode(WOV_MODE_OFF); - wov_stop_ram_capture(); - } else if (strcasecmp(argv[2], "vad") == 0) { - wov_set_mode(WOV_MODE_VAD); - } else if (strcasecmp(argv[2], "ram") == 0) { - if (wov_set_buffer((uint32_t *)voice_buffer, - sizeof(voice_buffer) / sizeof(uint32_t)) - == EC_SUCCESS) - wov_set_mode(WOV_MODE_RAM); - else - return EC_ERROR_INVAL; - } else if (strcasecmp(argv[2], "i2s") == 0) { - wov_set_mode(WOV_MODE_I2S); - } else if (strcasecmp(argv[2], "rami2s") == 0) { - if (wov_set_buffer((uint32_t *)voice_buffer, - sizeof(voice_buffer) / sizeof(uint32_t)) - == EC_SUCCESS) - wov_set_mode(WOV_MODE_RAM_AND_I2S); - else - return EC_ERROR_INVAL; - } else { - return EC_ERROR_INVAL; - } - wov_i2s_fifo_reset(); - return EC_SUCCESS; - } - if (strcasecmp(argv[1], "mute") == 0) { - if (strcasecmp(argv[2], "enable") == 0) { - wov_mute(1); - return EC_SUCCESS; - } - if (strcasecmp(argv[2], "disable") == 0) { - wov_mute(0); - return EC_SUCCESS; - } - } - if (strcasecmp(argv[1], "fmul2") == 0) { - if (strcasecmp(argv[2], "enable") == 0) { - CLEAR_BIT(NPCX_FMUL2_FM2CTRL, - NPCX_FMUL2_FM2CTRL_TUNE_DIS); - return EC_SUCCESS; - } - if (strcasecmp(argv[2], "disable") == 0) { - SET_BIT(NPCX_FMUL2_FM2CTRL, - NPCX_FMUL2_FM2CTRL_TUNE_DIS); - return EC_SUCCESS; - } - } - if (strcasecmp(argv[1], "vadsens") == 0) - return wov_set_vad_sensitivity(atoi(argv[2])); - - if (strcasecmp(argv[1], "gain") == 0) { - wov_set_gain(atoi(argv[2]), atoi(argv[2])); - return EC_SUCCESS; - } - } else if (argc == 5) { - if (strcasecmp(argv[1], "cfgtdm") == 0) { - int delay0, delay1; - uint32_t flags; - - delay0 = atoi(argv[2]); - delay1 = atoi(argv[3]); - flags = atoi(argv[4]); - if ((delay0 > 496) || (delay1 > 496) || (flags > 3) || - (delay0 < 0) || (delay1 < 0)) { - return EC_ERROR_INVAL; - } - wov_set_i2s_tdm_config(delay0, delay1, flags); - return EC_SUCCESS; - } - } - - return EC_ERROR_INVAL; -} - -DECLARE_CONSOLE_COMMAND(wov, command_wov, - "init\n" - "mute <enable|disable>\n" - "capram\n" - "cfgsrc <mono|stereo|left|right>\n" - "cfgbit <16|18|20|24>\n" - "cfgsfs <8000|12000|16000|24000|32000|48000>\n" - "cfgbck <32fs|48fs|64fs|128fs|256fs>\n" - "cfgfmt <i2s|right|left|pcma|pcmb|tdm>\n" - "cfgmod <off|vad|ram|i2s|rami2s>\n" - "cfgtdm [0~496 0~496 0~3]>\n" - "cfgdckV <0.75|1.0|1.2|2.4|3.0>\n" - "cfgdckR <0.75|1.0|1.2|2.4|3.0>\n" - "cfgdckI <0.75|1.0|1.2|2.4|3.0>\n" - "cfgget\n" - "fmul2 <enable|disable>\n" - "vadsens <0~31>\n" - "gain <0~31>", - "wov configuration"); -#endif diff --git a/chip/npcx/wov_chip.h b/chip/npcx/wov_chip.h deleted file mode 100644 index dce534c501..0000000000 --- a/chip/npcx/wov_chip.h +++ /dev/null @@ -1,658 +0,0 @@ -/* Copyright 2018 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_WOV_CHIP_H -#define __CROS_EC_WOV_CHIP_H - -#include "common.h" - -/* FMUL2 clock Frequency. */ -enum fmul2_clk_freq { - FMUL2_48_MHZ = 0, /* Default */ - FMUL2_24_MHZ -}; - -enum fmul2_clk_divider { - FMUL2_CLK_NO_DIVIDER = 0x00, - FMUL2_CLK_DIVIDER_BY_2 = 0x01, - FMUL2_CLK_DIVIDER_BY_4 = 0x03, /* Default */ - FMUL2_CLK_DIVIDER_BY_8 = 0x07 -}; - -/* Microphone source. */ -enum wov_mic_source { - /* Only data from left mic. */ - WOV_SRC_LEFT = 0, - /* Only data from right mic. */ - WOV_SRC_RIGHT, - /* Both channels have the same data (average of left & right */ - WOV_SRC_MONO, - /* Each channel has its own data. */ - WOV_SRC_STEREO -}; - -/* Clock source for APM. */ -enum wov_clk_src_sel { - WOV_FMUL2_CLK_SRC = 0, - WOV_PLL_CLK_SRC = 1 -}; - -/* FMUL clock division factore. */ -enum wov_fmul_div { - WOV_NODIV = 0, - WOV_DIV_BY_2, - WOV_DIV_BY_4, /* Default value */ - WOV_DIV_BY_8 -}; - -/* Lock state. */ -enum wov_lock_state { - WOV_UNLOCK = 0, - WOV_LOCK = 1 -}; - -/* Reference clock source select. */ -enum wov_ref_clk_src_sel { - WOV_FREE_RUN_OSCILLATOR = 0, - WOV_CRYSTAL_OSCILLATOR = 1 -}; - -/* PLL external divider select. */ -enum wov_ext_div_sel { - WOV_EXT_DIV_BINARY_CNT = 0, - WOV_EXT_DIV_LFSR_DIV = 1 -}; - -/* FMUL output frequency. */ -enum wov_fmul_out_freq { - WOV_FMUL_OUT_FREQ_48_MHZ = 0, - WOV_FMUL_OUT_FREQ_49_MHZ = 1 -}; - -/* Digital microphone clock divider select. */ -enum wov_dmic_clk_div_sel { - WOV_DMIC_DIV_DISABLE = 1, - WOV_DMIC_DIV_BY_2 = 2, - WOV_DMIC_DIV_BY_4 = 4 -}; - -/* FIFO threshold. */ -enum wov_fifo_threshold { - WOV_FIFO_THRESHOLD_1_DATA_WORD = 0, - WOV_FIFO_THRESHOLD_2_DATA_WORDS = 1, - WOV_FIFO_THRESHOLD_4_DATA_WORDS = 2, - WOV_FIFO_THRESHOLD_8_DATA_WORDS = 4, - WOV_FIFO_THRESHOLD_16_DATA_WORDS = 8, - WOV_FIFO_THRESHOLD_32_DATA_WORDS = 16, - WOV_FIFO_THRESHOLD_40_DATA_WORDS = 20, - WOV_FIFO_THRESHOLD_64_DATA_WORDS = 32, - WOV_FIFO_THRESHOLD_80_DATA_WORDS = 40, - WOV_FIFO_THRESHOLD_96_DATA_WORDS = 48 -}; - -/* FIFO DMA request select. */ -enum wov_fifo_dma_req_sel { - WOV_FIFO_DMA_DFLT_DMA_REQ_CONN = 0, - WOV_FIFO_DMA_DMA_REQ_CON_FIFO -}; - -/* FIFO operational state. */ -enum wov_fifo_oper_state { - WOV_FIFO_OPERATIONAL = 0, - WOV_FIFO_RESET, /* Default */ -}; - -/* WoV interrupt index. */ -enum wov_interrupt_index { - WOV_VAD_INT_INDX, - WOV_VAD_WAKE_INDX, - WOV_CFIFO_NOT_EMPTY_INDX, - WOV_CFIFO_THRESHOLD_INT_INDX, - WOV_CFIFO_THRESHOLD_WAKE_INDX, - WOV_CFIFO_OVERRUN_INT_INDX, - WOV_I2SFIFO_OVERRUN_INT_INDX, - WOV_I2SFIFO_UNDERRUN_INT_INDX -}; - -/* FIFO DMA request selection. */ -enum wov_dma_req_sel { - WOV_DFLT_ESPI_DMA_REQ = 0, - WOV_FROM_FIFO_DMA_REQUEST -}; - -/* Core FIFO input select. */ -enum wov_core_fifo_in_sel { - WOV_CFIFO_IN_LEFT_CHAN_2_CONS_16_BITS = 0, /* Default */ - WOV_CFIFO_IN_LEFT_RIGHT_CHAN_16_BITS, - WOV_CFIFO_IN_LEFT_CHAN_24_BITS, - WOV_CFIFO_IN_LEFT_RIGHT_CHAN_24_BITS -}; - -/* PLL external divider selector. */ -enum wov_pll_ext_div_sel { - WOV_PLL_EXT_DIV_BIN_CNT = 0, - WOV_PLL_EXT_DIV_LFSR -}; - -/* Code for events for call back function. */ -enum wov_events { - WOV_NO_EVENT = 0, - /* - * Data is ready. - * need to call to wov_set_buffer to update the buffer * pointer - */ - WOV_EVENT_DATA_READY = 1, - WOV_EVENT_VAD, /* Voice activity detected */ - - WOV_EVENT_ERROR_FIRST = 128, - WOV_EVENT_ERROR_CORE_FIFO_OVERRUN = 128, - WOV_EVENT_ERROR_I2S_FIFO_UNDERRUN = 129, - WOV_EVENT_ERROR_I2S_FIFO_OVERRUN = 130, - WOV_EVENT_ERROR_LAST = 255, - -}; - -/* WoV FIFO errors. */ -enum wov_fifo_errors { - WOV_FIFO_NO_ERROR = 0, - WOV_CORE_FIFO_OVERRUN = 1, /* 2 : I2S FIFO is underrun. */ - WOV_I2S_FIFO_OVERRUN = 2, /* 3 : I2S FIFO is overrun. */ - WOV_I2S_FIFO_UNDERRUN = 3 /* 4 : I2S FIFO is underrun. */ - -}; - -/* Selects I2S test mode. */ -enum wov_test_mode { WOV_NORMAL_MODE = 0, WOV_TEST_MODE }; - -/* PULL_UP/PULL_DOWN selection. */ -enum wov_pull_upd_down_sel { WOV_PULL_DOWN = 0, WOV_PULL_UP }; - -/* I2S output data floating mode. */ -enum wov_floating_mode { WOV_FLOATING_DRIVEN = 0, WOV_FLOATING }; - -/* Clock inverted mode. */ -enum wov_clk_inverted_mode { WOV_CLK_NORMAL = 0, WOV_CLK_INVERTED }; - -enum wov_i2s_chan_trigger { - WOV_I2S_SAMPLED_1_AFTER_0 = 0, - WOV_I2S_SAMPLED_0_AFTER_1 = 1 -}; - -/* APM modes. */ -enum wov_modes { - WOV_MODE_OFF = 1, - WOV_MODE_VAD, - WOV_MODE_RAM, - WOV_MODE_I2S, - WOV_MODE_RAM_AND_I2S -}; - -/* DAI format. */ -enum wov_dai_format { - WOV_DAI_FMT_I2S, /* I2S mode */ - WOV_DAI_FMT_RIGHT_J, /* Right Justified mode */ - WOV_DAI_FMT_LEFT_J, /* Left Justified mode */ - WOV_DAI_FMT_PCM_A, /* PCM A Audio */ - WOV_DAI_FMT_PCM_B, /* PCM B Audio */ - WOV_DAI_FMT_PCM_TDM /* Time Division Multiplexing */ -}; - -struct wov_config { - enum wov_modes mode; - uint32_t sample_per_sec; - int bit_depth; - enum wov_mic_source mic_src; - int left_chan_gain; - int right_chan_gain; - uint16_t i2s_start_delay_0; - uint16_t i2s_start_delay_1; - uint32_t i2s_clock; - enum wov_dai_format dai_format; - int sensitivity_db; -}; - -extern struct wov_config wov_conf; - -/** - * Set FMUL2 clock divider. - * - * @param None - * @return None - */ -void wov_fmul2_set_clk_divider(enum fmul2_clk_divider clk_div); - -/** - * WoV Call back function decleration. - * - * @param event - the event that cause the call to the callback - * function. - * - * @return None - */ -typedef void (*wov_call_back_t)(enum wov_events); - -/* - * WoV macros. - */ - -/* MACROs that set fields of the Clock Control Register structure. */ -#define WOV_APM_CLK_SRC_FMUL2(reg_val) reg_val.clk_sel = 0 -#define WOV_APM_CLK_SRC_PLL(reg_val) reg_val.clk_sel = 1 -#define WOV_APM_GET_CLK_SRC(reg_val) (reg_val.clk_sel) - -/* Core FIFO threshold. */ -#define WOV_GET_CORE_FIFO_THRESHOLD WOV_GET_FIFO_INT_THRESHOLD - -/****************************************************************************** - * - * WoV APIs - * - ******************************************************************************/ - -/** - * Initiates WoV. - * - * @param callback - Pointer to callback function. - * - * @return None - */ -void wov_init(void); - -/** - * Sets WoV stage - * - * @param wov_mode - WoV stage (Table 38) - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_set_mode(enum wov_modes wov_mode); - -/** - * Gets WoV mode - * - * @param None - * @return WoV mode - */ -enum wov_modes wov_get_mode(void); - -/** - * Configure WoV. - * - * @param samples_per_second - Valid sample rate. - * @return In case sample rate is valid return EC_SUCCESS othewise return - * error code. - */ -int wov_set_sample_rate(uint32_t samples_per_second); - -/** - * Gets sampling rate. - * - * @param None - * @return the current sampling rate. - */ -uint32_t wov_get_sample_rate(void); - -/** - * Sets sampling depth. - * - * @param bits_num - Valid sample depth in bits. - * @return In case sample depth is valid return EC_SUCCESS othewise return - * error code. - */ -int wov_set_sample_depth(int bits_num); - -/** - * Gets sampling depth. - * - * @param None. - * @return sample depth in bits. - */ -int wov_get_sample_depth(void); - -/** - * Sets microphone source. - * - * @param mic_src - Valid microphone source - * @return return EC_SUCCESS if mic source valid othewise - * return error code. - */ -int wov_set_mic_source(enum wov_mic_source mic_src); - -/** - * Gets microphone source. - * - * @param None. - * @return sample depth in bits. - */ -enum wov_mic_source wov_get_mic_source(void); - -/** - * Mutes the WoV. - * - * @param enable - enabled flag, true means enable - * @return None - */ -void wov_mute(int enable); - -/** - * Gets gain values - * - * @param left_chan_gain - address of left channel gain response. - * @param right_chan_gain - address of right channel gain response. - * @return None - */ -void wov_get_gain(int *left_chan_gain, int *right_chan_gain); - -/** - * Sets gain - * - * @param left_chan_gain - Left channel gain. - * @param right_chan_gain - Right channel gain - * @return None - */ -void wov_set_gain(int left_chan_gain, int right_chan_gain); - -/** - * Enables/Disables ADC. - * - * @param enable - enabled flag, true means enable - * @return None - */ -void wov_enable_agc(int enable); - -/** - * Enables/Disables the automatic gain. - * - * @param stereo - Stereo enabled flag, 1 means enable. - * @param target - Target output level of the ADC. - * @param noise_gate_threshold - Noise Gate system select. 1 means enable. - * @param hold_time - Hold time before starting AGC adjustment to - * the TARGET value. - * @param attack_time - Attack time - gain ramp down. - * @param decay_time - Decay time - gain ramp up. - * @param max_applied_gain - Maximum Gain Value to apply to the ADC path. - * @param min_applied_gain - Minimum Gain Value to apply to the ADC path. - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_set_agc_config(int stereo, float target, - int noise_gate_threshold, uint8_t hold_time, - uint16_t attack_time, uint16_t decay_time, - float max_applied_gain, float min_applied_gain); - -/** - * Sets VAD sensitivity. - * - * @param sensitivity_db - VAD sensitivity in db. - * @return None - */ -int wov_set_vad_sensitivity(int sensitivity_db); - -/** - * Gets VAD sensitivity. - * - * @param None. - * @return VAD sensitivity in db - */ -int wov_get_vad_sensitivity(void); - -/** - * Configure I2S bus format. (Sample rate and size are determined via common - * config functions.) - * - * @param format - one of the following: I2S mode, Right Justified mode, - * Left Justified mode, PCM A Audio, PCM B Audio and - * Time Division Multiplexing - * @return EC error code. - */ -void wov_set_i2s_fmt(enum wov_dai_format format); - -/** - * Configure I2S bus clock. (Sample rate and size are determined via common - * config functions.) - * - * @param i2s_clock - I2S clock frequency in Hz (needed in order to - * configure the internal PLL for 12MHz) - * @return EC error code. - */ -void wov_set_i2s_bclk(uint32_t i2s_clock); - -/** - * Configure I2S bus. (Sample rate and size are determined via common - * config functions.) - * - * @param ch0_delay - 0 to 496. Defines the delay from the SYNC till the - * first bit (MSB) of channel 0 (left channel) - * @param ch1_delay - -1 to 496. Defines the delay from the SYNC till the - * first bit (MSB) of channel 1 (right channel). - * If channel 1 is not used set this field to -1. - * - * @param flags - WOV_TDM_ADJACENT_TO_CH0 = BIT(0). There is a - * channel adjacent to channel 0, so float SDAT when - * driving the last bit (LSB) of the channel during the - * second half of the clock cycle to avoid bus contention. - * - * WOV_TDM_ADJACENT_TO_CH1 = BIT(1). There is a channel - * adjacent to channel 1. - * - * @return EC error code. - */ -enum ec_error_list wov_set_i2s_tdm_config(int ch0_delay, int ch1_delay, - uint32_t flags); - -/** - * Configure FMUL2 clock tunning. - * - * @param None - * @return None - */ -void wov_fmul2_conf_tuning(void); - -/** - * Configure DMIC clock. - * - * @param enable - DMIC enabled , true means enable - * @param clk_div - DMIC clock division factor (disable, divide by 2 - * divide by 4) - * @return None - */ -void wov_dmic_clk_config(int enable, enum wov_dmic_clk_div_sel clk_div); - -/** - * FMUL2 clock control configuration. - * - * @param clk_src - select between FMUL2 (WOV_FMUL2_CLK_SRC) and - * PLL (WOV_PLL_CLK_SRC) - * @return None - */ -extern void wov_set_clk_selection(enum wov_clk_src_sel clk_src); - -/** - * Configure PLL clock. - * - * @param ext_div_sel - PLL external divider selector. - * @param div_factor - When ext_div_sel is WOV_PLL_EXT_DIV_BIN_CNT - * then it is the 4 LSBits of this field, - * otherwise this field is an index to - * PLL External Divider Load Values table. - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_pll_clk_ext_div_config( - enum wov_pll_ext_div_sel ext_div_sel, uint32_t div_factor); - -/** - * PLL power down. - * - * @param enable - true power down the PLL or false PLL operating - * @return None - */ -void wov_pll_enable(int enable); - -/** - * Configures PLL clock dividers.. - * - * @param out_div_1 - PLL output divider #1, valid values 1-7 - * @param out_div_2 - PLL output divider #2, valid values 1-7 - * @param feedback_div - PLL feadback divider (Default is 375 decimal) - * @param in_div - PLL input divider - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_pll_clk_div_config(uint32_t out_div_1, - uint32_t out_div_2, - uint32_t feedback_div, - uint32_t in_div); - -/** - * Enables/Disables WoV interrupt. - * - * @param int_index - Interrupt ID. - * @param enable - enabled flag, 1 means enable - * - * @return None. - */ -void wov_interrupt_enable(enum wov_interrupt_index int_index, int enable); - -/** - * Sets core FIFO threshold. - * - * @param in_sel - Core FIFO input select - * @param threshold - Core FIFO threshold - * - * @return None - */ -void wov_cfifo_config(enum wov_core_fifo_in_sel in_sel, - enum wov_fifo_threshold threshold); - -/** - * Start the actual capturing of the Voice data to the RAM. - * Note that the pointer to the RAM buffer must be precisely - * set by calling wov_set_buffer(); - * - * @param None - * - * @return None - */ -void wov_start_ram_capture(void); - -/** - * Stop the capturing of the Voice data to the RAM. - * - * @param none - * - * @return None - */ -void wov_stop_ram_capture(void); - -/** - * Rests the Core FIFO. - * - * @param None - * - * @return None - */ -void wov_core_fifo_reset(void); - -/** - * Rests the I2S FIFO. - * - * @param None - * - * @return None - */ -void wov_i2s_fifo_reset(void); - -/** - * Start the capturing of the Voice data via I2S. - * - * @param None - * - * @return None - */ -void wov_start_i2s_capture(void); - -/** - * Stop the capturing of the Voice data via I2S. - * - * @param none - * - * @return None - */ -void wov_stop_i2s_capture(void); - -/** - * Reads data from the core fifo. - * - * @param num_elements - Number of elements (Dword) to read. - * - * @return None - */ -void wov_cfifo_read_handler(uint32_t num_elements); - -/** - * Sets data buffer for reading from core FIFO - * - * @param buff - Pointer to the read buffer, buffer must be 32 bits - * aligned. - * @param size_in_words - Size must be a multiple of CONFIG_WOV_THRESHOLD_WORDS - * (defaulte = 80 words) - * - * @return None - * - * Note - When the data buffer will be full the FW will be notifyed - * about it, and the FW will need to recall to this function. - */ -int wov_set_buffer(uint32_t *buff, int size_in_words); - -/** - * Resets the APM. - * - * @param enable - enabled flag, true or false - * @return None - */ -void wov_apm_active(int enable); - -void wov_handle_event(enum wov_events event); - -/** - * I2S golobal configuration - * - * @param i2s_hiz_data - Defines when the I2S data output is floating. - * @param i2s_hiz - Defines if the I2S data output is always floating. - * @param clk_invert - Defines the I2S bit clock edge sensitivity - * @param out_pull_en - Enable a pull-up or a pull-down resistor on - * I2S output - * @param out_pull_mode - Select a pull-up or a pull-down resistor on - * I2S output - * @param in_pull_en - Enable a pull-up or a pull-down resistor on - * I2S input - * @param in_pull_mode - Select a pull-up or a pull-down resistor on - * I2S intput - * @param test_mode - Selects I2S test mode - * - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_i2s_global_config( - enum wov_floating_mode i2s_hiz_data, - enum wov_floating_mode i2s_hiz, - enum wov_clk_inverted_mode clk_invert, - int out_pull_en, enum wov_pull_upd_down_sel out_pull_mode, - int in_pull_en, - enum wov_pull_upd_down_sel in_pull_mode, - enum wov_test_mode test_mode); - -/** - * I2S channel configuration - * - * @param channel_num - I2S channel number, 0 or 1. - * @param bit_count - I2S channel bit count. - * @param trigger - Define the I2S chanel trigger 1->0 or 0->1 - * @param start_delay - Defines the delay from the trigger defined for - * the channel till the first bit (MSB) of the data. - * - * @return EC_ERROR_INVAL or EC_SUCCESS - */ -enum ec_error_list wov_i2s_channel_config(uint32_t channel_num, - uint32_t bit_count, enum wov_i2s_chan_trigger trigger, - int32_t start_delay); - -#endif /* __CROS_EC_WOV_CHIP_H */ |