diff options
Diffstat (limited to 'chip/it83xx')
36 files changed, 0 insertions, 12015 deletions
diff --git a/chip/it83xx/adc.c b/chip/it83xx/adc.c deleted file mode 100644 index 2839da5af2..0000000000 --- a/chip/it83xx/adc.c +++ /dev/null @@ -1,379 +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. - */ - -/* IT83xx ADC module for Chrome EC */ - -#include "adc.h" -#include "clock.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) - -/* Global variables */ -static struct mutex adc_lock; -static int adc_init_done; -static volatile task_id_t task_waiting; - -/* Data structure of ADC channel control registers. */ -const struct adc_ctrl_t adc_ctrl_regs[] = { - {&IT83XX_ADC_VCH0CTL, &IT83XX_ADC_VCH0DATM, &IT83XX_ADC_VCH0DATL}, - {&IT83XX_ADC_VCH1CTL, &IT83XX_ADC_VCH1DATM, &IT83XX_ADC_VCH1DATL}, - {&IT83XX_ADC_VCH2CTL, &IT83XX_ADC_VCH2DATM, &IT83XX_ADC_VCH2DATL}, - {&IT83XX_ADC_VCH3CTL, &IT83XX_ADC_VCH3DATM, &IT83XX_ADC_VCH3DATL}, - {&IT83XX_ADC_VCH4CTL, &IT83XX_ADC_VCH4DATM, &IT83XX_ADC_VCH4DATL}, - {&IT83XX_ADC_VCH5CTL, &IT83XX_ADC_VCH5DATM, &IT83XX_ADC_VCH5DATL}, - {&IT83XX_ADC_VCH6CTL, &IT83XX_ADC_VCH6DATM, &IT83XX_ADC_VCH6DATL}, - {&IT83XX_ADC_VCH7CTL, &IT83XX_ADC_VCH7DATM, &IT83XX_ADC_VCH7DATL}, - {&IT83XX_ADC_VCH13CTL, &IT83XX_ADC_VCH13DATM, &IT83XX_ADC_VCH13DATL}, - {&IT83XX_ADC_VCH14CTL, &IT83XX_ADC_VCH14DATM, &IT83XX_ADC_VCH14DATL}, - {&IT83XX_ADC_VCH15CTL, &IT83XX_ADC_VCH15DATM, &IT83XX_ADC_VCH15DATL}, - {&IT83XX_ADC_VCH16CTL, &IT83XX_ADC_VCH16DATM, &IT83XX_ADC_VCH16DATL}, -}; -BUILD_ASSERT(ARRAY_SIZE(adc_ctrl_regs) == CHIP_ADC_COUNT); - -#ifdef CONFIG_ADC_VOLTAGE_COMPARATOR -#define VCMP_ADC_CH_MASK_H BIT(3) -#define VCMP_ADC_CH_MASK_L 0x7 -/* 10-bits resolution */ -#define VCMP_RESOLUTION BIT(10) -#define VCMP_MAX_MVOLT 3000 - -/* Data structure of voltage comparator control registers. */ -const struct vcmp_ctrl_t vcmp_ctrl_regs[] = { - {&IT83XX_ADC_VCMP0CTL, &IT83XX_ADC_VCMP0CSELM, &IT83XX_ADC_CMP0THRDATM, - &IT83XX_ADC_CMP0THRDATL}, - {&IT83XX_ADC_VCMP1CTL, &IT83XX_ADC_VCMP1CSELM, &IT83XX_ADC_CMP1THRDATM, - &IT83XX_ADC_CMP1THRDATL}, - {&IT83XX_ADC_VCMP2CTL, &IT83XX_ADC_VCMP2CSELM, &IT83XX_ADC_CMP2THRDATM, - &IT83XX_ADC_CMP2THRDATL}, - {&IT83XX_ADC_VCMP3CTL, &IT83XX_ADC_VCMP3CSELM, &IT83XX_ADC_CMP3THRDATM, - &IT83XX_ADC_CMP3THRDATL}, - {&IT83XX_ADC_VCMP4CTL, &IT83XX_ADC_VCMP4CSELM, &IT83XX_ADC_CMP4THRDATM, - &IT83XX_ADC_CMP4THRDATL}, - {&IT83XX_ADC_VCMP5CTL, &IT83XX_ADC_VCMP5CSELM, &IT83XX_ADC_CMP5THRDATM, - &IT83XX_ADC_CMP5THRDATL}, -}; -BUILD_ASSERT(ARRAY_SIZE(vcmp_ctrl_regs) == CHIP_VCMP_COUNT); -#endif - -static void adc_enable_channel(int ch) -{ - if (ch < CHIP_ADC_CH4) - /* - * for channel 0, 1, 2, and 3 - * bit4 ~ bit0 : indicates voltage channel[x] - * input is selected for measurement (enable) - * bit5 : data valid interrupt of adc. - * bit7 : W/C data valid flag - */ - *adc_ctrl_regs[ch].adc_ctrl = 0xa0 + ch; - else - /* - * for channel 4 ~ 7 and 13 ~ 16. - * bit4 : voltage channel enable (ch 4~7 and 13 ~ 16) - * bit5 : data valid interrupt of adc. - * bit7 : W/C data valid flag - */ - *adc_ctrl_regs[ch].adc_ctrl = 0xb0; - - task_clear_pending_irq(IT83XX_IRQ_ADC); - task_enable_irq(IT83XX_IRQ_ADC); - - /* bit 0 : adc module enable */ - IT83XX_ADC_ADCCFG |= 0x01; -} - -static void adc_disable_channel(int ch) -{ - if (ch < CHIP_ADC_CH4) - /* - * for channel 0, 1, 2, and 3 - * bit4 ~ bit0 : indicates voltage channel[x] - * input is selected for measurement (disable) - * bit 7 : W/C data valid flag - */ - *adc_ctrl_regs[ch].adc_ctrl = 0x9F; - else - /* - * for channel 4 ~ 7 and 13 ~ 16. - * bit4 : voltage channel disable (ch 4~7 and 13 ~ 16) - * bit7 : W/C data valid flag - */ - *adc_ctrl_regs[ch].adc_ctrl = 0x80; - - /* bit 0 : adc module disable */ - IT83XX_ADC_ADCCFG &= ~0x01; - - task_disable_irq(IT83XX_IRQ_ADC); -} - -static int adc_data_valid(enum chip_adc_channel adc_ch) -{ - return (adc_ch <= CHIP_ADC_CH7) ? - (IT83XX_ADC_ADCDVSTS & BIT(adc_ch)) : - (IT83XX_ADC_ADCDVSTS2 & (1 << (adc_ch - CHIP_ADC_CH13))); -} - -int adc_read_channel(enum adc_channel ch) -{ - uint32_t events; - /* voltage 0 ~ 3v = adc data register raw data 0 ~ 3FFh (10-bit ) */ - uint16_t adc_raw_data; - int valid = 0; - int adc_ch, mv; - - if (!adc_init_done) - return ADC_READ_ERROR; - - mutex_lock(&adc_lock); - - disable_sleep(SLEEP_MASK_ADC); - task_waiting = task_get_current(); - adc_ch = adc_channels[ch].channel; - adc_enable_channel(adc_ch); - /* Wait for interrupt */ - events = task_wait_event_mask(TASK_EVENT_ADC_DONE, ADC_TIMEOUT_US); - task_waiting = TASK_ID_INVALID; - /* - * Ensure EC won't post the adc done event which is set after getting - * events (events |= __wait_evt() in task_wait_event_mask()) to next - * adc read. - * NOTE: clear TASK_EVENT_ADC_DONE event must happen after setting - * task_waiting to invalid. So TASK_EVENT_ADC_DONE would not set until - * next read. - */ - atomic_clear_bits(task_get_event_bitmap(task_get_current()), - TASK_EVENT_ADC_DONE); - - /* data valid of adc channel[x] */ - if (adc_data_valid(adc_ch)) { - /* read adc raw data msb and lsb */ - adc_raw_data = (*adc_ctrl_regs[adc_ch].adc_datm << 8) + - *adc_ctrl_regs[adc_ch].adc_datl; - - /* W/C data valid flag */ - if (adc_ch <= CHIP_ADC_CH7) - IT83XX_ADC_ADCDVSTS = BIT(adc_ch); - else - IT83XX_ADC_ADCDVSTS2 = (1 << (adc_ch - CHIP_ADC_CH13)); - - mv = adc_raw_data * adc_channels[ch].factor_mul / - adc_channels[ch].factor_div + adc_channels[ch].shift; - valid = 1; - } - - if (!valid) { - CPRINTS("ADC failed to read!!! (regs=%x, %x, ch=%d, evt=%x)", - IT83XX_ADC_ADCDVSTS, - IT83XX_ADC_ADCDVSTS2, - adc_ch, events); - } - - adc_disable_channel(adc_ch); - enable_sleep(SLEEP_MASK_ADC); - - mutex_unlock(&adc_lock); - - return valid ? mv : ADC_READ_ERROR; -} - -void adc_interrupt(void) -{ - /* - * Clear the interrupt status. - * - * NOTE: - * The ADC interrupt pending flag won't be cleared unless - * we W/C data valid flag of ADC module as well. - * (If interrupt type setting is high-level triggered) - */ - task_clear_pending_irq(IT83XX_IRQ_ADC); - /* - * We disable ADC interrupt here, because current setting of - * interrupt type is high-level triggered. - * The interrupt will be triggered again and again until - * we W/C data valid flag if we don't disable it. - */ - task_disable_irq(IT83XX_IRQ_ADC); - /* 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); -} - -#ifdef CONFIG_ADC_VOLTAGE_COMPARATOR -/* Clear voltage comparator interrupt status */ -void clear_vcmp_status(int vcmp_x) -{ - if (vcmp_x <= CHIP_VCMP2) - IT83XX_ADC_VCMPSTS = BIT(vcmp_x); - else - IT83XX_ADC_VCMPSTS2 = BIT(vcmp_x - CHIP_VCMP3); -} - -/* Enable/Disable voltage comparator interrupt */ -void vcmp_enable(int idx, int enable) -{ - if (enable) { - /* Enable comparator interrupt */ - *vcmp_ctrl_regs[idx].vcmp_ctrl |= ADC_VCMP_CMPINTEN; - /* Start voltage comparator */ - *vcmp_ctrl_regs[idx].vcmp_ctrl |= ADC_VCMP_CMPEN; - } else { - /* Stop voltage comparator */ - *vcmp_ctrl_regs[idx].vcmp_ctrl &= ~ADC_VCMP_CMPEN; - /* Disable comparator interrupt */ - *vcmp_ctrl_regs[idx].vcmp_ctrl &= ~ADC_VCMP_CMPINTEN; - } -} - -/* Set voltage comparator conditions */ -void set_voltage_comparator_condition(int idx) -{ - int val; - - /* CMPXTHRDAT[9:0] = threshold(mv) * 1024 / 3000(mv) */ - val = vcmp_list[idx].threshold * VCMP_RESOLUTION / VCMP_MAX_MVOLT; - *vcmp_ctrl_regs[idx].vcmp_datl = (uint8_t)(val & 0xff); - *vcmp_ctrl_regs[idx].vcmp_datm = (uint8_t)((val >> 8) & 0xff); - - /* Select greater or less equal than threshold */ - if (vcmp_list[idx].flag & GREATER_THRESHOLD) - *vcmp_ctrl_regs[idx].vcmp_ctrl |= ADC_VCMP_GREATER_THRESHOLD; - else - *vcmp_ctrl_regs[idx].vcmp_ctrl &= ~ADC_VCMP_GREATER_THRESHOLD; -} - -/* Voltage comparator interrupt, handle one channel at a time. */ -void voltage_comparator_interrupt(void) -{ - int idx, status; - - /* Find out which voltage comparator triggered */ - status = IT83XX_ADC_VCMPSTS & 0x07; - status |= (IT83XX_ADC_VCMPSTS2 & 0x07) << 3; - - for (idx = CHIP_VCMP0; idx < VCMP_COUNT; idx++) { - if (status & BIT(idx)) { - /* Called back to board-level function */ - if (vcmp_list[idx].vcmp_thresh_cb) - vcmp_list[idx].vcmp_thresh_cb(); - /* Clear voltage comparator interrupt status */ - clear_vcmp_status(idx); - } - } - - /* Clear interrupt status */ - task_clear_pending_irq(IT83XX_IRQ_V_COMP); -} - -/* Voltage comparator initialization */ -static void voltage_comparator_init(void) -{ - int idx; - - /* No voltage comparator is declared */ - if (!VCMP_COUNT) - return; - - for (idx = CHIP_VCMP0; idx < VCMP_COUNT; idx++) { - /* - * Select voltage comparator: - * vcmp_list[i] use voltage comparator i, i = 0 ~ 5. - */ - - /* Select which ADC channel output voltage into comparator */ - *vcmp_ctrl_regs[idx].vcmp_ctrl |= - vcmp_list[idx].adc_ch & VCMP_ADC_CH_MASK_L; - if (vcmp_list[idx].adc_ch & VCMP_ADC_CH_MASK_H) - *vcmp_ctrl_regs[idx].vcmp_adc_chm |= ADC_VCMP_VCMPCSELM; - - /* Set "all voltage comparator" scan period */ - IT83XX_ADC_VCMPSCP = vcmp_list[idx].scan_period; - /* Set voltage comparator conditions */ - set_voltage_comparator_condition(idx); - /* Clear voltage comparator interrupt status */ - clear_vcmp_status(idx); - /* Enable comparator interrupt and start */ - vcmp_enable(idx, 1); - } - - /* Clear interrupt status */ - task_clear_pending_irq(IT83XX_IRQ_V_COMP); - /* Enable voltage comparator to interrupt MCU */ - task_enable_irq(IT83XX_IRQ_V_COMP); -} -#endif - -/* - * ADC analog accuracy initialization (only once after VSTBY power on) - * - * Write 1 to this bit and write 0 to this bit immediately once and - * only once during the firmware initialization and do not write 1 again - * after initialization since IT83xx takes much power consumption - * if this bit is set as 1 - */ -static void adc_accuracy_initialization(void) -{ - /* bit3 : start adc accuracy initialization */ - IT83XX_ADC_ADCSTS |= 0x08; - /* Enable automatic HW calibration. */ - IT83XX_ADC_KDCTL |= IT83XX_ADC_AHCE; - /* short delay for adc accuracy initialization */ - IT83XX_GCTRL_WNCKR = 0; - /* bit3 : stop adc accuracy initialization */ - IT83XX_ADC_ADCSTS &= ~0x08; -} - -/* ADC module Initialization */ -static void adc_init(void) -{ - /* ADC analog accuracy initialization */ - adc_accuracy_initialization(); - - /* Enable alternate function */ - gpio_config_module(MODULE_ADC, 1); - /* - * bit7@ADCSTS : ADCCTS1 = 0 - * bit5@ADCCFG : ADCCTS0 = 0 - * bit[5-0]@ADCCTL : SCLKDIV - * The ADC channel conversion time is 30.8*(SCLKDIV+1) us. - * (Current setting is 61.6us) - * - * NOTE: A sample time delay (60us) also need to be included in - * conversion time, so the final result is ~= 121.6us. - */ - IT83XX_ADC_ADCSTS &= ~BIT(7); - IT83XX_ADC_ADCCFG &= ~BIT(5); - IT83XX_ADC_ADCCTL = 1; - /* - * Enable this bit, and data of VCHxDATL/VCHxDATM will be - * kept until data valid is cleared. - */ - IT83XX_ADC_ADCGCR |= IT83XX_ADC_DBKEN; - - task_waiting = TASK_ID_INVALID; - /* disable adc interrupt */ - task_disable_irq(IT83XX_IRQ_ADC); - -#ifdef CONFIG_ADC_VOLTAGE_COMPARATOR - /* - * Init voltage comparator - * NOTE:ADC channel signal output to voltage comparator, - * so we need set the channel to ADC alternate mode first. - */ - voltage_comparator_init(); -#endif - - adc_init_done = 1; -} -DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_INIT_ADC); diff --git a/chip/it83xx/adc_chip.h b/chip/it83xx/adc_chip.h deleted file mode 100644 index 15a8e68e94..0000000000 --- a/chip/it83xx/adc_chip.h +++ /dev/null @@ -1,135 +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. - */ - -/* IT83xx ADC module for Chrome EC */ - -#ifndef __CROS_EC_ADC_CHIP_H -#define __CROS_EC_ADC_CHIP_H - -#include <stdint.h> - -#include "common.h" - -/* - * Maximum time we allow for an ADC conversion. - * NOTE: - * Because this setting greater than "SLEEP_SET_HTIMER_DELAY_USEC" in clock.c, - * so we enabled sleep mask to prevent going in to deep sleep while ADC - * converting. - */ -#define ADC_TIMEOUT_US MSEC - -/* Minimum and maximum values returned by adc_read_channel(). */ -#define ADC_READ_MIN 0 -#define ADC_READ_MAX 1023 -#define ADC_MAX_MVOLT 3000 - -/* List of ADC channels. */ -enum chip_adc_channel { - CHIP_ADC_CH0 = 0, - CHIP_ADC_CH1, - CHIP_ADC_CH2, - CHIP_ADC_CH3, - CHIP_ADC_CH4, - CHIP_ADC_CH5, - CHIP_ADC_CH6, - CHIP_ADC_CH7, - CHIP_ADC_CH13, - CHIP_ADC_CH14, - CHIP_ADC_CH15, - CHIP_ADC_CH16, - CHIP_ADC_COUNT, -}; - -/* List of voltage comparator. */ -enum chip_vcmp { - CHIP_VCMP0 = 0, - CHIP_VCMP1, - CHIP_VCMP2, - CHIP_VCMP3, - CHIP_VCMP4, - CHIP_VCMP5, - CHIP_VCMP_COUNT, -}; - -/* List of voltage comparator scan period times. */ -enum vcmp_scan_period { - VCMP_SCAN_PERIOD_100US = 0x10, - VCMP_SCAN_PERIOD_200US = 0x20, - VCMP_SCAN_PERIOD_400US = 0x30, - VCMP_SCAN_PERIOD_600US = 0x40, - VCMP_SCAN_PERIOD_800US = 0x50, - VCMP_SCAN_PERIOD_1MS = 0x60, - VCMP_SCAN_PERIOD_1_5MS = 0x70, - VCMP_SCAN_PERIOD_2MS = 0x80, - VCMP_SCAN_PERIOD_2_5MS = 0x90, - VCMP_SCAN_PERIOD_3MS = 0xA0, - VCMP_SCAN_PERIOD_4MS = 0xB0, - VCMP_SCAN_PERIOD_5MS = 0xC0, -}; - -/* Data structure to define ADC channel control registers. */ -struct adc_ctrl_t { - volatile uint8_t *adc_ctrl; - volatile uint8_t *adc_datm; - volatile uint8_t *adc_datl; -}; - -/* Data structure to define ADC channels. */ -struct adc_t { - const char *name; - int factor_mul; - int factor_div; - int shift; - enum chip_adc_channel channel; -}; - -/* Data structure to define voltage comparator control registers. */ -struct vcmp_ctrl_t { - volatile uint8_t *vcmp_ctrl; - volatile uint8_t *vcmp_adc_chm; - volatile uint8_t *vcmp_datm; - volatile uint8_t *vcmp_datl; -}; - -/* supported flags (member "flag" in struct vcmp_t) for voltage comparator */ -#define GREATER_THRESHOLD BIT(0) -#define LESS_EQUAL_THRESHOLD BIT(1) - -/* Data structure for board to define voltage comparator list. */ -struct vcmp_t { - const char *name; - int threshold; - /* - * Select greater/less equal threshold. - * NOTE: once edge trigger interrupt fires, we need disable the voltage - * comparator, or the matching threshold level will infinitely - * triggers interrupt. - */ - char flag; - /* Called when the interrupt fires */ - void (*vcmp_thresh_cb)(void); - /* - * Select "all voltage comparator" scan period time. - * The power consumption is positively relative with scan frequency. - */ - enum vcmp_scan_period scan_period; - /* - * Select which ADC channel output voltage into comparator and we - * should set the ADC channel pin in alternate mode via adc_channels[]. - */ - enum chip_adc_channel adc_ch; -}; - -#ifdef CONFIG_ADC_VOLTAGE_COMPARATOR -/* - * Boards must provide this list of voltage comparator definitions. - * This must match the enum board_vcmp list provided by the board. - */ -extern const struct vcmp_t vcmp_list[]; -#endif -void vcmp_enable(int index, int enable); - -#endif /* __CROS_EC_ADC_CHIP_H */ diff --git a/chip/it83xx/build.mk b/chip/it83xx/build.mk deleted file mode 100644 index bbff9f009b..0000000000 --- a/chip/it83xx/build.mk +++ /dev/null @@ -1,40 +0,0 @@ -# -*- makefile -*- -# Copyright 2013 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# IT83xx chip specific files build -# - -# IT8xxx1 and IT83xx are Andes N8 core. -# IT8xxx2 is RISC-V core. -ifeq ($(CHIP_FAMILY), it8xxx2) -CORE:=riscv-rv32i -else -CORE:=nds32 -endif - -# Required chip modules -chip-y=hwtimer.o uart.o gpio.o system.o clock.o irq.o intc.o - -# Optional chip modules -chip-$(CONFIG_WATCHDOG)+=watchdog.o -chip-$(CONFIG_FANS)+=fan.o pwm.o -chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o -# IT8xxx2 series use the FPU instruction set of RISC-V (single-precision only). -ifneq ($(CHIP_FAMILY), it8xxx2) -chip-$(CONFIG_FPU)+=it83xx_fpu.o -endif -chip-$(CONFIG_PWM)+=pwm.o -chip-$(CONFIG_ADC)+=adc.o -chip-$(CONFIG_DAC)+=dac.o -chip-$(CONFIG_HOSTCMD_X86)+=lpc.o ec2i.o -chip-$(CONFIG_HOSTCMD_ESPI)+=espi.o -chip-$(CONFIG_SPI_CONTROLLER)+=spi_master.o -chip-$(CONFIG_SPI)+=spi.o -chip-$(CONFIG_PECI)+=peci.o -ifndef CONFIG_KEYBOARD_NOT_RAW -chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o -endif -chip-$(CONFIG_I2C_CONTROLLER)+=i2c.o -chip-$(CONFIG_I2C_PERIPHERAL)+=i2c_peripheral.o diff --git a/chip/it83xx/clock.c b/chip/it83xx/clock.c deleted file mode 100644 index 41f800721a..0000000000 --- a/chip/it83xx/clock.c +++ /dev/null @@ -1,701 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Clocks and power management settings */ - -#include "adc_chip.h" -#include "clock.h" -#include "common.h" -#include "console.h" -#include "hwtimer.h" -#include "hwtimer_chip.h" -#include "intc.h" -#include "irq_chip.h" -#include "it83xx_pd.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "uart.h" -#include "util.h" - -/* Console output macros. */ -#define CPUTS(outstr) cputs(CC_CLOCK, outstr) -#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args) - -#ifdef CONFIG_LOW_POWER_IDLE -#define SLEEP_SET_HTIMER_DELAY_USEC 250 -#define SLEEP_FTIMER_SKIP_USEC (HOOK_TICK_INTERVAL * 2) - -static timestamp_t sleep_mode_t0; -static timestamp_t sleep_mode_t1; -static int idle_doze_cnt; -static int idle_sleep_cnt; -static uint64_t total_idle_sleep_time_us; -static uint32_t ec_sleep; -/* - * Fixed amount of time to keep the console in use flag true after boot in - * order to give a permanent window in which the heavy sleep mode is not used. - */ -#define CONSOLE_IN_USE_ON_BOOT_TIME (15*SECOND) -static int console_in_use_timeout_sec = 5; -static timestamp_t console_expire_time; - -/* clock source is 32.768KHz */ -#define TIMER_32P768K_CNT_TO_US(cnt) ((uint64_t)(cnt) * 1000000 / 32768) -#define TIMER_CNT_8M_32P768K(cnt) (((cnt) / (8000000 / 32768)) + 1) -#endif /*CONFIG_LOW_POWER_IDLE */ - -static int freq; - -struct clock_gate_ctrl { - volatile uint8_t *reg; - uint8_t mask; -}; - -static void clock_module_disable(void) -{ - /* bit0: FSPI interface tri-state */ - IT83XX_SMFI_FLHCTRL3R |= BIT(0); - /* bit7: USB pad power-on disable */ - IT83XX_GCTRL_PMER2 &= ~BIT(7); - /* bit7: USB debug disable */ - IT83XX_GCTRL_MCCR &= ~BIT(7); - clock_disable_peripheral((CGC_OFFSET_EGPC | CGC_OFFSET_CIR), 0, 0); - clock_disable_peripheral((CGC_OFFSET_SMBA | CGC_OFFSET_SMBB | - CGC_OFFSET_SMBC | CGC_OFFSET_SMBD | CGC_OFFSET_SMBE | - CGC_OFFSET_SMBF), 0, 0); - clock_disable_peripheral((CGC_OFFSET_SSPI | CGC_OFFSET_PECI | - CGC_OFFSET_USB), 0, 0); -} - -enum pll_freq_idx { - PLL_24_MHZ = 1, - PLL_48_MHZ = 2, - PLL_96_MHZ = 4, -}; - -static const uint8_t pll_to_idx[8] = { - 0, - 0, - PLL_24_MHZ, - 0, - PLL_48_MHZ, - 0, - 0, - PLL_96_MHZ -}; - -struct clock_pll_t { - int pll_freq; - uint8_t pll_setting; - uint8_t div_fnd; - uint8_t div_uart; - uint8_t div_usb; - uint8_t div_smb; - uint8_t div_sspi; - uint8_t div_ec; - uint8_t div_jtag; - uint8_t div_pwm; - uint8_t div_usbpd; -}; - -const struct clock_pll_t clock_pll_ctrl[] = { - /* - * UART: 24MHz - * SMB: 24MHz - * EC: 8MHz - * JTAG: 24MHz - * USBPD: 8MHz - * USB: 48MHz(no support if PLL=24MHz) - * SSPI: 48MHz(24MHz if PLL=24MHz) - */ - /* PLL:24MHz, MCU:24MHz, Fnd(e-flash):24MHz */ - [PLL_24_MHZ] = {24000000, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0x2}, -#ifdef CONFIG_IT83XX_FLASH_CLOCK_48MHZ - /* PLL:48MHz, MCU:48MHz, Fnd:48MHz */ - [PLL_48_MHZ] = {48000000, 4, 0, 1, 0, 1, 0, 6, 1, 0, 0x5}, - /* PLL:96MHz, MCU:96MHz, Fnd:48MHz */ - [PLL_96_MHZ] = {96000000, 7, 1, 3, 1, 3, 1, 6, 3, 1, 0xb}, -#else - /* PLL:48MHz, MCU:48MHz, Fnd:24MHz */ - [PLL_48_MHZ] = {48000000, 4, 1, 1, 0, 1, 0, 2, 1, 0, 0x5}, - /* PLL:96MHz, MCU:96MHz, Fnd:32MHz */ - [PLL_96_MHZ] = {96000000, 7, 2, 3, 1, 3, 1, 4, 3, 1, 0xb}, -#endif -}; - -static uint8_t pll_div_fnd; -static uint8_t pll_div_ec; -static uint8_t pll_div_jtag; -static uint8_t pll_setting; - -void __ram_code clock_ec_pll_ctrl(enum ec_pll_ctrl mode) -{ - volatile uint8_t _pll_ctrl __unused; - - IT83XX_ECPM_PLLCTRL = mode; - /* - * for deep doze / sleep mode - * This load operation will ensure PLL setting is taken into - * control register before wait for interrupt instruction. - */ - _pll_ctrl = IT83XX_ECPM_PLLCTRL; - -#ifdef IT83XX_CHIP_FLASH_NO_DEEP_POWER_DOWN - /* - * WORKAROUND: this workaround is used to fix EC gets stuck in low power - * mode when WRST# is asserted. - * - * By default, flash will go into deep power down mode automatically - * when EC is in low power mode. But we got an issue on IT83202BX that - * flash won't be able to wake up correctly when WRST# is asserted - * under this condition. - * This issue might cause cold reset failure so we fix it. - * - * NOTE: this fix will increase power number about 40uA in low power - * mode. - */ - if (mode == EC_PLL_DOZE) - IT83XX_SMFI_SMECCS &= ~IT83XX_SMFI_MASK_HOSTWA; - else - /* - * Don't send deep power down mode command to flash when EC in - * low power mode. - */ - IT83XX_SMFI_SMECCS |= IT83XX_SMFI_MASK_HOSTWA; -#endif - /* - * barrier: ensure low power mode setting is taken into control - * register before standby instruction. - */ - data_serialization_barrier(); -} - -void __ram_code clock_pll_changed(void) -{ - IT83XX_GCTRL_SSCR &= ~BIT(0); - /* - * Update PLL settings. - * Writing data to this register doesn't change the - * PLL frequency immediately until the status is changed - * into wakeup from the sleep mode. - * The following code is intended to make the system - * enter sleep mode, and set up a HW timer to wakeup EC to - * complete PLL update. - */ - IT83XX_ECPM_PLLFREQR = pll_setting; - /* Pre-set FND clock frequency = PLL / 3 */ - IT83XX_ECPM_SCDCR0 = (2 << 4); - /* JTAG and EC */ - IT83XX_ECPM_SCDCR3 = (pll_div_jtag << 4) | pll_div_ec; - /* EC sleep after standby instruction */ - clock_ec_pll_ctrl(EC_PLL_SLEEP); - if (IS_ENABLED(CHIP_CORE_NDS32)) { - /* Global interrupt enable */ - asm volatile ("setgie.e"); - /* EC sleep */ - asm("standby wake_grant"); - /* Global interrupt disable */ - asm volatile ("setgie.d"); - } else if (IS_ENABLED(CHIP_CORE_RISCV)) { - /* Global interrupt enable */ - asm volatile ("csrsi mstatus, 0x8"); - /* EC sleep */ - asm("wfi"); - /* Global interrupt disable */ - asm volatile ("csrci mstatus, 0x8"); - } - /* New FND clock frequency */ - IT83XX_ECPM_SCDCR0 = (pll_div_fnd << 4); - /* EC doze after standby instruction */ - clock_ec_pll_ctrl(EC_PLL_DOZE); -} - -/* NOTE: Don't use this function in other place. */ -static void clock_set_pll(enum pll_freq_idx idx) -{ - int pll; - - pll_div_fnd = clock_pll_ctrl[idx].div_fnd; - pll_div_ec = clock_pll_ctrl[idx].div_ec; - pll_div_jtag = clock_pll_ctrl[idx].div_jtag; - pll_setting = clock_pll_ctrl[idx].pll_setting; - - /* Update PLL settings or not */ - if (((IT83XX_ECPM_PLLFREQR & 0xf) != pll_setting) || - ((IT83XX_ECPM_SCDCR0 & 0xf0) != (pll_div_fnd << 4)) || - ((IT83XX_ECPM_SCDCR3 & 0xf) != pll_div_ec)) { - /* Enable hw timer to wakeup EC from the sleep mode */ - ext_timer_ms(LOW_POWER_EXT_TIMER, EXT_PSR_32P768K_HZ, - 1, 1, 5, 1, 0); - task_clear_pending_irq(et_ctrl_regs[LOW_POWER_EXT_TIMER].irq); -#ifdef CONFIG_HOSTCMD_ESPI - /* - * Workaround for (b:70537592): - * We have to set chip select pin as input mode in order to - * change PLL. - */ - IT83XX_GPIO_GPCRM5 = (IT83XX_GPIO_GPCRM5 & ~0xc0) | BIT(7); -#ifdef IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED - /* - * On DX version, we have to disable eSPI pad before changing - * PLL sequence or sequence will fail if CS# pin is low. - */ - espi_enable_pad(0); -#endif -#endif - /* Update PLL settings. */ - clock_pll_changed(); -#ifdef CONFIG_HOSTCMD_ESPI -#ifdef IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED - /* Enable eSPI pad after changing PLL sequence. */ - espi_enable_pad(1); -#endif - /* (b:70537592) Change back to ESPI CS# function. */ - IT83XX_GPIO_GPCRM5 &= ~0xc0; -#endif - } - - /* Get new/current setting of PLL frequency */ - pll = pll_to_idx[IT83XX_ECPM_PLLFREQR & 0xf]; - /* USB and UART */ - IT83XX_ECPM_SCDCR1 = (clock_pll_ctrl[pll].div_usb << 4) | - clock_pll_ctrl[pll].div_uart; - /* SSPI and SMB */ - IT83XX_ECPM_SCDCR2 = (clock_pll_ctrl[pll].div_sspi << 4) | - clock_pll_ctrl[pll].div_smb; - /* USBPD and PWM */ - IT83XX_ECPM_SCDCR4 = (clock_pll_ctrl[pll].div_usbpd << 4) | - clock_pll_ctrl[pll].div_pwm; - /* Current PLL frequency */ - freq = clock_pll_ctrl[pll].pll_freq; -} - -void clock_init(void) -{ - uint32_t image_type = (uint32_t)clock_init; - - /* To change interrupt vector base if at RW image */ - if (image_type > CONFIG_RW_MEM_OFF) - /* Interrupt Vector Table Base Address, in 64k Byte unit */ - IT83XX_GCTRL_IVTBAR = (CONFIG_RW_MEM_OFF >> 16) & 0xFF; - -#if (PLL_CLOCK == 24000000) || \ - (PLL_CLOCK == 48000000) || \ - (PLL_CLOCK == 96000000) - /* Set PLL frequency */ - clock_set_pll(PLL_CLOCK / 24000000); -#else -#error "Support only for PLL clock speed of 24/48/96MHz." -#endif - /* - * The VCC power status is treated as power-on. - * The VCC supply of LPC and related functions (EC2I, - * KBC, SWUC, PMC, CIR, SSPI, UART, BRAM, and PECI). - * It means VCC (pin 11) should be logic high before using - * these functions, or firmware treats VCC logic high - * as following setting. - */ - IT83XX_GCTRL_RSTS = (IT83XX_GCTRL_RSTS & 0x3F) + 0x40; - -#if defined(IT83XX_ESPI_RESET_MODULE_BY_FW) && defined(CONFIG_HOSTCMD_ESPI) - /* - * Because we don't support eSPI HW reset function (b/111480168) on DX - * version, so we have to reset eSPI configurations during init to - * ensure Host and EC are synchronized (especially for the field of - * I/O mode) - */ - if (!system_jumped_to_this_image()) - espi_fw_reset_module(); -#endif - /* Turn off auto clock gating. */ - IT83XX_ECPM_AUTOCG = 0x00; - - /* Default doze mode */ - clock_ec_pll_ctrl(EC_PLL_DOZE); - - clock_module_disable(); - -#ifdef CONFIG_HOSTCMD_X86 - IT83XX_WUC_WUESR4 = BIT(2); - task_clear_pending_irq(IT83XX_IRQ_WKINTAD); - /* bit2, wake-up enable for LPC access */ - IT83XX_WUC_WUENR4 |= BIT(2); -#endif -} - -int clock_get_freq(void) -{ - return freq; -} - -/** - * Enable clock to specified peripheral - * - * @param offset Should be element of clock_gate_offsets enum. - * Bits 8-15 specify the ECPM offset of the specific clock reg. - * Bits 0-7 specify the mask for the clock register. - * @param mask Unused - * @param mode Unused - */ -void clock_enable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode) -{ - volatile uint8_t *reg = (volatile uint8_t *) - (IT83XX_ECPM_BASE + (offset >> 8)); - uint8_t reg_mask = offset & 0xff; - - /* - * Note: CGCTRL3R, bit 6, must always write 1, but since there is no - * offset argument that addresses this bit, then we are guaranteed - * that this line will write a 1 to that bit. - */ - *reg &= ~reg_mask; -} - -/** - * Disable clock to specified peripheral - * - * @param offset Should be element of clock_gate_offsets enum. - * Bits 8-15 specify the ECPM offset of the specific clock reg. - * Bits 0-7 specify the mask for the clock register. - * @param mask Unused - * @param mode Unused - */ -void clock_disable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode) -{ - volatile uint8_t *reg = (volatile uint8_t *) - (IT83XX_ECPM_BASE + (offset >> 8)); - uint8_t reg_mask = offset & 0xff; - uint8_t tmp_mask = 0; - - /* CGCTRL3R, bit 6, must always write a 1. */ - tmp_mask |= ((offset >> 8) == IT83XX_ECPM_CGCTRL3R_OFF) ? 0x40 : 0x00; - - *reg |= reg_mask | tmp_mask; -} - -#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; -} - -static void clock_event_timer_clock_change(enum ext_timer_clock_source clock, - uint32_t count) -{ - IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) &= ~BIT(0); - IT83XX_ETWD_ETXPSR(EVENT_EXT_TIMER) = clock; - IT83XX_ETWD_ETXCNTLR(EVENT_EXT_TIMER) = count; - IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) |= 0x3; -} - -static void clock_htimer_enable(void) -{ - uint32_t c; - - /* change event timer clock source to 32.768 KHz */ -#ifdef IT83XX_EXT_OBSERVATION_REG_READ_TWO_TIMES - c = TIMER_CNT_8M_32P768K(ext_observation_reg_read(EVENT_EXT_TIMER)); -#else - c = TIMER_CNT_8M_32P768K(IT83XX_ETWD_ETXCNTOR(EVENT_EXT_TIMER)); -#endif - clock_event_timer_clock_change(EXT_PSR_32P768K_HZ, c); -} - -static int clock_allow_low_power_idle(void) -{ - /* - * Avoiding using low frequency clock run the same count as awaken in - * sleep mode, so don't go to sleep mode before timer reload count. - */ - if (!(IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) & BIT(0))) - return 0; - - /* If timer interrupt status is set, don't go to sleep mode. */ - if (*et_ctrl_regs[EVENT_EXT_TIMER].isr & - et_ctrl_regs[EVENT_EXT_TIMER].mask) - return 0; - - /* - * If timer is less than 250us to expire, then we don't go to sleep - * mode. - */ -#ifdef IT83XX_EXT_OBSERVATION_REG_READ_TWO_TIMES - if (EVENT_TIMER_COUNT_TO_US(ext_observation_reg_read(EVENT_EXT_TIMER)) < -#else - if (EVENT_TIMER_COUNT_TO_US(IT83XX_ETWD_ETXCNTOR(EVENT_EXT_TIMER)) < -#endif - SLEEP_SET_HTIMER_DELAY_USEC) - return 0; - - /* - * We calculate 32bit free clock overflow counts for 64bit value, - * if clock almost reach overflow, we don't go to sleep mode for - * avoiding miss overflow count. - */ - sleep_mode_t0 = get_time(); - if ((sleep_mode_t0.le.lo > (0xffffffff - SLEEP_FTIMER_SKIP_USEC)) || - (sleep_mode_t0.le.lo < SLEEP_FTIMER_SKIP_USEC)) - return 0; - - /* If we are waked up by console, then keep awake at least 5s. */ - if (sleep_mode_t0.val < console_expire_time.val) - return 0; - - return 1; -} - -int clock_ec_wake_from_sleep(void) -{ - return ec_sleep; -} - -void __ram_code clock_cpu_standby(void) -{ - /* standby instruction */ - if (IS_ENABLED(CHIP_CORE_NDS32)) { - asm("standby wake_grant"); - } else if (IS_ENABLED(CHIP_CORE_RISCV)) { - if (!IS_ENABLED(IT83XX_RISCV_WAKEUP_CPU_WITHOUT_INT_ENABLED)) - /* - * we have to enable interrupts before - * standby instruction on IT83202 bx version. - */ - interrupt_enable(); - - asm("wfi"); - } -} - -void __enter_hibernate(uint32_t seconds, uint32_t microseconds) -{ - int i; - - /* disable all interrupts */ - interrupt_disable(); - for (i = 0; i < IT83XX_IRQ_COUNT; i++) { - chip_disable_irq(i); - chip_clear_pending_irq(i); - } - /* bit5: watchdog is disabled. */ - IT83XX_ETWD_ETWCTRL |= BIT(5); - - /* - * Setup GPIOs for hibernate. 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) { - /* - * Set reset flag in case board_hibernate_late() doesn't - * return. - */ - chip_save_reset_flags(EC_RESET_FLAG_HIBERNATE); - board_hibernate_late(); - } - - if (seconds || microseconds) { - /* At least 1 ms for hibernate. */ - uint64_t c = (seconds * 1000 + microseconds / 1000 + 1) * 1024; - - uint64divmod(&c, 1000); - /* enable a 56-bit timer and clock source is 1.024 KHz */ - ext_timer_stop(FREE_EXT_TIMER_L, 1); - ext_timer_stop(FREE_EXT_TIMER_H, 1); - IT83XX_ETWD_ETXPSR(FREE_EXT_TIMER_L) = EXT_PSR_1P024K_HZ; - IT83XX_ETWD_ETXPSR(FREE_EXT_TIMER_H) = EXT_PSR_1P024K_HZ; - IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_L) = c & 0xffffff; - IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) = (c >> 24) & 0xffffffff; - ext_timer_start(FREE_EXT_TIMER_H, 1); - ext_timer_start(FREE_EXT_TIMER_L, 0); - } - - if (IS_ENABLED(CONFIG_USB_PD_TCPM_ITE_ON_CHIP)) { - /* - * Disable active cc and pd modules and only left Rd_5.1k (Not - * Rd_DB) alive in hibernate for better power consumption. - */ - for (i = 0; i < CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT; i++) - it83xx_Rd_5_1K_only_for_hibernate(i); - } - - if (IS_ENABLED(CONFIG_ADC_VOLTAGE_COMPARATOR)) { - /* - * Disable all voltage comparator modules in hibernate - * for better power consumption. - */ - for (i = CHIP_VCMP0; i < CHIP_VCMP_COUNT; i++) - vcmp_enable(i, 0); - } - - for (i = 0; i < hibernate_wake_pins_used; ++i) - gpio_enable_interrupt(hibernate_wake_pins[i]); - - /* EC sleep */ - ec_sleep = 1; -#if defined(IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED) && \ -defined(CONFIG_HOSTCMD_ESPI) - /* Disable eSPI pad. */ - espi_enable_pad(0); -#endif - clock_ec_pll_ctrl(EC_PLL_SLEEP); - interrupt_enable(); - /* standby instruction */ - clock_cpu_standby(); - - /* we should never reach that point */ - __builtin_unreachable(); -} - -/* use data type int here not bool to get better instruction number. */ -static volatile int wait_interrupt_fired; -void clock_sleep_mode_wakeup_isr(void) -{ - uint32_t st_us, c; - - /* Clear flag on each interrupt. */ - if (IS_ENABLED(CHIP_CORE_RISCV)) - wait_interrupt_fired = 0; - - /* trigger a reboot if wake up EC from sleep mode (system hibernate) */ - if (clock_ec_wake_from_sleep()) { -#if defined(IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED) && \ -defined(CONFIG_HOSTCMD_ESPI) - /* - * Enable eSPI pad. - * We will not need to enable eSPI pad here if Dx is able to - * enable watchdog hardware reset function. But the function is - * failed (b:111264984), so the following system reset is - * software reset (PLL setting is not reset). - * We will not go into the change PLL sequence on reboot if PLL - * setting is the same, so the operation of enabling eSPI pad we - * added in clock_set_pll() will not be applied. - */ - espi_enable_pad(1); -#endif - system_reset(SYSTEM_RESET_HARD); - } - - if (IT83XX_ECPM_PLLCTRL == EC_PLL_DEEP_DOZE) { - clock_ec_pll_ctrl(EC_PLL_DOZE); - /* update free running timer */ - c = LOW_POWER_TIMER_MASK - - IT83XX_ETWD_ETXCNTOR(LOW_POWER_EXT_TIMER); - st_us = TIMER_32P768K_CNT_TO_US(c); - sleep_mode_t1.val = sleep_mode_t0.val + st_us; - __hw_clock_source_set(sleep_mode_t1.le.lo); - - /* reset event timer and clock source is 8 MHz */ - clock_event_timer_clock_change(EXT_PSR_8M_HZ, 0xffffffff); - task_clear_pending_irq(et_ctrl_regs[EVENT_EXT_TIMER].irq); - process_timers(0); -#ifdef CONFIG_HOSTCMD_X86 - /* disable lpc access wui */ - task_disable_irq(IT83XX_IRQ_WKINTAD); - IT83XX_WUC_WUESR4 = BIT(2); - task_clear_pending_irq(IT83XX_IRQ_WKINTAD); -#endif - /* disable uart wui */ - uart_exit_dsleep(); - /* Record time spent in sleep. */ - total_idle_sleep_time_us += st_us; - } -} - -void __keep __idle_init(void) -{ - console_expire_time.val = get_time().val + CONSOLE_IN_USE_ON_BOOT_TIME; - /* init hw timer and clock source is 32.768 KHz */ - ext_timer_ms(LOW_POWER_EXT_TIMER, EXT_PSR_32P768K_HZ, 1, 0, - 0xffffffff, 1, 1); - - /* - * Print when the idle task starts. This is the lowest priority task, - * so this only starts once all other tasks have gotten a chance to do - * their task inits and have gone to sleep. - */ - CPRINTS("low power idle task started"); -} - -/** - * Low power idle task. Executed when no tasks are ready to be scheduled. - */ -void __ram_code __idle(void) -{ - /* - * There is not enough space from ram code section to cache entire idle - * function, hence pull initialization function out of the section. - */ - __idle_init(); - - while (1) { - /* Disable interrupts */ - interrupt_disable(); - /* Check if the EC can enter deep doze mode or not */ - if (DEEP_SLEEP_ALLOWED && clock_allow_low_power_idle()) { - /* reset low power mode hw timer */ - IT83XX_ETWD_ETXCTRL(LOW_POWER_EXT_TIMER) |= BIT(1); - sleep_mode_t0 = get_time(); -#ifdef CONFIG_HOSTCMD_X86 - /* enable lpc access wui */ - task_enable_irq(IT83XX_IRQ_WKINTAD); -#endif - /* enable uart wui */ - uart_enter_dsleep(); - /* enable hw timer for deep doze / sleep mode wake-up */ - clock_htimer_enable(); - /* deep doze mode */ - clock_ec_pll_ctrl(EC_PLL_DEEP_DOZE); - idle_sleep_cnt++; - } else { - /* doze mode */ - clock_ec_pll_ctrl(EC_PLL_DOZE); - idle_doze_cnt++; - } - /* Set flag before entering low power mode. */ - if (IS_ENABLED(CHIP_CORE_RISCV)) - wait_interrupt_fired = 1; - clock_cpu_standby(); - interrupt_enable(); - /* - * Sometimes wfi instruction may fail due to CPU's MTIP@mip - * register is non-zero. - * If the wait_interrupt_fired flag is true at this point, - * it means that EC waked-up by the above issue not an - * interrupt. Hence we loop running wfi instruction here until - * wfi success. - */ - while (IS_ENABLED(CHIP_CORE_RISCV) && wait_interrupt_fired) - clock_cpu_standby(); - } -} -#endif /* CONFIG_LOW_POWER_IDLE */ - -#ifdef CONFIG_LOW_POWER_IDLE -#ifdef CONFIG_CMD_IDLE_STATS -/** - * Print low power idle statistics - */ -static int command_idle_stats(int argc, char **argv) -{ - timestamp_t ts = get_time(); - - ccprintf("Num idle calls that doze: %d\n", idle_doze_cnt); - ccprintf("Num idle calls that sleep: %d\n", idle_sleep_cnt); - - ccprintf("Total Time spent in sleep(sec): %.6lld(s)\n", - total_idle_sleep_time_us); - ccprintf("Total time on: %.6llds\n\n", ts.val); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats, - "", - "Print last idle stats"); - -#endif /* CONFIG_CMD_IDLE_STATS */ -#endif /* CONFIG_LOW_POWER_IDLE */ diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h deleted file mode 100644 index 2f552c794a..0000000000 --- a/chip/it83xx/config_chip.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_CONFIG_CHIP_H -#define __CROS_EC_CONFIG_CHIP_H - -#if defined(CHIP_FAMILY_IT8320) /* N8 core */ -#include "config_chip_it8320.h" -#elif defined(CHIP_FAMILY_IT8XXX2) /* RISCV core */ -#include "config_chip_it8xxx2.h" -#else -#error "Unsupported chip family!" -#endif - -/* Number of IRQ vectors on the IVIC */ -#define CONFIG_IRQ_COUNT IT83XX_IRQ_COUNT - -/* Interval between HOOK_TICK notifications */ -#define HOOK_TICK_INTERVAL_MS 500 -#define HOOK_TICK_INTERVAL (HOOK_TICK_INTERVAL_MS * MSEC) - -/* Default PLL frequency. */ -#define PLL_CLOCK 48000000 - -/* Number of I2C ports */ -#define I2C_PORT_COUNT 6 - -/* I2C ports on chip - * IT83xx - There are three i2c standard ports. - * There are three i2c enhanced ports. - */ -#define I2C_STANDARD_PORT_COUNT 3 -#define I2C_ENHANCED_PORT_COUNT 3 - -/* System stack size */ -#define CONFIG_STACK_SIZE 1024 - -/* non-standard task stack sizes */ -#define SMALLER_TASK_STACK_SIZE (384 + CHIP_EXTRA_STACK_SPACE) -#define IDLE_TASK_STACK_SIZE (512 + CHIP_EXTRA_STACK_SPACE) -#define LARGER_TASK_STACK_SIZE (768 + CHIP_EXTRA_STACK_SPACE) -#define VENTI_TASK_STACK_SIZE (896 + CHIP_EXTRA_STACK_SPACE) -#define ULTRA_TASK_STACK_SIZE (1056 + CHIP_EXTRA_STACK_SPACE) -#define TRENTA_TASK_STACK_SIZE (1184 + CHIP_EXTRA_STACK_SPACE) - -/* Default task stack size */ -#define TASK_STACK_SIZE (512 + CHIP_EXTRA_STACK_SPACE) - -#ifdef IT83XX_CHIP_FLASH_IS_KGD -#define CONFIG_FLASH_BANK_SIZE 0x00001000 /* protect bank size */ -#define CONFIG_FLASH_ERASE_SIZE 0x00001000 /* erase bank size */ -#else -#define CONFIG_FLASH_BANK_SIZE 0x00000800 /* protect bank size */ -#define CONFIG_FLASH_ERASE_SIZE 0x00000400 /* erase bank size */ -#endif -#define CONFIG_FLASH_WRITE_SIZE 0x00000004 /* minimum write size */ - -/* - * This is the block size of the ILM on the it83xx chip. - * The ILM for static code cache, CPU fetch instruction from - * ILM(ILM -> CPU)instead of flash(flash -> IMMU -> CPU) if enabled. - */ -#define IT83XX_ILM_BLOCK_SIZE 0x00001000 - -#ifdef IT83XX_CHIP_FLASH_IS_KGD -/* - * One page program instruction allows maximum 256 bytes (a page) of data - * to be programmed. - */ -#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 -#else -/* - * The AAI program instruction allows continue write flash - * until write disable instruction. - */ -#define CONFIG_FLASH_WRITE_IDEAL_SIZE CONFIG_FLASH_ERASE_SIZE -#endif - -/****************************************************************************/ -/* Define our flash layout. */ - -/* Memory-mapped internal flash */ -#define CONFIG_INTERNAL_STORAGE -#define CONFIG_MAPPED_STORAGE - -/* Program is run directly from storage */ -#define CONFIG_MAPPED_STORAGE_BASE CONFIG_PROGRAM_MEMORY_BASE - -/* Compute the rest of the flash params from these */ -#include "config_std_internal_flash.h" - -/****************************************************************************/ -/* H2RAM memory mapping */ - -/* - * Only it839x series and IT838x DX support mapping LPC I/O cycle 800h ~ 9FFh - * to 0x8D800h ~ 0x8D9FFh of DLM13. - * - * IT8xxx2 series support mapping LPC/eSPI I/O cycle 800h ~ 9FFh - * to 0x80081800 ~ 0x800819FF of DLM1. - */ -#define CONFIG_H2RAM_BASE (CHIP_H2RAM_BASE) -#define CONFIG_H2RAM_SIZE 0x00001000 -#define CONFIG_H2RAM_HOST_LPC_IO_BASE 0x800 - -/****************************************************************************/ -/* Customize the build */ - -#define CONFIG_FW_RESET_VECTOR - -/* Optional features present on this chip */ -#define CHIP_FAMILY_IT83XX -#define CONFIG_ADC -#define CONFIG_SWITCH - -/* Chip needs to do custom pre-init */ -#define CONFIG_CHIP_PRE_INIT - -#define GPIO_PIN(port, index) GPIO_##port, BIT(index) -#define GPIO_PIN_MASK(p, m) .port = GPIO_##p, .mask = (m) - -#define __RAM_CODE_SECTION_NAME ".ram_code" - -#endif /* __CROS_EC_CONFIG_CHIP_H */ diff --git a/chip/it83xx/config_chip_it8320.h b/chip/it83xx/config_chip_it8320.h deleted file mode 100644 index 53f4a1cbd3..0000000000 --- a/chip/it83xx/config_chip_it8320.h +++ /dev/null @@ -1,104 +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_CONFIG_CHIP_IT8320_H -#define __CROS_EC_CONFIG_CHIP_IT8320_H - -/* CPU core BFD configuration */ -#include "core/nds32/config_core.h" - -/* N8 core */ -#define CHIP_CORE_NDS32 -/* The base address of EC interrupt controller registers. */ -#define CHIP_EC_INTC_BASE 0x00F01100 - -/****************************************************************************/ -/* Memory mapping */ - -#define CHIP_H2RAM_BASE 0x0008D000 /* 0x0008D000~0x0008DFFF */ -#define CHIP_RAMCODE_BASE 0x0008E000 /* 0x0008E000~0x0008EFFF */ -#define CHIP_EXTRA_STACK_SPACE 0 - -#define CONFIG_RAM_BASE 0x00080000 -#define CONFIG_RAM_SIZE 0x0000C000 - -#define CONFIG_PROGRAM_MEMORY_BASE 0x00000000 - -/****************************************************************************/ -/* Chip IT8320 is used with IT83XX TCPM driver */ -#define CONFIG_USB_PD_TCPM_DRIVER_IT83XX - -#if defined(CHIP_VARIANT_IT8320BX) -/* This is the physical size of the flash on the chip. We'll reserve one bank - * in order to emulate per-bank write-protection UNTIL REBOOT. The hardware - * doesn't support a write-protect pin, and if we make the write-protection - * permanent, it can't be undone easily enough to support RMA. - */ -#define CONFIG_FLASH_SIZE_BYTES 0x00040000 -/* For IT8320BX, we have to reload cc parameters after ec softreset. */ -#define IT83XX_USBPD_CC_PARAMETER_RELOAD -/* - * The voltage detector of CC1 and CC2 is enabled/disabled by different bit - * of the control register (bit1 and bit5 at register IT83XX_USBPD_CCCSR). - */ -#define IT83XX_USBPD_CC_VOLTAGE_DETECTOR_INDEPENDENT -/* Chip IT8320BX actually has TCPC physical port count */ -#define IT83XX_USBPD_PHY_PORT_COUNT 2 -/* For IT8320BX, we have to write 0xff to clear pending bit.*/ -#define IT83XX_ESPI_VWCTRL1_WRITE_FF_CLEAR -/* For IT8320BX, we have to read observation register of external timer two - * times to get correct time. - */ -#define IT83XX_EXT_OBSERVATION_REG_READ_TWO_TIMES -#elif defined(CHIP_VARIANT_IT8320DX) -#define CONFIG_FLASH_SIZE_BYTES 0x00080000 -#define CONFIG_IT83XX_FLASH_CLOCK_48MHZ -/* - * Disable eSPI pad, then PLL change - * (include EC clock frequency) is succeed even CS# is low. - */ -#define IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED -/* - * The peripheral frequency is adjustable - * (bit[2-0] at register IT83XX_ESPI_GCAC1) - */ -#define IT83XX_ESPI_PERIPHERAL_MAX_FREQ_CONFIGURABLE -/* - * TODO(b/111480168): eSPI HW reset can't be used because the DMA address - * gets set incorrectly resulting in a memory access exception. - */ -#define IT83XX_ESPI_RESET_MODULE_BY_FW -/* Watchdog reset supports hardware reset. */ -/* TODO(b/111264984): watchdog hardware reset function failed. */ -#undef IT83XX_ETWD_HW_RESET_SUPPORT -/* - * (b/112452221): - * Floating-point multiplication single-precision is failed on DX version, - * so we use the formula "A/(1/B)" to replace a multiplication operation - * (A*B = A/(1/B)). - */ -#define IT83XX_FPU_MUL_BY_DIV -/* - * More GPIOs can be set as 1.8v input. - * Please refer to gpio_1p8v_sel[] for 1.8v GPIOs. - */ -#define IT83XX_GPIO_1P8V_PIN_EXTENDED -/* All GPIOs support interrupt on rising, falling, and either edge. */ -#define IT83XX_GPIO_INT_FLEXIBLE -/* Enable FRS detection interrupt. */ -#define IT83XX_INTC_FAST_SWAP_SUPPORT -/* Enable interrupts of group 21 and 22. */ -#define IT83XX_INTC_GROUP_21_22_SUPPORT -/* Enable detect type-c plug in and out interrupt. */ -#define IT83XX_INTC_PLUG_IN_OUT_SUPPORT -/* Chip Dx transmit status bit of PD register is different from Bx. */ -#define IT83XX_PD_TX_ERROR_STATUS_BIT5 -/* Chip IT8320DX actually has TCPC physical port count */ -#define IT83XX_USBPD_PHY_PORT_COUNT 2 -#else -#error "Unsupported chip variant!" -#endif - -#endif /* __CROS_EC_CONFIG_CHIP_IT8320_H */ diff --git a/chip/it83xx/config_chip_it8xxx2.h b/chip/it83xx/config_chip_it8xxx2.h deleted file mode 100644 index a5b4096c8b..0000000000 --- a/chip/it83xx/config_chip_it8xxx2.h +++ /dev/null @@ -1,159 +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_CONFIG_CHIP_IT8XXX2_H -#define __CROS_EC_CONFIG_CHIP_IT8XXX2_H - -/* CPU core BFD configuration */ -#include "core/riscv-rv32i/config_core.h" - -/* RISCV core */ -#define CHIP_CORE_RISCV -#define CHIP_ILM_DLM_ORDER -/* The base address of EC interrupt controller registers. */ -#define CHIP_EC_INTC_BASE 0x00F03F00 -#define CONFIG_IT83XX_FLASH_CLOCK_48MHZ -/* - * ILM/DLM size register. - * bit[3-0] ILM size: - * 7: 512K byte (default setting), 8: 1M byte - */ -#define IT83XX_GCTRL_EIDSR 0xf02031 - -/****************************************************************************/ -/* Memory mapping */ - -#define CHIP_ILM_BASE 0x80000000 -#define CHIP_EXTRA_STACK_SPACE 128 -/* We reserve 12KB space for ramcode, h2ram, and immu sections. */ -#define CHIP_RAM_SPACE_RESERVED 0x3000 -#define CONFIG_PROGRAM_MEMORY_BASE (CHIP_ILM_BASE) - -/****************************************************************************/ -/* Chip IT83202 is used with IT8XXX2 TCPM driver */ -#define CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 - -#if defined(CHIP_VARIANT_IT83202BX) -/* TODO(b/133460224): enable properly chip config option. */ -#define CONFIG_FLASH_SIZE_BYTES 0x00080000 -#define CONFIG_RAM_BASE 0x80080000 -#define CONFIG_RAM_SIZE 0x00010000 - -/* Embedded flash is KGD */ -#define IT83XX_CHIP_FLASH_IS_KGD -/* Don't let internal flash go into deep power down mode. */ -#define IT83XX_CHIP_FLASH_NO_DEEP_POWER_DOWN -/* chip id is 3 bytes */ -#define IT83XX_CHIP_ID_3BYTES -/* - * The bit19 of ram code base address is controlled by bit7 of register SCARxH - * instead of bit3. - */ -#define IT83XX_DAM_ADDR_BIT19_AT_REG_SCARXH_BIT7 -/* - * Disable eSPI pad, then PLL change - * (include EC clock frequency) is succeed even CS# is low. - */ -#define IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED -/* - * The peripheral frequency is adjustable - * (bit[2-0] at register IT83XX_ESPI_GCAC1) - */ -#define IT83XX_ESPI_PERIPHERAL_MAX_FREQ_CONFIGURABLE -/* Watchdog reset supports hardware reset. */ -#define IT83XX_ETWD_HW_RESET_SUPPORT -/* - * More GPIOs can be set as 1.8v input. - * Please refer to gpio_1p8v_sel[] for 1.8v GPIOs. - */ -#define IT83XX_GPIO_1P8V_PIN_EXTENDED -/* All GPIOs support interrupt on rising, falling, and either edge. */ -#define IT83XX_GPIO_INT_FLEXIBLE -/* Remap host I/O cycles to base address of H2RAM section. */ -#define IT83XX_H2RAM_REMAPPING -/* Enable FRS detection interrupt. */ -#define IT83XX_INTC_FAST_SWAP_SUPPORT -/* Enable detect type-c plug in and out interrupt. */ -#define IT83XX_INTC_PLUG_IN_OUT_SUPPORT -/* Chip IT83202BX actually has TCPC physical port count. */ -#define IT83XX_USBPD_PHY_PORT_COUNT 3 -#elif defined(CHIP_VARIANT_IT81302AX_1024) \ -|| defined(CHIP_VARIANT_IT81202AX_1024) \ -|| defined(CHIP_VARIANT_IT81302BX_1024) \ -|| defined(CHIP_VARIANT_IT81202BX_1024) -#define CONFIG_FLASH_SIZE_BYTES 0x00100000 -#define CONFIG_RAM_BASE 0x80100000 -#define CONFIG_RAM_SIZE 0x0000f000 - -/* Embedded flash is KGD */ -#define IT83XX_CHIP_FLASH_IS_KGD -/* Set ILM (instruction local memory) size up to 1M bytes */ -#define IT83XX_CHIP_FLASH_SIZE_1MB -/* chip id is 3 bytes */ -#define IT83XX_CHIP_ID_3BYTES -/* - * The bit19 of ram code base address is controlled by bit7 of register SCARxH - * instead of bit3. - */ -#define IT83XX_DAM_ADDR_BIT19_AT_REG_SCARXH_BIT7 -/* - * Disable eSPI pad, then PLL change - * (include EC clock frequency) is succeed even CS# is low. - */ -#define IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED -/* - * The peripheral frequency is adjustable - * (bit[2-0] at register IT83XX_ESPI_GCAC1) - */ -#define IT83XX_ESPI_PERIPHERAL_MAX_FREQ_CONFIGURABLE -/* Watchdog reset supports hardware reset. */ -#define IT83XX_ETWD_HW_RESET_SUPPORT -/* - * More GPIOs can be set as 1.8v input. - * Please refer to gpio_1p8v_sel[] for 1.8v GPIOs. - */ -#define IT83XX_GPIO_1P8V_PIN_EXTENDED -#if defined(CHIP_VARIANT_IT81202AX_1024) || defined(CHIP_VARIANT_IT81202BX_1024) -/* Pins of group K and L are set as internal pull-down at initialization. */ -#define IT83XX_GPIO_GROUP_K_L_DEFAULT_PULL_DOWN -#endif -/* GPIOH7 is set as output low at initialization. */ -#define IT83XX_GPIO_H7_DEFAULT_OUTPUT_LOW -/* All GPIOs support interrupt on rising, falling, and either edge. */ -#define IT83XX_GPIO_INT_FLEXIBLE -/* Remap host I/O cycles to base address of H2RAM section. */ -#define IT83XX_H2RAM_REMAPPING -/* Enable FRS detection interrupt. */ -#define IT83XX_INTC_FAST_SWAP_SUPPORT -/* Enable detect type-c plug in and out interrupt. */ -#define IT83XX_INTC_PLUG_IN_OUT_SUPPORT -/* Wake up CPU from low power mode even if interrupts are disabled */ -#define IT83XX_RISCV_WAKEUP_CPU_WITHOUT_INT_ENABLED -/* Individual setting CC1 and CC2 resistance. */ -#define IT83XX_USBPD_CC1_CC2_RESISTANCE_SEPARATE -/* Chip actually has TCPC physical port count. */ -#define IT83XX_USBPD_PHY_PORT_COUNT 2 -#else -#error "Unsupported chip variant!" -#endif - -#define CHIP_RAMCODE_ILM0 (CONFIG_RAM_BASE + 0) /* base+0000h~base+0FFF */ -#define CHIP_H2RAM_BASE (CONFIG_RAM_BASE + 0x1000) /* base+1000h~base+1FFF */ -#define CHIP_RAMCODE_BASE (CONFIG_RAM_BASE + 0x2000) /* base+2000h~base+2FFF */ - -#ifdef BASEBOARD_KUKUI -/* - * Reserved 0x80000~0xfffff 512kb on flash for saving EC logs (8kb space is - * enough to save the logs). This configuration reduces EC FW binary size to - * 512kb. With this config, we still have 4x kb space on RO and 6x kb space on - * RW. - */ -#define CHIP_FLASH_PRESERVE_LOGS_BASE 0x80000 -#define CHIP_FLASH_PRESERVE_LOGS_SIZE 0x2000 -#undef CONFIG_FLASH_SIZE_BYTES -#define CONFIG_FLASH_SIZE_BYTES CHIP_FLASH_PRESERVE_LOGS_BASE -#endif - -#endif /* __CROS_EC_CONFIG_CHIP_IT8XXX2_H */ diff --git a/chip/it83xx/dac.c b/chip/it83xx/dac.c deleted file mode 100644 index 695d1cbc68..0000000000 --- a/chip/it83xx/dac.c +++ /dev/null @@ -1,90 +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. - */ - -/* IT83xx DAC module for Chrome EC */ - -#include "console.h" -#include "dac_chip.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "util.h" - -/* DAC module enable */ -void dac_enable_channel(enum chip_dac_channel ch) -{ - IT83XX_DAC_DACPDREG &= ~IT83XX_DAC_POWDN(ch); -} - -/* DAC module disable */ -void dac_disable_channel(enum chip_dac_channel ch) -{ - IT83XX_DAC_DACPDREG |= IT83XX_DAC_POWDN(ch); -} - -/* Set DAC output voltage */ -void dac_set_output_voltage(enum chip_dac_channel ch, int mv) -{ - IT83XX_DAC_DACDAT(ch) = mv * DAC_RAW_DATA / DAC_AVCC; -} - -/* Get DAC output voltage */ -int dac_get_output_voltage(enum chip_dac_channel ch) -{ - return IT83XX_DAC_DACDAT(ch) * DAC_AVCC / DAC_RAW_DATA; -} - -/* DAC module Initialization */ -static void dac_init(void) -{ - /* Configure GPIOs */ - gpio_config_module(MODULE_DAC, 1); -} -DECLARE_HOOK(HOOK_INIT, dac_init, HOOK_PRIO_INIT_DAC); - -static int command_dac(int argc, char **argv) -{ - char *e; - int ch, mv, rv; - - if (argc < 2) - return EC_ERROR_PARAM_COUNT; - - ch = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - if (ch < 2 || ch > 5) { - ccprintf("ch%d is not supported\n", ch); - return EC_ERROR_PARAM1; - } - - if (argc == 2) { - if (!(IT83XX_DAC_DACPDREG & IT83XX_DAC_POWDN(ch))) { - /* Get DAC output voltage */ - rv = dac_get_output_voltage(ch); - ccprintf("DAC ch%d VOLT=%dmV\n", ch, rv); - } else - ccprintf("The DAC ch%d is powered down.\n", ch); - } else { - /* - * DAC data register raw data - * 0 ~ 0xFF(8-bit) = voltage 0 ~ 3300mV - */ - mv = strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - if (mv) { - /* Set DAC output voltage */ - dac_set_output_voltage(ch, mv); - dac_enable_channel(ch); - } else - dac_disable_channel(ch); - } - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(dac, command_dac, - "[ch2-5] [0-3300mV]", - "Enable or disable(0mV) DAC output voltage."); diff --git a/chip/it83xx/dac_chip.h b/chip/it83xx/dac_chip.h deleted file mode 100644 index fa50769c85..0000000000 --- a/chip/it83xx/dac_chip.h +++ /dev/null @@ -1,58 +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. - */ - -/* IT83xx DAC module for Chrome EC */ - -#ifndef __CROS_EC_DAC_CHIP_H -#define __CROS_EC_DAC_CHIP_H - -#define DAC_AVCC 3300 -/* - * Each channel generates an output ranging - * from 0V to AVCC with 8-bit resolution. - */ -#define DAC_RAW_DATA (BIT(8) - 1) - -/* List of DAC channels. */ -enum chip_dac_channel { - CHIP_DAC_CH2 = 2, - CHIP_DAC_CH3, - CHIP_DAC_CH4, - CHIP_DAC_CH5, -}; - -/** - * DAC module enable. - * - * @param ch Channel to enable. - */ -void dac_enable_channel(enum chip_dac_channel ch); - -/** - * DAC module disable. - * - * @param ch Channel to disable. - */ -void dac_disable_channel(enum chip_dac_channel ch); - -/** - * Set DAC output voltage. - * - * @param ch Channel to set. - * @param mv Setting ch output voltage. - */ -void dac_set_output_voltage(enum chip_dac_channel ch, int mv); - -/** - * Get DAC output voltage. - * - * @param ch Channel to get. - * - * @return Getting ch output voltage. - */ -int dac_get_output_voltage(enum chip_dac_channel ch); - -#endif /* __CROS_EC_DAC_CHIP_H */ - diff --git a/chip/it83xx/ec2i.c b/chip/it83xx/ec2i.c deleted file mode 100644 index be02a8f813..0000000000 --- a/chip/it83xx/ec2i.c +++ /dev/null @@ -1,312 +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. - */ - -/* EC2I control module for IT83xx. */ - -#include "common.h" -#include "console.h" -#include "ec2i_chip.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -static const struct ec2i_t keyboard_settings[] = { - /* Select logical device 06h(keyboard) */ - {HOST_INDEX_LDN, LDN_KBC_KEYBOARD}, - /* Set IRQ=01h for logical device */ - {HOST_INDEX_IRQNUMX, 0x01}, - /* Configure IRQTP for KBC. */ -#ifdef CONFIG_HOSTCMD_ESPI - /* - * Interrupt request type select (IRQTP) for KBC. - * bit 1, 0: IRQ request is buffered and applied to SERIRQ - * 1: IRQ request is inverted before being applied to SERIRQ - * bit 0, 0: Edge triggered mode - * 1: Level triggered mode - * - * SERIRQ# is by default deasserted level high. However, when using - * eSPI, SERIRQ# is routed over virtual wire as interrupt event. As - * per eSPI base spec (doc#327432), all virtual wire interrupt events - * are deasserted level low. Thus, it is necessary to configure this - * interrupt as inverted. ITE hardware takes care of routing the SERIRQ# - * signal appropriately over eSPI / LPC depending upon the selected - * mode. - * - * Additionally, this interrupt is configured as edge-triggered on the - * host side. So, match the trigger mode on the EC side as well. - */ - {HOST_INDEX_IRQTP, 0x02}, -#endif - /* Enable logical device */ - {HOST_INDEX_LDA, 0x01}, -}; - -#ifdef CONFIG_IT83XX_ENABLE_MOUSE_DEVICE -static const struct ec2i_t mouse_settings[] = { - /* Select logical device 05h(mouse) */ - {HOST_INDEX_LDN, LDN_KBC_MOUSE}, - /* Set IRQ=0Ch for logical device */ - {HOST_INDEX_IRQNUMX, 0x0C}, - /* Enable logical device */ - {HOST_INDEX_LDA, 0x01}, -}; -#endif - -static const struct ec2i_t pm1_settings[] = { - /* Select logical device 11h(PM1 ACPI) */ - {HOST_INDEX_LDN, LDN_PMC1}, - /* Set IRQ=00h for logical device */ - {HOST_INDEX_IRQNUMX, 0x00}, - /* Enable logical device */ - {HOST_INDEX_LDA, 0x01}, -}; - -static const struct ec2i_t pm2_settings[] = { - /* Select logical device 12h(PM2) */ - {HOST_INDEX_LDN, LDN_PMC2}, - /* I/O Port Base Address 200h/204h */ - {HOST_INDEX_IOBAD0_MSB, 0x02}, - {HOST_INDEX_IOBAD0_LSB, 0x00}, - {HOST_INDEX_IOBAD1_MSB, 0x02}, - {HOST_INDEX_IOBAD1_LSB, 0x04}, - /* Set IRQ=00h for logical device */ - {HOST_INDEX_IRQNUMX, 0x00}, - /* Enable logical device */ - {HOST_INDEX_LDA, 0x01}, -}; - -static const struct ec2i_t smfi_settings[] = { - /* Select logical device 0Fh(SMFI) */ - {HOST_INDEX_LDN, LDN_SMFI}, - /* H2RAM LPC I/O cycle Dxxx */ - {HOST_INDEX_DSLDC6, 0x00}, - /* Enable H2RAM LPC I/O cycle */ - {HOST_INDEX_DSLDC7, 0x01}, - /* Enable logical device */ - {HOST_INDEX_LDA, 0x01}, -}; - -/* - * PM3 is enabled and base address is set to 80h so that we are able to get an - * interrupt when host outputs data to port 80. - */ -static const struct ec2i_t pm3_settings[] = { - /* Select logical device 17h(PM3) */ - {HOST_INDEX_LDN, LDN_PMC3}, - /* I/O Port Base Address 80h */ - {HOST_INDEX_IOBAD0_MSB, 0x00}, - {HOST_INDEX_IOBAD0_LSB, 0x80}, - {HOST_INDEX_IOBAD1_MSB, 0x00}, - {HOST_INDEX_IOBAD1_LSB, 0x00}, - /* Set IRQ=00h for logical device */ - {HOST_INDEX_IRQNUMX, 0x00}, - /* Enable logical device */ - {HOST_INDEX_LDA, 0x01}, -}; - -/* - * This logical device is not enabled, however P80L* settings need to be - * performed on this logical device to ensure that port80 BRAM index is - * initialized correctly. - */ -static const struct ec2i_t rtct_settings[] = { - /* Select logical device 10h(RTCT) */ - {HOST_INDEX_LDN, LDN_RTCT}, - /* P80L Begin Index */ - {HOST_INDEX_DSLDC4, P80L_P80LB}, - /* P80L End Index */ - {HOST_INDEX_DSLDC5, P80L_P80LE}, - /* P80L Current Index */ - {HOST_INDEX_DSLDC6, P80L_P80LC}, -}; - -#ifdef CONFIG_UART_HOST -static const struct ec2i_t uart2_settings[] = { - /* Select logical device 2h(UART2) */ - {HOST_INDEX_LDN, LDN_UART2}, - /* - * I/O port base address is 2F8h. - * Host can use LPC I/O port 0x2F8 ~ 0x2FF to access UART2. - * See specification 7.24.4 for more detial. - */ - {HOST_INDEX_IOBAD0_MSB, 0x02}, - {HOST_INDEX_IOBAD0_LSB, 0xF8}, - /* IRQ number is 3 */ - {HOST_INDEX_IRQNUMX, 0x03}, - /* - * Interrupt Request Type Select - * bit1, 0: IRQ request is buffered and applied to SERIRQ. - * 1: IRQ request is inverted before being applied to SERIRQ. - * bit0, 0: Edge triggered mode. - * 1: Level triggered mode. - */ - {HOST_INDEX_IRQTP, 0x02}, - /* Enable logical device */ - {HOST_INDEX_LDA, 0x01}, -}; -#endif - -/* EC2I access index/data port */ -enum ec2i_access { - /* index port */ - EC2I_ACCESS_INDEX = 0, - /* data port */ - EC2I_ACCESS_DATA = 1, -}; - -enum ec2i_status_mask { - /* 1: EC read-access is still processing. */ - EC2I_STATUS_CRIB = BIT(1), - /* 1: EC write-access is still processing with IHD register. */ - EC2I_STATUS_CWIB = BIT(2), - EC2I_STATUS_ALL = (EC2I_STATUS_CRIB | EC2I_STATUS_CWIB), -}; - -static int ec2i_wait_status_bit_cleared(enum ec2i_status_mask mask) -{ - /* delay ~15.25us */ - IT83XX_GCTRL_WNCKR = 0; - - return (IT83XX_EC2I_IBCTL & mask); -} - -static enum ec2i_message ec2i_write_pnpcfg(enum ec2i_access sel, uint8_t data) -{ - int rv = EC_ERROR_UNKNOWN; - - /* bit1 : VCC power on */ - if (IT83XX_SWUC_SWCTL1 & BIT(1)) { - /* - * Wait that both CRIB and CWIB bits in IBCTL register - * are cleared. - */ - rv = ec2i_wait_status_bit_cleared(EC2I_STATUS_ALL); - if (!rv) { - /* Set indirect host I/O offset. */ - IT83XX_EC2I_IHIOA = sel; - /* Write the data to IHD register */ - IT83XX_EC2I_IHD = data; - /* Enable EC access to the PNPCFG registers */ - IT83XX_EC2I_IBMAE |= BIT(0); - /* bit0: EC to I-Bus access enabled. */ - IT83XX_EC2I_IBCTL |= BIT(0); - /* Wait the CWIB bit in IBCTL cleared. */ - rv = ec2i_wait_status_bit_cleared(EC2I_STATUS_CWIB); - /* Disable EC access to the PNPCFG registers. */ - IT83XX_EC2I_IBMAE &= ~BIT(0); - /* Disable EC to I-Bus access. */ - IT83XX_EC2I_IBCTL &= ~BIT(0); - } - } - - return rv ? EC2I_WRITE_ERROR : EC2I_WRITE_SUCCESS; -} - -static enum ec2i_message ec2i_read_pnpcfg(enum ec2i_access sel) -{ - int rv = EC_ERROR_UNKNOWN; - uint8_t ihd = 0; - - /* bit1 : VCC power on */ - if (IT83XX_SWUC_SWCTL1 & BIT(1)) { - /* - * Wait that both CRIB and CWIB bits in IBCTL register - * are cleared. - */ - rv = ec2i_wait_status_bit_cleared(EC2I_STATUS_ALL); - if (!rv) { - /* Set indirect host I/O offset. */ - IT83XX_EC2I_IHIOA = sel; - /* Enable EC access to the PNPCFG registers */ - IT83XX_EC2I_IBMAE |= BIT(0); - /* bit1: a read-action */ - IT83XX_EC2I_IBCTL |= BIT(1); - /* bit0: EC to I-Bus access enabled. */ - IT83XX_EC2I_IBCTL |= BIT(0); - /* Wait the CRIB bit in IBCTL cleared. */ - rv = ec2i_wait_status_bit_cleared(EC2I_STATUS_CRIB); - /* Read the data from IHD register */ - ihd = IT83XX_EC2I_IHD; - /* Disable EC access to the PNPCFG registers. */ - IT83XX_EC2I_IBMAE &= ~BIT(0); - /* Disable EC to I-Bus access. */ - IT83XX_EC2I_IBCTL &= ~BIT(0); - } - } - - return rv ? EC2I_READ_ERROR : (EC2I_READ_SUCCESS + ihd); -} - -/* EC2I read */ -enum ec2i_message ec2i_read(enum host_pnpcfg_index index) -{ - enum ec2i_message ret = EC2I_READ_ERROR; - /* critical section with interrupts off */ - uint32_t int_mask = read_clear_int_mask(); - - /* Set index */ - if (ec2i_write_pnpcfg(EC2I_ACCESS_INDEX, index) == EC2I_WRITE_SUCCESS) - /* read data port */ - ret = ec2i_read_pnpcfg(EC2I_ACCESS_DATA); - /* restore interrupts */ - set_int_mask(int_mask); - - return ret; -} - -/* EC2I write */ -enum ec2i_message ec2i_write(enum host_pnpcfg_index index, uint8_t data) -{ - enum ec2i_message ret = EC2I_WRITE_ERROR; - /* critical section with interrupts off */ - uint32_t int_mask = read_clear_int_mask(); - - /* Set index */ - if (ec2i_write_pnpcfg(EC2I_ACCESS_INDEX, index) == EC2I_WRITE_SUCCESS) - /* Set data */ - ret = ec2i_write_pnpcfg(EC2I_ACCESS_DATA, data); - /* restore interrupts */ - set_int_mask(int_mask); - - return ret; -} - -static void pnpcfg_configure(const struct ec2i_t *settings, size_t entries) -{ - size_t i; - - for (i = 0; i < entries; i++) { - if (ec2i_write(settings[i].index_port, settings[i].data_port) == - EC2I_WRITE_ERROR) { - ccprints("Failed to apply %zd", i); - break; - } - } -} - -#define PNPCFG(_s) \ - pnpcfg_configure(_s##_settings, ARRAY_SIZE(_s##_settings)) - -static void pnpcfg_init(void) -{ - /* Host access is disabled */ - IT83XX_EC2I_LSIOHA |= 0x3; - - PNPCFG(keyboard); -#ifdef CONFIG_IT83XX_ENABLE_MOUSE_DEVICE - PNPCFG(mouse); -#endif - PNPCFG(pm1); - PNPCFG(pm2); - PNPCFG(smfi); - PNPCFG(pm3); - PNPCFG(rtct); -#ifdef CONFIG_UART_HOST - PNPCFG(uart2); -#endif -} -DECLARE_HOOK(HOOK_INIT, pnpcfg_init, HOOK_PRIO_DEFAULT); diff --git a/chip/it83xx/ec2i_chip.h b/chip/it83xx/ec2i_chip.h deleted file mode 100644 index c8069f4ff5..0000000000 --- a/chip/it83xx/ec2i_chip.h +++ /dev/null @@ -1,129 +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. - */ - -/* EC2I control module for IT83xx. */ - -#ifndef __CROS_EC_EC2I_CHIP_H -#define __CROS_EC_EC2I_CHIP_H - -#define P80L_P80LB 0 -#define P80L_P80LE 0x3F -#define P80L_P80LC 0 -#define P80L_BRAM_BANK1_SIZE_MASK 0x3F - -/* Index list of the host interface registers of PNPCFG */ -enum host_pnpcfg_index { - /* Logical Device Number */ - HOST_INDEX_LDN = 0x07, - /* Chip ID Byte 1 */ - HOST_INDEX_CHIPID1 = 0x20, - /* Chip ID Byte 2 */ - HOST_INDEX_CHIPID2 = 0x21, - /* Chip Version */ - HOST_INDEX_CHIPVER = 0x22, - /* Super I/O Control */ - HOST_INDEX_SIOCTRL = 0x23, - /* Super I/O IRQ Configuration */ - HOST_INDEX_SIOIRQ = 0x25, - /* Super I/O General Purpose */ - HOST_INDEX_SIOGP = 0x26, - /* Super I/O Power Mode */ - HOST_INDEX_SIOPWR = 0x2D, - /* Depth 2 I/O Address */ - HOST_INDEX_D2ADR = 0x2E, - /* Depth 2 I/O Data */ - HOST_INDEX_D2DAT = 0x2F, - /* Logical Device Activate Register */ - HOST_INDEX_LDA = 0x30, - /* I/O Port Base Address Bits [15:8] for Descriptor 0 */ - HOST_INDEX_IOBAD0_MSB = 0x60, - /* I/O Port Base Address Bits [7:0] for Descriptor 0 */ - HOST_INDEX_IOBAD0_LSB = 0x61, - /* I/O Port Base Address Bits [15:8] for Descriptor 1 */ - HOST_INDEX_IOBAD1_MSB = 0x62, - /* I/O Port Base Address Bits [7:0] for Descriptor 1 */ - HOST_INDEX_IOBAD1_LSB = 0x63, - /* Interrupt Request Number and Wake-Up on IRQ Enabled */ - HOST_INDEX_IRQNUMX = 0x70, - /* Interrupt Request Type Select */ - HOST_INDEX_IRQTP = 0x71, - /* DMA Channel Select 0 */ - HOST_INDEX_DMAS0 = 0x74, - /* DMA Channel Select 1 */ - HOST_INDEX_DMAS1 = 0x75, - /* Device Specific Logical Device Configuration 1 to 10 */ - HOST_INDEX_DSLDC1 = 0xF0, - HOST_INDEX_DSLDC2 = 0xF1, - HOST_INDEX_DSLDC3 = 0xF2, - HOST_INDEX_DSLDC4 = 0xF3, - HOST_INDEX_DSLDC5 = 0xF4, - HOST_INDEX_DSLDC6 = 0xF5, - HOST_INDEX_DSLDC7 = 0xF6, - HOST_INDEX_DSLDC8 = 0xF7, - HOST_INDEX_DSLDC9 = 0xF8, - HOST_INDEX_DSLDC10 = 0xF9, -}; - -/* List of logical device number (LDN) assignments */ -enum logical_device_number { - /* Serial Port 1 */ - LDN_UART1 = 0x01, - /* Serial Port 2 */ - LDN_UART2 = 0x02, - /* System Wake-Up Control */ - LDN_SWUC = 0x04, - /* KBC/Mouse Interface */ - LDN_KBC_MOUSE = 0x05, - /* KBC/Keyboard Interface */ - LDN_KBC_KEYBOARD = 0x06, - /* Consumer IR */ - LDN_CIR = 0x0A, - /* Shared Memory/Flash Interface */ - LDN_SMFI = 0x0F, - /* RTC-like Timer */ - LDN_RTCT = 0x10, - /* Power Management I/F Channel 1 */ - LDN_PMC1 = 0x11, - /* Power Management I/F Channel 2 */ - LDN_PMC2 = 0x12, - /* Serial Peripheral Interface */ - LDN_SSPI = 0x13, - /* Platform Environment Control Interface */ - LDN_PECI = 0x14, - /* Power Management I/F Channel 3 */ - LDN_PMC3 = 0x17, - /* Power Management I/F Channel 4 */ - LDN_PMC4 = 0x18, - /* Power Management I/F Channel 5 */ - LDN_PMC5 = 0x19, -}; - -/* EC2I read/write message */ -enum ec2i_message { - /* EC2I write success */ - EC2I_WRITE_SUCCESS = 0x00, - /* EC2I write error */ - EC2I_WRITE_ERROR = 0x01, - /* EC2I read success */ - EC2I_READ_SUCCESS = 0x8000, - /* EC2I read error */ - EC2I_READ_ERROR = 0x8100, -}; - -/* Data structure for initializing PNPCFG via ec2i. */ -struct ec2i_t { - /* index port */ - enum host_pnpcfg_index index_port; - /* data port */ - uint8_t data_port; -}; - -/* EC2I write */ -enum ec2i_message ec2i_write(enum host_pnpcfg_index index, uint8_t data); - -/* EC2I read */ -enum ec2i_message ec2i_read(enum host_pnpcfg_index index); - -#endif /* __CROS_EC_EC2I_CHIP_H */ diff --git a/chip/it83xx/espi.c b/chip/it83xx/espi.c deleted file mode 100644 index 7385e83a93..0000000000 --- a/chip/it83xx/espi.c +++ /dev/null @@ -1,624 +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. - */ - -/* ESPI module for Chrome EC */ - -#include "console.h" -#include "espi.h" -#include "hooks.h" -#include "port80.h" -#include "power.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "uart.h" -#include "util.h" - -/* Console output macros */ -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) - -struct vw_channel_t { - uint8_t index; /* VW index of signal */ - uint8_t level_mask; /* level bit of signal */ - uint8_t valid_mask; /* valid bit of signal */ -}; - -/* VW settings after the controller enables the VW channel. */ -static const struct vw_channel_t en_vw_setting[] = { - /* EC sends SUS_ACK# = 1 VW to PCH. That does not apply to GLK SoC. */ -#ifndef CONFIG_CHIPSET_GEMINILAKE - {ESPI_SYSTEM_EVENT_VW_IDX_40, - VW_LEVEL_FIELD(0), - VW_VALID_FIELD(VW_IDX_40_SUS_ACK)}, -#endif -}; - -/* VW settings after the controller enables the OOB channel. */ -static const struct vw_channel_t en_oob_setting[] = { - {ESPI_SYSTEM_EVENT_VW_IDX_4, - VW_LEVEL_FIELD(0), - VW_VALID_FIELD(VW_IDX_4_OOB_RST_ACK)}, -}; - -/* VW settings after the controller enables the flash channel. */ -static const struct vw_channel_t en_flash_setting[] = { - {ESPI_SYSTEM_EVENT_VW_IDX_5, - VW_LEVEL_FIELD(VW_IDX_5_BTLD_STATUS_DONE), - VW_VALID_FIELD(VW_IDX_5_BTLD_STATUS_DONE)}, -}; - -/* VW settings at host startup */ -static const struct vw_channel_t vw_host_startup_setting[] = { - {ESPI_SYSTEM_EVENT_VW_IDX_6, - VW_LEVEL_FIELD(VW_IDX_6_SCI | VW_IDX_6_SMI | - VW_IDX_6_RCIN | VW_IDX_6_HOST_RST_ACK), - VW_VALID_FIELD(VW_IDX_6_SCI | VW_IDX_6_SMI | - VW_IDX_6_RCIN | VW_IDX_6_HOST_RST_ACK)}, -}; - -#define VW_CHAN(name, idx, level, valid) \ - [(name - VW_SIGNAL_START)] = {idx, level, valid} - -/* VW signals used in eSPI (NOTE: must match order of enum espi_vw_signal). */ -static const struct vw_channel_t vw_channel_list[] = { - /* index 02h: controller to peripheral. */ - VW_CHAN(VW_SLP_S3_L, - ESPI_SYSTEM_EVENT_VW_IDX_2, - VW_LEVEL_FIELD(VW_IDX_2_SLP_S3), - VW_VALID_FIELD(VW_IDX_2_SLP_S3)), - VW_CHAN(VW_SLP_S4_L, - ESPI_SYSTEM_EVENT_VW_IDX_2, - VW_LEVEL_FIELD(VW_IDX_2_SLP_S4), - VW_VALID_FIELD(VW_IDX_2_SLP_S4)), - VW_CHAN(VW_SLP_S5_L, - ESPI_SYSTEM_EVENT_VW_IDX_2, - VW_LEVEL_FIELD(VW_IDX_2_SLP_S5), - VW_VALID_FIELD(VW_IDX_2_SLP_S5)), - /* index 03h: controller to peripheral. */ - VW_CHAN(VW_SUS_STAT_L, - ESPI_SYSTEM_EVENT_VW_IDX_3, - VW_LEVEL_FIELD(VW_IDX_3_SUS_STAT), - VW_VALID_FIELD(VW_IDX_3_SUS_STAT)), - VW_CHAN(VW_PLTRST_L, - ESPI_SYSTEM_EVENT_VW_IDX_3, - VW_LEVEL_FIELD(VW_IDX_3_PLTRST), - VW_VALID_FIELD(VW_IDX_3_PLTRST)), - VW_CHAN(VW_OOB_RST_WARN, - ESPI_SYSTEM_EVENT_VW_IDX_3, - VW_LEVEL_FIELD(VW_IDX_3_OOB_RST_WARN), - VW_VALID_FIELD(VW_IDX_3_OOB_RST_WARN)), - /* index 04h: peripheral to controller. */ - VW_CHAN(VW_OOB_RST_ACK, - ESPI_SYSTEM_EVENT_VW_IDX_4, - VW_LEVEL_FIELD(VW_IDX_4_OOB_RST_ACK), - VW_VALID_FIELD(VW_IDX_4_OOB_RST_ACK)), - VW_CHAN(VW_WAKE_L, - ESPI_SYSTEM_EVENT_VW_IDX_4, - VW_LEVEL_FIELD(VW_IDX_4_WAKE), - VW_VALID_FIELD(VW_IDX_4_WAKE)), - VW_CHAN(VW_PME_L, - ESPI_SYSTEM_EVENT_VW_IDX_4, - VW_LEVEL_FIELD(VW_IDX_4_PME), - VW_VALID_FIELD(VW_IDX_4_PME)), - /* index 05h: peripheral to controller. */ - VW_CHAN(VW_ERROR_FATAL, - ESPI_SYSTEM_EVENT_VW_IDX_5, - VW_LEVEL_FIELD(VW_IDX_5_FATAL), - VW_VALID_FIELD(VW_IDX_5_FATAL)), - VW_CHAN(VW_ERROR_NON_FATAL, - ESPI_SYSTEM_EVENT_VW_IDX_5, - VW_LEVEL_FIELD(VW_IDX_5_NON_FATAL), - VW_VALID_FIELD(VW_IDX_5_NON_FATAL)), - VW_CHAN(VW_PERIPHERAL_BTLD_STATUS_DONE, - ESPI_SYSTEM_EVENT_VW_IDX_5, - VW_LEVEL_FIELD(VW_IDX_5_BTLD_STATUS_DONE), - VW_VALID_FIELD(VW_IDX_5_BTLD_STATUS_DONE)), - /* index 06h: peripheral to controller. */ - VW_CHAN(VW_SCI_L, - ESPI_SYSTEM_EVENT_VW_IDX_6, - VW_LEVEL_FIELD(VW_IDX_6_SCI), - VW_VALID_FIELD(VW_IDX_6_SCI)), - VW_CHAN(VW_SMI_L, - ESPI_SYSTEM_EVENT_VW_IDX_6, - VW_LEVEL_FIELD(VW_IDX_6_SMI), - VW_VALID_FIELD(VW_IDX_6_SMI)), - VW_CHAN(VW_RCIN_L, - ESPI_SYSTEM_EVENT_VW_IDX_6, - VW_LEVEL_FIELD(VW_IDX_6_RCIN), - VW_VALID_FIELD(VW_IDX_6_RCIN)), - VW_CHAN(VW_HOST_RST_ACK, - ESPI_SYSTEM_EVENT_VW_IDX_6, - VW_LEVEL_FIELD(VW_IDX_6_HOST_RST_ACK), - VW_VALID_FIELD(VW_IDX_6_HOST_RST_ACK)), - /* index 07h: controller to peripheral. */ - VW_CHAN(VW_HOST_RST_WARN, - ESPI_SYSTEM_EVENT_VW_IDX_7, - VW_LEVEL_FIELD(VW_IDX_7_HOST_RST_WARN), - VW_VALID_FIELD(VW_IDX_7_HOST_RST_WARN)), - /* index 40h: peripheral to controller. */ - VW_CHAN(VW_SUS_ACK, - ESPI_SYSTEM_EVENT_VW_IDX_40, - VW_LEVEL_FIELD(VW_IDX_40_SUS_ACK), - VW_VALID_FIELD(VW_IDX_40_SUS_ACK)), - /* index 41h: controller to peripheral. */ - VW_CHAN(VW_SUS_WARN_L, - ESPI_SYSTEM_EVENT_VW_IDX_41, - VW_LEVEL_FIELD(VW_IDX_41_SUS_WARN), - VW_VALID_FIELD(VW_IDX_41_SUS_WARN)), - VW_CHAN(VW_SUS_PWRDN_ACK_L, - ESPI_SYSTEM_EVENT_VW_IDX_41, - VW_LEVEL_FIELD(VW_IDX_41_SUS_PWRDN_ACK), - VW_VALID_FIELD(VW_IDX_41_SUS_PWRDN_ACK)), - VW_CHAN(VW_SLP_A_L, - ESPI_SYSTEM_EVENT_VW_IDX_41, - VW_LEVEL_FIELD(VW_IDX_41_SLP_A), - VW_VALID_FIELD(VW_IDX_41_SLP_A)), - /* index 42h: controller to peripheral. */ - VW_CHAN(VW_SLP_LAN, - ESPI_SYSTEM_EVENT_VW_IDX_42, - VW_LEVEL_FIELD(VW_IDX_42_SLP_LAN), - VW_VALID_FIELD(VW_IDX_42_SLP_LAN)), - VW_CHAN(VW_SLP_WLAN, - ESPI_SYSTEM_EVENT_VW_IDX_42, - VW_LEVEL_FIELD(VW_IDX_42_SLP_WLAN), - VW_VALID_FIELD(VW_IDX_42_SLP_WLAN)), -}; -BUILD_ASSERT(ARRAY_SIZE(vw_channel_list) == VW_SIGNAL_COUNT); - -/* Get vw index & value information by signal */ -static int espi_vw_get_signal_index(enum espi_vw_signal event) -{ - uint32_t i = event - VW_SIGNAL_START; - - return (i < ARRAY_SIZE(vw_channel_list)) ? i : -1; -} - -/** - * 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) -{ - /* Get index of vw signal list by signale name */ - int i = espi_vw_get_signal_index(signal); - - if (i < 0) - return EC_ERROR_PARAM1; - - /* critical section with interrupts off */ - interrupt_disable(); - if (level) - IT83XX_ESPI_VWIDX(vw_channel_list[i].index) |= - vw_channel_list[i].level_mask; - else - IT83XX_ESPI_VWIDX(vw_channel_list[i].index) &= - ~vw_channel_list[i].level_mask; - /* restore interrupts */ - interrupt_enable(); - - 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) -{ - /* Get index of vw signal list by signale name */ - int i = espi_vw_get_signal_index(signal); - - if (i < 0) - return 0; - - /* Not valid */ - if (!(IT83XX_ESPI_VWIDX(vw_channel_list[i].index) & - vw_channel_list[i].valid_mask)) - return 0; - - return !!(IT83XX_ESPI_VWIDX(vw_channel_list[i].index) & - vw_channel_list[i].level_mask); -} - -/** - * 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) -{ - /* - * Common code calls this function to enable VW interrupt of power - * sequence signal. - * IT83xx only use a bit (bit7@IT83XX_ESPI_VWCTRL0) to enable VW - * interrupt. - * VW interrupt will be triggerd with any updated VW index flag - * if this control bit is set. - * So we will always return success here. - */ - 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) -{ - /* - * We can't disable VW interrupt of power sequence signal - * individually. - */ - return EC_ERROR_UNIMPLEMENTED; -} - -/* Configure virtual wire outputs */ -static void espi_configure_vw(const struct vw_channel_t *settings, - size_t entries) -{ - size_t i; - - for (i = 0; i < entries; i++) - IT83XX_ESPI_VWIDX(settings[i].index) |= - (settings[i].level_mask | settings[i].valid_mask); -} - -static void espi_vw_host_startup(void) -{ - espi_configure_vw(vw_host_startup_setting, - ARRAY_SIZE(vw_host_startup_setting)); -} - -static void espi_vw_no_isr(uint8_t flag_changed, uint8_t vw_evt) -{ - CPRINTS("espi VW interrupt event is ignored! (bit%d at VWCTRL1)", - vw_evt); -} - -#ifndef CONFIG_CHIPSET_GEMINILAKE -static void espi_vw_idx41_isr(uint8_t flag_changed, uint8_t vw_evt) -{ - if (flag_changed & VW_LEVEL_FIELD(VW_IDX_41_SUS_WARN)) - espi_vw_set_wire(VW_SUS_ACK, espi_vw_get_wire(VW_SUS_WARN_L)); -} -#endif - -static void espi_vw_idx7_isr(uint8_t flag_changed, uint8_t vw_evt) -{ - if (flag_changed & VW_LEVEL_FIELD(VW_IDX_7_HOST_RST_WARN)) - espi_vw_set_wire(VW_HOST_RST_ACK, - espi_vw_get_wire(VW_HOST_RST_WARN)); -} - -#ifdef CONFIG_CHIPSET_RESET_HOOK -static void espi_chipset_reset(void) -{ - hook_notify(HOOK_CHIPSET_RESET); -} -DECLARE_DEFERRED(espi_chipset_reset); -#endif - -static void espi_vw_idx3_isr(uint8_t flag_changed, uint8_t vw_evt) -{ - if (flag_changed & VW_LEVEL_FIELD(VW_IDX_3_PLTRST)) { - int pltrst = espi_vw_get_wire(VW_PLTRST_L); - - if (pltrst) { - espi_vw_host_startup(); - } else { -#ifdef CONFIG_CHIPSET_RESET_HOOK - hook_call_deferred(&espi_chipset_reset_data, MSEC); -#endif - /* Store port 80 reset event */ - port_80_write(PORT_80_EVENT_RESET); - } - - CPRINTS("VW PLTRST_L %sasserted", pltrst ? "de" : ""); - } - - if (flag_changed & VW_LEVEL_FIELD(VW_IDX_3_OOB_RST_WARN)) - espi_vw_set_wire(VW_OOB_RST_ACK, - espi_vw_get_wire(VW_OOB_RST_WARN)); -} - -static void espi_vw_idx2_isr(uint8_t flag_changed, uint8_t vw_evt) -{ - if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S3)) - power_signal_interrupt(VW_SLP_S3_L); - if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S4)) - power_signal_interrupt(VW_SLP_S4_L); - if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S5)) - power_signal_interrupt(VW_SLP_S5_L); -} - -struct vw_interrupt_t { - void (*vw_isr)(uint8_t flag_changed, uint8_t vw_evt); - uint8_t vw_index; -}; - -/* - * The ISR of espi VW interrupt in array needs to match bit order in - * IT83XX_ESPI_VWCTRL1 register. - */ -#ifdef CONFIG_CHIPSET_GEMINILAKE -static const struct vw_interrupt_t vw_isr_list[] = { - [0] = {espi_vw_idx2_isr, ESPI_SYSTEM_EVENT_VW_IDX_2}, - [1] = {espi_vw_idx3_isr, ESPI_SYSTEM_EVENT_VW_IDX_3}, - [2] = {espi_vw_idx7_isr, ESPI_SYSTEM_EVENT_VW_IDX_7}, - [3] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_41}, - [4] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_42}, - [5] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_43}, - [6] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_44}, - [7] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_47}, -}; -#else -static const struct vw_interrupt_t vw_isr_list[] = { - [0] = {espi_vw_idx2_isr, ESPI_SYSTEM_EVENT_VW_IDX_2}, - [1] = {espi_vw_idx3_isr, ESPI_SYSTEM_EVENT_VW_IDX_3}, - [2] = {espi_vw_idx7_isr, ESPI_SYSTEM_EVENT_VW_IDX_7}, - [3] = {espi_vw_idx41_isr, ESPI_SYSTEM_EVENT_VW_IDX_41}, - [4] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_42}, - [5] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_43}, - [6] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_44}, - [7] = {espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_47}, -}; -#endif - -/* - * This is used to record the previous VW valid / level field state to discover - * changes. Then do following sequence only when state is changed. - */ -static uint8_t vw_index_flag[ARRAY_SIZE(vw_isr_list)]; - -void espi_vw_interrupt(void) -{ - int i; - uint8_t vwidx_updated = IT83XX_ESPI_VWCTRL1; - -#ifdef IT83XX_ESPI_VWCTRL1_WRITE_FF_CLEAR - /* For IT8320BX, we have to write 0xff to clear pending bit.*/ - IT83XX_ESPI_VWCTRL1 = 0xff; -#else - /* write-1 to clear */ - IT83XX_ESPI_VWCTRL1 = vwidx_updated; -#endif - task_clear_pending_irq(IT83XX_IRQ_ESPI_VW); - - for (i = 0; i < ARRAY_SIZE(vw_isr_list); i++) { - if (vwidx_updated & BIT(i)) { - uint8_t idx_flag; - - idx_flag = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index); - vw_isr_list[i].vw_isr(vw_index_flag[i] ^ idx_flag, i); - vw_index_flag[i] = idx_flag; - } - } -} - -static void espi_reset_vw_index_flags(void) -{ - int i; - - /* reset vw_index_flag */ - for (i = 0; i < ARRAY_SIZE(vw_isr_list); i++) - vw_index_flag[i] = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index); -} - -#ifdef IT83XX_ESPI_RESET_MODULE_BY_FW -void __ram_code espi_fw_reset_module(void) -{ - /* - * (b/111480168): Force a reset of logic VCC domain in EC. This will - * reset both LPC and eSPI blocks. The IT8320DX spec describes the - * purpose of these bits as deciding whether VCC power status is used as - * an internal "power good" signal. However, toggling this field while - * VCC is applied results in resettig VCC domain logic in EC. This code - * must reside in SRAM to prevent DMA address corruption. - * - * bit[7-6]: - * 00b: The VCC power status is treated as power-off. - * 01b: The VCC power status is treated as power-on. - */ - IT83XX_GCTRL_RSTS = (IT83XX_GCTRL_RSTS & ~0xc0); - IT83XX_GCTRL_RSTS = (IT83XX_GCTRL_RSTS & ~0xc0) | BIT(6); -} -#endif - -void espi_reset_pin_asserted_interrupt(enum gpio_signal signal) -{ -#ifdef IT83XX_ESPI_RESET_MODULE_BY_FW - espi_fw_reset_module(); - /* - * bit[7], enable P80L function. - * bit[6], accept port 80h cycle. - * bit[1-0], 10b: I2EC is read-only. - */ - IT83XX_GCTRL_SPCTRL1 |= 0xC2; -#endif - /* reset vw_index_flag when espi_reset# asserted. */ - espi_reset_vw_index_flags(); -} - -static int espi_get_reset_enable_config(void) -{ - uint8_t config; - const struct gpio_info *espi_rst = gpio_list + GPIO_ESPI_RESET_L; - - /* - * Determine if eSPI HW reset is connected to eiter B7 or D2. - * bit[2-1]: - * 00b: reserved. - * 01b: espi_reset# is enabled on GPB7. - * 10b: espi_reset# is enabled on GPD2. - * 11b: reset is disabled. - */ - if (espi_rst->port == GPIO_D && espi_rst->mask == BIT(2)) { - config = IT83XX_GPIO_GCR_LPC_RST_D2; - } else if (espi_rst->port == GPIO_B && espi_rst->mask == BIT(7)) { - config = IT83XX_GPIO_GCR_LPC_RST_B7; - } else { - config = IT83XX_GPIO_GCR_LPC_RST_DISABLE; - CPRINTS("EC's espi_reset pin is not enabled correctly"); - } - - return config; -} - -static void espi_enable_reset(void) -{ - int config = espi_get_reset_enable_config(); - -#ifdef IT83XX_ESPI_RESET_MODULE_BY_FW - /* - * Need to overwrite the config to ensure that eSPI HW reset is - * disabled. The reset function is instead handled by FW in the - * interrupt handler. - */ - config = IT83XX_GPIO_GCR_LPC_RST_DISABLE; - CPRINTS("EC's espi_reset pin hw auto reset is disabled"); - -#endif - IT83XX_GPIO_GCR = (IT83XX_GPIO_GCR & ~0x6) | - (config << IT83XX_GPIO_GCR_LPC_RST_POS); - - /* enable interrupt of EC's espi_reset pin */ - gpio_clear_pending_interrupt(GPIO_ESPI_RESET_L); - gpio_enable_interrupt(GPIO_ESPI_RESET_L); -} - -/* Interrupt event of controller enables the VW channel. */ -static void espi_vw_en_asserted(uint8_t evt) -{ - /* - * Configure peripheral to controller virtual wire outputs after - * receiving the event of controller enables the VW channel. - */ - espi_configure_vw(en_vw_setting, ARRAY_SIZE(en_vw_setting)); -} - -/* Interrupt event of controller enables the OOB channel. */ -static void espi_oob_en_asserted(uint8_t evt) -{ - /* - * Configure peripheral to controller virtual wire outputs after - * receiving the event of controller enables the OOB channel. - */ - espi_configure_vw(en_oob_setting, ARRAY_SIZE(en_oob_setting)); -} - -/* Interrupt event of controller enables the flash channel. */ -static void espi_flash_en_asserted(uint8_t evt) -{ - /* - * Configure peripheral to controller virtual wire outputs after - * receiving the event of controller enables the flash channel. - */ - espi_configure_vw(en_flash_setting, ARRAY_SIZE(en_flash_setting)); -} - -static void espi_no_isr(uint8_t evt) -{ - CPRINTS("espi interrupt event is ignored! (bit%d at ESGCTRL0)", evt); -} - -/* - * The ISR of espi interrupt event in array need to be matched bit order in - * IT83XX_ESPI_ESGCTRL0 register. - */ -static void (*espi_isr[])(uint8_t evt) = { - [0] = espi_no_isr, - [1] = espi_vw_en_asserted, - [2] = espi_oob_en_asserted, - [3] = espi_flash_en_asserted, - [4] = espi_no_isr, - [5] = espi_no_isr, - [6] = espi_no_isr, - [7] = espi_no_isr, -}; - -void espi_interrupt(void) -{ - int i; - /* get espi interrupt events */ - uint8_t espi_event = IT83XX_ESPI_ESGCTRL0; - - /* write-1 to clear */ - IT83XX_ESPI_ESGCTRL0 = espi_event; - /* process espi interrupt events */ - for (i = 0; i < ARRAY_SIZE(espi_isr); i++) { - if (espi_event & BIT(i)) - espi_isr[i](i); - } - /* - * bit7: the peripheral has received a peripheral posted/completion. - * This bit indicates the peripheral has received a packet from eSPI - * peripheral channel. We can check cycle type (bit[3-0] at ESPCTRL0) - * and make corresponding modification if needed. - */ - if (IT83XX_ESPI_ESPCTRL0 & ESPI_INTERRUPT_EVENT_PUT_PC) { - /* write-1-clear to release PC_FREE */ - IT83XX_ESPI_ESPCTRL0 = ESPI_INTERRUPT_EVENT_PUT_PC; - CPRINTS("A packet from peripheral channel is ignored!"); - } - - task_clear_pending_irq(IT83XX_IRQ_ESPI); -} - -#ifdef IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED -/* Enable/Disable eSPI pad */ -void espi_enable_pad(int enable) -{ - if (enable) - /* Enable eSPI pad. */ - IT83XX_ESPI_ESGCTRL2 &= ~BIT(6); - else - /* Disable eSPI pad. */ - IT83XX_ESPI_ESGCTRL2 |= BIT(6); -} -#endif - -void espi_init(void) -{ - /* - * bit[2-0], the maximum frequency of operation supported by peripheral: - * 000b: 20MHz - * 001b: 25MHz - * 010b: 33MHz - * 011b: 50MHz - * 100b: 66MHz - */ -#ifdef IT83XX_ESPI_PERIPHERAL_MAX_FREQ_CONFIGURABLE - IT83XX_ESPI_GCAC1 = (IT83XX_ESPI_GCAC1 & ~0x7) | BIT(2); -#endif - /* reset vw_index_flag at initialization */ - espi_reset_vw_index_flags(); - - /* - * bit[3]: The reset source of PNPCFG is RSTPNP bit in RSTCH - * register and WRST#. - */ - IT83XX_GCTRL_RSTS &= ~BIT(3); - task_clear_pending_irq(IT83XX_IRQ_ESPI_VW); - /* bit7: VW interrupt enable */ - IT83XX_ESPI_VWCTRL0 |= BIT(7); - task_enable_irq(IT83XX_IRQ_ESPI_VW); - - /* bit7: eSPI interrupt enable */ - IT83XX_ESPI_ESGCTRL1 |= BIT(7); - /* bit4: eSPI to WUC enable */ - IT83XX_ESPI_ESGCTRL2 |= BIT(4); - task_enable_irq(IT83XX_IRQ_ESPI); - - /* enable interrupt and reset from eSPI_reset# */ - espi_enable_reset(); -} diff --git a/chip/it83xx/fan.c b/chip/it83xx/fan.c deleted file mode 100644 index adb3985025..0000000000 --- a/chip/it83xx/fan.c +++ /dev/null @@ -1,478 +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. - */ - -/* Fan control module. */ - -#include "clock.h" -#include "fan.h" -#include "gpio.h" -#include "hooks.h" -#include "hwtimer_chip.h" -#include "math_util.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "util.h" - -#define TACH_EC_FREQ 8000000 -#define FAN_CTRL_BASED_MS 10 -#define FAN_CTRL_INTERVAL_MAX_MS 60 - -/* The sampling rate (fs) is FreqEC / 128 */ -#define TACH_DATA_VALID_TIMEOUT_MS (0xFFFF * 128 / (TACH_EC_FREQ / 1000)) - -/* - * Fan Speed (RPM) = 60 / (1/fs sec * {FnTMRR, FnTLRR} * P) - * n denotes 1 or 2. - * P denotes the numbers of square pulses per revolution. - * And {FnTMRR, FnTLRR} = 0000h denotes Fan Speed is zero. - * The sampling rate (fs) is FreqEC / 128. - */ -/* pulse, the numbers of square pulses per revolution. */ -#define TACH0_TO_RPM(pulse, raw) (60 * TACH_EC_FREQ / 128 / pulse / raw) -#define TACH1_TO_RPM(pulse, raw) (raw * 120 / (pulse * 2)) - -enum fan_output_s { - FAN_DUTY_I = 0x01, - FAN_DUTY_R = 0x02, - FAN_DUTY_OV = 0x03, - FAN_DUTY_DONE = 0x04, -}; - -struct fan_info { - unsigned int flags; - int fan_mode; - int fan_p; - int rpm_target; - int rpm_actual; - int tach_valid_ms; - int rpm_re; - int fan_ms; - int fan_ms_idx; - int startup_duty; - enum fan_status fan_sts; - int enabled; -}; -static struct fan_info fan_info_data[TACH_CH_COUNT]; - -static enum tach_ch_sel tach_bind(int ch) -{ - return fan_tach[pwm_channels[ch].channel].ch_tach; -} - -static void fan_set_interval(int ch) -{ - int diff, fan_ms; - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - diff = ABS(fan_info_data[tach_ch].rpm_target - - fan_info_data[tach_ch].rpm_actual) / 100; - - fan_ms = FAN_CTRL_INTERVAL_MAX_MS; - - fan_ms -= diff; - if (fan_ms < FAN_CTRL_BASED_MS) - fan_ms = FAN_CTRL_BASED_MS; - - fan_info_data[tach_ch].fan_ms = fan_ms; -} - -static void fan_init_start(int ch) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - fan_set_duty(ch, fan_info_data[tach_ch].startup_duty); -} - -static int fan_all_disabled(void) -{ - int fan, all_disabled = 0; - - for (fan = 0; fan < fan_get_count(); fan++) { - if (!fan_get_enabled(FAN_CH(fan))) - all_disabled++; - } - - if (all_disabled >= fan_get_count()) - return 1; - - return 0; -} - -void fan_set_enabled(int ch, int enabled) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - /* enable */ - if (enabled) { - if (tach_ch < TACH_CH_COUNT) - fan_info_data[tach_ch].fan_sts = FAN_STATUS_CHANGING; - - disable_sleep(SLEEP_MASK_FAN); - /* enable timer interrupt for fan control */ - ext_timer_start(FAN_CTRL_EXT_TIMER, 1); - /* disable */ - } else { - fan_set_duty(ch, 0); - - if (tach_ch < TACH_CH_COUNT) { - fan_info_data[tach_ch].rpm_actual = 0; - fan_info_data[tach_ch].fan_sts = FAN_STATUS_STOPPED; - } - } - - /* on/off */ - if (tach_ch < TACH_CH_COUNT) { - fan_info_data[tach_ch].enabled = enabled; - fan_info_data[tach_ch].tach_valid_ms = 0; - } - - pwm_enable(ch, enabled); - - if (!enabled) { - /* disable timer interrupt if all fan off. */ - if (fan_all_disabled()) { - ext_timer_stop(FAN_CTRL_EXT_TIMER, 1); - enable_sleep(SLEEP_MASK_FAN); - } - } -} - -int fan_get_enabled(int ch) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - return pwm_get_enabled(ch) && fan_info_data[tach_ch].enabled; - else - return 0; -} - -void fan_set_duty(int ch, int percent) -{ - pwm_set_duty(ch, percent); -} - -int fan_get_duty(int ch) -{ - return pwm_get_duty(ch); -} - -int fan_get_rpm_mode(int ch) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - return fan_info_data[tach_ch].fan_mode; - else - return EC_ERROR_UNKNOWN; -} - -void fan_set_rpm_mode(int ch, int rpm_mode) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - fan_info_data[tach_ch].fan_mode = rpm_mode; -} - -int fan_get_rpm_actual(int ch) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - return fan_info_data[tach_ch].rpm_actual; - else - return EC_ERROR_UNKNOWN; -} - -int fan_get_rpm_target(int ch) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - return fan_info_data[tach_ch].rpm_target; - else - return EC_ERROR_UNKNOWN; -} - -test_mockable void fan_set_rpm_target(int ch, int rpm) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - fan_info_data[tach_ch].rpm_target = rpm; -} - -enum fan_status fan_get_status(int ch) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - return fan_info_data[tach_ch].fan_sts; - else - return FAN_STATUS_STOPPED; -} - -/** - * Return non-zero if fan is enabled but stalled. - */ -int fan_is_stalled(int ch) -{ - /* Must be enabled with non-zero target to stall */ - if (!fan_get_enabled(ch) || - fan_get_rpm_target(ch) == 0 || - !fan_get_duty(ch)) - return 0; - - /* Check for stall condition */ - return fan_get_status(ch) == FAN_STATUS_STOPPED; -} - -void fan_channel_setup(int ch, unsigned int flags) -{ - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - if (tach_ch < TACH_CH_COUNT) - fan_info_data[tach_ch].flags = flags; -} - -static void fan_ctrl(int ch) -{ - int status = -1, adjust = 0; - int rpm_actual, rpm_target, rpm_re, duty; - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - fan_info_data[tach_ch].fan_ms_idx += FAN_CTRL_BASED_MS; - if (fan_info_data[tach_ch].fan_ms_idx > - fan_info_data[tach_ch].fan_ms) { - fan_info_data[tach_ch].fan_ms_idx = 0x00; - adjust = 1; - } - - if (adjust) { - /* get current pwm output duty */ - duty = fan_get_duty(ch); - - /* rpm mode */ - if (fan_info_data[tach_ch].fan_mode) { - rpm_actual = fan_info_data[tach_ch].rpm_actual; - rpm_target = fan_info_data[tach_ch].rpm_target; - rpm_re = fan_info_data[tach_ch].rpm_re; - - if (rpm_actual < (rpm_target - rpm_re)) { - if (duty == 100) { - status = FAN_DUTY_OV; - } else { - if (duty == 0) - fan_init_start(ch); - - pwm_duty_inc(ch); - status = FAN_DUTY_I; - } - } else if (rpm_actual > (rpm_target + rpm_re)) { - if (duty == 0) { - status = FAN_DUTY_OV; - } else { - pwm_duty_reduce(ch); - status = FAN_DUTY_R; - } - } else { - status = FAN_DUTY_DONE; - } - } else { - fan_info_data[tach_ch].fan_sts = FAN_STATUS_LOCKED; - } - - if (status == FAN_DUTY_DONE) { - fan_info_data[tach_ch].fan_sts = FAN_STATUS_LOCKED; - } else if ((status == FAN_DUTY_I) || (status == FAN_DUTY_R)) { - fan_info_data[tach_ch].fan_sts = FAN_STATUS_CHANGING; - } else if (status == FAN_DUTY_OV) { - fan_info_data[tach_ch].fan_sts = FAN_STATUS_FRUSTRATED; - - if (!fan_info_data[tach_ch].rpm_actual && duty) - fan_info_data[tach_ch].fan_sts = - FAN_STATUS_STOPPED; - } - } -} - -static int tach_ch_valid(enum tach_ch_sel tach_ch) -{ - int valid = 0; - - switch (tach_ch) { - case TACH_CH_TACH0A: - if ((IT83XX_PWM_TSWCTRL & 0x0C) == 0x08) - valid = 1; - break; - case TACH_CH_TACH1A: - if ((IT83XX_PWM_TSWCTRL & 0x03) == 0x02) - valid = 1; - break; - case TACH_CH_TACH0B: - if ((IT83XX_PWM_TSWCTRL & 0x0C) == 0x0C) - valid = 1; - break; - case TACH_CH_TACH1B: - if ((IT83XX_PWM_TSWCTRL & 0x03) == 0x03) - valid = 1; - break; - default: - break; - } - - return valid; -} - -static int get_tach0_rpm(int fan_p) -{ - uint16_t rpm; - - /* TACH0A / TACH0B data is valid */ - if (IT83XX_PWM_TSWCTRL & 0x08) { - rpm = (IT83XX_PWM_F1TMRR << 8) | IT83XX_PWM_F1TLRR; - - if (rpm) - rpm = TACH0_TO_RPM(fan_p, rpm); - - /* W/C */ - IT83XX_PWM_TSWCTRL |= 0x08; - return rpm; - } - return -1; -} - -static int get_tach1_rpm(int fan_p) -{ - uint16_t rpm; - - /* TACH1A / TACH1B data is valid */ - if (IT83XX_PWM_TSWCTRL & 0x02) { - rpm = (IT83XX_PWM_F2TMRR << 8) | IT83XX_PWM_F2TLRR; - - if (rpm) - rpm = TACH1_TO_RPM(fan_p, rpm); - - /* W/C */ - IT83XX_PWM_TSWCTRL |= 0x02; - return rpm; - } - return -1; -} - -static void proc_tach(int ch) -{ - int t_rpm; - enum tach_ch_sel tach_ch; - - tach_ch = tach_bind(ch); - - /* tachometer data valid */ - if (tach_ch_valid(tach_ch)) { - if ((tach_ch == TACH_CH_TACH0A) || (tach_ch == TACH_CH_TACH0B)) - t_rpm = get_tach0_rpm(fan_info_data[tach_ch].fan_p); - else - t_rpm = get_tach1_rpm(fan_info_data[tach_ch].fan_p); - - fan_info_data[tach_ch].rpm_actual = t_rpm; - fan_set_interval(ch); - fan_info_data[tach_ch].tach_valid_ms = 0; - } else { - fan_info_data[tach_ch].tach_valid_ms += FAN_CTRL_BASED_MS; - if (fan_info_data[tach_ch].tach_valid_ms > - TACH_DATA_VALID_TIMEOUT_MS) - fan_info_data[tach_ch].rpm_actual = 0; - } -} - -void fan_ext_timer_interrupt(void) -{ - int fan; - - task_clear_pending_irq(et_ctrl_regs[FAN_CTRL_EXT_TIMER].irq); - - for (fan = 0; fan < fan_get_count(); fan++) { - if (fan_get_enabled(FAN_CH(fan))) { - proc_tach(FAN_CH(fan)); - fan_ctrl(FAN_CH(fan)); - } - } -} - -static void fan_init(void) -{ - int ch, rpm_re, fan_p, s_duty; - enum tach_ch_sel tach_ch; - - for (ch = 0; ch < fan_get_count(); ch++) { - - rpm_re = fan_tach[pwm_channels[FAN_CH(ch)].channel].rpm_re; - fan_p = fan_tach[pwm_channels[FAN_CH(ch)].channel].fan_p; - s_duty = fan_tach[pwm_channels[FAN_CH(ch)].channel].s_duty; - tach_ch = tach_bind(FAN_CH(ch)); - - if (tach_ch < TACH_CH_COUNT) { - - if (tach_ch == TACH_CH_TACH0B) { - /* GPJ2 will select TACH0B as its alt. */ - IT83XX_GPIO_GRC5 |= 0x01; - /* bit2, to select TACH0B */ - IT83XX_PWM_TSWCTRL |= 0x04; - } else if (tach_ch == TACH_CH_TACH1B) { - /* GPJ3 will select TACH1B as its alt. */ - IT83XX_GPIO_GRC5 |= 0x02; - /* bit0, to select TACH1B */ - IT83XX_PWM_TSWCTRL |= 0x01; - } - - fan_info_data[tach_ch].flags = 0; - fan_info_data[tach_ch].fan_mode = 0; - fan_info_data[tach_ch].rpm_target = 0; - fan_info_data[tach_ch].rpm_actual = 0; - fan_info_data[tach_ch].tach_valid_ms = 0; - fan_info_data[tach_ch].fan_ms_idx = 0; - fan_info_data[tach_ch].enabled = 0; - fan_info_data[tach_ch].fan_p = fan_p; - fan_info_data[tach_ch].rpm_re = rpm_re; - fan_info_data[tach_ch].fan_ms = FAN_CTRL_BASED_MS; - fan_info_data[tach_ch].fan_sts = FAN_STATUS_STOPPED; - fan_info_data[tach_ch].startup_duty = s_duty; - } - } - - /* init external timer for fan control */ - ext_timer_ms(FAN_CTRL_EXT_TIMER, EXT_PSR_32P768K_HZ, 0, 0, - FAN_CTRL_BASED_MS, 1, 0); -} -DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_INIT_FAN); diff --git a/chip/it83xx/flash.c b/chip/it83xx/flash.c deleted file mode 100644 index ed02aa882f..0000000000 --- a/chip/it83xx/flash.c +++ /dev/null @@ -1,808 +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. - */ - -#include "common.h" -#include "console.h" -#include "flash.h" -#include "flash_chip.h" -#include "host_command.h" -#include "intc.h" -#include "system.h" -#include "util.h" -#include "watchdog.h" -#include "registers.h" -#include "task.h" -#include "shared_mem.h" -#include "uart.h" - -#define FLASH_DMA_START ((uint32_t) &__flash_dma_start) -#define FLASH_DMA_CODE __attribute__((section(".flash_direct_map"))) -#define FLASH_ILM0_ADDR ((uint32_t) &__ilm0_ram_code) - -/* erase size of sector is 1KB or 4KB */ -#define FLASH_SECTOR_ERASE_SIZE CONFIG_FLASH_ERASE_SIZE - -#ifdef IT83XX_CHIP_FLASH_IS_KGD -/* page program command */ -#define FLASH_CMD_PAGE_WRITE 0x2 -/* ector erase command (erase size is 4KB) */ -#define FLASH_CMD_SECTOR_ERASE 0x20 -/* command for flash write */ -#define FLASH_CMD_WRITE FLASH_CMD_PAGE_WRITE -#else -/* Auto address increment programming */ -#define FLASH_CMD_AAI_WORD 0xAD -/* Flash sector erase (1K bytes) command */ -#define FLASH_CMD_SECTOR_ERASE 0xD7 -/* command for flash write */ -#define FLASH_CMD_WRITE FLASH_CMD_AAI_WORD -#endif -/* Write status register */ -#define FLASH_CMD_WRSR 0x01 -/* Write disable */ -#define FLASH_CMD_WRDI 0x04 -/* Write enable */ -#define FLASH_CMD_WREN 0x06 -/* Read status register */ -#define FLASH_CMD_RS 0x05 - -#if (CONFIG_FLASH_SIZE_BYTES == 0x80000) && defined(CHIP_CORE_NDS32) -#define FLASH_TEXT_START ((uint32_t) &__flash_text_start) -/* Apply workaround of the issue (b:111808417) */ -#define IMMU_CACHE_TAG_INVALID -/* The default tag index of immu. */ -#define IMMU_TAG_INDEX_BY_DEFAULT 0x7E000 -/* immu cache size is 8K bytes. */ -#define IMMU_SIZE 0x2000 -#endif - -static int stuck_locked; -static int inconsistent_locked; -static int all_protected; -static int flash_dma_code_enabled; - -#define FWP_REG(bank) (bank / 8) -#define FWP_MASK(bank) (1 << (bank % 8)) - -enum flash_wp_interface { - FLASH_WP_HOST = 0x01, - FLASH_WP_DBGR = 0x02, - FLASH_WP_EC = 0x04, -}; - -enum flash_wp_status { - FLASH_WP_STATUS_PROTECT_RO = EC_FLASH_PROTECT_RO_NOW, - FLASH_WP_STATUS_PROTECT_ALL = EC_FLASH_PROTECT_ALL_NOW, -}; - -enum flash_status_mask { - FLASH_SR_NO_BUSY = 0, - /* Internal write operation is in progress */ - FLASH_SR_BUSY = 0x01, - /* Device is memory Write enabled */ - FLASH_SR_WEL = 0x02, - - FLASH_SR_ALL = (FLASH_SR_BUSY | FLASH_SR_WEL), -}; - -enum dlm_address_view { - SCAR0_ILM0_DLM13 = 0x8D000, /* DLM ~ 0x8DFFF H2RAM map LPC I/O */ - SCAR1_ILM1_DLM11 = 0x8B000, /* DLM ~ 0x8BFFF ram 44K ~ 48K */ - SCAR2_ILM2_DLM14 = 0x8E000, /* DLM ~ 0x8EFFF RO/RW flash code DMA */ - SCAR3_ILM3_DLM6 = 0x86000, /* DLM ~ 0x86FFF ram 24K ~ 28K */ - SCAR4_ILM4_DLM7 = 0x87000, /* DLM ~ 0x87FFF ram 28K ~ 32K */ - SCAR5_ILM5_DLM8 = 0x88000, /* DLM ~ 0x88FFF ram 32K ~ 36K */ - SCAR6_ILM6_DLM9 = 0x89000, /* DLM ~ 0x89FFF ram 36K ~ 40K */ - SCAR7_ILM7_DLM10 = 0x8A000, /* DLM ~ 0x8AFFF ram 40K ~ 44K */ - SCAR8_ILM8_DLM4 = 0x84000, /* DLM ~ 0x84FFF ram 16K ~ 20K */ - SCAR9_ILM9_DLM5 = 0x85000, /* DLM ~ 0x85FFF ram 20K ~ 24K */ - SCAR10_ILM10_DLM2 = 0x82000, /* DLM ~ 0x82FFF ram 8K ~ 12K */ - SCAR11_ILM11_DLM3 = 0x83000, /* DLM ~ 0x83FFF ram 12K ~ 16K */ - SCAR12_ILM12_DLM12 = 0x8C000, /* DLM ~ 0x8CFFF immu cache */ -}; - -void FLASH_DMA_CODE dma_reset_immu(int fill_immu) -{ - /* Immu tag sram reset */ - IT83XX_GCTRL_MCCR |= 0x10; - /* Make sure the immu(dynamic cache) is reset */ - data_serialization_barrier(); - - IT83XX_GCTRL_MCCR &= ~0x10; - data_serialization_barrier(); - -#ifdef IMMU_CACHE_TAG_INVALID - /* - * Workaround for (b:111808417): - * After immu reset, we will fill the immu cache with 8KB data - * that are outside address 0x7e000 ~ 0x7ffff. - * When CPU tries to fetch contents from address 0x7e000 ~ 0x7ffff, - * immu will re-fetch the missing contents inside 0x7e000 ~ 0x7ffff. - */ - if (fill_immu) { - volatile int immu __unused; - const uint32_t *ptr = (uint32_t *)FLASH_TEXT_START; - int i = 0; - - while (i < IMMU_SIZE) { - immu = *ptr++; - i += sizeof(*ptr); - } - } -#endif -} - -void FLASH_DMA_CODE dma_flash_follow_mode(void) -{ - /* - * ECINDAR3-0 are EC-indirect memory address registers. - * - * Enter follow mode by writing 0xf to low nibble of ECINDAR3 register, - * and set high nibble as 0x4 to select internal flash. - */ - IT83XX_SMFI_ECINDAR3 = (EC_INDIRECT_READ_INTERNAL_FLASH | 0xf); - /* Set FSCE# as high level by writing 0 to address xfff_fe00h */ - IT83XX_SMFI_ECINDAR2 = 0xFF; - IT83XX_SMFI_ECINDAR1 = 0xFE; - IT83XX_SMFI_ECINDAR0 = 0x00; - /* EC-indirect memory data register */ - IT83XX_SMFI_ECINDDR = 0x00; -} - -void FLASH_DMA_CODE dma_flash_follow_mode_exit(void) -{ - /* Exit follow mode, and keep the setting of selecting internal flash */ - IT83XX_SMFI_ECINDAR3 = EC_INDIRECT_READ_INTERNAL_FLASH; - IT83XX_SMFI_ECINDAR2 = 0x00; -} - -void FLASH_DMA_CODE dma_flash_fsce_high(void) -{ - /* FSCE# high level */ - IT83XX_SMFI_ECINDAR1 = 0xFE; - IT83XX_SMFI_ECINDDR = 0x00; -} - -uint8_t FLASH_DMA_CODE dma_flash_read_dat(void) -{ - /* Read data from FMISO */ - return IT83XX_SMFI_ECINDDR; -} - -void FLASH_DMA_CODE dma_flash_write_dat(uint8_t wdata) -{ - /* Write data to FMOSI */ - IT83XX_SMFI_ECINDDR = wdata; -} - -void FLASH_DMA_CODE dma_flash_transaction(int wlen, uint8_t *wbuf, - int rlen, uint8_t *rbuf, int cmd_end) -{ - int i; - - /* FSCE# with low level */ - IT83XX_SMFI_ECINDAR1 = 0xFD; - /* Write data to FMOSI */ - for (i = 0; i < wlen; i++) - IT83XX_SMFI_ECINDDR = wbuf[i]; - /* Read data from FMISO */ - for (i = 0; i < rlen; i++) - rbuf[i] = IT83XX_SMFI_ECINDDR; - - /* FSCE# high level if transaction done */ - if (cmd_end) - dma_flash_fsce_high(); -} - -void FLASH_DMA_CODE dma_flash_cmd_read_status(enum flash_status_mask mask, - enum flash_status_mask target) -{ - uint8_t status[1]; - uint8_t cmd_rs[] = {FLASH_CMD_RS}; - - /* - * We prefer no timeout here. We can always get the status - * we want, or wait for watchdog triggered to check - * e-flash's status instead of breaking loop. - * This will avoid fetching unknown instruction from e-flash - * and causing exception. - */ - while (1) { - /* read status */ - dma_flash_transaction(sizeof(cmd_rs), cmd_rs, 1, status, 1); - /* only bit[1:0] valid */ - if ((status[0] & mask) == target) - break; - } -} - -void FLASH_DMA_CODE dma_flash_cmd_write_enable(void) -{ - uint8_t cmd_we[] = {FLASH_CMD_WREN}; - - /* enter EC-indirect follow mode */ - dma_flash_follow_mode(); - /* send write enable command */ - dma_flash_transaction(sizeof(cmd_we), cmd_we, 0, NULL, 1); - /* read status and make sure busy bit cleared and write enabled. */ - dma_flash_cmd_read_status(FLASH_SR_ALL, FLASH_SR_WEL); - /* exit EC-indirect follow mode */ - dma_flash_follow_mode_exit(); -} - -void FLASH_DMA_CODE dma_flash_cmd_write_disable(void) -{ - uint8_t cmd_wd[] = {FLASH_CMD_WRDI}; - - /* enter EC-indirect follow mode */ - dma_flash_follow_mode(); - /* send write disable command */ - dma_flash_transaction(sizeof(cmd_wd), cmd_wd, 0, NULL, 1); - /* make sure busy bit cleared. */ - dma_flash_cmd_read_status(FLASH_SR_ALL, FLASH_SR_NO_BUSY); - /* exit EC-indirect follow mode */ - dma_flash_follow_mode_exit(); -} - -void FLASH_DMA_CODE dma_flash_cmd_erase(int addr, int cmd) -{ - uint8_t cmd_erase[] = {cmd, ((addr >> 16) & 0xFF), - ((addr >> 8) & 0xFF), (addr & 0xFF)}; - - /* enter EC-indirect follow mode */ - dma_flash_follow_mode(); - /* send erase command */ - dma_flash_transaction(sizeof(cmd_erase), cmd_erase, 0, NULL, 1); - /* make sure busy bit cleared. */ - dma_flash_cmd_read_status(FLASH_SR_BUSY, FLASH_SR_NO_BUSY); - /* exit EC-indirect follow mode */ - dma_flash_follow_mode_exit(); -} - -void FLASH_DMA_CODE dma_flash_cmd_write(int addr, int wlen, uint8_t *wbuf) -{ - int i; - uint8_t flash_write[] = {FLASH_CMD_WRITE, ((addr >> 16) & 0xFF), - ((addr >> 8) & 0xFF), (addr & 0xFF)}; - - /* enter EC-indirect follow mode */ - dma_flash_follow_mode(); - /* send flash write command (aai word or page program) */ - dma_flash_transaction(sizeof(flash_write), flash_write, 0, NULL, 0); -#ifdef IT83XX_CHIP_FLASH_IS_KGD - for (i = 0; i < wlen; i++) { - /* send data byte */ - dma_flash_write_dat(wbuf[i]); - - /* - * we want to restart the write sequence every IDEAL_SIZE - * chunk worth of data. - */ - if (!(++addr % CONFIG_FLASH_WRITE_IDEAL_SIZE)) { - uint8_t w_en[] = {FLASH_CMD_WREN}; - - dma_flash_fsce_high(); - /* make sure busy bit cleared. */ - dma_flash_cmd_read_status(FLASH_SR_BUSY, - FLASH_SR_NO_BUSY); - /* send write enable command */ - dma_flash_transaction(sizeof(w_en), w_en, 0, NULL, 1); - /* make sure busy bit cleared and write enabled. */ - dma_flash_cmd_read_status(FLASH_SR_ALL, FLASH_SR_WEL); - /* re-send write command */ - flash_write[1] = (addr >> 16) & 0xff; - flash_write[2] = (addr >> 8) & 0xff; - flash_write[3] = addr & 0xff; - dma_flash_transaction(sizeof(flash_write), flash_write, - 0, NULL, 0); - } - } - dma_flash_fsce_high(); - /* make sure busy bit cleared. */ - dma_flash_cmd_read_status(FLASH_SR_BUSY, FLASH_SR_NO_BUSY); -#else - for (i = 0; i < wlen; i += 2) { - dma_flash_write_dat(wbuf[i]); - dma_flash_write_dat(wbuf[i + 1]); - dma_flash_fsce_high(); - /* make sure busy bit cleared. */ - dma_flash_cmd_read_status(FLASH_SR_BUSY, FLASH_SR_NO_BUSY); - /* resend aai word command without address field */ - if ((i + 2) < wlen) - dma_flash_transaction(1, flash_write, 0, NULL, 0); - } -#endif - /* exit EC-indirect follow mode */ - dma_flash_follow_mode_exit(); -} - -uint8_t FLASH_DMA_CODE dma_flash_indirect_fast_read(int addr) -{ - IT83XX_SMFI_ECINDAR3 = EC_INDIRECT_READ_INTERNAL_FLASH; - IT83XX_SMFI_ECINDAR2 = (addr >> 16) & 0xFF; - IT83XX_SMFI_ECINDAR1 = (addr >> 8) & 0xFF; - IT83XX_SMFI_ECINDAR0 = (addr & 0xFF); - - return IT83XX_SMFI_ECINDDR; -} - -int FLASH_DMA_CODE dma_flash_verify(int addr, int size, const char *data) -{ - int i; - uint8_t *wbuf = (uint8_t *)data; - uint8_t *flash = (uint8_t *)addr; - - /* verify for erase */ - if (data == NULL) { - for (i = 0; i < size; i++) { - if (flash[i] != 0xFF) - return EC_ERROR_UNKNOWN; - } - /* verify for write */ - } else { - for (i = 0; i < size; i++) { - if (flash[i] != wbuf[i]) - return EC_ERROR_UNKNOWN; - } - } - - return EC_SUCCESS; -} - -void FLASH_DMA_CODE dma_flash_write(int addr, int wlen, const char *wbuf) -{ - dma_flash_cmd_write_enable(); - dma_flash_cmd_write(addr, wlen, (uint8_t *)wbuf); - dma_flash_cmd_write_disable(); -} - -void FLASH_DMA_CODE dma_flash_erase(int addr, int cmd) -{ - dma_flash_cmd_write_enable(); - dma_flash_cmd_erase(addr, cmd); - dma_flash_cmd_write_disable(); -} - -static enum flash_wp_status flash_check_wp(void) -{ - enum flash_wp_status wp_status; - int all_bank_count, bank; - - all_bank_count = CONFIG_FLASH_SIZE_BYTES / CONFIG_FLASH_BANK_SIZE; - - for (bank = 0; bank < all_bank_count; bank++) { - if (!(IT83XX_GCTRL_EWPR0PFEC(FWP_REG(bank)) & FWP_MASK(bank))) - break; - } - - if (bank == WP_BANK_COUNT) - wp_status = FLASH_WP_STATUS_PROTECT_RO; - else if (bank == (WP_BANK_COUNT + PSTATE_BANK_COUNT)) - wp_status = FLASH_WP_STATUS_PROTECT_RO; - else if (bank == all_bank_count) - wp_status = FLASH_WP_STATUS_PROTECT_ALL; - else - wp_status = 0; - - return wp_status; -} - -/** - * Protect flash banks until reboot. - * - * @param start_bank Start bank to protect - * @param bank_count Number of banks to protect - */ -static void flash_protect_banks(int start_bank, - int bank_count, - enum flash_wp_interface wp_if) -{ - int bank; - - for (bank = start_bank; bank < start_bank + bank_count; bank++) { - if (wp_if & FLASH_WP_EC) - IT83XX_GCTRL_EWPR0PFEC(FWP_REG(bank)) |= FWP_MASK(bank); - if (wp_if & FLASH_WP_HOST) - IT83XX_GCTRL_EWPR0PFH(FWP_REG(bank)) |= FWP_MASK(bank); - if (wp_if & FLASH_WP_DBGR) - IT83XX_GCTRL_EWPR0PFD(FWP_REG(bank)) |= FWP_MASK(bank); - } -} - -int FLASH_DMA_CODE crec_flash_physical_read(int offset, int size, char *data) -{ - int i; - - for (i = 0; i < size; i++) { - data[i] = dma_flash_indirect_fast_read(offset); - offset++; - } - - return EC_SUCCESS; -} - -/** - * Write to physical flash. - * - * Offset and size must be a multiple of CONFIG_FLASH_WRITE_SIZE. - * - * @param offset Flash offset to write. - * @param size Number of bytes to write. - * @param data Data to write to flash. Must be 32-bit aligned. - */ -int FLASH_DMA_CODE crec_flash_physical_write(int offset, int size, - const char *data) -{ - int ret = EC_ERROR_UNKNOWN; - - if (flash_dma_code_enabled == 0) - return EC_ERROR_ACCESS_DENIED; - - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - watchdog_reload(); - - /* - * CPU can't fetch instruction from flash while use - * EC-indirect follow mode to access flash, interrupts need to be - * disabled. - */ - interrupt_disable(); - - dma_flash_write(offset, size, data); -#ifdef IMMU_CACHE_TAG_INVALID - dma_reset_immu((offset + size) >= IMMU_TAG_INDEX_BY_DEFAULT); -#else - dma_reset_immu(0); -#endif - /* - * Internal flash of N8 or RISC-V core is ILM(Instruction Local Memory) - * mapped, but RISC-V's ILM base address is 0x80000000. - * - * Ensure that we will get the ILM address of a flash offset. - */ - offset |= CONFIG_MAPPED_STORAGE_BASE; - ret = dma_flash_verify(offset, size, data); - - interrupt_enable(); - - return ret; -} - -/** - * Erase physical flash. - * - * Offset and size must be a multiple of CONFIG_FLASH_ERASE_SIZE. - * - * @param offset Flash offset to erase. - * @param size Number of bytes to erase. - */ -int FLASH_DMA_CODE crec_flash_physical_erase(int offset, int size) -{ - int v_size = size, v_addr = offset, ret = EC_ERROR_UNKNOWN; - - if (flash_dma_code_enabled == 0) - return EC_ERROR_ACCESS_DENIED; - - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - /* - * CPU can't fetch instruction from flash while use - * EC-indirect follow mode to access flash, interrupts need to be - * disabled. - */ - interrupt_disable(); - - /* Always use sector erase command (1K or 4K bytes) */ - for (; size > 0; size -= FLASH_SECTOR_ERASE_SIZE) { - dma_flash_erase(offset, FLASH_CMD_SECTOR_ERASE); - offset += FLASH_SECTOR_ERASE_SIZE; - /* - * If requested erase size is too large at one time on KGD - * flash, we need to reload watchdog to prevent the reset. - */ - if (IS_ENABLED(IT83XX_CHIP_FLASH_IS_KGD) && (size > 0x10000)) - watchdog_reload(); - /* - * EC still need to handle AP's EC_CMD_GET_COMMS_STATUS command - * during erasing. - */ -#ifdef IT83XX_IRQ_SPI_PERIPHERAL - if (IS_ENABLED(CONFIG_SPI) && - IS_ENABLED(HAS_TASK_HOSTCMD) && - IS_ENABLED(CONFIG_HOST_COMMAND_STATUS)) { - if (IT83XX_SPI_RX_VLISR & IT83XX_SPI_RVLI) - task_trigger_irq(IT83XX_IRQ_SPI_PERIPHERAL); - } -#endif - } -#ifdef IMMU_CACHE_TAG_INVALID - dma_reset_immu((v_addr + v_size) >= IMMU_TAG_INDEX_BY_DEFAULT); -#else - dma_reset_immu(0); -#endif - /* get the ILM address of a flash offset. */ - v_addr |= CONFIG_MAPPED_STORAGE_BASE; - ret = dma_flash_verify(v_addr, v_size, NULL); - - interrupt_enable(); - - return ret; -} - -/** - * Read physical write protect setting for a flash bank. - * - * @param bank Bank index to check. - * @return non-zero if bank is protected until reboot. - */ -int crec_flash_physical_get_protect(int bank) -{ - return IT83XX_GCTRL_EWPR0PFEC(FWP_REG(bank)) & FWP_MASK(bank); -} - -/** - * Protect flash now. - * - * @param all Protect all (=1) or just read-only and pstate (=0). - * @return non-zero if error. - */ -int crec_flash_physical_protect_now(int all) -{ - if (all) { - /* Protect the entire flash */ - flash_protect_banks(0, - CONFIG_FLASH_SIZE_BYTES / CONFIG_FLASH_BANK_SIZE, - FLASH_WP_EC); - all_protected = 1; - } else { - /* Protect the read-only section and persistent state */ - flash_protect_banks(WP_BANK_OFFSET, - WP_BANK_COUNT, FLASH_WP_EC); -#ifdef PSTATE_BANK - flash_protect_banks(PSTATE_BANK, - PSTATE_BANK_COUNT, FLASH_WP_EC); -#endif - } - - /* - * bit[0], eflash protect lock register which can only be write 1 and - * only be cleared by power-on reset. - */ - IT83XX_GCTRL_EPLR |= 0x01; - - return EC_SUCCESS; -} - -/** - * Return flash protect state flags from the physical layer. - * - * This should only be called by flash_get_protect(). - * - * Uses the EC_FLASH_PROTECT_* flags from ec_commands.h - */ -uint32_t crec_flash_physical_get_protect_flags(void) -{ - uint32_t flags = 0; - - flags |= flash_check_wp(); - - if (all_protected) - flags |= EC_FLASH_PROTECT_ALL_NOW; - - /* Check if blocks were stuck locked at pre-init */ - if (stuck_locked) - flags |= EC_FLASH_PROTECT_ERROR_STUCK; - - /* Check if flash protection is in inconsistent state at pre-init */ - if (inconsistent_locked) - flags |= EC_FLASH_PROTECT_ERROR_INCONSISTENT; - - return flags; -} - -/** - * Return the valid flash protect flags. - * - * @return A combination of EC_FLASH_PROTECT_* flags from ec_commands.h - */ -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; -} - -/** - * Return the writable flash protect flags. - * - * @param cur_flags The current flash protect flags. - * @return A combination of EC_FLASH_PROTECT_* flags from ec_commands.h - */ -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; -} - -static void flash_enable_second_ilm(void) -{ -#ifdef CHIP_CORE_RISCV - /* Make sure no interrupt while enable static cache */ - interrupt_disable(); - - /* Invalid ILM0 */ - IT83XX_GCTRL_RVILMCR0 &= ~ILMCR_ILM0_ENABLE; - IT83XX_SMFI_SCAR0H = BIT(3); - /* copy code to ram */ - memcpy((void *)CHIP_RAMCODE_ILM0, - (const void *)FLASH_ILM0_ADDR, - IT83XX_ILM_BLOCK_SIZE); - /* - * Set the logic memory address(flash code of RO/RW) in flash - * by programming the register SCAR0x bit19-bit0. - */ - IT83XX_SMFI_SCAR0L = FLASH_ILM0_ADDR & GENMASK(7, 0); - IT83XX_SMFI_SCAR0M = (FLASH_ILM0_ADDR >> 8) & GENMASK(7, 0); - IT83XX_SMFI_SCAR0H = (FLASH_ILM0_ADDR >> 16) & GENMASK(2, 0); - if (FLASH_ILM0_ADDR & BIT(19)) - IT83XX_SMFI_SCAR0H |= BIT(7); - else - IT83XX_SMFI_SCAR0H &= ~BIT(7); - /* Enable ILM 0 */ - IT83XX_GCTRL_RVILMCR0 |= ILMCR_ILM0_ENABLE; - - interrupt_enable(); -#endif -} - -static void flash_code_static_dma(void) -{ - - /* Make sure no interrupt while enable static DMA */ - interrupt_disable(); - - /* invalid static DMA first */ - if (IS_ENABLED(CHIP_CORE_RISCV)) - IT83XX_GCTRL_RVILMCR0 &= ~ILMCR_ILM2_ENABLE; - IT83XX_SMFI_SCAR2H = 0x08; - - /* Enable DLM 56k~60k region and than copy data into it */ - if (IS_ENABLED(CHIP_CORE_NDS32)) - IT83XX_GCTRL_MCCR2 |= IT83XX_DLM14_ENABLE; - memcpy((void *)CHIP_RAMCODE_BASE, (const void *)FLASH_DMA_START, - IT83XX_ILM_BLOCK_SIZE); - if (IS_ENABLED(CHIP_CORE_RISCV)) - IT83XX_GCTRL_RVILMCR0 |= ILMCR_ILM2_ENABLE; - /* Disable DLM 56k~60k region and be the ram code section */ - if (IS_ENABLED(CHIP_CORE_NDS32)) - IT83XX_GCTRL_MCCR2 &= ~IT83XX_DLM14_ENABLE; - - /* - * Enable ILM - * Set the logic memory address(flash code of RO/RW) in eflash - * by programming the register SCARx bit19-bit0. - */ - IT83XX_SMFI_SCAR2L = FLASH_DMA_START & 0xFF; - IT83XX_SMFI_SCAR2M = (FLASH_DMA_START >> 8) & 0xFF; -#ifdef IT83XX_DAM_ADDR_BIT19_AT_REG_SCARXH_BIT7 - IT83XX_SMFI_SCAR2H = (FLASH_DMA_START >> 16) & 0x7; - if (FLASH_DMA_START & BIT(19)) - IT83XX_SMFI_SCAR2H |= BIT(7); - else - IT83XX_SMFI_SCAR2H &= ~BIT(7); -#else - IT83XX_SMFI_SCAR2H = (FLASH_DMA_START >> 16) & 0x0F; -#endif - /* - * Validate Direct-map SRAM function by programming - * register SCARx bit20=0 - */ - IT83XX_SMFI_SCAR2H &= ~0x10; - - flash_dma_code_enabled = 0x01; - - interrupt_enable(); -} - -/** - * Initialize the module. - * - * Applies at-boot protection settings if necessary. - */ -int crec_flash_pre_init(void) -{ - int32_t reset_flags, prot_flags, unwanted_prot_flags; - - /* By default, select internal flash for indirect fast read. */ - IT83XX_SMFI_ECINDAR3 = EC_INDIRECT_READ_INTERNAL_FLASH; - if (IS_ENABLED(IT83XX_CHIP_FLASH_IS_KGD)) - IT83XX_SMFI_FLHCTRL6R |= IT83XX_SMFI_MASK_ECINDPP; - flash_code_static_dma(); - /* - * Enable second ilm (ILM0 of it8xxx2 series), so we can pull more code - * (4kB) into static cache to save latency of fetching code from flash. - */ - flash_enable_second_ilm(); - - reset_flags = system_get_reset_flags(); - prot_flags = crec_flash_get_protect(); - unwanted_prot_flags = EC_FLASH_PROTECT_ALL_NOW | - EC_FLASH_PROTECT_ERROR_INCONSISTENT; - - /* - * If we have already jumped between images, an earlier image could - * have applied write protection. Nothing additional needs to be done. - */ - if (reset_flags & EC_RESET_FLAG_SYSJUMP) - return EC_SUCCESS; - - if (prot_flags & EC_FLASH_PROTECT_GPIO_ASSERTED) { - /* Protect the entire flash of host interface */ - flash_protect_banks(0, - CONFIG_FLASH_SIZE_BYTES / CONFIG_FLASH_BANK_SIZE, - FLASH_WP_HOST); - /* Protect the entire flash of DBGR interface */ - flash_protect_banks(0, - CONFIG_FLASH_SIZE_BYTES / CONFIG_FLASH_BANK_SIZE, - FLASH_WP_DBGR); - /* - * Write protect is asserted. If we want RO flash protected, - * protect it now. - */ - if ((prot_flags & EC_FLASH_PROTECT_RO_AT_BOOT) && - !(prot_flags & EC_FLASH_PROTECT_RO_NOW)) { - int rv = crec_flash_set_protect(EC_FLASH_PROTECT_RO_NOW, - EC_FLASH_PROTECT_RO_NOW); - if (rv) - return rv; - - /* Re-read flags */ - prot_flags = crec_flash_get_protect(); - } - } else { - /* Don't want RO flash protected */ - unwanted_prot_flags |= EC_FLASH_PROTECT_RO_NOW; - } - - /* If there are no unwanted flags, done */ - if (!(prot_flags & unwanted_prot_flags)) - return EC_SUCCESS; - - /* - * If the last reboot was a power-on reset, it should have cleared - * write-protect. If it didn't, then the flash write protect registers - * have been permanently committed and we can't fix that. - */ - if (reset_flags & EC_RESET_FLAG_POWER_ON) { - stuck_locked = 1; - return EC_ERROR_ACCESS_DENIED; - } else { - /* - * Set inconsistent flag, because there is no software - * reset can clear write-protect. - */ - inconsistent_locked = 1; - return EC_ERROR_ACCESS_DENIED; - } - - /* That doesn't return, so if we're still here that's an error */ - return EC_ERROR_UNKNOWN; -} diff --git a/chip/it83xx/flash_chip.h b/chip/it83xx/flash_chip.h deleted file mode 100644 index c1262da116..0000000000 --- a/chip/it83xx/flash_chip.h +++ /dev/null @@ -1,22 +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_FLASH_CHIP_H -#define __CROS_EC_FLASH_CHIP_H - -/* - * This symbol is defined in linker script and used to provide the begin - * address of the ram code section. With this address, we can enable a ILM - * (4K bytes static code cache) for ram code section. - */ -extern const char __flash_dma_start; - -/* This symbol is the begin address of the __ilm0_ram_code section. */ -extern const char __ilm0_ram_code; - -/* This symbol is the begin address of the text section. */ -extern const char __flash_text_start; - -#endif /* __CROS_EC_FLASH_CHIP_H */ diff --git a/chip/it83xx/gpio.c b/chip/it83xx/gpio.c deleted file mode 100644 index c0e2367720..0000000000 --- a/chip/it83xx/gpio.c +++ /dev/null @@ -1,906 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* GPIO module for Chrome EC */ - -#include "clock.h" -#include "common.h" -#include "gpio.h" -#include "hooks.h" -#include "intc.h" -#include "it83xx_pd.h" -#include "kmsc_chip.h" -#include "registers.h" -#include "switch.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Data structure to define KSI/KSO GPIO mode control registers. */ -struct kbs_gpio_ctrl_t { - /* GPIO mode control register. */ - volatile uint8_t *gpio_mode; - /* GPIO output enable register. */ - volatile uint8_t *gpio_out; -}; - -static const struct kbs_gpio_ctrl_t kbs_gpio_ctrl_regs[] = { - /* KSI pins 7:0 */ - {&IT83XX_KBS_KSIGCTRL, &IT83XX_KBS_KSIGOEN}, - /* KSO pins 15:8 */ - {&IT83XX_KBS_KSOHGCTRL, &IT83XX_KBS_KSOHGOEN}, - /* KSO pins 7:0 */ - {&IT83XX_KBS_KSOLGCTRL, &IT83XX_KBS_KSOLGOEN}, -}; - -/** - * Convert wake-up controller (WUC) group to the corresponding wake-up edge - * sense register (WUESR). Return pointer to the register. - * - * @param grp WUC group. - * - * @return Pointer to corresponding WUESR register. - */ -static volatile uint8_t *wuesr(uint8_t grp) -{ - /* - * From WUESR1-WUESR4, the address increases by ones. From WUESR5 on - * the address increases by fours. - */ - return (grp <= 4) ? - (volatile uint8_t *)(IT83XX_WUC_WUESR1 + grp-1) : - (volatile uint8_t *)(IT83XX_WUC_WUESR5 + 4*(grp-5)); -} - -/** - * Convert wake-up controller (WUC) group to the corresponding wake-up edge - * mode register (WUEMR). Return pointer to the register. - * - * @param grp WUC group. - * - * @return Pointer to corresponding WUEMR register. - */ -static volatile uint8_t *wuemr(uint8_t grp) -{ - /* - * From WUEMR1-WUEMR4, the address increases by ones. From WUEMR5 on - * the address increases by fours. - */ - return (grp <= 4) ? - (volatile uint8_t *)(IT83XX_WUC_WUEMR1 + grp-1) : - (volatile uint8_t *)(IT83XX_WUC_WUEMR5 + 4*(grp-5)); -} - -/** - * Convert wake-up controller (WUC) group to the corresponding wake-up both edge - * mode register (WUBEMR). Return pointer to the register. - * - * @param grp WUC group. - * - * @return Pointer to corresponding WUBEMR register. - */ -#ifdef IT83XX_GPIO_INT_FLEXIBLE -static volatile uint8_t *wubemr(uint8_t grp) -{ - /* - * From WUBEMR1-WUBEMR4, the address increases by ones. From WUBEMR5 on - * the address increases by fours. - */ - return (grp <= 4) ? - (volatile uint8_t *)(IT83XX_WUC_WUBEMR1 + grp-1) : - (volatile uint8_t *)(IT83XX_WUC_WUBEMR5 + 4*(grp-5)); -} -#endif - -/* - * Array to store the corresponding GPIO port and mask, and WUC group and mask - * for each WKO interrupt. This allows GPIO interrupts coming in through WKO - * to easily identify which pin caused the interrupt. - * Note: Using designated initializers here in addition to using the array size - * assert because many rows are purposely skipped. Not all IRQs are WKO IRQs, - * so the IRQ index skips around. But, we still want the entire array to take - * up the size of the total number of IRQs because the index to the array could - * be any IRQ number. - */ -static const struct { - uint8_t gpio_port; - uint8_t gpio_mask; - uint8_t wuc_group; - uint8_t wuc_mask; -} gpio_irqs[] = { - /* irq gpio_port,gpio_mask,wuc_group,wuc_mask */ - [IT83XX_IRQ_WKO20] = {GPIO_D, BIT(0), 2, BIT(0)}, - [IT83XX_IRQ_WKO21] = {GPIO_D, BIT(1), 2, BIT(1)}, - [IT83XX_IRQ_WKO22] = {GPIO_C, BIT(4), 2, BIT(2)}, - [IT83XX_IRQ_WKO23] = {GPIO_C, BIT(6), 2, BIT(3)}, - [IT83XX_IRQ_WKO24] = {GPIO_D, BIT(2), 2, BIT(4)}, -#ifdef IT83XX_GPIO_INT_FLEXIBLE - [IT83XX_IRQ_WKO40] = {GPIO_E, BIT(5), 4, BIT(0)}, - [IT83XX_IRQ_WKO45] = {GPIO_E, BIT(6), 4, BIT(5)}, - [IT83XX_IRQ_WKO46] = {GPIO_E, BIT(7), 4, BIT(6)}, -#endif - [IT83XX_IRQ_WKO50] = {GPIO_K, BIT(0), 5, BIT(0)}, - [IT83XX_IRQ_WKO51] = {GPIO_K, BIT(1), 5, BIT(1)}, - [IT83XX_IRQ_WKO52] = {GPIO_K, BIT(2), 5, BIT(2)}, - [IT83XX_IRQ_WKO53] = {GPIO_K, BIT(3), 5, BIT(3)}, - [IT83XX_IRQ_WKO54] = {GPIO_K, BIT(4), 5, BIT(4)}, - [IT83XX_IRQ_WKO55] = {GPIO_K, BIT(5), 5, BIT(5)}, - [IT83XX_IRQ_WKO56] = {GPIO_K, BIT(6), 5, BIT(6)}, - [IT83XX_IRQ_WKO57] = {GPIO_K, BIT(7), 5, BIT(7)}, - [IT83XX_IRQ_WKO60] = {GPIO_H, BIT(0), 6, BIT(0)}, - [IT83XX_IRQ_WKO61] = {GPIO_H, BIT(1), 6, BIT(1)}, - [IT83XX_IRQ_WKO62] = {GPIO_H, BIT(2), 6, BIT(2)}, - [IT83XX_IRQ_WKO63] = {GPIO_H, BIT(3), 6, BIT(3)}, - [IT83XX_IRQ_WKO64] = {GPIO_F, BIT(4), 6, BIT(4)}, - [IT83XX_IRQ_WKO65] = {GPIO_F, BIT(5), 6, BIT(5)}, - [IT83XX_IRQ_WKO65] = {GPIO_F, BIT(6), 6, BIT(6)}, - [IT83XX_IRQ_WKO67] = {GPIO_F, BIT(7), 6, BIT(7)}, - [IT83XX_IRQ_WKO70] = {GPIO_E, BIT(0), 7, BIT(0)}, - [IT83XX_IRQ_WKO71] = {GPIO_E, BIT(1), 7, BIT(1)}, - [IT83XX_IRQ_WKO72] = {GPIO_E, BIT(2), 7, BIT(2)}, - [IT83XX_IRQ_WKO73] = {GPIO_E, BIT(3), 7, BIT(3)}, - [IT83XX_IRQ_WKO74] = {GPIO_I, BIT(4), 7, BIT(4)}, - [IT83XX_IRQ_WKO75] = {GPIO_I, BIT(5), 7, BIT(5)}, - [IT83XX_IRQ_WKO76] = {GPIO_I, BIT(6), 7, BIT(6)}, - [IT83XX_IRQ_WKO77] = {GPIO_I, BIT(7), 7, BIT(7)}, - [IT83XX_IRQ_WKO80] = {GPIO_A, BIT(3), 8, BIT(0)}, - [IT83XX_IRQ_WKO81] = {GPIO_A, BIT(4), 8, BIT(1)}, - [IT83XX_IRQ_WKO82] = {GPIO_A, BIT(5), 8, BIT(2)}, - [IT83XX_IRQ_WKO83] = {GPIO_A, BIT(6), 8, BIT(3)}, - [IT83XX_IRQ_WKO84] = {GPIO_B, BIT(2), 8, BIT(4)}, - [IT83XX_IRQ_WKO85] = {GPIO_C, BIT(0), 8, BIT(5)}, - [IT83XX_IRQ_WKO86] = {GPIO_C, BIT(7), 8, BIT(6)}, - [IT83XX_IRQ_WKO87] = {GPIO_D, BIT(7), 8, BIT(7)}, - [IT83XX_IRQ_WKO88] = {GPIO_H, BIT(4), 9, BIT(0)}, - [IT83XX_IRQ_WKO89] = {GPIO_H, BIT(5), 9, BIT(1)}, - [IT83XX_IRQ_WKO90] = {GPIO_H, BIT(6), 9, BIT(2)}, - [IT83XX_IRQ_WKO91] = {GPIO_A, BIT(0), 9, BIT(3)}, - [IT83XX_IRQ_WKO92] = {GPIO_A, BIT(1), 9, BIT(4)}, - [IT83XX_IRQ_WKO93] = {GPIO_A, BIT(2), 9, BIT(5)}, - [IT83XX_IRQ_WKO94] = {GPIO_B, BIT(4), 9, BIT(6)}, - [IT83XX_IRQ_WKO95] = {GPIO_C, BIT(2), 9, BIT(7)}, - [IT83XX_IRQ_WKO96] = {GPIO_F, BIT(0), 10, BIT(0)}, - [IT83XX_IRQ_WKO97] = {GPIO_F, BIT(1), 10, BIT(1)}, - [IT83XX_IRQ_WKO98] = {GPIO_F, BIT(2), 10, BIT(2)}, - [IT83XX_IRQ_WKO99] = {GPIO_F, BIT(3), 10, BIT(3)}, - [IT83XX_IRQ_WKO100] = {GPIO_A, BIT(7), 10, BIT(4)}, - [IT83XX_IRQ_WKO101] = {GPIO_B, BIT(0), 10, BIT(5)}, - [IT83XX_IRQ_WKO102] = {GPIO_B, BIT(1), 10, BIT(6)}, - [IT83XX_IRQ_WKO103] = {GPIO_B, BIT(3), 10, BIT(7)}, - [IT83XX_IRQ_WKO104] = {GPIO_B, BIT(5), 11, BIT(0)}, - [IT83XX_IRQ_WKO105] = {GPIO_B, BIT(6), 11, BIT(1)}, - [IT83XX_IRQ_WKO106] = {GPIO_B, BIT(7), 11, BIT(2)}, - [IT83XX_IRQ_WKO107] = {GPIO_C, BIT(1), 11, BIT(3)}, - [IT83XX_IRQ_WKO108] = {GPIO_C, BIT(3), 11, BIT(4)}, - [IT83XX_IRQ_WKO109] = {GPIO_C, BIT(5), 11, BIT(5)}, - [IT83XX_IRQ_WKO110] = {GPIO_D, BIT(3), 11, BIT(6)}, - [IT83XX_IRQ_WKO111] = {GPIO_D, BIT(4), 11, BIT(7)}, - [IT83XX_IRQ_WKO112] = {GPIO_D, BIT(5), 12, BIT(0)}, - [IT83XX_IRQ_WKO113] = {GPIO_D, BIT(6), 12, BIT(1)}, - [IT83XX_IRQ_WKO114] = {GPIO_E, BIT(4), 12, BIT(2)}, - [IT83XX_IRQ_WKO115] = {GPIO_G, BIT(0), 12, BIT(3)}, - [IT83XX_IRQ_WKO116] = {GPIO_G, BIT(1), 12, BIT(4)}, - [IT83XX_IRQ_WKO117] = {GPIO_G, BIT(2), 12, BIT(5)}, - [IT83XX_IRQ_WKO118] = {GPIO_G, BIT(6), 12, BIT(6)}, - [IT83XX_IRQ_WKO119] = {GPIO_I, BIT(0), 12, BIT(7)}, - [IT83XX_IRQ_WKO120] = {GPIO_I, BIT(1), 13, BIT(0)}, - [IT83XX_IRQ_WKO121] = {GPIO_I, BIT(2), 13, BIT(1)}, - [IT83XX_IRQ_WKO122] = {GPIO_I, BIT(3), 13, BIT(2)}, -#ifdef IT83XX_GPIO_INT_FLEXIBLE - [IT83XX_IRQ_WKO123] = {GPIO_G, BIT(3), 13, BIT(3)}, - [IT83XX_IRQ_WKO124] = {GPIO_G, BIT(4), 13, BIT(4)}, - [IT83XX_IRQ_WKO125] = {GPIO_G, BIT(5), 13, BIT(5)}, - [IT83XX_IRQ_WKO126] = {GPIO_G, BIT(7), 13, BIT(6)}, -#endif - [IT83XX_IRQ_WKO128] = {GPIO_J, BIT(0), 14, BIT(0)}, - [IT83XX_IRQ_WKO129] = {GPIO_J, BIT(1), 14, BIT(1)}, - [IT83XX_IRQ_WKO130] = {GPIO_J, BIT(2), 14, BIT(2)}, - [IT83XX_IRQ_WKO131] = {GPIO_J, BIT(3), 14, BIT(3)}, - [IT83XX_IRQ_WKO132] = {GPIO_J, BIT(4), 14, BIT(4)}, - [IT83XX_IRQ_WKO133] = {GPIO_J, BIT(5), 14, BIT(5)}, - [IT83XX_IRQ_WKO134] = {GPIO_J, BIT(6), 14, BIT(6)}, - [IT83XX_IRQ_WKO135] = {GPIO_J, BIT(7), 14, BIT(7)}, - [IT83XX_IRQ_WKO136] = {GPIO_L, BIT(0), 15, BIT(0)}, - [IT83XX_IRQ_WKO137] = {GPIO_L, BIT(1), 15, BIT(1)}, - [IT83XX_IRQ_WKO138] = {GPIO_L, BIT(2), 15, BIT(2)}, - [IT83XX_IRQ_WKO139] = {GPIO_L, BIT(3), 15, BIT(3)}, - [IT83XX_IRQ_WKO140] = {GPIO_L, BIT(4), 15, BIT(4)}, - [IT83XX_IRQ_WKO141] = {GPIO_L, BIT(5), 15, BIT(5)}, - [IT83XX_IRQ_WKO142] = {GPIO_L, BIT(6), 15, BIT(6)}, - [IT83XX_IRQ_WKO143] = {GPIO_L, BIT(7), 15, BIT(7)}, -#ifdef IT83XX_GPIO_INT_FLEXIBLE - [IT83XX_IRQ_WKO144] = {GPIO_M, BIT(0), 16, BIT(0)}, - [IT83XX_IRQ_WKO145] = {GPIO_M, BIT(1), 16, BIT(1)}, - [IT83XX_IRQ_WKO146] = {GPIO_M, BIT(2), 16, BIT(2)}, - [IT83XX_IRQ_WKO147] = {GPIO_M, BIT(3), 16, BIT(3)}, - [IT83XX_IRQ_WKO148] = {GPIO_M, BIT(4), 16, BIT(4)}, - [IT83XX_IRQ_WKO149] = {GPIO_M, BIT(5), 16, BIT(5)}, - [IT83XX_IRQ_WKO150] = {GPIO_M, BIT(6), 16, BIT(6)}, -#endif -#if defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) - [IT83XX_IRQ_GPO0] = {GPIO_O, BIT(0), 19, BIT(0)}, - [IT83XX_IRQ_GPO1] = {GPIO_O, BIT(1), 19, BIT(1)}, - [IT83XX_IRQ_GPO2] = {GPIO_O, BIT(2), 19, BIT(2)}, - [IT83XX_IRQ_GPO3] = {GPIO_O, BIT(3), 19, BIT(3)}, - [IT83XX_IRQ_GPP0] = {GPIO_P, BIT(0), 20, BIT(0)}, - [IT83XX_IRQ_GPP1] = {GPIO_P, BIT(1), 20, BIT(1)}, - [IT83XX_IRQ_GPP2] = {GPIO_P, BIT(2), 20, BIT(2)}, - [IT83XX_IRQ_GPP3] = {GPIO_P, BIT(3), 20, BIT(3)}, - [IT83XX_IRQ_GPP4] = {GPIO_P, BIT(4), 20, BIT(4)}, - [IT83XX_IRQ_GPP5] = {GPIO_P, BIT(5), 20, BIT(5)}, - [IT83XX_IRQ_GPP6] = {GPIO_P, BIT(6), 20, BIT(6)}, - [IT83XX_IRQ_GPQ0] = {GPIO_Q, BIT(0), 21, BIT(0)}, - [IT83XX_IRQ_GPQ1] = {GPIO_Q, BIT(1), 21, BIT(1)}, - [IT83XX_IRQ_GPQ2] = {GPIO_Q, BIT(2), 21, BIT(2)}, - [IT83XX_IRQ_GPQ3] = {GPIO_Q, BIT(3), 21, BIT(3)}, - [IT83XX_IRQ_GPQ4] = {GPIO_Q, BIT(4), 21, BIT(4)}, - [IT83XX_IRQ_GPQ5] = {GPIO_Q, BIT(5), 21, BIT(5)}, - [IT83XX_IRQ_GPR0] = {GPIO_R, BIT(0), 22, BIT(0)}, - [IT83XX_IRQ_GPR1] = {GPIO_R, BIT(1), 22, BIT(1)}, - [IT83XX_IRQ_GPR2] = {GPIO_R, BIT(2), 22, BIT(2)}, - [IT83XX_IRQ_GPR3] = {GPIO_R, BIT(3), 22, BIT(3)}, - [IT83XX_IRQ_GPR4] = {GPIO_R, BIT(4), 22, BIT(4)}, - [IT83XX_IRQ_GPR5] = {GPIO_R, BIT(5), 22, BIT(5)}, -#endif - [IT83XX_IRQ_COUNT] = { 0, 0, 0, 0}, -}; -BUILD_ASSERT(ARRAY_SIZE(gpio_irqs) == IT83XX_IRQ_COUNT + 1); - -/** - * Given a GPIO port and mask, find the corresponding WKO interrupt number. - * - * @param port GPIO port - * @param mask GPIO mask - * - * @return IRQ for the WKO interrupt on the corresponding input pin. - */ -static int gpio_to_irq(uint8_t port, uint8_t mask) -{ - int i; - - for (i = 0; i < IT83XX_IRQ_COUNT; i++) { - if (gpio_irqs[i].gpio_port == port && - gpio_irqs[i].gpio_mask == mask) - return i; - } - - return -1; -} - -struct gpio_1p8v_t { - volatile uint8_t *reg; - uint8_t sel; -}; - -static const struct gpio_1p8v_t gpio_1p8v_sel[GPIO_PORT_COUNT][8] = { -#ifdef IT83XX_GPIO_1P8V_PIN_EXTENDED - [GPIO_A] = { [4] = {&IT83XX_GPIO_GRC24, BIT(0)}, - [5] = {&IT83XX_GPIO_GRC24, BIT(1)}, - [6] = {&IT83XX_GPIO_GRC24, BIT(5)}, - [7] = {&IT83XX_GPIO_GRC24, BIT(6)} }, - [GPIO_B] = { [3] = {&IT83XX_GPIO_GRC22, BIT(1)}, - [4] = {&IT83XX_GPIO_GRC22, BIT(0)}, - [5] = {&IT83XX_GPIO_GRC19, BIT(7)}, - [6] = {&IT83XX_GPIO_GRC19, BIT(6)}, - [7] = {&IT83XX_GPIO_GRC24, BIT(4)} }, - [GPIO_C] = { [0] = {&IT83XX_GPIO_GRC22, BIT(7)}, - [1] = {&IT83XX_GPIO_GRC19, BIT(5)}, - [2] = {&IT83XX_GPIO_GRC19, BIT(4)}, - [4] = {&IT83XX_GPIO_GRC24, BIT(2)}, - [6] = {&IT83XX_GPIO_GRC24, BIT(3)}, - [7] = {&IT83XX_GPIO_GRC19, BIT(3)} }, - [GPIO_D] = { [0] = {&IT83XX_GPIO_GRC19, BIT(2)}, - [1] = {&IT83XX_GPIO_GRC19, BIT(1)}, - [2] = {&IT83XX_GPIO_GRC19, BIT(0)}, - [3] = {&IT83XX_GPIO_GRC20, BIT(7)}, - [4] = {&IT83XX_GPIO_GRC20, BIT(6)}, - [5] = {&IT83XX_GPIO_GRC22, BIT(4)}, - [6] = {&IT83XX_GPIO_GRC22, BIT(5)}, - [7] = {&IT83XX_GPIO_GRC22, BIT(6)} }, - [GPIO_E] = { [0] = {&IT83XX_GPIO_GRC20, BIT(5)}, - [1] = {&IT83XX_GPIO_GCR28, BIT(6)}, - [2] = {&IT83XX_GPIO_GCR28, BIT(7)}, - [4] = {&IT83XX_GPIO_GRC22, BIT(2)}, - [5] = {&IT83XX_GPIO_GRC22, BIT(3)}, - [6] = {&IT83XX_GPIO_GRC20, BIT(4)}, - [7] = {&IT83XX_GPIO_GRC20, BIT(3)} }, - [GPIO_F] = { [0] = {&IT83XX_GPIO_GCR28, BIT(4)}, - [1] = {&IT83XX_GPIO_GCR28, BIT(5)}, - [2] = {&IT83XX_GPIO_GRC20, BIT(2)}, - [3] = {&IT83XX_GPIO_GRC20, BIT(1)}, - [4] = {&IT83XX_GPIO_GRC20, BIT(0)}, - [5] = {&IT83XX_GPIO_GRC21, BIT(7)}, - [6] = {&IT83XX_GPIO_GRC21, BIT(6)}, - [7] = {&IT83XX_GPIO_GRC21, BIT(5)} }, - [GPIO_G] = { [0] = {&IT83XX_GPIO_GCR28, BIT(2)}, - [1] = {&IT83XX_GPIO_GRC21, BIT(4)}, - [2] = {&IT83XX_GPIO_GCR28, BIT(3)}, - [6] = {&IT83XX_GPIO_GRC21, BIT(3)} }, - [GPIO_H] = { [0] = {&IT83XX_GPIO_GRC21, BIT(2)}, - [1] = {&IT83XX_GPIO_GRC21, BIT(1)}, - [2] = {&IT83XX_GPIO_GRC21, BIT(0)}, - [5] = {&IT83XX_GPIO_GCR27, BIT(7)}, - [6] = {&IT83XX_GPIO_GCR28, BIT(0)} }, - [GPIO_I] = { [0] = {&IT83XX_GPIO_GCR27, BIT(3)}, - [1] = {&IT83XX_GPIO_GRC23, BIT(4)}, - [2] = {&IT83XX_GPIO_GRC23, BIT(5)}, - [3] = {&IT83XX_GPIO_GRC23, BIT(6)}, - [4] = {&IT83XX_GPIO_GRC23, BIT(7)}, - [5] = {&IT83XX_GPIO_GCR27, BIT(4)}, - [6] = {&IT83XX_GPIO_GCR27, BIT(5)}, - [7] = {&IT83XX_GPIO_GCR27, BIT(6)} }, - [GPIO_J] = { [0] = {&IT83XX_GPIO_GRC23, BIT(0)}, - [1] = {&IT83XX_GPIO_GRC23, BIT(1)}, - [2] = {&IT83XX_GPIO_GRC23, BIT(2)}, - [3] = {&IT83XX_GPIO_GRC23, BIT(3)}, - [4] = {&IT83XX_GPIO_GCR27, BIT(0)}, - [5] = {&IT83XX_GPIO_GCR27, BIT(1)}, - [6] = {&IT83XX_GPIO_GCR27, BIT(2)}, - [7] = {&IT83XX_GPIO_GCR33, BIT(2)} }, - [GPIO_K] = { [0] = {&IT83XX_GPIO_GCR26, BIT(0)}, - [1] = {&IT83XX_GPIO_GCR26, BIT(1)}, - [2] = {&IT83XX_GPIO_GCR26, BIT(2)}, - [3] = {&IT83XX_GPIO_GCR26, BIT(3)}, - [4] = {&IT83XX_GPIO_GCR26, BIT(4)}, - [5] = {&IT83XX_GPIO_GCR26, BIT(5)}, - [6] = {&IT83XX_GPIO_GCR26, BIT(6)}, - [7] = {&IT83XX_GPIO_GCR26, BIT(7)} }, - [GPIO_L] = { [0] = {&IT83XX_GPIO_GCR25, BIT(0)}, - [1] = {&IT83XX_GPIO_GCR25, BIT(1)}, - [2] = {&IT83XX_GPIO_GCR25, BIT(2)}, - [3] = {&IT83XX_GPIO_GCR25, BIT(3)}, - [4] = {&IT83XX_GPIO_GCR25, BIT(4)}, - [5] = {&IT83XX_GPIO_GCR25, BIT(5)}, - [6] = {&IT83XX_GPIO_GCR25, BIT(6)}, - [7] = {&IT83XX_GPIO_GCR25, BIT(7)} }, -#if defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) - [GPIO_O] = { [0] = {&IT83XX_GPIO_GCR31, BIT(0)}, - [1] = {&IT83XX_GPIO_GCR31, BIT(1)}, - [2] = {&IT83XX_GPIO_GCR31, BIT(2)}, - [3] = {&IT83XX_GPIO_GCR31, BIT(3)} }, - [GPIO_P] = { [0] = {&IT83XX_GPIO_GCR32, BIT(0)}, - [1] = {&IT83XX_GPIO_GCR32, BIT(1)}, - [2] = {&IT83XX_GPIO_GCR32, BIT(2)}, - [3] = {&IT83XX_GPIO_GCR32, BIT(3)}, - [4] = {&IT83XX_GPIO_GCR32, BIT(4)}, - [5] = {&IT83XX_GPIO_GCR32, BIT(5)}, - [6] = {&IT83XX_GPIO_GCR32, BIT(6)} }, -#endif -#else - [GPIO_A] = { [4] = {&IT83XX_GPIO_GRC24, BIT(0)}, - [5] = {&IT83XX_GPIO_GRC24, BIT(1)} }, - [GPIO_B] = { [3] = {&IT83XX_GPIO_GRC22, BIT(1)}, - [4] = {&IT83XX_GPIO_GRC22, BIT(0)}, - [5] = {&IT83XX_GPIO_GRC19, BIT(7)}, - [6] = {&IT83XX_GPIO_GRC19, BIT(6)} }, - [GPIO_C] = { [1] = {&IT83XX_GPIO_GRC19, BIT(5)}, - [2] = {&IT83XX_GPIO_GRC19, BIT(4)}, - [7] = {&IT83XX_GPIO_GRC19, BIT(3)} }, - [GPIO_D] = { [0] = {&IT83XX_GPIO_GRC19, BIT(2)}, - [1] = {&IT83XX_GPIO_GRC19, BIT(1)}, - [2] = {&IT83XX_GPIO_GRC19, BIT(0)}, - [3] = {&IT83XX_GPIO_GRC20, BIT(7)}, - [4] = {&IT83XX_GPIO_GRC20, BIT(6)} }, - [GPIO_E] = { [0] = {&IT83XX_GPIO_GRC20, BIT(5)}, - [6] = {&IT83XX_GPIO_GRC20, BIT(4)}, - [7] = {&IT83XX_GPIO_GRC20, BIT(3)} }, - [GPIO_F] = { [2] = {&IT83XX_GPIO_GRC20, BIT(2)}, - [3] = {&IT83XX_GPIO_GRC20, BIT(1)}, - [4] = {&IT83XX_GPIO_GRC20, BIT(0)}, - [5] = {&IT83XX_GPIO_GRC21, BIT(7)}, - [6] = {&IT83XX_GPIO_GRC21, BIT(6)}, - [7] = {&IT83XX_GPIO_GRC21, BIT(5)} }, - [GPIO_H] = { [0] = {&IT83XX_GPIO_GRC21, BIT(2)}, - [1] = {&IT83XX_GPIO_GRC21, BIT(1)}, - [2] = {&IT83XX_GPIO_GRC21, BIT(0)} }, - [GPIO_I] = { [1] = {&IT83XX_GPIO_GRC23, BIT(4)}, - [2] = {&IT83XX_GPIO_GRC23, BIT(5)}, - [3] = {&IT83XX_GPIO_GRC23, BIT(6)}, - [4] = {&IT83XX_GPIO_GRC23, BIT(7)} }, - [GPIO_J] = { [0] = {&IT83XX_GPIO_GRC23, BIT(0)}, - [1] = {&IT83XX_GPIO_GRC23, BIT(1)}, - [2] = {&IT83XX_GPIO_GRC23, BIT(2)}, - [3] = {&IT83XX_GPIO_GRC23, BIT(3)} }, -#endif -}; - -static void gpio_1p8v_3p3v_sel_by_pin(uint8_t port, uint8_t pin, int sel_1p8v) -{ - volatile uint8_t *reg_1p8v = gpio_1p8v_sel[port][pin].reg; - uint8_t sel = gpio_1p8v_sel[port][pin].sel; - - if (reg_1p8v == NULL) - return; - - if (sel_1p8v) - *reg_1p8v |= sel; - else - *reg_1p8v &= ~sel; -} - -static inline void it83xx_set_alt_func(uint32_t port, uint32_t pin, - enum gpio_alternate_func func) -{ - /* - * If func is not ALT_FUNC_NONE, set for alternate function. - * Otherwise, turn the pin into an input as it's default. - */ - if (func != GPIO_ALT_FUNC_NONE) - IT83XX_GPIO_CTRL(port, pin) &= ~(GPCR_PORT_PIN_MODE_OUTPUT | - GPCR_PORT_PIN_MODE_INPUT); - else - IT83XX_GPIO_CTRL(port, pin) = - (IT83XX_GPIO_CTRL(port, pin) | GPCR_PORT_PIN_MODE_INPUT) - & ~GPCR_PORT_PIN_MODE_OUTPUT; -} - -void gpio_set_alternate_function(uint32_t port, uint32_t mask, - enum gpio_alternate_func func) -{ - uint32_t pin = 0; - - /* Alternate function configuration for KSI/KSO pins */ - if (port > GPIO_PORT_COUNT) { - port -= GPIO_KSI; - /* - * If func is non-negative, set for keyboard scan function. - * Otherwise, turn the pin into a GPIO input. - */ - if (func >= GPIO_ALT_FUNC_DEFAULT) { - /* KBS mode */ - *kbs_gpio_ctrl_regs[port].gpio_mode &= ~mask; - } else { - /* input */ - *kbs_gpio_ctrl_regs[port].gpio_out &= ~mask; - /* GPIO mode */ - *kbs_gpio_ctrl_regs[port].gpio_mode |= mask; - } - return; - } - - /* For each bit high in the mask, set that pin to use alt. func. */ - while (mask > 0) { - if (mask & 1) - it83xx_set_alt_func(port, pin, func); - pin++; - mask >>= 1; - } -} - -test_mockable int gpio_get_level(enum gpio_signal signal) -{ - return (IT83XX_GPIO_DATA_MIRROR(gpio_list[signal].port) & - gpio_list[signal].mask) ? 1 : 0; -} - -void gpio_set_level(enum gpio_signal signal, int value) -{ - /* critical section with interrupts off */ - uint32_t int_mask = read_clear_int_mask(); - - if (value) - IT83XX_GPIO_DATA(gpio_list[signal].port) |= - gpio_list[signal].mask; - else - IT83XX_GPIO_DATA(gpio_list[signal].port) &= - ~gpio_list[signal].mask; - /* restore interrupts */ - set_int_mask(int_mask); -} - -void gpio_kbs_pin_gpio_mode(uint32_t port, uint32_t mask, uint32_t flags) -{ - uint32_t idx = port - GPIO_KSI; - - /* Set GPIO mode */ - *kbs_gpio_ctrl_regs[idx].gpio_mode |= mask; - - /* Set input or output */ - if (flags & GPIO_OUTPUT) { - /* - * Select open drain first, so that we don't glitch the signal - * when changing the line to an output. - */ - if (flags & GPIO_OPEN_DRAIN) - /* - * it83xx: need external pullup for output data high - * it8xxx2: this pin is always internal pullup - */ - IT83XX_GPIO_GPOT(port) |= mask; - else - /* - * it8xxx2: this pin is not internal pullup - */ - IT83XX_GPIO_GPOT(port) &= ~mask; - - /* Set level before change to output. */ - if (flags & GPIO_HIGH) - IT83XX_GPIO_DATA(port) |= mask; - else if (flags & GPIO_LOW) - IT83XX_GPIO_DATA(port) &= ~mask; - *kbs_gpio_ctrl_regs[idx].gpio_out |= mask; - } else { - *kbs_gpio_ctrl_regs[idx].gpio_out &= ~mask; - if (flags & GPIO_PULL_UP) - IT83XX_GPIO_GPOT(port) |= mask; - else - /* No internal pullup and pulldown */ - IT83XX_GPIO_GPOT(port) &= ~mask; - } -} - -#ifndef IT83XX_GPIO_INT_FLEXIBLE -/* Returns true when the falling trigger bit actually mean both trigger. */ -static int group_falling_is_both(const int group) -{ - return group == 7 || group == 10 || group == 12; -} - -static const char *get_gpio_string(const int port, const int mask) -{ - static char buffer[3]; - int i; - - buffer[0] = port - GPIO_A + 'A'; - buffer[1] = '!'; - - for (i = 0; i < 8; ++i) { - if (mask & BIT(i)) { - buffer[1] = i + '0'; - break; - } - } - return buffer; -} -#endif /* IT83XX_GPIO_INT_FLEXIBLE */ - -void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) -{ - uint32_t pin = 0; - uint32_t mask_copy = mask; - - /* Set GPIO mode for KSI/KSO pins */ - if (port > GPIO_PORT_COUNT) { - gpio_kbs_pin_gpio_mode(port, mask, flags); - return; - } - - /* - * Select open drain first, so that we don't glitch the signal - * when changing the line to an output. - */ - if (flags & GPIO_OPEN_DRAIN) - IT83XX_GPIO_GPOT(port) |= mask; - else - IT83XX_GPIO_GPOT(port) &= ~mask; - - /* If output, set level before changing type to an output. */ - if (flags & GPIO_OUTPUT) { - if (flags & GPIO_HIGH) - IT83XX_GPIO_DATA(port) |= mask; - else if (flags & GPIO_LOW) - IT83XX_GPIO_DATA(port) &= ~mask; - } - - /* For each bit high in the mask, set input/output and pullup/down. */ - while (mask_copy > 0) { - if (mask_copy & 1) { - /* Set input or output. */ - if (flags & GPIO_OUTPUT) - IT83XX_GPIO_CTRL(port, pin) = - (IT83XX_GPIO_CTRL(port, pin) | - GPCR_PORT_PIN_MODE_OUTPUT) & - ~GPCR_PORT_PIN_MODE_INPUT; - else - IT83XX_GPIO_CTRL(port, pin) = - (IT83XX_GPIO_CTRL(port, pin) | - GPCR_PORT_PIN_MODE_INPUT) & - ~GPCR_PORT_PIN_MODE_OUTPUT; - - /* Handle pullup / pulldown */ - if (flags & GPIO_PULL_UP) { - IT83XX_GPIO_CTRL(port, pin) = - (IT83XX_GPIO_CTRL(port, pin) | - GPCR_PORT_PIN_MODE_PULLUP) & - ~GPCR_PORT_PIN_MODE_PULLDOWN; - } else if (flags & GPIO_PULL_DOWN) { - IT83XX_GPIO_CTRL(port, pin) = - (IT83XX_GPIO_CTRL(port, pin) | - GPCR_PORT_PIN_MODE_PULLDOWN) & - ~GPCR_PORT_PIN_MODE_PULLUP; - } else { - /* No pull up/down */ - IT83XX_GPIO_CTRL(port, pin) &= - ~(GPCR_PORT_PIN_MODE_PULLUP | - GPCR_PORT_PIN_MODE_PULLDOWN); - } - - /* To select 1.8v or 3.3v support. */ - gpio_1p8v_3p3v_sel_by_pin(port, pin, - (flags & GPIO_SEL_1P8V)); - } - - pin++; - mask_copy >>= 1; - } - - if (flags & (GPIO_INT_F_RISING | GPIO_INT_F_FALLING)) { - int irq, wuc_group, wuc_mask; - irq = gpio_to_irq(port, mask); - wuc_group = gpio_irqs[irq].wuc_group; - wuc_mask = gpio_irqs[irq].wuc_mask; - - /* - * Set both edges interrupt. - * The WUBEMR register is valid on IT8320 DX version. - * And the setting (falling or rising edge) of WUEMR register is - * invalid if this mode is set. - */ -#ifdef IT83XX_GPIO_INT_FLEXIBLE - if ((flags & GPIO_INT_BOTH) == GPIO_INT_BOTH) - *(wubemr(wuc_group)) |= wuc_mask; - else - *(wubemr(wuc_group)) &= ~wuc_mask; -#endif - - if (flags & GPIO_INT_F_FALLING) { -#ifndef IT83XX_GPIO_INT_FLEXIBLE - if (!!(flags & GPIO_INT_F_RISING) != - group_falling_is_both(wuc_group)) { - ccprintf("!!Fix GPIO %s interrupt config!!\n", - get_gpio_string(port, mask)); - } -#endif - *(wuemr(wuc_group)) |= wuc_mask; - } else { - *(wuemr(wuc_group)) &= ~wuc_mask; - } - /* - * Always write 1 to clear the WUC status register after - * modifying edge mode selection register (WUBEMR and WUEMR). - */ - *(wuesr(wuc_group)) = wuc_mask; - } -} - -int gpio_enable_interrupt(enum gpio_signal signal) -{ - int irq = gpio_to_irq(gpio_list[signal].port, gpio_list[signal].mask); - - if (irq == -1) - return EC_ERROR_UNKNOWN; - else - task_enable_irq(irq); - - return EC_SUCCESS; -} - -int gpio_disable_interrupt(enum gpio_signal signal) -{ - int irq = gpio_to_irq(gpio_list[signal].port, gpio_list[signal].mask); - - if (irq == -1) - return EC_ERROR_UNKNOWN; - else - task_disable_irq(irq); - - return EC_SUCCESS; -} - -int gpio_clear_pending_interrupt(enum gpio_signal signal) -{ - int irq = gpio_to_irq(gpio_list[signal].port, gpio_list[signal].mask); - - if (irq == -1) - return EC_ERROR_UNKNOWN; - - *(wuesr(gpio_irqs[irq].wuc_group)) = gpio_irqs[irq].wuc_mask; - task_clear_pending_irq(irq); - return EC_SUCCESS; -} - -/* To prevent cc pins leakage, disables integrated cc module. */ -void it83xx_disable_cc_module(int port) -{ - /* Power down all CC, and disable CC voltage detector */ - IT83XX_USBPD_CCGCR(port) |= USBPD_REG_MASK_DISABLE_CC; -#if defined(CONFIG_USB_PD_TCPM_DRIVER_IT83XX) - IT83XX_USBPD_CCCSR(port) |= USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR; -#elif defined(CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2) - IT83XX_USBPD_CCGCR(port) |= USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR; -#endif - /* - * Disconnect CC analog module (ex.UP/RD/DET/TX/RX), and - * disconnect CC 5.1K to GND - */ - IT83XX_USBPD_CCCSR(port) |= (USBPD_REG_MASK_CC2_DISCONNECT | - USBPD_REG_MASK_CC2_DISCONNECT_5_1K_TO_GND | - USBPD_REG_MASK_CC1_DISCONNECT | - USBPD_REG_MASK_CC1_DISCONNECT_5_1K_TO_GND); - /* Disconnect CC 5V tolerant */ - IT83XX_USBPD_CCPSR(port) |= (USBPD_REG_MASK_DISCONNECT_POWER_CC2 | - USBPD_REG_MASK_DISCONNECT_POWER_CC1); -} - -void gpio_pre_init(void) -{ - const struct gpio_info *g = gpio_list; - int is_warm = system_is_reboot_warm(); - int flags; - int i; - - IT83XX_GPIO_GCR = 0x06; - -#if !defined(CONFIG_IT83XX_VCC_1P8V) && !defined(CONFIG_IT83XX_VCC_3P3V) -#error Please select voltage level of VCC for EC. -#endif - -#if defined(CONFIG_IT83XX_VCC_1P8V) && defined(CONFIG_IT83XX_VCC_3P3V) -#error Must select only one voltage level of VCC for EC. -#endif - /* The power level of GPM6 follows VCC */ - IT83XX_GPIO_GCR29 |= BIT(0); - - /* The power level (VCC) of GPM0~6 is 1.8V */ - if (IS_ENABLED(CONFIG_IT83XX_VCC_1P8V)) - IT83XX_GPIO_GCR30 |= BIT(4); - - /* The power level (VCC) of GPM0~6 is 3.3V */ - if (IS_ENABLED(CONFIG_IT83XX_VCC_3P3V)) - IT83XX_GPIO_GCR30 &= ~BIT(4); - -#if IT83XX_USBPD_PHY_PORT_COUNT < CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT -#error "ITE pd active port count should be less than physical port count !" -#endif - /* - * To prevent cc pins leakage and cc pins can be used as gpio, - * disable board not active ITE TCPC port cc modules. - */ - for (i = CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT; - i < IT83XX_USBPD_PHY_PORT_COUNT; i++) { - it83xx_disable_cc_module(i); - /* Dis-connect 5.1K dead battery resistor to CC */ - IT83XX_USBPD_CCPSR(i) |= - (USBPD_REG_MASK_DISCONNECT_5_1K_CC2_DB | - USBPD_REG_MASK_DISCONNECT_5_1K_CC1_DB); - } - -#ifndef CONFIG_USB - /* - * We need to enable USB's clock so we can config USB control register. - * This is important for a software reset as the hardware clock may - * already be disabled from the previous run. - * We will disable clock to USB module in clock_module_disable() later. - */ - clock_enable_peripheral(CGC_OFFSET_USB, 0, 0); - /* - * Disable default pull-down of USB controller (GPH5 and GPH6) if we - * don't use this module. - */ - IT83XX_USB_P0MCR &= ~USB_DP_DM_PULL_DOWN_EN; -#endif - -#if defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) - /* Q group pins are default GPI mode, clear alternate setting. */ - IT83XX_VBATPC_XLPIER = 0x0; - /* - * R group pins are default alternate output low, we clear alternate - * setting (sink power switch from VBAT to VSTBY) to become GPO output - * low. - * NOTE: GPR0~5 pins are output low by default. It should consider - * that if output low signal effect external circuit or not, - * until we reconfig these pins in gpio.inc. - */ - IT83XX_VBATPC_BGPOPSCR = 0x0; -#endif - - /* - * On IT81202 (128-pins package), the pins of GPIO group K and L aren't - * bonding with pad. So we configure these pins as internal pull-down - * at default to prevent leakage current due to floating. - */ - if (IS_ENABLED(IT83XX_GPIO_GROUP_K_L_DEFAULT_PULL_DOWN)) { - for (i = 0; i < 8; i++) { - IT83XX_GPIO_CTRL(GPIO_K, i) = (GPCR_PORT_PIN_MODE_INPUT - | GPCR_PORT_PIN_MODE_PULLDOWN); - IT83XX_GPIO_CTRL(GPIO_L, i) = (GPCR_PORT_PIN_MODE_INPUT - | GPCR_PORT_PIN_MODE_PULLDOWN); - } - } - - /* - * On IT81202/IT81302, the GPIOH7 isn't bonding with pad and is left - * floating internally. We need to enable internal pull-down for the pin - * to prevent leakage current, but IT81202/IT81302 doesn't have the - * capability to pull it down. We can only set it as output low, - * so we enable output low for it at initialization to prevent leakage. - */ - if (IS_ENABLED(IT83XX_GPIO_H7_DEFAULT_OUTPUT_LOW)) { - IT83XX_GPIO_CTRL(GPIO_H, 7) = GPCR_PORT_PIN_MODE_OUTPUT; - IT83XX_GPIO_DATA(GPIO_H) &= ~BIT(7); - } - - 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); - } -} - -/** - * Handle a GPIO interrupt by calling the pins corresponding handler if - * one exists. - * - * @param port GPIO port (GPIO_*) - * @param mask GPIO mask - */ -static void gpio_interrupt(int port, uint8_t mask) -{ - int i = 0; - const struct gpio_info *g = gpio_list; - - for (i = 0; i < GPIO_IH_COUNT; i++, g++) { - if (port == g->port && (mask & g->mask)) { - gpio_irq_handlers[i](i); - return; - } - } -} - -/** - * Define one IRQ function to handle all GPIO interrupts. The IRQ determines - * the interrupt number which was triggered, calls the master handler above, - * and clears status registers. - */ -static void __gpio_irq(void) -{ - /* Determine interrupt number. */ - int irq = intc_get_ec_int(); - - /* assert failure if interrupt number is zero */ - ASSERT(irq); - -#if defined(HAS_TASK_KEYSCAN) && !defined(CONFIG_KEYBOARD_NOT_RAW) - if (irq == IT83XX_IRQ_WKINTC) { - keyboard_raw_interrupt(); - return; - } -#endif - -#ifdef CONFIG_HOSTCMD_X86 - if (irq == IT83XX_IRQ_WKINTAD) - return; -#endif - - /* - * Clear the WUC status register. Note the external pin first goes - * to the WUC module and is always edge triggered. - */ - *(wuesr(gpio_irqs[irq].wuc_group)) = gpio_irqs[irq].wuc_mask; - - /* - * Clear the interrupt controller status register. Note the interrupt - * controller is level triggered from the WUC status. - */ - task_clear_pending_irq(irq); - - /* Run the GPIO master handler above with corresponding port/mask. */ - gpio_interrupt(gpio_irqs[irq].gpio_port, gpio_irqs[irq].gpio_mask); -} - -/* Route all WKO interrupts coming from INT#2 into __gpio_irq. */ -DECLARE_IRQ(CPU_INT_2_ALL_GPIOS, __gpio_irq, 1); diff --git a/chip/it83xx/hwtimer.c b/chip/it83xx/hwtimer.c deleted file mode 100644 index 291751a1cb..0000000000 --- a/chip/it83xx/hwtimer.c +++ /dev/null @@ -1,345 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Hardware timers driver */ - -#include "cpu.h" -#include "common.h" -#include "hooks.h" -#include "hwtimer.h" -#include "hwtimer_chip.h" -#include "intc.h" -#include "irq_chip.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "watchdog.h" - -/* - * The IT839X series support combinational mode for combining specific pairs of - * timers: 3(24-bit) and 4(32-bit) / timer 5(24-bit) and 6(32-bit) / - * timer 7(24-bit) and 8(32-bit). - * - * 32-bit MHz free-running counter: We combine (bit3@IT83XX_ETWD_ETXCTRL) - * timer 3(TIMER_L) and 4(TIMER_H) and set clock source register to 8MHz. - * In combinational mode, the counter register(IT83XX_ETWD_ETXCNTLR) of timer 3 - * is a fixed value = 7, and observation register(IT83XX_ETWD_ETXCNTOR) - * of timer 4 will increase one per-us. - * - * For example, if - * __hw_clock_source_set() set 0 us, the counter setting registers are - * timer 3(TIMER_L) = 0x000007 (fixed, will not change) - * timer 4(TIMER_H) = 0xffffffff - * - * Note: - * In combinational mode, the counter observation value of - * timer 4(TIMER_H), 6, 8 will in incrementing order. - * For the above example, the counter observation value registers will be - * timer 3(TIMER_L) 0x0000007 - * timer 4(TIMER_H) ~0xffffffff = 0x00000000 - * - * The following will describe timer 3 and 4's operation in combinational mode: - * 1. When timer 3(TIMER_L) has completed each counting (per-us), - timer 4(TIMER_H) observation value++. - * 2. When timer 4(TIMER_H) observation value overflows: - * timer 4(TIMER_H) observation value = ~counter setting register. - * 3. Timer 4(TIMER_H) interrupt occurs. - * - * IT839X only supports terminal count interrupt. We need a separate - * 8 MHz 32-bit timer to handle events. - */ - -#define MS_TO_COUNT(hz, ms) ((hz) * (ms) / 1000) - -const struct ext_timer_ctrl_t et_ctrl_regs[] = { - {&IT83XX_INTC_IELMR19, &IT83XX_INTC_IPOLR19, &IT83XX_INTC_ISR19, 0x08, - IT83XX_IRQ_EXT_TIMER3}, - {&IT83XX_INTC_IELMR19, &IT83XX_INTC_IPOLR19, &IT83XX_INTC_ISR19, 0x10, - IT83XX_IRQ_EXT_TIMER4}, - {&IT83XX_INTC_IELMR19, &IT83XX_INTC_IPOLR19, &IT83XX_INTC_ISR19, 0x20, - IT83XX_IRQ_EXT_TIMER5}, - {&IT83XX_INTC_IELMR19, &IT83XX_INTC_IPOLR19, &IT83XX_INTC_ISR19, 0x40, - IT83XX_IRQ_EXT_TIMER6}, - {&IT83XX_INTC_IELMR19, &IT83XX_INTC_IPOLR19, &IT83XX_INTC_ISR19, 0x80, - IT83XX_IRQ_EXT_TIMER7}, - {&IT83XX_INTC_IELMR10, &IT83XX_INTC_IPOLR10, &IT83XX_INTC_ISR10, 0x01, - IT83XX_IRQ_EXT_TMR8}, -}; -BUILD_ASSERT(ARRAY_SIZE(et_ctrl_regs) == EXT_TIMER_COUNT); - -static void free_run_timer_overflow(void) -{ - /* - * If timer 4 (TIMER_H) counter register != 0xffffffff. - * This usually happens once after sysjump, force time, and etc. - * (when __hw_clock_source_set is called and param 'ts' != 0) - */ - if (IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) != 0xffffffff) { - /* set timer counter register */ - IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) = 0xffffffff; - /* bit[1], timer reset */ - IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= BIT(1); - } - /* w/c interrupt status */ - task_clear_pending_irq(et_ctrl_regs[FREE_EXT_TIMER_H].irq); - /* timer overflow */ - process_timers(1); - update_exc_start_time(); -} - -static void event_timer_clear_pending_isr(void) -{ - /* w/c interrupt status */ - task_clear_pending_irq(et_ctrl_regs[EVENT_EXT_TIMER].irq); -} - -uint32_t __ram_code __hw_clock_source_read(void) -{ -#ifdef IT83XX_EXT_OBSERVATION_REG_READ_TWO_TIMES - /* - * In combinational mode, the counter observation register of - * timer 4(TIMER_H) will increment. - */ - return ext_observation_reg_read(FREE_EXT_TIMER_H); -#else - return IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H); -#endif -} - -void __hw_clock_source_set(uint32_t ts) -{ - /* counting down timer, microseconds to timer counter register */ - IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) = 0xffffffff - ts; - /* bit[1], timer reset */ - IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= BIT(1); -} - -void __hw_clock_event_set(uint32_t deadline) -{ - uint32_t wait; - /* bit0, disable event timer */ - IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) &= ~BIT(0); - /* w/c interrupt status */ - event_timer_clear_pending_isr(); - /* microseconds to timer counter */ - wait = deadline - __hw_clock_source_read(); - IT83XX_ETWD_ETXCNTLR(EVENT_EXT_TIMER) = - wait < EVENT_TIMER_COUNT_TO_US(0xffffffff) ? - EVENT_TIMER_US_TO_COUNT(wait) : 0xffffffff; - /* enable and re-start timer */ - IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) |= 0x03; - task_enable_irq(et_ctrl_regs[EVENT_EXT_TIMER].irq); -} - -uint32_t __hw_clock_event_get(void) -{ - uint32_t next_event_us = __hw_clock_source_read(); - - /* bit0, event timer is enabled */ - if (IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) & BIT(0)) { - /* timer counter observation value to microseconds */ - next_event_us += EVENT_TIMER_COUNT_TO_US( -#ifdef IT83XX_EXT_OBSERVATION_REG_READ_TWO_TIMES - ext_observation_reg_read(EVENT_EXT_TIMER)); -#else - IT83XX_ETWD_ETXCNTOR(EVENT_EXT_TIMER)); -#endif - } - return next_event_us; -} - -void __hw_clock_event_clear(void) -{ - /* stop event timer */ - ext_timer_stop(EVENT_EXT_TIMER, 1); - event_timer_clear_pending_isr(); -} - -int __hw_clock_source_init(uint32_t start_t) -{ - /* bit3, timer 3 and timer 4 combinational mode */ - IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= BIT(3); - /* init free running timer (timer 4, TIMER_H), clock source is 8mhz */ - ext_timer_ms(FREE_EXT_TIMER_H, EXT_PSR_8M_HZ, 0, 1, 0xffffffff, 1, 1); - /* 1us counter setting (timer 3, TIMER_L) */ - ext_timer_ms(FREE_EXT_TIMER_L, EXT_PSR_8M_HZ, 1, 0, 7, 1, 1); - __hw_clock_source_set(start_t); - /* init event timer */ - ext_timer_ms(EVENT_EXT_TIMER, EXT_PSR_8M_HZ, 0, 0, 0xffffffff, 1, 1); - /* returns the IRQ number of event timer */ - return et_ctrl_regs[EVENT_EXT_TIMER].irq; -} - -static void __hw_clock_source_irq(void) -{ - /* Determine interrupt number. */ - int irq = intc_get_ec_int(); - - /* SW/HW interrupt of event timer. */ - if (irq == et_ctrl_regs[EVENT_EXT_TIMER].irq) { - IT83XX_ETWD_ETXCNTLR(EVENT_EXT_TIMER) = 0xffffffff; - IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) |= BIT(1); - event_timer_clear_pending_isr(); - process_timers(0); - return; - } - -#ifdef CONFIG_WATCHDOG - /* - * Both the external timer for the watchdog warning and the HW timer - * go through this irq. So, if this interrupt was caused by watchdog - * warning timer, then call that function. - */ - if (irq == et_ctrl_regs[WDT_EXT_TIMER].irq) { - watchdog_warning_irq(); - return; - } -#endif - -#ifdef CONFIG_FANS - if (irq == et_ctrl_regs[FAN_CTRL_EXT_TIMER].irq) { - fan_ext_timer_interrupt(); - return; - } -#endif - - /* Interrupt of free running timer TIMER_H. */ - if (irq == et_ctrl_regs[FREE_EXT_TIMER_H].irq) { - free_run_timer_overflow(); - return; - } - - /* - * This interrupt is used to wakeup EC from sleep mode - * to complete PLL frequency change. - */ - if (irq == et_ctrl_regs[LOW_POWER_EXT_TIMER].irq) { - ext_timer_stop(LOW_POWER_EXT_TIMER, 1); - return; - } -} -DECLARE_IRQ(CPU_INT_GROUP_3, __hw_clock_source_irq, 1); - -#ifdef IT83XX_EXT_OBSERVATION_REG_READ_TWO_TIMES -/* Number of CPU cycles in 125 us */ -#define CYCLES_125NS (125*(PLL_CLOCK/SECOND) / 1000) -uint32_t __ram_code ext_observation_reg_read(enum ext_timer_sel ext_timer) -{ - uint32_t prev_mask = read_clear_int_mask(); - uint32_t val; - - asm volatile( - /* read observation register for the first time */ - "lwi %0,[%1]\n\t" - /* - * the delay time between reading the first and second - * observation registers need to be greater than 0.125us and - * smaller than 0.250us. - */ - ".rept %2\n\t" - "nop\n\t" - ".endr\n\t" - /* read for the second time */ - "lwi %0,[%1]\n\t" - : "=&r"(val) - : "r"((uintptr_t) &IT83XX_ETWD_ETXCNTOR(ext_timer)), - "i"(CYCLES_125NS)); - /* restore interrupts */ - set_int_mask(prev_mask); - - return val; -} -#endif - -void ext_timer_start(enum ext_timer_sel ext_timer, int en_irq) -{ - /* enable external timer n */ - IT83XX_ETWD_ETXCTRL(ext_timer) |= 0x03; - - if (en_irq) { - task_clear_pending_irq(et_ctrl_regs[ext_timer].irq); - task_enable_irq(et_ctrl_regs[ext_timer].irq); - } -} - -void ext_timer_stop(enum ext_timer_sel ext_timer, int dis_irq) -{ - /* disable external timer n */ - IT83XX_ETWD_ETXCTRL(ext_timer) &= ~0x01; - - if (dis_irq) - task_disable_irq(et_ctrl_regs[ext_timer].irq); -} - -static void ext_timer_ctrl(enum ext_timer_sel ext_timer, - enum ext_timer_clock_source ext_timer_clock, - int start, - int with_int, - int32_t count) -{ - uint8_t intc_mask; - - /* rising-edge-triggered */ - intc_mask = et_ctrl_regs[ext_timer].mask; - *et_ctrl_regs[ext_timer].mode |= intc_mask; - *et_ctrl_regs[ext_timer].polarity &= ~intc_mask; - - /* clear interrupt status */ - task_clear_pending_irq(et_ctrl_regs[ext_timer].irq); - - /* These bits control the clock input source to the exttimer 3 - 8 */ - IT83XX_ETWD_ETXPSR(ext_timer) = ext_timer_clock; - - /* The count number of external timer n. */ - IT83XX_ETWD_ETXCNTLR(ext_timer) = count; - - ext_timer_stop(ext_timer, 0); - if (start) - ext_timer_start(ext_timer, 0); - - if (with_int) - task_enable_irq(et_ctrl_regs[ext_timer].irq); - else - task_disable_irq(et_ctrl_regs[ext_timer].irq); -} - -int ext_timer_ms(enum ext_timer_sel ext_timer, - enum ext_timer_clock_source ext_timer_clock, - int start, - int with_int, - int32_t ms, - int first_time_enable, - int raw) -{ - uint32_t count; - - if (raw) { - count = ms; - } else { - if (ext_timer_clock == EXT_PSR_32P768K_HZ) - count = MS_TO_COUNT(32768, ms); - else if (ext_timer_clock == EXT_PSR_1P024K_HZ) - count = MS_TO_COUNT(1024, ms); - else if (ext_timer_clock == EXT_PSR_32_HZ) - count = MS_TO_COUNT(32, ms); - else if (ext_timer_clock == EXT_PSR_8M_HZ) - count = 8000 * ms; - else - return -1; - } - - if (count == 0) - return -3; - - if (first_time_enable) { - ext_timer_start(ext_timer, 0); - ext_timer_stop(ext_timer, 0); - } - - ext_timer_ctrl(ext_timer, ext_timer_clock, start, with_int, count); - - return 0; -} diff --git a/chip/it83xx/hwtimer_chip.h b/chip/it83xx/hwtimer_chip.h deleted file mode 100644 index 2ccdce1d96..0000000000 --- a/chip/it83xx/hwtimer_chip.h +++ /dev/null @@ -1,93 +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. - */ - -/* External timers control module for IT83xx. */ - -#ifndef __CROS_EC_HWTIMER_CHIP_H -#define __CROS_EC_HWTIMER_CHIP_H - -#define TIMER_COUNT_1US_SHIFT 3 - -/* Microseconds to event timer counter setting register */ -#define EVENT_TIMER_US_TO_COUNT(us) ((us) << TIMER_COUNT_1US_SHIFT) -/* Event timer counter observation value to microseconds */ -#define EVENT_TIMER_COUNT_TO_US(cnt) ((cnt) >> TIMER_COUNT_1US_SHIFT) - -#define FREE_EXT_TIMER_L EXT_TIMER_3 -#define FREE_EXT_TIMER_H EXT_TIMER_4 -#define FAN_CTRL_EXT_TIMER EXT_TIMER_5 -#define EVENT_EXT_TIMER EXT_TIMER_6 -/* - * The low power timer is used to continue system time when EC goes into low - * power in idle task. Timer 7 is 24bit timer and configured at 32.768khz. - * The configuration is enough for continuing system time, because periodic - * tick event (interval is 500ms on it8xxx2) will wake EC up. - * - * IMPORTANT: - * If you change low power timer to a non-24bit timer, you also have to change - * mask of observation register in clock_sleep_mode_wakeup_isr() or EC will get - * wrong system time after resume. - */ -#define LOW_POWER_EXT_TIMER EXT_TIMER_7 -#define LOW_POWER_TIMER_MASK (BIT(24) - 1) -#define WDT_EXT_TIMER EXT_TIMER_8 - -enum ext_timer_clock_source { - EXT_PSR_32P768K_HZ = 0, - EXT_PSR_1P024K_HZ = 1, - EXT_PSR_32_HZ = 2, - EXT_PSR_8M_HZ = 3 -}; - -/* - * 24-bit timers: external timer 3, 5, and 7 - * 32-bit timers: external timer 4, 6, and 8 - */ -enum ext_timer_sel { - /* timer 3 and 4 combine mode for free running timer */ - EXT_TIMER_3 = 0, - EXT_TIMER_4, - /* For fan control */ - EXT_TIMER_5, - /* timer 6 for event timer */ - EXT_TIMER_6, - /* For WDT capture important state information before being reset */ - EXT_TIMER_7, - /* HW timer for low power mode */ - EXT_TIMER_8, - EXT_TIMER_COUNT, -}; - -struct ext_timer_ctrl_t { - volatile uint8_t *mode; - volatile uint8_t *polarity; - volatile uint8_t *isr; - uint8_t mask; - uint8_t irq; -}; - -extern const struct ext_timer_ctrl_t et_ctrl_regs[]; -#ifdef IT83XX_EXT_OBSERVATION_REG_READ_TWO_TIMES -uint32_t __ram_code ext_observation_reg_read(enum ext_timer_sel ext_timer); -#endif -void ext_timer_start(enum ext_timer_sel ext_timer, int en_irq); -void ext_timer_stop(enum ext_timer_sel ext_timer, int dis_irq); -void fan_ext_timer_interrupt(void); -void update_exc_start_time(void); - -/** - * Config a external timer. - * - * @param raw (!=0) timer count equal to param "ms" no conversion. - */ -int ext_timer_ms(enum ext_timer_sel ext_timer, - enum ext_timer_clock_source ext_timer_clock, - int start, - int et_int, - int32_t ms, - int first_time_enable, - int raw); - -#endif /* __CROS_EC_HWTIMER_CHIP_H */ diff --git a/chip/it83xx/i2c.c b/chip/it83xx/i2c.c deleted file mode 100644 index 5aa8f8a460..0000000000 --- a/chip/it83xx/i2c.c +++ /dev/null @@ -1,946 +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. - */ - -/* I2C module for Chrome EC */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) - -/* Default maximum time we allow for an I2C transfer */ -#define I2C_TIMEOUT_DEFAULT_US (100 * MSEC) - -enum enhanced_i2c_transfer_direct { - TX_DIRECT, - RX_DIRECT, -}; - -enum i2c_host_status { - /* Host busy */ - HOSTA_HOBY = 0x01, - /* Finish Interrupt */ - HOSTA_FINTR = 0x02, - /* Device error */ - HOSTA_DVER = 0x04, - /* Bus error */ - HOSTA_BSER = 0x08, - /* Fail */ - HOSTA_FAIL = 0x10, - /* Not response ACK */ - HOSTA_NACK = 0x20, - /* Time-out error */ - HOSTA_TMOE = 0x40, - /* Byte done status */ - HOSTA_BDS = 0x80, - /* Error bit is set */ - HOSTA_ANY_ERROR = (HOSTA_DVER | HOSTA_BSER | - HOSTA_FAIL | HOSTA_NACK | HOSTA_TMOE), - /* W/C for next byte */ - HOSTA_NEXT_BYTE = HOSTA_BDS, - /* W/C host status register */ - HOSTA_ALL_WC_BIT = (HOSTA_FINTR | HOSTA_ANY_ERROR | HOSTA_BDS), -}; - -enum enhanced_i2c_host_status { - /* ACK receive */ - E_HOSTA_ACK = 0x01, - /* Interrupt pending */ - E_HOSTA_INTP = 0x02, - /* Read/Write */ - E_HOSTA_RW = 0x04, - /* Time out error */ - E_HOSTA_TMOE = 0x08, - /* Arbitration lost */ - E_HOSTA_ARB = 0x10, - /* Bus busy */ - E_HOSTA_BB = 0x20, - /* Address match */ - E_HOSTA_AM = 0x40, - /* Byte done status */ - E_HOSTA_BDS = 0x80, - /* time out or lost arbitration */ - E_HOSTA_ANY_ERROR = (E_HOSTA_TMOE | E_HOSTA_ARB), - /* Byte transfer done and ACK receive */ - E_HOSTA_BDS_AND_ACK = (E_HOSTA_BDS | E_HOSTA_ACK), -}; - -enum enhanced_i2c_ctl { - /* Hardware reset */ - E_HW_RST = 0x01, - /* Stop */ - E_STOP = 0x02, - /* Start & Repeat start */ - E_START = 0x04, - /* Acknowledge */ - E_ACK = 0x08, - /* State reset */ - E_STS_RST = 0x10, - /* Mode select */ - E_MODE_SEL = 0x20, - /* I2C interrupt enable */ - E_INT_EN = 0x40, - /* 0 : Standard mode , 1 : Receive mode */ - E_RX_MODE = 0x80, - /* State reset and hardware reset */ - E_STS_AND_HW_RST = (E_STS_RST | E_HW_RST), - /* Generate start condition and transmit peripheral address */ - E_START_ID = (E_INT_EN | E_MODE_SEL | E_ACK | E_START | E_HW_RST), - /* Generate stop condition */ - E_FINISH = (E_INT_EN | E_MODE_SEL | E_ACK | E_STOP | E_HW_RST), -}; - -enum i2c_reset_cause { - I2C_RC_NO_IDLE_FOR_START = 1, - I2C_RC_TIMEOUT, -}; - -struct i2c_ch_freq { - int kbps; - uint8_t freq_set; -}; - -static const struct i2c_ch_freq i2c_freq_select[] = { - { 50, 1}, - { 100, 2}, - { 400, 3}, - { 1000, 4}, -}; - -struct i2c_pin { - volatile uint8_t *pin_clk; - volatile uint8_t *pin_data; - volatile uint8_t *pin_clk_ctrl; - volatile uint8_t *pin_data_ctrl; - volatile uint8_t *mirror_clk; - volatile uint8_t *mirror_data; - uint8_t clk_mask; - uint8_t data_mask; -}; - -static const struct i2c_pin i2c_pin_regs[] = { - { &IT83XX_GPIO_GPCRB3, &IT83XX_GPIO_GPCRB4, - &IT83XX_GPIO_GPDRB, &IT83XX_GPIO_GPDRB, - &IT83XX_GPIO_GPDMRB, &IT83XX_GPIO_GPDMRB, - 0x08, 0x10}, - { &IT83XX_GPIO_GPCRC1, &IT83XX_GPIO_GPCRC2, - &IT83XX_GPIO_GPDRC, &IT83XX_GPIO_GPDRC, - &IT83XX_GPIO_GPDMRC, &IT83XX_GPIO_GPDMRC, - 0x02, 0x04}, -#ifdef CONFIG_IT83XX_SMCLK2_ON_GPC7 - { &IT83XX_GPIO_GPCRC7, &IT83XX_GPIO_GPCRF7, - &IT83XX_GPIO_GPDRC, &IT83XX_GPIO_GPDRF, - &IT83XX_GPIO_GPDMRC, &IT83XX_GPIO_GPDMRF, - 0x80, 0x80}, -#else - { &IT83XX_GPIO_GPCRF6, &IT83XX_GPIO_GPCRF7, - &IT83XX_GPIO_GPDRF, &IT83XX_GPIO_GPDRF, - &IT83XX_GPIO_GPDMRF, &IT83XX_GPIO_GPDMRF, - 0x40, 0x80}, -#endif - { &IT83XX_GPIO_GPCRH1, &IT83XX_GPIO_GPCRH2, - &IT83XX_GPIO_GPDRH, &IT83XX_GPIO_GPDRH, - &IT83XX_GPIO_GPDMRH, &IT83XX_GPIO_GPDMRH, - 0x02, 0x04}, - { &IT83XX_GPIO_GPCRE0, &IT83XX_GPIO_GPCRE7, - &IT83XX_GPIO_GPDRE, &IT83XX_GPIO_GPDRE, - &IT83XX_GPIO_GPDMRE, &IT83XX_GPIO_GPDMRE, - 0x01, 0x80}, - { &IT83XX_GPIO_GPCRA4, &IT83XX_GPIO_GPCRA5, - &IT83XX_GPIO_GPDRA, &IT83XX_GPIO_GPDRA, - &IT83XX_GPIO_GPDMRA, &IT83XX_GPIO_GPDMRA, - 0x10, 0x20}, -}; - -struct i2c_ctrl_t { - uint8_t irq; - enum clock_gate_offsets clock_gate; - int reg_shift; -}; - -const struct i2c_ctrl_t i2c_ctrl_regs[] = { - {IT83XX_IRQ_SMB_A, CGC_OFFSET_SMBA, -1}, - {IT83XX_IRQ_SMB_B, CGC_OFFSET_SMBB, -1}, - {IT83XX_IRQ_SMB_C, CGC_OFFSET_SMBC, -1}, - {IT83XX_IRQ_SMB_D, CGC_OFFSET_SMBD, 3}, - {IT83XX_IRQ_SMB_E, CGC_OFFSET_SMBE, 0}, - {IT83XX_IRQ_SMB_F, CGC_OFFSET_SMBF, 1}, -}; - -enum i2c_ch_status { - I2C_CH_NORMAL = 0, - I2C_CH_REPEAT_START, - I2C_CH_WAIT_READ, - I2C_CH_WAIT_NEXT_XFER, -}; - -/* I2C port state data */ -struct i2c_port_data { - const uint8_t *out; /* Output data pointer */ - int out_size; /* Output data to transfer, in bytes */ - uint8_t *in; /* Input data pointer */ - int in_size; /* Input data to transfer, in bytes */ - int flags; /* Flags (I2C_XFER_*) */ - int widx; /* Index into output data */ - int ridx; /* Index into input data */ - int err; /* Error code, if any */ - uint8_t addr_8bit; /* address of device */ - uint32_t timeout_us; /* Transaction timeout, or 0 to use default */ - uint8_t freq; /* Frequency setting */ - - enum i2c_ch_status i2ccs; - /* Task waiting on port, or TASK_ID_INVALID if none. */ - volatile int task_waiting; -}; -static struct i2c_port_data pdata[I2C_PORT_COUNT]; - -static int i2c_ch_reg_shift(int p) -{ - /* - * only enhanced port needs to be changed the parameter of registers - */ - ASSERT(p >= I2C_STANDARD_PORT_COUNT && p < I2C_PORT_COUNT); - - /* - * The registers of i2c enhanced ports are not sequential. - * This routine transfers the i2c port number to related - * parameter of registers. - * - * IT83xx chip : i2c enhanced ports - channel D,E,F - * channel D registers : 0x3680 ~ 0x36FF - * channel E registers : 0x3500 ~ 0x357F - * channel F registers : 0x3580 ~ 0x35FF - */ - return i2c_ctrl_regs[p].reg_shift; -} - -static void i2c_reset(int p, int cause) -{ - int p_ch; - - if (p < I2C_STANDARD_PORT_COUNT) { - /* bit1, kill current transaction. */ - IT83XX_SMB_HOCTL(p) = 0x2; - IT83XX_SMB_HOCTL(p) = 0; - /* W/C host status register */ - IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; - } else { - /* Shift register */ - p_ch = i2c_ch_reg_shift(p); - /* State reset and hardware reset */ - IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; - } - CPRINTS("I2C ch%d reset cause %d", p, cause); -} - -static void i2c_r_last_byte(int p) -{ - struct i2c_port_data *pd = pdata + p; - - /* - * bit5, The firmware shall write 1 to this bit - * when the next byte will be the last byte for i2c read. - */ - if ((pd->flags & I2C_XFER_STOP) && (pd->ridx == pd->in_size - 1)) - IT83XX_SMB_HOCTL(p) |= 0x20; -} - -static void i2c_w2r_change_direction(int p) -{ - /* I2C switch direction */ - if (IT83XX_SMB_HOCTL2(p) & 0x08) { - i2c_r_last_byte(p); - IT83XX_SMB_HOSTA(p) = HOSTA_NEXT_BYTE; - } else { - /* - * bit2, I2C switch direction wait. - * bit3, I2C switch direction enable. - */ - IT83XX_SMB_HOCTL2(p) |= 0x0C; - IT83XX_SMB_HOSTA(p) = HOSTA_NEXT_BYTE; - i2c_r_last_byte(p); - IT83XX_SMB_HOCTL2(p) &= ~0x04; - } -} - -static void i2c_pio_trans_data(int p, enum enhanced_i2c_transfer_direct direct, - uint8_t data, int first_byte) -{ - struct i2c_port_data *pd = pdata + p; - int p_ch; - int nack = 0; - - /* Shift register */ - p_ch = i2c_ch_reg_shift(p); - - if (first_byte) { - /* First byte must be peripheral address. */ - IT83XX_I2C_DTR(p_ch) = - data | (direct == RX_DIRECT ? BIT(0) : 0); - /* start or repeat start signal. */ - IT83XX_I2C_CTR(p_ch) = E_START_ID; - } else { - if (direct == TX_DIRECT) - /* Transmit data */ - IT83XX_I2C_DTR(p_ch) = data; - else { - /* - * Receive data. - * Last byte should be NACK in the end of read cycle - */ - if (((pd->ridx + 1) == pd->in_size) && - (pd->flags & I2C_XFER_STOP)) - nack = 1; - } - /* Set hardware reset to start next transmission */ - IT83XX_I2C_CTR(p_ch) = - E_INT_EN | E_MODE_SEL | E_HW_RST | (nack ? 0 : E_ACK); - } -} - -static int i2c_tran_write(int p) -{ - struct i2c_port_data *pd = pdata + p; - - if (pd->flags & I2C_XFER_START) { - /* i2c enable */ - IT83XX_SMB_HOCTL2(p) = 0x13; - /* - * bit0, Direction of the host transfer. - * bit[1:7}, Address of the targeted peripheral. - */ - IT83XX_SMB_TRASLA(p) = pd->addr_8bit; - /* Send first byte */ - IT83XX_SMB_HOBDB(p) = *(pd->out++); - pd->widx++; - /* clear start flag */ - pd->flags &= ~I2C_XFER_START; - /* - * bit0, Host interrupt enable. - * bit[2:4}, Extend command. - * bit6, start. - */ - IT83XX_SMB_HOCTL(p) = 0x5D; - } else { - /* Host has completed the transmission of a byte */ - if (IT83XX_SMB_HOSTA(p) & HOSTA_BDS) { - if (pd->widx < pd->out_size) { - /* Send next byte */ - IT83XX_SMB_HOBDB(p) = *(pd->out++); - pd->widx++; - /* W/C byte done for next byte */ - IT83XX_SMB_HOSTA(p) = HOSTA_NEXT_BYTE; - if (pd->i2ccs == I2C_CH_REPEAT_START) { - pd->i2ccs = I2C_CH_NORMAL; - task_enable_irq(i2c_ctrl_regs[p].irq); - } - } else { - /* done */ - pd->out_size = 0; - if (pd->in_size > 0) { - /* write to read */ - i2c_w2r_change_direction(p); - } else { - if (pd->flags & I2C_XFER_STOP) { - /* set I2C_EN = 0 */ - IT83XX_SMB_HOCTL2(p) = 0x11; - /* W/C byte done for finish */ - IT83XX_SMB_HOSTA(p) = - HOSTA_NEXT_BYTE; - } else { - pd->i2ccs = I2C_CH_REPEAT_START; - return 0; - } - } - } - } - } - return 1; -} - -static int i2c_tran_read(int p) -{ - struct i2c_port_data *pd = pdata + p; - - if (pd->flags & I2C_XFER_START) { - /* i2c enable */ - IT83XX_SMB_HOCTL2(p) = 0x13; - /* - * bit0, Direction of the host transfer. - * bit[1:7}, Address of the targeted peripheral. - */ - IT83XX_SMB_TRASLA(p) = pd->addr_8bit | 0x01; - /* clear start flag */ - pd->flags &= ~I2C_XFER_START; - /* - * bit0, Host interrupt enable. - * bit[2:4}, Extend command. - * bit5, The firmware shall write 1 to this bit - * when the next byte will be the last byte. - * bit6, start. - */ - if ((1 == pd->in_size) && (pd->flags & I2C_XFER_STOP)) - IT83XX_SMB_HOCTL(p) = 0x7D; - else - IT83XX_SMB_HOCTL(p) = 0x5D; - } else { - if ((pd->i2ccs == I2C_CH_REPEAT_START) || - (pd->i2ccs == I2C_CH_WAIT_READ)) { - if (pd->i2ccs == I2C_CH_REPEAT_START) { - /* write to read */ - i2c_w2r_change_direction(p); - } else { - /* For last byte */ - i2c_r_last_byte(p); - /* W/C for next byte */ - IT83XX_SMB_HOSTA(p) = HOSTA_NEXT_BYTE; - } - pd->i2ccs = I2C_CH_NORMAL; - task_enable_irq(i2c_ctrl_regs[p].irq); - } else if (IT83XX_SMB_HOSTA(p) & HOSTA_BDS) { - if (pd->ridx < pd->in_size) { - /* To get received data. */ - *(pd->in++) = IT83XX_SMB_HOBDB(p); - pd->ridx++; - /* For last byte */ - i2c_r_last_byte(p); - /* done */ - if (pd->ridx == pd->in_size) { - pd->in_size = 0; - if (pd->flags & I2C_XFER_STOP) { - /* W/C for finish */ - IT83XX_SMB_HOSTA(p) = - HOSTA_NEXT_BYTE; - } else { - pd->i2ccs = I2C_CH_WAIT_READ; - return 0; - } - } else { - /* W/C for next byte */ - IT83XX_SMB_HOSTA(p) = HOSTA_NEXT_BYTE; - } - } - } - } - return 1; -} - -static void enhanced_i2c_start(int p) -{ - /* Shift register */ - int p_ch = i2c_ch_reg_shift(p); - - /* State reset and hardware reset */ - IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; - /* Set i2c frequency */ - IT83XX_I2C_PSR(p_ch) = pdata[p].freq; - IT83XX_I2C_HSPR(p_ch) = pdata[p].freq; - /* - * Set time out register. - * I2C D/E/F clock/data low timeout. - */ - IT83XX_I2C_TOR(p_ch) = I2C_CLK_LOW_TIMEOUT; - /* bit1: Enable enhanced i2c module */ - IT83XX_I2C_CTR1(p_ch) = BIT(1); -} - -static int enhanced_i2c_tran_write(int p) -{ - struct i2c_port_data *pd = pdata + p; - uint8_t out_data; - int p_ch; - - /* Shift register */ - p_ch = i2c_ch_reg_shift(p); - - if (pd->flags & I2C_XFER_START) { - /* Clear start bit */ - pd->flags &= ~I2C_XFER_START; - enhanced_i2c_start(p); - /* Send ID */ - i2c_pio_trans_data(p, TX_DIRECT, pd->addr_8bit, 1); - } else { - /* Host has completed the transmission of a byte */ - if (pd->widx < pd->out_size) { - out_data = *(pd->out++); - pd->widx++; - - /* Send Byte */ - i2c_pio_trans_data(p, TX_DIRECT, out_data, 0); - if (pd->i2ccs == I2C_CH_WAIT_NEXT_XFER) { - pd->i2ccs = I2C_CH_NORMAL; - task_enable_irq(i2c_ctrl_regs[p].irq); - } - } else { - /* done */ - pd->out_size = 0; - if (pd->in_size > 0) { - /* Write to read protocol */ - pd->i2ccs = I2C_CH_REPEAT_START; - /* Repeat Start */ - i2c_pio_trans_data(p, RX_DIRECT, - pd->addr_8bit, 1); - } else { - if (pd->flags & I2C_XFER_STOP) { - IT83XX_I2C_CTR(p_ch) = E_FINISH; - /* wait for stop bit interrupt*/ - return 1; - } - /* Direct write with direct read */ - pd->i2ccs = I2C_CH_WAIT_NEXT_XFER; - return 0; - } - } - } - return 1; -} - -static int enhanced_i2c_tran_read(int p) -{ - struct i2c_port_data *pd = pdata + p; - uint8_t in_data = 0; - int p_ch; - - /* Shift register */ - p_ch = i2c_ch_reg_shift(p); - - if (pd->flags & I2C_XFER_START) { - /* clear start flag */ - pd->flags &= ~I2C_XFER_START; - enhanced_i2c_start(p); - /* Direct read */ - pd->i2ccs = I2C_CH_WAIT_READ; - /* Send ID */ - i2c_pio_trans_data(p, RX_DIRECT, pd->addr_8bit, 1); - } else { - if (pd->i2ccs) { - if (pd->i2ccs == I2C_CH_REPEAT_START) { - pd->i2ccs = I2C_CH_NORMAL; - /* Receive data */ - i2c_pio_trans_data(p, RX_DIRECT, in_data, 0); - } else if (pd->i2ccs == I2C_CH_WAIT_READ) { - pd->i2ccs = I2C_CH_NORMAL; - /* Receive data */ - i2c_pio_trans_data(p, RX_DIRECT, in_data, 0); - /* Turn on irq before next direct read */ - task_enable_irq(i2c_ctrl_regs[p].irq); - } else { - /* Write to read */ - pd->i2ccs = I2C_CH_WAIT_READ; - /* Send ID */ - i2c_pio_trans_data(p, RX_DIRECT, - pd->addr_8bit, 1); - task_enable_irq(i2c_ctrl_regs[p].irq); - } - } else { - if (pd->ridx < pd->in_size) { - /* read data */ - *(pd->in++) = IT83XX_I2C_DRR(p_ch); - pd->ridx++; - - /* done */ - if (pd->ridx == pd->in_size) { - pd->in_size = 0; - if (pd->flags & I2C_XFER_STOP) { - pd->i2ccs = I2C_CH_NORMAL; - IT83XX_I2C_CTR(p_ch) = E_FINISH; - /* wait for stop bit interrupt*/ - return 1; - } - /* End the transaction */ - pd->i2ccs = I2C_CH_WAIT_READ; - return 0; - } - /* read next byte */ - i2c_pio_trans_data(p, RX_DIRECT, in_data, 0); - } - } - } - return 1; -} - -static int enhanced_i2c_error(int p) -{ - struct i2c_port_data *pd = pdata + p; - /* Shift register */ - int p_ch = i2c_ch_reg_shift(p); - int i2c_str = IT83XX_I2C_STR(p_ch); - - if (i2c_str & E_HOSTA_ANY_ERROR) { - pd->err = i2c_str & E_HOSTA_ANY_ERROR; - /* device does not respond ACK */ - } else if ((i2c_str & E_HOSTA_BDS_AND_ACK) == E_HOSTA_BDS) { - if (IT83XX_I2C_CTR(p_ch) & E_ACK) - pd->err = E_HOSTA_ACK; - } - - return pd->err; -} - -static int i2c_transaction(int p) -{ - struct i2c_port_data *pd = pdata + p; - int p_ch; - - if (p < I2C_STANDARD_PORT_COUNT) { - /* any error */ - if (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR) { - pd->err = (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR); - } else { - /* i2c write */ - if (pd->out_size) - return i2c_tran_write(p); - /* i2c read */ - else if (pd->in_size) - return i2c_tran_read(p); - /* wait finish */ - if (!(IT83XX_SMB_HOSTA(p) & HOSTA_FINTR)) - return 1; - } - /* W/C */ - IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; - /* disable the SMBus host interface */ - IT83XX_SMB_HOCTL2(p) = 0x00; - } else { - /* no error */ - if (!(enhanced_i2c_error(p))) { - /* i2c write */ - if (pd->out_size) - return enhanced_i2c_tran_write(p); - /* i2c read */ - else if (pd->in_size) - return enhanced_i2c_tran_read(p); - } - p_ch = i2c_ch_reg_shift(p); - IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; - IT83XX_I2C_CTR1(p_ch) = 0; - } - /* done doing work */ - return 0; -} - -int i2c_is_busy(int port) -{ - int p_ch; - - if (port < I2C_STANDARD_PORT_COUNT) - return (IT83XX_SMB_HOSTA(port) & - (HOSTA_HOBY | HOSTA_ALL_WC_BIT)); - - p_ch = i2c_ch_reg_shift(port); - return (IT83XX_I2C_STR(p_ch) & E_HOSTA_BB); -} - -int chip_i2c_xfer(int port, uint16_t addr_flags, - const uint8_t *out, int out_size, - uint8_t *in, int in_size, int flags) -{ - struct i2c_port_data *pd = pdata + port; - uint32_t events = 0; - - if (out_size == 0 && in_size == 0) - return EC_SUCCESS; - - /* - * Make the below i2c transaction work: - * - i2c_xfer with I2C_XFER_START flag - * - i2c_xfer with I2C_XFER_START flag - * - xxx - * - i2c_xfer with I2C_XFER_STOP flag - */ - if (pd->i2ccs) - flags &= ~I2C_XFER_START; - - /* Copy data to port struct */ - pd->out = out; - pd->out_size = out_size; - pd->in = in; - pd->in_size = in_size; - pd->flags = flags; - pd->widx = 0; - pd->ridx = 0; - pd->err = 0; - pd->addr_8bit = I2C_STRIP_FLAGS(addr_flags) << 1; - - /* Make sure we're in a good state to start */ - if ((flags & I2C_XFER_START) && (i2c_is_busy(port) - || (i2c_get_line_levels(port) != I2C_LINE_IDLE))) { - - /* Attempt to unwedge the port. */ - pd->err = i2c_unwedge(port); - - /* reset i2c port */ - i2c_reset(port, I2C_RC_NO_IDLE_FOR_START); - - /* Return if port is still wedged */ - if (pd->err) - return pd->err; - } - - pd->task_waiting = task_get_current(); - if (pd->flags & I2C_XFER_START) { - pd->i2ccs = I2C_CH_NORMAL; - /* enable i2c interrupt */ - task_clear_pending_irq(i2c_ctrl_regs[port].irq); - task_enable_irq(i2c_ctrl_regs[port].irq); - } - /* Start transaction */ - i2c_transaction(port); - /* Wait for transfer complete or timeout */ - events = task_wait_event_mask(TASK_EVENT_I2C_IDLE, pd->timeout_us); - /* disable i2c interrupt */ - task_disable_irq(i2c_ctrl_regs[port].irq); - pd->task_waiting = TASK_ID_INVALID; - - /* Handle timeout */ - if (!(events & TASK_EVENT_I2C_IDLE)) { - pd->err = EC_ERROR_TIMEOUT; - /* reset i2c port */ - i2c_reset(port, I2C_RC_TIMEOUT); - } - - /* reset i2c channel status */ - if (pd->err) - pd->i2ccs = I2C_CH_NORMAL; - - return pd->err; -} - -int i2c_raw_get_scl(int port) -{ - enum gpio_signal g; - - if (get_scl_from_i2c_port(port, &g) == EC_SUCCESS) - return !!(*i2c_pin_regs[port].mirror_clk & - i2c_pin_regs[port].clk_mask); - - /* 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; - - if (get_sda_from_i2c_port(port, &g) == EC_SUCCESS) - return !!(*i2c_pin_regs[port].mirror_data & - i2c_pin_regs[port].data_mask); - - /* If no SDA pin defined for this port, then return 1 to appear idle */ - return 1; -} - -int i2c_get_line_levels(int port) -{ - int pin_sts = 0; - - if (port < I2C_STANDARD_PORT_COUNT) - return IT83XX_SMB_SMBPCTL(port) & 0x03; - - if (*i2c_pin_regs[port].mirror_clk & i2c_pin_regs[port].clk_mask) - pin_sts |= I2C_LINE_SCL_HIGH; - if (*i2c_pin_regs[port].mirror_data & i2c_pin_regs[port].data_mask) - pin_sts |= I2C_LINE_SDA_HIGH; - - return pin_sts; -} - -void i2c_set_timeout(int port, uint32_t timeout) -{ - pdata[port].timeout_us = timeout ? timeout : I2C_TIMEOUT_DEFAULT_US; -} - -void i2c_interrupt(int port) -{ - int id = pdata[port].task_waiting; - - /* Clear the interrupt status */ - task_clear_pending_irq(i2c_ctrl_regs[port].irq); - - /* If no task is waiting, just return */ - if (id == TASK_ID_INVALID) - return; - - /* If done doing work, wake up the task waiting for the transfer */ - if (!i2c_transaction(port)) { - task_disable_irq(i2c_ctrl_regs[port].irq); - task_set_event(id, TASK_EVENT_I2C_IDLE); - } -} - -/* - * Set i2c standard port (A, B, or C) runs at 400kHz by using timing registers - * (offset 0h ~ 7h). - */ -static void i2c_standard_port_timing_regs_400khz(int port) -{ - /* Port clock frequency depends on setting of timing registers. */ - IT83XX_SMB_SCLKTS(port) = 0; - /* Suggested setting of timing registers of 400kHz. */ - IT83XX_SMB_4P7USL = 0x6; - IT83XX_SMB_4P0USL = 0; - IT83XX_SMB_300NS = 0x1; - IT83XX_SMB_250NS = 0x2; - IT83XX_SMB_45P3USL = 0x6a; - IT83XX_SMB_45P3USH = 0x1; - IT83XX_SMB_4P7A4P0H = 0; -} - -/* Set clock frequency for i2c port A, B , or C */ -static void i2c_standard_port_set_frequency(int port, int freq_khz) -{ - /* - * If port's clock frequency is 400kHz, we use timing registers - * for setting. So we can adjust tlow to meet timing. - * The others use basic 50/100/1000 KHz setting. - */ - if (freq_khz == 400) { - i2c_standard_port_timing_regs_400khz(port); - } else { - for (int f = ARRAY_SIZE(i2c_freq_select) - 1; f >= 0; f--) { - if (freq_khz >= i2c_freq_select[f].kbps) { - IT83XX_SMB_SCLKTS(port) = - i2c_freq_select[f].freq_set; - break; - } - } - } - - /* This field defines the SMCLK0/1/2 clock/data low timeout. */ - IT83XX_SMB_25MS = I2C_CLK_LOW_TIMEOUT; -} - -/* Set clock frequency for i2c port D, E , or F */ -static void i2c_enhanced_port_set_frequency(int port, int freq_khz) -{ - int port_reg_shift, clk_div, psr; - - /* Get base address of i2c enhanced port's registers. */ - port_reg_shift = i2c_ch_reg_shift(port); - /* - * Let psr(Prescale) = IT83XX_I2C_PSR(port_reg_shift) - * Then, 1 SCL cycle = 2 x (psr + 2) x SMBus clock cycle - * SMBus clock = PLL_CLOCK / clk_div - * SMBus clock cycle = 1 / SMBus clock - * 1 SCL cycle = 1 / (1000 x freq) - * 1 / (1000 x freq) = 2 x (psr + 2) x (1 / (PLL_CLOCK / clk_div)) - * psr = ((PLL_CLOCK / clk_div) x (1 / (1000 x freq)) x (1 / 2)) - 2 - */ - if (freq_khz) { - /* Get SMBus clock divide value */ - clk_div = (IT83XX_ECPM_SCDCR2 & 0x0F) + 1; - /* Calculate PSR value */ - psr = (PLL_CLOCK / (clk_div * (2 * 1000 * freq_khz))) - 2; - /* Set psr value under 0xFD */ - if (psr > 0xFD) - psr = 0xFD; - - /* Set I2C Speed */ - IT83XX_I2C_PSR(port_reg_shift) = (psr & 0xFF); - IT83XX_I2C_HSPR(port_reg_shift) = (psr & 0xFF); - /* Backup */ - pdata[port].freq = (psr & 0xFF); - } -} - -static void i2c_freq_changed(void) -{ - int i, freq, port; - - /* Set clock frequency for I2C ports */ - for (i = 0; i < i2c_ports_used; i++) { - freq = i2c_ports[i].kbps; - port = i2c_ports[i].port; - if (port < I2C_STANDARD_PORT_COUNT) - i2c_standard_port_set_frequency(port, freq); - else - i2c_enhanced_port_set_frequency(port, freq); - } -} -DECLARE_HOOK(HOOK_FREQ_CHANGE, i2c_freq_changed, HOOK_PRIO_DEFAULT); - -void i2c_init(void) -{ - int i, p, p_ch; - - /* Configure GPIOs */ - gpio_config_module(MODULE_I2C, 1); - -#ifdef CONFIG_IT83XX_SMCLK2_ON_GPC7 - /* bit7, 0: SMCLK2 is located on GPF6, 1: SMCLK2 is located on GPC7 */ - IT83XX_GPIO_GRC7 |= 0x80; -#endif - - /* Enable I2C function. */ - for (i = 0; i < i2c_ports_used; i++) { - /* I2c port mapping. */ - p = i2c_ports[i].port; - - clock_enable_peripheral(i2c_ctrl_regs[p].clock_gate, 0, 0); - - if (p < I2C_STANDARD_PORT_COUNT) { - /* - * bit0, The SMBus host interface is enabled. - * bit1, Enable to communicate with I2C device - * and support I2C-compatible cycles. - * bit4, This bit controls the reset mechanism - * of SMBus master to handle the SMDAT - * line low if 25ms reg timeout. - */ - IT83XX_SMB_HOCTL2(p) = 0x11; - /* - * bit1, Kill SMBus host transaction. - * bit0, Enable the interrupt for the master interface. - */ - IT83XX_SMB_HOCTL(p) = 0x03; - IT83XX_SMB_HOCTL(p) = 0x01; - /* W/C host status register */ - IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; - IT83XX_SMB_HOCTL2(p) = 0x00; - } else { - /* Shift register */ - p_ch = i2c_ch_reg_shift(p); - switch (p) { - case IT83XX_I2C_CH_D: - #ifndef CONFIG_UART_HOST - /* Enable SMBus D channel */ - IT83XX_GPIO_GRC2 |= 0x20; - #endif - break; - case IT83XX_I2C_CH_E: - /* Enable SMBus E channel */ - IT83XX_GCTRL_PMER1 |= 0x01; - break; - case IT83XX_I2C_CH_F: - /* Enable SMBus F channel */ - IT83XX_GCTRL_PMER1 |= 0x02; - break; - } - /* Software reset */ - IT83XX_I2C_DHTR(p_ch) |= 0x80; - IT83XX_I2C_DHTR(p_ch) &= 0x7F; - /* State reset and hardware reset */ - IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; - /* bit1, Module enable */ - IT83XX_I2C_CTR1(p_ch) = 0; - } - pdata[i].task_waiting = TASK_ID_INVALID; - } - - i2c_freq_changed(); - - for (i = 0; i < I2C_PORT_COUNT; i++) { - /* Use default timeout */ - i2c_set_timeout(i, 0); - } -} diff --git a/chip/it83xx/i2c_peripheral.c b/chip/it83xx/i2c_peripheral.c deleted file mode 100644 index 91eb2c1dfb..0000000000 --- a/chip/it83xx/i2c_peripheral.c +++ /dev/null @@ -1,344 +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. - */ - -/* I2C module for Chrome EC */ -#include "clock.h" -#include "compile_time_macros.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c_peripheral.h" -#include "registers.h" -#include <stddef.h> -#include <string.h> -#include "task.h" - -/* Console output macros */ -#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) - -/* The size must be a power of 2 */ -#define I2C_MAX_BUFFER_SIZE 0x100 -#define I2C_SIZE_MASK (I2C_MAX_BUFFER_SIZE - 1) - -#define I2C_READ_MAXFIFO_DATA 16 -#define I2C_ENHANCED_CH_INTERVAL 0x80 - -/* Store controller to peripheral data of channel D, E, F by DMA */ -static uint8_t in_data[I2C_ENHANCED_PORT_COUNT][I2C_MAX_BUFFER_SIZE] - __attribute__((section(".h2ram.pool.i2cslv"))); -/* Store peripheral to controller data of channel D, E, F by DMA */ -static uint8_t out_data[I2C_ENHANCED_PORT_COUNT][I2C_MAX_BUFFER_SIZE] - __attribute__((section(".h2ram.pool.i2cslv"))); -/* Store read and write data of channel A by FIFO mode */ -static uint8_t pbuffer[I2C_MAX_BUFFER_SIZE]; - -static uint32_t w_index; -static uint32_t r_index; -static int wr_done[I2C_ENHANCED_PORT_COUNT]; - -void buffer_index_reset(void) -{ - /* Reset write buffer index */ - w_index = 0; - /* Reset read buffer index */ - r_index = 0; -} - -/* Data structure to define I2C peripheral control configuration. */ -struct i2c_periph_ctrl_t { - int irq; /* peripheral irq */ - /* offset from base 0x00F03500 register; -1 means unused. */ - int offset; - enum clock_gate_offsets clock_gate; - int dma_index; -}; - -/* I2C peripheral control */ -const struct i2c_periph_ctrl_t i2c_periph_ctrl[] = { - [IT83XX_I2C_CH_A] = {.irq = IT83XX_IRQ_SMB_A, .offset = -1, - .clock_gate = CGC_OFFSET_SMBA, .dma_index = -1}, - [IT83XX_I2C_CH_D] = {.irq = IT83XX_IRQ_SMB_D, .offset = 0x180, - .clock_gate = CGC_OFFSET_SMBD, .dma_index = 0}, - [IT83XX_I2C_CH_E] = {.irq = IT83XX_IRQ_SMB_E, .offset = 0x0, - .clock_gate = CGC_OFFSET_SMBE, .dma_index = 1}, - [IT83XX_I2C_CH_F] = {.irq = IT83XX_IRQ_SMB_F, .offset = 0x80, - .clock_gate = CGC_OFFSET_SMBF, .dma_index = 2}, -}; - -void i2c_peripheral_read_write_data(int port) -{ - int periph_status, i; - - /* I2C peripheral channel A FIFO mode */ - if (port < I2C_STANDARD_PORT_COUNT) { - int count; - - periph_status = IT83XX_SMB_SLSTA; - - /* bit0-4 : FIFO byte count */ - count = IT83XX_SMB_SFFSTA & 0x1F; - - /* Peripheral data register is waiting for read or write. */ - if (periph_status & IT83XX_SMB_SDS) { - /* Controller to read data */ - if (periph_status & IT83XX_SMB_RCS) { - for (i = 0; i < I2C_READ_MAXFIFO_DATA; i++) - /* Return buffer data to controller */ - IT83XX_SMB_SLDA = - pbuffer[(i + r_index) & I2C_SIZE_MASK]; - - /* Index to next 16 bytes of read buffer */ - r_index += I2C_READ_MAXFIFO_DATA; - } - /* Controller to write data */ - else { - /* FIFO Full */ - if (IT83XX_SMB_SFFSTA & IT83XX_SMB_SFFFULL) { - for (i = 0; i < count; i++) - /* Get data from controller to buffer */ - pbuffer[(w_index + i) & - I2C_SIZE_MASK] = IT83XX_SMB_SLDA; - } - - /* Index to next byte of write buffer */ - w_index += count; - } - } - /* Stop condition, indicate stop condition detected. */ - if (periph_status & IT83XX_SMB_SPDS) { - /* Read data less 16 bytes status */ - if (periph_status & IT83XX_SMB_RCS) { - /* Disable FIFO mode to clear left count */ - IT83XX_SMB_SFFCTL &= ~IT83XX_SMB_SAFE; - - /* Peripheral A FIFO Enable */ - IT83XX_SMB_SFFCTL |= IT83XX_SMB_SAFE; - } - /* Controller to write data */ - else { - for (i = 0; i < count; i++) - /* Get data from controller to buffer */ - pbuffer[(i + w_index) & - I2C_SIZE_MASK] = IT83XX_SMB_SLDA; - } - - /* Reset read and write buffer index */ - buffer_index_reset(); - } - /* Peripheral time status, timeout status occurs. */ - if (periph_status & IT83XX_SMB_STS) { - /* Reset read and write buffer index */ - buffer_index_reset(); - } - - /* Write clear the peripheral status */ - IT83XX_SMB_SLSTA = periph_status; - } - /* Enhanced I2C peripheral channel D, E, F DMA mode */ - else { - int ch, idx; - - /* Get enhanced i2c channel */ - ch = i2c_periph_ctrl[port].offset / I2C_ENHANCED_CH_INTERVAL; - - idx = i2c_periph_ctrl[port].dma_index; - - /* Interrupt pending */ - if (IT83XX_I2C_STR(ch) & IT83XX_I2C_INTPEND) { - - periph_status = IT83XX_I2C_IRQ_ST(ch); - - /* Controller to read data */ - if (periph_status & IT83XX_I2C_IDR_CLR) { - /* - * TODO(b:129360157): Return buffer data by - * "out_data" array. - * Ex: Write data to buffer from 0x00 to 0xFF - */ - for (i = 0; i < I2C_MAX_BUFFER_SIZE; i++) - out_data[idx][i] = i; - } - /* Controller to write data */ - if (periph_status & IT83XX_I2C_IDW_CLR) { - /* Controller to write data finish flag */ - wr_done[idx] = 1; - } - /* Peripheral finish */ - if (periph_status & IT83XX_I2C_P_CLR) { - if (wr_done[idx]) { - /* - * TODO(b:129360157): Handle controller write - * data by "in_data" array. - */ - CPRINTS("WData: %ph", - HEX_BUF(in_data[idx], - I2C_MAX_BUFFER_SIZE)); - wr_done[idx] = 0; - } - } - - /* Write clear the peripheral status */ - IT83XX_I2C_IRQ_ST(ch) = periph_status; - } - - /* Hardware reset */ - IT83XX_I2C_CTR(ch) |= IT83XX_I2C_HALT; - } -} - -void i2c_periph_interrupt(int port) -{ - /* Peripheral to read and write fifo data */ - i2c_peripheral_read_write_data(port); - - /* Clear the interrupt status */ - task_clear_pending_irq(i2c_periph_ctrl[port].irq); -} - -void i2c_peripheral_enable(int port, uint8_t periph_addr) -{ - - clock_enable_peripheral(i2c_periph_ctrl[port].clock_gate, 0, 0); - - /* I2C peripheral channel A FIFO mode */ - if (port < I2C_STANDARD_PORT_COUNT) { - - /* This field defines the SMCLK0/1/2 clock/data low timeout. */ - IT83XX_SMB_25MS = I2C_CLK_LOW_TIMEOUT; - - /* bit0 : Peripheral A FIFO Enable */ - IT83XX_SMB_SFFCTL |= IT83XX_SMB_SAFE; - - /* - * bit1 : Peripheral interrupt enable. - * bit2 : SMCLK/SMDAT will be released if timeout. - * bit3 : Peripheral detect STOP condition interrupt enable. - */ - IT83XX_SMB_SICR = 0x0E; - - /* Peripheral address 1 */ - IT83XX_SMB_RESLADR = periph_addr; - - /* Write clear all peripheral status */ - IT83XX_SMB_SLSTA = 0xE7; - - /* bit5 : Enable the SMBus peripheral device */ - IT83XX_SMB_HOCTL2(port) |= IT83XX_SMB_SLVEN; - } - /* Enhanced I2C peripheral channel D, E, F DMA mode */ - else { - int ch, idx; - uint32_t in_data_addr, out_data_addr; - - /* Get enhanced i2c channel */ - ch = i2c_periph_ctrl[port].offset / I2C_ENHANCED_CH_INTERVAL; - - idx = i2c_periph_ctrl[port].dma_index; - - switch (port) { - case IT83XX_I2C_CH_D: - /* Enable I2C D channel */ - IT83XX_GPIO_GRC2 |= (1 << 5); - break; - case IT83XX_I2C_CH_E: - /* Enable I2C E channel */ - IT83XX_GCTRL_PMER1 |= (1 << 0); - break; - case IT83XX_I2C_CH_F: - /* Enable I2C F channel */ - IT83XX_GCTRL_PMER1 |= (1 << 1); - break; - } - - /* Software reset */ - IT83XX_I2C_DHTR(ch) |= (1 << 7); - IT83XX_I2C_DHTR(ch) &= ~(1 << 7); - - /* This field defines the SMCLK3/4/5 clock/data low timeout. */ - IT83XX_I2C_TOR(ch) = I2C_CLK_LOW_TIMEOUT; - - /* Bit stretching */ - IT83XX_I2C_TOS(ch) |= IT83XX_I2C_CLK_STR; - - /* Peripheral address(8-bit)*/ - IT83XX_I2C_IDR(ch) = periph_addr << 1; - - /* I2C interrupt enable and set acknowledge */ - IT83XX_I2C_CTR(ch) = IT83XX_I2C_HALT | - IT83XX_I2C_INTEN | IT83XX_I2C_ACK; - - /* - * bit3 : Peripheral ID write flag - * bit2 : Peripheral ID read flag - * bit1 : Peripheral received data flag - * bit0 : Peripheral finish - */ - IT83XX_I2C_IRQ_ST(ch) = 0xFF; - - /* Clear read and write data buffer of DMA */ - memset(in_data[idx], 0, I2C_MAX_BUFFER_SIZE); - memset(out_data[idx], 0, I2C_MAX_BUFFER_SIZE); - - if (IS_ENABLED(CHIP_ILM_DLM_ORDER)) { - in_data_addr = (uint32_t)in_data[idx] & 0xffffff; - out_data_addr = (uint32_t)out_data[idx] & 0xffffff; - } else { - in_data_addr = (uint32_t)in_data[idx] & 0xfff; - out_data_addr = (uint32_t)out_data[idx] & 0xfff; - } - - /* DMA write target address register */ - IT83XX_I2C_RAMHA(ch) = in_data_addr >> 8; - IT83XX_I2C_RAMLA(ch) = in_data_addr; - - if (IS_ENABLED(CHIP_ILM_DLM_ORDER)) { - /* - * DMA write target address register - * for high order byte - */ - IT83XX_I2C_RAMH2A(ch) = in_data_addr >> 16; - /* - * DMA read target address register - * for high order byte - */ - IT83XX_I2C_CMD_ADDH2(ch) = out_data_addr >> 16; - IT83XX_I2C_CMD_ADDH(ch) = out_data_addr >> 8; - IT83XX_I2C_CMD_ADDL(ch) = out_data_addr; - } else { - /* DMA read target address register */ - IT83XX_I2C_RAMHA2(ch) = out_data_addr >> 8; - IT83XX_I2C_RAMLA2(ch) = out_data_addr; - } - - /* I2C module enable and command queue mode */ - IT83XX_I2C_CTR1(ch) = IT83XX_I2C_COMQ_EN | - IT83XX_I2C_MDL_EN; - } -} - -static void i2c_peripheral_init(void) -{ - int i, p; - - /* DLM 52k~56k size select enable */ - IT83XX_GCTRL_MCCR2 |= (1 << 4); - - /* Enable I2C Peripheral function */ - for (i = 0; i < i2c_periphs_used; i++) { - - /* I2c peripheral port mapping. */ - p = i2c_periph_ports[i].port; - - /* To enable peripheral ch[x] */ - i2c_peripheral_enable(p, i2c_periph_ports[i].addr); - - /* Clear the interrupt status */ - task_clear_pending_irq(i2c_periph_ctrl[p].irq); - - /* enable i2c interrupt */ - task_enable_irq(i2c_periph_ctrl[p].irq); - } -} -DECLARE_HOOK(HOOK_INIT, i2c_peripheral_init, HOOK_PRIO_INIT_I2C + 1); diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c deleted file mode 100644 index 80abfaad63..0000000000 --- a/chip/it83xx/intc.c +++ /dev/null @@ -1,198 +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. - */ - -#include "common.h" -#include "intc.h" -#include "it83xx_pd.h" -#include "ite_pd_intc.h" -#include "kmsc_chip.h" -#include "registers.h" -#include "task.h" -#include "tcpm/tcpm.h" -#include "usb_pd.h" - -int __ram_code intc_get_ec_int(void) -{ - extern volatile int ec_int; - return ec_int; -} - -void intc_cpu_int_group_5(void) -{ - /* Determine interrupt number. */ - int intc_group_5 = intc_get_ec_int(); - - switch (intc_group_5) { -#if defined(CONFIG_HOSTCMD_X86) && defined(HAS_TASK_KEYPROTO) - case IT83XX_IRQ_KBC_OUT: - lpc_kbc_obe_interrupt(); - break; - - case IT83XX_IRQ_KBC_IN: - lpc_kbc_ibf_interrupt(); - break; -#endif - default: - break; - } -} -DECLARE_IRQ(CPU_INT_GROUP_5, intc_cpu_int_group_5, 2); - -void intc_cpu_int_group_4(void) -{ - /* Determine interrupt number. */ - int intc_group_4 = intc_get_ec_int(); - - switch (intc_group_4) { -#ifdef CONFIG_HOSTCMD_X86 - case IT83XX_IRQ_PMC_IN: - pm1_ibf_interrupt(); - break; - - case IT83XX_IRQ_PMC2_IN: - pm2_ibf_interrupt(); - break; - - case IT83XX_IRQ_PMC3_IN: - pm3_ibf_interrupt(); - break; - - case IT83XX_IRQ_PMC4_IN: - pm4_ibf_interrupt(); - break; - - case IT83XX_IRQ_PMC5_IN: - pm5_ibf_interrupt(); - break; -#endif - default: - break; - } -} -DECLARE_IRQ(CPU_INT_GROUP_4, intc_cpu_int_group_4, 2); - -void intc_cpu_int_group_12(void) -{ - /* Determine interrupt number. */ - int intc_group_12 = intc_get_ec_int(); - - switch (intc_group_12) { -#ifdef CONFIG_PECI - case IT83XX_IRQ_PECI: - peci_interrupt(); - break; -#endif -#ifdef CONFIG_HOSTCMD_ESPI - case IT83XX_IRQ_ESPI: - espi_interrupt(); - break; - - case IT83XX_IRQ_ESPI_VW: - espi_vw_interrupt(); - break; -#endif -#ifdef CONFIG_USB_PD_TCPM_ITE_ON_CHIP - case IT83XX_IRQ_USBPD0: - chip_pd_irq(USBPD_PORT_A); - break; - - case IT83XX_IRQ_USBPD1: - chip_pd_irq(USBPD_PORT_B); - break; -#ifdef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 - case IT83XX_IRQ_USBPD2: - chip_pd_irq(USBPD_PORT_C); - break; -#endif -#endif -#ifdef CONFIG_SPI - case IT83XX_IRQ_SPI_PERIPHERAL: - spi_peripheral_int_handler(); - break; -#endif - default: - break; - } -} -DECLARE_IRQ(CPU_INT_GROUP_12, intc_cpu_int_group_12, 2); - -void intc_cpu_int_group_7(void) -{ - /* Determine interrupt number. */ - int intc_group_7 = intc_get_ec_int(); - - switch (intc_group_7) { -#ifdef CONFIG_ADC - case IT83XX_IRQ_ADC: - adc_interrupt(); - break; -#ifdef CONFIG_ADC_VOLTAGE_COMPARATOR - case IT83XX_IRQ_V_COMP: - voltage_comparator_interrupt(); - break; -#endif -#endif - default: - break; - } -} -DECLARE_IRQ(CPU_INT_GROUP_7, intc_cpu_int_group_7, 2); - -void intc_cpu_int_group_6(void) -{ - /* Determine interrupt number. */ - int intc_group_6 = intc_get_ec_int(); - - switch (intc_group_6) { -#if defined(CONFIG_I2C_CONTROLLER) || defined(CONFIG_I2C_PERIPHERAL) - case IT83XX_IRQ_SMB_A: -#ifdef CONFIG_I2C_PERIPHERAL - if (IT83XX_SMB_SFFCTL & IT83XX_SMB_SAFE) - i2c_periph_interrupt(IT83XX_I2C_CH_A); - else -#endif - i2c_interrupt(IT83XX_I2C_CH_A); - break; - - case IT83XX_IRQ_SMB_B: - i2c_interrupt(IT83XX_I2C_CH_B); - break; - - case IT83XX_IRQ_SMB_C: - i2c_interrupt(IT83XX_I2C_CH_C); - break; - - case IT83XX_IRQ_SMB_D: -#ifdef CONFIG_I2C_PERIPHERAL - if (!(IT83XX_I2C_CTR(3) & IT83XX_I2C_MODE)) - i2c_periph_interrupt(IT83XX_I2C_CH_D); - else -#endif - i2c_interrupt(IT83XX_I2C_CH_D); - break; - - case IT83XX_IRQ_SMB_E: -#ifdef CONFIG_I2C_PERIPHERAL - if (!(IT83XX_I2C_CTR(0) & IT83XX_I2C_MODE)) - i2c_periph_interrupt(IT83XX_I2C_CH_E); - else -#endif - i2c_interrupt(IT83XX_I2C_CH_E); - break; - - case IT83XX_IRQ_SMB_F: -#ifdef CONFIG_I2C_PERIPHERAL - if (!(IT83XX_I2C_CTR(1) & IT83XX_I2C_MODE)) - i2c_periph_interrupt(IT83XX_I2C_CH_F); - else -#endif - i2c_interrupt(IT83XX_I2C_CH_F); - break; -#endif - default: - break; - } -} -DECLARE_IRQ(CPU_INT_GROUP_6, intc_cpu_int_group_6, 2); diff --git a/chip/it83xx/intc.h b/chip/it83xx/intc.h deleted file mode 100644 index 62ceb34576..0000000000 --- a/chip/it83xx/intc.h +++ /dev/null @@ -1,54 +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. - */ - -/* INTC control module for IT83xx. */ - -#ifndef __CROS_EC_INTC_H -#define __CROS_EC_INTC_H - -/* - * The DSB instruction guarantees a modified architecture or hardware state - * can be seen by any following dependent data operations. - */ -static inline void data_serialization_barrier(void) -{ - if (IS_ENABLED(CHIP_CORE_NDS32)) - asm volatile ("dsb"); -} - -int intc_get_ec_int(void); -void pm1_ibf_interrupt(void); -void pm2_ibf_interrupt(void); -void pm3_ibf_interrupt(void); -void pm4_ibf_interrupt(void); -void pm5_ibf_interrupt(void); -void lpcrst_interrupt(enum gpio_signal signal); -void peci_interrupt(void); -void adc_interrupt(void); -#ifdef CONFIG_ADC_VOLTAGE_COMPARATOR -void voltage_comparator_interrupt(void); -#endif -void i2c_interrupt(int port); -#ifdef CONFIG_I2C_PERIPHERAL -void i2c_periph_interrupt(int port); -#endif -void clock_sleep_mode_wakeup_isr(void); -int clock_ec_wake_from_sleep(void); -void __enter_hibernate(uint32_t seconds, uint32_t microseconds); -void espi_reset_pin_asserted_interrupt(enum gpio_signal signal); -void espi_fw_reset_module(void); -void espi_interrupt(void); -void espi_vw_interrupt(void); -void espi_enable_pad(int enable); -void espi_init(void); -void clock_cpu_standby(void); -void spi_emmc_cmd0_isr(uint32_t *cmd0_payload); -void spi_peripheral_int_handler(void); -#if defined(CONFIG_HOSTCMD_X86) && defined(HAS_TASK_KEYPROTO) -void lpc_kbc_ibf_interrupt(void); -void lpc_kbc_obe_interrupt(void); -#endif - -#endif /* __CROS_EC_INTC_H */ diff --git a/chip/it83xx/irq.c b/chip/it83xx/irq.c deleted file mode 100644 index fb01309721..0000000000 --- a/chip/it83xx/irq.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * IT83xx chip-specific part of the IRQ handling. - */ - -#include "common.h" -#include "irq_chip.h" -#include "registers.h" -#include "util.h" - -#define IRQ_GROUP(n, cpu_ints...) \ - {(uint32_t)&CONCAT2(IT83XX_INTC_ISR, n) - IT83XX_INTC_BASE, \ - (uint32_t)&CONCAT2(IT83XX_INTC_IER, n) - IT83XX_INTC_BASE, \ - ##cpu_ints} - -static const struct { - uint8_t isr_off; - uint8_t ier_off; - uint8_t cpu_int[8]; -} irq_groups[] = { - IRQ_GROUP(0, {-1, 2, 5, 4, 6, 2, 2, 4}), - IRQ_GROUP(1, { 7, 6, 6, 5, 2, 2, 2, 8}), - IRQ_GROUP(2, { 6, 2, 8, 8, 8, 2, 12, 12}), - IRQ_GROUP(3, { 5, 4, 4, 4, 11, 11, 3, 2}), - IRQ_GROUP(4, {11, 11, 11, 11, 8, 9, 9, 9}), - IRQ_GROUP(5, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(6, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(7, {10, 10, 3, 12, 3, 3, 3, 3}), - IRQ_GROUP(8, { 4, 4, 4, 4, 4, 4, -1, 12}), - IRQ_GROUP(9, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(10, { 3, 6, 12, 12, 5, 2, 2, 2}), - IRQ_GROUP(11, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(12, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(13, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(14, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(15, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(16, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(17, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(18, { 2, 2, 2, 2, -1, 4, 4, 7}), - IRQ_GROUP(19, { 6, 6, 12, 3, 3, 3, 3, 3}), - IRQ_GROUP(20, {12, 12, 12, 12, 12, 12, 12, -1}), -#if defined(IT83XX_INTC_GROUP_21_22_SUPPORT) - IRQ_GROUP(21, { 2, 2, 2, 2, 2, 2, 2, 2}), - IRQ_GROUP(22, { 2, 2, -1, -1, -1, -1, -1, -1}), -#elif defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) - IRQ_GROUP(21, {-1, -1, 12, 12, 12, 12, 12, 12}), - IRQ_GROUP(22, { 2, 2, 2, 2, 2, 2, 2, 2}), -#else - IRQ_GROUP(21, {-1, -1, -1, -1, -1, -1, -1, -1}), - IRQ_GROUP(22, {-1, -1, -1, -1, -1, -1, -1, -1}), -#endif - IRQ_GROUP(23, { 2, 2, -1, -1, -1, -1, -1, 2}), - IRQ_GROUP(24, { 2, 2, 2, 2, 2, 2, -1, 2}), - IRQ_GROUP(25, { 2, 2, 2, 2, -1, -1, -1, -1}), - IRQ_GROUP(26, { 2, 2, 2, 2, 2, 2, 2, -1}), - IRQ_GROUP(27, { 2, 2, 2, 2, 2, 2, -1, -1}), - IRQ_GROUP(28, { 2, 2, 2, 2, 2, 2, -1, -1}), -}; - -#if defined(CHIP_FAMILY_IT8320) /* N8 core */ -/* Number of CPU hardware interrupts (HW0 ~ HW15) */ -int cpu_int_entry_number; -#endif - -int chip_get_ec_int(void) -{ - extern volatile int ec_int; - -#if defined(CHIP_FAMILY_IT8320) /* N8 core */ - int i; - - for (i = 0; i < IT83XX_IRQ_COUNT; i++) { - ec_int = IT83XX_INTC_IVCT(cpu_int_entry_number); - /* - * WORKAROUND: when the interrupt vector register isn't - * latched in a load operation, - * we read it again to make sure the value we got - * is the correct value. - */ - if (ec_int == IT83XX_INTC_IVCT(cpu_int_entry_number)) - break; - } - /* Determine interrupt number */ - ec_int -= 16; -#else /* defined(CHIP_FAMILY_IT8XXX2) RISCV core */ - /* wait until two equal interrupt values are read */ - do { - ec_int = IT83XX_INTC_AIVCT; - } while (ec_int != IT83XX_INTC_AIVCT); - ec_int -= 0x10; - /* Unsupported EC INT number. */ - if (chip_get_intc_group(ec_int) >= 16) - return -1; -#endif - return ec_int; -} - -int chip_get_intc_group(int irq) -{ - return irq_groups[irq / 8].cpu_int[irq % 8]; -} - -void chip_enable_irq(int irq) -{ - int group = irq / 8; - int bit = irq % 8; - - /* SOC's interrupts share CPU machine-mode external interrupt */ - if (IS_ENABLED(CHIP_CORE_RISCV)) - IT83XX_INTC_REG(irq_groups[group].ier_off) |= BIT(bit); - - /* SOC's interrupts use CPU HW interrupt 2 ~ 15 */ - if (IS_ENABLED(CHIP_CORE_NDS32)) - IT83XX_INTC_REG(IT83XX_INTC_EXT_IER_OFF(group)) |= BIT(bit); -} - -void chip_disable_irq(int irq) -{ - int group = irq / 8; - int bit = irq % 8; - - /* SOC's interrupts share CPU machine-mode external interrupt */ - if (IS_ENABLED(CHIP_CORE_RISCV)) { - volatile uint8_t _ier __unused; - - IT83XX_INTC_REG(irq_groups[group].ier_off) &= ~BIT(bit); - /* - * This load operation will guarantee the above modification of - * EC's register can be seen by any following instructions. - */ - _ier = IT83XX_INTC_REG(irq_groups[group].ier_off); - } - - /* SOC's interrupts use CPU HW interrupt 2 ~ 15 */ - if (IS_ENABLED(CHIP_CORE_NDS32)) { - volatile uint8_t _ext_ier __unused; - - IT83XX_INTC_REG(IT83XX_INTC_EXT_IER_OFF(group)) &= ~BIT(bit); - /* - * This load operation will guarantee the above modification of - * EC's register can be seen by any following instructions. - */ - _ext_ier = IT83XX_INTC_REG(IT83XX_INTC_EXT_IER_OFF(group)); - } -} - -void chip_clear_pending_irq(int irq) -{ - int group = irq / 8; - int bit = irq % 8; - - /* always write 1 clear, no | */ - IT83XX_INTC_REG(irq_groups[group].isr_off) = BIT(bit); -} - -int chip_trigger_irq(int irq) -{ - int group = irq / 8; - int bit = irq % 8; - - return irq_groups[group].cpu_int[bit]; -} - -void chip_init_irqs(void) -{ - int i; - - /* Clear all IERx and EXT_IERx */ - for (i = 0; i < ARRAY_SIZE(irq_groups); i++) { - IT83XX_INTC_REG(irq_groups[i].ier_off) = 0; - if (IS_ENABLED(CHIP_CORE_NDS32)) - IT83XX_INTC_REG(IT83XX_INTC_EXT_IER_OFF(i)) = 0; - } -} diff --git a/chip/it83xx/it83xx_fpu.S b/chip/it83xx/it83xx_fpu.S deleted file mode 100644 index 5265eb7253..0000000000 --- a/chip/it83xx/it83xx_fpu.S +++ /dev/null @@ -1,145 +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 "config_chip.h" - -/* - * DLMB register = 0x80189: - * Disable all interrupts and switching CPU's - * ALU (Arithmetic Logic Unit) to floating point operation mode. - * (IEEE standard 754 floating point) - * - * DLMB register = 0x80009: - * Restore interrupts and ALU. - */ - .text - .align 2 - .global __addsf3 - .type __addsf3, @function -__addsf3: - sethi $r2, 0x80 /* r2 = 0x80000 */ - addi $r3, $r2, 0x189 /* r3 = 0x80189 */ - addi45 $r2, 0x9 /* r2 = 0x80009 */ - mtsr $r3, $dlmb /* dlmb = 0x80189 */ - dsb - /* Floating-point addition single-precision */ - add45 $r0, $r1 - mtsr $r2, $dlmb /* dlmb = 0x80009 */ - dsb - ret5 $lp - .size __addsf3, .-__addsf3 - - .text - .align 2 - .global __subsf3 - .type __subsf3, @function -__subsf3: - sethi $r2, 0x80 /* r2 = 0x80000 */ - addi $r3, $r2, 0x189 /* r3 = 0x80189 */ - addi45 $r2, 0x9 /* r2 = 0x80009 */ - mtsr $r3, $dlmb /* dlmb = 0x80189 */ - dsb - /* Floating-point subtraction single-precision */ - sub45 $r0, $r1 - mtsr $r2, $dlmb /* dlmb = 0x80009 */ - dsb - ret5 $lp - .size __subsf3, .-__subsf3 - - .text - .align 2 - .global __mulsf3 - .type __mulsf3, @function -__mulsf3: -#ifdef IT83XX_FPU_MUL_BY_DIV -#define SIGN $r2 -#define EXPOA $r3 -#define MANTA $r4 -#define VALUA $r5 -#define EXPOB $r6 -#define MANTB $r7 -#define VALUB $r8 -#define SPROD $r15 - /* save r6-r8 */ - smw.adm $r6, [$sp], $r8, #0x0 - xor SPROD, $r1, $r0 /* sign(A xor B) */ - move SIGN, #0x80000000 - and SPROD, SPROD, SIGN /* store sign bit */ - slli VALUA, $r0, 1 /* A<<1, (exponent and mantissa) */ - slli VALUB, $r1, 1 /* B<<1, (exponent and mantissa) */ - srli EXPOA, VALUA, 24 /* exponent(A) */ - srli EXPOB, VALUB, 24 /* exponent(B) */ - slli MANTA, VALUA, 7 /* A<<8, mantissa(A) with exponent's LSB */ - slli MANTB, VALUB, 7 /* A<<8, mantissa(B) with exponent's LSB */ - beqz VALUA, .LFzeroA /* exponent(A) and mantissa (A) are zero */ - beqc EXPOA, 0xff, .LFinfnanA /* A is inf or NaN */ - beqz VALUB, .LFzeroB /* exponent(B) and mantissa (B) are zero */ - beqc EXPOB, 0xff, .LFinfnanB /* B is inf or NaN */ - /* A*B = A/(1/B) */ - sethi $r2, 0x80 /* r2 = 0x80000 */ - addi $r3, $r2, 0x189 /* r3 = 0x80189 */ - addi45 $r2, 0x9 /* r2 = 0x80009 */ - mtsr $r3, $dlmb /* dlmb = 0x80189 */ - dsb - sethi $r5, #0x3f800 /* r5 = 1.0f */ - divsr $r1,$r1,$r5,$r1 /* r1 = 1.0f / r1 */ - divsr $r0,$r0,$r0,$r1 /* r0 = r0 / r1 */ - mtsr $r2, $dlmb /* dlmb = 0x80009 */ - dsb -.LFret: - /* restore r6-r8 */ - lmw.bim $r6, [$sp], $r8, #0x0 - ret5 $lp - -.LFzeroA: /* A is zero */ - beqc EXPOB, 0xff, .LFnan/*zero * inf = zero * NaN = NaN */ -.LFzero: - move $r0, SPROD /* return 0.0f or -0.0f */ - b .LFret -.LFinfnanA: /* exponent(A) is 0xff */ - bne MANTA, SIGN, .LFnan/* A is NaN: NaN * B = NaN */ - beqz VALUB, .LFnan /* A is inf and B is zero: inf * zero = NaN */ - bnec EXPOB, 0xff, .LFinf/* B is finite: inf * B = inf */ -.LFinfnanB: /* exponent(B) is 0xff */ - bne MANTB, SIGN, .LFnan/* B is NaN: A * NaN = NaN */ -.LFinf: - move $r0, #0x7f800000 - or $r0, $r0, SPROD /* return inf or -inf */ - b .LFret -.LFzeroB: /* B is zero and A is finit */ - b .LFzero /* B is zero */ -.LFnan: - move $r0, #0xffc00000 /* return NaN */ - b .LFret -#else /* !IT83XX_FPU_MUL_BY_DIV */ - sethi $r2, 0x80 /* r2 = 0x80000 */ - addi $r3, $r2, 0x189 /* r3 = 0x80189 */ - addi45 $r2, 0x9 /* r2 = 0x80009 */ - mtsr $r3, $dlmb /* dlmb = 0x80189 */ - dsb - /* Floating-point multiplication single-precision */ - mul33 $r0, $r1 - mtsr $r2, $dlmb /* dlmb = 0x80009 */ - dsb - ret5 $lp -#endif /* IT83XX_FPU_MUL_BY_DIV */ - .size __mulsf3, .-__mulsf3 - - .text - .align 2 - .global __divsf3 - .type __divsf3, @function -__divsf3: - sethi $r2, 0x80 /* r2 = 0x80000 */ - addi $r3, $r2, 0x189 /* r3 = 0x80189 */ - addi45 $r2, 0x9 /* r2 = 0x80009 */ - mtsr $r3, $dlmb /* dlmb = 0x80189 */ - dsb - /* Floating-point division single-precision */ - divsr $r0,$r0,$r0,$r1 - mtsr $r2, $dlmb /* dlmb = 0x80009 */ - dsb - ret5 $lp - .size __divsf3, .-__divsf3 diff --git a/chip/it83xx/keyboard_raw.c b/chip/it83xx/keyboard_raw.c deleted file mode 100644 index 6c7a10c463..0000000000 --- a/chip/it83xx/keyboard_raw.c +++ /dev/null @@ -1,158 +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. - */ - -#include "common.h" -#include "keyboard_raw.h" -#include "keyboard_scan.h" -#include "registers.h" -#include "task.h" -#include "irq_chip.h" - -#define KSOH_PIN_MASK (((1 << (KEYBOARD_COLS_MAX - 8)) - 1) & 0xff) - -/* - * Initialize the raw keyboard interface. - */ -void keyboard_raw_init(void) -{ - uint32_t int_mask; - - /* Ensure top-level interrupt is disabled */ - keyboard_raw_enable_interrupt(0); - - /* - * bit2, Setting 1 enables the internal pull-up of the KSO[15:0] pins. - * To pull up KSO[17:16], set the GPCR registers of their - * corresponding GPIO ports. - * bit0, Setting 1 enables the open-drain mode of the KSO[17:0] pins. - */ - IT83XX_KBS_KSOCTRL = 0x05; - - /* bit2, 1 enables the internal pull-up of the KSI[7:0] pins. */ - IT83XX_KBS_KSICTRL = 0x04; - -#ifdef CONFIG_KEYBOARD_COL2_INVERTED - /* KSO[2] is high, others are low. */ - IT83XX_KBS_KSOL = BIT(2); - /* Enable KSO2's push-pull */ - IT83XX_KBS_KSOLGCTRL |= BIT(2); - IT83XX_KBS_KSOLGOEN |= BIT(2); -#else - /* KSO[7:0] pins low. */ - IT83XX_KBS_KSOL = 0x00; -#endif - - /* critical section with interrupts off */ - int_mask = read_clear_int_mask(); - /* - * KSO[COLS_MAX:8] pins low. - * NOTE: KSO[15:8] pins can part be enabled for keyboard function and - * rest be configured as GPIO output mode. In this case that we - * disable the ISR in critical section to avoid race condition. - */ - IT83XX_KBS_KSOH1 &= ~KSOH_PIN_MASK; - /* restore interrupts */ - set_int_mask(int_mask); - - /* KSI[0-7] falling-edge triggered is selected */ - IT83XX_WUC_WUEMR3 = 0xFF; - - /* W/C */ - IT83XX_WUC_WUESR3 = 0xFF; - - task_clear_pending_irq(IT83XX_IRQ_WKINTC); - - /* Enable WUC for KSI[0-7] */ - IT83XX_WUC_WUENR3 = 0xFF; -} - -/* - * Finish initialization after task scheduling has started. - */ -void keyboard_raw_task_start(void) -{ - IT83XX_WUC_WUESR3 = 0xFF; - task_clear_pending_irq(IT83XX_IRQ_WKINTC); - task_enable_irq(IT83XX_IRQ_WKINTC); -} - -/* - * Drive the specified column low. - */ -test_mockable void keyboard_raw_drive_column(int col) -{ - int mask; - uint32_t int_mask; - - /* Tri-state all outputs */ - if (col == KEYBOARD_COLUMN_NONE) - mask = 0xffff; - /* Assert all outputs */ - else if (col == KEYBOARD_COLUMN_ALL) - mask = 0; - /* Assert a single output */ - else - mask = 0xffff ^ BIT(col); - -#ifdef CONFIG_KEYBOARD_COL2_INVERTED - /* KSO[2] is inverted. */ - mask ^= BIT(2); -#endif - IT83XX_KBS_KSOL = mask & 0xff; - - /* critical section with interrupts off */ - int_mask = read_clear_int_mask(); - /* - * Because IT83XX_KBS_KSOH1 register is shared by keyboard scan - * out and GPIO output mode, so we don't drive all KSOH pins - * here (this depends on how many keyboard matrix output pin - * we are using). - */ - IT83XX_KBS_KSOH1 = (IT83XX_KBS_KSOH1 & ~KSOH_PIN_MASK) | - ((mask >> 8) & KSOH_PIN_MASK); - /* restore interrupts */ - set_int_mask(int_mask); -} - -/* - * 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 IT83XX_KBS_KSI ^ 0xff; -} - -/* - * Enable or disable keyboard matrix scan interrupts. - */ -void keyboard_raw_enable_interrupt(int enable) -{ - if (enable) { - IT83XX_WUC_WUESR3 = 0xFF; - task_clear_pending_irq(IT83XX_IRQ_WKINTC); - task_enable_irq(IT83XX_IRQ_WKINTC); - } else { - task_disable_irq(IT83XX_IRQ_WKINTC); - } -} - -/* - * Interrupt handler for keyboard matrix scan interrupt. - */ -void keyboard_raw_interrupt(void) -{ - IT83XX_WUC_WUESR3 = 0xFF; - task_clear_pending_irq(IT83XX_IRQ_WKINTC); - - /* Wake the scan task */ - task_wake(TASK_ID_KEYSCAN); -} - -int keyboard_raw_is_input_low(int port, int id) -{ - return !(IT83XX_GPIO_DATA_MIRROR(port) & BIT(id)); -} diff --git a/chip/it83xx/kmsc_chip.h b/chip/it83xx/kmsc_chip.h deleted file mode 100644 index cf4169a1c4..0000000000 --- a/chip/it83xx/kmsc_chip.h +++ /dev/null @@ -1,13 +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. - */ - -/* Keyboard matrix scan control module for IT83xx. */ - -#ifndef __CROS_EC_KMSC_CHIP_H -#define __CROS_EC_KMSC_CHIP_H - -void keyboard_raw_interrupt(void); - -#endif /* __CROS_EC_KMSC_CHIP_H */ diff --git a/chip/it83xx/lpc.c b/chip/it83xx/lpc.c deleted file mode 100644 index 867d9e024f..0000000000 --- a/chip/it83xx/lpc.c +++ /dev/null @@ -1,770 +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 "ec2i_chip.h" -#include "espi.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "intc.h" -#include "irq_chip.h" -#include "keyboard_protocol.h" -#include "lpc.h" -#include "port80.h" -#include "pwm.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "uart.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) - -/* LPC PM channels */ -enum lpc_pm_ch { - LPC_PM1 = 0, - LPC_PM2, - LPC_PM3, - LPC_PM4, - LPC_PM5, -}; - -enum pm_ctrl_mask { - /* Input Buffer Full Interrupt Enable. */ - PM_CTRL_IBFIE = 0x01, - /* Output Buffer Empty Interrupt Enable. */ - PM_CTRL_OBEIE = 0x02, -}; - -#define LPC_ACPI_CMD LPC_PM1 /* ACPI commands 62h/66h port */ -#define LPC_HOST_CMD LPC_PM2 /* Host commands 200h/204h port */ -#define LPC_HOST_PORT_80H LPC_PM3 /* Host 80h port */ - -static uint8_t acpi_ec_memmap[EC_MEMMAP_SIZE] - __attribute__((section(".h2ram.pool.acpiec"))); -static uint8_t host_cmd_memmap[256] - __attribute__((section(".h2ram.pool.hostcmd"))); - -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 */ - -/* Params must be 32-bit aligned */ -static uint8_t params_copy[EC_LPC_HOST_PACKET_SIZE] __aligned(4); -static int init_done; -static int p80l_index; - -static struct ec_lpc_host_args * const lpc_host_args = - (struct ec_lpc_host_args *)host_cmd_memmap; - -static void pm_set_ctrl(enum lpc_pm_ch ch, enum pm_ctrl_mask ctrl, int set) -{ - if (set) - IT83XX_PMC_PMCTL(ch) |= ctrl; - else - IT83XX_PMC_PMCTL(ch) &= ~ctrl; -} - -static void pm_set_status(enum lpc_pm_ch ch, uint8_t status, int set) -{ - if (set) - IT83XX_PMC_PMSTS(ch) |= status; - else - IT83XX_PMC_PMSTS(ch) &= ~status; -} - -static uint8_t pm_get_status(enum lpc_pm_ch ch) -{ - return IT83XX_PMC_PMSTS(ch); -} - -static uint8_t pm_get_data_in(enum lpc_pm_ch ch) -{ - return IT83XX_PMC_PMDI(ch); -} - -static void pm_put_data_out(enum lpc_pm_ch ch, uint8_t out) -{ - IT83XX_PMC_PMDO(ch) = out; -} - -static void pm_clear_ibf(enum lpc_pm_ch ch) -{ - /* bit7, write-1 clear IBF */ - IT83XX_PMC_PMIE(ch) |= BIT(7); -} - -#ifdef CONFIG_KEYBOARD_IRQ_GPIO -static void keyboard_irq_assert(void) -{ - /* - * 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); -} -#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) -{ -#ifdef CONFIG_HOSTCMD_ESPI - espi_vw_set_wire(VW_SMI_L, 0); - udelay(65); - espi_vw_set_wire(VW_SMI_L, 1); -#else - gpio_set_level(GPIO_PCH_SMI_L, 0); - udelay(65); - gpio_set_level(GPIO_PCH_SMI_L, 1); -#endif -} - -static void lpc_generate_sci(void) -{ -#ifdef CONFIG_HOSTCMD_ESPI - espi_vw_set_wire(VW_SCI_L, 0); - udelay(65); - espi_vw_set_wire(VW_SCI_L, 1); -#else - gpio_set_level(GPIO_PCH_SCI_L, 0); - udelay(65); - gpio_set_level(GPIO_PCH_SCI_L, 1); -#endif -} - -/** - * 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); -} - -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 OBF status bit. */ - pm_put_data_out(LPC_HOST_CMD, args->result); - - /* Clear the busy bit, so the host knows the EC is done. */ - pm_set_status(LPC_HOST_CMD, EC_LPC_STATUS_PROCESSING, 0); -} - -void lpc_update_host_event_status(void) -{ - int need_sci = 0; - int need_smi = 0; - - if (!init_done) - return; - - /* Disable PMC1 interrupt while updating status register */ - task_disable_irq(IT83XX_IRQ_PMC_IN); - - if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI)) { - /* Only generate SMI for first event */ - if (!(pm_get_status(LPC_ACPI_CMD) & EC_LPC_STATUS_SMI_PENDING)) - need_smi = 1; - pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_SMI_PENDING, 1); - } else { - pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_SMI_PENDING, 0); - } - - if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI)) { - /* Generate SCI for every event */ - need_sci = 1; - pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_SCI_PENDING, 1); - } else { - pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_SCI_PENDING, 0); - } - - /* Copy host events to mapped memory */ - *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = - lpc_get_host_events(); - - task_enable_irq(IT83XX_IRQ_PMC_IN); - - /* 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(); -} - -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. */ - pm_put_data_out(LPC_HOST_CMD, pkt->driver_result); - - /* Clear the busy bit, so the host knows the EC is done. */ - pm_set_status(LPC_HOST_CMD, EC_LPC_STATUS_PROCESSING, 0); -} - -uint8_t *lpc_get_memmap_range(void) -{ - return (uint8_t *)acpi_ec_memmap; -} - -int lpc_keyboard_has_char(void) -{ - /* OBE or OBF */ - return IT83XX_KBC_KBHISR & 0x01; -} - -int lpc_keyboard_input_pending(void) -{ - /* IBE or IBF */ - return IT83XX_KBC_KBHISR & 0x02; -} - -void lpc_keyboard_put_char(uint8_t chr, int send_irq) -{ - /* Clear programming data bit 7-4 */ - IT83XX_KBC_KBHISR &= 0x0F; - - /* keyboard */ - IT83XX_KBC_KBHISR |= 0x10; - -#ifdef CONFIG_KEYBOARD_IRQ_GPIO - task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); - /* The data output to the KBC Data Output Register. */ - IT83XX_KBC_KBHIKDOR = chr; - task_enable_irq(IT83XX_IRQ_KBC_OUT); - if (send_irq) - keyboard_irq_assert(); -#else - /* - * bit0 = 0, The IRQ1 is controlled by the IRQ1B bit in KBIRQR. - * bit1 = 0, The IRQ12 is controlled by the IRQ12B bit in KBIRQR. - */ - IT83XX_KBC_KBHICR &= 0x3C; - - /* - * Enable the interrupt to keyboard driver in the host processor - * via SERIRQ when the output buffer is full. - */ - if (send_irq) - IT83XX_KBC_KBHICR |= 0x01; - - udelay(16); - - task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); - /* The data output to the KBC Data Output Register. */ - IT83XX_KBC_KBHIKDOR = chr; - task_enable_irq(IT83XX_IRQ_KBC_OUT); -#endif -} - -void lpc_keyboard_clear_buffer(void) -{ - uint32_t int_mask = read_clear_int_mask(); - - /* bit6, write-1 clear OBF */ - IT83XX_KBC_KBHICR |= BIT(6); - IT83XX_KBC_KBHICR &= ~BIT(6); - set_int_mask(int_mask); -} - -void lpc_keyboard_resume_irq(void) -{ - if (lpc_keyboard_has_char()) { -#ifdef CONFIG_KEYBOARD_IRQ_GPIO - keyboard_irq_assert(); -#else - /* The IRQ1 is controlled by the IRQ1B bit in KBIRQR. */ - IT83XX_KBC_KBHICR &= ~0x01; - - /* - * When the OBFKIE bit in KBC Host Interface Control Register - * (KBHICR) is 0, the bit directly controls the IRQ1 signal. - */ - IT83XX_KBC_KBIRQR |= 0x01; -#endif - - task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); - - task_enable_irq(IT83XX_IRQ_KBC_OUT); - } -} - -void lpc_set_acpi_status_mask(uint8_t mask) -{ - pm_set_status(LPC_ACPI_CMD, mask, 1); -} - -void lpc_clear_acpi_status_mask(uint8_t mask) -{ - pm_set_status(LPC_ACPI_CMD, mask, 0); -} - -#ifndef CONFIG_HOSTCMD_ESPI -int lpc_get_pltrst_asserted(void) -{ - return !gpio_get_level(GPIO_PCH_PLTRST_L); -} -#endif - -#ifdef HAS_TASK_KEYPROTO -/* KBC and PMC control modules */ -void lpc_kbc_ibf_interrupt(void) -{ - if (lpc_keyboard_input_pending()) { - keyboard_host_write(IT83XX_KBC_KBHIDIR, - (IT83XX_KBC_KBHISR & 0x08) ? 1 : 0); - /* bit7, write-1 clear IBF */ - IT83XX_KBC_KBHICR |= BIT(7); - IT83XX_KBC_KBHICR &= ~BIT(7); - } - - task_clear_pending_irq(IT83XX_IRQ_KBC_IN); - - task_wake(TASK_ID_KEYPROTO); -} - -void lpc_kbc_obe_interrupt(void) -{ - task_disable_irq(IT83XX_IRQ_KBC_OUT); - - task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); - -#ifndef CONFIG_KEYBOARD_IRQ_GPIO - if (!(IT83XX_KBC_KBHICR & 0x01)) { - IT83XX_KBC_KBIRQR &= ~0x01; - - IT83XX_KBC_KBHICR |= 0x01; - } -#endif - - task_wake(TASK_ID_KEYPROTO); -} -#endif /* HAS_TASK_KEYPROTO */ - -void pm1_ibf_interrupt(void) -{ - int is_cmd; - uint8_t value, result; - - if (pm_get_status(LPC_ACPI_CMD) & EC_LPC_STATUS_FROM_HOST) { - /* Set the busy bit */ - pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_PROCESSING, 1); - - /* data from command port or data port */ - is_cmd = pm_get_status(LPC_ACPI_CMD) & EC_LPC_STATUS_LAST_CMD; - - /* Get command or data */ - value = pm_get_data_in(LPC_ACPI_CMD); - - /* Handle whatever this was. */ - if (acpi_ap_to_ec(is_cmd, value, &result)) - pm_put_data_out(LPC_ACPI_CMD, result); - - pm_clear_ibf(LPC_ACPI_CMD); - - /* Clear the busy bit */ - pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_PROCESSING, 0); - - /* - * ACPI 5.0-12.6.1: Generate SCI for Input Buffer Empty - * Output Buffer Full condition on the kernel channel. - */ - lpc_generate_sci(); - } - - task_clear_pending_irq(IT83XX_IRQ_PMC_IN); -} - -void pm2_ibf_interrupt(void) -{ - uint8_t value __attribute__((unused)) = 0; - uint8_t status; - - status = pm_get_status(LPC_HOST_CMD); - /* IBE */ - if (!(status & EC_LPC_STATUS_FROM_HOST)) { - task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); - return; - } - - /* IBF and data port */ - if (!(status & EC_LPC_STATUS_LAST_CMD)) { - /* R/C IBF*/ - value = pm_get_data_in(LPC_HOST_CMD); - pm_clear_ibf(LPC_HOST_CMD); - task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); - return; - } - - /* Set the busy bit */ - pm_set_status(LPC_HOST_CMD, EC_LPC_STATUS_PROCESSING, 1); - - /* - * Read the command byte. This clears the FRMH bit in - * the status byte. - */ - host_cmd_args.command = pm_get_data_in(LPC_HOST_CMD); - - host_cmd_args.result = EC_RES_SUCCESS; - if (host_cmd_args.command != EC_COMMAND_PROTOCOL_3) - host_cmd_args.send_response = lpc_send_response; - host_cmd_flags = lpc_host_args->flags; - - /* We only support new style command (v3) now */ - if (host_cmd_args.command == EC_COMMAND_PROTOCOL_3) { - lpc_packet.send_response = lpc_send_response_packet; - - lpc_packet.request = (const void *)host_cmd_memmap; - 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 *)host_cmd_memmap; - 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); - - pm_clear_ibf(LPC_HOST_CMD); - task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); - 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); - - pm_clear_ibf(LPC_HOST_CMD); - task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); -} - -void pm3_ibf_interrupt(void) -{ - int new_p80_idx, i; - enum ec2i_message ec2i_r; - - /* set LDN */ - if (ec2i_write(HOST_INDEX_LDN, LDN_RTCT) == EC2I_WRITE_SUCCESS) { - /* get P80L current index */ - ec2i_r = ec2i_read(HOST_INDEX_DSLDC6); - /* clear IBF */ - pm_clear_ibf(LPC_HOST_PORT_80H); - /* read OK */ - if ((ec2i_r & 0xff00) == EC2I_READ_SUCCESS) { - new_p80_idx = ec2i_r & P80L_BRAM_BANK1_SIZE_MASK; - for (i = 0; i < (P80L_P80LE - P80L_P80LB + 1); i++) { - if (++p80l_index > P80L_P80LE) - p80l_index = P80L_P80LB; - port_80_write(IT83XX_BRAM_BANK1(p80l_index)); - if (p80l_index == new_p80_idx) - break; - } - } - } else { - pm_clear_ibf(LPC_HOST_PORT_80H); - } - - task_clear_pending_irq(IT83XX_IRQ_PMC3_IN); -} - -void pm4_ibf_interrupt(void) -{ - pm_clear_ibf(LPC_PM4); - task_clear_pending_irq(IT83XX_IRQ_PMC4_IN); -} - -void pm5_ibf_interrupt(void) -{ - pm_clear_ibf(LPC_PM5); - task_clear_pending_irq(IT83XX_IRQ_PMC5_IN); -} - -static void lpc_init(void) -{ - enum ec2i_message ec2i_r; - - /* SPI peripheral interface is disabled */ - IT83XX_GCTRL_SSCR = 0; - /* - * DLM 52k~56k size select enable. - * For mapping LPC I/O cycle 800h ~ 9FFh to DLM 8D800 ~ 8D9FF. - */ - IT83XX_GCTRL_MCCR2 |= 0x10; - - /* The register pair to access PNPCFG is 004Eh and 004Fh */ - IT83XX_GCTRL_BADRSEL = 0x01; - - /* Disable KBC IRQ */ - IT83XX_KBC_KBIRQR = 0x00; - - /* - * bit2, Output Buffer Empty CPU Interrupt Enable. - * bit3, Input Buffer Full CPU Interrupt Enable. - * bit5, IBF/OBF EC clear mode. - * 0b: IBF cleared if EC read data register, EC reset, or host reset. - * OBF cleared if host read data register, or EC reset. - * 1b: IBF cleared if EC write-1 to bit7 at related registers, - * EC reset, or host reset. - * OBF cleared if host read data register, EC write-1 to bit6 at - * related registers, or EC reset. - */ - IT83XX_KBC_KBHICR |= 0x2C; - - /* PM1 Input Buffer Full Interrupt Enable for 62h/66 port */ - pm_set_ctrl(LPC_ACPI_CMD, PM_CTRL_IBFIE, 1); - - /* PM2 Input Buffer Full Interrupt Enable for 200h/204 port */ - pm_set_ctrl(LPC_HOST_CMD, PM_CTRL_IBFIE, 1); - - memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE); - memset(lpc_host_args, 0, sizeof(*lpc_host_args)); - - /* Host LPC I/O cycle mapping to RAM */ -#ifdef IT83XX_H2RAM_REMAPPING - /* - * On it8xxx2 series, host I/O cycles are mapped to the first block - * (0x80080000~0x80080fff) at default, and it is adjustable. - * We should set the correct offset depends on the base address of - * H2RAM section, so EC will be able to receive/handle commands from - * host. - */ - IT83XX_GCTRL_H2ROFSR = - (CONFIG_H2RAM_BASE - CONFIG_RAM_BASE) / CONFIG_H2RAM_SIZE; -#endif - /* - * bit[4], H2RAM through LPC IO cycle. - * bit[1], H2RAM window 1 enabled. - * bit[0], H2RAM window 0 enabled. - */ - IT83XX_SMFI_HRAMWC |= 0x13; - - /* - * bit[7:6] - * Host RAM Window[x] Read Protect Enable - * 00b: Disabled - * 01b: Lower half of RAM window protected - * 10b: Upper half of RAM window protected - * 11b: All protected - * - * bit[5:4] - * Host RAM Window[x] Write Protect Enable - * 00b: Disabled - * 01b: Lower half of RAM window protected - * 10b: Upper half of RAM window protected - * 11b: All protected - * - * bit[2:0] - * Host RAM Window 1 Size (HRAMW1S) - * 0h: 16 bytes - * 1h: 32 bytes - * 2h: 64 bytes - * 3h: 128 bytes - * 4h: 256 bytes - * 5h: 512 bytes - * 6h: 1024 bytes - * 7h: 2048 bytes - */ - - /* H2RAM Win 0 Base Address 800h allow r/w for host_cmd_memmap */ - IT83XX_SMFI_HRAMW0BA = 0x80; - IT83XX_SMFI_HRAMW0AAS = 0x04; - - /* H2RAM Win 1 Base Address 900h allow r for acpi_ec_memmap */ - IT83XX_SMFI_HRAMW1BA = 0x90; - IT83XX_SMFI_HRAMW1AAS = 0x34; - - /* 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; - - /* - * bit[5], Dedicated interrupt - * INT3: PMC1 Output Buffer Empty Int - * INT25: PMC1 Input Buffer Full Int - * INT26: PMC2 Output Buffer Empty Int - * INT27: PMC2 Input Buffer Full Int - */ - IT83XX_PMC_MBXCTRL |= 0x20; - - /* PM3 Input Buffer Full Interrupt Enable for 80h port */ - pm_set_ctrl(LPC_HOST_PORT_80H, PM_CTRL_IBFIE, 1); - - p80l_index = P80L_P80LC; - if (ec2i_write(HOST_INDEX_LDN, LDN_RTCT) == EC2I_WRITE_SUCCESS) { - /* get P80L current index */ - ec2i_r = ec2i_read(HOST_INDEX_DSLDC6); - /* read OK */ - if ((ec2i_r & 0xff00) == EC2I_READ_SUCCESS) - p80l_index = ec2i_r & P80L_BRAM_BANK1_SIZE_MASK; - } - - /* - * bit[7], enable P80L function. - * bit[6], accept port 80h cycle. - * bit[1-0], 10b: I2EC is read-only. - */ - IT83XX_GCTRL_SPCTRL1 |= 0xC2; - -#ifndef CONFIG_HOSTCMD_ESPI - gpio_enable_interrupt(GPIO_PCH_PLTRST_L); -#endif - -#ifdef HAS_TASK_KEYPROTO - task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); - task_disable_irq(IT83XX_IRQ_KBC_OUT); - - task_clear_pending_irq(IT83XX_IRQ_KBC_IN); - task_enable_irq(IT83XX_IRQ_KBC_IN); -#endif - - task_clear_pending_irq(IT83XX_IRQ_PMC_IN); - pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_PROCESSING, 0); - task_enable_irq(IT83XX_IRQ_PMC_IN); - - task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); - pm_set_status(LPC_HOST_CMD, EC_LPC_STATUS_PROCESSING, 0); - task_enable_irq(IT83XX_IRQ_PMC2_IN); - - task_clear_pending_irq(IT83XX_IRQ_PMC3_IN); - task_enable_irq(IT83XX_IRQ_PMC3_IN); - -#ifdef CONFIG_HOSTCMD_ESPI - espi_init(); -#endif - /* Sufficiently initialized */ - init_done = 1; - - /* Update host events now that we can copy them to memmap */ - lpc_update_host_event_status(); -} -/* - * 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); - -#ifndef CONFIG_HOSTCMD_ESPI -void lpcrst_interrupt(enum gpio_signal signal) -{ - if (lpc_get_pltrst_asserted()) - /* Store port 80 reset event */ - port_80_write(PORT_80_EVENT_RESET); - - CPRINTS("LPC RESET# %sasserted", - lpc_get_pltrst_asserted() ? "" : "de"); -} -#endif - -/* Enable LPC ACPI-EC interrupts */ -void lpc_enable_acpi_interrupts(void) -{ - task_enable_irq(IT83XX_IRQ_PMC_IN); -} - -/* Disable LPC ACPI-EC interrupts */ -void lpc_disable_acpi_interrupts(void) -{ - task_disable_irq(IT83XX_IRQ_PMC_IN); -} - -/* 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)); diff --git a/chip/it83xx/peci.c b/chip/it83xx/peci.c deleted file mode 100644 index 07336eaaf6..0000000000 --- a/chip/it83xx/peci.c +++ /dev/null @@ -1,216 +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. - */ - -/* PECI interface for Chrome EC */ - -#include "clock.h" -#include "hooks.h" -#include "peci.h" -#include "registers.h" -#include "util.h" -#include "timer.h" -#include "task.h" - -enum peci_status { - PECI_STATUS_NO_ERR = 0x00, - PECI_STATUS_HOBY = 0x01, - PECI_STATUS_FINISH = 0x02, - PECI_STATUS_RD_FCS_ERR = 0x04, - PECI_STATUS_WR_FCS_ERR = 0x08, - PECI_STATUS_EXTERR = 0x20, - PECI_STATUS_BUSERR = 0x40, - PECI_STATUS_RCV_ERRCODE = 0x80, - PECI_STATUS_ERR_NEED_RST = (PECI_STATUS_BUSERR | PECI_STATUS_EXTERR), - PECI_STATUS_ANY_ERR = (PECI_STATUS_RCV_ERRCODE | - PECI_STATUS_BUSERR | - PECI_STATUS_EXTERR | - PECI_STATUS_WR_FCS_ERR | - PECI_STATUS_RD_FCS_ERR), - PECI_STATUS_ANY_BIT = 0xFE, - PECI_STATUS_TIMEOUT = 0xFF, -}; - -static task_id_t peci_current_task; - -static void peci_init_vtt_freq(void) -{ - /* - * bit2, enable the PECI interrupt generated by data valid event - * from PECI. - * - * bit[1-0], these bits are used to set PECI VTT level. - * 00b: 1.10v - * 01b: 1.05v - * 10b: 1.00v - */ - IT83XX_PECI_PADCTLR = 0x06; - - /* - * bit[2-0], these bits are used to set PECI host's optimal - * transfer rate. - * 000b: 2.0 MHz - * 001b: 1.0 MHz - * 100b: 1.6 MHz - */ - IT83XX_PECI_HOCTL2R = 0x01; -} - -static void peci_reset(void) -{ - /* Reset PECI */ - IT83XX_GCTRL_RSTC4 |= 0x10; - - /* short delay */ - udelay(15); - - peci_init_vtt_freq(); -} - -/** - * Start a PECI transaction - * - * @param peci transaction data - * - * @return zero if successful, non-zero if error - */ -int peci_transaction(struct peci_data *peci) -{ - uint8_t status; - int index; - - /* To enable PECI function pin */ - IT83XX_GPIO_GPCRF6 = 0x00; - - /* - * bit5, Both write and read data FIFO pointers will be cleared. - * - * bit4, This bit enables the PECI host to abort the transaction - * when FCS error occurs. - * - * bit2, This bit enables the contention mechanism of the PECI bus. - * When this bit is set, the host will abort the transaction - * if the PECI bus is contentious. - */ - IT83XX_PECI_HOCTLR |= 0x34; - - /* This register is the target address field of the PECI protocol. */ - IT83XX_PECI_HOTRADDR = peci->addr; - - /* This register is the write length field of the PECI protocol. */ - ASSERT(peci->w_len <= PECI_WRITE_DATA_FIFO_SIZE); - - if (peci->cmd_code == PECI_CMD_PING) { - /* write length is 0 */ - IT83XX_PECI_HOWRLR = 0x00; - } else { - if ((peci->cmd_code == PECI_CMD_WR_PKG_CFG) || - (peci->cmd_code == PECI_CMD_WR_IAMSR) || - (peci->cmd_code == PECI_CMD_WR_PCI_CFG) || - (peci->cmd_code == PECI_CMD_WR_PCI_CFG_LOCAL)) { - - /* write length include Cmd Code + AW FCS */ - IT83XX_PECI_HOWRLR = peci->w_len + 2; - - /* bit1, The bit enables the AW_FCS hardwired mechanism - * based on the PECI command. This bit is functional - * only when the AW_FCS supported command of - * PECI 2.0/3.0/3.1 is issued. - * When this bit is set, the hardware will handle the - * calculation of AW_FCS. - */ - IT83XX_PECI_HOCTLR |= 0x02; - } else { - /* write length include Cmd Code */ - IT83XX_PECI_HOWRLR = peci->w_len + 1; - - IT83XX_PECI_HOCTLR &= ~0x02; - } - } - - /* This register is the read length field of the PECI protocol. */ - ASSERT(peci->r_len <= PECI_READ_DATA_FIFO_SIZE); - IT83XX_PECI_HORDLR = peci->r_len; - - /* This register is the command field of the PECI protocol. */ - IT83XX_PECI_HOCMDR = peci->cmd_code; - - /* The write data field of the PECI protocol. */ - for (index = 0x00; index < peci->w_len; index++) - IT83XX_PECI_HOWRDR = peci->w_buf[index]; - - peci_current_task = task_get_current(); - task_clear_pending_irq(IT83XX_IRQ_PECI); - task_enable_irq(IT83XX_IRQ_PECI); - - /* start */ - IT83XX_PECI_HOCTLR |= 0x01; - - /* pre-set timeout */ - index = peci->timeout_us; - if (task_wait_event(peci->timeout_us) != TASK_EVENT_TIMER) - index = 0; - - task_disable_irq(IT83XX_IRQ_PECI); - - peci_current_task = TASK_ID_INVALID; - - if (index < peci->timeout_us) { - - status = IT83XX_PECI_HOSTAR; - - /* any error */ - if (IT83XX_PECI_HOSTAR & PECI_STATUS_ANY_ERR) { - - if (IT83XX_PECI_HOSTAR & PECI_STATUS_ERR_NEED_RST) - peci_reset(); - - } else if (IT83XX_PECI_HOSTAR & PECI_STATUS_FINISH) { - - /* The read data field of the PECI protocol. */ - for (index = 0x00; index < peci->r_len; index++) - peci->r_buf[index] = IT83XX_PECI_HORDDR; - - /* W/C */ - IT83XX_PECI_HOSTAR = PECI_STATUS_FINISH; - status = IT83XX_PECI_HOSTAR; - } - } else { - /* transaction timeout */ - status = PECI_STATUS_TIMEOUT; - } - - /* Don't disable PECI host controller if controller already enable. */ - IT83XX_PECI_HOCTLR = 0x08; - - /* W/C */ - IT83XX_PECI_HOSTAR = PECI_STATUS_ANY_BIT; - - /* Disable PECI function pin */ - IT83XX_GPIO_GPCRF6 = 0x80; - - return status; -} - -void peci_interrupt(void) -{ - task_clear_pending_irq(IT83XX_IRQ_PECI); - task_disable_irq(IT83XX_IRQ_PECI); - - if (peci_current_task != TASK_ID_INVALID) - task_wake(peci_current_task); -} - -static void peci_init(void) -{ - clock_enable_peripheral(CGC_OFFSET_PECI, 0, 0); - peci_init_vtt_freq(); - - /* bit3,this bit enables the PECI host controller. */ - IT83XX_PECI_HOCTLR |= 0x08; - - /* bit4, PECI enable */ - IT83XX_GPIO_GRC2 |= 0x10; -} -DECLARE_HOOK(HOOK_INIT, peci_init, HOOK_PRIO_DEFAULT); diff --git a/chip/it83xx/pwm.c b/chip/it83xx/pwm.c deleted file mode 100644 index fda8dd23d6..0000000000 --- a/chip/it83xx/pwm.c +++ /dev/null @@ -1,281 +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 IT83xx. */ - -#include "clock.h" -#include "gpio.h" -#include "hooks.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "registers.h" -#include "util.h" -#include "math_util.h" - -#define PWM_CTRX_MIN 100 -#define PWM_EC_FREQ 8000000 - -const struct pwm_ctrl_t pwm_ctrl_regs[] = { - { &IT83XX_PWM_DCR0, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA0}, - { &IT83XX_PWM_DCR1, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA1}, - { &IT83XX_PWM_DCR2, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA2}, - { &IT83XX_PWM_DCR3, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA3}, - { &IT83XX_PWM_DCR4, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA4}, - { &IT83XX_PWM_DCR5, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA5}, - { &IT83XX_PWM_DCR6, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA6}, - { &IT83XX_PWM_DCR7, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA7}, -}; - -const struct pwm_ctrl_t2 pwm_clock_ctrl_regs[] = { - { &IT83XX_PWM_CTR, &IT83XX_PWM_C0CPRS, &IT83XX_PWM_C0CPRS, - &IT83XX_PWM_PCFSR, 0x01}, - { &IT83XX_PWM_CTR1, &IT83XX_PWM_C4CPRS, &IT83XX_PWM_C4MCPRS, - &IT83XX_PWM_PCFSR, 0x02}, - { &IT83XX_PWM_CTR2, &IT83XX_PWM_C6CPRS, &IT83XX_PWM_C6MCPRS, - &IT83XX_PWM_PCFSR, 0x04}, - { &IT83XX_PWM_CTR3, &IT83XX_PWM_C7CPRS, &IT83XX_PWM_C7MCPRS, - &IT83XX_PWM_PCFSR, 0x08}, -}; - -static int pwm_get_cycle_time(enum pwm_channel ch) -{ - int pcs_shift; - int pcs_mask; - int pcs_reg; - int cycle_time_setting; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* bit shift for "Prescaler Clock Source Select Group" register. */ - pcs_shift = (ch % 4) * 2; - - /* setting of "Prescaler Clock Source Select Group" register. */ - pcs_reg = *pwm_ctrl_regs[ch].pwm_clock_source; - - /* only bit0 bit1 information. */ - pcs_mask = (pcs_reg >> pcs_shift) & 0x03; - - /* get cycle time setting of PWM channel x. */ - cycle_time_setting = *pwm_clock_ctrl_regs[pcs_mask].pwm_cycle_time; - - return cycle_time_setting; -} - -void pwm_enable(enum pwm_channel ch, int enabled) -{ - /* pwm channel mapping */ - int pwm_reg_index = pwm_channels[ch].channel; - - /* - * enabled : pin to PWM function. - * disabled : pin to GPIO input function. - */ - if (enabled) - *pwm_ctrl_regs[pwm_reg_index].pwm_pin = 0x00; - else - *pwm_ctrl_regs[pwm_reg_index].pwm_pin = 0x80 | - ((pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) ? - 4 : 2); -} - -int pwm_get_enabled(enum pwm_channel ch) -{ - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* pin is PWM function and PWMs clock counter was enabled */ - return ((*pwm_ctrl_regs[ch].pwm_pin & ~0x04) == 0x00 && - IT83XX_PWM_ZTIER & 0x02) ? 1 : 0; -} - -void pwm_set_duty(enum pwm_channel ch, int percent) -{ - int pcs_shift; - int pcs_mask; - int pcs_reg; - int cycle_time_setting; - - if (percent < 0) - percent = 0; - else if (percent > 100) - percent = 100; - - if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) - percent = 100 - percent; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* bit shift for "Prescaler Clock Source Select Group" register. */ - pcs_shift = (ch % 4) * 2; - - /* setting of "Prescaler Clock Source Select Group" register.*/ - pcs_reg = *pwm_ctrl_regs[ch].pwm_clock_source; - - /* only bit0 bit1 information. */ - pcs_mask = (pcs_reg >> pcs_shift) & 0x03; - - /* get cycle time setting of PWM channel x. */ - cycle_time_setting = *pwm_clock_ctrl_regs[pcs_mask].pwm_cycle_time; - - /* to update PWM DCRx depend on CTRx setting. */ - if (percent == 100) { - *pwm_ctrl_regs[ch].pwm_duty = cycle_time_setting; - } else { - *pwm_ctrl_regs[ch].pwm_duty = - ((cycle_time_setting + 1) * percent) / 100; - } -} - -int pwm_get_duty(enum pwm_channel ch) -{ - int pcs_mask; - int pcs_reg; - int cycle_time_setting; - int percent; - int ch_idx; - - ch_idx = ch; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* setting of "Prescaler Clock Source Select Group" register.*/ - pcs_reg = *pwm_ctrl_regs[ch].pwm_clock_source; - - /* only bit0 bit1 information. */ - pcs_mask = (pcs_reg >> ((ch % 4) * 2)) & 0x03; - - /* get cycle time setting of PWM channel x. */ - cycle_time_setting = *pwm_clock_ctrl_regs[pcs_mask].pwm_cycle_time; - - percent = *pwm_ctrl_regs[ch].pwm_duty * 100 / cycle_time_setting; - - if (pwm_channels[ch_idx].flags & PWM_CONFIG_ACTIVE_LOW) - percent = 100 - percent; - - /* output signal duty cycle. */ - return percent; -} - -void pwm_duty_inc(enum pwm_channel ch) -{ - int cycle_time, pwm_ch; - - /* pwm channel mapping */ - pwm_ch = pwm_channels[ch].channel; - - cycle_time = pwm_get_cycle_time(ch); - - if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty > 0) - *pwm_ctrl_regs[pwm_ch].pwm_duty -= 1; - } else { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty < cycle_time) - *pwm_ctrl_regs[pwm_ch].pwm_duty += 1; - } -} - -void pwm_duty_reduce(enum pwm_channel ch) -{ - int cycle_time, pwm_ch; - - /* pwm channel mapping */ - pwm_ch = pwm_channels[ch].channel; - - cycle_time = pwm_get_cycle_time(ch); - - if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty < cycle_time) - *pwm_ctrl_regs[pwm_ch].pwm_duty += 1; - } else { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty > 0) - *pwm_ctrl_regs[pwm_ch].pwm_duty -= 1; - } -} - -static int pwm_ch_freq(enum pwm_channel ch) -{ - int actual_freq = -1, targe_freq, deviation; - int pcfsr, ctr, pcfsr_sel, pcs_shift, pcs_mask; - int pwm_clk_src = (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) ? - 32768 : PWM_EC_FREQ; - - targe_freq = pwm_channels[ch].freq_hz; - deviation = (targe_freq / 100) + 1; - - for (ctr = 0xFF; ctr >= PWM_CTRX_MIN; ctr--) { - pcfsr = (pwm_clk_src / (ctr + 1) / targe_freq) - 1; - if (pcfsr >= 0) { - actual_freq = pwm_clk_src / (ctr + 1) / (pcfsr + 1); - if (ABS(actual_freq - targe_freq) < deviation) - break; - } - } - - if (ctr < PWM_CTRX_MIN) { - actual_freq = -1; - } else { - pcfsr_sel = pwm_channels[ch].pcfsr_sel; - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_cycle_time = ctr; - - if (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) - /* - * Select 32.768KHz as PWM clock source. -] * - * NOTE: - * For pwm_channels[], the maximum supported pwm output - * signal frequency is 324 Hz (32768/(PWM_CTRX_MIN+1)). - */ - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_reg &= - ~pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_ctrl; - else - /* ec clock 8MHz */ - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_reg |= - pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_ctrl; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* - * bit shift for "Prescaler Clock Source Select Group" - * register. - */ - pcs_shift = (ch % 4) * 2; - pcs_mask = pcfsr_sel << pcs_shift; - - *pwm_ctrl_regs[ch].pwm_clock_source &= ~(0x3 << pcs_shift); - *pwm_ctrl_regs[ch].pwm_clock_source |= pcs_mask; - - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_cpr_lsb = pcfsr & 0xFF; - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_cpr_msb = - (pcfsr >> 8) & 0xFF; - } - - return actual_freq; -} - -static void pwm_init(void) -{ - int ch; - - for (ch = 0; ch < PWM_CH_COUNT; ch++) - pwm_ch_freq(ch); - - /* - * The cycle timer1 of chip 8320 later series was enhanced from - * 8bits to 10bits resolution, and others are still 8bit resolution. - * Because the cycle timer1 high byte default value is not zero, - * we clear cycle timer1 high byte at init and use it as 8-bit - * resolution like others. - */ - IT83XX_PWM_CTR1M = 0; - /* enable PWMs clock counter. */ - IT83XX_PWM_ZTIER |= 0x02; -} - -/* The chip PWM module initialization. */ -DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_INIT_PWM); diff --git a/chip/it83xx/pwm_chip.h b/chip/it83xx/pwm_chip.h deleted file mode 100644 index 4e8aba1c62..0000000000 --- a/chip/it83xx/pwm_chip.h +++ /dev/null @@ -1,97 +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 IT83xx. */ - -#ifndef __CROS_EC_PWM_CHIP_H -#define __CROS_EC_PWM_CHIP_H - -enum pwm_pcfsr_sel { - PWM_PRESCALER_C4 = 1, - PWM_PRESCALER_C6 = 2, - PWM_PRESCALER_C7 = 3, -}; - -enum pwm_hw_channel { - PWM_HW_CH_DCR0 = 0, - PWM_HW_CH_DCR1, - PWM_HW_CH_DCR2, - PWM_HW_CH_DCR3, - PWM_HW_CH_DCR4, - PWM_HW_CH_DCR5, - PWM_HW_CH_DCR6, - PWM_HW_CH_DCR7, - - PWM_HW_CH_TOTAL, -}; - -enum tach_ch_sel { - /* Pin GPIOD.6 */ - TACH_CH_TACH0A = 0, - /* Pin GPIOD.7 */ - TACH_CH_TACH1A, - /* Pin GPIOJ.2 */ - TACH_CH_TACH0B, - /* Pin GPIOJ.3 */ - TACH_CH_TACH1B, - /* Number of TACH channels */ - TACH_CH_COUNT, - - TACH_CH_NULL = 0xFF, -}; - -/* Data structure to define PWM channel control registers. */ -struct pwm_ctrl_t { - /* PWM channel output duty register. */ - volatile uint8_t *pwm_duty; - /* PWM channel clock source selection register. */ - volatile uint8_t *pwm_clock_source; - /* PWM channel pin control register. */ - volatile uint8_t *pwm_pin; -}; - -/* Data structure to define PWM channel control registers part 2. */ -struct pwm_ctrl_t2 { - /* PWM cycle time register. */ - volatile uint8_t *pwm_cycle_time; - /* PWM channel clock prescaler register (LSB). */ - volatile uint8_t *pwm_cpr_lsb; - /* PWM channel clock prescaler register (MSB). */ - volatile uint8_t *pwm_cpr_msb; - /* PWM prescaler clock frequency select register. */ - volatile uint8_t *pwm_pcfsr_reg; - /* PWM prescaler clock frequency select register setting. */ - uint8_t pwm_pcfsr_ctrl; -}; - -/* Data structure to define PWM channels. */ -struct pwm_t { - /* PWM channel ID */ - int channel; - /* PWM channel flags. See include/pwm.h */ - uint32_t flags; - int freq_hz; - enum pwm_pcfsr_sel pcfsr_sel; -}; - -/* Tachometer channel of each physical fan */ -struct fan_tach_t { - enum tach_ch_sel ch_tach; - /* the numbers of square pulses per revolution of fan. */ - int fan_p; - /* allow actual rpm ~= targe rpm +- rpm_re */ - int rpm_re; - /* startup duty of fan */ - int s_duty; -}; - -extern const struct pwm_t pwm_channels[]; -/* The list of tachometer channel of fans is instantiated in board.c. */ -extern const struct fan_tach_t fan_tach[]; - -void pwm_duty_inc(enum pwm_channel ch); -void pwm_duty_reduce(enum pwm_channel ch); - -#endif /* __CROS_EC_PWM_CHIP_H */ diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h deleted file mode 100644 index 34a2ddd6ae..0000000000 --- a/chip/it83xx/registers.h +++ /dev/null @@ -1,1678 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Register map for IT83xx processor - */ - -#ifndef __CROS_EC_REGISTERS_H -#define __CROS_EC_REGISTERS_H - -#include "common.h" -#include "compile_time_macros.h" - -#define __ram_code __attribute__((section(__RAM_CODE_SECTION_NAME))) - -/* IRQ numbers */ -/* Group 0 */ -#define IT83XX_IRQ_WKO20 1 -#define IT83XX_IRQ_KBC_OUT 2 -#define IT83XX_IRQ_PMC_OUT 3 -#define IT83XX_IRQ_SMB_D 4 -#define IT83XX_IRQ_WKINTAD 5 -#define IT83XX_IRQ_WKO23 6 -#define IT83XX_IRQ_PWM 7 -/* Group 1 */ -#define IT83XX_IRQ_ADC 8 -#define IT83XX_IRQ_SMB_A 9 -#define IT83XX_IRQ_SMB_B 10 -#define IT83XX_IRQ_KB_MATRIX 11 -#define IT83XX_IRQ_WKO26 12 -#define IT83XX_IRQ_WKINTC 13 -#define IT83XX_IRQ_WKO25 14 -#define IT83XX_IRQ_CIR 15 -/* Group 2 */ -#define IT83XX_IRQ_SMB_C 16 -#define IT83XX_IRQ_WKO24 17 -#define IT83XX_IRQ_PS2_2 18 -#define IT83XX_IRQ_PS2_1 19 -#define IT83XX_IRQ_PS2_0 20 -#define IT83XX_IRQ_WKO22 21 -#define IT83XX_IRQ_SMFI 22 -#define IT83XX_IRQ_USB 23 -/* Group 3 */ -#define IT83XX_IRQ_KBC_IN 24 -#define IT83XX_IRQ_PMC_IN 25 -#define IT83XX_IRQ_PMC2_OUT 26 -#define IT83XX_IRQ_PMC2_IN 27 -#define IT83XX_IRQ_GINT 28 -#define IT83XX_IRQ_EGPC 29 -#define IT83XX_IRQ_EXT_TIMER1 30 -#define IT83XX_IRQ_WKO21 31 -/* Group 4 */ -#define IT83XX_IRQ_GPINT0 32 -#define IT83XX_IRQ_GPINT1 33 -#define IT83XX_IRQ_GPINT2 34 -#define IT83XX_IRQ_GPINT3 35 -#define IT83XX_IRQ_CIR_GPINT 36 -#define IT83XX_IRQ_SSPI 37 -#define IT83XX_IRQ_UART1 38 -#define IT83XX_IRQ_UART2 39 -/* Group 5 */ -#define IT83XX_IRQ_WKO50 40 -#define IT83XX_IRQ_WKO51 41 -#define IT83XX_IRQ_WKO52 42 -#define IT83XX_IRQ_WKO53 43 -#define IT83XX_IRQ_WKO54 44 -#define IT83XX_IRQ_WKO55 45 -#define IT83XX_IRQ_WKO56 46 -#define IT83XX_IRQ_WKO57 47 -/* Group 6 */ -#define IT83XX_IRQ_WKO60 48 -#define IT83XX_IRQ_WKO61 49 -#define IT83XX_IRQ_WKO62 50 -#define IT83XX_IRQ_WKO63 51 -#define IT83XX_IRQ_WKO64 52 -#define IT83XX_IRQ_WKO65 53 -#define IT83XX_IRQ_WKO66 54 -#define IT83XX_IRQ_WKO67 55 -/* Group 7 */ -#define IT83XX_IRQ_RTCT_ALARM1 56 -#define IT83XX_IRQ_RTCT_ALARM2 57 -#define IT83XX_IRQ_EXT_TIMER2 58 -#define IT83XX_IRQ_DEFERRED_SPI 59 -#define IT83XX_IRQ_TMR_A0 60 -#define IT83XX_IRQ_TMR_A1 61 -#define IT83XX_IRQ_TMR_B0 62 -#define IT83XX_IRQ_TMR_B1 63 -/* Group 8 */ -#define IT83XX_IRQ_PMC2EX_OUT 64 -#define IT83XX_IRQ_PMC2EX_IN 65 -#define IT83XX_IRQ_PMC3_OUT 66 -#define IT83XX_IRQ_PMC3_IN 67 -#define IT83XX_IRQ_PMC4_OUT 68 -#define IT83XX_IRQ_PMC4_IN 69 -#define IT83XX_IRQ_I2BRAM 71 -/* Group 9 */ -#define IT83XX_IRQ_WKO70 72 -#define IT83XX_IRQ_WKO71 73 -#define IT83XX_IRQ_WKO72 74 -#define IT83XX_IRQ_WKO73 75 -#define IT83XX_IRQ_WKO74 76 -#define IT83XX_IRQ_WKO75 77 -#define IT83XX_IRQ_WKO76 78 -#define IT83XX_IRQ_WKO77 79 -/* Group 10 */ -#define IT83XX_IRQ_EXT_TMR8 80 -#define IT83XX_IRQ_SMB_CLOCK_HELD 81 -#define IT83XX_IRQ_CEC 82 -#define IT83XX_IRQ_H2RAM_LPC 83 -#define IT83XX_IRQ_HW_KB_SCAN 84 -#define IT83XX_IRQ_WKO88 85 -#define IT83XX_IRQ_WKO89 86 -#define IT83XX_IRQ_WKO90 87 -/* Group 11 */ -#define IT83XX_IRQ_WKO80 88 -#define IT83XX_IRQ_WKO81 89 -#define IT83XX_IRQ_WKO82 90 -#define IT83XX_IRQ_WKO83 91 -#define IT83XX_IRQ_WKO84 92 -#define IT83XX_IRQ_WKO85 93 -#define IT83XX_IRQ_WKO86 94 -#define IT83XX_IRQ_WKO87 95 -/* Group 12 */ -#define IT83XX_IRQ_WKO91 96 -#define IT83XX_IRQ_WKO92 97 -#define IT83XX_IRQ_WKO93 98 -#define IT83XX_IRQ_WKO94 99 -#define IT83XX_IRQ_WKO95 100 -#define IT83XX_IRQ_WKO96 101 -#define IT83XX_IRQ_WKO97 102 -#define IT83XX_IRQ_WKO98 103 -/* Group 13 */ -#define IT83XX_IRQ_WKO99 104 -#define IT83XX_IRQ_WKO100 105 -#define IT83XX_IRQ_WKO101 106 -#define IT83XX_IRQ_WKO102 107 -#define IT83XX_IRQ_WKO103 108 -#define IT83XX_IRQ_WKO104 109 -#define IT83XX_IRQ_WKO105 110 -#define IT83XX_IRQ_WKO106 111 -/* Group 14 */ -#define IT83XX_IRQ_WKO107 112 -#define IT83XX_IRQ_WKO108 113 -#define IT83XX_IRQ_WKO109 114 -#define IT83XX_IRQ_WKO110 115 -#define IT83XX_IRQ_WKO111 116 -#define IT83XX_IRQ_WKO112 117 -#define IT83XX_IRQ_WKO113 118 -#define IT83XX_IRQ_WKO114 119 -/* Group 15 */ -#define IT83XX_IRQ_WKO115 120 -#define IT83XX_IRQ_WKO116 121 -#define IT83XX_IRQ_WKO117 122 -#define IT83XX_IRQ_WKO118 123 -#define IT83XX_IRQ_WKO119 124 -#define IT83XX_IRQ_WKO120 125 -#define IT83XX_IRQ_WKO121 126 -#define IT83XX_IRQ_WKO122 127 -/* Group 16 */ -#define IT83XX_IRQ_WKO128 128 -#define IT83XX_IRQ_WKO129 129 -#define IT83XX_IRQ_WKO130 130 -#define IT83XX_IRQ_WKO131 131 -#define IT83XX_IRQ_WKO132 132 -#define IT83XX_IRQ_WKO133 133 -#define IT83XX_IRQ_WKO134 134 -#define IT83XX_IRQ_WKO135 135 -/* Group 17 */ -#define IT83XX_IRQ_WKO136 136 -#define IT83XX_IRQ_WKO137 137 -#define IT83XX_IRQ_WKO138 138 -#define IT83XX_IRQ_WKO139 139 -#define IT83XX_IRQ_WKO140 140 -#define IT83XX_IRQ_WKO141 141 -#define IT83XX_IRQ_WKO142 142 -#define IT83XX_IRQ_WKO143 143 -/* Group 18 */ -#define IT83XX_IRQ_WKO123 144 -#define IT83XX_IRQ_WKO124 145 -#define IT83XX_IRQ_WKO125 146 -#define IT83XX_IRQ_WKO126 147 -#define IT83XX_IRQ_PMC5_OUT 149 -#define IT83XX_IRQ_PMC5_IN 150 -#define IT83XX_IRQ_V_COMP 151 -/* Group 19 */ -#define IT83XX_IRQ_SMB_E 152 -#define IT83XX_IRQ_SMB_F 153 -#define IT83XX_IRQ_OSC_DMA 154 -#define IT83XX_IRQ_EXT_TIMER3 155 -#define IT83XX_IRQ_EXT_TIMER4 156 -#define IT83XX_IRQ_EXT_TIMER5 157 -#define IT83XX_IRQ_EXT_TIMER6 158 -#define IT83XX_IRQ_EXT_TIMER7 159 -/* Group 20 */ -#define IT83XX_IRQ_PECI 160 -#define IT83XX_IRQ_SOFTWARE 161 -#define IT83XX_IRQ_ESPI 162 -#define IT83XX_IRQ_ESPI_VW 163 -#define IT83XX_IRQ_PCH_P80 164 -#define IT83XX_IRQ_USBPD0 165 -#define IT83XX_IRQ_USBPD1 166 -/* Group 21 */ -#if defined(CHIP_FAMILY_IT8320) -#define IT83XX_IRQ_WKO40 168 -#define IT83XX_IRQ_WKO45 169 -#define IT83XX_IRQ_WKO46 170 -#define IT83XX_IRQ_WKO144 171 -#define IT83XX_IRQ_WKO145 172 -#define IT83XX_IRQ_WKO146 173 -#define IT83XX_IRQ_WKO147 174 -#define IT83XX_IRQ_WKO148 175 -/* Group 22 */ -#define IT83XX_IRQ_WKO149 176 -#define IT83XX_IRQ_WKO150 177 - -#define IT83XX_IRQ_COUNT 178 -#elif defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) -/* Group 21 */ -#define IT83XX_IRQ_AUDIO_IF 170 -#define IT83XX_IRQ_SPI_PERIPHERAL 171 -#define IT83XX_IRQ_DSP_ENGINE 172 -#define IT83XX_IRQ_NN_ENGINE 173 -#define IT83XX_IRQ_USBPD2 174 -#define IT83XX_IRQ_CRYPTO 175 -/* Group 22 */ -#define IT83XX_IRQ_WKO40 176 -#define IT83XX_IRQ_WKO45 177 -#define IT83XX_IRQ_WKO46 178 -#define IT83XX_IRQ_WKO144 179 -#define IT83XX_IRQ_WKO145 180 -#define IT83XX_IRQ_WKO146 181 -#define IT83XX_IRQ_WKO147 182 -#define IT83XX_IRQ_WKO148 183 -/* Group 23 */ -#define IT83XX_IRQ_WKO149 184 -#define IT83XX_IRQ_WKO150 185 -#define IT83XX_IRQ_SSPI1 191 -/* Group 24 */ -#define IT83XX_IRQ_XLPIN0 192 -#define IT83XX_IRQ_XLPIN1 193 -#define IT83XX_IRQ_XLPIN2 194 -#define IT83XX_IRQ_XLPIN3 195 -#define IT83XX_IRQ_XLPIN4 196 -#define IT83XX_IRQ_XLPIN5 197 -#define IT83XX_IRQ_WEEK_ALARM 199 -/* Group 25 */ -#define IT83XX_IRQ_GPO0 200 -#define IT83XX_IRQ_GPO1 201 -#define IT83XX_IRQ_GPO2 202 -#define IT83XX_IRQ_GPO3 203 -/* Group 26 */ -#define IT83XX_IRQ_GPP0 208 -#define IT83XX_IRQ_GPP1 209 -#define IT83XX_IRQ_GPP2 210 -#define IT83XX_IRQ_GPP3 211 -#define IT83XX_IRQ_GPP4 212 -#define IT83XX_IRQ_GPP5 213 -#define IT83XX_IRQ_GPP6 214 -/* Group 27 */ -#define IT83XX_IRQ_GPQ0 216 -#define IT83XX_IRQ_GPQ1 217 -#define IT83XX_IRQ_GPQ2 218 -#define IT83XX_IRQ_GPQ3 219 -#define IT83XX_IRQ_GPQ4 220 -#define IT83XX_IRQ_GPQ5 221 -/* Group 28 */ -#define IT83XX_IRQ_GPR0 224 -#define IT83XX_IRQ_GPR1 225 -#define IT83XX_IRQ_GPR2 226 -#define IT83XX_IRQ_GPR3 227 -#define IT83XX_IRQ_GPR4 228 -#define IT83XX_IRQ_GPR5 229 - -#define IT83XX_IRQ_COUNT 230 -#endif /* !defined(CHIP_FAMILY_IT8320) */ - -/* IRQ dispatching to CPU INT vectors */ -#define IT83XX_CPU_INT_IRQ_1 2 -#define IT83XX_CPU_INT_IRQ_2 5 -#define IT83XX_CPU_INT_IRQ_3 4 -#define IT83XX_CPU_INT_IRQ_4 6 -#define IT83XX_CPU_INT_IRQ_5 2 -#define IT83XX_CPU_INT_IRQ_6 2 -#define IT83XX_CPU_INT_IRQ_7 4 -#define IT83XX_CPU_INT_IRQ_8 7 -#define IT83XX_CPU_INT_IRQ_9 6 -#define IT83XX_CPU_INT_IRQ_10 6 -#define IT83XX_CPU_INT_IRQ_11 5 -#define IT83XX_CPU_INT_IRQ_12 2 -#define IT83XX_CPU_INT_IRQ_13 2 -#define IT83XX_CPU_INT_IRQ_14 2 -#define IT83XX_CPU_INT_IRQ_15 8 -#define IT83XX_CPU_INT_IRQ_16 6 -#define IT83XX_CPU_INT_IRQ_17 2 -#define IT83XX_CPU_INT_IRQ_18 8 -#define IT83XX_CPU_INT_IRQ_19 8 -#define IT83XX_CPU_INT_IRQ_20 8 -#define IT83XX_CPU_INT_IRQ_21 2 -#define IT83XX_CPU_INT_IRQ_22 12 -#define IT83XX_CPU_INT_IRQ_23 12 -#define IT83XX_CPU_INT_IRQ_24 5 -#define IT83XX_CPU_INT_IRQ_25 4 -#define IT83XX_CPU_INT_IRQ_26 4 -#define IT83XX_CPU_INT_IRQ_27 4 -#define IT83XX_CPU_INT_IRQ_28 11 -#define IT83XX_CPU_INT_IRQ_29 11 -#define IT83XX_CPU_INT_IRQ_30 3 -#define IT83XX_CPU_INT_IRQ_31 2 -#define IT83XX_CPU_INT_IRQ_32 11 -#define IT83XX_CPU_INT_IRQ_33 11 -#define IT83XX_CPU_INT_IRQ_34 11 -#define IT83XX_CPU_INT_IRQ_35 11 -#define IT83XX_CPU_INT_IRQ_36 8 -#define IT83XX_CPU_INT_IRQ_37 9 -#define IT83XX_CPU_INT_IRQ_38 9 -#define IT83XX_CPU_INT_IRQ_39 9 -#define IT83XX_CPU_INT_IRQ_40 2 -#define IT83XX_CPU_INT_IRQ_41 2 -#define IT83XX_CPU_INT_IRQ_42 2 -#define IT83XX_CPU_INT_IRQ_43 2 -#define IT83XX_CPU_INT_IRQ_44 2 -#define IT83XX_CPU_INT_IRQ_45 2 -#define IT83XX_CPU_INT_IRQ_46 2 -#define IT83XX_CPU_INT_IRQ_47 2 -#define IT83XX_CPU_INT_IRQ_48 2 -#define IT83XX_CPU_INT_IRQ_49 2 -#define IT83XX_CPU_INT_IRQ_50 2 -#define IT83XX_CPU_INT_IRQ_51 2 -#define IT83XX_CPU_INT_IRQ_52 2 -#define IT83XX_CPU_INT_IRQ_53 2 -#define IT83XX_CPU_INT_IRQ_54 2 -#define IT83XX_CPU_INT_IRQ_55 2 -#define IT83XX_CPU_INT_IRQ_56 10 -#define IT83XX_CPU_INT_IRQ_57 10 -#define IT83XX_CPU_INT_IRQ_58 3 -#define IT83XX_CPU_INT_IRQ_59 12 -#define IT83XX_CPU_INT_IRQ_60 3 -#define IT83XX_CPU_INT_IRQ_61 3 -#define IT83XX_CPU_INT_IRQ_62 3 -#define IT83XX_CPU_INT_IRQ_63 3 -#define IT83XX_CPU_INT_IRQ_64 4 -#define IT83XX_CPU_INT_IRQ_65 4 -#define IT83XX_CPU_INT_IRQ_66 4 -#define IT83XX_CPU_INT_IRQ_67 4 -#define IT83XX_CPU_INT_IRQ_68 4 -#define IT83XX_CPU_INT_IRQ_69 4 -#define IT83XX_CPU_INT_IRQ_71 12 -#define IT83XX_CPU_INT_IRQ_72 2 -#define IT83XX_CPU_INT_IRQ_73 2 -#define IT83XX_CPU_INT_IRQ_74 2 -#define IT83XX_CPU_INT_IRQ_75 2 -#define IT83XX_CPU_INT_IRQ_76 2 -#define IT83XX_CPU_INT_IRQ_77 2 -#define IT83XX_CPU_INT_IRQ_78 2 -#define IT83XX_CPU_INT_IRQ_79 2 -#define IT83XX_CPU_INT_IRQ_80 3 -#define IT83XX_CPU_INT_IRQ_81 6 -#define IT83XX_CPU_INT_IRQ_82 12 -#define IT83XX_CPU_INT_IRQ_83 12 -#define IT83XX_CPU_INT_IRQ_84 5 -#define IT83XX_CPU_INT_IRQ_85 2 -#define IT83XX_CPU_INT_IRQ_86 2 -#define IT83XX_CPU_INT_IRQ_87 2 -#define IT83XX_CPU_INT_IRQ_88 2 -#define IT83XX_CPU_INT_IRQ_89 2 -#define IT83XX_CPU_INT_IRQ_90 2 -#define IT83XX_CPU_INT_IRQ_91 2 -#define IT83XX_CPU_INT_IRQ_92 2 -#define IT83XX_CPU_INT_IRQ_93 2 -#define IT83XX_CPU_INT_IRQ_94 2 -#define IT83XX_CPU_INT_IRQ_95 2 -#define IT83XX_CPU_INT_IRQ_96 2 -#define IT83XX_CPU_INT_IRQ_97 2 -#define IT83XX_CPU_INT_IRQ_98 2 -#define IT83XX_CPU_INT_IRQ_99 2 -#define IT83XX_CPU_INT_IRQ_100 2 -#define IT83XX_CPU_INT_IRQ_101 2 -#define IT83XX_CPU_INT_IRQ_102 2 -#define IT83XX_CPU_INT_IRQ_103 2 -#define IT83XX_CPU_INT_IRQ_104 2 -#define IT83XX_CPU_INT_IRQ_105 2 -#define IT83XX_CPU_INT_IRQ_106 2 -#define IT83XX_CPU_INT_IRQ_107 2 -#define IT83XX_CPU_INT_IRQ_108 2 -#define IT83XX_CPU_INT_IRQ_109 2 -#define IT83XX_CPU_INT_IRQ_110 2 -#define IT83XX_CPU_INT_IRQ_111 2 -#define IT83XX_CPU_INT_IRQ_112 2 -#define IT83XX_CPU_INT_IRQ_113 2 -#define IT83XX_CPU_INT_IRQ_114 2 -#define IT83XX_CPU_INT_IRQ_115 2 -#define IT83XX_CPU_INT_IRQ_116 2 -#define IT83XX_CPU_INT_IRQ_117 2 -#define IT83XX_CPU_INT_IRQ_118 2 -#define IT83XX_CPU_INT_IRQ_119 2 -#define IT83XX_CPU_INT_IRQ_120 2 -#define IT83XX_CPU_INT_IRQ_121 2 -#define IT83XX_CPU_INT_IRQ_122 2 -#define IT83XX_CPU_INT_IRQ_123 2 -#define IT83XX_CPU_INT_IRQ_124 2 -#define IT83XX_CPU_INT_IRQ_125 2 -#define IT83XX_CPU_INT_IRQ_126 2 -#define IT83XX_CPU_INT_IRQ_127 2 -#define IT83XX_CPU_INT_IRQ_128 2 -#define IT83XX_CPU_INT_IRQ_129 2 -#define IT83XX_CPU_INT_IRQ_130 2 -#define IT83XX_CPU_INT_IRQ_131 2 -#define IT83XX_CPU_INT_IRQ_132 2 -#define IT83XX_CPU_INT_IRQ_133 2 -#define IT83XX_CPU_INT_IRQ_134 2 -#define IT83XX_CPU_INT_IRQ_135 2 -#define IT83XX_CPU_INT_IRQ_136 2 -#define IT83XX_CPU_INT_IRQ_137 2 -#define IT83XX_CPU_INT_IRQ_138 2 -#define IT83XX_CPU_INT_IRQ_139 2 -#define IT83XX_CPU_INT_IRQ_140 2 -#define IT83XX_CPU_INT_IRQ_141 2 -#define IT83XX_CPU_INT_IRQ_142 2 -#define IT83XX_CPU_INT_IRQ_143 2 -#define IT83XX_CPU_INT_IRQ_144 2 -#define IT83XX_CPU_INT_IRQ_145 2 -#define IT83XX_CPU_INT_IRQ_146 2 -#define IT83XX_CPU_INT_IRQ_147 2 -#define IT83XX_CPU_INT_IRQ_149 4 -#define IT83XX_CPU_INT_IRQ_150 4 -#define IT83XX_CPU_INT_IRQ_151 7 -#define IT83XX_CPU_INT_IRQ_152 6 -#define IT83XX_CPU_INT_IRQ_153 6 -#define IT83XX_CPU_INT_IRQ_154 12 -#define IT83XX_CPU_INT_IRQ_155 3 -#define IT83XX_CPU_INT_IRQ_156 3 -#define IT83XX_CPU_INT_IRQ_157 3 -#define IT83XX_CPU_INT_IRQ_158 3 -#define IT83XX_CPU_INT_IRQ_159 3 -#define IT83XX_CPU_INT_IRQ_160 12 -#define IT83XX_CPU_INT_IRQ_161 12 -#define IT83XX_CPU_INT_IRQ_162 12 -#define IT83XX_CPU_INT_IRQ_163 12 -#define IT83XX_CPU_INT_IRQ_164 12 -#define IT83XX_CPU_INT_IRQ_165 12 -#define IT83XX_CPU_INT_IRQ_166 12 -#define IT83XX_CPU_INT_IRQ_167 12 -#define IT83XX_CPU_INT_IRQ_168 2 -#define IT83XX_CPU_INT_IRQ_169 2 -#if defined(CHIP_FAMILY_IT8320) -#define IT83XX_CPU_INT_IRQ_170 2 -#define IT83XX_CPU_INT_IRQ_171 2 -#define IT83XX_CPU_INT_IRQ_172 2 -#define IT83XX_CPU_INT_IRQ_173 2 -#define IT83XX_CPU_INT_IRQ_174 2 -#define IT83XX_CPU_INT_IRQ_175 2 -#elif defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) -#define IT83XX_CPU_INT_IRQ_170 12 -#define IT83XX_CPU_INT_IRQ_171 12 -#define IT83XX_CPU_INT_IRQ_172 12 -#define IT83XX_CPU_INT_IRQ_173 12 -#define IT83XX_CPU_INT_IRQ_174 12 -#define IT83XX_CPU_INT_IRQ_175 12 -#endif -#define IT83XX_CPU_INT_IRQ_176 2 -#define IT83XX_CPU_INT_IRQ_177 2 -#define IT83XX_CPU_INT_IRQ_178 2 -#define IT83XX_CPU_INT_IRQ_179 2 -#define IT83XX_CPU_INT_IRQ_180 2 -#define IT83XX_CPU_INT_IRQ_181 2 -#define IT83XX_CPU_INT_IRQ_182 2 -#define IT83XX_CPU_INT_IRQ_183 2 -#define IT83XX_CPU_INT_IRQ_184 2 -#define IT83XX_CPU_INT_IRQ_185 2 -#define IT83XX_CPU_INT_IRQ_191 2 -#define IT83XX_CPU_INT_IRQ_192 2 -#define IT83XX_CPU_INT_IRQ_193 2 -#define IT83XX_CPU_INT_IRQ_194 2 -#define IT83XX_CPU_INT_IRQ_195 2 -#define IT83XX_CPU_INT_IRQ_196 2 -#define IT83XX_CPU_INT_IRQ_197 2 -#define IT83XX_CPU_INT_IRQ_199 2 -#define IT83XX_CPU_INT_IRQ_200 2 -#define IT83XX_CPU_INT_IRQ_201 2 -#define IT83XX_CPU_INT_IRQ_202 2 -#define IT83XX_CPU_INT_IRQ_203 2 -#define IT83XX_CPU_INT_IRQ_208 2 -#define IT83XX_CPU_INT_IRQ_209 2 -#define IT83XX_CPU_INT_IRQ_210 2 -#define IT83XX_CPU_INT_IRQ_211 2 -#define IT83XX_CPU_INT_IRQ_212 2 -#define IT83XX_CPU_INT_IRQ_213 2 -#define IT83XX_CPU_INT_IRQ_214 2 -#define IT83XX_CPU_INT_IRQ_216 2 -#define IT83XX_CPU_INT_IRQ_217 2 -#define IT83XX_CPU_INT_IRQ_218 2 -#define IT83XX_CPU_INT_IRQ_219 2 -#define IT83XX_CPU_INT_IRQ_220 2 -#define IT83XX_CPU_INT_IRQ_221 2 -#define IT83XX_CPU_INT_IRQ_224 2 -#define IT83XX_CPU_INT_IRQ_225 2 -#define IT83XX_CPU_INT_IRQ_226 2 -#define IT83XX_CPU_INT_IRQ_227 2 -#define IT83XX_CPU_INT_IRQ_228 2 -#define IT83XX_CPU_INT_IRQ_229 2 - -/* "Fake" IRQ to declare in readable fashion all WKO IRQ routed to INT#2 */ -#define CPU_INT_2_ALL_GPIOS 255 -#define IT83XX_CPU_INT_IRQ_255 2 - -#define CPU_INT_GROUP_5 254 -#define IT83XX_CPU_INT_IRQ_254 5 - -#define CPU_INT_GROUP_4 252 -#define IT83XX_CPU_INT_IRQ_252 4 - -#define CPU_INT_GROUP_12 253 -#define IT83XX_CPU_INT_IRQ_253 12 - -#define CPU_INT_GROUP_3 251 -#define IT83XX_CPU_INT_IRQ_251 3 - -#define CPU_INT_GROUP_6 250 -#define IT83XX_CPU_INT_IRQ_250 6 - -#define CPU_INT_GROUP_9 249 -#define IT83XX_CPU_INT_IRQ_249 9 - -#define CPU_INT_GROUP_7 248 -#define IT83XX_CPU_INT_IRQ_248 7 - -#define CPU_INT(irq) CONCAT2(IT83XX_CPU_INT_IRQ_, irq) - -/* --- INTC --- */ -#define IT83XX_INTC_BASE CHIP_EC_INTC_BASE - -#define IT83XX_INTC_REG(n) REG8(IT83XX_INTC_BASE+(n)) - -#define IT83XX_INTC_AIVCT REG8(IT83XX_INTC_BASE+0x10) - -#define IT83XX_INTC_IER0 REG8(IT83XX_INTC_BASE+0x04) -#define IT83XX_INTC_IER1 REG8(IT83XX_INTC_BASE+0x05) -#define IT83XX_INTC_IER2 REG8(IT83XX_INTC_BASE+0x06) -#define IT83XX_INTC_IER3 REG8(IT83XX_INTC_BASE+0x07) -#define IT83XX_INTC_IER4 REG8(IT83XX_INTC_BASE+0x15) -#define IT83XX_INTC_IER5 REG8(IT83XX_INTC_BASE+0x19) -#define IT83XX_INTC_IER6 REG8(IT83XX_INTC_BASE+0x1d) -#define IT83XX_INTC_IER7 REG8(IT83XX_INTC_BASE+0x21) -#define IT83XX_INTC_IER8 REG8(IT83XX_INTC_BASE+0x25) -#define IT83XX_INTC_IER9 REG8(IT83XX_INTC_BASE+0x29) -#define IT83XX_INTC_IER10 REG8(IT83XX_INTC_BASE+0x2d) -#define IT83XX_INTC_IER11 REG8(IT83XX_INTC_BASE+0x31) -#define IT83XX_INTC_IER12 REG8(IT83XX_INTC_BASE+0x35) -#define IT83XX_INTC_IER13 REG8(IT83XX_INTC_BASE+0x39) -#define IT83XX_INTC_IER14 REG8(IT83XX_INTC_BASE+0x3d) -#define IT83XX_INTC_IER15 REG8(IT83XX_INTC_BASE+0x41) -#define IT83XX_INTC_IER16 REG8(IT83XX_INTC_BASE+0x45) -#define IT83XX_INTC_IER17 REG8(IT83XX_INTC_BASE+0x49) -#define IT83XX_INTC_IER18 REG8(IT83XX_INTC_BASE+0x4d) -#define IT83XX_INTC_IER19 REG8(IT83XX_INTC_BASE+0x51) -#define IT83XX_INTC_IER20 REG8(IT83XX_INTC_BASE+0x55) -#define IT83XX_INTC_IER21 REG8(IT83XX_INTC_BASE+0x59) -#define IT83XX_INTC_IER22 REG8(IT83XX_INTC_BASE+0x5d) -#define IT83XX_INTC_IER23 REG8(IT83XX_INTC_BASE+0x91) -#define IT83XX_INTC_IER24 REG8(IT83XX_INTC_BASE+0x95) -#define IT83XX_INTC_IER25 REG8(IT83XX_INTC_BASE+0x99) -#define IT83XX_INTC_IER26 REG8(IT83XX_INTC_BASE+0x9d) -#define IT83XX_INTC_IER27 REG8(IT83XX_INTC_BASE+0xa1) -#define IT83XX_INTC_IER28 REG8(IT83XX_INTC_BASE+0xa5) - -#define IT83XX_INTC_ISR0 REG8(IT83XX_INTC_BASE+0x00) -#define IT83XX_INTC_ISR1 REG8(IT83XX_INTC_BASE+0x01) -#define IT83XX_INTC_ISR2 REG8(IT83XX_INTC_BASE+0x02) -#define IT83XX_INTC_ISR3 REG8(IT83XX_INTC_BASE+0x03) -#define IT83XX_INTC_ISR4 REG8(IT83XX_INTC_BASE+0x14) -#define IT83XX_INTC_ISR5 REG8(IT83XX_INTC_BASE+0x18) -#define IT83XX_INTC_ISR6 REG8(IT83XX_INTC_BASE+0x1c) -#define IT83XX_INTC_ISR7 REG8(IT83XX_INTC_BASE+0x20) -#define IT83XX_INTC_ISR8 REG8(IT83XX_INTC_BASE+0x24) -#define IT83XX_INTC_ISR9 REG8(IT83XX_INTC_BASE+0x28) -#define IT83XX_INTC_ISR10 REG8(IT83XX_INTC_BASE+0x2c) -#define IT83XX_INTC_ISR11 REG8(IT83XX_INTC_BASE+0x30) -#define IT83XX_INTC_ISR12 REG8(IT83XX_INTC_BASE+0x34) -#define IT83XX_INTC_ISR13 REG8(IT83XX_INTC_BASE+0x38) -#define IT83XX_INTC_ISR14 REG8(IT83XX_INTC_BASE+0x3c) -#define IT83XX_INTC_ISR15 REG8(IT83XX_INTC_BASE+0x40) -#define IT83XX_INTC_ISR16 REG8(IT83XX_INTC_BASE+0x44) -#define IT83XX_INTC_ISR17 REG8(IT83XX_INTC_BASE+0x48) -#define IT83XX_INTC_ISR18 REG8(IT83XX_INTC_BASE+0x4c) -#define IT83XX_INTC_ISR19 REG8(IT83XX_INTC_BASE+0x50) -#define IT83XX_INTC_ISR20 REG8(IT83XX_INTC_BASE+0x54) -#define IT83XX_INTC_ISR21 REG8(IT83XX_INTC_BASE+0x58) -#define IT83XX_INTC_ISR22 REG8(IT83XX_INTC_BASE+0x5c) -#define IT83XX_INTC_ISR23 REG8(IT83XX_INTC_BASE+0x90) -#define IT83XX_INTC_ISR24 REG8(IT83XX_INTC_BASE+0x94) -#define IT83XX_INTC_ISR25 REG8(IT83XX_INTC_BASE+0x98) -#define IT83XX_INTC_ISR26 REG8(IT83XX_INTC_BASE+0x9c) -#define IT83XX_INTC_ISR27 REG8(IT83XX_INTC_BASE+0xa0) -#define IT83XX_INTC_ISR28 REG8(IT83XX_INTC_BASE+0xa4) - -#define IT83XX_INTC_IELMR10 REG8(IT83XX_INTC_BASE+0x2E) -#define IT83XX_INTC_IPOLR10 REG8(IT83XX_INTC_BASE+0x2F) -#define IT83XX_INTC_IELMR19 REG8(IT83XX_INTC_BASE+0x52) -#define IT83XX_INTC_IPOLR19 REG8(IT83XX_INTC_BASE+0x53) - -#define IT83XX_INTC_EXT_IER_OFF(n) (0x60 + (n)) -#define IT83XX_INTC_IVCT(i) REG8(IT83XX_INTC_BASE+0x80+(i)) - -/* --- EC Access to the Host Controlled Modules (EC2I Bridge) --- */ -#define IT83XX_EC2I_BASE 0x00F01200 - -#define IT83XX_EC2I_IHIOA REG8(IT83XX_EC2I_BASE+0x00) -#define IT83XX_EC2I_IHD REG8(IT83XX_EC2I_BASE+0x01) -#define IT83XX_EC2I_LSIOHA REG8(IT83XX_EC2I_BASE+0x02) -#define IT83XX_EC2I_SIOLV REG8(IT83XX_EC2I_BASE+0x03) -#define IT83XX_EC2I_IBMAE REG8(IT83XX_EC2I_BASE+0x04) -#define IT83XX_EC2I_IBCTL REG8(IT83XX_EC2I_BASE+0x05) - -/* --- System Wake-UP Control (SWUC) --- */ -#define IT83XX_SWUC_BASE 0x00F01400 -#define IT83XX_SWUC_SWCTL1 REG8(IT83XX_SWUC_BASE+0x00) - -/* --- Wake-Up Control (WUC) --- */ -#define IT83XX_WUC_BASE 0x00F01B00 - -#define IT83XX_WUC_WUEMR1 (IT83XX_WUC_BASE+0x00) -#define IT83XX_WUC_WUEMR5 (IT83XX_WUC_BASE+0x0c) -#define IT83XX_WUC_WUESR1 (IT83XX_WUC_BASE+0x04) -#define IT83XX_WUC_WUESR5 (IT83XX_WUC_BASE+0x0d) -#define IT83XX_WUC_WUBEMR1 (IT83XX_WUC_BASE+0x3c) -#define IT83XX_WUC_WUBEMR5 (IT83XX_WUC_BASE+0x0f) - -#define IT83XX_WUC_WUESR10 REG8(IT83XX_WUC_BASE+0x21) -#define IT83XX_WUC_WUESR11 REG8(IT83XX_WUC_BASE+0x25) - -#define IT83XX_WUC_WUEMR3 REG8(IT83XX_WUC_BASE+0x02) -#define IT83XX_WUC_WUESR3 REG8(IT83XX_WUC_BASE+0x06) -#define IT83XX_WUC_WUENR3 REG8(IT83XX_WUC_BASE+0x0A) - -#define IT83XX_WUC_WUEMR4 REG8(IT83XX_WUC_BASE+0x03) -#define IT83XX_WUC_WUESR4 REG8(IT83XX_WUC_BASE+0x07) -#define IT83XX_WUC_WUENR4 REG8(IT83XX_WUC_BASE+0x0B) - -/* --- UART --- */ -#define IT83XX_UART0_BASE 0x00F02700 -#define IT83XX_UART1_BASE 0x00F02800 - -#define IT83XX_UART_BASE(n) CONCAT3(IT83XX_UART, n, _BASE) -#define IT83XX_UART_REG(n, offset) REG8(IT83XX_UART_BASE(n) + (offset)) - -#define IT83XX_UART_DLL(n) IT83XX_UART_REG(n, 0x00) -#define IT83XX_UART_DLM(n) IT83XX_UART_REG(n, 0x01) -#define IT83XX_UART_RBR(n) IT83XX_UART_REG(n, 0x00) -#define IT83XX_UART_THR(n) IT83XX_UART_REG(n, 0x00) -#define IT83XX_UART_IER(n) IT83XX_UART_REG(n, 0x01) -#define IT83XX_UART_IIR(n) IT83XX_UART_REG(n, 0x02) -#define IT83XX_UART_FCR(n) IT83XX_UART_REG(n, 0x02) -#define IT83XX_UART_LCR(n) IT83XX_UART_REG(n, 0x03) -#define IT83XX_UART_MCR(n) IT83XX_UART_REG(n, 0x04) -#define IT83XX_UART_LSR(n) IT83XX_UART_REG(n, 0x05) -#define IT83XX_UART_MSR(n) IT83XX_UART_REG(n, 0x06) -#define IT83XX_UART_SCR(n) IT83XX_UART_REG(n, 0x07) -#define IT83XX_UART_ECSMPR(n) IT83XX_UART_REG(n, 0x08) -#define IT83XX_UART_CSSR(n) IT83XX_UART_REG(n, 0x09) - -/* --- GPIO --- */ - -#define IT83XX_GPIO_BASE 0x00F01600 -#define IT83XX_GPIO2_BASE 0x00F03E00 - -#define IT83XX_GPIO_GCR REG8(IT83XX_GPIO_BASE+0x00) -#define IT83XX_GPIO_GCR_LPC_RST_B7 0x1 -#define IT83XX_GPIO_GCR_LPC_RST_D2 0x2 -#define IT83XX_GPIO_GCR_LPC_RST_DISABLE 0x3 -#define IT83XX_GPIO_GCR_LPC_RST_POS 1 - -#define IT83XX_GPIO_GPDRA REG8(IT83XX_GPIO_BASE+0x01) -#define IT83XX_GPIO_GPDRB REG8(IT83XX_GPIO_BASE+0x02) -#define IT83XX_GPIO_GPDRC REG8(IT83XX_GPIO_BASE+0x03) -#define IT83XX_GPIO_GPDRE REG8(IT83XX_GPIO_BASE+0x05) -#define IT83XX_GPIO_GPDRF REG8(IT83XX_GPIO_BASE+0x06) -#define IT83XX_GPIO_GPDRH REG8(IT83XX_GPIO_BASE+0x08) - -#define IT83XX_GPIO_GPCRA0 REG8(IT83XX_GPIO_BASE+0x10) -#define IT83XX_GPIO_GPCRA1 REG8(IT83XX_GPIO_BASE+0x11) -#define IT83XX_GPIO_GPCRA2 REG8(IT83XX_GPIO_BASE+0x12) -#define IT83XX_GPIO_GPCRA3 REG8(IT83XX_GPIO_BASE+0x13) -#define IT83XX_GPIO_GPCRA4 REG8(IT83XX_GPIO_BASE+0x14) -#define IT83XX_GPIO_GPCRA5 REG8(IT83XX_GPIO_BASE+0x15) -#define IT83XX_GPIO_GPCRA6 REG8(IT83XX_GPIO_BASE+0x16) -#define IT83XX_GPIO_GPCRA7 REG8(IT83XX_GPIO_BASE+0x17) - -#define IT83XX_GPIO_GPCRB0 REG8(IT83XX_GPIO_BASE+0x18) -#define IT83XX_GPIO_GPCRB1 REG8(IT83XX_GPIO_BASE+0x19) -#define IT83XX_GPIO_GPCRB2 REG8(IT83XX_GPIO_BASE+0x1A) -#define IT83XX_GPIO_GPCRB3 REG8(IT83XX_GPIO_BASE+0x1B) -#define IT83XX_GPIO_GPCRB4 REG8(IT83XX_GPIO_BASE+0x1C) -#define IT83XX_GPIO_GPCRB5 REG8(IT83XX_GPIO_BASE+0x1D) -#define IT83XX_GPIO_GPCRB6 REG8(IT83XX_GPIO_BASE+0x1E) -#define IT83XX_GPIO_GPCRB7 REG8(IT83XX_GPIO_BASE+0x1F) - -#define IT83XX_GPIO_GPCRC0 REG8(IT83XX_GPIO_BASE+0x20) -#define IT83XX_GPIO_GPCRC1 REG8(IT83XX_GPIO_BASE+0x21) -#define IT83XX_GPIO_GPCRC2 REG8(IT83XX_GPIO_BASE+0x22) -#define IT83XX_GPIO_GPCRC3 REG8(IT83XX_GPIO_BASE+0x23) -#define IT83XX_GPIO_GPCRC4 REG8(IT83XX_GPIO_BASE+0x24) -#define IT83XX_GPIO_GPCRC5 REG8(IT83XX_GPIO_BASE+0x25) -#define IT83XX_GPIO_GPCRC6 REG8(IT83XX_GPIO_BASE+0x26) -#define IT83XX_GPIO_GPCRC7 REG8(IT83XX_GPIO_BASE+0x27) - -#define IT83XX_GPIO_GPCRE0 REG8(IT83XX_GPIO_BASE+0x30) -#define IT83XX_GPIO_GPCRE1 REG8(IT83XX_GPIO_BASE+0x31) -#define IT83XX_GPIO_GPCRE2 REG8(IT83XX_GPIO_BASE+0x32) -#define IT83XX_GPIO_GPCRE3 REG8(IT83XX_GPIO_BASE+0x33) -#define IT83XX_GPIO_GPCRE4 REG8(IT83XX_GPIO_BASE+0x34) -#define IT83XX_GPIO_GPCRE5 REG8(IT83XX_GPIO_BASE+0x35) -#define IT83XX_GPIO_GPCRE6 REG8(IT83XX_GPIO_BASE+0x36) -#define IT83XX_GPIO_GPCRE7 REG8(IT83XX_GPIO_BASE+0x37) - -#define IT83XX_GPIO_GPCRF0 REG8(IT83XX_GPIO_BASE+0x38) -#define IT83XX_GPIO_GPCRF1 REG8(IT83XX_GPIO_BASE+0x39) -#define IT83XX_GPIO_GPCRF2 REG8(IT83XX_GPIO_BASE+0x3A) -#define IT83XX_GPIO_GPCRF3 REG8(IT83XX_GPIO_BASE+0x3B) -#define IT83XX_GPIO_GPCRF4 REG8(IT83XX_GPIO_BASE+0x3C) -#define IT83XX_GPIO_GPCRF5 REG8(IT83XX_GPIO_BASE+0x3D) -#define IT83XX_GPIO_GPCRF6 REG8(IT83XX_GPIO_BASE+0x3E) -#define IT83XX_GPIO_GPCRF7 REG8(IT83XX_GPIO_BASE+0x3F) - -#define IT83XX_GPIO_GPCRH0 REG8(IT83XX_GPIO_BASE+0x48) -#define IT83XX_GPIO_GPCRH1 REG8(IT83XX_GPIO_BASE+0x49) -#define IT83XX_GPIO_GPCRH2 REG8(IT83XX_GPIO_BASE+0x4A) -#define IT83XX_GPIO_GPCRH3 REG8(IT83XX_GPIO_BASE+0x4B) -#define IT83XX_GPIO_GPCRH4 REG8(IT83XX_GPIO_BASE+0x4C) -#define IT83XX_GPIO_GPCRH5 REG8(IT83XX_GPIO_BASE+0x4D) -#define IT83XX_GPIO_GPCRH6 REG8(IT83XX_GPIO_BASE+0x4E) -#define IT83XX_GPIO_GPCRH7 REG8(IT83XX_GPIO_BASE+0x4F) - -#define IT83XX_GPIO_GPCRI0 REG8(IT83XX_GPIO_BASE+0x50) -#define IT83XX_GPIO_GPCRI1 REG8(IT83XX_GPIO_BASE+0x51) -#define IT83XX_GPIO_GPCRI2 REG8(IT83XX_GPIO_BASE+0x52) -#define IT83XX_GPIO_GPCRI3 REG8(IT83XX_GPIO_BASE+0x53) -#define IT83XX_GPIO_GPCRI4 REG8(IT83XX_GPIO_BASE+0x54) -#define IT83XX_GPIO_GPCRI5 REG8(IT83XX_GPIO_BASE+0x55) -#define IT83XX_GPIO_GPCRI6 REG8(IT83XX_GPIO_BASE+0x56) -#define IT83XX_GPIO_GPCRI7 REG8(IT83XX_GPIO_BASE+0x57) - -#define IT83XX_GPIO_GPCRM5 REG8(IT83XX_GPIO_BASE+0xA5) - -#define IT83XX_GPIO_GPDMRA REG8(IT83XX_GPIO_BASE+0x61) -#define IT83XX_GPIO_GPDMRB REG8(IT83XX_GPIO_BASE+0x62) -#define IT83XX_GPIO_GPDMRC REG8(IT83XX_GPIO_BASE+0x63) -#define IT83XX_GPIO_GPDMRE REG8(IT83XX_GPIO_BASE+0x65) -#define IT83XX_GPIO_GPDMRF REG8(IT83XX_GPIO_BASE+0x66) -#define IT83XX_GPIO_GPDMRH REG8(IT83XX_GPIO_BASE+0x68) - -#define IT83XX_GPIO_GPCRL0 REG8(IT83XX_GPIO_BASE+0x98) -#define IT83XX_GPIO_GPCRL1 REG8(IT83XX_GPIO_BASE+0x99) -#define IT83XX_GPIO_GPCRL2 REG8(IT83XX_GPIO_BASE+0x9A) -#define IT83XX_GPIO_GPCRL3 REG8(IT83XX_GPIO_BASE+0x9B) -#define IT83XX_GPIO_GPCRP0 REG8(IT83XX_GPIO2_BASE+0x18) -#define IT83XX_GPIO_GPCRP1 REG8(IT83XX_GPIO2_BASE+0x19) - -#define IT83XX_GPIO_GRC1 REG8(IT83XX_GPIO_BASE+0xF0) -#define IT83XX_GPIO_GRC2 REG8(IT83XX_GPIO_BASE+0xF1) -#define IT83XX_GPIO_GRC3 REG8(IT83XX_GPIO_BASE+0xF2) -#define IT83XX_GPIO_GRC4 REG8(IT83XX_GPIO_BASE+0xF3) -#define IT83XX_GPIO_GRC5 REG8(IT83XX_GPIO_BASE+0xF4) -#define IT83XX_GPIO_GRC6 REG8(IT83XX_GPIO_BASE+0xF5) -#define IT83XX_GPIO_GRC7 REG8(IT83XX_GPIO_BASE+0xF6) -#define IT83XX_GPIO_GRC8 REG8(IT83XX_GPIO_BASE+0xF7) -#define IT83XX_GPIO_GRC19 REG8(IT83XX_GPIO_BASE+0xE4) -#define IT83XX_GPIO_GRC20 REG8(IT83XX_GPIO_BASE+0xE5) -#define IT83XX_GPIO_GRC21 REG8(IT83XX_GPIO_BASE+0xE6) -#define IT83XX_GPIO_GRC22 REG8(IT83XX_GPIO_BASE+0xE7) -#define IT83XX_GPIO_GRC23 REG8(IT83XX_GPIO_BASE+0xE8) -#define IT83XX_GPIO_GRC24 REG8(IT83XX_GPIO_BASE+0xE9) -#define IT83XX_GPIO_GCR25 REG8(IT83XX_GPIO_BASE+0xD1) -#define IT83XX_GPIO_GCR26 REG8(IT83XX_GPIO_BASE+0xD2) -#define IT83XX_GPIO_GCR27 REG8(IT83XX_GPIO_BASE+0xD3) -#define IT83XX_GPIO_GCR28 REG8(IT83XX_GPIO_BASE+0xD4) -#define IT83XX_GPIO_GCR29 REG8(IT83XX_GPIO_BASE+0xEE) -#define IT83XX_GPIO_GCR30 REG8(IT83XX_GPIO_BASE+0xED) -#define IT83XX_GPIO_GCR31 REG8(IT83XX_GPIO_BASE+0xD5) -#define IT83XX_GPIO_GCR32 REG8(IT83XX_GPIO_BASE+0xD6) -#define IT83XX_GPIO_GCR33 REG8(IT83XX_GPIO_BASE+0xD7) - -#define IT83XX_VBATPC_BGPOPSCR REG8(IT83XX_GPIO2_BASE+0xF0) -#define IT83XX_VBATPC_XLPIER REG8(IT83XX_GPIO2_BASE+0xF5) - -enum { - /* GPIO group index */ - GPIO_A = 0x1, - GPIO_B = 0x2, - GPIO_C = 0x3, - GPIO_D = 0x4, - GPIO_E = 0x5, - GPIO_F = 0x6, - GPIO_G = 0x7, - GPIO_H = 0x8, - GPIO_I = 0x9, - GPIO_J = 0xa, - GPIO_K = 0xb, - GPIO_L = 0xc, - GPIO_M = 0xd, -#if defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) - GPIO_O = 0xe, - GPIO_P = 0xf, - GPIO_Q = 0x10, - GPIO_R = 0x11, -#endif - GPIO_PORT_COUNT, - - /* - * NOTE: support flags when KSI/KSO are configured as GPIO - * 1) it8320bx: - * output: GPIO_OUTPUT, GPIO_OPEN_DRAIN, GPIO_HIGH, GPIO_LOW - * input: GPIO_INPUT - * 2) it8320dx, it8xxx1, and it8xxx2: - * output: GPIO_OUTPUT, GPIO_OPEN_DRAIN(always internal pullup), - * GPIO_HIGH, GPIO_LOW - * input: GPIO_INPUT, GPIO_PULL_UP - */ - /* KSI[7-0] GPIO data mirror register. */ - GPIO_KSI, - /* KSO[15-8] GPIO data mirror register. */ - GPIO_KSO_H, - /* KSO[7-0] GPIO data mirror register. */ - GPIO_KSO_L, - /* Compiler check COUNT and gpio_group_to_reg member cnt match or not */ - COUNT, -}; - -struct gpio_reg_t { - /* GPIO and KSI/KSO port data register (bit mapping to pin) */ - uint32_t reg_gpdr; - /* GPIO and KSI/KSO port data mirror register (bit mapping to pin) */ - uint32_t reg_gpdmr; - /* GPIO and KSI/KSO port output type register (bit mapping to pin) */ - uint32_t reg_gpotr; - /* GPIO port control register (byte mapping to pin) */ - uint32_t reg_gpcr; -}; - -/* GPIO group index convert to GPIO data/output type/ctrl group address */ -static const struct gpio_reg_t gpio_group_to_reg[] = { - /* GPDR(set), GPDMR(get), GPOTR, GPCR */ - [GPIO_A] = { 0x00F01601, 0x00F01661, 0x00F01671, 0x00F01610 }, - [GPIO_B] = { 0x00F01602, 0x00F01662, 0x00F01672, 0x00F01618 }, - [GPIO_C] = { 0x00F01603, 0x00F01663, 0x00F01673, 0x00F01620 }, - [GPIO_D] = { 0x00F01604, 0x00F01664, 0x00F01674, 0x00F01628 }, - [GPIO_E] = { 0x00F01605, 0x00F01665, 0x00F01675, 0x00F01630 }, - [GPIO_F] = { 0x00F01606, 0x00F01666, 0x00F01676, 0x00F01638 }, - [GPIO_G] = { 0x00F01607, 0x00F01667, 0x00F01677, 0x00F01640 }, - [GPIO_H] = { 0x00F01608, 0x00F01668, 0x00F01678, 0x00F01648 }, - [GPIO_I] = { 0x00F01609, 0x00F01669, 0x00F01679, 0x00F01650 }, - [GPIO_J] = { 0x00F0160A, 0x00F0166A, 0x00F0167A, 0x00F01658 }, - [GPIO_K] = { 0x00F0160B, 0x00F0166B, 0x00F0167B, 0x00F01690 }, - [GPIO_L] = { 0x00F0160C, 0x00F0166C, 0x00F0167C, 0x00F01698 }, - [GPIO_M] = { 0x00F0160D, 0x00F0166D, 0x00F0167D, 0x00F016a0 }, -#if defined(CHIP_FAMILY_IT8XXX1) || defined(CHIP_FAMILY_IT8XXX2) - [GPIO_O] = { 0x00F03E01, 0x00F03E61, 0x00F03E71, 0x00F03E10 }, - [GPIO_P] = { 0x00F03E02, 0x00F03E62, 0x00F03E72, 0x00F03E18 }, - [GPIO_Q] = { 0x00F03E03, 0x00F03E63, 0x00F03E73, 0x00F03E20 }, - [GPIO_R] = { 0x00F03E04, 0x00F03E64, 0x00F03E74, 0x00F03E28 }, -#endif - [GPIO_KSI] = { 0x00F01D08, 0x00F01D09, 0x00F01D26, 0xFFFFFFFF }, - [GPIO_KSO_H] = { 0x00F01D01, 0x00F01D0C, 0x00F01D27, 0xFFFFFFFF }, - [GPIO_KSO_L] = { 0x00F01D00, 0x00F01D0F, 0x00F01D28, 0xFFFFFFFF }, -}; -BUILD_ASSERT(ARRAY_SIZE(gpio_group_to_reg) == (COUNT)); - -#define UNIMPLEMENTED_GPIO_BANK GPIO_A - -#define IT83XX_GPIO_DATA(port) \ - REG8(gpio_group_to_reg[port].reg_gpdr) -#define IT83XX_GPIO_DATA_MIRROR(port) \ - REG8(gpio_group_to_reg[port].reg_gpdmr) -#define IT83XX_GPIO_GPOT(port) \ - REG8(gpio_group_to_reg[port].reg_gpotr) -#define IT83XX_GPIO_CTRL(port, pin_offset) \ - REG8(gpio_group_to_reg[port].reg_gpcr + pin_offset) -#define GPCR_PORT_PIN_MODE_INPUT BIT(7) -#define GPCR_PORT_PIN_MODE_OUTPUT BIT(6) -#define GPCR_PORT_PIN_MODE_PULLUP BIT(2) -#define GPCR_PORT_PIN_MODE_PULLDOWN BIT(1) - -/* --- Clock and Power Management (ECPM) --- */ - -#define IT83XX_ECPM_BASE 0x00F01E00 - -#define IT83XX_ECPM_CGCTRL1R_OFF 0x01 -#define IT83XX_ECPM_CGCTRL2R_OFF 0x02 -#define IT83XX_ECPM_CGCTRL3R_OFF 0x05 -#define IT83XX_ECPM_CGCTRL4R_OFF 0x09 - -#define IT83XX_ECPM_PLLCTRL REG8(IT83XX_ECPM_BASE+0x03) -enum ec_pll_ctrl { - EC_PLL_DOZE = 0, - EC_PLL_SLEEP = 1, - EC_PLL_DEEP_DOZE = 3, -}; - -#define IT83XX_ECPM_AUTOCG REG8(IT83XX_ECPM_BASE+0x04) -#define IT83XX_ECPM_PLLFREQR REG8(IT83XX_ECPM_BASE+0x06) -#define IT83XX_ECPM_PLLCSS REG8(IT83XX_ECPM_BASE+0x08) -#define IT83XX_ECPM_SCDCR0 REG8(IT83XX_ECPM_BASE+0x0c) -#define IT83XX_ECPM_SCDCR1 REG8(IT83XX_ECPM_BASE+0x0d) -#define IT83XX_ECPM_SCDCR2 REG8(IT83XX_ECPM_BASE+0x0e) -#define IT83XX_ECPM_SCDCR3 REG8(IT83XX_ECPM_BASE+0x0f) -#define IT83XX_ECPM_SCDCR4 REG8(IT83XX_ECPM_BASE+0x10) - -/* - * The clock gate offsets combine the register offset from ECPM_BASE and the - * mask within that register into one value. These are used for - * clock_enable_peripheral() and clock_disable_peripheral() - */ -enum clock_gate_offsets { - CGC_OFFSET_EGPC = ((IT83XX_ECPM_CGCTRL2R_OFF << 8) | 0x40), - CGC_OFFSET_CIR = ((IT83XX_ECPM_CGCTRL2R_OFF << 8) | 0x20), - CGC_OFFSET_SWUC = ((IT83XX_ECPM_CGCTRL2R_OFF << 8) | 0x10), - CGC_OFFSET_USB = ((IT83XX_ECPM_CGCTRL3R_OFF << 8) | 0x20), - CGC_OFFSET_PECI = ((IT83XX_ECPM_CGCTRL3R_OFF << 8) | 0x08), - CGC_OFFSET_UART = ((IT83XX_ECPM_CGCTRL3R_OFF << 8) | 0x04), - CGC_OFFSET_SSPI = ((IT83XX_ECPM_CGCTRL3R_OFF << 8) | 0x02), - CGC_OFFSET_DBGR = ((IT83XX_ECPM_CGCTRL3R_OFF << 8) | 0x01), - CGC_OFFSET_SMBF = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x80), - CGC_OFFSET_SMBE = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x40), - CGC_OFFSET_SMBD = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x20), - CGC_OFFSET_SMBC = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x10), - CGC_OFFSET_SMBB = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x08), - CGC_OFFSET_SMBA = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x04), - CGC_OFFSET_SMB = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x02), - CGC_OFFSET_CEC = ((IT83XX_ECPM_CGCTRL4R_OFF << 8) | 0x01) -}; - -/* --- Timer (TMR) --- */ -#define IT83XX_TMR_BASE 0x00F02900 - -#define IT83XX_TMR_PRSC REG8(IT83XX_TMR_BASE+0x00) -#define IT83XX_TMR_GCSMS REG8(IT83XX_TMR_BASE+0x01) -#define IT83XX_TMR_CTR_A0 REG8(IT83XX_TMR_BASE+0x02) -#define IT83XX_TMR_CTR_A1 REG8(IT83XX_TMR_BASE+0x03) -#define IT83XX_TMR_CTR_B0 REG8(IT83XX_TMR_BASE+0x04) -#define IT83XX_TMR_CTR_B1 REG8(IT83XX_TMR_BASE+0x05) -#define IT83XX_TMR_DCR_A0 REG8(IT83XX_TMR_BASE+0x06) -#define IT83XX_TMR_DCR_A1 REG8(IT83XX_TMR_BASE+0x07) -#define IT83XX_TMR_DCR_B0 REG8(IT83XX_TMR_BASE+0x08) -#define IT83XX_TMR_DCR_B1 REG8(IT83XX_TMR_BASE+0x09) -#define IT83XX_TMR_CCGSR REG8(IT83XX_TMR_BASE+0x0A) -#define IT83XX_TMR_TMRCE REG8(IT83XX_TMR_BASE+0x0B) -#define IT83XX_TMR_TMRIE REG8(IT83XX_TMR_BASE+0x0C) - -/* --- External Timer and Watchdog (ETWD) --- */ -#define IT83XX_ETWD_BASE 0x00F01F00 - -#define IT83XX_ETWD_ETWCFG REG8(IT83XX_ETWD_BASE+0x01) -#define IT83XX_ETWD_ET1PSR REG8(IT83XX_ETWD_BASE+0x02) -#define IT83XX_ETWD_ET1CNTLHR REG8(IT83XX_ETWD_BASE+0x03) -#define IT83XX_ETWD_ET1CNTLLR REG8(IT83XX_ETWD_BASE+0x04) -#define IT83XX_ETWD_ETWCTRL REG8(IT83XX_ETWD_BASE+0x05) -#define IT83XX_ETWD_EWDCNTLLR REG8(IT83XX_ETWD_BASE+0x06) -#define IT83XX_ETWD_EWDKEYR REG8(IT83XX_ETWD_BASE+0x07) -#define IT83XX_ETWD_EWDCNTLHR REG8(IT83XX_ETWD_BASE+0x09) -#define IT83XX_ETWD_ETXCTRL(n) REG8(IT83XX_ETWD_BASE + 0x10 + (n << 3)) -#define IT83XX_ETWD_ETXPSR(n) REG8(IT83XX_ETWD_BASE + 0x11 + (n << 3)) -#define IT83XX_ETWD_ETXCNTLR(n) REG32(IT83XX_ETWD_BASE + 0x14 + (n << 3)) -#define IT83XX_ETWD_ETXCNTOR(n) REG32(IT83XX_ETWD_BASE + 0x48 + (n << 2)) - -/* --- General Control (GCTRL) --- */ -#define IT83XX_GCTRL_BASE 0x00F02000 - -#ifdef IT83XX_CHIP_ID_3BYTES -#define IT83XX_GCTRL_CHIPID1 REG8(IT83XX_GCTRL_BASE+0x85) -#define IT83XX_GCTRL_CHIPID2 REG8(IT83XX_GCTRL_BASE+0x86) -#define IT83XX_GCTRL_CHIPID3 REG8(IT83XX_GCTRL_BASE+0x87) -#else -#define IT83XX_GCTRL_CHIPID1 REG8(IT83XX_GCTRL_BASE+0x00) -#define IT83XX_GCTRL_CHIPID2 REG8(IT83XX_GCTRL_BASE+0x01) -#endif -#define IT83XX_GCTRL_CHIPVER REG8(IT83XX_GCTRL_BASE+0x02) -#define IT83XX_GCTRL_DBGROS REG8(IT83XX_GCTRL_BASE+0x03) -#define IT83XX_SMB_DBGR BIT(0) -#define IT83XX_GCTRL_WNCKR REG8(IT83XX_GCTRL_BASE+0x0B) -#define IT83XX_GCTRL_RSTS REG8(IT83XX_GCTRL_BASE+0x06) -#define IT83XX_GCTRL_BADRSEL REG8(IT83XX_GCTRL_BASE+0x0A) -#define IT83XX_GCTRL_SPCTRL1 REG8(IT83XX_GCTRL_BASE+0x0D) -#define IT83XX_GCTRL_RSTDMMC REG8(IT83XX_GCTRL_BASE+0x10) -#define IT83XX_GCTRL_RSTC4 REG8(IT83XX_GCTRL_BASE+0x11) -#define IT83XX_GCTRL_SPCTRL4 REG8(IT83XX_GCTRL_BASE+0x1C) -#define IT83XX_GCTRL_MCCR3 REG8(IT83XX_GCTRL_BASE+0x20) -#define IT83XX_GCTRL_SPISLVPFE BIT(6) -#define IT83XX_GCTRL_RSTC5 REG8(IT83XX_GCTRL_BASE+0x21) -#define IT83XX_GCTRL_MCCR REG8(IT83XX_GCTRL_BASE+0x30) -#define IT83XX_GCTRL_PMER1 REG8(IT83XX_GCTRL_BASE+0x32) -#define IT83XX_GCTRL_PMER2 REG8(IT83XX_GCTRL_BASE+0x33) -#define IT83XX_GCTRL_EPLR REG8(IT83XX_GCTRL_BASE+0x37) -#define IT83XX_GCTRL_IVTBAR REG8(IT83XX_GCTRL_BASE+0x41) -#define IT83XX_GCTRL_MCCR2 REG8(IT83XX_GCTRL_BASE+0x44) -#define IT83XX_GCTRL_PIN_MUX0 REG8(IT83XX_GCTRL_BASE+0x46) -#define IT83XX_DLM14_ENABLE BIT(5) -#define IT83XX_GCTRL_SSCR REG8(IT83XX_GCTRL_BASE+0x4A) -#define IT83XX_GCTRL_ETWDUARTCR REG8(IT83XX_GCTRL_BASE+0x4B) -#define IT83XX_GCTRL_WMCR REG8(IT83XX_GCTRL_BASE+0x4C) -#define IT83XX_GCTRL_H2ROFSR REG8(IT83XX_GCTRL_BASE+0x53) -/* bit[0] = 0 or 1 : disable or enable ETWD hardware reset */ -#define ETWD_HW_RST_EN BIT(0) -#define IT83XX_GCTRL_RVILMCR0 REG8(IT83XX_GCTRL_BASE+0x5D) -#define ILMCR_ILM0_ENABLE BIT(0) -#define ILMCR_ILM2_ENABLE BIT(2) -#define IT83XX_GCTRL_EWPR0PFH(i) REG8(IT83XX_GCTRL_BASE+0x60+i) -#define IT83XX_GCTRL_EWPR0PFD(i) REG8(IT83XX_GCTRL_BASE+0xA0+i) -#define IT83XX_GCTRL_EWPR0PFEC(i) REG8(IT83XX_GCTRL_BASE+0xC0+i) - -/* --- Pulse Width Modulation (PWM) --- */ -#define IT83XX_PWM_BASE 0x00F01800 - -#define IT83XX_PWM_C0CPRS REG8(IT83XX_PWM_BASE+0x00) -#define IT83XX_PWM_CTR REG8(IT83XX_PWM_BASE+0x01) -#define IT83XX_PWM_DCR0 REG8(IT83XX_PWM_BASE+0x02) -#define IT83XX_PWM_DCR1 REG8(IT83XX_PWM_BASE+0x03) -#define IT83XX_PWM_DCR2 REG8(IT83XX_PWM_BASE+0x04) -#define IT83XX_PWM_DCR3 REG8(IT83XX_PWM_BASE+0x05) -#define IT83XX_PWM_DCR4 REG8(IT83XX_PWM_BASE+0x06) -#define IT83XX_PWM_DCR5 REG8(IT83XX_PWM_BASE+0x07) -#define IT83XX_PWM_DCR6 REG8(IT83XX_PWM_BASE+0x08) -#define IT83XX_PWM_DCR7 REG8(IT83XX_PWM_BASE+0x09) -#define IT83XX_PWM_PWMPOL REG8(IT83XX_PWM_BASE+0x0A) -#define IT83XX_PWM_PCFSR REG8(IT83XX_PWM_BASE+0x0B) -#define IT83XX_PWM_PCSSGL REG8(IT83XX_PWM_BASE+0x0C) -#define IT83XX_PWM_PCSSGH REG8(IT83XX_PWM_BASE+0x0D) -#define IT83XX_PWM_CR256PCSSG REG8(IT83XX_PWM_BASE+0x0E) -#define IT83XX_PWM_PCSGR REG8(IT83XX_PWM_BASE+0x0F) -#define IT83XX_PWM_CTR1M REG8(IT83XX_PWM_BASE+0x10) -#define IT83XX_PWM_F1TLRR REG8(IT83XX_PWM_BASE+0x1E) -#define IT83XX_PWM_F1TMRR REG8(IT83XX_PWM_BASE+0x1F) -#define IT83XX_PWM_F2TLRR REG8(IT83XX_PWM_BASE+0x20) -#define IT83XX_PWM_F2TMRR REG8(IT83XX_PWM_BASE+0x21) -#define IT83XX_PWM_ZINTSCR REG8(IT83XX_PWM_BASE+0x22) -#define IT83XX_PWM_ZTIER REG8(IT83XX_PWM_BASE+0x23) -#define IT83XX_PWM_TSWCTLR REG8(IT83XX_PWM_BASE+0x24) -#define IT83XX_PWM_C4CPRS REG8(IT83XX_PWM_BASE+0x27) -#define IT83XX_PWM_C4MCPRS REG8(IT83XX_PWM_BASE+0x28) -#define IT83XX_PWM_C6CPRS REG8(IT83XX_PWM_BASE+0x2B) -#define IT83XX_PWM_C6MCPRS REG8(IT83XX_PWM_BASE+0x2C) -#define IT83XX_PWM_C7CPRS REG8(IT83XX_PWM_BASE+0x2D) -#define IT83XX_PWM_C7MCPRS REG8(IT83XX_PWM_BASE+0x2E) -#define IT83XX_PWM_CLK6MSEL REG8(IT83XX_PWM_BASE+0x40) -#define IT83XX_PWM_CTR1 REG8(IT83XX_PWM_BASE+0x41) -#define IT83XX_PWM_CTR2 REG8(IT83XX_PWM_BASE+0x42) -#define IT83XX_PWM_CTR3 REG8(IT83XX_PWM_BASE+0x43) -#define IT83XX_PWM_PWM5TOCTRL REG8(IT83XX_PWM_BASE+0x44) -#define IT83XX_PWM_CFLRR REG8(IT83XX_PWM_BASE+0x45) -#define IT83XX_PWM_CFMRR REG8(IT83XX_PWM_BASE+0x46) -#define IT83XX_PWM_CFINTCTRL REG8(IT83XX_PWM_BASE+0x47) -#define IT83XX_PWM_TSWCTRL REG8(IT83XX_PWM_BASE+0x48) -#define IT83XX_PWM_PWMODENR REG8(IT83XX_PWM_BASE+0x49) - -/* Analog to Digital Converter (ADC) */ -#define IT83XX_ADC_BASE 0x00F01900 - -#define IT83XX_ADC_ADCSTS REG8(IT83XX_ADC_BASE+0x00) -#define IT83XX_ADC_ADCCFG REG8(IT83XX_ADC_BASE+0x01) -#define IT83XX_ADC_ADCCTL REG8(IT83XX_ADC_BASE+0x02) -#define IT83XX_ADC_ADCGCR REG8(IT83XX_ADC_BASE+0x03) -#define IT83XX_ADC_DBKEN BIT(7) /* ADC data buffer keep enable. */ -#define IT83XX_ADC_VCH0CTL REG8(IT83XX_ADC_BASE+0x04) -#define IT83XX_ADC_KDCTL REG8(IT83XX_ADC_BASE+0x05) -#define IT83XX_ADC_AHCE BIT(7) -#define IT83XX_ADC_VCH1CTL REG8(IT83XX_ADC_BASE+0x06) -#define IT83XX_ADC_VCH1DATL REG8(IT83XX_ADC_BASE+0x07) -#define IT83XX_ADC_VCH1DATM REG8(IT83XX_ADC_BASE+0x08) -#define IT83XX_ADC_VCH2CTL REG8(IT83XX_ADC_BASE+0x09) -#define IT83XX_ADC_VCH2DATL REG8(IT83XX_ADC_BASE+0x0A) -#define IT83XX_ADC_VCH2DATM REG8(IT83XX_ADC_BASE+0x0B) -#define IT83XX_ADC_VCH3CTL REG8(IT83XX_ADC_BASE+0x0C) -#define IT83XX_ADC_VCH3DATL REG8(IT83XX_ADC_BASE+0x0D) -#define IT83XX_ADC_VCH3DATM REG8(IT83XX_ADC_BASE+0x0E) -#define IT83XX_ADC_VHSCDBL REG8(IT83XX_ADC_BASE+0x14) -#define IT83XX_ADC_VHSCDBM REG8(IT83XX_ADC_BASE+0x15) -#define IT83XX_ADC_VCH0DATL REG8(IT83XX_ADC_BASE+0x18) -#define IT83XX_ADC_VCH0DATM REG8(IT83XX_ADC_BASE+0x19) -#define IT83XX_ADC_VHSGCDBL REG8(IT83XX_ADC_BASE+0x1C) -#define IT83XX_ADC_VHSGCDBM REG8(IT83XX_ADC_BASE+0x1D) -#define IT83XX_ADC_ADCSAR REG8(IT83XX_ADC_BASE+0x32) -#define IT83XX_ADC_VCMPSCP REG8(IT83XX_ADC_BASE+0x37) -#define IT83XX_ADC_VCH4CTL REG8(IT83XX_ADC_BASE+0x38) -#define IT83XX_ADC_VCH4DATM REG8(IT83XX_ADC_BASE+0x39) -#define IT83XX_ADC_VCH4DATL REG8(IT83XX_ADC_BASE+0x3A) -#define IT83XX_ADC_VCH5CTL REG8(IT83XX_ADC_BASE+0x3B) -#define IT83XX_ADC_VCH5DATM REG8(IT83XX_ADC_BASE+0x3C) -#define IT83XX_ADC_VCH5DATL REG8(IT83XX_ADC_BASE+0x3D) -#define IT83XX_ADC_VCH6CTL REG8(IT83XX_ADC_BASE+0x3E) -#define IT83XX_ADC_VCH6DATM REG8(IT83XX_ADC_BASE+0x3F) -#define IT83XX_ADC_VCH6DATL REG8(IT83XX_ADC_BASE+0x40) -#define IT83XX_ADC_VCH7CTL REG8(IT83XX_ADC_BASE+0x41) -#define IT83XX_ADC_VCH7DATM REG8(IT83XX_ADC_BASE+0x42) -#define IT83XX_ADC_VCH7DATL REG8(IT83XX_ADC_BASE+0x43) -#define IT83XX_ADC_ADCDVSTS REG8(IT83XX_ADC_BASE+0x44) -#define IT83XX_ADC_VCMPSTS REG8(IT83XX_ADC_BASE+0x45) -#define IT83XX_ADC_VCMP0CTL REG8(IT83XX_ADC_BASE+0x46) -#define ADC_VCMP_CMPEN BIT(7) -#define ADC_VCMP_CMPINTEN BIT(6) -#define ADC_VCMP_GREATER_THRESHOLD BIT(5) -#define ADC_VCMP_EDGE_TRIGGER BIT(4) -#define ADC_VCMP_GPIO_ACTIVE_LOW BIT(3) -#define IT83XX_ADC_CMP0THRDATM REG8(IT83XX_ADC_BASE+0x47) -#define IT83XX_ADC_CMP0THRDATL REG8(IT83XX_ADC_BASE+0x48) -#define IT83XX_ADC_VCMP1CTL REG8(IT83XX_ADC_BASE+0x49) -#define IT83XX_ADC_CMP1THRDATM REG8(IT83XX_ADC_BASE+0x4A) -#define IT83XX_ADC_CMP1THRDATL REG8(IT83XX_ADC_BASE+0x4B) -#define IT83XX_ADC_VCMP2CTL REG8(IT83XX_ADC_BASE+0x4C) -#define IT83XX_ADC_CMP2THRDATM REG8(IT83XX_ADC_BASE+0x4D) -#define IT83XX_ADC_CMP2THRDATL REG8(IT83XX_ADC_BASE+0x4E) -#define IT83XX_ADC_VCH13CTL REG8(IT83XX_ADC_BASE+0x60) -#define IT83XX_ADC_VCH13DATM REG8(IT83XX_ADC_BASE+0x61) -#define IT83XX_ADC_VCH13DATL REG8(IT83XX_ADC_BASE+0x62) -#define IT83XX_ADC_VCH14CTL REG8(IT83XX_ADC_BASE+0x63) -#define IT83XX_ADC_VCH14DATM REG8(IT83XX_ADC_BASE+0x64) -#define IT83XX_ADC_VCH14DATL REG8(IT83XX_ADC_BASE+0x65) -#define IT83XX_ADC_VCH15CTL REG8(IT83XX_ADC_BASE+0x66) -#define IT83XX_ADC_VCH15DATM REG8(IT83XX_ADC_BASE+0x67) -#define IT83XX_ADC_VCH15DATL REG8(IT83XX_ADC_BASE+0x68) -#define IT83XX_ADC_VCH16CTL REG8(IT83XX_ADC_BASE+0x69) -#define IT83XX_ADC_VCH16DATM REG8(IT83XX_ADC_BASE+0x6A) -#define IT83XX_ADC_VCH16DATL REG8(IT83XX_ADC_BASE+0x6B) -#define IT83XX_ADC_ADCDVSTS2 REG8(IT83XX_ADC_BASE+0x6C) -#define IT83XX_ADC_VCMPSTS2 REG8(IT83XX_ADC_BASE+0x6D) -#define IT83XX_ADC_VCMP3CTL REG8(IT83XX_ADC_BASE+0x6E) -#define IT83XX_ADC_CMP3THRDATM REG8(IT83XX_ADC_BASE+0x6F) -#define IT83XX_ADC_CMP3THRDATL REG8(IT83XX_ADC_BASE+0x70) -#define IT83XX_ADC_VCMP4CTL REG8(IT83XX_ADC_BASE+0x71) -#define IT83XX_ADC_CMP4THRDATM REG8(IT83XX_ADC_BASE+0x72) -#define IT83XX_ADC_CMP4THRDATL REG8(IT83XX_ADC_BASE+0x73) -#define IT83XX_ADC_VCMP5CTL REG8(IT83XX_ADC_BASE+0x74) -#define IT83XX_ADC_CMP5THRDATM REG8(IT83XX_ADC_BASE+0x75) -#define IT83XX_ADC_CMP5THRDATL REG8(IT83XX_ADC_BASE+0x76) -#define IT83XX_ADC_VCMP0CSELM REG8(IT83XX_ADC_BASE+0x77) -#define ADC_VCMP_VCMPCSELM BIT(0) -#define IT83XX_ADC_VCMP1CSELM REG8(IT83XX_ADC_BASE+0x78) -#define IT83XX_ADC_VCMP2CSELM REG8(IT83XX_ADC_BASE+0x79) -#define IT83XX_ADC_VCMP3CSELM REG8(IT83XX_ADC_BASE+0x7A) -#define IT83XX_ADC_VCMP4CSELM REG8(IT83XX_ADC_BASE+0x7B) -#define IT83XX_ADC_VCMP5CSELM REG8(IT83XX_ADC_BASE+0x7C) - -/* Digital to Analog Converter (DAC) */ -#define IT83XX_DAC_BASE 0x00F01A00 - -#define IT83XX_DAC_DACPDREG REG8(IT83XX_DAC_BASE+0x01) -#define IT83XX_DAC_POWDN(ch) BIT(ch) -#define IT83XX_DAC_DACDAT(ch) REG8(IT83XX_DAC_BASE+0x02+ch) - -/* Keyboard Controller (KBC) */ -#define IT83XX_KBC_BASE 0x00F01300 - -#define IT83XX_KBC_KBHICR REG8(IT83XX_KBC_BASE+0x00) -#define IT83XX_KBC_KBIRQR REG8(IT83XX_KBC_BASE+0x02) -#define IT83XX_KBC_KBHISR REG8(IT83XX_KBC_BASE+0x04) -#define IT83XX_KBC_KBHIKDOR REG8(IT83XX_KBC_BASE+0x06) -#define IT83XX_KBC_KBHIMDOR REG8(IT83XX_KBC_BASE+0x08) -#define IT83XX_KBC_KBHIDIR REG8(IT83XX_KBC_BASE+0x0A) - -/* Power Management Channel (PMC) */ -#define IT83XX_PMC_BASE 0x00F01500 - -#define IT83XX_PMC_PM1STS REG8(IT83XX_PMC_BASE+0x00) -#define IT83XX_PMC_PM1DO REG8(IT83XX_PMC_BASE+0x01) -#define IT83XX_PMC_PM1DOSCI REG8(IT83XX_PMC_BASE+0x02) -#define IT83XX_PMC_PM1DOSMI REG8(IT83XX_PMC_BASE+0x03) -#define IT83XX_PMC_PM1DI REG8(IT83XX_PMC_BASE+0x04) -#define IT83XX_PMC_PM1DISCI REG8(IT83XX_PMC_BASE+0x05) -#define IT83XX_PMC_PM1CTL REG8(IT83XX_PMC_BASE+0x06) -#define IT83XX_PMC_PM1IC REG8(IT83XX_PMC_BASE+0x07) -#define IT83XX_PMC_PM1IE REG8(IT83XX_PMC_BASE+0x08) -#define IT83XX_PMC_PM2STS REG8(IT83XX_PMC_BASE+0x10) -#define IT83XX_PMC_PM2DO REG8(IT83XX_PMC_BASE+0x11) -#define IT83XX_PMC_PM2DOSCI REG8(IT83XX_PMC_BASE+0x12) -#define IT83XX_PMC_PM2DOSMI REG8(IT83XX_PMC_BASE+0x13) -#define IT83XX_PMC_PM2DI REG8(IT83XX_PMC_BASE+0x14) -#define IT83XX_PMC_PM2DISCI REG8(IT83XX_PMC_BASE+0x15) -#define IT83XX_PMC_PM2CTL REG8(IT83XX_PMC_BASE+0x16) -#define IT83XX_PMC_PM2IC REG8(IT83XX_PMC_BASE+0x17) -#define IT83XX_PMC_PM2IE REG8(IT83XX_PMC_BASE+0x18) -#define IT83XX_PMC_PM3STS REG8(IT83XX_PMC_BASE+0x20) -#define IT83XX_PMC_PM3DO REG8(IT83XX_PMC_BASE+0x21) -#define IT83XX_PMC_PM3DI REG8(IT83XX_PMC_BASE+0x22) -#define IT83XX_PMC_PM3CTL REG8(IT83XX_PMC_BASE+0x23) -#define IT83XX_PMC_PM3IC REG8(IT83XX_PMC_BASE+0x24) -#define IT83XX_PMC_PM3IE REG8(IT83XX_PMC_BASE+0x25) -#define IT83XX_PMC_PM4STS REG8(IT83XX_PMC_BASE+0x30) -#define IT83XX_PMC_PM4DO REG8(IT83XX_PMC_BASE+0x31) -#define IT83XX_PMC_PM4DI REG8(IT83XX_PMC_BASE+0x32) -#define IT83XX_PMC_PM4CTL REG8(IT83XX_PMC_BASE+0x33) -#define IT83XX_PMC_PM4IC REG8(IT83XX_PMC_BASE+0x34) -#define IT83XX_PMC_PM4IE REG8(IT83XX_PMC_BASE+0x35) -#define IT83XX_PMC_PM5STS REG8(IT83XX_PMC_BASE+0x40) -#define IT83XX_PMC_PM5DO REG8(IT83XX_PMC_BASE+0x41) -#define IT83XX_PMC_PM5DI REG8(IT83XX_PMC_BASE+0x42) -#define IT83XX_PMC_PM5CTL REG8(IT83XX_PMC_BASE+0x43) -#define IT83XX_PMC_PM5IC REG8(IT83XX_PMC_BASE+0x44) -#define IT83XX_PMC_PM5IE REG8(IT83XX_PMC_BASE+0x45) -#define IT83XX_PMC_MBXCTRL REG8(IT83XX_PMC_BASE+0x19) -#define IT83XX_PMC_MBXEC_00 REG8(IT83XX_PMC_BASE+0xF0) -#define IT83XX_PMC_MBXEC_01 REG8(IT83XX_PMC_BASE+0xF1) -#define IT83XX_PMC_MBXEC_02 REG8(IT83XX_PMC_BASE+0xF2) -#define IT83XX_PMC_MBXEC_03 REG8(IT83XX_PMC_BASE+0xF3) -#define IT83XX_PMC_MBXEC_04 REG8(IT83XX_PMC_BASE+0xF4) -#define IT83XX_PMC_MBXEC_05 REG8(IT83XX_PMC_BASE+0xF5) -#define IT83XX_PMC_MBXEC_06 REG8(IT83XX_PMC_BASE+0xF6) -#define IT83XX_PMC_MBXEC_07 REG8(IT83XX_PMC_BASE+0xF7) -#define IT83XX_PMC_MBXEC_08 REG8(IT83XX_PMC_BASE+0xF8) -#define IT83XX_PMC_MBXEC_09 REG8(IT83XX_PMC_BASE+0xF9) -#define IT83XX_PMC_MBXEC_10 REG8(IT83XX_PMC_BASE+0xFA) -#define IT83XX_PMC_MBXEC_11 REG8(IT83XX_PMC_BASE+0xFB) -#define IT83XX_PMC_MBXEC_12 REG8(IT83XX_PMC_BASE+0xFC) -#define IT83XX_PMC_MBXEC_13 REG8(IT83XX_PMC_BASE+0xFD) -#define IT83XX_PMC_MBXEC_14 REG8(IT83XX_PMC_BASE+0xFE) -#define IT83XX_PMC_MBXEC_15 REG8(IT83XX_PMC_BASE+0xFF) -#define IT83XX_PMC_PMSTS(ch) REG8(IT83XX_PMC_BASE + 0x00 + (ch << 4)) -#define IT83XX_PMC_PMDO(ch) REG8(IT83XX_PMC_BASE + 0x01 + (ch << 4)) -#define IT83XX_PMC_PMDI(ch) \ -REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 2 : 4) + (ch << 4)) -#define IT83XX_PMC_PMCTL(ch) \ -REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 3 : 6) + (ch << 4)) -#define IT83XX_PMC_PMIE(ch) \ -REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4)) - -/* Keyboard Matrix Scan control (KBS) */ -#define IT83XX_KBS_BASE 0x00F01D00 - -#define IT83XX_KBS_KSOL REG8(IT83XX_KBS_BASE+0x00) -#define IT83XX_KBS_KSOH1 REG8(IT83XX_KBS_BASE+0x01) -#define IT83XX_KBS_KSOCTRL REG8(IT83XX_KBS_BASE+0x02) -#define IT83XX_KBS_KSOH2 REG8(IT83XX_KBS_BASE+0x03) -#define IT83XX_KBS_KSI REG8(IT83XX_KBS_BASE+0x04) -#define IT83XX_KBS_KSICTRL REG8(IT83XX_KBS_BASE+0x05) -#define IT83XX_KBS_KSIGCTRL REG8(IT83XX_KBS_BASE+0x06) -#define IT83XX_KBS_KSIGOEN REG8(IT83XX_KBS_BASE+0x07) -#define IT83XX_KBS_KSIGDAT REG8(IT83XX_KBS_BASE+0x08) -#define IT83XX_KBS_KSIGDMRR REG8(IT83XX_KBS_BASE+0x09) -#define IT83XX_KBS_KSOHGCTRL REG8(IT83XX_KBS_BASE+0x0A) -#define IT83XX_KBS_KSOHGOEN REG8(IT83XX_KBS_BASE+0x0B) -#define IT83XX_KBS_KSOHGDMRR REG8(IT83XX_KBS_BASE+0x0C) -#define IT83XX_KBS_KSOLGCTRL REG8(IT83XX_KBS_BASE+0x0D) -#define IT83XX_KBS_KSOLGOEN REG8(IT83XX_KBS_BASE+0x0E) -#define IT83XX_KBS_KSOLGDMRR REG8(IT83XX_KBS_BASE+0x0F) -#define IT83XX_KBS_KSO0LSDR REG8(IT83XX_KBS_BASE+0x10) -#define IT83XX_KBS_KSO1LSDR REG8(IT83XX_KBS_BASE+0x11) -#define IT83XX_KBS_KSO2LSDR REG8(IT83XX_KBS_BASE+0x12) -#define IT83XX_KBS_KSO3LSDR REG8(IT83XX_KBS_BASE+0x13) -#define IT83XX_KBS_KSO4LSDR REG8(IT83XX_KBS_BASE+0x14) -#define IT83XX_KBS_KSO5LSDR REG8(IT83XX_KBS_BASE+0x15) -#define IT83XX_KBS_KSO6LSDR REG8(IT83XX_KBS_BASE+0x16) -#define IT83XX_KBS_KSO7LSDR REG8(IT83XX_KBS_BASE+0x17) -#define IT83XX_KBS_KSO8LSDR REG8(IT83XX_KBS_BASE+0x18) -#define IT83XX_KBS_KSO9LSDR REG8(IT83XX_KBS_BASE+0x19) -#define IT83XX_KBS_KSO10LSDR REG8(IT83XX_KBS_BASE+0x1A) -#define IT83XX_KBS_KSO11LSDR REG8(IT83XX_KBS_BASE+0x1B) -#define IT83XX_KBS_KSO12LSDR REG8(IT83XX_KBS_BASE+0x1C) -#define IT83XX_KBS_KSO13LSDR REG8(IT83XX_KBS_BASE+0x1D) -#define IT83XX_KBS_KSO14LSDR REG8(IT83XX_KBS_BASE+0x1E) -#define IT83XX_KBS_KSO15LSDR REG8(IT83XX_KBS_BASE+0x1F) -#define IT83XX_KBS_KSO16LSDR REG8(IT83XX_KBS_BASE+0x20) -#define IT83XX_KBS_KSO17LSDR REG8(IT83XX_KBS_BASE+0x21) -#define IT83XX_KBS_SDC1R REG8(IT83XX_KBS_BASE+0x22) -#define IT83XX_KBS_SDC2R REG8(IT83XX_KBS_BASE+0x23) -#define IT83XX_KBS_SDC3R REG8(IT83XX_KBS_BASE+0x24) -#define IT83XX_KBS_SDSR REG8(IT83XX_KBS_BASE+0x25) -#define IT83XX_KBS_KSIGPODR REG8(IT83XX_KBS_BASE+0x26) -#define IT83XX_KBS_KSOHGPODR REG8(IT83XX_KBS_BASE+0x27) -#define IT83XX_KBS_KSOLGPODR REG8(IT83XX_KBS_BASE+0x28) - -/* Shared Memory Flash Interface Bridge (SMFI) */ -#define IT83XX_SMFI_BASE 0x00F01000 - -#define IT83XX_SMFI_SMECCS REG8(IT83XX_SMFI_BASE+0x20) -#define IT83XX_SMFI_MASK_HOSTWA BIT(5) -#define IT83XX_SMFI_HRAMWC REG8(IT83XX_SMFI_BASE+0x5A) -#define IT83XX_SMFI_HRAMW0BA REG8(IT83XX_SMFI_BASE+0x5B) -#define IT83XX_SMFI_HRAMW1BA REG8(IT83XX_SMFI_BASE+0x5C) -#define IT83XX_SMFI_HRAMW0AAS REG8(IT83XX_SMFI_BASE+0x5D) -#define IT83XX_SMFI_HRAMW1AAS REG8(IT83XX_SMFI_BASE+0x5E) -#define IT83XX_SMFI_HRAMW2BA REG8(IT83XX_SMFI_BASE+0x76) -#define IT83XX_SMFI_HRAMW3BA REG8(IT83XX_SMFI_BASE+0x77) -#define IT83XX_SMFI_HRAMW2AAS REG8(IT83XX_SMFI_BASE+0x78) -#define IT83XX_SMFI_HRAMW3AAS REG8(IT83XX_SMFI_BASE+0x79) -#define IT83XX_SMFI_H2RAMECSIE REG8(IT83XX_SMFI_BASE+0x7A) -#define IT83XX_SMFI_H2RAMECSA REG8(IT83XX_SMFI_BASE+0x7B) -#define IT83XX_SMFI_H2RAMHSS REG8(IT83XX_SMFI_BASE+0x7C) -#define IT83XX_SMFI_ECINDAR0 REG8(IT83XX_SMFI_BASE+0x3B) -#define IT83XX_SMFI_ECINDAR1 REG8(IT83XX_SMFI_BASE+0x3C) -#define IT83XX_SMFI_ECINDAR2 REG8(IT83XX_SMFI_BASE+0x3D) -#define IT83XX_SMFI_ECINDAR3 REG8(IT83XX_SMFI_BASE+0x3E) -#define EC_INDIRECT_READ_INTERNAL_FLASH BIT(6) -#define IT83XX_SMFI_ECINDDR REG8(IT83XX_SMFI_BASE+0x3F) -#define IT83XX_SMFI_SCAR0L REG8(IT83XX_SMFI_BASE+0x40) -#define IT83XX_SMFI_SCAR0M REG8(IT83XX_SMFI_BASE+0x41) -#define IT83XX_SMFI_SCAR0H REG8(IT83XX_SMFI_BASE+0x42) -#define IT83XX_SMFI_SCAR2L REG8(IT83XX_SMFI_BASE+0x46) -#define IT83XX_SMFI_SCAR2M REG8(IT83XX_SMFI_BASE+0x47) -#define IT83XX_SMFI_SCAR2H REG8(IT83XX_SMFI_BASE+0x48) -#define IT83XX_SMFI_FLHCTRL3R REG8(IT83XX_SMFI_BASE+0x63) -#define IT83XX_SMFI_STCDMACR REG8(IT83XX_SMFI_BASE+0x80) -#define IT83XX_SMFI_FLHCTRL6R REG8(IT83XX_SMFI_BASE+0xA2) -/* Enable EC-indirect page program command */ -#define IT83XX_SMFI_MASK_ECINDPP BIT(3) - -/* Serial Peripheral Interface (SSPI) */ -#define IT83XX_SSPI_BASE 0x00F02600 - -#define IT83XX_SSPI_SPIDATA REG8(IT83XX_SSPI_BASE+0x00) -#define IT83XX_SSPI_SPICTRL1 REG8(IT83XX_SSPI_BASE+0x01) -#define IT83XX_SSPI_SPICTRL2 REG8(IT83XX_SSPI_BASE+0x02) -#define IT83XX_SSPI_SPISTS REG8(IT83XX_SSPI_BASE+0x03) -#define IT83XX_SSPI_SPICTRL3 REG8(IT83XX_SSPI_BASE+0x04) - -/* Serial Peripheral Interface (SPI) */ -#define IT83XX_SPI_BASE 0x00F03A00 - -#define IT83XX_SPI_SPISGCR REG8(IT83XX_SPI_BASE+0x00) -#define IT83XX_SPI_SPISCEN BIT(0) -#define IT83XX_SPI_TXRXFAR REG8(IT83XX_SPI_BASE+0x01) -#define IT83XX_SPI_CPURXF2A BIT(4) -#define IT83XX_SPI_CPURXF1A BIT(3) -#define IT83XX_SPI_CPUTFA BIT(1) -#define IT83XX_SPI_TXFCR REG8(IT83XX_SPI_BASE+0x02) -#define IT83XX_SPI_TXFCMR BIT(2) -#define IT83XX_SPI_TXFR BIT(1) -#define IT83XX_SPI_TXFS BIT(0) -#define IT83XX_SPI_GCR2 REG8(IT83XX_SPI_BASE+0x03) -#define IT83XX_SPI_RXF2OC BIT(4) -#define IT83XX_SPI_RXF1OC BIT(3) -#define IT83XX_SPI_RXFAR BIT(0) -#define IT83XX_SPI_IMR REG8(IT83XX_SPI_BASE+0x04) -#define IT83XX_SPI_RX_FIFO_FULL BIT(7) -#define IT83XX_SPI_RX_REACH BIT(5) -#define IT83XX_SPI_EDIM BIT(2) -#define IT83XX_SPI_ISR REG8(IT83XX_SPI_BASE+0x05) -#define IT83XX_SPI_TXFSR REG8(IT83XX_SPI_BASE+0x06) -#define IT83XX_SPI_ENDDETECTINT BIT(2) -#define IT83XX_SPI_RXFSR REG8(IT83XX_SPI_BASE+0x07) -#define IT83XX_SPI_RXFFSM (BIT(4) | BIT(3)) -#define IT83XX_SPI_RXF2FS BIT(2) -#define IT83XX_SPI_RXF1FS BIT(1) -#ifdef CHIP_VARIANT_IT83202BX -#define IT83XX_SPI_SPISRDR REG8(IT83XX_SPI_BASE+0x08) -#else -#define IT83XX_SPI_SPISRDR REG8(IT83XX_SPI_BASE+0x0b) -#endif -#define IT83XX_SPI_CPUWTFDB0 REG32(IT83XX_SPI_BASE+0x08) -#define IT83XX_SPI_FCR REG8(IT83XX_SPI_BASE+0x09) -#define IT83XX_SPI_SPISRTXF BIT(2) -#define IT83XX_SPI_RXFR BIT(1) -#define IT83XX_SPI_RXFCMR BIT(0) -#define IT83XX_SPI_RXFRDRB0 REG32(IT83XX_SPI_BASE+0x0C) -#define IT83XX_SPI_FTCB0R REG8(IT83XX_SPI_BASE+0x18) -#define IT83XX_SPI_FTCB1R REG8(IT83XX_SPI_BASE+0x19) -#define IT83XX_SPI_TCCB0 REG8(IT83XX_SPI_BASE+0x1A) -#define IT83XX_SPI_TCCB1 REG8(IT83XX_SPI_BASE+0x1B) -#define IT83XX_SPI_HPR2 REG8(IT83XX_SPI_BASE+0x1E) -#define IT83XX_SPI_EMMCBMR REG8(IT83XX_SPI_BASE+0x21) -#define IT83XX_SPI_EMMCABM BIT(1) /* eMMC Alternative Boot Mode */ -#define IT83XX_SPI_RX_VLISMR REG8(IT83XX_SPI_BASE+0x26) -#define IT83XX_SPI_RVLIM BIT(0) -#define IT83XX_SPI_RX_VLISR REG8(IT83XX_SPI_BASE+0x27) -#define IT83XX_SPI_RVLI BIT(0) - -/* Platform Environment Control Interface (PECI) */ -#define IT83XX_PECI_BASE 0x00F02C00 - -#define IT83XX_PECI_HOSTAR REG8(IT83XX_PECI_BASE+0x00) -#define IT83XX_PECI_HOCTLR REG8(IT83XX_PECI_BASE+0x01) -#define IT83XX_PECI_HOCMDR REG8(IT83XX_PECI_BASE+0x02) -#define IT83XX_PECI_HOTRADDR REG8(IT83XX_PECI_BASE+0x03) -#define IT83XX_PECI_HOWRLR REG8(IT83XX_PECI_BASE+0x04) -#define IT83XX_PECI_HORDLR REG8(IT83XX_PECI_BASE+0x05) -#define IT83XX_PECI_HOWRDR REG8(IT83XX_PECI_BASE+0x06) -#define IT83XX_PECI_HORDDR REG8(IT83XX_PECI_BASE+0x07) -#define IT83XX_PECI_HOCTL2R REG8(IT83XX_PECI_BASE+0x08) -#define IT83XX_PECI_RWFCSV REG8(IT83XX_PECI_BASE+0x09) -#define IT83XX_PECI_RRFCSV REG8(IT83XX_PECI_BASE+0x0A) -#define IT83XX_PECI_WFCSV REG8(IT83XX_PECI_BASE+0x0B) -#define IT83XX_PECI_RFCSV REG8(IT83XX_PECI_BASE+0x0C) -#define IT83XX_PECI_AWFCSV REG8(IT83XX_PECI_BASE+0x0D) -#define IT83XX_PECI_PADCTLR REG8(IT83XX_PECI_BASE+0x0E) - -/* - * The count number of the counter for 25 ms register. - * The 25 ms register is calculated by (count number *1.024 kHz). - */ -#define I2C_CLK_LOW_TIMEOUT 255 /* ~=249 ms */ - -/* SMBus/I2C Interface (SMB/I2C) */ -#define IT83XX_SMB_BASE 0x00F01C00 - -#define IT83XX_SMB_4P7USL REG8(IT83XX_SMB_BASE+0x00) -#define IT83XX_SMB_4P0USL REG8(IT83XX_SMB_BASE+0x01) -#define IT83XX_SMB_300NS REG8(IT83XX_SMB_BASE+0x02) -#define IT83XX_SMB_250NS REG8(IT83XX_SMB_BASE+0x03) -#define IT83XX_SMB_25MS REG8(IT83XX_SMB_BASE+0x04) -#define IT83XX_SMB_45P3USL REG8(IT83XX_SMB_BASE+0x05) -#define IT83XX_SMB_45P3USH REG8(IT83XX_SMB_BASE+0x06) -#define IT83XX_SMB_4P7A4P0H REG8(IT83XX_SMB_BASE+0x07) -#define IT83XX_SMB_SLVISELR REG8(IT83XX_SMB_BASE+0x08) -#define IT83XX_SMB_SCLKTS(ch) REG8(IT83XX_SMB_BASE+0x09+ch) -#define IT83XX_SMB_CHSEF REG8(IT83XX_SMB_BASE+0x11) -#define IT83XX_SMB_CHSAB REG8(IT83XX_SMB_BASE+0x20) -#define IT83XX_SMB_CHSCD REG8(IT83XX_SMB_BASE+0x21) -#define IT83XX_SMB_HOSTA(ch) REG8(IT83XX_SMB_BASE+0x40+(ch << 6)) -#define IT83XX_SMB_HOCTL(ch) REG8(IT83XX_SMB_BASE+0x41+(ch << 6)) -#define IT83XX_SMB_HOCMD(ch) REG8(IT83XX_SMB_BASE+0x42+(ch << 6)) -#define IT83XX_SMB_TRASLA(ch) REG8(IT83XX_SMB_BASE+0x43+(ch << 6)) -#define IT83XX_SMB_D0REG(ch) REG8(IT83XX_SMB_BASE+0x44+(ch << 6)) -#define IT83XX_SMB_D1REG(ch) REG8(IT83XX_SMB_BASE+0x45+(ch << 6)) -#define IT83XX_SMB_HOBDB(ch) REG8(IT83XX_SMB_BASE+0x46+(ch << 6)) -#define IT83XX_SMB_PECERC(ch) REG8(IT83XX_SMB_BASE+0x47+(ch << 6)) -#define IT83XX_SMB_SMBPCTL(ch) REG8(IT83XX_SMB_BASE+0x4A+(ch << 6)) -#define IT83XX_SMB_HOCTL2(ch) REG8(IT83XX_SMB_BASE+0x50+(ch << 6)) -#define IT83XX_SMB_SLVEN (1 << 5) -#define IT83XX_SMB_RESLADR REG8(IT83XX_SMB_BASE+0x48) -#define IT83XX_SMB_SLDA REG8(IT83XX_SMB_BASE+0x49) -#define IT83XX_SMB_SLSTA REG8(IT83XX_SMB_BASE+0x4B) -#define IT83XX_SMB_SPDS (1 << 5) -#define IT83XX_SMB_RCS (1 << 3) -#define IT83XX_SMB_STS (1 << 2) -#define IT83XX_SMB_SDS (1 << 1) -#define IT83XX_SMB_SICR REG8(IT83XX_SMB_BASE+0x4C) -#define IT83XX_SMB_RESLADR2 REG8(IT83XX_SMB_BASE+0x51) -#define IT83XX_SMB_ENADDR2 (1 << 7) -#define IT83XX_SMB_SFFCTL REG8(IT83XX_SMB_BASE+0x55) -#define IT83XX_SMB_HSAPE BIT(1) -#define IT83XX_SMB_SAFE (1 << 0) -#define IT83XX_SMB_SFFSTA REG8(IT83XX_SMB_BASE+0x56) -#define IT83XX_SMB_SFFFULL (1 << 6) - -/* BRAM */ -#define IT83XX_BRAM_BASE 0x00F02200 - -/* offset 0 ~ 0x7f */ -#define IT83XX_BRAM_BANK0(i) REG8(IT83XX_BRAM_BASE + i) -/* Battery backed RAM indices. */ -enum bram_indices { - /* reset flags uses 4 bytes */ - BRAM_IDX_RESET_FLAGS0 = 0, - BRAM_IDX_RESET_FLAGS1 = 1, - BRAM_IDX_RESET_FLAGS2 = 2, - BRAM_IDX_RESET_FLAGS3 = 3, - - /* PD state data for CONFIG_USB_PD_DUAL_ROLE uses 1 byte per port */ - BRAM_IDX_PD0 = 4, - BRAM_IDX_PD1 = 5, - BRAM_IDX_PD2 = 6, - - /* index 7 is reserved */ - - BRAM_IDX_SCRATCHPAD0 = 8, - BRAM_IDX_SCRATCHPAD1 = 9, - BRAM_IDX_SCRATCHPAD2 = 0xa, - BRAM_IDX_SCRATCHPAD3 = 0xb, - - /* EC logs status */ - BRAM_IDX_EC_LOG_STATUS = 0xc, - - /* offset 0x0d ~ 0x1f are reserved for future use. */ -#if defined(CONFIG_HOSTCMD_LPC) || defined(CONFIG_HOSTCMD_ESPI) - /* - * offset 0x20 ~ 0x7b are reserved for future use. - * (apply to x86 platform) - */ - - /* This field is used to indicate BRAM is valid or not. */ - BRAM_IDX_VALID_FLAGS0 = 0x7c, - BRAM_IDX_VALID_FLAGS1 = 0x7d, - BRAM_IDX_VALID_FLAGS2 = 0x7e, - BRAM_IDX_VALID_FLAGS3 = 0x7f - /* offset 0x7f is the end of BRAM bank 0. */ -#else - - /* panic data uses 144 bytes (offset 0x20 ~ 0xaf) */ - BRAM_PANIC_DATA_START = 0x20, - BRAM_PANIC_DATA_END = 0xaf, - - /* This field is used to indicate BRAM is valid or not. */ - BRAM_IDX_VALID_FLAGS0 = 0xbc, - BRAM_IDX_VALID_FLAGS1 = 0xbd, - BRAM_IDX_VALID_FLAGS2 = 0xbe, - BRAM_IDX_VALID_FLAGS3 = 0xbf - /* offset 0xbf is the end of BRAM bank 1. */ -#endif -}; -#define BRAM_RESET_FLAGS0 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS0) -#define BRAM_RESET_FLAGS1 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS1) -#define BRAM_RESET_FLAGS2 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS2) -#define BRAM_RESET_FLAGS3 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS3) - -#define BRAM_SCRATCHPAD0 IT83XX_BRAM_BANK0(BRAM_IDX_SCRATCHPAD0) -#define BRAM_SCRATCHPAD1 IT83XX_BRAM_BANK0(BRAM_IDX_SCRATCHPAD1) -#define BRAM_SCRATCHPAD2 IT83XX_BRAM_BANK0(BRAM_IDX_SCRATCHPAD2) -#define BRAM_SCRATCHPAD3 IT83XX_BRAM_BANK0(BRAM_IDX_SCRATCHPAD3) - -#define BRAM_EC_LOG_STATUS IT83XX_BRAM_BANK0(BRAM_IDX_EC_LOG_STATUS) -enum bram_ec_logs_status { - EC_LOG_SAVED_IN_FLASH = 1, - EC_LOG_SAVED_IN_MEMORY -}; - -#define BRAM_VALID_FLAGS0 IT83XX_BRAM_BANK0(BRAM_IDX_VALID_FLAGS0) -#define BRAM_VALID_FLAGS1 IT83XX_BRAM_BANK0(BRAM_IDX_VALID_FLAGS1) -#define BRAM_VALID_FLAGS2 IT83XX_BRAM_BANK0(BRAM_IDX_VALID_FLAGS2) -#define BRAM_VALID_FLAGS3 IT83XX_BRAM_BANK0(BRAM_IDX_VALID_FLAGS3) - -/* - * These 128 bytes are use to latch port 80h data on x86 platform. - * And they will be used to save panic data if the GPG1 reset mechanism - * is enabled. - */ -#if defined(CONFIG_HOSTCMD_LPC) || defined(CONFIG_HOSTCMD_ESPI) -/* offset 0x80 ~ 0xbf */ -#define IT83XX_BRAM_BANK1(i) REG8(IT83XX_BRAM_BASE + 0x80 + i) -#else -/* Length of bram panic data */ -#define BRAM_PANIC_LEN (BRAM_PANIC_DATA_END - BRAM_PANIC_DATA_START + 1) -#endif - -/* - * Enhanced SMBus/I2C Interface - * Ch_D: 0x00F03680 , Ch_E: 0x00F03500 , Ch_F: 0x00F03580 - * Ch_D: ch = 0x03 , Ch_E: ch = 0x00 , Ch_F: ch = 0x01 - */ -#define IT83XX_I2C_BASE 0x00F03500 - -#define IT83XX_I2C_DRR(ch) REG8(IT83XX_I2C_BASE+0x00+(ch << 7)) -#define IT83XX_I2C_PSR(ch) REG8(IT83XX_I2C_BASE+0x01+(ch << 7)) -#define IT83XX_I2C_HSPR(ch) REG8(IT83XX_I2C_BASE+0x02+(ch << 7)) -#define IT83XX_I2C_STR(ch) REG8(IT83XX_I2C_BASE+0x03+(ch << 7)) -#define IT83XX_I2C_BB (1 << 5) -#define IT83XX_I2C_TIME_OUT (1 << 3) -#define IT83XX_I2C_RW (1 << 2) -#define IT83XX_I2C_INTPEND (1 << 1) -#define IT83XX_I2C_DHTR(ch) REG8(IT83XX_I2C_BASE+0x04+(ch << 7)) -#define IT83XX_I2C_TOR(ch) REG8(IT83XX_I2C_BASE+0x05+(ch << 7)) -#define IT83XX_I2C_DTR(ch) REG8(IT83XX_I2C_BASE+0x08+(ch << 7)) -#define IT83XX_I2C_CTR(ch) REG8(IT83XX_I2C_BASE+0x09+(ch << 7)) -#define IT83XX_I2C_INTEN (1 << 6) -#define IT83XX_I2C_MODE (1 << 5) -#define IT83XX_I2C_STARST (1 << 4) -#define IT83XX_I2C_ACK (1 << 3) -#define IT83XX_I2C_HALT (1 << 0) -#define IT83XX_I2C_CTR1(ch) REG8(IT83XX_I2C_BASE+0x0A+(ch << 7)) -#define IT83XX_I2C_COMQ_EN (1 << 7) -#define IT83XX_I2C_MDL_EN (1 << 1) -#define IT83XX_I2C_BYTE_CNT_L(ch) REG8(IT83XX_I2C_BASE+0x0C+(ch << 7)) -#define IT83XX_I2C_IRQ_ST(ch) REG8(IT83XX_I2C_BASE+0x0D+(ch << 7)) -#define IT83XX_I2C_IDW_CLR (1 << 3) -#define IT83XX_I2C_IDR_CLR (1 << 2) -#define IT83XX_I2C_SLVDATAFLG (1 << 1) -#define IT83XX_I2C_P_CLR (1 << 0) -#define IT83XX_I2C_IDR(ch) REG8(IT83XX_I2C_BASE+0x06+(ch << 7)) -#define IT83XX_I2C_TOS(ch) REG8(IT83XX_I2C_BASE+0x07+(ch << 7)) -#define IT83XX_I2C_CLK_STR (1 << 7) -#define IT83XX_I2C_IDR2(ch) REG8(IT83XX_I2C_BASE+0x1F+(ch << 7)) -#define IT83XX_I2C_RAMHA(ch) REG8(IT83XX_I2C_BASE+0x23+(ch << 7)) -#define IT83XX_I2C_RAMLA(ch) REG8(IT83XX_I2C_BASE+0x24+(ch << 7)) -#define IT83XX_I2C_RAMHA2(ch) REG8(IT83XX_I2C_BASE+0x2B+(ch << 7)) -#define IT83XX_I2C_RAMLA2(ch) REG8(IT83XX_I2C_BASE+0x2C+(ch << 7)) -#define IT83XX_I2C_CMD_ADDH(ch) REG8(IT83XX_I2C_BASE+0x25+(ch << 7)) -#define IT83XX_I2C_CMD_ADDL(ch) REG8(IT83XX_I2C_BASE+0x26+(ch << 7)) -#define IT83XX_I2C_RAMH2A(ch) REG8(IT83XX_I2C_BASE+0x50+(ch << 7)) -#define IT83XX_I2C_CMD_ADDH2(ch) REG8(IT83XX_I2C_BASE+0x52+(ch << 7)) - -enum i2c_channels { - IT83XX_I2C_CH_A, /* GPIO.B3/B4 */ - IT83XX_I2C_CH_B, /* GPIO.C1/C2 */ - IT83XX_I2C_CH_C, /* GPIO.F6/F7 or GPIO.C7/F7 */ - IT83XX_I2C_CH_D, /* GPIO.H1/H2 */ - IT83XX_I2C_CH_E, /* GPIO.E0/E7 */ - IT83XX_I2C_CH_F, /* GPIO.A4/A5 (for util/iteflash) */ - IT83XX_I2C_PORT_COUNT, -}; - -#define USB_VID_ITE 0x048d - -#define IT83XX_ESPI_BASE 0x00F03100 - -#define IT83XX_ESPI_GCAC1 REG8(IT83XX_ESPI_BASE+0x05) -#define IT83XX_ESPI_ESPCTRL0 REG8(IT83XX_ESPI_BASE+0x90) -#define IT83XX_ESPI_ESGCTRL0 REG8(IT83XX_ESPI_BASE+0xA0) -#define IT83XX_ESPI_ESGCTRL1 REG8(IT83XX_ESPI_BASE+0xA1) -#define IT83XX_ESPI_ESGCTRL2 REG8(IT83XX_ESPI_BASE+0xA2) - -/* eSPI VW */ -#define IT83XX_ESPI_VW_BASE 0x00F03200 -#define IT83XX_ESPI_VWIDX(i) REG8(IT83XX_ESPI_VW_BASE+(i)) - -#define VW_LEVEL_FIELD(f) ((f) << 0) -#define VW_VALID_FIELD(f) ((f) << 4) - -#define ESPI_SYSTEM_EVENT_VW_IDX_2 0x2 -#define VW_IDX_2_SLP_S3 BIT(0) -#define VW_IDX_2_SLP_S4 BIT(1) -#define VW_IDX_2_SLP_S5 BIT(2) - -#define ESPI_SYSTEM_EVENT_VW_IDX_3 0x3 -#define VW_IDX_3_SUS_STAT BIT(0) -#define VW_IDX_3_PLTRST BIT(1) -#define VW_IDX_3_OOB_RST_WARN BIT(2) - -#define ESPI_SYSTEM_EVENT_VW_IDX_4 0x4 -#define VW_IDX_4_OOB_RST_ACK BIT(0) -#define VW_IDX_4_WAKE BIT(2) -#define VW_IDX_4_PME BIT(3) - -#define ESPI_SYSTEM_EVENT_VW_IDX_5 0x5 -#define VW_IDX_5_SLAVE_BTLD_DONE BIT(0) -#define VW_IDX_5_FATAL BIT(1) -#define VW_IDX_5_NON_FATAL BIT(2) -#define VW_IDX_5_SLAVE_BTLD_STATUS BIT(3) -#define VW_IDX_5_BTLD_STATUS_DONE (VW_IDX_5_SLAVE_BTLD_DONE | \ - VW_IDX_5_SLAVE_BTLD_STATUS) - -#define ESPI_SYSTEM_EVENT_VW_IDX_6 0x6 -#define VW_IDX_6_SCI BIT(0) -#define VW_IDX_6_SMI BIT(1) -#define VW_IDX_6_RCIN BIT(2) -#define VW_IDX_6_HOST_RST_ACK BIT(3) - -#define ESPI_SYSTEM_EVENT_VW_IDX_7 0x7 -#define VW_IDX_7_HOST_RST_WARN BIT(0) - -#define ESPI_SYSTEM_EVENT_VW_IDX_40 0x40 -#define VW_IDX_40_SUS_ACK BIT(0) - -#define ESPI_SYSTEM_EVENT_VW_IDX_41 0x41 -#define VW_IDX_41_SUS_WARN BIT(0) -#define VW_IDX_41_SUS_PWRDN_ACK BIT(1) -#define VW_IDX_41_SLP_A BIT(3) - -#define ESPI_SYSTEM_EVENT_VW_IDX_42 0x42 -#define VW_IDX_42_SLP_LAN BIT(0) -#define VW_IDX_42_SLP_WLAN BIT(1) - -#define ESPI_SYSTEM_EVENT_VW_IDX_43 0x43 -#define ESPI_SYSTEM_EVENT_VW_IDX_44 0x44 -#define ESPI_SYSTEM_EVENT_VW_IDX_47 0x47 - -#define IT83XX_ESPI_VWCTRL0 REG8(IT83XX_ESPI_VW_BASE+0x90) -#define ESPI_INTERRUPT_EVENT_PUT_PC BIT(7) - -#define IT83XX_ESPI_VWCTRL1 REG8(IT83XX_ESPI_VW_BASE+0x91) -#define IT83XX_ESPI_VWCTRL2 REG8(IT83XX_ESPI_VW_BASE+0x92) -#define IT83XX_ESPI_VWCTRL3 REG8(IT83XX_ESPI_VW_BASE+0x93) - -/* eSPI Queue 0 */ -#define IT83XX_ESPI_QUEUE_BASE 0x00F03300 -/* PUT_PC data byte 0 - 63 */ -#define IT83XX_ESPI_QUEUE_PUT_PC(i) REG8(IT83XX_ESPI_QUEUE_BASE+(i)) -/* PUT_OOB data byte 0 - 79 */ -#define IT83XX_ESPI_QUEUE_PUT_OOB(i) REG8(IT83XX_ESPI_QUEUE_BASE+0x80+(i)) - -/* USB Controller */ -#define IT83XX_USB_BASE 0x00F02F00 - -#define IT83XX_USB_P0MCR REG8(IT83XX_USB_BASE+0xE4) -#define USB_DP_DM_PULL_DOWN_EN BIT(4) - -/* Wake pin definitions, defined at board-level */ -#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 - -/* --- MISC (not implemented yet) --- */ - -#define IT83XX_PS2_BASE 0x00F01700 -#define IT83XX_EGPIO_BASE 0x00F02100 -#define IT83XX_CIR_BASE 0x00F02300 -#define IT83XX_DBGR_BASE 0x00F02500 -#define IT83XX_OW_BASE 0x00F02A00 -#define IT83XX_CEC_BASE 0x00F02E00 - -#endif /* __CROS_EC_REGISTERS_H */ diff --git a/chip/it83xx/spi.c b/chip/it83xx/spi.c deleted file mode 100644 index 63f8e4247c..0000000000 --- a/chip/it83xx/spi.c +++ /dev/null @@ -1,400 +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. - * - * SPI driver for Chrome EC. - * - * This uses FIFO mode to handle transmission and reception. - */ - -#include "chipset.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "intc.h" -#include "registers.h" -#include "spi.h" -#include "system.h" -#include "task.h" -#include "util.h" - -/* Console output macros */ -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SPI, format, ## args) - -#define SPI_RX_MAX_FIFO_SIZE 256 -#define SPI_TX_MAX_FIFO_SIZE 256 - -#define EC_SPI_PREAMBLE_LENGTH 4 -#define EC_SPI_PAST_END_LENGTH 4 - -/* Max data size for a version 3 request/response packet. */ -#define SPI_MAX_REQUEST_SIZE SPI_RX_MAX_FIFO_SIZE -#define SPI_MAX_RESPONSE_SIZE (SPI_TX_MAX_FIFO_SIZE - \ - EC_SPI_PREAMBLE_LENGTH - EC_SPI_PAST_END_LENGTH) - -static const uint8_t out_preamble[EC_SPI_PREAMBLE_LENGTH] = { - EC_SPI_PROCESSING, - EC_SPI_PROCESSING, - EC_SPI_PROCESSING, - /* This is the byte which matters */ - EC_SPI_FRAME_START, -}; - -/* Store read and write data buffer */ -static uint8_t in_msg[SPI_RX_MAX_FIFO_SIZE] __aligned(4); -static uint8_t out_msg[SPI_TX_MAX_FIFO_SIZE] __aligned(4); - -/* Parameters used by host protocols */ -static struct host_packet spi_packet; - -enum spi_peripheral_state_machine { - /* Ready to receive next request */ - SPI_STATE_READY_TO_RECV, - /* Receiving request */ - SPI_STATE_RECEIVING, - /* Processing request */ - SPI_STATE_PROCESSING, - /* Received bad data */ - SPI_STATE_RX_BAD, - - SPI_STATE_COUNT, -} spi_peripheral_state; - -static const int spi_response_state[] = { - [SPI_STATE_READY_TO_RECV] = EC_SPI_OLD_READY, - [SPI_STATE_RECEIVING] = EC_SPI_RECEIVING, - [SPI_STATE_PROCESSING] = EC_SPI_PROCESSING, - [SPI_STATE_RX_BAD] = EC_SPI_RX_BAD_DATA, -}; -BUILD_ASSERT(ARRAY_SIZE(spi_response_state) == SPI_STATE_COUNT); - -static void spi_set_state(int state) -{ - /* SPI peripheral state machine */ - spi_peripheral_state = state; - /* Response spi peripheral state */ - IT83XX_SPI_SPISRDR = spi_response_state[state]; -} - -static void reset_rx_fifo(void) -{ - /* End Rx FIFO access */ - IT83XX_SPI_TXRXFAR = 0x00; - /* Rx FIFO reset and count monitor reset */ - IT83XX_SPI_FCR = IT83XX_SPI_RXFR | IT83XX_SPI_RXFCMR; -} - -/* This routine handles spi received unexcepted data */ -static void spi_bad_received_data(int count) -{ - int i; - - /* State machine mismatch, timeout, or protocol we can't handle. */ - spi_set_state(SPI_STATE_RX_BAD); - /* End CPU access Rx FIFO, so it can clock in bytes from AP again. */ - IT83XX_SPI_TXRXFAR = 0; - - CPRINTS("SPI rx bad data"); - CPRINTF("in_msg=["); - for (i = 0; i < count; i++) - CPRINTF("%02x ", in_msg[i]); - CPRINTF("]\n"); -} - -static void spi_response_host_data(uint8_t *out_msg_addr, int tx_size) -{ - int i; - - /* Tx FIFO reset and count monitor reset */ - IT83XX_SPI_TXFCR = IT83XX_SPI_TXFR | IT83XX_SPI_TXFCMR; - /* CPU Tx FIFO1 and FIFO2 access */ - IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPUTFA; - - for (i = 0; i < tx_size; i += 4) - /* Write response data from out_msg buffer to Tx FIFO */ - IT83XX_SPI_CPUWTFDB0 = *(uint32_t *)(out_msg_addr + i); - - /* - * After writing data to Tx FIFO is finished, this bit will - * be to indicate the SPI peripheral. - */ - IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS; - /* End Tx FIFO access */ - IT83XX_SPI_TXRXFAR = 0; - /* SPI peripheral read Tx FIFO */ - IT83XX_SPI_FCR = IT83XX_SPI_SPISRTXF; -} - -/* - * 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 spi_send_response_packet(struct host_packet *pkt) -{ - int i, tx_size; - - if (spi_peripheral_state != SPI_STATE_PROCESSING) { - CPRINTS("The request data is not processing."); - return; - } - - /* Append our past-end byte, which we reserved space for. */ - for (i = 0; i < EC_SPI_PAST_END_LENGTH; i++) - ((uint8_t *)pkt->response)[pkt->response_size + i] - = EC_SPI_PAST_END; - - tx_size = pkt->response_size + EC_SPI_PREAMBLE_LENGTH + - EC_SPI_PAST_END_LENGTH; - - /* Transmit the reply */ - spi_response_host_data(out_msg, tx_size); -} - -/* Store request data from Rx FIFO to in_msg buffer */ -static void spi_host_request_data(uint8_t *in_msg_addr, int count) -{ - int i; - - /* CPU Rx FIFO1 access */ - IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPURXF1A; - /* - * In spi_parse_header, the request data will separate to - * write in_msg buffer so we cannot set CPU to end accessing - * Rx FIFO in this function. We will set IT83XX_SPI_TXRXFAR = 0 - * in reset_rx_fifo. - */ - - for (i = 0; i < count; i += 4) - /* Get data from controller to buffer */ - *(uint32_t *)(in_msg_addr + i) = IT83XX_SPI_RXFRDRB0; -} - -/* Parse header for version of spi-protocol */ -static void spi_parse_header(void) -{ - struct ec_host_request *r = (struct ec_host_request *)in_msg; - - /* Store request data from Rx FIFO to in_msg buffer */ - spi_host_request_data(in_msg, sizeof(*r)); - - /* Protocol version 3 */ - if (in_msg[0] == EC_HOST_REQUEST_VERSION) { - int pkt_size; - - /* Check how big the packet should be */ - pkt_size = host_request_expected_size(r); - - if (pkt_size == 0 || pkt_size > sizeof(in_msg)) - return spi_bad_received_data(pkt_size); - - /* Store request data from Rx FIFO to in_msg buffer */ - spi_host_request_data(in_msg + sizeof(*r), - pkt_size - sizeof(*r)); - - /* Set up parameters for host request */ - spi_packet.send_response = spi_send_response_packet; - spi_packet.request = in_msg; - spi_packet.request_temp = NULL; - spi_packet.request_max = sizeof(in_msg); - spi_packet.request_size = pkt_size; - - /* Response must start with the preamble */ - memcpy(out_msg, out_preamble, EC_SPI_PREAMBLE_LENGTH); - - spi_packet.response = out_msg + EC_SPI_PREAMBLE_LENGTH; - /* Reserve space for frame start and trailing past-end byte */ - spi_packet.response_max = SPI_MAX_RESPONSE_SIZE; - spi_packet.response_size = 0; - spi_packet.driver_result = EC_RES_SUCCESS; - - /* Move to processing state */ - spi_set_state(SPI_STATE_PROCESSING); - - /* Go to common-layer to handle request */ - host_packet_receive(&spi_packet); - } else { - /* Invalid version number */ - CPRINTS("Invalid version number"); - return spi_bad_received_data(1); - } -} - -void spi_event(enum gpio_signal signal) -{ - if (chipset_in_state(CHIPSET_STATE_ON)) { - /* EC has started receiving the request from the AP */ - spi_set_state(SPI_STATE_RECEIVING); - /* Disable idle task deep sleep bit of SPI in S0. */ - disable_sleep(SLEEP_MASK_SPI); - } -} - -void spi_peripheral_int_handler(void) -{ - if (IS_ENABLED(CONFIG_BOOTBLOCK) && - (IT83XX_SPI_ISR & IT83XX_SPI_RX_FIFO_FULL) && - (IT83XX_SPI_EMMCBMR & IT83XX_SPI_EMMCABM)) { - spi_host_request_data(in_msg, 128); - /* End CPU access RX FIFO */ - IT83XX_SPI_TXRXFAR = 0; - /* Write to clear interrupt status */ - IT83XX_SPI_ISR = 0xff; - /* - * Handle eMMC CMD0: - * GO_IDLE_STATE, GO_PRE_IDLE_STATE, and BOOT_INITIATION - */ - spi_emmc_cmd0_isr((uint32_t *)in_msg); - return; - } - - /* - * The status of SPI end detection interrupt bit is set, it - * means that host command parse has been completed and AP - * has received the last byte which is EC_SPI_PAST_END from - * EC responded data, then AP ended the transaction. - */ - if (IT83XX_SPI_ISR & IT83XX_SPI_ENDDETECTINT) { - /* Ready to receive */ - spi_set_state(SPI_STATE_READY_TO_RECV); - /* - * Once there is no SPI active, enable idle task deep - * sleep bit of SPI in S3 or lower. - */ - enable_sleep(SLEEP_MASK_SPI); - /* CS# is deasserted, so write clear all peripheral status */ - IT83XX_SPI_ISR = 0xff; - } - /* - * The status of Rx valid length interrupt bit is set that - * indicates reached target count(IT83XX_SPI_FTCB1R, - * IT83XX_SPI_FTCB0R) and the length field of the host - * requested data. - */ - if (IT83XX_SPI_RX_VLISR & IT83XX_SPI_RVLI) { - /* write clear peripheral status */ - IT83XX_SPI_RX_VLISR = IT83XX_SPI_RVLI; - /* Parse header for version of spi-protocol */ - spi_parse_header(); - } - - /* Clear the interrupt status */ - task_clear_pending_irq(IT83XX_IRQ_SPI_PERIPHERAL); -} - -static void spi_init(void) -{ - /* Set FIFO data target count */ - struct ec_host_request cmd_head; - - /* - * Target count means the size of host request. - * And plus extra 4 bytes because the CPU accesses FIFO base on - * word. If host requested data length is one byte, we need to - * align the data length to 4 bytes. - */ - int target_count = sizeof(cmd_head) + 4; - /* Offset of data_len member of host request. */ - int offset = (char *)&cmd_head.data_len - (char *)&cmd_head; - - IT83XX_SPI_FTCB1R = (target_count >> 8) & 0xff; - IT83XX_SPI_FTCB0R = target_count & 0xff; - /* - * The register setting can capture the length field of host - * request. - */ - IT83XX_SPI_TCCB1 = (offset >> 8) & 0xff; - IT83XX_SPI_TCCB0 = offset & 0xff; - - /* Set SPI pins to alternate function */ - gpio_config_module(MODULE_SPI, 1); - /* - * Memory controller configuration register 3. - * bit6 : SPI pin function select (0b:Enable, 1b:Mask) - */ - IT83XX_GCTRL_MCCR3 |= IT83XX_GCTRL_SPISLVPFE; - /* Set unused blocked byte */ - IT83XX_SPI_HPR2 = 0x00; - /* Rx valid length interrupt enabled */ - IT83XX_SPI_RX_VLISMR &= ~IT83XX_SPI_RVLIM; - /* - * General control register2 - * bit4 : Rx FIFO2 will not be overwrited once it's full. - * bit3 : Rx FIFO1 will not be overwrited once it's full. - * bit0 : Rx FIFO1/FIFO2 will reset after each CS_N goes high. - */ - IT83XX_SPI_GCR2 = IT83XX_SPI_RXF2OC | IT83XX_SPI_RXF1OC - | IT83XX_SPI_RXFAR; - /* - * Interrupt mask register (0b:Enable, 1b:Mask) - * bit5 : Rx byte reach interrupt mask - * bit2 : SPI end detection interrupt mask - */ - IT83XX_SPI_IMR &= ~IT83XX_SPI_EDIM; - /* Reset fifo and prepare to for next transaction */ - reset_rx_fifo(); - /* Ready to receive */ - spi_set_state(SPI_STATE_READY_TO_RECV); - /* Interrupt status register(write one to clear) */ - IT83XX_SPI_ISR = 0xff; - /* SPI peripheral enable (after settings are ready) */ - IT83XX_SPI_SPISGCR = IT83XX_SPI_SPISCEN; - /* Enable SPI peripheral interrupt */ - task_clear_pending_irq(IT83XX_IRQ_SPI_PERIPHERAL); - task_enable_irq(IT83XX_IRQ_SPI_PERIPHERAL); - /* Enable SPI chip select pin interrupt */ - gpio_clear_pending_interrupt(GPIO_SPI0_CS); - gpio_enable_interrupt(GPIO_SPI0_CS); -} -DECLARE_HOOK(HOOK_INIT, spi_init, HOOK_PRIO_INIT_SPI); - -/* reset peripheral SPI module */ -static void spi_reset(void) -{ - /* - * Reset SPI module before sysjump. New FW images (RO/RW) will - * re-configure it. - */ - IT83XX_GCTRL_RSTC5 |= BIT(1); -} -DECLARE_HOOK(HOOK_SYSJUMP, spi_reset, HOOK_PRIO_DEFAULT); - -#if defined(SECTION_IS_RO) && defined(CONFIG_BOOTBLOCK) -/* AP has booted */ -void emmc_ap_jump_to_bl(enum gpio_signal signal) -{ - /* Transmission completed. Set SPI pin mux to AP communication mode */ - IT83XX_GCTRL_PIN_MUX0 &= ~BIT(7); - /* Reset and re-initialize SPI module to communication mode */ - spi_reset(); - spi_init(); - /* Disable interrupt of detection of AP's BOOTBLOCK_EN_L */ - gpio_disable_interrupt(GPIO_BOOTBLOCK_EN_L); - enable_sleep(SLEEP_MASK_EMMC); - - CPRINTS("eMMC emulation disabled. AP Jumped to BL"); -} -#endif - -/* Get protocol information */ -enum ec_status spi_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 = SPI_MAX_REQUEST_SIZE; - r->max_response_packet_size = SPI_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, - spi_get_protocol_info, - EC_VER_MASK(0)); diff --git a/chip/it83xx/spi_master.c b/chip/it83xx/spi_master.c deleted file mode 100644 index d3898deef6..0000000000 --- a/chip/it83xx/spi_master.c +++ /dev/null @@ -1,173 +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. - */ - -/* SPI module for Chrome EC */ - -#include "clock.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "spi.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) - -enum sspi_clk_sel { - sspi_clk_24mhz = 0, - sspi_clk_12mhz, - sspi_clk_8mhz, - sspi_clk_6mhz, - sspi_clk_4p8mhz, - sspi_clk_4mhz, - sspi_clk_3p428mhz, - sspi_clk_3mhz, -}; - -enum sspi_ch_sel { - SSPI_CH_CS0 = 0, - SSPI_CH_CS1, -}; - -static void sspi_frequency(enum sspi_clk_sel freq) -{ - /* - * bit[6:5] - * Bit 6:Clock Polarity (CLPOL) - * 0: SSCK is low in the idle mode. - * 1: SSCK is high in the idle mode. - * Bit 5:Clock Phase (CLPHS) - * 0: Latch data on the first SSCK edge. - * 1: Latch data on the second SSCK edge. - * - * bit[4:2] - * 000b: 1/2 clk_sspi - * 001b: 1/4 clk_sspi - * 010b: 1/6 clk_sspi - * 011b: 1/8 clk_sspi - * 100b: 1/10 clk_sspi - * 101b: 1/12 clk_sspi - * 110b: 1/14 clk_sspi - * 111b: 1/16 clk_sspi - * - * SSCK frequency is [freq] MHz and mode 3. - * note, clk_sspi need equal to 48MHz above. - */ - IT83XX_SSPI_SPICTRL1 |= (0x60 | (freq << 2)); -} - -static void sspi_transmission_end(void) -{ - /* Write 1 to end the SPI transmission. */ - IT83XX_SSPI_SPISTS = 0x20; - - /* Short delay for "Transfer End Flag" */ - IT83XX_GCTRL_WNCKR = 0; - - /* Write 1 to clear this bit and terminate data transmission. */ - IT83XX_SSPI_SPISTS = 0x02; -} - -/* We assume only one SPI port in the chip, one SPI device */ -int spi_enable(const struct spi_device_t *spi_device, int enable) -{ - int port = spi_device->port; - - if (enable) { - /* - * bit[5:4] - * 00b: SPI channel 0 and channel 1 are disabled. - * 10b: SSCK/SMOSI/SMISO/SSCE1# are enabled. - * 01b: SSCK/SMOSI/SMISO/SSCE0# are enabled. - * 11b: SSCK/SMOSI/SMISO/SSCE1#/SSCE0# are enabled. - */ - if (port == SSPI_CH_CS1) - IT83XX_GPIO_GRC1 |= 0x20; - else - IT83XX_GPIO_GRC1 |= 0x10; - - gpio_config_module(MODULE_SPI_CONTROLLER, 1); - } else { - if (port == SSPI_CH_CS1) - IT83XX_GPIO_GRC1 &= ~0x20; - else - IT83XX_GPIO_GRC1 &= ~0x10; - - gpio_config_module(MODULE_SPI_CONTROLLER, 0); - } - - return EC_SUCCESS; -} - -int spi_transaction(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - int idx; - uint8_t port = spi_device->port; - static struct mutex spi_mutex; - - mutex_lock(&spi_mutex); - /* bit[0]: Write cycle */ - IT83XX_SSPI_SPICTRL2 &= ~0x04; - for (idx = 0x00; idx < txlen; idx++) { - IT83XX_SSPI_SPIDATA = txdata[idx]; - if (port == SSPI_CH_CS1) - /* Write 1 to start the data transmission of CS1 */ - IT83XX_SSPI_SPISTS |= 0x08; - else - /* Write 1 to start the data transmission of CS0 */ - IT83XX_SSPI_SPISTS |= 0x10; - } - - /* bit[1]: Read cycle */ - IT83XX_SSPI_SPICTRL2 |= 0x04; - for (idx = 0x00; idx < rxlen; idx++) { - if (port == SSPI_CH_CS1) - /* Write 1 to start the data transmission of CS1 */ - IT83XX_SSPI_SPISTS |= 0x08; - else - /* Write 1 to start the data transmission of CS0 */ - IT83XX_SSPI_SPISTS |= 0x10; - rxdata[idx] = IT83XX_SSPI_SPIDATA; - } - - sspi_transmission_end(); - mutex_unlock(&spi_mutex); - - return EC_SUCCESS; -} - -static void sspi_init(void) -{ - int i; - - clock_enable_peripheral(CGC_OFFSET_SSPI, 0, 0); - sspi_frequency(sspi_clk_8mhz); - - /* - * bit[5:3] Byte Width (BYTEWIDTH) - * 000b: 8-bit transmission - * 001b: 1-bit transmission - * 010b: 2-bit transmission - * 011b: 3-bit transmission - * 100b: 4-bit transmission - * 101b: 5-bit transmission - * 110b: 6-bit transmission - * 111b: 7-bit transmission - * - * bit[1] Blocking selection - */ - IT83XX_SSPI_SPICTRL2 |= 0x02; - - for (i = 0; i < spi_devices_used; i++) - /* Disabling spi module */ - spi_enable(&spi_devices[i], 0); -} -DECLARE_HOOK(HOOK_INIT, sspi_init, HOOK_PRIO_INIT_SPI); diff --git a/chip/it83xx/system.c b/chip/it83xx/system.c deleted file mode 100644 index 16871e5826..0000000000 --- a/chip/it83xx/system.c +++ /dev/null @@ -1,475 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* System module for Chrome EC : hardware specific implementation */ - -#include "console.h" -#include "cpu.h" -#include "cros_version.h" -#include "ec2i_chip.h" -#include "flash.h" -#include "hooks.h" -#include "host_command.h" -#include "intc.h" -#include "link_defs.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "util.h" -#include "watchdog.h" - -void system_hibernate(uint32_t seconds, uint32_t microseconds) -{ -#ifdef CONFIG_HOSTCMD_PD - /* Inform the PD MCU that we are going to hibernate. */ - host_command_pd_request_hibernate(); - /* Wait to ensure exchange with PD before hibernating. */ - msleep(100); -#endif - - /* Flush console before hibernating */ - cflush(); - - if (board_hibernate) - board_hibernate(); - - /* chip specific standby mode */ - __enter_hibernate(seconds, microseconds); -} - -/* Clear reset flags if it's not cleared in check_reset_cause() */ -static int delayed_clear_reset_flags; -static void clear_reset_flags(void) -{ - if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON) && - delayed_clear_reset_flags) { - chip_save_reset_flags(0); - } -} -DECLARE_HOOK(HOOK_INIT, clear_reset_flags, HOOK_PRIO_LAST); - -#if !defined(CONFIG_HOSTCMD_LPC) && !defined(CONFIG_HOSTCMD_ESPI) -static void system_save_panic_data_to_bram(void) -{ - uint8_t *ptr = (uint8_t *)PANIC_DATA_PTR; - - for (int i = 0; i < CONFIG_PANIC_DATA_SIZE; i++) - IT83XX_BRAM_BANK0(i + BRAM_PANIC_DATA_START) = ptr[i]; -} - -static void system_restore_panic_data_from_bram(void) -{ - uint8_t *ptr = (uint8_t *)PANIC_DATA_PTR; - - for (int i = 0; i < CONFIG_PANIC_DATA_SIZE; i++) - ptr[i] = IT83XX_BRAM_BANK0(i + BRAM_PANIC_DATA_START); -} -BUILD_ASSERT(BRAM_PANIC_LEN >= CONFIG_PANIC_DATA_SIZE); -#else -static void system_save_panic_data_to_bram(void) {} -static void system_restore_panic_data_from_bram(void) {} -#endif - -static void system_reset_ec_by_gpg1(void) -{ - system_save_panic_data_to_bram(); - /* Set GPG1 as output high and wait until EC reset. */ - IT83XX_GPIO_CTRL(GPIO_G, 1) = GPCR_PORT_PIN_MODE_OUTPUT; - IT83XX_GPIO_DATA(GPIO_G) |= BIT(1); - while (1) - ; -} - -static void check_reset_cause(void) -{ - uint32_t flags; - uint8_t raw_reset_cause = IT83XX_GCTRL_RSTS & 0x03; - uint8_t raw_reset_cause2 = IT83XX_GCTRL_SPCTRL4 & 0x07; - - /* Restore saved reset flags. */ - flags = chip_read_reset_flags(); - - /* Clear reset cause. */ - IT83XX_GCTRL_RSTS |= 0x03; - IT83XX_GCTRL_SPCTRL4 |= 0x07; - - /* Determine if watchdog reset or power on reset. */ - if (raw_reset_cause & 0x02) { - flags |= EC_RESET_FLAG_WATCHDOG; - if (IS_ENABLED(CONFIG_IT83XX_HARD_RESET_BY_GPG1)) { - /* - * Save watchdog reset flag to BRAM so we can restore - * the flag on next reboot. - */ - chip_save_reset_flags(EC_RESET_FLAG_WATCHDOG); - /* - * Assert GPG1 to reset EC and then EC_RST_ODL will be - * toggled. - */ - system_reset_ec_by_gpg1(); - } - } else if (raw_reset_cause & 0x01) { - flags |= EC_RESET_FLAG_POWER_ON; - } else { - if ((IT83XX_GCTRL_RSTS & 0xC0) == 0x80) - flags |= EC_RESET_FLAG_POWER_ON; - } - - if (raw_reset_cause2 & 0x04) - flags |= EC_RESET_FLAG_RESET_PIN; - - /* watchdog module triggers these reset */ - if (flags & (EC_RESET_FLAG_HARD | EC_RESET_FLAG_SOFT)) - flags &= ~EC_RESET_FLAG_WATCHDOG; - - /* - * On power-on of some boards, H1 releases the EC from reset but then - * quickly asserts and releases the reset a second time. This means the - * EC sees 2 resets. In order to carry over some important flags (e.g. - * HIBERNATE) to the second resets, the reset flag will not be wiped if - * we know this is the first reset. - */ - if (IS_ENABLED(CONFIG_BOARD_RESET_AFTER_POWER_ON) && - (flags & EC_RESET_FLAG_POWER_ON)) { - if (flags & EC_RESET_FLAG_INITIAL_PWR) { - /* Second boot, clear the flag immediately */ - chip_save_reset_flags(0); - } else { - /* - * First boot, Keep current flags and set INITIAL_PWR - * flag. EC reset should happen soon. - * - * It's possible that H1 never trigger EC reset, or - * reset happens before this line. Both cases should be - * fine because we will have the correct flag anyway. - */ - chip_save_reset_flags(chip_read_reset_flags() | - EC_RESET_FLAG_INITIAL_PWR); - - /* - * Schedule chip_save_reset_flags(0) later. - * Wait until end of HOOK_INIT should be long enough. - */ - delayed_clear_reset_flags = 1; - } - } else { - /* Clear saved reset flags. */ - chip_save_reset_flags(0); - } - - system_set_reset_flags(flags); - - /* Clear PD contract recorded in bram if this is a power-on reset. */ - if (IS_ENABLED(CONFIG_IT83XX_RESET_PD_CONTRACT_IN_BRAM) && - (flags == (EC_RESET_FLAG_POWER_ON | EC_RESET_FLAG_RESET_PIN))) { - for (int i = 0; i < MAX_SYSTEM_BBRAM_IDX_PD_PORTS; i++) - system_set_bbram((SYSTEM_BBRAM_IDX_PD0 + i), 0); - } - - if ((IS_ENABLED(CONFIG_IT83XX_HARD_RESET_BY_GPG1)) && - (flags & ~(EC_RESET_FLAG_POWER_ON | EC_RESET_FLAG_RESET_PIN))) - system_restore_panic_data_from_bram(); -} - -static void system_reset_cause_is_unknown(void) -{ - /* No reset cause and not sysjump. */ - if (!system_get_reset_flags() && !system_jumped_to_this_image()) - /* - * We decrease 4 or 2 for "ec_reset_lp" here, that depend on - * which jump and link instruction has executed. - * eg: Andes core (jral5: LP=PC+2, jal: LP=PC+4) - */ - ccprintf("===Unknown reset! jump from %x or %x===\n", - ec_reset_lp - 4, ec_reset_lp - 2); -} -DECLARE_HOOK(HOOK_INIT, system_reset_cause_is_unknown, HOOK_PRIO_FIRST); - -int system_is_reboot_warm(void) -{ - uint32_t reset_flags; - /* - * Check reset cause here, - * gpio_pre_init is executed faster than system_pre_init - */ - check_reset_cause(); - reset_flags = system_get_reset_flags(); - - if ((reset_flags & EC_RESET_FLAG_RESET_PIN) || - (reset_flags & EC_RESET_FLAG_POWER_ON) || - (reset_flags & EC_RESET_FLAG_WATCHDOG) || - (reset_flags & EC_RESET_FLAG_HARD) || - (reset_flags & EC_RESET_FLAG_SOFT) || - (reset_flags & EC_RESET_FLAG_HIBERNATE)) - return 0; - else - return 1; -} - -void chip_pre_init(void) -{ - /* bit1=0: disable pre-defined command */ - IT83XX_SMB_SFFCTL &= ~IT83XX_SMB_HSAPE; - - /* bit0, EC received the special waveform from iteflash */ - if (IT83XX_GCTRL_DBGROS & IT83XX_SMB_DBGR) { - /* - * Wait ~200ms, so iteflash will have enough time to let - * EC enter follow mode. And once EC goes into follow mode, EC - * will be stayed here (no following sequences, eg: - * enable watchdog/write protect/power-on sequence...) until - * we reset it. - */ - for (int i = 0; i < (200 * MSEC / 15); i++) - /* delay ~15.25us */ - IT83XX_GCTRL_WNCKR = 0; - } - - if (IS_ENABLED(IT83XX_ETWD_HW_RESET_SUPPORT)) - /* System triggers a soft reset by default (command: reboot). */ - IT83XX_GCTRL_ETWDUARTCR &= ~ETWD_HW_RST_EN; - - if (IS_ENABLED(IT83XX_RISCV_WAKEUP_CPU_WITHOUT_INT_ENABLED)) - /* - * bit7: wake up CPU if it is in low power mode and - * an interrupt is pending. - */ - IT83XX_GCTRL_WMCR |= BIT(7); -} - -#define BRAM_VALID_MAGIC 0x4252414D /* "BRAM" */ -#define BRAM_VALID_MAGIC_FIELD0 (BRAM_VALID_MAGIC & 0xff) -#define BRAM_VALID_MAGIC_FIELD1 ((BRAM_VALID_MAGIC >> 8) & 0xff) -#define BRAM_VALID_MAGIC_FIELD2 ((BRAM_VALID_MAGIC >> 16) & 0xff) -#define BRAM_VALID_MAGIC_FIELD3 ((BRAM_VALID_MAGIC >> 24) & 0xff) -void chip_bram_valid(void) -{ - int i; - - if ((BRAM_VALID_FLAGS0 != BRAM_VALID_MAGIC_FIELD0) || - (BRAM_VALID_FLAGS1 != BRAM_VALID_MAGIC_FIELD1) || - (BRAM_VALID_FLAGS2 != BRAM_VALID_MAGIC_FIELD2) || - (BRAM_VALID_FLAGS3 != BRAM_VALID_MAGIC_FIELD3)) { - /* - * Magic does not match, so BRAM must be uninitialized. Clear - * entire Bank0 BRAM, and set magic value. - */ - for (i = 0; i < BRAM_IDX_VALID_FLAGS0; i++) - IT83XX_BRAM_BANK0(i) = 0; - - BRAM_VALID_FLAGS0 = BRAM_VALID_MAGIC_FIELD0; - BRAM_VALID_FLAGS1 = BRAM_VALID_MAGIC_FIELD1; - BRAM_VALID_FLAGS2 = BRAM_VALID_MAGIC_FIELD2; - BRAM_VALID_FLAGS3 = BRAM_VALID_MAGIC_FIELD3; - } - -#if defined(CONFIG_PRESERVE_LOGS) && defined(CONFIG_IT83XX_HARD_RESET_BY_GPG1) - if (BRAM_EC_LOG_STATUS == EC_LOG_SAVED_IN_FLASH) { - /* Restore EC logs from flash. */ - memcpy((void *)__preserved_logs_start, - (const void *)CHIP_FLASH_PRESERVE_LOGS_BASE, - (uintptr_t)__preserved_logs_size); - } - BRAM_EC_LOG_STATUS = 0; -#endif -} - -void system_pre_init(void) -{ - /* No initialization required */ - -} - -uint32_t chip_read_reset_flags(void) -{ - uint32_t flags = 0; - flags |= BRAM_RESET_FLAGS0 << 24; - flags |= BRAM_RESET_FLAGS1 << 16; - flags |= BRAM_RESET_FLAGS2 << 8; - flags |= BRAM_RESET_FLAGS3; - return flags; -} - -void chip_save_reset_flags(uint32_t save_flags) -{ - BRAM_RESET_FLAGS0 = save_flags >> 24; - BRAM_RESET_FLAGS1 = (save_flags >> 16) & 0xff; - BRAM_RESET_FLAGS2 = (save_flags >> 8) & 0xff; - BRAM_RESET_FLAGS3 = save_flags & 0xff; -} - -void system_reset(int flags) -{ - uint32_t save_flags = 0; - - /* We never get this warning message in normal case. */ - if (IT83XX_GCTRL_DBGROS & IT83XX_SMB_DBGR) { - ccprintf("!Reset will be failed due to EC is in debug mode!\n"); - cflush(); - } - -#if defined(CONFIG_PRESERVE_LOGS) && defined(CONFIG_IT83XX_HARD_RESET_BY_GPG1) - /* Saving EC logs into flash before reset. */ - crec_flash_physical_erase(CHIP_FLASH_PRESERVE_LOGS_BASE, - CHIP_FLASH_PRESERVE_LOGS_SIZE); - crec_flash_physical_write(CHIP_FLASH_PRESERVE_LOGS_BASE, - (uintptr_t)__preserved_logs_size, __preserved_logs_start); - BRAM_EC_LOG_STATUS = EC_LOG_SAVED_IN_FLASH; -#endif - - /* Disable interrupts to avoid task swaps during reboot. */ - interrupt_disable(); - - /* Handle saving common reset flags. */ - system_encode_save_flags(flags, &save_flags); - - if (clock_ec_wake_from_sleep()) - save_flags |= EC_RESET_FLAG_HIBERNATE; - - /* Store flags to battery backed RAM. */ - chip_save_reset_flags(save_flags); - - /* If WAIT_EXT is set, then allow 10 seconds for external reset */ - if (flags & SYSTEM_RESET_WAIT_EXT) { - int i; - - /* Wait 10 seconds for external reset */ - for (i = 0; i < 1000; i++) { - watchdog_reload(); - udelay(10000); - } - } - - /* bit0: enable watchdog hardware reset. */ -#ifdef IT83XX_ETWD_HW_RESET_SUPPORT - if (flags & SYSTEM_RESET_HARD) - IT83XX_GCTRL_ETWDUARTCR |= ETWD_HW_RST_EN; -#endif - /* Set GPG1 as output high and wait until EC reset. */ - if (IS_ENABLED(CONFIG_IT83XX_HARD_RESET_BY_GPG1)) - system_reset_ec_by_gpg1(); - - /* - * Writing invalid key to watchdog module triggers a soft or hardware - * reset. It depends on the setting of bit0 at ETWDUARTCR register. - */ - IT83XX_ETWD_ETWCFG |= 0x20; - IT83XX_ETWD_EWDKEYR = 0x00; - - /* Spin and wait for reboot; should never return */ - while (1) - ; -} - -int system_set_scratchpad(uint32_t value) -{ - BRAM_SCRATCHPAD3 = (value >> 24) & 0xff; - BRAM_SCRATCHPAD2 = (value >> 16) & 0xff; - BRAM_SCRATCHPAD1 = (value >> 8) & 0xff; - BRAM_SCRATCHPAD0 = value & 0xff; - - return EC_SUCCESS; -} - -int system_get_scratchpad(uint32_t *value) -{ - *value = (BRAM_SCRATCHPAD3 << 24) | (BRAM_SCRATCHPAD2 << 16) | - (BRAM_SCRATCHPAD1 << 8) | (BRAM_SCRATCHPAD0); - return EC_SUCCESS; -} - -static uint32_t system_get_chip_id(void) -{ -#ifdef IT83XX_CHIP_ID_3BYTES - return (IT83XX_GCTRL_CHIPID1 << 16) | (IT83XX_GCTRL_CHIPID2 << 8) | - IT83XX_GCTRL_CHIPID3; -#else - return (IT83XX_GCTRL_CHIPID1 << 8) | IT83XX_GCTRL_CHIPID2; -#endif -} - -static uint8_t system_get_chip_version(void) -{ - /* bit[3-0], chip version */ - return IT83XX_GCTRL_CHIPVER & 0x0F; -} - -static char to_hex(int x) -{ - if (x >= 0 && x <= 9) - return '0' + x; - return 'a' + x - 10; -} - -const char *system_get_chip_vendor(void) -{ - return "ite"; -} - -const char *system_get_chip_name(void) -{ - static char buf[8] = {'i', 't'}; - int num = (IS_ENABLED(IT83XX_CHIP_ID_3BYTES) ? 4 : 3); - uint32_t chip_id = system_get_chip_id(); - - for (int n = 2; num >= 0; n++, num--) - buf[n] = to_hex(chip_id >> (num * 4) & 0xF); - - return buf; -} - -const char *system_get_chip_revision(void) -{ - static char buf[3]; - uint8_t rev = system_get_chip_version(); - - buf[0] = to_hex(rev + 0xa); - buf[1] = 'x'; - buf[2] = '\0'; - return buf; -} - -static int bram_idx_lookup(enum system_bbram_idx idx) -{ - if (idx == SYSTEM_BBRAM_IDX_PD0) - return BRAM_IDX_PD0; - if (idx == SYSTEM_BBRAM_IDX_PD1) - return BRAM_IDX_PD1; - if (idx == SYSTEM_BBRAM_IDX_PD2) - return BRAM_IDX_PD2; - return -1; -} - -int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) -{ - int bram_idx = bram_idx_lookup(idx); - - if (bram_idx < 0) - return EC_ERROR_INVAL; - - *value = IT83XX_BRAM_BANK0(bram_idx); - return EC_SUCCESS; -} - -int system_set_bbram(enum system_bbram_idx idx, uint8_t value) -{ - int bram_idx = bram_idx_lookup(idx); - - if (bram_idx < 0) - return EC_ERROR_INVAL; - - IT83XX_BRAM_BANK0(bram_idx) = value; - return EC_SUCCESS; -} - -uintptr_t system_get_fw_reset_vector(uintptr_t base) -{ - /* - * Because our reset vector is at the beginning of image copy - * (see init.S). So I just need to return 'base' here and EC will jump - * to the reset vector. - */ - return base; -} diff --git a/chip/it83xx/uart.c b/chip/it83xx/uart.c deleted file mode 100644 index d0b645e68c..0000000000 --- a/chip/it83xx/uart.c +++ /dev/null @@ -1,247 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* UART module for Chrome EC */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "intc.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "uart.h" -#include "util.h" - -/* Traces on UART1 */ -#define UART_PORT 0 -#define UART_PORT_HOST 1 - -static int init_done; - -int uart_init_done(void) -{ - return init_done; -} - -void uart_tx_start(void) -{ - /* If interrupt is already enabled, nothing to do */ - if (IT83XX_UART_IER(UART_PORT) & 0x02) - return; - - /* Do not allow deep sleep while transmit in progress */ - disable_sleep(SLEEP_MASK_UART); - - /* Re-enable the transmit interrupt. */ - IT83XX_UART_IER(UART_PORT) |= 0x02; -} - -void uart_tx_stop(void) -{ - IT83XX_UART_IER(UART_PORT) &= ~0x02; - - /* Re-allow deep sleep */ - enable_sleep(SLEEP_MASK_UART); -} - -void uart_tx_flush(void) -{ - /* - * Wait for transmit FIFO empty (TEMT) and transmitter holder - * register and transmitter shift registers to be empty (THRE). - */ - while ((IT83XX_UART_LSR(UART_PORT) & 0x60) != 0x60) - ; -} - -int uart_tx_ready(void) -{ - /* Transmit is ready when FIFO is empty (THRE). */ - return IT83XX_UART_LSR(UART_PORT) & 0x20; -} - -int uart_tx_in_progress(void) -{ - /* - * Transmit is in progress if transmit holding register or transmitter - * shift register are not empty (TEMT). - */ - return !(IT83XX_UART_LSR(UART_PORT) & 0x40); -} - -int uart_rx_available(void) -{ - return IT83XX_UART_LSR(UART_PORT) & 0x01; -} - -void uart_write_char(char c) -{ - /* Wait for space in transmit FIFO. */ - while (!uart_tx_ready()) - ; - - IT83XX_UART_THR(UART_PORT) = c; -} - -int uart_read_char(void) -{ - return IT83XX_UART_RBR(UART_PORT); -} - -static void uart_ec_interrupt(void) -{ - uint8_t uart_ier; - - /* clear interrupt status */ - task_clear_pending_irq(IT83XX_IRQ_UART1); - - /* Read input FIFO until empty, then fill output FIFO */ - uart_process_input(); - uart_process_output(); - - uart_ier = IT83XX_UART_IER(UART_PORT); - IT83XX_UART_IER(UART_PORT) = 0; - IT83XX_UART_IER(UART_PORT) = uart_ier; -} - -static void intc_cpu_int_group_9(void) -{ - /* Determine interrupt number. */ - int intc_group_9 = intc_get_ec_int(); - - switch (intc_group_9) { - case IT83XX_IRQ_UART1: - uart_ec_interrupt(); - break; - default: - break; - } -} -DECLARE_IRQ(CPU_INT_GROUP_9, intc_cpu_int_group_9, 1); - -static void uart_config(void) -{ - /* - * Specify clock source of the UART is 24MHz, - * must match CLK_UART_DIV_SEL. - */ - IT83XX_UART_CSSR(UART_PORT) = 0x01; - - /* 8-N-1 and DLAB set to allow access to DLL and DLM registers. */ - IT83XX_UART_LCR(UART_PORT) = 0x83; - - /* Set divisor to set baud rate to 115200 */ - IT83XX_UART_DLM(UART_PORT) = 0x00; - IT83XX_UART_DLL(UART_PORT) = 0x01; - - /* - * Clear DLAB bit to exclude access to DLL and DLM and give access to - * RBR and THR. - */ - IT83XX_UART_LCR(UART_PORT) = 0x03; - - /* - * Enable TX and RX FIFOs and set RX FIFO interrupt level to the - * minimum 1 byte. - */ - IT83XX_UART_FCR(UART_PORT) = 0x07; - - /* - * set OUT2 bit to enable interrupt logic. - */ - IT83XX_UART_MCR(UART_PORT) = 0x08; -} - -#ifdef CONFIG_UART_HOST -static void host_uart_config(void) -{ - /* - * Specify clock source of the UART is 24MHz, - * must match CLK_UART_DIV_SEL. - */ - IT83XX_UART_CSSR(UART_PORT_HOST) = 0x01; - /* 8-N-1 and DLAB set to allow access to DLL and DLM registers. */ - IT83XX_UART_LCR(UART_PORT_HOST) = 0x83; - /* Set divisor to set baud rate to 115200 */ - IT83XX_UART_DLM(UART_PORT_HOST) = 0x00; - IT83XX_UART_DLL(UART_PORT_HOST) = 0x01; - /* - * Clear DLAB bit to exclude access to DLL and DLM and give access to - * RBR and THR. - */ - IT83XX_UART_LCR(UART_PORT_HOST) = 0x03; - /* - * Enable TX and RX FIFOs and set RX FIFO interrupt level to the - * minimum 1 byte. - */ - IT83XX_UART_FCR(UART_PORT_HOST) = 0x07; -} -#endif - -#ifdef CONFIG_LOW_POWER_IDLE -void uart_enter_dsleep(void) -{ - gpio_clear_pending_interrupt(GPIO_UART1_RX); - gpio_enable_interrupt(GPIO_UART1_RX); -} - -void uart_exit_dsleep(void) -{ - gpio_disable_interrupt(GPIO_UART1_RX); - gpio_clear_pending_interrupt(GPIO_UART1_RX); -} - -void uart_deepsleep_interrupt(enum gpio_signal signal) -{ - clock_refresh_console_in_use(); - /* Disable interrupts on UART1 RX pin to avoid repeated interrupts. */ - gpio_disable_interrupt(GPIO_UART1_RX); -} -#endif /* CONFIG_LOW_POWER_IDLE */ - -void uart_init(void) -{ - /* - * bit3: uart1 belongs to the EC side. - * This is necessary for enabling eSPI module. - */ - IT83XX_GCTRL_RSTDMMC |= BIT(3); - - /* reset uart before config it */ - IT83XX_GCTRL_RSTC4 |= BIT(1); - - /* Waiting for when we can use the GPIO module to set pin muxing */ - gpio_config_module(MODULE_UART, 1); - - /* switch UART1 on without hardware flow control */ - IT83XX_GPIO_GRC1 |= 0x01; - IT83XX_GPIO_GRC6 |= 0x03; - - /* Enable clocks to UART 1 and 2. */ - clock_enable_peripheral(CGC_OFFSET_UART, 0, 0); - - /* Config UART 1 */ - uart_config(); - -#ifdef CONFIG_UART_HOST - /* bit2, reset UART2 */ - IT83XX_GCTRL_RSTC4 |= BIT(2); - /* SIN1/SOUT1 of UART 2 is enabled. */ - IT83XX_GPIO_GRC1 |= BIT(2); - /* Config UART 2 */ - host_uart_config(); -#endif - - /* clear interrupt status */ - task_clear_pending_irq(IT83XX_IRQ_UART1); - - /* Enable interrupts */ - IT83XX_UART_IER(UART_PORT) = 0x03; - task_enable_irq(IT83XX_IRQ_UART1); - - init_done = 1; -} diff --git a/chip/it83xx/watchdog.c b/chip/it83xx/watchdog.c deleted file mode 100644 index f0e200c4ac..0000000000 --- a/chip/it83xx/watchdog.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Watchdog driver */ - -#include "common.h" -#include "cpu.h" -#include "hooks.h" -#include "hwtimer_chip.h" -#include "panic.h" -#include "registers.h" -#include "task.h" -#include "watchdog.h" - -/* Enter critical period or not. */ -static int wdt_warning_fired; - -/* - * We use WDT_EXT_TIMER to trigger an interrupt just before the watchdog timer - * will fire so that we can capture important state information before - * being reset. - */ - -/* Magic value to tickle the watchdog register. */ -#define ITE83XX_WATCHDOG_MAGIC_WORD 0x5C -/* Start to print warning message. */ -#define ITE83XX_WATCHDOG_WARNING_MS CONFIG_AUX_TIMER_PERIOD_MS -/* The interval to print warning message at critical period. */ -#define ITE83XX_WATCHDOG_CRITICAL_MS 30 - -/* set warning timer */ -static void watchdog_set_warning_timer(int32_t ms, int init) -{ - ext_timer_ms(WDT_EXT_TIMER, EXT_PSR_32P768K_HZ, 1, 1, ms, init, 0); -} - -void watchdog_warning_irq(void) -{ -#ifdef CONFIG_SOFTWARE_PANIC - struct panic_data * const pdata_ptr = get_panic_data_write(); - -#if defined(CHIP_CORE_NDS32) - pdata_ptr->nds_n8.ipc = get_ipc(); -#elif defined(CHIP_CORE_RISCV) - pdata_ptr->riscv.mepc = get_mepc(); -#endif -#endif - /* clear interrupt status */ - task_clear_pending_irq(et_ctrl_regs[WDT_EXT_TIMER].irq); - - /* Reset warning timer. */ - IT83XX_ETWD_ETXCTRL(WDT_EXT_TIMER) = 0x03; - -#if defined(CHIP_CORE_NDS32) - /* - * The IPC (Interruption Program Counter) is the shadow stack register - * of the PC (Program Counter). It stores the return address of program - * (PC->IPC) when the ISR was called. - * - * The LP (Link Pointer) stores the program address of the next - * sequential instruction for function call return purposes. - * LP = PC+4 after a jump and link instruction (jal). - */ - panic_printf("Pre-WDT warning! IPC:%08x LP:%08x TASK_ID:%d\n", - get_ipc(), ilp, task_get_current()); -#elif defined(CHIP_CORE_RISCV) - panic_printf("Pre-WDT warning! MEPC:%08x RA:%08x TASK_ID:%d\n", - get_mepc(), ira, task_get_current()); -#endif - - if (!wdt_warning_fired++) - /* - * Reduce interval of warning timer, so we can print more - * warning messages during critical period. - */ - watchdog_set_warning_timer(ITE83XX_WATCHDOG_CRITICAL_MS, 0); -} - -void watchdog_reload(void) -{ - /* Reset warning timer. */ - IT83XX_ETWD_ETXCTRL(WDT_EXT_TIMER) = 0x03; - - /* Restart (tickle) watchdog timer. */ - IT83XX_ETWD_EWDKEYR = ITE83XX_WATCHDOG_MAGIC_WORD; - - if (wdt_warning_fired) { - wdt_warning_fired = 0; - /* Reset warning timer to default if watchdog is touched. */ - watchdog_set_warning_timer(ITE83XX_WATCHDOG_WARNING_MS, 0); - } -} -DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); - -int watchdog_init(void) -{ - uint16_t wdt_count = CONFIG_WATCHDOG_PERIOD_MS * 1024 / 1000; - - /* Unlock access to watchdog registers. */ - IT83XX_ETWD_ETWCFG = 0x00; - - /* Set WD timer to use 1.024kHz clock. */ - IT83XX_ETWD_ET1PSR = 0x01; - - /* Set WDT key match enabled and WDT clock to use ET1PSR. */ - IT83XX_ETWD_ETWCFG = 0x30; - -#ifdef CONFIG_HIBERNATE - /* bit4: watchdog can be stopped. */ - IT83XX_ETWD_ETWCTRL |= BIT(4); -#else - /* Specify that watchdog cannot be stopped. */ - IT83XX_ETWD_ETWCTRL = 0x00; -#endif - - /* Start WDT_EXT_TIMER (CONFIG_AUX_TIMER_PERIOD_MS ms). */ - watchdog_set_warning_timer(ITE83XX_WATCHDOG_WARNING_MS, 1); - - /* Start timer 1 (must be started for watchdog timer to run). */ - IT83XX_ETWD_ET1CNTLLR = 0x00; - - /* - * Set watchdog timer to CONFIG_WATCHDOG_PERIOD_MS ms. - * Writing CNTLL starts timer. - */ - IT83XX_ETWD_EWDCNTLHR = (wdt_count >> 8) & 0xff; - IT83XX_ETWD_EWDCNTLLR = wdt_count & 0xff; - - /* Lock access to watchdog registers. */ - IT83XX_ETWD_ETWCFG = 0x3f; - - return EC_SUCCESS; -} |