diff options
Diffstat (limited to 'chip/mchp')
47 files changed, 0 insertions, 18341 deletions
diff --git a/chip/mchp/adc.c b/chip/mchp/adc.c deleted file mode 100644 index d40a8a9d1c..0000000000 --- a/chip/mchp/adc.c +++ /dev/null @@ -1,157 +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 "adc.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "tfdp_chip.h" - -/* - * Conversion on a single channel takes less than 12 ms. Set timeout to - * 15 ms so that we have a 3-ms margin. - */ -#define ADC_SINGLE_READ_TIME 15000 - -struct mutex adc_lock; - -/* - * Volatile should not be needed. - * ADC ISR only reads task_waiting. - * Two other non-ISR routines only write task_waiting when - * interrupt is disabled or before starting ADC. - */ -static task_id_t task_waiting; - -/* - * Start ADC single-shot conversion. - * 1. Disable ADC interrupt. - * 2. Clear sticky hardware status. - * 3. Start conversion. - * 4. Enable interrupt. - * 5. Wait with timeout for ADC ISR to - * to set TASK_EVENT_TIMER. - */ -static int start_single_and_wait(int timeout) -{ - int event; - - MCHP_INT_DISABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - task_waiting = task_get_current(); - - /* clear all R/W1C channel status */ - MCHP_ADC_STS = 0xffffu; - /* clear R/W1C single done status */ - MCHP_ADC_CTRL |= BIT(7); - /* clear GIRQ single status */ - MCHP_INT_SOURCE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - /* make sure all writes are issued before starting conversion */ - asm volatile ("dsb"); - - /* Start conversion */ - MCHP_ADC_CTRL |= BIT(1); - - MCHP_INT_ENABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - - /* Wait for interrupt, ISR disables interrupt */ - event = task_wait_event(timeout); - task_waiting = TASK_ID_INVALID; - return event != TASK_EVENT_TIMER; -} - -int adc_read_channel(enum adc_channel ch) -{ - const struct adc_t *adc = adc_channels + ch; - int value; - - mutex_lock(&adc_lock); - - MCHP_ADC_SINGLE = 1 << adc->channel; - - if (start_single_and_wait(ADC_SINGLE_READ_TIME)) - value = (MCHP_ADC_READ(adc->channel) * adc->factor_mul) / - adc->factor_div + adc->shift; - else - value = ADC_READ_ERROR; - - mutex_unlock(&adc_lock); - return value; -} - -int adc_read_all_channels(int *data) -{ - int i; - int ret = EC_SUCCESS; - const struct adc_t *adc; - - mutex_lock(&adc_lock); - - MCHP_ADC_SINGLE = 0; - for (i = 0; i < ADC_CH_COUNT; ++i) - MCHP_ADC_SINGLE |= 1 << adc_channels[i].channel; - - if (!start_single_and_wait(ADC_SINGLE_READ_TIME * ADC_CH_COUNT)) { - ret = EC_ERROR_TIMEOUT; - goto exit_all_channels; - } - - for (i = 0; i < ADC_CH_COUNT; ++i) { - adc = adc_channels + i; - data[i] = (MCHP_ADC_READ(adc->channel) * adc->factor_mul) / - adc->factor_div + adc->shift; - } - -exit_all_channels: - mutex_unlock(&adc_lock); - - return ret; -} - -/* - * Enable GPIO pins. - * Using MEC17xx direct mode interrupts. Do not - * set Interrupt Aggregator Block Enable bit - * for GIRQ containing ADC. - */ -static void adc_init(void) -{ - trace0(0, ADC, 0, "adc_init"); - - gpio_config_module(MODULE_ADC, 1); - - /* clear ADC sleep enable */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_ADC); - - /* Activate ADC module */ - MCHP_ADC_CTRL |= BIT(0); - - /* Enable interrupt */ - task_waiting = TASK_ID_INVALID; - MCHP_INT_ENABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - task_enable_irq(MCHP_IRQ_ADC_SNGL); -} -DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_INIT_ADC); - -void adc_interrupt(void) -{ - MCHP_INT_DISABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - - /* clear individual chan conversion status */ - MCHP_ADC_STS = 0xffffu; - - /* Clear interrupt status bit */ - MCHP_ADC_CTRL |= BIT(7); - - MCHP_INT_SOURCE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - - if (task_waiting != TASK_ID_INVALID) - task_wake(task_waiting); -} -DECLARE_IRQ(MCHP_IRQ_ADC_SNGL, adc_interrupt, 2); diff --git a/chip/mchp/adc_chip.h b/chip/mchp/adc_chip.h deleted file mode 100644 index 0f14d5a459..0000000000 --- a/chip/mchp/adc_chip.h +++ /dev/null @@ -1,45 +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. - */ - -/* MCHP MEC specific ADC module for Chrome EC */ - -#ifndef __CROS_EC_ADC_CHIP_H -#define __CROS_EC_ADC_CHIP_H - -/* Data structure to define ADC channels. */ -struct adc_t { - const char *name; - int factor_mul; - int factor_div; - int shift; - int channel; -}; - -/* 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_COUNT, -}; - -/* Minimum and maximum values returned by adc_read_channel(). */ -#define ADC_READ_MIN 0 -#ifdef CHIP_FAMILY_MEC172X -/* MEC172x ADC is 12BIT resolution in default */ -#define ADC_READ_MAX 4095 -#else -#define ADC_READ_MAX 1023 -#endif - -/* Just plain id mapping for code readability */ -#define MCHP_ADC_CH(x) (x) - -#endif /* __CROS_EC_ADC_CHIP_H */ diff --git a/chip/mchp/build.mk b/chip/mchp/build.mk deleted file mode 100644 index 155fbf385f..0000000000 --- a/chip/mchp/build.mk +++ /dev/null @@ -1,119 +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. -# -# Microchip(MCHP) MEC chip specific files build -# - -# pass verbose build setting to SPI image generation script -SCRIPTVERBOSE= -ifeq ($(V),1) -SCRIPTVERBOSE=--verbose -endif - -# MCHP MEC SoC's have a Cortex-M4 ARM core -CORE:=cortex-m -# Allow the full Cortex-M4 instruction set -CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4 - -# JTAG debug with Keil ARM MDK debugger -# do not allow GCC dwarf debug extensions -#CFLAGS_DEBUG_EXTRA=-gdwarf-3 -gstrict-dwarf - -LDFLAGS_EXTRA= - -ifeq ($(CONFIG_LTO),y) -# Re-include the core's build.mk file so we can remove the lto flag. -include core/$(CORE)/build.mk -endif - -# Required chip modules -chip-y=clock.o gpio.o hwtimer.o system.o uart.o port80.o tfdp.o -chip-$(CONFIG_ADC)+=adc.o -chip-$(CONFIG_DMA)+=dma.o -chip-$(CONFIG_HOSTCMD_ESPI)+=espi.o -chip-$(CONFIG_FANS)+=fan.o -chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o -chip-$(CONFIG_I2C)+=i2c.o -chip-$(CONFIG_MEC_GPIO_EC_CMDS)+=gpio_cmds.o -chip-$(CONFIG_HOSTCMD_X86)+=lpc.o -chip-$(CONFIG_MCHP_GPSPI)+=gpspi.o -chip-$(CONFIG_PWM)+=pwm.o -chip-$(CONFIG_SPI)+=spi.o qmspi.o -chip-$(CONFIG_TFDP)+=tfdp.o -chip-$(CONFIG_WATCHDOG)+=watchdog.o -ifndef CONFIG_KEYBOARD_NOT_RAW -chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o -endif - -# location of the scripts and keys used to pack the SPI flash image -SCRIPTDIR:=./chip/${CHIP}/util - -# Allow SPI size to be overridden by board specific size, default to 512KB -CHIP_SPI_SIZE_KB?=512 - -TEST_SPI= -ifeq ($(CONFIG_MCHP_LFW_DEBUG),y) - TEST_SPI=--test_spi -endif - -# Select chip. Default is MEC170X -PACK_EC=pack_ec.py -ifeq ($(CHIP_FAMILY),mec152x) - PACK_EC=pack_ec_mec152x.py -endif -ifeq ($(CHIP_FAMILY),mec172x) - PACK_EC=pack_ec_mec172x.py -endif - -# pack_ec.py creates SPI flash image for MEC -# _rw_size is CONFIG_RW_SIZE -# Commands to convert $^ to $@.tmp -cmd_obj_to_bin = $(OBJCOPY) --gap-fill=0xff -O binary $< $@.tmp1 ; \ - ${SCRIPTDIR}/${PACK_EC} -o $@.tmp -i $@.tmp1 \ - --loader_file $(chip-lfw-flat) ${TEST_SPI} \ - --spi_size ${CHIP_SPI_SIZE_KB} \ - --image_size $(_rw_size) ${SCRIPTVERBOSE}; rm -f $@.tmp1 - -chip-lfw = chip/${CHIP}/lfw/ec_lfw -chip-lfw-flat = $(out)/RW/$(chip-lfw)-lfw.flat - -# build these specifically for lfw with -lfw suffix -objs_lfw = $(patsubst %, $(out)/RW/%-lfw.o, \ - $(addprefix common/, util util_stdlib gpio) \ - $(addprefix chip/$(CHIP)/, spi qmspi dma gpio clock hwtimer tfdp) \ - core/$(CORE)/cpu $(chip-lfw)) - -# reuse version.o (and its dependencies) from main board -objs_lfw += $(out)/RW/common/version.o - -dirs-y+=chip/$(CHIP)/lfw - -# objs with -lfw suffix are to include lfw's gpio -$(out)/RW/%-lfw.o: private CC+=-Ichip/mchp/lfw -DLFW=$(EMPTY) -# Remove the lto flag for the loader. It actually causes it to bloat in size. -ifeq ($(CONFIG_LTO),y) -$(out)/RW/%-lfw.o: private CFLAGS_CPU := $(filter-out -flto, $(CFLAGS_CPU)) -endif -$(out)/RW/%-lfw.o: %.c - $(call quiet,c_to_o,CC ) - -# let lfw's elf link only with selected objects -ifeq ($(CHIP_FAMILY),mec172x) -$(out)/RW/%-lfw.elf: private objs = $(objs_lfw) -$(out)/RW/%-lfw.elf: override shlib := -$(out)/RW/%-lfw.elf: %_416kb.ld $(objs_lfw) - $(call quiet,elf,LD ) - -# final image needs lfw loader -$(out)/$(PROJECT).bin: $(chip-lfw-flat) -else -$(out)/RW/%-lfw.elf: private objs = $(objs_lfw) -$(out)/RW/%-lfw.elf: override shlib := -$(out)/RW/%-lfw.elf: %.ld $(objs_lfw) - $(call quiet,elf,LD ) - -# final image needs lfw loader -$(out)/$(PROJECT).bin: $(chip-lfw-flat) -endif diff --git a/chip/mchp/clock.c b/chip/mchp/clock.c deleted file mode 100644 index 362025ee1c..0000000000 --- a/chip/mchp/clock.c +++ /dev/null @@ -1,780 +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. - */ - -/* Clocks and power management settings */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "cpu.h" -#include "hooks.h" -#include "hwtimer.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "registers.h" -#include "shared_mem.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "uart.h" -#include "util.h" -#include "tfdp_chip.h" -#include "vboot_hash.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 HTIMER_DIV_1_US_MAX (1998848) -#define HTIMER_DIV_1_1SEC (0x8012) - -/* Recovery time for HvySlp2 is 0 us */ -#define HEAVY_SLEEP_RECOVER_TIME_USEC 75 - -#define SET_HTIMER_DELAY_USEC 200 - -static int idle_sleep_cnt; -static int idle_dsleep_cnt; -static uint64_t total_idle_dsleep_time_us; - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG -static uint32_t pcr_slp_en[MCHP_PCR_SLP_RST_REG_MAX]; -static uint32_t pcr_clk_req[MCHP_PCR_SLP_RST_REG_MAX]; -static uint32_t ecia_result[MCHP_INT_GIRQ_NUM]; -#endif - -/* - * 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 = 60; -static timestamp_t console_expire_time; -#endif /*CONFIG_LOW_POWER_IDLE */ - -static int freq = 48000000; - -void clock_wait_cycles(uint32_t cycles) -{ - asm volatile("1: subs %0, #1\n" - " bne 1b\n" : "+r"(cycles)); -} - -int clock_get_freq(void) -{ - return freq; -} - -/* - * MEC170x and MEC152x have the same 32 KHz clock enable hardware. - * MEC172x 32 KHz clock configuration is different and includes - * hardware to check the crystal before switching and to monitor - * the 32 KHz input if desired. - */ -#ifdef CHIP_FAMILY_MEC172X -/* 32 KHz crystal connected in parallel */ -static inline void config_32k_src_crystal(void) -{ - MCHP_VBAT_CSS = MCHP_VBAT_CSS_XTAL_EN - | MCHP_VBAT_CSS_SRC_XTAL; -} - -/* 32 KHz source is 32KHZ_IN pin which must be configured */ -static inline void config_32k_src_se_input(void) -{ - MCHP_VBAT_CSS = MCHP_VBAT_CSS_SIL32K_EN - | MCHP_VBAT_CSS_SRC_SWPS; -} - -static inline void config_32k_src_sil_osc(void) -{ - MCHP_VBAT_CSS = MCHP_VBAT_CSS_SIL32K_EN; -} - -#else -static void config_32k_src_crystal(void) -{ - MCHP_VBAT_CE = MCHP_VBAT_CE_XOSEL_PAR - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL; -} - -/* 32 KHz source is 32KHZ_IN pin which must be configured */ -static inline void config_32k_src_se_input(void) -{ - MCHP_VBAT_CE = MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_INT; -} - -static inline void config_32k_src_sil_osc(void) -{ - MCHP_VBAT_CE = ~(MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL); -} -#endif - -/** clock_init - * @note - * MCHP MEC implements 4 control bits in the VBAT Clock Enable register. - * It also implements an internal silicon 32KHz +/- 2% oscillator powered - * by VBAT. - * b[3] = XOSEL 0=parallel, 1=single-ended - * b[2] = 32KHZ_SOURCE specifies source of always-on clock domain - * 0=internal silicon oscillator - * 1=crystal XOSEL pin(s) - * b[1] = EXT_32K use always-on clock domain or external 32KHZ_IN pin - * 0=32K source is always-on clock domain - * 1=32K source is 32KHZ_IN pin (GPIO 0165) - * b[0] = 32K_SUPPRESS - * 0=32K clock domain stays enabled if VTR is off. Powered by VBAT - * 1=32K clock domain is disabled if VTR is off. - * Set b[3] based on CONFIG_CLOCK_CRYSTAL - * Set b[2:0] = 100b - * b[0]=0 32K clock domain always on (requires VBAT if VTR is off) - * b[1]=0 32K source is the 32K clock domain NOT the 32KHZ_IN pin - * b[2]=1 If activity detected on crystal pins switch 32K input from - * internal silicon oscillator to XOSEL pin(s) based on b[3]. - */ -void clock_init(void) -{ - if (IS_ENABLED(CONFIG_CLOCK_SRC_EXTERNAL)) - if (IS_ENABLED(CONFIG_CLOCK_CRYSTAL)) - config_32k_src_crystal(); - else - /* 32KHz 50% duty waveform on 32KHZ_IN pin */ - config_32k_src_se_input(); - else - /* Use internal silicon 32KHz OSC */ - config_32k_src_sil_osc(); - - /* Wait for PLL to lock onto 32KHz source (OSC_LOCK == 1) */ - while (!(MCHP_PCR_CHIP_OSC_ID & 0x100)) - ; -} - -/** - * Speed through boot + vboot hash calculation, dropping our processor - * clock only after vboot hashing is completed. - */ -static void clock_turbo_disable(void); -DECLARE_DEFERRED(clock_turbo_disable); - -static void clock_turbo_disable(void) -{ -#ifdef CONFIG_VBOOT_HASH - if (vboot_hash_in_progress()) - hook_call_deferred(&clock_turbo_disable_data, 100 * MSEC); - else -#endif - /* Use 12 MHz processor clock for power savings */ - MCHP_PCR_PROC_CLK_CTL = MCHP_PCR_CLK_CTL_12MHZ; -} -DECLARE_HOOK(HOOK_INIT, - clock_turbo_disable, - HOOK_PRIO_INIT_VBOOT_HASH + 1); - -/** - * initialization of Hibernation timer 0 - * Clear PCR sleep enable. - * GIRQ=21, aggregator bit = 1, Direct NVIC = 112 - * NVIC direct connect interrupts are used for all peripherals - * (exception GPIO's) then the MCHP_INT_BLK_EN GIRQ bit should not be - * set. - */ -void htimer_init(void) -{ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_HTMR0); - MCHP_HTIMER_PRELOAD(0) = 0; /* disable at beginning */ - MCHP_INT_SOURCE(MCHP_HTIMER_GIRQ) = MCHP_HTIMER_GIRQ_BIT(0); - MCHP_INT_ENABLE(MCHP_HTIMER_GIRQ) = MCHP_HTIMER_GIRQ_BIT(0); - - task_enable_irq(MCHP_IRQ_HTIMER0); -} - -/** - * Use hibernate module to set up an htimer interrupt at a given - * time from now - * - * @param seconds Number of seconds before htimer interrupt - * @param microseconds Number of microseconds before htimer interrupt - * @note hibernation timer input clock is 32.768KHz. - * Control register bit[0] selects the divider. - * 0 is divide by 1 for 30.5 us per LSB for a maximum of - * 65535 * 30.5 us = 1998817.5 us or 32.786 counts per second - * 1 is divide by 4096 for 0.125 s per LSB for a maximum of ~2 hours. - * 65535 * 0.125 s ~ 8192 s = 2.27 hours - */ -void system_set_htimer_alarm(uint32_t seconds, - uint32_t microseconds) -{ - uint32_t hcnt, ns; - uint8_t hctrl; - - MCHP_HTIMER_PRELOAD(0) = 0; /* disable */ - - if (microseconds > 1000000ul) { - ns = (microseconds / 1000000ul); - microseconds %= 1000000ul; - if ((0xfffffffful - seconds) > ns) - seconds += ns; - else - seconds = 0xfffffffful; - } - - if (seconds > 1) { - hcnt = (seconds << 3); /* divide by 0.125 */ - if (hcnt > 0xfffful) - hcnt = 0xfffful; - hctrl = 1; - } else { - /* - * approximate(~2% error) as seconds is 0 or 1 - * seconds / 30.5e-6 + microseconds / 30.5 - */ - hcnt = (seconds << 15) + (microseconds >> 5) + - (microseconds >> 10); - hctrl = 0; - } - - MCHP_HTIMER_CONTROL(0) = hctrl; - MCHP_HTIMER_PRELOAD(0) = hcnt; -} - -#ifdef CONFIG_LOW_POWER_IDLE - -/** - * return time slept in micro-seconds - */ -static timestamp_t system_get_htimer(void) -{ - uint16_t count; - timestamp_t time; - - count = MCHP_HTIMER_COUNT(0); - - - if (MCHP_HTIMER_CONTROL(0) == 1) /* if > 2 sec */ - /* 0.125 sec per count */ - time.le.lo = (uint32_t)(count * 125000); - else /* if < 2 sec */ - /* 30.5(=61/2) us per count */ - time.le.lo = (uint32_t)(count * 61 / 2); - - time.le.hi = 0; - - return time; /* in uSec */ -} - -/** - * Disable and clear hibernation timer interrupt - */ -static void system_reset_htimer_alarm(void) -{ - MCHP_HTIMER_PRELOAD(0) = 0; - MCHP_INT_SOURCE(MCHP_HTIMER_GIRQ) = - MCHP_HTIMER_GIRQ_BIT(0); -} - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG -static void print_pcr_regs(void) -{ - int i; - - trace0(0, MEC, 0, "Current PCR registers"); - for (i = 0; i < 5; i++) { - trace12(0, MEC, 0, "REG SLP_EN[%d] = 0x%08X", - i, MCHP_PCR_SLP_EN(i)); - trace12(0, MEC, 0, "REG CLK_REQ[%d] = 0x%08X", - i, MCHP_PCR_CLK_REQ(i)); - } -} - -static void print_ecia_regs(void) -{ - int i; - - trace0(0, MEC, 0, "Current GIRQn.Result registers"); - for (i = MCHP_INT_GIRQ_FIRST; - i <= MCHP_INT_GIRQ_LAST; i++) - trace12(0, MEC, 0, "GIRQ[%d].Result = 0x%08X", - i, MCHP_INT_RESULT(i)); -} - -static void save_regs(void) -{ - int i; - - for (i = 0; i < MCHP_PCR_SLP_RST_REG_MAX; i++) { - pcr_slp_en[i] = MCHP_PCR_SLP_EN(i); - pcr_clk_req[i] = MCHP_PCR_CLK_REQ(i); - } - - for (i = 0; i < MCHP_INT_GIRQ_NUM; i++) - ecia_result[i] = - MCHP_INT_RESULT(MCHP_INT_GIRQ_FIRST + i); -} - -static void print_saved_regs(void) -{ - int i; - - trace0(0, BRD, 0, "Before sleep saved registers"); - for (i = 0; i < MCHP_PCR_SLP_RST_REG_MAX; i++) { - trace12(0, BRD, 0, "PCR_SLP_EN[%d] = 0x%08X", - i, pcr_slp_en[i]); - trace12(0, BRD, 0, "PCR_CLK_REQ[%d] = 0x%08X", - i, pcr_clk_req[i]); - } - - for (i = 0; i < MCHP_INT_GIRQ_NUM; i++) - trace12(0, BRD, 0, "GIRQ[%d].Result = 0x%08X", - (i+MCHP_INT_GIRQ_FIRST), ecia_result[i]); -} -#else -static __maybe_unused void print_pcr_regs(void) {} -static __maybe_unused void print_ecia_regs(void) {} -static __maybe_unused void save_regs(void) {} -static __maybe_unused void print_saved_regs(void) {} -#endif /* #ifdef CONFIG_MCHP_DEEP_SLP_DEBUG */ - -/** - * This is MCHP specific and equivalent to ARM Cortex's - * 'DeepSleep' via system control block register, CPU_SCB_SYSCTRL - * MCHP has new SLP_ALL feature. - * When SLP_ALL is enabled and HW sees sleep entry trigger from CPU. - * 1. HW saves PCR.SLP_EN registers - * 2. HW sets all PCR.SLP_EN bits to 1. - * 3. System sleeps - * 4. wake event wakes system - * 5. HW restores original values of all PCR.SLP_EN registers - * NOTE1: Current RTOS core (Cortex-M4) does not use SysTick timer. - * We can leave code to disable it but do not re-enable on wake. - * NOTE2: Some peripherals will not sleep until outstanding transactions - * are complete: I2C, DMA, GPSPI, QMSPI, etc. - * NOTE3: Security blocks do not fully implement HW sleep therefore their - * sleep enables must be manually set/restored. - * - */ -static void prepare_for_deep_sleep(void) -{ - /* sysTick timer */ - CPU_NVIC_ST_CTRL &= ~ST_ENABLE; - CPU_NVIC_ST_CTRL &= ~ST_COUNTFLAG; - - CPU_NVIC_ST_CTRL &= ~ST_TICKINT; /* SYS_TICK_INT_DISABLE */ - - /* Enable assertion of DeepSleep signals - * from the core when core enters sleep. - */ - CPU_SCB_SYSCTRL |= BIT(2); - - /* Stop timers */ - MCHP_TMR32_CTL(0) &= ~1; - MCHP_TMR32_CTL(1) &= ~1; -#ifdef CONFIG_WATCHDOG_HELP - MCHP_TMR16_CTL(0) &= ~1; - MCHP_INT_DISABLE(MCHP_TMR16_GIRQ) = - MCHP_TMR16_GIRQ_BIT(0); - MCHP_INT_SOURCE(MCHP_TMR16_GIRQ) = - MCHP_TMR16_GIRQ_BIT(0); -#endif - MCHP_INT_DISABLE(MCHP_TMR32_GIRQ) = - MCHP_TMR32_GIRQ_BIT(0) + - MCHP_TMR32_GIRQ_BIT(1); - MCHP_INT_SOURCE(MCHP_TMR32_GIRQ) = - MCHP_TMR32_GIRQ_BIT(0) + - MCHP_TMR32_GIRQ_BIT(1); - -#ifdef CONFIG_WATCHDOG - /* Stop watchdog */ - MCHP_WDG_CTL &= ~1; -#endif - - -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_ESPI; - MCHP_INT_ENABLE(22) = MCHP_INT22_WAKE_ONLY_ESPI; -#else - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_LPC; - MCHP_INT_ENABLE(22) = MCHP_INT22_WAKE_ONLY_LPC; -#endif - -#ifdef CONFIG_ADC - /* - * Clear ADC activate bit. If a conversion is in progress the - * ADC block will not enter low power until the conversion is - * complete. - */ - MCHP_ADC_CTRL &= ~1; -#endif - - /* stop Port80 capture timer */ -#ifndef CHIP_FAMILY_MEC172X - MCHP_P80_ACTIVATE(0) = 0; -#endif - - /* - * Clear SLP_EN bit(s) for wake sources. - * Currently only Hibernation timer 0. - * GPIO pins can always wake. - */ - MCHP_PCR_SLP_EN3 &= ~(MCHP_PCR_SLP_EN3_HTMR0); - -#ifdef CONFIG_PWM - pwm_keep_awake(); /* clear sleep enables of active PWM's */ -#else - /* Disable 100 Khz clock */ - MCHP_PCR_SLOW_CLK_CTL &= 0xFFFFFC00; -#endif - -#ifdef CONFIG_CHIPSET_DEBUG - /* Disable JTAG and preserve mode */ - MCHP_EC_JTAG_EN &= ~(MCHP_JTAG_ENABLE); -#endif - - /* call board level */ -#ifdef CONFIG_BOARD_DEEP_SLEEP - board_prepare_for_deep_sleep(); -#endif - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG - save_regs(); -#endif -} - -static void resume_from_deep_sleep(void) -{ - MCHP_PCR_SYS_SLP_CTL = 0x00; /* default */ - - /* Disable assertion of DeepSleep signal when core executes WFI */ - CPU_SCB_SYSCTRL &= ~BIT(2); - -#ifdef CONFIG_MCHP_DEEP_SLP_DEBUG - print_saved_regs(); - print_pcr_regs(); - print_ecia_regs(); -#endif - -#ifdef CONFIG_CHIPSET_DEBUG - MCHP_EC_JTAG_EN |= (MCHP_JTAG_ENABLE); -#endif - - MCHP_PCR_SLOW_CLK_CTL |= 0x1e0; - - /* call board level */ -#ifdef CONFIG_BOARD_DEEP_SLEEP - board_resume_from_deep_sleep(); -#endif - /* - * re-enable hibernation timer 0 PCR.SLP_EN to - * reduce power. - */ - MCHP_PCR_SLP_EN3 |= (MCHP_PCR_SLP_EN3_HTMR0); - -#ifdef CONFIG_HOSTCMD_ESPI - #ifdef CONFIG_POWER_S0IX - MCHP_INT_DISABLE(22) = MCHP_INT22_WAKE_ONLY_ESPI; - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_ESPI; - #else - MCHP_ESPI_ACTIVATE |= 1; - #endif -#else - #ifdef CONFIG_POWER_S0IX - MCHP_INT_DISABLE(22) = MCHP_INT22_WAKE_ONLY_LPC; - MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_LPC; - #else - MCHP_LPC_ACT |= 1; - #endif -#endif - - /* re-enable Port 80 capture */ -#ifndef CHIP_FAMILY_MEC172X - MCHP_P80_ACTIVATE(0) = 1; -#endif - -#ifdef CONFIG_ADC - MCHP_ADC_CTRL |= 1; -#endif - - /* Enable timer */ - MCHP_TMR32_CTL(0) |= 1; - MCHP_TMR32_CTL(1) |= 1; - MCHP_TMR16_CTL(0) |= 1; - MCHP_INT_ENABLE(MCHP_TMR32_GIRQ) = - MCHP_TMR32_GIRQ_BIT(0) + - MCHP_TMR32_GIRQ_BIT(1); - MCHP_INT_ENABLE(MCHP_TMR16_GIRQ) = - MCHP_TMR16_GIRQ_BIT(0); - - /* Enable watchdog */ -#ifdef CONFIG_WATCHDOG -#ifdef CONFIG_CHIPSET_DEBUG - /* enable WDG stall on active JTAG and do not start */ - MCHP_WDG_CTL = BIT(4); -#else - MCHP_WDG_CTL |= 1; -#endif -#endif -} - - -void clock_refresh_console_in_use(void) -{ - disable_sleep(SLEEP_MASK_CONSOLE); - - /* Set console in use expire time. */ - console_expire_time = get_time(); - console_expire_time.val += console_in_use_timeout_sec * SECOND; -} - -/** - * Low power idle task. Executed when no tasks are ready to be scheduled. - */ -void __idle(void) -{ - timestamp_t t0; - timestamp_t t1; - timestamp_t ht_t1; - uint32_t next_delay; - uint32_t max_sleep_time; - int time_for_dsleep; - int uart_ready_for_deepsleep; - - htimer_init(); /* hibernation timer initialize */ - - disable_sleep(SLEEP_MASK_CONSOLE); - console_expire_time.val = get_time().val + - CONSOLE_IN_USE_ON_BOOT_TIME; - - - /* - * 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 initializations and have gone to sleep. - */ - CPRINTS("MEC low power idle task started"); - - while (1) { - /* Disable interrupts */ - interrupt_disable(); - - t0 = get_time(); /* uSec */ - - /* __hw_clock_event_get() is next programmed timer event */ - next_delay = __hw_clock_event_get() - t0.le.lo; - - time_for_dsleep = next_delay > - (HEAVY_SLEEP_RECOVER_TIME_USEC + - SET_HTIMER_DELAY_USEC); - - max_sleep_time = next_delay - - HEAVY_SLEEP_RECOVER_TIME_USEC; - - /* check if there enough time for deep sleep */ - if (DEEP_SLEEP_ALLOWED && time_for_dsleep) { - /* - * Check if the console use has expired and - * console sleep is masked by GPIO(UART-RX) - * interrupt. - */ - if ((sleep_mask & SLEEP_MASK_CONSOLE) && - t0.val > console_expire_time.val) { - /* allow console to sleep. */ - enable_sleep(SLEEP_MASK_CONSOLE); - - /* - * Wait one clock before checking if - * heavy sleep is allowed to give time - * for sleep mask to be updated. - */ - clock_wait_cycles(1); - - if (LOW_SPEED_DEEP_SLEEP_ALLOWED) - CPRINTS("MEC Disable console " - "in deep sleep"); - } - - - /* UART is not being used */ - uart_ready_for_deepsleep = - LOW_SPEED_DEEP_SLEEP_ALLOWED && - !uart_tx_in_progress() && - uart_buffer_empty(); - - /* - * Since MCHP's heavy sleep mode requires all - * blocks to be sleep capable, UART/console - * readiness is final decision factor of - * heavy sleep of EC. - */ - if (uart_ready_for_deepsleep) { - - idle_dsleep_cnt++; - - /* - * configure UART Rx as GPIO wakeup - * interrupt source - */ - uart_enter_dsleep(); - - /* MCHP specific deep-sleep mode */ - prepare_for_deep_sleep(); - - /* - * 'max_sleep_time' value should be big - * enough so that hibernation timer's - * interrupt triggers only after 'wfi' - * completes its execution. - */ - max_sleep_time -= - (get_time().le.lo - t0.le.lo); - - /* setup/enable htimer wakeup interrupt */ - system_set_htimer_alarm(0, - max_sleep_time); - - /* set sleep all just before WFI */ - MCHP_PCR_SYS_SLP_CTL |= - MCHP_PCR_SYS_SLP_HEAVY; - MCHP_PCR_SYS_SLP_CTL |= - MCHP_PCR_SYS_SLP_ALL; - - } else { - idle_sleep_cnt++; - } - - /* Wait for interrupt: goes into deep sleep. */ - asm("dsb"); - asm("wfi"); - asm("isb"); - asm("nop"); - - if (uart_ready_for_deepsleep) { - - resume_from_deep_sleep(); - - /* - * Fast forward timer according to htimer - * counter: - * Since all blocks including timers - * will be in sleep mode, timers stops - * except hibernate timer. - * And system schedule timer should be - * corrected after wakeup by either - * hibernate timer or GPIO_UART_RX - * interrupt. - */ - ht_t1 = system_get_htimer(); - - /* disable/clear htimer wakeup interrupt */ - system_reset_htimer_alarm(); - - t1.val = t0.val + - (uint64_t)(max_sleep_time - - ht_t1.le.lo); - - force_time(t1); - - /* re-enable UART */ - uart_exit_dsleep(); - - /* Record time spent in deep sleep. */ - total_idle_dsleep_time_us += - (uint64_t)(max_sleep_time - - ht_t1.le.lo); - } - - } else { /* CPU 'Sleep' mode */ - - idle_sleep_cnt++; - - asm("wfi"); - - } - - interrupt_enable(); - } /* while(1) */ -} - -#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 sleep: %d\n", - idle_sleep_cnt); - ccprintf("Num idle calls that deep-sleep: %d\n", - idle_dsleep_cnt); - - ccprintf("Total Time spent in deep-sleep(sec): %.6lld(s)\n", - total_idle_dsleep_time_us); - ccprintf("Total time on: %.6llds\n\n", - ts.val); - - if (IS_ENABLED(CONFIG_MCHP_DEEP_SLP_DEBUG)) - print_pcr_regs(); /* debug */ - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats, - "", - "Print last idle stats"); -#endif /* defined(CONFIG_CMD_IDLE_STATS) */ - -/** - * Configure deep sleep clock settings. - */ -static int command_dsleep(int argc, char **argv) -{ - int v; - - if (argc > 1) { - if (parse_bool(argv[1], &v)) { - /* - * Force deep sleep not to use heavy sleep mode or - * allow it to use the heavy sleep mode. - */ - if (v) /* 'on' */ - disable_sleep( - SLEEP_MASK_FORCE_NO_LOW_SPEED); - else /* 'off' */ - enable_sleep( - SLEEP_MASK_FORCE_NO_LOW_SPEED); - } else { - /* Set console in use timeout. */ - char *e; - - v = strtoi(argv[1], &e, 10); - if (*e) - return EC_ERROR_PARAM1; - - console_in_use_timeout_sec = v; - - /* Refresh console in use to use new timeout. */ - clock_refresh_console_in_use(); - } - } - - ccprintf("Sleep mask: %08x\n", sleep_mask); - ccprintf("Console in use timeout: %d sec\n", - console_in_use_timeout_sec); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(dsleep, command_dsleep, - "[ on | off | <timeout> sec]", - "Deep sleep clock settings:\nUse 'on' to force deep " - "sleep NOT to enter heavy sleep mode.\nUse 'off' to " - "allow deep sleep to use heavy sleep whenever conditions " - "allow.\n" - "Give a timeout value for the console in use timeout.\n" - "See also 'sleep mask'."); -#endif /* CONFIG_LOW_POWER_IDLE */ diff --git a/chip/mchp/clock_chip.h b/chip/mchp/clock_chip.h deleted file mode 100644 index 2e7de60358..0000000000 --- a/chip/mchp/clock_chip.h +++ /dev/null @@ -1,17 +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. - */ - -/* Microchip MEC1701 specific module for Chrome EC */ - -#ifndef __CROS_EC_CLOCK_CHIP_H -#define __CROS_EC_CLOCK_CHIP_H - -#include <stdint.h> - -void htimer_init(void); -void system_set_htimer_alarm(uint32_t seconds, - uint32_t microseconds); - -#endif /* __CROS_EC_I2C_CLOCK_H */ diff --git a/chip/mchp/config_chip.h b/chip/mchp/config_chip.h deleted file mode 100644 index cf7ead512a..0000000000 --- a/chip/mchp/config_chip.h +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_CONFIG_CHIP_H -#define __CROS_EC_CONFIG_CHIP_H - -/* CPU core BFD configuration */ -#include "core/cortex-m/config_core.h" - -/* Number of IRQ vectors on the NVIC */ -#ifdef CHIP_FAMILY_MEC152X -#define CONFIG_IRQ_COUNT 174 -#elif defined(CHIP_FAMILY_MEC170X) -#define CONFIG_IRQ_COUNT 157 -#elif defined(CHIP_FAMILY_MEC172X) -#define CONFIG_IRQ_COUNT 181 -#endif - -/* Use a bigger console output buffer */ -#undef CONFIG_UART_TX_BUF_SIZE -#define CONFIG_UART_TX_BUF_SIZE 1024 - -/* Interval between HOOK_TICK notifications */ -#define HOOK_TICK_INTERVAL_MS 250 -#define HOOK_TICK_INTERVAL (HOOK_TICK_INTERVAL_MS * MSEC) - -/* - * Enable chip_pre_init called from main - * Used for configuring peripheral block - * sleep enables. - */ -#define CONFIG_CHIP_PRE_INIT - -/* - * MCHP EC's have I2C controllers and multiple I2C ports. Any port may be - * mapped to any controller at run time. Enable multi-port controller feature. - * Board level configuration determines how many controllers/ports are used - * and the mapping of port(s) to controller(s). NOTE: Some MCHP packages - * may not implement all I2C ports. - */ -#define CONFIG_I2C_MULTI_PORT_CONTROLLER - -/* - * MCHP I2C controllers also act as I2C peripherals listening for their - * peripheral address. Each controller has two programmable peripheral - * addresses. Define fake peripheral addresses that aren't used by - * peripherals on the board. - */ -#define CONFIG_MCHP_I2C0_SLAVE_ADDRS 0xE3E1 -#define CONFIG_MCHP_I2C1_SLAVE_ADDRS 0xE3E1 -#define CONFIG_MCHP_I2C2_SLAVE_ADDRS 0xE3E1 -#define CONFIG_MCHP_I2C3_SLAVE_ADDRS 0xE3E1 -#define CONFIG_MCHP_I2C4_SLAVE_ADDRS 0xE3E1 -#define CONFIG_MCHP_I2C5_SLAVE_ADDRS 0xE3E1 -#define CONFIG_MCHP_I2C6_SLAVE_ADDRS 0xE3E1 -#define CONFIG_MCHP_I2C7_SLAVE_ADDRS 0xE3E1 - -/************************************************************************/ -/* Memory mapping */ - -/* - * MEC170x-H and MEC152x-H have a total of 256KB SRAM. - * CODE at 0xE0000 - 0x117FFF, DATA at 0x118000 - 0x11FFFF - * MEC172x-N has a total of 416KB SRAM: 352KB CODE 64KB DATA - * CODE at 0xC0000 - 0x117FFF, DATA at 0x118000 - 0x127FFF - * Customer data preserved across reset is 1KB at 0x12_7400. - * Set top of SRAM to 0x12_7800. We lose the top 2KB. - * MCHP MEC can fetch code from data or data from code. - */ - -/************************************************************************/ -/* Define our RAM layout. */ - -#if defined(CHIP_FAMILY_MEC172X) -#define CONFIG_MEC_SRAM_BASE_START 0x000C0000 -#define CONFIG_MEC_SRAM_BASE_END (0x00128000 - (2 * 1024)) -#else -#define CONFIG_MEC_SRAM_BASE_START 0x000E0000 -#define CONFIG_MEC_SRAM_BASE_END 0x00120000 -#endif - -#define CONFIG_MEC_SRAM_SIZE (CONFIG_MEC_SRAM_BASE_END - \ - CONFIG_MEC_SRAM_BASE_START) -/* 64k Data RAM for RO / RW / loader */ -#define CONFIG_RAM_SIZE 0x00010000 -#define CONFIG_RAM_BASE (CONFIG_MEC_SRAM_BASE_END - \ - CONFIG_RAM_SIZE) - -/* System stack size */ -/* was 1024, temporarily expanded to 2048 for debug */ -#define CONFIG_STACK_SIZE 2048 - -/* non-standard task stack sizes */ -#define IDLE_TASK_STACK_SIZE 672 -#define LARGER_TASK_STACK_SIZE 800 -#define VENTI_TASK_STACK_SIZE 928 -#define ULTRA_TASK_STACK_SIZE 1056 -#define TRENTA_TASK_STACK_SIZE 1184 - -#define CHARGER_TASK_STACK_SIZE 1024 /* 640 */ -#define HOOKS_TASK_STACK_SIZE 1024 /* 640 */ -#define CONSOLE_TASK_STACK_SIZE 1024 /* 640 */ -#define HOST_CMD_TASK_STACK_SIZE 1024 /* 640 */ - -/* - * TODO: Large stack consumption - * https://code.google.com/p/chrome-os-partner/issues/detail?id=49245 - */ -/* original = 800, if stack exceptions expand to 1024 for debug */ -#define PD_TASK_STACK_SIZE 2048 - -/* Default task stack size */ -#define TASK_STACK_SIZE 672 - -/************************************************************************/ -/* Define our flash layout. */ - -/* - * MEC1521H loads firmware using QMSPI controller - * CONFIG_SPI_FLASH_PORT is the index into - * spi_devices[] in board.c - */ -#define CONFIG_SPI_FLASH_PORT 0 -#define CONFIG_SPI_FLASH - -/* - * MEC1727 chip has integrated SPI flash with 512KB size - */ -#if (defined(CHIP_VARIANT_MEC1727SZ) || defined(CHIP_VARIANT_MEC1727LJ)) -/* Total size of writable flash */ -#define CONFIG_FLASH_SIZE_BYTES 524288 -#endif - -/* Protect bank size 4K bytes */ -#define CONFIG_FLASH_BANK_SIZE 0x00001000 -/* Sector erase size 4K bytes */ -#define CONFIG_FLASH_ERASE_SIZE 0x00001000 -/* Minimum write size */ -#define CONFIG_FLASH_WRITE_SIZE 0x00000004 - -/* One page size for write */ -#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 - -/* Program memory base address */ -#if defined(CHIP_FAMILY_MEC172X) -#define CONFIG_PROGRAM_MEMORY_BASE 0x000C0000 -#else -#define CONFIG_PROGRAM_MEMORY_BASE 0x000E0000 -#endif - -/* - * Optimize SPI flash read timing, MEC172x QMSPI controller controls CS# - * by hardware, it will add several system clock cycles delay between CS - * deassertion to CS assertion at the start of the next transaction, this - * guarantees SPI back to back transactions, so 1ms delay can be removed - * to optimze timing. MEC172x chip supports this hardware feature. - */ -#if defined(CHIP_FAMILY_MEC172X) -#undef CONFIG_SPI_FLASH_READ_WAIT_MS -#define CONFIG_SPI_FLASH_READ_WAIT_MS 0 -#endif - -#include "config_flash_layout.h" - -/************************************************************************/ -/* Customize the build */ -/* Optional features present on this chip */ -#define CONFIG_ADC -#define CONFIG_DMA -#define CONFIG_HOSTCMD_X86 -#define CONFIG_SPI -#define CONFIG_SWITCH - -/* - * Enable configuration after ESPI_RESET# de-asserts - */ -#undef CONFIG_MCHP_ESPI_RESET_DEASSERT_INIT - -/* - * Enable CPRINT in chip eSPI module - * Define at board level. - */ -#undef CONFIG_MCHP_ESPI_DEBUG - -/* - * Enable EC UART commands in eSPI module useful for debugging. - */ -#undef CONFIG_MCHP_ESPI_EC_CMD - -/* - * Enable CPRINT debug messages in LPC module - */ -#undef CONFIG_MCHP_DEBUG_LPC - -/* - * Define this to use MEC1701 ROM SPI read API - * in little firmware module instead of SPI code - * from this module - */ -#undef CONFIG_CHIP_LFW_USE_ROM_SPI - -/* - * Use DMA when transmitting commands & data - * with GPSPI controllers. - */ -#if defined(CHIP_FAMILY_MEC170X) || defined(CHIP_FAMILY_MEC172X) -#define CONFIG_MCHP_GPSPI_TX_DMA -#endif - -/* - * Use DMA when transmitting command & data of length - * greater than QMSPI TX FIFO size. - */ -#define CONFIG_MCHP_QMSPI_TX_DMA - -/* - * Board level gpio.inc is using MCHP data sheet GPIO pin - * numbers which are octal. - * MCHP has 6 banks/ports each containing 32 GPIO's. - * Each bank/port is connected to a GIRQ. - * Port numbering: - * GPIO_015 = 13 decimal. Port = 13/32 = 0, bit = 13 % 32 = 13 - * GPIO_0123 = 83 decimal. Port 83/32 = 2, bit = 83 % 32 = 19 - * OR port = 0123 >> 5, bit = 0123 & 037(0x1F) = 023 = 19 decimal. - * You must use octal GPIO numbers in PIN(gpio_num) macro in - * gpio.inc files. - * Example: GPIO 211 in documentation 0211 = 137 = 0x89 - * GPIO(PCH_SLP_S0_L, PIN(0211), GPIO_INPUT | GPIO_PULL_DOWN) - * OR - * GPIO(PCH_SLP_S0_L, PIN(0x89), GPIO_INPUT | GPIO_PULL_DOWN) - */ -#define GPIO_BANK(index) ((index) >> 5) -#define GPIO_BANK_MASK(index) (1ul << ((index) & 0x1F)) - -#define GPIO_PIN(index) GPIO_BANK(index), GPIO_BANK_MASK(index) -#define GPIO_PIN_MASK(p, m) .port = (p), .mask = (m) - -#ifndef __ASSEMBLER__ - - -#endif /* #ifndef __ASSEMBLER__ */ - -#endif /* __CROS_EC_CONFIG_CHIP_H */ diff --git a/chip/mchp/config_flash_layout.h b/chip/mchp/config_flash_layout.h deleted file mode 100644 index d423ac0238..0000000000 --- a/chip/mchp/config_flash_layout.h +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_CONFIG_FLASH_LAYOUT_H -#define __CROS_EC_CONFIG_FLASH_LAYOUT_H - -/* - * mec17xx flash layout: - * - Non memory-mapped, external SPI. - * - RW image at the beginning of writable region. - * - Bootloader at the beginning of protected region, followed by RO image. - * - Loader + (RO | RW) loaded into program memory. - */ - -/* Non-memmory mapped, external SPI */ -#define CONFIG_EXTERNAL_STORAGE -#undef CONFIG_MAPPED_STORAGE -#undef CONFIG_FLASH_PSTATE -#define CONFIG_SPI_FLASH - -/* - * MEC170x/MEC152x BootROM uses two 4-byte TAG's at SPI offset 0x0 and 0x04. - * One valid TAG must be present. - * TAG's point to a Header which must be located on a 256 byte - * boundary anywhere in the flash (24-bit addressing). - * Locate BootROM load Header + LFW + EC_RO at start of second - * 4KB sector (offset 0x1000). - * Locate BootROM load Header + EC_RW at start of second half of - * SPI flash. - * LFW size is 4KB - * EC_RO and EC_RW padded sizes from the build are 188KB each. - * Storage size is 1/2 flash size. - */ -#define CONFIG_EC_PROTECTED_STORAGE_OFF 0 -/* Lower 256KB of flash is protected region */ -#define CONFIG_EC_PROTECTED_STORAGE_SIZE 0x40000 -/* Writable storage for EC_RW starts at 256KB */ -#define CONFIG_EC_WRITABLE_STORAGE_OFF 0x40000 -/* Writeable storage is 256KB */ -#define CONFIG_EC_WRITABLE_STORAGE_SIZE 0x40000 - - -/* Loader resides at the beginning of program memory */ -#define CONFIG_LOADER_MEM_OFF 0 -#define CONFIG_LOADER_SIZE 0x1000 - -/* Write protect Loader and RO Image */ -#define CONFIG_WP_STORAGE_OFF CONFIG_EC_PROTECTED_STORAGE_OFF -/* - * Write protect LFW + EC_RO - */ -#define CONFIG_WP_STORAGE_SIZE CONFIG_EC_PROTECTED_STORAGE_SIZE - -/* - * RO / RW images follow the loader in program memory. Either RO or RW - * image will be loaded -- both cannot be loaded at the same time. - */ -#define CONFIG_RO_MEM_OFF (CONFIG_LOADER_MEM_OFF + \ - CONFIG_LOADER_SIZE) -/* - * Total SRAM and the amount allocated for data are specified - * by CONFIG_MEC_SRAM_SIZE and CONFIG_RAM_SIZE in config_chip.h - * The little firmware (lfw) loader is resident in first 4KB of Code SRAM. - * EC_RO/RW size = Total SRAM - Data SRAM - LFW size. - * !!! EC_RO/RW size MUST be a multiple of flash erase block size. - * defined by CONFIG_FLASH_ERASE_SIZE in chip/config_chip.h - * and must be located on a erase block boundary. !!! - */ -#if (CONFIG_MEC_SRAM_SIZE > CONFIG_EC_PROTECTED_STORAGE_SIZE) -#define CONFIG_RO_SIZE (CONFIG_EC_PROTECTED_STORAGE_SIZE - \ - CONFIG_LOADER_SIZE - 0x2000) -#else -#define CONFIG_RO_SIZE (CONFIG_MEC_SRAM_SIZE - \ - CONFIG_RAM_SIZE - CONFIG_LOADER_SIZE) -#endif - -#define CONFIG_RW_MEM_OFF CONFIG_RO_MEM_OFF -/* - * NOTE: CONFIG_RW_SIZE is passed to the SPI image generation script by - * chip build.mk - * LFW requires CONFIG_RW_SIZE is equal to CONFIG_RO_SIZE !!! - */ -#define CONFIG_RW_SIZE CONFIG_RO_SIZE - -/* - * WP region consists of first half of SPI containing TAGs at beginning - * of SPI flash and header + binary(LFW+EC_RO) an offset aligned on - * a 256 byte boundary. - * NOTE: Changing CONFIG_BOOT_HEADER_STORAGE_OFF requires changing - * parameter --payload_offset parameter in build.mk passed to the - * python image builder. - * Two 4-byte TAG's exist at offset 0 and 4 in the SPI flash device. - * We only use first TAG pointing to LFW + EC_RO. - * MEC170x Header size is 128 bytes. - * MEC152x Header size is 320 bytes. - * Firmware binary is located immediately after the header. - * Second half of SPI flash contains: - * Header(128/320 bytes) + EC_RW - * EC flash erase/write commands check alignment base on - * CONFIG_FLASH_ERASE_SIZE defined in config_chip.h - * NOTE: EC_RO and EC_RW must start at CONFIG_FLASH_ERASE_SIZE or - * greater aligned boundaries. - */ -#define CONFIG_BOOT_HEADER_STORAGE_OFF 0x1000 -#define CONFIG_RW_BOOT_HEADER_STORAGE_OFF 0 -#if defined(CHIP_FAMILY_MEC172X) -#define CONFIG_BOOT_HEADER_STORAGE_SIZE 0xc0 -#elif defined(CHIP_FAMILY_MEC152X) -#define CONFIG_BOOT_HEADER_STORAGE_SIZE 0x140 -#elif defined(CHIP_FAMILY_MEC170X) -#define CONFIG_BOOT_HEADER_STORAGE_SIZE 0x80 -#else -#error "FORCED BUILD ERROR: CHIP_FAMILY_xxxx not set or invalid" -#endif -#define CONFIG_RW_BOOT_HEADER_STORAGE_SIZE 0 - -/* Loader / lfw image immediately follows the boot header on SPI */ -#define CONFIG_LOADER_STORAGE_OFF (CONFIG_BOOT_HEADER_STORAGE_OFF + \ - CONFIG_BOOT_HEADER_STORAGE_SIZE) - -/* RO image immediately follows the loader image */ -#define CONFIG_RO_STORAGE_OFF (CONFIG_LOADER_STORAGE_OFF + \ - CONFIG_LOADER_SIZE) - -/* - * RW image starts at offset 0 of second half of SPI. - * RW Header not needed. - */ -#define CONFIG_RW_STORAGE_OFF (CONFIG_RW_BOOT_HEADER_STORAGE_OFF + \ - CONFIG_RW_BOOT_HEADER_STORAGE_SIZE) - - -#endif /* __CROS_EC_CONFIG_FLASH_LAYOUT_H */ diff --git a/chip/mchp/dma.c b/chip/mchp/dma.c deleted file mode 100644 index 982dfa8122..0000000000 --- a/chip/mchp/dma.c +++ /dev/null @@ -1,393 +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 "common.h" -#include "console.h" -#include "dma.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "tfdp_chip.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_DMA, outstr) -#define CPRINTS(format, args...) cprints(CC_DMA, format, ## args) - -dma_chan_t *dma_get_channel(enum dma_channel channel) -{ - dma_chan_t *pd = NULL; - - if (channel < MCHP_DMAC_COUNT) { - pd = (dma_chan_t *)(MCHP_DMA_BASE + MCHP_DMA_CH_OFS + - (channel << MCHP_DMA_CH_OFS_BITPOS)); - } - - return pd; -} - -void dma_disable(enum dma_channel channel) -{ - if (channel < MCHP_DMAC_COUNT) { - if (MCHP_DMA_CH_CTRL(channel) & MCHP_DMA_RUN) - MCHP_DMA_CH_CTRL(channel) &= ~(MCHP_DMA_RUN); - - if (MCHP_DMA_CH_ACT(channel) & MCHP_DMA_ACT_EN) - MCHP_DMA_CH_ACT(channel) = 0; - } -} - -void dma_disable_all(void) -{ - uint16_t ch; - uint32_t unused = 0; - - for (ch = 0; ch < MCHP_DMAC_COUNT; ch++) { - /* Abort any current transfer. */ - MCHP_DMA_CH_CTRL(ch) |= MCHP_DMA_ABORT; - /* Disable the channel. */ - MCHP_DMA_CH_CTRL(ch) &= ~(MCHP_DMA_RUN); - MCHP_DMA_CH_ACT(ch) = 0; - } - - /* Soft-reset the block. */ - MCHP_DMA_MAIN_CTRL = MCHP_DMA_MAIN_CTRL_SRST; - unused += MCHP_DMA_MAIN_CTRL; - MCHP_DMA_MAIN_CTRL = MCHP_DMA_MAIN_CTRL_ACT; -} - -/** - * Prepare a channel for use and start it - * - * @param chan Channel to read - * @param count Number of bytes to transfer - * @param periph Pointer to peripheral data register - * @param memory Pointer to memory address for receive/transmit - * @param flags DMA flags for the control register, normally: - * MCHP_DMA_INC_MEM | MCHP_DMA_TO_DEV for tx - * MCHP_DMA_INC_MEM for rx - * Plus transfer unit length(1, 2, or 4) in bits[22:20] - * @note MCHP DMA does not require address aliasing. Because count - * is the number of bytes to transfer memory start - memory end = count. - */ -static void prepare_channel(enum dma_channel ch, unsigned int count, - void *periph, void *memory, unsigned int flags) -{ - if (ch < MCHP_DMAC_COUNT) { - - MCHP_DMA_CH_CTRL(ch) = 0; - MCHP_DMA_CH_MEM_START(ch) = (uint32_t)memory; - MCHP_DMA_CH_MEM_END(ch) = (uint32_t)memory + count; - - MCHP_DMA_CH_DEV_ADDR(ch) = (uint32_t)periph; - - MCHP_DMA_CH_CTRL(ch) = flags; - MCHP_DMA_CH_ACT(ch) = MCHP_DMA_ACT_EN; - } -} - -void dma_go(dma_chan_t *chan) -{ - /* Flush data in write buffer so that DMA can get the - * latest data. - */ - asm volatile("dsb;"); - - if (chan != NULL) - chan->ctrl |= MCHP_DMA_RUN; -} - -void dma_go_chan(enum dma_channel ch) -{ - asm volatile("dsb;"); - if (ch < MCHP_DMAC_COUNT) - MCHP_DMA_CH_CTRL(ch) |= MCHP_DMA_RUN; -} - -void dma_prepare_tx(const struct dma_option *option, unsigned count, - const void *memory) -{ - if (option != NULL) - /* - * Cast away const for memory pointer; this is ok because - * we know we're preparing the channel for transmit. - */ - prepare_channel(option->channel, count, option->periph, - (void *)memory, - MCHP_DMA_INC_MEM | - MCHP_DMA_TO_DEV | - MCHP_DMA_DEV(option->channel) | - option->flags); -} - -void dma_xfr_prepare_tx(const struct dma_option *option, uint32_t count, - const void *memory, uint32_t dma_xfr_units) -{ - uint32_t nflags; - - if (option != NULL) { - nflags = option->flags & ~(MCHP_DMA_XFER_SIZE_MASK); - nflags |= MCHP_DMA_XFER_SIZE(dma_xfr_units & 0x07); - /* - * Cast away const for memory pointer; this is ok because - * we know we're preparing the channel for transmit. - */ - prepare_channel(option->channel, count, option->periph, - (void *)memory, - MCHP_DMA_INC_MEM | - MCHP_DMA_TO_DEV | - MCHP_DMA_DEV(option->channel) | - nflags); - } -} - -void dma_start_rx(const struct dma_option *option, unsigned count, - void *memory) -{ - if (option != NULL) { - prepare_channel(option->channel, count, option->periph, - memory, - MCHP_DMA_INC_MEM | - MCHP_DMA_DEV(option->channel) | - option->flags); - dma_go_chan(option->channel); - } -} - -/* - * Configure and start DMA channel for read from device and write to - * memory. Allow caller to override DMA transfer unit length. - */ -void dma_xfr_start_rx(const struct dma_option *option, - uint32_t dma_xfr_ulen, - uint32_t count, void *memory) -{ - uint32_t ch, ctrl; - - if (option != NULL) { - ch = option->channel; - if (ch < MCHP_DMAC_COUNT) { - - MCHP_DMA_CH_CTRL(ch) = 0; - MCHP_DMA_CH_MEM_START(ch) = (uint32_t)memory; - MCHP_DMA_CH_MEM_END(ch) = (uint32_t)memory + - count; - - MCHP_DMA_CH_DEV_ADDR(ch) = - (uint32_t)option->periph; - - ctrl = option->flags & - ~(MCHP_DMA_XFER_SIZE_MASK); - ctrl |= MCHP_DMA_INC_MEM; - ctrl |= MCHP_DMA_XFER_SIZE(dma_xfr_ulen); - ctrl |= MCHP_DMA_DEV(option->channel); - MCHP_DMA_CH_CTRL(ch) = ctrl; - MCHP_DMA_CH_ACT(ch) = MCHP_DMA_ACT_EN; - } - - dma_go_chan(option->channel); - } -} - -/* - * Return the number of bytes transferred. - * The number of bytes transferred can be easily determined - * from the difference in DMA memory start address register - * and memory end address register. No need to look at DMA - * transfer size field because the hardware increments memory - * start address by unit size on each unit transferred. - * Why is a signed integer being used for a count value? - */ -int dma_bytes_done(dma_chan_t *chan, int orig_count) -{ - int bcnt; - - if (chan == NULL) - return 0; - - bcnt = (int)chan->mem_end; - bcnt -= (int)chan->mem_start; - bcnt = orig_count - bcnt; - - return bcnt; -} - -bool dma_is_enabled(dma_chan_t *chan) -{ - return (chan->ctrl & MCHP_DMA_RUN); -} - -int dma_bytes_done_chan(enum dma_channel ch, uint32_t orig_count) -{ - uint32_t cnt; - - cnt = 0; - if (ch < MCHP_DMAC_COUNT) - if (MCHP_DMA_CH_CTRL(ch) & MCHP_DMA_RUN) - cnt = (uint32_t)orig_count - - (MCHP_DMA_CH_MEM_END(ch) - - MCHP_DMA_CH_MEM_START(ch)); - - return (int)cnt; -} - -/* - * Initialize DMA block. - * Clear PCR DMA sleep enable. - * Soft-Reset block should clear after one clock but read-back to - * be safe. - * Set block activate bit after reset. - */ -void dma_init(void) -{ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_DMA); - MCHP_DMA_MAIN_CTRL = MCHP_DMA_MAIN_CTRL_SRST; - MCHP_DMA_MAIN_CTRL; - MCHP_DMA_MAIN_CTRL = MCHP_DMA_MAIN_CTRL_ACT; -} - -int dma_wait(enum dma_channel channel) -{ - timestamp_t deadline; - - if (channel < MCHP_DMAC_COUNT) { - if (MCHP_DMA_CH_ACT(channel) == 0) - return EC_SUCCESS; - - deadline.val = get_time().val + DMA_TRANSFER_TIMEOUT_US; - - while (!(MCHP_DMA_CH_ISTS(channel) & - MCHP_DMA_STS_DONE)) { - - if (deadline.val <= get_time().val) - return EC_ERROR_TIMEOUT; - - udelay(DMA_POLLING_INTERVAL_US); - } - return EC_SUCCESS; - } - - return EC_ERROR_INVAL; -} - -/* - * Clear all interrupt status in specified DMA channel - */ -void dma_clear_isr(enum dma_channel channel) -{ - if (channel < MCHP_DMAC_COUNT) - MCHP_DMA_CH_ISTS(channel) = 0x0f; -} - -void dma_cfg_buffers(enum dma_channel ch, const void *membuf, - uint32_t nb, const void *pdev) -{ - if (ch < MCHP_DMAC_COUNT) { - MCHP_DMA_CH_MEM_START(ch) = (uint32_t)membuf; - MCHP_DMA_CH_MEM_END(ch) = (uint32_t)membuf + nb; - MCHP_DMA_CH_DEV_ADDR(ch) = (uint32_t)pdev; - } -} - -/* - * ch = zero based DMA channel number - * unit_len = DMA unit size 1, 2 or 4 bytes - * flags - * b[0] = direction, 0=device_to_memory, 1=memory_to_device - * b[1] = 1 increment memory address - * b[2] = 1 increment device address - * b[3] = disable HW flow control - */ -void dma_cfg_xfr(enum dma_channel ch, uint8_t unit_len, - uint8_t dev_id, uint8_t flags) -{ - uint32_t ctrl; - - if (ch < MCHP_DMAC_COUNT) { - ctrl = MCHP_DMA_XFER_SIZE(unit_len & 0x07); - ctrl += MCHP_DMA_DEV(dev_id & MCHP_DMA_DEV_MASK0); - if (flags & 0x01) - ctrl |= MCHP_DMA_TO_DEV; - if (flags & 0x02) - ctrl |= MCHP_DMA_INC_MEM; - if (flags & 0x04) - ctrl |= MCHP_DMA_INC_DEV; - if (flags & 0x08) - ctrl |= MCHP_DMA_DIS_HW_FLOW; - MCHP_DMA_CH_CTRL(ch) = ctrl; - } -} - -void dma_clr_chan(enum dma_channel ch) -{ - if (ch < MCHP_DMAC_COUNT) { - MCHP_DMA_CH_ACT(ch) = 0; - MCHP_DMA_CH_CTRL(ch) = 0; - MCHP_DMA_CH_IEN(ch) = 0; - MCHP_DMA_CH_ISTS(ch) = 0xff; - MCHP_DMA_CH_FSM_RO(ch) = MCHP_DMA_CH_ISTS(ch); - MCHP_DMA_CH_ACT(ch) = 1; - } -} - -void dma_run(enum dma_channel ch) -{ - if (ch < MCHP_DMAC_COUNT) { - if (MCHP_DMA_CH_CTRL(ch) & MCHP_DMA_DIS_HW_FLOW) - MCHP_DMA_CH_CTRL(ch) |= MCHP_DMA_SW_GO; - else - MCHP_DMA_CH_CTRL(ch) |= MCHP_DMA_RUN; - } -} - -/* - * Check if DMA channel is done or stopped on error - * Returns 0 not done or stopped on error - * Returns non-zero if done or stopped. - * Caller should check bit pattern for specific bit, - * done, flow control error, and bus error. - */ -uint32_t dma_is_done_chan(enum dma_channel ch) -{ - if (ch < MCHP_DMAC_COUNT) - return (uint32_t)(MCHP_DMA_CH_ISTS(ch) & 0x07); - - return 0; -} - -/* - * Use DMA Channel 0 CRC32 ALU to compute CRC32 of data. - * Hardware implements IEEE 802.3 CRC32. - * IEEE 802.3 CRC32 initial value = 0xffffffff. - * Data must be aligned >= 4-bytes and number of bytes must - * be a multiple of 4. - */ -int dma_crc32_start(const uint8_t *mstart, const uint32_t nbytes, int ien) -{ - if ((mstart == NULL) || (nbytes == 0)) - return EC_ERROR_INVAL; - - if ((((uint32_t)mstart | nbytes) & 0x03) != 0) - return EC_ERROR_INVAL; - - MCHP_DMA_CH_ACT(0) = 0; - MCHP_DMA_CH_CTRL(0) = 0; - MCHP_DMA_CH_IEN(0) = 0; - MCHP_DMA_CH_ISTS(0) = 0xff; - MCHP_DMA_CH0_CRC32_EN = 1; - MCHP_DMA_CH0_CRC32_DATA = 0xfffffffful; - /* program device address to point to read-only register */ - MCHP_DMA_CH_DEV_ADDR(0) = (uint32_t)(MCHP_DMA_CH_BASE + 0x1c); - MCHP_DMA_CH_MEM_START(0) = (uint32_t)mstart; - MCHP_DMA_CH_MEM_END(0) = (uint32_t)mstart + nbytes; - if (ien != 0) - MCHP_DMA_CH_IEN(0) = 0x07; - MCHP_DMA_CH_ACT(0) = 1; - MCHP_DMA_CH_CTRL(0) = MCHP_DMA_TO_DEV + MCHP_DMA_INC_MEM + - MCHP_DMA_DIS_HW_FLOW + MCHP_DMA_XFER_SIZE(4); - MCHP_DMA_CH_CTRL(0) |= MCHP_DMA_SW_GO; - return EC_SUCCESS; -} diff --git a/chip/mchp/dma_chip.h b/chip/mchp/dma_chip.h deleted file mode 100644 index 4784b2c922..0000000000 --- a/chip/mchp/dma_chip.h +++ /dev/null @@ -1,68 +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. - * - * MCHP MEC DMA controller chip level API - */ -/** @file dma_chip.h - *MCHP MEC Direct Memory Access block - */ -/** @defgroup MEC dma - */ - -#ifndef _DMA_CHIP_H -#define _DMA_CHIP_H - -#include <stdint.h> -#include <stddef.h> - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Place any C interfaces here */ - -void dma_xfr_start_rx(const struct dma_option *option, - uint32_t dma_xfr_ulen, - uint32_t count, void *memory); - -void dma_xfr_prepare_tx(const struct dma_option *option, uint32_t count, - const void *memory, uint32_t dma_xfr_units); - -void dma_clr_chan(enum dma_channel ch); - -void dma_cfg_buffers(enum dma_channel ch, const void *membuf, - uint32_t nb, const void *pdev); - -/* - * ch = zero based DMA channel number - * unit_len = DMA unit size 1, 2 or 4 bytes - * flags - * b[0] = direction, 0=device_to_memory, 1=memory_to_device - * b[1] = 1 increment memory address - * b[2] = 1 increment device address - * b[3] = disable HW flow control - */ -#define DMA_FLAG_D2M 0 -#define DMA_FLAG_M2D 1 -#define DMA_FLAG_INCR_MEM 2 -#define DMA_FLAG_INCR_DEV 4 -#define DMA_FLAG_SW_FLOW 8 -void dma_cfg_xfr(enum dma_channel ch, uint8_t unit_len, - uint8_t dev_id, uint8_t flags); - -void dma_run(enum dma_channel ch); - -uint32_t dma_is_done_chan(enum dma_channel ch); - -int dma_crc32_start(const uint8_t *mstart, const uint32_t nbytes, int ien); - -#ifdef __cplusplus -} -#endif - -#endif /* #ifndef _DMA_CHIP_H */ -/** @} - */ - diff --git a/chip/mchp/espi.c b/chip/mchp/espi.c deleted file mode 100644 index 8a38a82688..0000000000 --- a/chip/mchp/espi.c +++ /dev/null @@ -1,1505 +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 "common.h" -#include "acpi.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "keyboard_protocol.h" -#include "port80.h" -#include "util.h" -#include "chipset.h" - -#include "registers.h" -#include "espi.h" -#include "lpc.h" -#include "lpc_chip.h" -#include "system.h" -#include "task.h" -#include "console.h" -#include "uart.h" -#include "util.h" -#include "power.h" -#include "timer.h" -#include "tfdp_chip.h" - -/* Console output macros */ -#ifdef CONFIG_MCHP_ESPI_DEBUG -#ifdef CONFIG_MCHP_TFDP -#define CPUTS(...) -#define CPRINTS(...) -#else -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) -#endif -#else -#define CPUTS(...) -#define CPRINTS(...) -#endif - -/* Default config to use maximum frequency */ -#ifndef CONFIG_HOSTCMD_ESPI_EC_MAX_FREQ -#if defined(CHIP_FAMILY_MEC172X) -#define CONFIG_HOSTCMD_ESPI_EC_MAX_FREQ MCHP_ESPI_CAP1_MAX_FREQ_66M -#else -#define CONFIG_HOSTCMD_ESPI_EC_MAX_FREQ MCHP_ESPI_CAP1_MAX_FREQ_50M -#endif -#endif - -/* Default config to support all modes */ -#ifndef CONFIG_HOSTCMD_ESPI_EC_MODE -#define CONFIG_HOSTCMD_ESPI_EC_MODE MCHP_ESPI_CAP1_ALL_MODE -#endif - -/* Default config to support all channels */ -#ifndef CONFIG_HOSTCMD_ESPI_EC_CHAN_BITMAP -#define CONFIG_HOSTCMD_ESPI_EC_CHAN_BITMAP MCHP_ESPI_CAP0_ALL_CHAN_SUPP -#endif -/* - * eSPI slave to master virtual wire pulse timeout. - */ -#define ESPI_S2M_VW_PULSE_LOOP_CNT 50 -#define ESPI_S2M_VW_PULSE_LOOP_DLY_US 10 - -/* - * eSPI master enable virtual wire channel timeout. - */ -#define ESPI_CHAN_READY_TIMEOUT_US (100 * MSEC) -#define ESPI_CHAN_READY_POLL_INTERVAL_US 100 - -static uint32_t espi_channels_ready; - -/* - * eSPI Virtual Wire reset values - * VWire name used by chip independent code. - * Host eSPI Master VWire index containing signal - * Reset value of VWire. Note, each Host VWire index may - * have a different reset source: - * EC Power-on/chip reset - * ESPI_RESET# assertion by Host eSPI master - * eSPI Platform Reset assertion by Host eSPI master - * MEC1701H allows eSPI Platform reset to - * be a VWire or side band signal. - * - * NOTE MEC1701H Boot-ROM will restore VWires ... from - * VBAT power register MCHP_VBAT_VWIRE_BACKUP. - * bits[3:0] = Master-to-Slave Index 02h SRC3:SRC0 values - * MSVW00 register - * SRC0 = SLP_S3# - * SRC1 = SLP_S4# - * SRC2 = SLP_S5# - * SRC3 = reserved - * bits[7:4] = Master-to-Slave Index 42h SRC3:SRC0 values - * MSVW04 register - * SRC0 = SLP_LAN# - * SRC1 = SLP_WLAN# - * SRC2 = reserved - * SRC3 = reserved - * - */ -struct vw_info_t { - uint16_t name; /* signal name */ - uint8_t host_idx; /* Host VWire index of signal */ - uint8_t reset_val; /* reset value of VWire */ - uint8_t flags; /* b[0]=0(MSVW), =1(SMVW) */ - uint8_t reg_idx; /* MSVW or SMVW index */ - uint8_t src_num; /* SRC number */ - uint8_t rsvd; -}; - - -/* VW signals used in eSPI */ -/* - * MEC1701H VWire mapping based on eSPI Spec 1.0, - * eSPI Compatibility spec 0.96, - * MCHP HW defaults and ec/include/espi.h - * - * MSVW00 index=02h PORValue=00000000_04040404_00000102 reset=RESET_SYS - * SRC0 = VW_SLP_S3_L, IntrDis - * SRC1 = VW_SLP_S4_L, IntrDis - * SRC2 = VW_SLP_S5_L, IntrDis - * SRC3 = reserved, IntrDis - * MSVW01 index=03h PORValue=00000000_04040404_00000003 reset=RESET_ESPI - * SRC0 = VW_SUS_STAT_L, IntrDis - * SRC1 = VW_PLTRST_L, IntrDis - * SRC2 = VW_OOB_RST_WARN, IntrDis - * SRC3 = reserved, IntrDis - * MSVW02 index=07h PORValue=00000000_04040404_00000307 reset=PLTRST - * SRC0 = VW_HOST_RST_WARN - * SRC1 = 0 reserved - * SRC2 = 0 reserved - * SRC3 = 0 reserved - * MSVW03 index=41h PORValue=00000000_04040404_00000041 reset=RESET_ESPI - * SRC0 = VW_SUS_WARN_L, IntrDis - * SRC1 = VW_SUS_PWRDN_ACK_L, IntrDis - * SRC2 = 0 reserved, IntrDis - * SRC3 = VW_SLP_A_L, IntrDis - * MSVW04 index=42h PORValue=00000000_04040404_00000141 reset=RESET_SYS - * SRC0 = VW_SLP_LAN, IntrDis - * SRC1 = VW_SLP_WLAN, IntrDis - * SRC2 = reserved, IntrDis - * SRC3 = reserved, IntrDis - * - * SMVW00 index=04h PORValue=01010000_0000C004 STOM=1100 reset=RESET_ESPI - * SRC0 = VW_OOB_RST_ACK - * SRC1 = 0 reserved - * SRC2 = VW_WAKE_L - * SRC3 = VW_PME_L - * SMVW01 index=05h PORValue=00000000_00000005 STOM=0000 reset=RESET_ESPI - * SRC0 = SLAVE_BOOT_LOAD_DONE !!! NOTE: Google combines SRC0 & SRC3 - * SRC1 = VW_ERROR_FATAL - * SRC2 = VW_ERROR_NON_FATAL - * SRC3 = SLAVE_BOOT_LOAD_STATUS !!! into VW_PERIPHERAL_BTLD_STATUS_DONE - * SMVW02 index=06h PORValue=00010101_00007306 STOM=0111 reset=PLTRST - * SRC0 = VW_SCI_L - * SRC1 = VW_SMI_L - * SRC2 = VW_RCIN_L - * SRC3 = VW_HOST_RST_ACK - * SMVW03 index=40h PORValue=00000000_00000040 STOM=0000 reset=RESET_ESPI - * SRC0 = assign VW_SUS_ACK - * SRC1 = 0 - * SRC2 = 0 - * SRC3 = 0 - * - * table of vwire structures - * MSVW00 at 0x400F9C00 offset = 0x000 - * MSVW01 at 0x400F9C0C offset = 0x00C - * - * SMVW00 at 0x400F9E00 offset = 0x200 - * SMVW01 at 0x400F9E08 offset = 0x208 - * - */ - -/* - * Virtual Wire table - * Each entry contains: - * Signal name from include/espi.h - * Host chipset VWire index number - * Reset value of VWire - * flags where bit[0]==0 Wire is Master-to-Slave or 1 Slave-to-Master - * MEC1701 register index into MSVW or SMVW register banks - * MEC1701 source number in MSVW or SMVW bank - * Reserved - * Pointer to name string for debug - */ -static const struct vw_info_t vw_info_tbl[] = { - /* name host reset reg SRC - * index value flags index num rsvd - */ - /* MSVW00 Host index 02h (In) */ - {VW_SLP_S3_L, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}, - {VW_SLP_S4_L, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00}, - {VW_SLP_S5_L, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00}, - /* MSVW01 Host index 03h (In) */ - {VW_SUS_STAT_L, 0x03, 0x00, 0x10, 0x01, 0x00, 0x00}, - {VW_PLTRST_L, 0x03, 0x00, 0x10, 0x01, 0x01, 0x00}, - {VW_OOB_RST_WARN, 0x03, 0x00, 0x10, 0x01, 0x02, 0x00}, - /* SMVW00 Host Index 04h (Out) */ - {VW_OOB_RST_ACK, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00}, - {VW_WAKE_L, 0x04, 0x01, 0x01, 0x00, 0x02, 0x00}, - {VW_PME_L, 0x04, 0x01, 0x01, 0x00, 0x03, 0x00}, - /* SMVW01 Host index 05h (Out) */ - {VW_ERROR_FATAL, 0x05, 0x00, 0x01, 0x01, 0x01, 0x00}, - {VW_ERROR_NON_FATAL, 0x05, 0x00, 0x01, 0x01, 0x02, 0x00}, - {VW_PERIPHERAL_BTLD_STATUS_DONE, 0x05, 0x00, 0x01, 0x01, 0x30, 0x00}, - /* SMVW02 Host index 06h (Out) */ - {VW_SCI_L, 0x06, 0x01, 0x01, 0x02, 0x00, 0x00}, - {VW_SMI_L, 0x06, 0x01, 0x01, 0x02, 0x01, 0x00}, - {VW_RCIN_L, 0x06, 0x01, 0x01, 0x02, 0x02, 0x00}, - {VW_HOST_RST_ACK, 0x06, 0x00, 0x01, 0x02, 0x03, 0x00}, - /* MSVW02 Host index 07h (In) */ - {VW_HOST_RST_WARN, 0x07, 0x00, 0x10, 0x02, 0x00, 0x00}, - /* SMVW03 Host Index 40h (Out) */ - {VW_SUS_ACK, 0x40, 0x00, 0x01, 0x03, 0x00, 0x00}, - /* MSVW03 Host Index 41h (In) */ - {VW_SUS_WARN_L, 0x41, 0x00, 0x10, 0x03, 0x00, 0x00}, - {VW_SUS_PWRDN_ACK_L, 0x41, 0x00, 0x10, 0x03, 0x01, 0x00}, - {VW_SLP_A_L, 0x41, 0x00, 0x10, 0x03, 0x03, 0x00}, - /* MSVW04 Host index 42h (In) */ - {VW_SLP_LAN, 0x42, 0x00, 0x10, 0x04, 0x00, 0x00}, - {VW_SLP_WLAN, 0x42, 0x00, 0x10, 0x04, 0x01, 0x00} -}; -BUILD_ASSERT(ARRAY_SIZE(vw_info_tbl) == VW_SIGNAL_COUNT); - - -/************************************************************************/ -/* eSPI internal utilities */ - -static int espi_vw_get_signal_index(enum espi_vw_signal event) -{ - int i; - - /* Search table by signal name */ - for (i = 0; i < ARRAY_SIZE(vw_info_tbl); i++) { - if (vw_info_tbl[i].name == event) - return i; - } - - return -1; -} - - -/* - * Initialize eSPI hardware upon ESPI_RESET# de-assertion - */ -#ifdef CONFIG_MCHP_ESPI_RESET_DEASSERT_INIT -static void espi_reset_deassert_init(void) -{ - -} -#endif - -/* Call this on entry to deepest sleep state with EC turned off. - * May not be required in future host eSPI chipsets. - * - * Save Master-to-Slave VWire Index 02h & 42h before - * entering a deep sleep state where EC power is shut off. - * PCH requires we restore these VWires on wake. - * SLP_S3#, SLP_S4#, SLP_S5# in index 02h - * SLP_LAN#, SLP_WLAN# in index 42h - * Current VWire states are saved to a battery backed 8-bit - * register in MEC1701H. - * If a VBAT POR occurs the value of this register = 0 which - * is the default state of the above VWires on a hardware - * POR. - * VBAT byte bit definitions - * Host Index 02h -> MSVW00 - * Host Index 42h -> MSVW04 - * 0 Host Index 02h SRC0 - * 1 Host Index 02h SRC1 - * 2 Host Index 02h SRC2 - * 3 Host Index 02h SRC3 - * 4 Host Index 42h SRC0 - * 5 Host Index 42h SRC1 - * 6 Host Index 42h SRC2 - * 7 Host Index 42h SRC3 - */ -#ifdef CONFIG_MCHP_ESPI_VW_SAVE_ON_SLEEP -static void espi_vw_save(void) -{ - uint32_t i, r; - uint8_t vb; - - vb = 0; - r = MCHP_ESPI_VW_M2S_SRC_ALL(MSVW_H42); - for (i = 0; i < 4; i++) { - if (r & (1ul << (i << 3))) - vb |= (1u << i); - } - - vb <<= 4; - r = MCHP_ESPI_VW_M2S_SRC_ALL(MSVW_H02); - for (i = 0; i < 4; i++) { - if (r & (1ul << (i << 3))) - vb |= (1u << i); - } - - r = MCHP_VBAT_RAM(MCHP_VBAT_VWIRE_BACKUP); - r = (r & 0xFFFFFF00) | vb; - MCHP_VBAT_RAM(MCHP_VBAT_VWIRE_BACKUP) = r; -} - -/* - * Update MEC1701H VBAT powered VWire backup values restored on - * MCHP chip reset. MCHP Boot-ROM loads these values into - * MSVW00 SRC[0:3](Index 02h) and MSVW04 SRC[0:3](Index 42h) - * on chip reset(POR, WDT reset, chip reset, wake from EC off). - * Always clear backup value after restore. - */ -static void espi_vw_restore(void) -{ - uint32_t i, r; - uint8_t vb; - -#ifdef EVB_NO_ESPI_TEST_MODE - vb = 0xff; /* force SLP_Sx# signals to 1 */ -#else - vb = MCHP_VBAT_RAM(MCHP_VBAT_VWIRE_BACKUP) & 0xff; -#endif - r = 0; - for (i = 0; i < 4; i++) { - if (vb & (1u << i)) - r |= (1ul << (i << 3)); - } - MCHP_ESPI_VW_M2S_SRC_ALL(MSVW_H02) = r; - CPRINTS("eSPI restore MSVW00(Index 02h) = 0x%08x", r); - - vb >>= 4; - r = 0; - for (i = 0; i < 4; i++) { - if (vb & (1u << i)) - r |= (1ul << (i << 3)); - } - MCHP_ESPI_VW_M2S_SRC_ALL(MSVW_H42) = r; - CPRINTS("eSPI restore MSVW00(Index 42h) = 0x%08x", r); - - r = MCHP_VBAT_RAM(MCHP_VBAT_VWIRE_BACKUP); - MCHP_VBAT_RAM(MCHP_VBAT_VWIRE_BACKUP) = r & 0xFFFFFF00; - -} -#endif - -static uint8_t __attribute__((unused)) espi_msvw_srcs_get(uint8_t msvw_id) -{ - uint8_t msvw; - - msvw = 0; - if (msvw_id < MSVW_MAX) { - uint32_t r = MCHP_ESPI_VW_M2S_SRC_ALL(msvw_id); - - msvw = (r & 0x01); - msvw |= ((r >> 7) & 0x02); - msvw |= ((r >> 14) & 0x04); - msvw |= ((r >> 21) & 0x08); - } - - return msvw; -} - -static void __attribute__((unused)) espi_msvw_srcs_set(uint8_t msvw_id, - uint8_t src_bitmap) -{ - if (msvw_id < MSVW_MAX) { - uint32_t r = (src_bitmap & 0x08) << 21; - - r |= (src_bitmap & 0x04) << 14; - r |= (src_bitmap & 0x02) << 7; - r |= (src_bitmap & 0x01); - MCHP_ESPI_VW_M2S_SRC_ALL(msvw_id) = r; - } -} - -static uint8_t __attribute__((unused)) espi_smvw_srcs_get(uint8_t smvw_id) -{ - uint8_t smvw; - - smvw = 0; - if (smvw_id < SMVW_MAX) { - uint32_t r = MCHP_ESPI_VW_S2M_SRC_ALL(smvw_id); - - smvw = (r & 0x01); - smvw |= ((r >> 7) & 0x02); - smvw |= ((r >> 14) & 0x04); - smvw |= ((r >> 21) & 0x08); - } - - return smvw; -} - -static void __attribute__((unused)) espi_smvw_srcs_set(uint8_t smvw_id, - uint8_t src_bitmap) -{ - if (smvw_id < SMVW_MAX) { - uint32_t r = (src_bitmap & 0x08) << 21; - - r |= (src_bitmap & 0x04) << 14; - r |= (src_bitmap & 0x02) << 7; - r |= (src_bitmap & 0x01); - MCHP_ESPI_VW_S2M_SRC_ALL(smvw_id) = r; - } -} - - -/* - * Called before releasing RSMRST# - * ESPI_RESET# is asserted - * PLATFORM_RESET# is asserted - */ -static void espi_bar_pre_init(void) -{ - /* Configuration IO BAR set to 0x2E/0x2F */ - MCHP_ESPI_IO_BAR_ADDR_LSB(MCHP_ESPI_IO_BAR_ID_CFG_PORT) = 0x2E; - MCHP_ESPI_IO_BAR_ADDR_MSB(MCHP_ESPI_IO_BAR_ID_CFG_PORT) = 0x00; - MCHP_ESPI_IO_BAR_VALID(MCHP_ESPI_IO_BAR_ID_CFG_PORT) = 1; -} - -/* - * Called before releasing RSMRST# - * ESPI_RESET# is asserted - * PLATFORM_RESET# is asserted - * Set all MSVW to either edge interrupt - * IRQ_SELECT fields are reset on RESET_SYS not ESPI_RESET or PLTRST - * - */ -static void espi_vw_pre_init(void) -{ - uint32_t i; - - CPRINTS("eSPI VW Pre-Init"); - -#ifdef CONFIG_MCHP_ESPI_VW_SAVE_ON_SLEEP - espi_vw_restore(); -#endif - - /* disable all */ - for (i = 0; i < MSVW_MAX; i++) - MCHP_ESPI_VW_M2S_IRQSEL_ALL(i) = 0x0f0f0f0ful; - - /* clear spurious status */ - MCHP_INT_SOURCE(24) = 0xfffffffful; - MCHP_INT_SOURCE(25) = 0xfffffffful; - - MCHP_ESPI_VW_M2S_IRQSEL_ALL(MSVW_H02) = 0x040f0f0ful; - MCHP_ESPI_VW_M2S_IRQSEL_ALL(MSVW_H03) = 0x040f0f0ful; - MCHP_ESPI_VW_M2S_IRQSEL_ALL(MSVW_H07) = 0x0404040ful; - MCHP_ESPI_VW_M2S_IRQSEL_ALL(MSVW_H41) = 0x0f040f0ful; - MCHP_ESPI_VW_M2S_IRQSEL_ALL(MSVW_H42) = 0x04040f0ful; - MCHP_ESPI_VW_M2S_IRQSEL_ALL(MSVW_H47) = 0x0404040ful; - - MCHP_INT_ENABLE(24) = 0xfff3b177ul; - MCHP_INT_ENABLE(25) = 0x01ul; - - MCHP_INT_SOURCE(24) = 0xfffffffful; - MCHP_INT_SOURCE(25) = 0xfffffffful; - - MCHP_INT_BLK_EN = (1ul << 24) + (1ul << 25); - - task_enable_irq(MCHP_IRQ_GIRQ24); - task_enable_irq(MCHP_IRQ_GIRQ25); - - CPRINTS("eSPI VW Pre-Init Done"); -} - - -/* - * If VWire, Flash, and OOB channels have been enabled - * then set VWires SLAVE_BOOT_LOAD_STATUS = SLAVE_BOOT_LOAD_DONE = 1 - * SLAVE_BOOT_LOAD_STATUS = SRC3 of Slave-to-Master Index 05h - * SLAVE_BOOT_LOAD_DONE = SRC0 of Slave-to-Master Index 05h - * Note, if set individually then set status first then done. - * We set both simultaneously. ESPI_ALERT# will assert only if one - * or both bits change. - * SRC0 is bit[32] of SMVW01 - * SRC3 is bit[56] of SMVW01 - */ -static void espi_send_boot_load_done(void) -{ - /* First set SLAVE_BOOT_LOAD_STATUS = 1 */ - MCHP_ESPI_VW_S2M_SRC3(SMVW_H05) = 1; - /* Next set SLAVE_BOOT_LOAD_DONE = 1 */ - MCHP_ESPI_VW_S2M_SRC0(SMVW_H05) = 1; - - CPRINTS("eSPI Send SLAVE_BOOT_LOAD_STATUS/DONE = 1"); -} - - -/* - * Called when eSPI PLTRST# VWire de-asserts - * Re-initialize any hardware that was reset while PLTRST# was - * asserted. - * Logical Device BAR's, etc. - * Each BAR requires address, mask, and valid bit - * mask = bit map of address[7:0] to mask out - * 0 = no masking, match exact address - * 0x01 = mask bit[0], match two consecutive addresses - * 0xff = mask bits[7:0], match 256 consecutive bytes - * eSPI has two registers for each BAR - * Host visible register - * base address in bits[31:16] - * valid = bit[0] - * EC only register - * mask = bits[7:0] - * Logical device number = bits[13:8] - * Virtualized = bit[16] Not Implemented - */ -static void espi_host_init(void) -{ - CPRINTS("eSPI - espi_host_init"); - - /* BAR's */ - - /* Configuration IO BAR set to 0x2E/0x2F */ - MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_ID_CFG_PORT) = 0x01; - MCHP_ESPI_IO_BAR_ADDR_LSB(MCHP_ESPI_IO_BAR_ID_CFG_PORT) = 0x2E; - MCHP_ESPI_IO_BAR_ADDR_MSB(MCHP_ESPI_IO_BAR_ID_CFG_PORT) = 0x00; - MCHP_ESPI_IO_BAR_VALID(MCHP_ESPI_IO_BAR_ID_CFG_PORT) = 1; - - /* Set up ACPI0 for 0x62/0x66 */ - chip_acpi_ec_config(0, 0x62, 0x04); - - /* Set up ACPI1 for 0x200-0x203, 0x204-0x207 */ - chip_acpi_ec_config(1, 0x200, 0x07); - - /* Set up 8042 interface at 0x60/0x64 */ - chip_8042_config(0x60); - - /* EMI at 0x800 for accessing shared memory */ - chip_emi0_config(0x800); - - /* Setup Port80 Debug Hardware for I/O 80h */ - chip_port80_config(0x80); - - lpc_mem_mapped_init(); - - MCHP_ESPI_PC_STATUS = 0xfffffffful; - /* PC enable & Mastering enable changes */ - MCHP_ESPI_PC_IEN = (1ul << 25) + (1ul << 28); - - - /* Sufficiently initialized */ - lpc_set_init_done(1); - - /* last set eSPI Peripheral Channel Ready = 1 */ - /* Done in ISR for PC Channel */ - MCHP_ESPI_IO_PC_READY = 1; - - /* Update host events now that we can copy them to memmap */ - /* NOTE: This routine may pulse SCI# and/or SMI# - * For eSPI these are virtual wires. VWire channel should be - * enabled before PLTRST# is de-asserted so its safe BUT has - * PC Channel(I/O) Enable occurred? - */ - lpc_update_host_event_status(); - - CPRINTS("eSPI - espi_host_init Done"); -} -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, espi_host_init, HOOK_PRIO_FIRST); - - -/* - * Called in response to VWire OOB_RST_WARN==1 from - * espi_vw_evt_oob_rst_warn. - * Host chipset eSPI documentation states eSPI slave should - * if necessary flush any OOB upstream (OOB TX) data before the slave - * sends OOB_RST_ACK=1 to the Host. - */ -static void espi_oob_flush(void) -{ -} - - -/* - * Called in response to VWire HOST_RST_WARN==1 from - * espi_vw_evt_host_rst_warn. - * Host chipset eSPI documentation states assertion of HOST_RST_WARN - * can be used if necessary to flush any Peripheral Channel data - * before slave sends HOST_RST_ACK to Host. - */ -static void espi_pc_flush(void) -{ -} - -/* The ISRs of VW signals which used for power sequences */ -void espi_vw_power_signal_interrupt(enum espi_vw_signal signal) -{ - CPRINTS("eSPI power signal interrupt for VW %d", signal); - power_signal_interrupt((enum gpio_signal) signal); -} - -/************************************************************************/ -/* IC specific low-level driver */ - - -/** - * Set eSPI Virtual-Wire signal to Host - * - * @param signal vw signal needs to set - * @param level level of vw signal - * @return EC_SUCCESS, or non-zero if error. - */ -int espi_vw_set_wire(enum espi_vw_signal signal, uint8_t level) -{ - int tidx; - uint8_t ridx, src_num; - - tidx = espi_vw_get_signal_index(signal); - - if (tidx < 0) - return EC_ERROR_PARAM1; - - if (0 == (vw_info_tbl[tidx].flags & (1u << 0))) - return EC_ERROR_PARAM1; /* signal is Master-to-Slave */ - - ridx = vw_info_tbl[tidx].reg_idx; - src_num = vw_info_tbl[tidx].src_num; - - if (level) - level = 1; - - if (signal == VW_PERIPHERAL_BTLD_STATUS_DONE) { - /* SLAVE_BOOT_LOAD_STATUS */ - MCHP_ESPI_VW_S2M_SRC3(ridx) = level; - /* SLAVE_BOOT_LOAD_DONE after status */ - MCHP_ESPI_VW_S2M_SRC0(ridx) = level; - } else { - MCHP_ESPI_VW_S2M_SRC(ridx, src_num) = level; - } - -#ifdef CONFIG_MCHP_ESPI_DEBUG - CPRINTS("eSPI VW Set Wire %s = %d", - espi_vw_get_wire_name(signal), level); -#endif - - return EC_SUCCESS; -} - -/* - * Set Slave to Master virtual wire to level and wait for hardware - * to process virtual wire. - * If virtual wire written to same value then hardware change bit - * is 0 and routine returns success. - * If virtual wire written to different value then hardware change bit - * goes to 1 until bit is transmitted upstream to the master. This may - * happen quickly is bus is idle. Poll for hardware clearing change bit - * until timeout. - */ -static int espi_vw_s2m_set_w4m(uint32_t ridx, uint32_t src_num, - uint8_t level) -{ - uint32_t i; - - MCHP_ESPI_VW_S2M_SRC(ridx, src_num) = level & 0x01; - - for (i = 0; i < ESPI_S2M_VW_PULSE_LOOP_CNT; i++) { - if ((MCHP_ESPI_VW_S2M_CHANGE(ridx) & - (1u << src_num)) == 0) - return EC_SUCCESS; - udelay(ESPI_S2M_VW_PULSE_LOOP_DLY_US); - } - - return EC_ERROR_TIMEOUT; -} - -/* - * Create a pulse on a Slave-to-Master VWire - * Use case is generate low pulse on SCI# virtual wire. - * Should a timeout mechanism be added because we are - * waiting on Host eSPI Master to respond to eSPI Alert and - * then read the VWires. If the eSPI Master is OK the maximum - * time will still be variable depending upon link frequency and - * other activity on the link. Other activity is currently bounded by - * Host chipset eSPI maximum payload length of 64 bytes + packet overhead. - * Lowest eSPI transfer rate is 1x at 20 MHz, assume 30% packet overhead. - * (64 * 1.3) * 8 = 666 bits is roughly 34 us. Pad to 100 us. - */ -int espi_vw_pulse_wire(enum espi_vw_signal signal, int pulse_level) -{ - int rc, tidx; - uint8_t ridx, src_num, level; - - tidx = espi_vw_get_signal_index(signal); - - if (tidx < 0) - return EC_ERROR_PARAM1; - - if (0 == (vw_info_tbl[tidx].flags & (1u << 0))) - return EC_ERROR_PARAM1; /* signal is Master-to-Slave */ - - ridx = vw_info_tbl[tidx].reg_idx; - src_num = vw_info_tbl[tidx].src_num; - - level = 0; - if (pulse_level) - level = 1; - -#ifdef CONFIG_MCHP_ESPI_DEBUG - CPRINTS("eSPI VW Pulse Wire %s to %d", - espi_vw_get_wire_name(signal), level); -#endif - - /* set requested inactive state */ - rc = espi_vw_s2m_set_w4m(ridx, src_num, ~level); - if (rc != EC_SUCCESS) - return rc; - - /* drive to requested active state */ - rc = espi_vw_s2m_set_w4m(ridx, src_num, level); - if (rc != EC_SUCCESS) - return rc; - - /* set to requested inactive state */ - rc = espi_vw_s2m_set_w4m(ridx, src_num, ~level); - - return rc; -} - -/** - * 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) -{ - int vw, tidx; - uint8_t ridx, src_num; - - vw = 0; - tidx = espi_vw_get_signal_index(signal); - - if (tidx >= 0 && (0 == (vw_info_tbl[tidx].flags & (1u << 0)))) { - ridx = vw_info_tbl[tidx].reg_idx; - src_num = vw_info_tbl[tidx].src_num; - vw = MCHP_ESPI_VW_M2S_SRC(ridx, src_num) & 0x01; -#ifdef CONFIG_MCHP_ESPI_DEBUG - CPRINTS("VW GetWire %s = %d", - espi_vw_get_wire_name(signal), vw); -#endif - } - - return vw; -} - -/** - * 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) -{ - int tidx; - uint8_t ridx, src_num, girq_num, bpos; - - tidx = espi_vw_get_signal_index(signal); - - if (tidx < 0) - return EC_ERROR_PARAM1; - - if (0 != (vw_info_tbl[tidx].flags & (1u << 0))) - return EC_ERROR_PARAM1; /* signal is Slave-to-Master */ - -#ifdef CONFIG_MCHP_ESPI_DEBUG - CPRINTS("VW IntrEn for VW[%s]", - espi_vw_get_wire_name(signal)); -#endif - - ridx = vw_info_tbl[tidx].reg_idx; - src_num = vw_info_tbl[tidx].src_num; - - /* - * Set SRCn_IRQ_SELECT field for VWire to either edge - * Write enable set bit in GIRQ24 or GIRQ25 - * GIRQ24 MSVW00[0:3] through MSVW06[0:3] (bits[0:27]) - * GIRQ25 MSVW07[0:3] through MSVW10[0:3] (bits[0:25]) - */ - MCHP_ESPI_VW_M2S_IRQSEL(ridx, src_num) = - MCHP_ESPI_MSVW_IRQSEL_BOTH_EDGES; - - girq_num = 24; - if (ridx > 6) { - girq_num++; - ridx -= 7; - } - bpos = (ridx << 2) + src_num; - - MCHP_INT_SOURCE(girq_num) = (1ul << bpos); - MCHP_INT_ENABLE(girq_num) = (1ul << bpos); - - 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) -{ - int tidx; - uint8_t ridx, src_num, bpos; - - tidx = espi_vw_get_signal_index(signal); - - if (tidx < 0) - return EC_ERROR_PARAM1; - - if (0 != (vw_info_tbl[tidx].flags & (1u << 0))) - return EC_ERROR_PARAM1; /* signal is Slave-to-Master */ - -#ifdef CONFIG_MCHP_ESPI_DEBUG - CPRINTS("VW IntrDis for VW[%s]", - espi_vw_get_wire_name(signal)); -#endif - - ridx = vw_info_tbl[tidx].reg_idx; - src_num = vw_info_tbl[tidx].src_num; - - /* - * Set SRCn_IRQ_SELECT field for VWire to disabled - * Write enable set bit in GIRQ24 or GIRQ25 - * GIRQ24 MSVW00[0:3] through MSVW06[0:3] (bits[0:27]) - * GIRQ25 MSVW07[0:3] through MSVW10[0:3] (bits[0:25]) - */ - MCHP_ESPI_VW_M2S_IRQSEL(ridx, src_num) = - MCHP_ESPI_MSVW_IRQSEL_DISABLED; - - if (ridx < 7) { - bpos = (ridx << 2) + src_num; - MCHP_INT_DISABLE(24) = (1ul << bpos); - - } else { - bpos = ((ridx - 7) << 2) + src_num; - MCHP_INT_DISABLE(25) = (1ul << bpos); - } - - return EC_SUCCESS; -} - -/************************************************************************/ -/* VW event handlers */ - -#ifdef CONFIG_CHIPSET_RESET_HOOK -static void espi_chipset_reset(void) -{ - hook_notify(HOOK_CHIPSET_RESET); -} -DECLARE_DEFERRED(espi_chipset_reset); -#endif - - -/* SLP_Sx event handler */ -void espi_vw_evt_slp_s3_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SLP_S3: %d", wire_state); - espi_vw_power_signal_interrupt(VW_SLP_S3_L); -} - -void espi_vw_evt_slp_s4_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SLP_S4: %d", wire_state); - espi_vw_power_signal_interrupt(VW_SLP_S4_L); -} - -void espi_vw_evt_slp_s5_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SLP_S5: %d", wire_state); - espi_vw_power_signal_interrupt(VW_SLP_S5_L); -} - -void espi_vw_evt_sus_stat_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SUS_STAT: %d", wire_state); - espi_vw_power_signal_interrupt(VW_SUS_STAT_L); -} - -/* PLTRST# event handler */ -void espi_vw_evt_pltrst_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW PLTRST#: %d", wire_state); - - if (wire_state) /* Platform Reset de-assertion */ - espi_host_init(); - else /* assertion */ -#ifdef CONFIG_CHIPSET_RESET_HOOK - hook_call_deferred(&espi_chipset_reset_data, MSEC); -#endif - -} - -/* OOB Reset Warn event handler */ -void espi_vw_evt_oob_rst_warn(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW OOB_RST_WARN: %d", wire_state); - - espi_oob_flush(); - - espi_vw_set_wire(VW_OOB_RST_ACK, wire_state); -} - -/* SUS_WARN# event handler */ -void espi_vw_evt_sus_warn_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SUS_WARN#: %d", wire_state); - - udelay(100); - - /* - * Add any Deep Sx prep here - * NOTE: we could schedule a deferred function and have - * it send ACK to host after preparing for Deep Sx - */ -#ifdef CONFIG_MCHP_ESPI_VW_SAVE_ON_SLEEP - espi_vw_save(); -#endif - /* Send ACK to host by WARN#'s wire */ - espi_vw_set_wire(VW_SUS_ACK, wire_state); -} - -/* - * SUS_PWRDN_ACK - * PCH is informing us it does not need suspend power well. - * if SUS_PWRDN_ACK == 1 we can turn off suspend power well assuming - * hardware design allow. - */ -void espi_vw_evt_sus_pwrdn_ack(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SUS_PWRDN_ACK: %d", wire_state); -} - -/* SLP_A#(SLP_M#) */ -void espi_vw_evt_slp_a_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SLP_A: %d", wire_state); - - /* Put handling of ASW well devices here, if any */ -} - -/* HOST_RST WARN event handler */ -void espi_vw_evt_host_rst_warn(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW HOST_RST_WARN: %d", wire_state); - - espi_pc_flush(); - - /* Send HOST_RST_ACK to host */ - espi_vw_set_wire(VW_HOST_RST_ACK, wire_state); -} - -/* SLP_LAN# */ -void espi_vw_evt_slp_lan_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SLP_LAN: %d", wire_state); -} - -/* SLP_WLAN# */ -void espi_vw_evt_slp_wlan_n(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW SLP_WLAN: %d", wire_state); - -} - -void espi_vw_evt_host_c10(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("VW HOST_C10: %d", wire_state); -} - -void espi_vw_evt1_dflt(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("Unknown M2S VW: state=%d GIRQ24 bitpos=%d", wire_state, bpos); -} - -void espi_vw_evt2_dflt(uint32_t wire_state, uint32_t bpos) -{ - CPRINTS("Unknown M2S VW: state=%d GIRQ25 bitpos=%d", wire_state, bpos); -} - -/************************************************************************/ -/* Interrupt handlers */ - -/* MEC1701H - * GIRQ19 all direct connect capable, none wake capable - * b[0] = Peripheral Channel (PC) - * b[1] = Bus Master 1 (BM1) - * b[2] = Bus Master 2 (BM2) - * b[3] = LTR - * b[4] = OOB_UP - * b[5] = OOB_DN - * b[6] = Flash Channel (FC) - * b[7] = ESPI_RESET# change - * b[8] = VWire Channel (VW) enable assertion - * b[9:31] = 0 reserved - * - * GIRQ22 b[9]=ESPI interface wake peripheral logic only, not EC. - * Not direct connect capable - * - * GIRQ24 - * b[0:3] = MSVW00_SRC[0:3] - * b[4:7] = MSVW01_SRC[0:3] - * b[8:11] = MSVW02_SRC[0:3] - * b[12:15] = MSVW03_SRC[0:3] - * b[16:19] = MSVW04_SRC[0:3] - * b[20:23] = MSVW05_SRC[0:3] - * b[24:27] = MSVW06_SRC[0:3] - * b[28:31] = 0 reserved - * - * GIRQ25 - * b[0:3] = MSVW07_SRC[0:3] - * b[4:7] = MSVW08_SRC[0:3] - * b[8:11] = MSVW09_SRC[0:3] - * b[12:15] = MSVW10_SRC[0:3] - * b[16:31] = 0 reserved - * - */ - -typedef void (*FPVW)(uint32_t, uint32_t); - -#define MCHP_GIRQ24_NUM_M2S (7 * 4) -const FPVW girq24_vw_handlers[MCHP_GIRQ24_NUM_M2S] = { - espi_vw_evt_slp_s3_n, /* MSVW00, Host M2S 02h */ - espi_vw_evt_slp_s4_n, - espi_vw_evt_slp_s5_n, - espi_vw_evt1_dflt, - espi_vw_evt_sus_stat_n, /* MSVW01, Host M2S 03h */ - espi_vw_evt_pltrst_n, - espi_vw_evt_oob_rst_warn, - espi_vw_evt1_dflt, - espi_vw_evt_host_rst_warn, /* MSVW02, Host M2S 07h */ - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, - espi_vw_evt_sus_warn_n, /* MSVW03, Host M2S 41h */ - espi_vw_evt_sus_pwrdn_ack, - espi_vw_evt1_dflt, - espi_vw_evt_slp_a_n, - espi_vw_evt_slp_lan_n, /* MSVW04, Host M2S 42h */ - espi_vw_evt_slp_wlan_n, - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, /* MSVW05, Host M2S 43h */ - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, /* MSVW06, Host M2S 44h */ - espi_vw_evt1_dflt, - espi_vw_evt1_dflt, - espi_vw_evt1_dflt -}; - -#define MCHP_GIRQ25_NUM_M2S (4 * 4) -const FPVW girq25_vw_handlers[MCHP_GIRQ25_NUM_M2S] = { - espi_vw_evt_host_c10, /* MSVW07, Host M2S 47h */ - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, /* MSVW08 unassigned */ - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, /* MSVW09 unassigned */ - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, /* MSVW10 unassigned */ - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, - espi_vw_evt2_dflt, -}; - -/* Interrupt handler for eSPI virtual wires in MSVW00 - MSVW01 */ -void espi_mswv1_interrupt(void) -{ - uint32_t d, girq24_result, bpos; - - d = MCHP_INT_ENABLE(24); - girq24_result = MCHP_INT_RESULT(24); - MCHP_INT_SOURCE(24) = girq24_result; - - bpos = __builtin_ctz(girq24_result); /* rbit, clz sequence */ - while (bpos != 32) { - d = *(uint8_t *)(MCHP_ESPI_MSVW_BASE + 8 + - (12 * (bpos >> 2)) + (bpos & 0x03)) & 0x01; - (girq24_vw_handlers[bpos])(d, bpos); - girq24_result &= ~(1ul << bpos); - bpos = __builtin_ctz(girq24_result); - } -} -DECLARE_IRQ(MCHP_IRQ_GIRQ24, espi_mswv1_interrupt, 2); - - -/* Interrupt handler for eSPI virtual wires in MSVW07 - MSVW10 */ -void espi_msvw2_interrupt(void) -{ - uint32_t d, girq25_result, bpos; - - d = MCHP_INT_ENABLE(25); - girq25_result = MCHP_INT_RESULT(25); - MCHP_INT_SOURCE(25) = girq25_result; - - bpos = __builtin_ctz(girq25_result); /* rbit, clz sequence */ - while (bpos != 32) { - d = *(uint8_t *)(MCHP_ESPI_MSVW_BASE + (12 * 7) + 8 + - (12 * (bpos >> 2)) + (bpos & 0x03)) & 0x01; - (girq25_vw_handlers[bpos])(d, bpos); - girq25_result &= ~(1ul << bpos); - bpos = __builtin_ctz(girq25_result); - } -} -DECLARE_IRQ(MCHP_IRQ_GIRQ25, espi_msvw2_interrupt, 2); - - - -/* - * NOTES: - * While ESPI_RESET# is asserted, all eSPI blocks are held in reset and - * their registers can't be programmed. All channel Enable and Ready bits - * are cleared. The only operational logic is the ESPI_RESET# change - * detection logic. - * Once ESPI_RESET# de-asserts, firmware can enable interrupts on all - * other eSPI channels/components. - * Implications are: - * ESPI_RESET# assertion - - * All channel ready bits are cleared stopping all outstanding - * transactions and clearing registers and internal FIFO's. - * ESPI_RESET# de-assertion - - * All channels/components can now be programmed and can detect - * reception of channel enable messages from the eSPI Master. - */ - -/* - * eSPI Reset change handler - * Multiple scenarios must be handled. - * eSPI Link initialization from de-assertion of RSMRST# - * Upon RSMRST# de-assertion, the PCH may drive ESPI_RESET# low - * and then back high. If the platform has a pull-down on ESPI_RESET# - * then we will not see both edges. We must handle the scenario where - * ESPI_RESET# has only a rising edge or is pulsed low once RSMRST# - * has been released. - * eSPI Link is operational and PCH asserts ESPI_RESET# due to - * global reset event or some other system problem. - * eSPI link is operational and the system generates a global reset - * event to the PCH. EC is unaware of global reset and sees PCH - * activate ESPI_RESET#. - * - * ESPI_RESET# assertion will disable all MCHP eSPI channel ready - * bits and place all channels is reset state. Any hardware affected by - * ESPI_RESET# must be re-initialized after ESPI_RESET# de-asserts. - * - * Note ESPI_RESET# is not equivalent to LPC LRESET#. LRESET# is - * equivalent to eSPI Platform Reset. - * - */ -void espi_reset_isr(void) -{ - uint8_t erst; - - erst = MCHP_ESPI_IO_RESET_STATUS; - MCHP_ESPI_IO_RESET_STATUS = erst; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = MCHP_ESPI_RESET_GIRQ_BIT; - if (erst & (1ul << 1)) { /* rising edge - reset de-asserted */ - MCHP_INT_ENABLE(MCHP_ESPI_GIRQ) = ( - MCHP_ESPI_PC_GIRQ_BIT + - MCHP_ESPI_OOB_TX_GIRQ_BIT + - MCHP_ESPI_FC_GIRQ_BIT + - MCHP_ESPI_VW_EN_GIRQ_BIT); - MCHP_ESPI_OOB_TX_IEN = (1ul << 1); - MCHP_ESPI_FC_IEN = (1ul << 1); - MCHP_ESPI_PC_IEN = (1ul << 25); - CPRINTS("eSPI Reset de-assert"); - - } else { /* falling edge - reset asserted */ - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = ( - MCHP_ESPI_PC_GIRQ_BIT + - MCHP_ESPI_OOB_TX_GIRQ_BIT + - MCHP_ESPI_FC_GIRQ_BIT + - MCHP_ESPI_VW_EN_GIRQ_BIT); - MCHP_INT_DISABLE(MCHP_ESPI_GIRQ) = ( - MCHP_ESPI_PC_GIRQ_BIT + - MCHP_ESPI_OOB_TX_GIRQ_BIT + - MCHP_ESPI_FC_GIRQ_BIT + - MCHP_ESPI_VW_EN_GIRQ_BIT); - espi_channels_ready = 0; - - chipset_handle_espi_reset_assert(); - - CPRINTS("eSPI Reset assert"); - } -} -DECLARE_IRQ(MCHP_IRQ_ESPI_RESET, espi_reset_isr, 3); - -/* - * eSPI Virtual Wire channel enable handler - * Must disable once VW Enable is set by eSPI Master - */ -void espi_vw_en_isr(void) -{ - MCHP_INT_DISABLE(MCHP_ESPI_GIRQ) = MCHP_ESPI_VW_EN_GIRQ_BIT; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = MCHP_ESPI_VW_EN_GIRQ_BIT; - - MCHP_ESPI_IO_VW_READY = 1; - - espi_channels_ready |= (1ul << 0); - - CPRINTS("eSPI VW Enable received, set VW Ready"); - - if (0x03 == (espi_channels_ready & 0x03)) - espi_send_boot_load_done(); -} -DECLARE_IRQ(MCHP_IRQ_ESPI_VW_EN, espi_vw_en_isr, 2); - - -/* - * eSPI OOB TX and OOB channel enable change interrupt handler - */ -void espi_oob_tx_isr(void) -{ - uint32_t sts; - - sts = MCHP_ESPI_OOB_TX_STATUS; - MCHP_ESPI_OOB_TX_STATUS = sts; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = MCHP_ESPI_OOB_TX_GIRQ_BIT; - if (sts & (1ul << 1)) { - /* Channel Enable change */ - if (sts & (1ul << 9)) { /* enable? */ - MCHP_ESPI_OOB_RX_LEN = 73; - MCHP_ESPI_IO_OOB_READY = 1; - espi_channels_ready |= (1ul << 2); - CPRINTS("eSPI OOB_UP ISR: OOB Channel Enable"); - } else { /* no, disabled by Master */ - espi_channels_ready &= ~(1ul << 2); - CPRINTS("eSPI OOB_UP ISR: OOB Channel Disable"); - } - } else { - /* Handle OOB Up transmit status: done and/or errors, here */ - CPRINTS("eSPI OOB_UP status = 0x%x", sts); - } -} -DECLARE_IRQ(MCHP_IRQ_ESPI_OOB_UP, espi_oob_tx_isr, 2); - - -/* eSPI OOB RX interrupt handler */ -void espi_oob_rx_isr(void) -{ - uint32_t sts; - - sts = MCHP_ESPI_OOB_RX_STATUS; - MCHP_ESPI_OOB_RX_STATUS = sts; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = MCHP_ESPI_OOB_RX_GIRQ_BIT; - /* Handle OOB Up transmit status: done and/or errors, if any */ - CPRINTS("eSPI OOB_DN status = 0x%x", sts); -} -DECLARE_IRQ(MCHP_IRQ_ESPI_OOB_DN, espi_oob_rx_isr, 2); - - -/* - * eSPI Flash Channel enable change and data transfer - * interrupt handler - */ -void espi_fc_isr(void) -{ - uint32_t sts; - - sts = MCHP_ESPI_FC_STATUS; - MCHP_ESPI_FC_STATUS = sts; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = MCHP_ESPI_FC_GIRQ_BIT; - if (sts & (1ul << 1)) { - /* Channel Enable change */ - if (sts & (1ul << 0)) { /* enable? */ - MCHP_ESPI_IO_FC_READY = 1; - espi_channels_ready |= (1ul << 1); - CPRINTS("eSPI FC ISR: Enable"); - if (0x03 == (espi_channels_ready & 0x03)) - espi_send_boot_load_done(); - } else { /* no, disabled by Master */ - espi_channels_ready &= ~(1ul << 1); - CPRINTS("eSPI FC ISR: Disable"); - } - } else { - /* Handle FC command status: done and/or errors */ - CPRINTS("eSPI FC status = 0x%x", sts); - } -} -DECLARE_IRQ(MCHP_IRQ_ESPI_FC, espi_fc_isr, 2); - - -/* eSPI Peripheral Channel interrupt handler */ -void espi_pc_isr(void) -{ - uint32_t sts; - - sts = MCHP_ESPI_PC_STATUS; - MCHP_ESPI_PC_STATUS = sts; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = MCHP_ESPI_PC_GIRQ_BIT; - if (sts & (1ul << 25)) { - if (sts & (1ul << 24)) { - MCHP_ESPI_IO_PC_READY = 1; - espi_channels_ready |= (1ul << 3); - CPRINTS("eSPI PC Channel Enable"); - } else { - espi_channels_ready &= ~(1ul << 3); - CPRINTS("eSPI PC Channel Disable"); - } - - } else { - /* Handler PC channel errors here */ - CPRINTS("eSPI PC status = 0x%x", sts); - } -} -DECLARE_IRQ(MCHP_IRQ_ESPI_PC, espi_pc_isr, 2); - - -/************************************************************************/ - -/* - * Enable/disable direct mode interrupt for ESPI_RESET# change. - * Optionally clear status before enable or after disable. - */ -static void espi_reset_ictrl(int enable, int clr_status) -{ - if (enable) { - if (clr_status) { - MCHP_ESPI_IO_RESET_STATUS = - MCHP_ESPI_RST_CHG_STS; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = - MCHP_ESPI_RESET_GIRQ_BIT; - } - MCHP_ESPI_IO_RESET_IEN |= MCHP_ESPI_RST_IEN; - MCHP_INT_ENABLE(MCHP_ESPI_GIRQ) = - MCHP_ESPI_RESET_GIRQ_BIT; - task_enable_irq(MCHP_IRQ_ESPI_RESET); - } else { - task_disable_irq(MCHP_IRQ_ESPI_RESET); - MCHP_INT_DISABLE(MCHP_ESPI_GIRQ) = - MCHP_ESPI_RESET_GIRQ_BIT; - MCHP_ESPI_IO_RESET_IEN &= ~(MCHP_ESPI_RST_IEN); - if (clr_status) { - MCHP_ESPI_IO_RESET_STATUS = - MCHP_ESPI_RST_CHG_STS; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = - MCHP_ESPI_RESET_GIRQ_BIT; - } - } -} - -/* eSPI Initialization functions */ - -/* MEC1701H */ -void espi_init(void) -{ - espi_channels_ready = 0; - - CPRINTS("eSPI - espi_init"); - - /* Clear PCR eSPI sleep enable */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_ESPI); - - /* - * b[8]=0(eSPI PLTRST# VWire is platform reset), b[0]=0 - * VCC_PWRGD is asserted when PLTRST# VWire is 1(inactive) - */ - MCHP_PCR_PWR_RST_CTL = 0; - - /* - * There is no MODULE_ESPI in include/module_id.h - * eSPI pins marked as MODULE_LPC in board/myboard/board.h - * eSPI pins are on VTR3. - * Make sure VTR3 chip knows VTR3 is 1.8V - * This is done in system_pre_init() - */ - gpio_config_module(MODULE_LPC, 1); - - /* Set channel */ - MCHP_ESPI_IO_CAP0 = CONFIG_HOSTCMD_ESPI_EC_CHAN_BITMAP; - - /* Set eSPI frequency & mode */ - MCHP_ESPI_IO_CAP1 = (MCHP_ESPI_IO_CAP1 & - (~(MCHP_ESPI_CAP1_MAX_FREQ_MASK | - MCHP_ESPI_CAP1_IO_MASK))) | - CONFIG_HOSTCMD_ESPI_EC_MAX_FREQ | - (CONFIG_HOSTCMD_ESPI_EC_MODE - << MCHP_ESPI_CAP1_IO_BITPOS); - -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_ESPI_IO_PLTRST_SRC = MCHP_ESPI_PLTRST_SRC_VW; -#else - MCHP_ESPI_IO_PLTRST_SRC = MCHP_ESPI_PLTRST_SRC_PIN; -#endif - - MCHP_PCR_PWR_RST_CTL &= - ~(1ul << MCHP_PCR_PWR_HOST_RST_SEL_BITPOS); - - MCHP_ESPI_ACTIVATE = 1; - - espi_bar_pre_init(); - - /* - * VWires are configured to be reset by different events. - * Default configuration has: - * RESET_SYS (chip reset) MSVW00, MSVW04 - * RESET_ESPI MSVW01, MSVW03, SMVW00, SMVW01 - * PLTRST MSVW02, SMVW02 - */ - espi_vw_pre_init(); - - /* - * Configure MSVW00 & MSVW04 - * Any change to default values (SRCn bits) - * Any change to interrupt enable, SRCn_IRQ_SELECT bit fields - * Should interrupt bits in MSVWyx and GIRQ24/25 be touched - * before ESPI_RESET# de-asserts? - */ - - MCHP_ESPI_PC_STATUS = 0xfffffffful; - MCHP_ESPI_OOB_RX_STATUS = 0xfffffffful; - MCHP_ESPI_FC_STATUS = 0xfffffffful; - MCHP_INT_DISABLE(MCHP_ESPI_GIRQ) = 0xfffffffful; - MCHP_INT_SOURCE(MCHP_ESPI_GIRQ) = 0xfffffffful; - - task_enable_irq(MCHP_IRQ_ESPI_PC); - task_enable_irq(MCHP_IRQ_ESPI_OOB_UP); - task_enable_irq(MCHP_IRQ_ESPI_OOB_DN); - task_enable_irq(MCHP_IRQ_ESPI_FC); - task_enable_irq(MCHP_IRQ_ESPI_VW_EN); - - /* Enable eSPI Master-to-Slave Virtual wire NVIC inputs - * VWire block interrupts are all disabled by default - * and will be controlled by espi_vw_enable/disable_wire_in - */ - CPRINTS("eSPI - enable ESPI_RESET# interrupt"); - - /* Enable ESPI_RESET# interrupt and clear status */ - espi_reset_ictrl(1, 1); - - CPRINTS("eSPI - espi_init - done"); -} - - -#ifdef CONFIG_MCHP_ESPI_EC_CMD -static int command_espi(int argc, char **argv) -{ - uint32_t chan, w0, w1, w2; - char *e; - - if (argc == 1) { - return EC_ERROR_INVAL; - /* Get value of eSPI registers */ - } else if (argc == 2) { - int i; - - if (strcasecmp(argv[1], "cfg") == 0) { - ccprintf("eSPI Reg32A [0x%08x]\n", - MCHP_ESPI_IO_REG32_A); - ccprintf("eSPI Reg32B [0x%08x]\n", - MCHP_ESPI_IO_REG32_B); - ccprintf("eSPI Reg32C [0x%08x]\n", - MCHP_ESPI_IO_REG32_C); - ccprintf("eSPI Reg32D [0x%08x]\n", - MCHP_ESPI_IO_REG32_D); - } else if (strcasecmp(argv[1], "vsm") == 0) { - for (i = 0; i < MSVW_MAX; i++) { - w0 = MSVW(i, 0); - w1 = MSVW(i, 1); - w2 = MSVW(i, 2); - ccprintf("MSVW%d: 0x%08x:%08x:%08x\n", i, - w2, w1, w0); - } - } else if (strcasecmp(argv[1], "vms") == 0) { - for (i = 0; i < SMVW_MAX; i++) { - w0 = SMVW(i, 0); - w1 = SMVW(i, 1); - ccprintf("SMVW%d: 0x%08x:%08x\n", i, w1, w0); - } - } - /* Enable/Disable the channels of eSPI */ - } else if (argc == 3) { - uint32_t m = (uint32_t) strtoi(argv[2], &e, 0); - - if (*e) - return EC_ERROR_PARAM2; - if (m < 0 || m > 4) - return EC_ERROR_PARAM2; - else if (m == 4) - chan = 0x0F; - else - chan = 0x01 << m; - if (strcasecmp(argv[1], "en") == 0) - MCHP_ESPI_IO_CAP0 |= chan; - else if (strcasecmp(argv[1], "dis") == 0) - MCHP_ESPI_IO_CAP0 &= ~chan; - else - return EC_ERROR_PARAM1; - ccprintf("eSPI IO Cap0 [0x%02x]\n", MCHP_ESPI_IO_CAP0); - } - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(espi, command_espi, - "cfg/vms/vsm/en/dis [channel]", - "eSPI configurations"); -#endif diff --git a/chip/mchp/fan.c b/chip/mchp/fan.c deleted file mode 100644 index 17b60b703d..0000000000 --- a/chip/mchp/fan.c +++ /dev/null @@ -1,175 +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. - */ - -/* MCHP MEC fan control module. */ - -/* This assumes 2-pole fan. For each rotation, 5 edges are measured. */ - -#include "fan.h" -#include "registers.h" -#include "util.h" -#include "tfdp_chip.h" - -/* Maximum fan driver setting value */ -#define MAX_FAN_DRIVER_SETTING 0x3ff - -/* Fan driver setting data in bit[15:6] of hardware register */ -#define FAN_DRIVER_SETTING_SHIFT 6 - -/* Maximum tach reading/target value */ -#define MAX_TACH 0x1fff - -/* Tach target value for disable fan */ -#define FAN_OFF_TACH 0xfff8 - -/* - * RPM = (n - 1) * m * f * 60 / poles / TACH - * n = number of edges = 5 - * m = multiplier defined by RANGE = 2 in our case - * f = 32.768K - * poles = 2 - */ -#define RPM_TO_TACH(rpm) MIN((7864320 / MAX((rpm), 1)), MAX_TACH) -#define TACH_TO_RPM(tach) (7864320 / MAX((tach), 1)) - -static int rpm_setting; -static int duty_setting; -static int in_rpm_mode = 1; - - -static void clear_status(void) -{ - /* Clear DRIVE_FAIL, FAN_SPIN, and FAN_STALL bits */ - MCHP_FAN_STATUS(0) = 0x23; -} - -void fan_set_enabled(int ch, int enabled) -{ - if (in_rpm_mode) { - if (enabled) - fan_set_rpm_target(ch, rpm_setting); - else - MCHP_FAN_TARGET(0) = FAN_OFF_TACH; - } else { - if (enabled) - fan_set_duty(ch, duty_setting); - else - MCHP_FAN_SETTING(0) = 0; - } - clear_status(); -} - -int fan_get_enabled(int ch) -{ - if (in_rpm_mode) - return (MCHP_FAN_TARGET(0) & 0xff00) != 0xff00; - else - return !!MCHP_FAN_SETTING(0); -} - -void fan_set_duty(int ch, int percent) -{ - if (percent < 0) - percent = 0; - else if (percent > 100) - percent = 100; - - duty_setting = percent; - MCHP_FAN_SETTING(0) = (percent * MAX_FAN_DRIVER_SETTING / 100) - << FAN_DRIVER_SETTING_SHIFT; - clear_status(); -} - -int fan_get_duty(int ch) -{ - duty_setting = (MCHP_FAN_SETTING(0) >> FAN_DRIVER_SETTING_SHIFT) - * 100 / MAX_FAN_DRIVER_SETTING; - return duty_setting; -} - -int fan_get_rpm_mode(int ch) -{ - return !!(MCHP_FAN_CFG1(0) & BIT(7)); -} - -void fan_set_rpm_mode(int ch, int rpm_mode) -{ - if (rpm_mode) - MCHP_FAN_CFG1(0) |= BIT(7); - else - MCHP_FAN_CFG1(0) &= ~BIT(7); - clear_status(); -} - -int fan_get_rpm_actual(int ch) -{ - if ((MCHP_FAN_READING(0) >> 8) == 0xff) - return 0; - else - return TACH_TO_RPM(MCHP_FAN_READING(0) >> 3); -} - -int fan_get_rpm_target(int ch) -{ - return rpm_setting; -} - -void fan_set_rpm_target(int ch, int rpm) -{ - rpm_setting = rpm; - MCHP_FAN_TARGET(0) = RPM_TO_TACH(rpm) << 3; - clear_status(); -} - -enum fan_status fan_get_status(int ch) -{ - uint8_t sts = MCHP_FAN_STATUS(0); - - if (sts & (BIT(5) | BIT(1))) - return FAN_STATUS_FRUSTRATED; - if (fan_get_rpm_actual(ch) == 0) - return FAN_STATUS_STOPPED; - return FAN_STATUS_LOCKED; -} - -int fan_is_stalled(int ch) -{ - uint8_t sts = MCHP_FAN_STATUS(0); - - if (fan_get_rpm_actual(ch)) { - MCHP_FAN_STATUS(0) = 0x1; - return 0; - } - return sts & 0x1; -} - -void fan_channel_setup(int ch, unsigned int flags) -{ - /* Clear PCR sleep enable for RPM2FAN0 */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_RPMPWM0); - /* Configure PWM Min drive */ - MCHP_FAN_MIN_DRV(0) = 0x0A; - /* - * Fan configuration 1 register: - * 0x80 = bit 7 = RPM mode (0x00 if FAN_USE_RPM_MODE not set) - * 0x20 = bits 6:5 = min 1000 RPM, multiplier = 2 - * 0x08 = bits 4:3 = 5 edges, 2 poles - * 0x03 = bits 2:0 = 400 ms update time - * - * Fan configuration 2 register: - * 0x00 = bit 7 = Ramp control disabled - * 0x00 = bit 6 = Glitch filter enabled - * 0x30 = bits 5:4 = Using both derivative options - * 0x04 = bits 3:2 = error range is 50 RPM - * 0x00 = bits 1 = normal polarity - * 0x00 = bit 0 = Reserved - */ - if (flags & FAN_USE_RPM_MODE) - MCHP_FAN_CFG1(0) = 0xab; - else - MCHP_FAN_CFG1(0) = 0x2b; - MCHP_FAN_CFG2(0) = 0x34; - clear_status(); -} diff --git a/chip/mchp/flash.c b/chip/mchp/flash.c deleted file mode 100644 index 1679cf92cb..0000000000 --- a/chip/mchp/flash.c +++ /dev/null @@ -1,278 +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 "common.h" -#include "console.h" -#include "flash.h" -#include "host_command.h" -#include "shared_mem.h" -#include "spi.h" -#include "spi_flash.h" -#include "system.h" -#include "util.h" -#include "hooks.h" -#include "tfdp_chip.h" - -#define PAGE_SIZE 256 - -#define FLASH_SYSJUMP_TAG 0x5750 /* "WP" - Write Protect */ -#define FLASH_HOOK_VERSION 1 - -static int entire_flash_locked; - -/* The previous write protect state before sys jump */ - -struct flash_wp_state { - int entire_flash_locked; -}; - -/** - * Read from physical flash. - * - * @param offset Flash offset to write. - * @param size Number of bytes to write. - * @param data Destination buffer for data. - */ -int crec_flash_physical_read(int offset, int size, char *data) -{ - trace13(0, FLASH, 0, - "flash_phys_read: offset=0x%08X size=0x%08X dataptr=0x%08X", - offset, size, (uint32_t)data); - return spi_flash_read(data, offset, size); -} - -/** - * 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 crec_flash_physical_write(int offset, int size, const char *data) -{ - int ret = EC_SUCCESS; - int i, write_size; - - trace13(0, FLASH, 0, - "flash_phys_write: offset=0x%08X size=0x%08X dataptr=0x%08X", - offset, size, (uint32_t)data); - - if (entire_flash_locked) - return EC_ERROR_ACCESS_DENIED; - - /* Fail if offset, size, and data aren't at least word-aligned */ - if ((offset | size | (uint32_t)(uintptr_t)data) & 3) - return EC_ERROR_INVAL; - - for (i = 0; i < size; i += write_size) { - write_size = MIN((size - i), SPI_FLASH_MAX_WRITE_SIZE); - ret = spi_flash_write(offset + i, - write_size, - (uint8_t *)data + i); - if (ret != EC_SUCCESS) - break; - } - 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 crec_flash_physical_erase(int offset, int size) -{ - int ret; - - if (entire_flash_locked) - return EC_ERROR_ACCESS_DENIED; - - trace12(0, FLASH, 0, - "flash_phys_erase: offset=0x%08X size=0x%08X", - offset, size); - ret = spi_flash_erase(offset, size); - 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 spi_flash_check_protect(bank * CONFIG_FLASH_BANK_SIZE, - CONFIG_FLASH_BANK_SIZE); -} - -/** - * Protect flash now. - * - * This is always successful, and only emulates "now" protection - * - * @param all Protect all (=1) or just read-only - * @return non-zero if error. - */ -int crec_flash_physical_protect_now(int all) -{ - if (all) - entire_flash_locked = 1; - - /* - * RO "now" protection is not currently implemented. If needed, it - * can be added by splitting the entire_flash_locked variable into - * and RO and RW vars, and setting + checking the appropriate var - * as required. - */ - 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; - - if (spi_flash_check_protect(CONFIG_WP_STORAGE_OFF, - CONFIG_WP_STORAGE_SIZE)) { - flags |= EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_RO_NOW; - } - - if (entire_flash_locked) - flags |= EC_FLASH_PROTECT_ALL_NOW; - - 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; - enum spi_flash_wp wp_status = SPI_WP_NONE; - - wp_status = spi_flash_check_wp(); - - if (wp_status == SPI_WP_NONE || (wp_status == SPI_WP_HARDWARE && - !(cur_flags & EC_FLASH_PROTECT_GPIO_ASSERTED))) - ret = EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_RO_NOW; - - if (!entire_flash_locked) - ret |= EC_FLASH_PROTECT_ALL_NOW; - - return ret; -} - -/** - * Enable write protect for the specified range. - * - * Once write protect is enabled, it will stay enabled until HW PIN is - * de-asserted and SRP register is unset. - * - * However, this implementation treats FLASH_WP_ALL as FLASH_WP_RO but - * tries to remember if "all" region is protected. - * - * @param range The range to protect. - * @return EC_SUCCESS, or nonzero if error. - */ -int crec_flash_physical_protect_at_boot(uint32_t new_flags) -{ - int offset, size, ret; - enum spi_flash_wp flashwp = SPI_WP_NONE; - - if ((new_flags & (EC_FLASH_PROTECT_RO_AT_BOOT | - EC_FLASH_PROTECT_ALL_AT_BOOT)) == 0) { - /* Clear protection */ - offset = size = 0; - flashwp = SPI_WP_NONE; - } else { - if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT) - entire_flash_locked = 1; - - offset = CONFIG_WP_STORAGE_OFF; - size = CONFIG_WP_STORAGE_SIZE; - flashwp = SPI_WP_HARDWARE; - } - - ret = spi_flash_set_protect(offset, size); - if (ret == EC_SUCCESS) - ret = spi_flash_set_wp(flashwp); - return ret; -} - -/** - * Initialize the module. - * - * Applies at-boot protection settings if necessary. - */ -int crec_flash_pre_init(void) -{ - crec_flash_physical_restore_state(); - return EC_SUCCESS; -} - -int crec_flash_physical_restore_state(void) -{ - uint32_t reset_flags = system_get_reset_flags(); - int version, size; - const struct flash_wp_state *prev; - - /* - * 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) { - prev = (const struct flash_wp_state *)system_get_jump_tag( - FLASH_SYSJUMP_TAG, &version, &size); - if (prev && version == FLASH_HOOK_VERSION && - size == sizeof(*prev)) - entire_flash_locked = prev->entire_flash_locked; - return 1; - } - - return 0; -} - -/************************************************************************/ -/* Hooks */ - -static void flash_preserve_state(void) -{ - struct flash_wp_state state; - - state.entire_flash_locked = entire_flash_locked; - - system_add_jump_tag(FLASH_SYSJUMP_TAG, FLASH_HOOK_VERSION, - sizeof(state), &state); -} -DECLARE_HOOK(HOOK_SYSJUMP, flash_preserve_state, HOOK_PRIO_DEFAULT); diff --git a/chip/mchp/gpio.c b/chip/mchp/gpio.c deleted file mode 100644 index 611ced1019..0000000000 --- a/chip/mchp/gpio.c +++ /dev/null @@ -1,497 +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. - */ - -/* GPIO module for MCHP MEC */ - -#include "common.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "lpc_chip.h" -#include "tfdp_chip.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) - - -struct gpio_int_mapping { - int8_t girq_id; - int8_t port_offset; -}; - -/* - * Mapping from GPIO port to GIRQ info - * MEC17xx each bank contains 32 GPIO's. - * Pin Id is the bit position [0:31] - * Bank GPIO's GIRQ - * 0 0000 - 0036 11 - * 1 0040 - 0076 10 - * 2 0100 - 0135 9 - * 3 0140 - 0175 8 - * 4 0200 - 0235 12 - * 5 0240 - 0276 26 - */ -static const struct gpio_int_mapping int_map[] = { - { 11, 0 }, { 10, 1 }, { 9, 2 }, - { 8, 3 }, { 12, 4 }, { 26, 5 } -}; -BUILD_ASSERT(ARRAY_SIZE(int_map) == MCHP_GPIO_MAX_PORT); - -/* - * These pins default to BGPO functionality. BGPO overrides GPIO Control - * register programming. If the pin is in the GPIO list the user wants to - * use the pin as GPIO and we must disable BGPIO functionality for this pin. - */ -struct bgpo_pin { - uint16_t pin; - uint8_t bgpo_pos; -}; - -static const struct bgpo_pin bgpo_list[] = { - { 0101, 1 }, /* GPIO 0101 */ - { 0102, 2 }, /* GPIO 0102 */ -#if defined(CHIP_FAMILY_MEC152X) - { 0253, 0 }, /* GPIO 0253 */ -#elif defined(CHIP_FAMILY_MEC170X) - { 0172, 3 }, /* GPIO 0172 */ -#endif -}; - -static const uint32_t bgpo_map[] = { -#if defined(CHIP_FAMILY_MEC152X) - 0, 0, (BIT(1) | BIT(2)), 0, 0, BIT(11) -#elif defined(CHIP_FAMILY_MEC170X) - 0, 0, (BIT(1) | BIT(2)), BIT(26), 0, 0 -#else - 0, 0, 0, 0, 0, 0 -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(bgpo_map) == MCHP_GPIO_MAX_PORT); - -/* Check for BGPO capable pins on this port and disable BGPO feature */ -static void disable_bgpo(uint32_t port, uint32_t mask) -{ - int i, n; - uint32_t gpnum; - uint32_t m = bgpo_map[port] & mask; - - while (m) { - i = __builtin_ffs(m) - 1; - gpnum = (port * 32U) + i; - for (n = 0; n < ARRAY_SIZE(bgpo_list); n++) - if (gpnum == bgpo_list[n].pin) - MCHP_WKTIMER_BGPO_POWER &= - ~BIT(bgpo_list[n].bgpo_pos); - m &= ~BIT(i); - } -} - -/* - * NOTE: GCC __builtin_ffs(val) returns (index + 1) of least significant - * 1-bit of val or if val == 0 returns 0 - */ -void gpio_set_alternate_function(uint32_t port, uint32_t mask, - enum gpio_alternate_func func) -{ - int i; - uint32_t val; - - if (port >= MCHP_GPIO_MAX_PORT) - return; - - while (mask) { - i = __builtin_ffs(mask) - 1; - val = MCHP_GPIO_CTL(port, i); - val &= ~(BIT(12) | BIT(13)); - /* mux_control = DEFAULT, indicates GPIO */ - if (func > GPIO_ALT_FUNC_DEFAULT) - val |= (func & 0x3) << 12; - MCHP_GPIO_CTL(port, i) = val; - mask &= ~BIT(i); - } -} - -test_mockable int gpio_get_level(enum gpio_signal signal) -{ - uint32_t mask = gpio_list[signal].mask; - int i; - uint32_t val; - - if (mask == 0) - return 0; - i = GPIO_MASK_TO_NUM(mask); - val = MCHP_GPIO_CTL(gpio_list[signal].port, i); - - return (val & BIT(24)) ? 1 : 0; -} - -void gpio_set_level(enum gpio_signal signal, int value) -{ - uint32_t mask = gpio_list[signal].mask; - int i; - - if (mask == 0) - return; - i = GPIO_MASK_TO_NUM(mask); - - if (value) - MCHP_GPIO_CTL(gpio_list[signal].port, i) |= BIT(16); - else - MCHP_GPIO_CTL(gpio_list[signal].port, i) &= ~BIT(16); -} - -/* - * Add support for new #ifdef CONFIG_CMD_GPIO_POWER_DOWN. - * If GPIO_POWER_DOWN flag is set force GPIO Control to - * GPIO input, interrupt detect disabled, power control field - * in bits[3:2]=10b. - * NOTE: if interrupt detect is enabled when pin is powered down - * then a false edge may be detected. - * NOTE 2: MEC152x family implements input pad disable (bit[15]=1). - */ -void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) -{ - int i; - uint32_t val; - - if (port >= MCHP_GPIO_MAX_PORT) - return; - - while (mask) { - i = GPIO_MASK_TO_NUM(mask); - mask &= ~BIT(i); - val = MCHP_GPIO_CTL(port, i); - -#ifdef CONFIG_GPIO_POWER_DOWN - if (flags & GPIO_POWER_DOWN) { - val = (MCHP_GPIO_CTRL_PWR_OFF - | MCHP_GPIO_INTDET_DISABLED - | MCHP_GPIO_CTRL_DIS_INPUT_BIT); - - MCHP_GPIO_CTL(port, i) = val; - continue; - } -#endif - val &= ~(MCHP_GPIO_CTRL_PWR_MASK - | MCHP_GPIO_CTRL_DIS_INPUT_BIT); - - val |= MCHP_GPIO_CTRL_PWR_VTR; - /* - * Select open drain first, so that we don't - * glitch the signal when changing the line to - * an output. - */ - if (flags & GPIO_OPEN_DRAIN) - val |= (MCHP_GPIO_OPEN_DRAIN); - else - val &= ~(MCHP_GPIO_OPEN_DRAIN); - - if (flags & GPIO_OUTPUT) { - val |= (MCHP_GPIO_OUTPUT); - val &= ~(MCHP_GPIO_OUTSEL_PAR); - } else { - val &= ~(MCHP_GPIO_OUTPUT); - val |= (MCHP_GPIO_OUTSEL_PAR); - } - - /* Handle pull-up / pull-down */ - val &= ~(MCHP_GPIO_CTRL_PUD_MASK); - if (flags & GPIO_PULL_UP) - val |= MCHP_GPIO_CTRL_PUD_PU; - else if (flags & GPIO_PULL_DOWN) - val |= MCHP_GPIO_CTRL_PUD_PD; - else - val |= MCHP_GPIO_CTRL_PUD_NONE; - - /* Set up interrupt */ - val &= ~(MCHP_GPIO_INTDET_MASK); - switch (flags & GPIO_INT_ANY) { - case GPIO_INT_F_RISING: - val |= MCHP_GPIO_INTDET_EDGE_RIS; - break; - case GPIO_INT_F_FALLING: - val |= MCHP_GPIO_INTDET_EDGE_FALL; - break; - case GPIO_INT_BOTH: /* both edges */ - val |= MCHP_GPIO_INTDET_EDGE_BOTH; - break; - case GPIO_INT_F_LOW: - val |= MCHP_GPIO_INTDET_LVL_LO; - break; - case GPIO_INT_F_HIGH: - val |= MCHP_GPIO_INTDET_LVL_HI; - break; - default: - val |= MCHP_GPIO_INTDET_DISABLED; - break; - } - - /* Set up level */ - if (flags & GPIO_HIGH) - val |= (MCHP_GPIO_CTRL_OUT_LVL); - else if (flags & GPIO_LOW) - val &= ~(MCHP_GPIO_CTRL_OUT_LVL); - - MCHP_GPIO_CTL(port, i) = val; - } -} - -void gpio_power_off_by_mask(uint32_t port, uint32_t mask) -{ - int i; - - if (port >= MCHP_GPIO_MAX_PORT) - return; - - while (mask) { - i = GPIO_MASK_TO_NUM(mask); - mask &= ~BIT(i); - MCHP_GPIO_CTL(port, i) = (MCHP_GPIO_CTRL_PWR_OFF - | MCHP_GPIO_INTDET_DISABLED - | MCHP_GPIO_CTRL_DIS_INPUT_BIT); - } -} - -int gpio_power_off(enum gpio_signal signal) -{ - int i, port; - - if (gpio_list[signal].mask == 0) - return EC_ERROR_INVAL; - - i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); - port = gpio_list[signal].port; - MCHP_GPIO_CTL(port, i) = (MCHP_GPIO_CTRL_PWR_OFF - | MCHP_GPIO_INTDET_DISABLED - | MCHP_GPIO_CTRL_DIS_INPUT_BIT); - - return EC_SUCCESS; -} - -/* - * gpio_list[signal].port = [0, 6] each port contains up to 32 pins - * gpio_list[signal].mask = bit mask in 32-bit port - * NOTE: MCHP GPIO are always aggregated not direct connected to NVIC. - * GPIO's are aggregated into banks of 32 pins. - * Each bank/port are connected to a GIRQ. - * int_map[port].girq_id is the GIRQ ID - * The bit number in the GIRQ registers is the same as the bit number - * in the GPIO bank. - */ -int gpio_enable_interrupt(enum gpio_signal signal) -{ - int i, port, girq_id; - - if (gpio_list[signal].mask == 0) - return EC_SUCCESS; - - i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); - port = gpio_list[signal].port; - girq_id = int_map[port].girq_id; - - MCHP_INT_ENABLE(girq_id) = BIT(i); - MCHP_INT_BLK_EN |= BIT(girq_id); - - return EC_SUCCESS; -} - -int gpio_disable_interrupt(enum gpio_signal signal) -{ - int i, port, girq_id; - - if (gpio_list[signal].mask == 0) - return EC_SUCCESS; - - i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); - port = gpio_list[signal].port; - girq_id = int_map[port].girq_id; - - - MCHP_INT_DISABLE(girq_id) = BIT(i); - - return EC_SUCCESS; -} - -/* - * MCHP Interrupt Source is R/W1C no need for read-modify-write. - * GPIO's are aggregated meaning the NVIC Pending bit may be - * set for another GPIO in the GIRQ. You can clear NVIC pending - * and the hardware should re-assert it within one Cortex-M4 clock. - * If the Cortex-M4 is clocked slower than AHB then the Cortex-M4 - * will take longer to register the interrupt. Not clearing NVIC - * pending leave a pending status if only the GPIO this routine - * clears is pending. - * NVIC (system control) register space is strongly-ordered - * Interrupt Aggregator is in Device space (system bus connected - * to AHB) with the Cortex-M4 write buffer. - * We need to insure the write to aggregator register in device - * AHB space completes before NVIC pending is cleared. - * The Cortex-M4 memory ordering rules imply Device access - * comes before strongly ordered access. Cortex-M4 will not re-order - * the writes. Due to the presence of the write buffer a DSB will - * not guarantee the clearing of the device status completes. Add - * a read back before clearing NVIC pending. - * GIRQ 8, 9, 10, 11, 12, 26 map to NVIC inputs 0, 1, 2, 3, 4, and 18. - */ -int gpio_clear_pending_interrupt(enum gpio_signal signal) -{ - int i, port, girq_id; - - if (gpio_list[signal].mask == 0) - return EC_SUCCESS; - - i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); - port = gpio_list[signal].port; - girq_id = int_map[port].girq_id; - - /* Clear interrupt source sticky status bit even if not enabled */ - MCHP_INT_SOURCE(girq_id) = BIT(i); - i = MCHP_INT_SOURCE(girq_id); - task_clear_pending_irq(girq_id - 8); - - return EC_SUCCESS; -} - -/* - * MCHP NOTE - called from main before scheduler started - */ -void gpio_pre_init(void) -{ - int i; - int flags; - int is_warm = system_is_reboot_warm(); - const struct gpio_info *g = gpio_list; - - - for (i = 0; i < GPIO_COUNT; i++, g++) { - flags = g->flags; - - if (flags & GPIO_DEFAULT) - continue; - - /* - * If this is a warm reboot, don't set the output levels or - * we'll shut off the AP. - */ - if (is_warm) - flags &= ~(GPIO_LOW | GPIO_HIGH); - - disable_bgpo(g->port, g->mask); - - gpio_set_flags_by_mask(g->port, g->mask, flags); - - /* Use as GPIO, not alternate function */ - gpio_set_alternate_function(g->port, g->mask, - GPIO_ALT_FUNC_NONE); - } -} - -/* Clear any interrupt flags before enabling GPIO interrupt - * Original code has flaws. - * Writing result register to source only clears bits that have their - * enable and sources bits set. - * We must clear the NVIC pending R/W bit before setting NVIC enable. - * NVIC Pending is only cleared by the NVIC HW on ISR entry. - * Modifications are: - * 1. Clear all status bits in each GPIO GIRQ. This assumes any edges - * will occur after gpio_init. The old code is also making this - * assumption for the GPIO's that have been enabled. - * 2. Clear NVIC pending to prevent ISR firing on false edge. - */ -#define ENABLE_GPIO_GIRQ(x) \ - do { \ - MCHP_INT_SOURCE(x) = 0xfffffffful; \ - task_clear_pending_irq(MCHP_IRQ_GIRQ ## x); \ - task_enable_irq(MCHP_IRQ_GIRQ ## x); \ - } while (0) - - -static void gpio_init(void) -{ - ENABLE_GPIO_GIRQ(8); - ENABLE_GPIO_GIRQ(9); - ENABLE_GPIO_GIRQ(10); - ENABLE_GPIO_GIRQ(11); - ENABLE_GPIO_GIRQ(12); - ENABLE_GPIO_GIRQ(26); -} -DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT); - -/************************************************************************/ -/* Interrupt handlers */ - - -/** - * Handler for each GIRQ interrupt. This reads and clears the interrupt - * bits for the GIRQ interrupt, then finds and calls the corresponding - * GPIO interrupt handlers. - * - * @param girq GIRQ index - * @param port zero based GPIO port number [0, 5] - * @note __builtin_ffs(x) returns bitpos+1 of least significant 1-bit - * in x or 0 if no bits are set. - */ -static void gpio_interrupt(int girq, int port) -{ - int i, bit; - const struct gpio_info *g = gpio_list; - uint32_t sts = MCHP_INT_RESULT(girq); - - /* RW1C, no need for read-modify-write */ - MCHP_INT_SOURCE(girq) = sts; - - trace12(0, GPIO, 0, "GPIO GIRQ %d result = 0x%08x", girq, sts); - trace12(0, GPIO, 0, "GPIO ParIn[%d] = 0x%08x", - port, MCHP_GPIO_PARIN(port)); - - for (i = 0; (i < GPIO_IH_COUNT) && sts; ++i, ++g) { - if (g->port != port) - continue; - - bit = __builtin_ffs(g->mask); - if (bit) { - bit--; - if (sts & BIT(bit)) { - trace12(0, GPIO, 0, - "Bit[%d]: handler @ 0x%08x", bit, - (uint32_t)gpio_irq_handlers[i]); - gpio_irq_handlers[i](i); - } - sts &= ~BIT(bit); - } - } -} - -#define GPIO_IRQ_FUNC(irqfunc, girq, port)\ - void irqfunc(void) \ - { \ - gpio_interrupt(girq, port);\ - } - -GPIO_IRQ_FUNC(__girq_8_interrupt, 8, 3); -GPIO_IRQ_FUNC(__girq_9_interrupt, 9, 2); -GPIO_IRQ_FUNC(__girq_10_interrupt, 10, 1); -GPIO_IRQ_FUNC(__girq_11_interrupt, 11, 0); -GPIO_IRQ_FUNC(__girq_12_interrupt, 12, 4); -GPIO_IRQ_FUNC(__girq_26_interrupt, 26, 5); - -#undef GPIO_IRQ_FUNC - -/* - * Declare IRQs. Nesting this macro inside the GPIO_IRQ_FUNC macro works - * poorly because DECLARE_IRQ() stringizes its inputs. - */ -DECLARE_IRQ(MCHP_IRQ_GIRQ8, __girq_8_interrupt, 1); -DECLARE_IRQ(MCHP_IRQ_GIRQ9, __girq_9_interrupt, 1); -DECLARE_IRQ(MCHP_IRQ_GIRQ10, __girq_10_interrupt, 1); -DECLARE_IRQ(MCHP_IRQ_GIRQ11, __girq_11_interrupt, 1); -DECLARE_IRQ(MCHP_IRQ_GIRQ12, __girq_12_interrupt, 1); -DECLARE_IRQ(MCHP_IRQ_GIRQ26, __girq_26_interrupt, 1); - diff --git a/chip/mchp/gpio_chip.h b/chip/mchp/gpio_chip.h deleted file mode 100644 index 7baaa76fa2..0000000000 --- a/chip/mchp/gpio_chip.h +++ /dev/null @@ -1,38 +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. - * - * Register map for MCHP MEC processor - */ -/** @file gpio_chip.h - *MEC GPIO module - */ -/** @defgroup MEC gpio - */ - -#ifndef _GPIO_CHIP_H -#define _GPIO_CHIP_H - -#include <stdint.h> -#include <stddef.h> - -#include "gpio.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Place any C interfaces here */ - -int gpio_power_off(enum gpio_signal signal); - -void gpio_power_off_by_mask(uint32_t port, uint32_t mask); - -#ifdef __cplusplus -} -#endif - -#endif /* #ifndef _GPIO_CHIP_H */ -/** @} - */ - diff --git a/chip/mchp/gpio_cmds.c b/chip/mchp/gpio_cmds.c deleted file mode 100644 index cbf5f4c462..0000000000 --- a/chip/mchp/gpio_cmds.c +++ /dev/null @@ -1,97 +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. - */ - -/* MCHP MEC GPIO module EC UART commands */ - -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "system.h" -#include "util.h" -#include "gpio_chip.h" -#include "tfdp_chip.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) - - - -static int cmd_gp_get_config(int argc, char **argv) -{ - char *e; - int i; - uint32_t gctrl; - - /* If a signal is specified, print only that one */ - if (argc == 2) { - i = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - - if (!gpio_is_implemented(i)) - return EC_ERROR_PARAM1; - - gctrl = MCHP_GPIO_CTRL(i); - - ccprintf(" GPIO[0x%X].Ctrl = 0x%08X\n", i, gctrl); - - } else { /* Otherwise print them all */ - for (i = 0; i < GPIO_COUNT; i++) { - if (!gpio_is_implemented(i)) - continue; /* Skip unsupported signals */ - - gctrl = MCHP_GPIO_CTRL(i); - - ccprintf(" GPIO[0x%X].Ctrl = 0x%08X\n", i, gctrl); - } - } - - /* Flush console to avoid truncating output */ - cflush(); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(gpgetcfg, cmd_gp_get_config, - "[number]", - "Read GPIO config"); - -static int cmd_gp_set_config(int argc, char **argv) -{ - char *e; - int i; - uint32_t gctrl; - - /* If a signal is specified, print only that one */ - if (argc > 2) { - i = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - - if (!gpio_is_implemented(i)) - return EC_ERROR_PARAM1; - - gctrl = (uint32_t)strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - - MCHP_GPIO_CTRL(i) = gctrl; - gctrl = MCHP_GPIO_CTRL(i); - ccprintf(" GPIO[0x%X].Ctrl = 0x%08X\n", i, gctrl); - - } else { - ccprintf(" Requires two parameters: GPIO num and new config"); - } - /* Flush console to avoid truncating output */ - cflush(); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(gpsetcfg, cmd_gp_set_config, - "gp_num val", - "Set GPIO config"); - diff --git a/chip/mchp/gpspi.c b/chip/mchp/gpspi.c deleted file mode 100644 index 5234db8260..0000000000 --- a/chip/mchp/gpspi.c +++ /dev/null @@ -1,267 +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. - */ - -/* General Purpose SPI master module for MCHP MEC */ - -#include "common.h" -#include "console.h" -#include "dma.h" -#include "gpio.h" -#include "registers.h" -#include "spi.h" -#include "timer.h" -#include "util.h" -#include "hooks.h" -#include "task.h" -#include "spi_chip.h" -#include "gpspi_chip.h" -#include "tfdp_chip.h" - -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) - -#define SPI_BYTE_TRANSFER_TIMEOUT_US (3 * MSEC) -/* One byte at 12 MHz full duplex = 0.67 us */ -#define SPI_BYTE_TRANSFER_POLL_INTERVAL_US 20 - -/* - * GP-SPI - */ - -/** - * Return zero based GPSPI controller index given hardware port. - * @param hw_port b[7:4]==1 (GPSPI), b[3:0]=0(GPSPI0), 1(GPSPI1) - * @return 0(GPSPI0) or 1(GPSPI1) - */ -static uint8_t gpspi_port_to_ctrl_id(uint8_t hw_port) -{ - return (hw_port & 0x01); -} - -static int gpspi_wait_byte(const int ctrl) -{ - timestamp_t deadline; - - deadline.val = get_time().val + SPI_BYTE_TRANSFER_TIMEOUT_US; - while ((MCHP_SPI_SR(ctrl) & 0x3) != 0x3) { - if (timestamp_expired(deadline, NULL)) - return EC_ERROR_TIMEOUT; - usleep(SPI_BYTE_TRANSFER_POLL_INTERVAL_US); - } - return EC_SUCCESS; -} - -/* NOTE: auto-read must be disabled before calling this routine! */ -static void gpspi_rx_fifo_clean(const int ctrl) -{ - uint8_t unused = 0; - - /* If ACTIVE and/or RXFF then clean it */ - if ((MCHP_SPI_SR(ctrl) & 0x4) == 0x4) - unused += MCHP_SPI_RD(ctrl); - - if ((MCHP_SPI_SR(ctrl) & 0x2) == 0x2) - unused += MCHP_SPI_RD(ctrl); -} -/* - * NOTE: auto-read must be disabled before calling this routine! - */ -#ifndef CONFIG_MCHP_GPSPI_TX_DMA -static int gpspi_tx(const int ctrl, const uint8_t *txdata, int txlen) -{ - int i; - int ret; - uint8_t unused = 0; - - gpspi_rx_fifo_clean(ctrl); - - ret = EC_SUCCESS; - for (i = 0; i < txlen; ++i) { - MCHP_SPI_TD(ctrl) = txdata[i]; - ret = gpspi_wait_byte(ctrl); - if (ret != EC_SUCCESS) - break; - unused += MCHP_SPI_RD(ctrl); - } - - return ret; -} -#endif - -int gpspi_transaction_async(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - int hw_port, ctrl; - int ret = EC_SUCCESS; - int cs_asserted = 0; - const struct dma_option *opdma; -#ifdef CONFIG_MCHP_GPSPI_TX_DMA - dma_chan_t *chan; -#endif - if (spi_device == NULL) - return EC_ERROR_PARAM1; - - hw_port = spi_device->port; - - ctrl = gpspi_port_to_ctrl_id(hw_port); - - /* Disable auto read */ - MCHP_SPI_CR(ctrl) &= ~BIT(5); - - if ((txdata != NULL) && (txdata != 0)) { -#ifdef CONFIG_MCHP_GPSPI_TX_DMA - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_WR); - if (opdma == NULL) - return EC_ERROR_INVAL; - - gpspi_rx_fifo_clean(ctrl); - - dma_prepare_tx(opdma, txlen, txdata); - - chan = dma_get_channel(opdma->channel); - - gpio_set_level(spi_device->gpio_cs, 0); - cs_asserted = 1; - - dma_go(chan); - ret = dma_wait(opdma->channel); - if (ret == EC_SUCCESS) - ret = gpspi_wait_byte(ctrl); - - dma_disable(opdma->channel); - dma_clear_isr(opdma->channel); - - gpspi_rx_fifo_clean(ctrl); -#else - gpio_set_level(spi_device->gpio_cs, 0); - cs_asserted = 1; - - ret = gpspi_tx(ctrl, txdata, txlen); -#endif - } - - if (ret == EC_SUCCESS) - if ((rxlen != 0) && (rxdata != NULL)) { - ret = EC_ERROR_INVAL; - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - if (opdma != NULL) { - if (!cs_asserted) - gpio_set_level(spi_device->gpio_cs, 0); - /* Enable auto read */ - MCHP_SPI_CR(ctrl) |= BIT(5); - dma_start_rx(opdma, rxlen, rxdata); - MCHP_SPI_TD(ctrl) = 0; - ret = EC_SUCCESS; - } - } - - return ret; -} - -int gpspi_transaction_flush(const struct spi_device_t *spi_device) -{ - int ctrl, hw_port; - int ret; - enum dma_channel chan; - const struct dma_option *opdma; - timestamp_t deadline; - - if (spi_device == NULL) - return EC_ERROR_PARAM1; - - hw_port = spi_device->port; - ctrl = gpspi_port_to_ctrl_id(hw_port); - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - chan = opdma->channel; - - ret = dma_wait(chan); - - /* Disable auto read */ - MCHP_SPI_CR(ctrl) &= ~BIT(5); - - deadline.val = get_time().val + SPI_BYTE_TRANSFER_TIMEOUT_US; - /* Wait for FIFO empty SPISR_TXBE */ - while ((MCHP_SPI_SR(ctrl) & 0x01) != 0x1) { - if (timestamp_expired(deadline, NULL)) { - ret = EC_ERROR_TIMEOUT; - break; - } - usleep(SPI_BYTE_TRANSFER_POLL_INTERVAL_US); - } - - dma_disable(chan); - dma_clear_isr(chan); - if (MCHP_SPI_SR(ctrl) & 0x2) - hw_port = MCHP_SPI_RD(ctrl); - - gpio_set_level(spi_device->gpio_cs, 1); - - return ret; -} - -int gpspi_transaction_wait(const struct spi_device_t *spi_device) -{ - const struct dma_option *opdma; - - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - - return dma_wait(opdma->channel); -} - -/** - * Enable GPSPI controller and MODULE_SPI_CONTROLLER pins - * - * @param hw_port b[7:4]=1 b[3:0]=0(GPSPI0), 1(GPSPI1) - * @param enable - * @return EC_SUCCESS or EC_ERROR_INVAL if port is unrecognized - * @note called from mec1701/spi.c - * - */ -int gpspi_enable(int hw_port, int enable) -{ - uint32_t ctrl; - - if ((hw_port != GPSPI0_PORT) && (hw_port != GPSPI1_PORT)) - return EC_ERROR_INVAL; - - gpio_config_module(MODULE_SPI_CONTROLLER, (enable > 0)); - - ctrl = (uint32_t)hw_port & 0x0f; - - if (enable) { - - if (ctrl) - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_GPSPI1); - else - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_GPSPI0); - - /* Set enable bit in SPI_AR */ - MCHP_SPI_AR(ctrl) |= 0x1; - - /* Set SPDIN to 0 -> Full duplex */ - MCHP_SPI_CR(ctrl) &= ~(0x3 << 2); - - /* Set CLKPOL, TCLKPH, RCLKPH to 0 */ - MCHP_SPI_CC(ctrl) &= ~0x7; - - /* Set LSBF to 0 -> MSB first */ - MCHP_SPI_CR(ctrl) &= ~0x1; - } else { - /* soft reset */ - MCHP_SPI_CR(ctrl) |= (1u << 4); - - /* Clear enable bit in SPI_AR */ - MCHP_SPI_AR(ctrl) &= ~0x1; - - if (ctrl) - MCHP_PCR_SLP_EN_DEV(MCHP_PCR_GPSPI1); - else - MCHP_PCR_SLP_EN_DEV(MCHP_PCR_GPSPI0); - } - - return EC_SUCCESS; -} - diff --git a/chip/mchp/gpspi_chip.h b/chip/mchp/gpspi_chip.h deleted file mode 100644 index 529a727e36..0000000000 --- a/chip/mchp/gpspi_chip.h +++ /dev/null @@ -1,35 +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. - * - * Register map for MCHP MEC processor - */ -/** @file gpspi_chip.h - *MCHP MEC General Purpose SPI Master - */ -/** @defgroup MCHP MEC gpspi - */ - -#ifndef _GPSPI_CHIP_H -#define _GPSPI_CHIP_H - -#include <stdint.h> -#include <stddef.h> - -/* struct spi_device_t */ -#include "spi.h" - -int gpspi_transaction_flush(const struct spi_device_t *spi_device); - -int gpspi_transaction_wait(const struct spi_device_t *spi_device); - -int gpspi_transaction_async(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen); - -int gpspi_enable(int port, int enable); - -#endif /* #ifndef _GPSPI_CHIP_H */ -/** @} - */ - diff --git a/chip/mchp/hwtimer.c b/chip/mchp/hwtimer.c deleted file mode 100644 index e84f278f4a..0000000000 --- a/chip/mchp/hwtimer.c +++ /dev/null @@ -1,121 +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. - */ - -/* Hardware timers driver */ - -#include "clock.h" -#include "common.h" -#include "hooks.h" -#include "hwtimer.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "tfdp_chip.h" - -void __hw_clock_event_set(uint32_t deadline) -{ - MCHP_TMR32_CNT(1) = MCHP_TMR32_CNT(0) - - (0xffffffff - deadline); - MCHP_TMR32_CTL(1) |= BIT(5); -} - -uint32_t __hw_clock_event_get(void) -{ - return MCHP_TMR32_CNT(1) - MCHP_TMR32_CNT(0) + 0xffffffff; -} - -void __hw_clock_event_clear(void) -{ - MCHP_TMR32_CTL(1) &= ~BIT(5); -} - -uint32_t __hw_clock_source_read(void) -{ - return 0xffffffff - MCHP_TMR32_CNT(0); -} - -void __hw_clock_source_set(uint32_t ts) -{ - MCHP_TMR32_CTL(0) &= ~BIT(5); - MCHP_TMR32_CNT(0) = 0xffffffff - ts; - MCHP_TMR32_CTL(0) |= BIT(5); -} - -/* - * Always clear both timer and aggregator status - */ -static void __hw_clock_source_irq(int timer_id) -{ - MCHP_TMR32_STS(timer_id & 0x01) |= 1; - MCHP_INT_SOURCE(MCHP_TMR32_GIRQ) = - MCHP_TMR32_GIRQ_BIT(timer_id & 0x01); - - /* If IRQ is from timer 0, 32-bit timer overflowed */ - process_timers(timer_id == 0); -} - -void __hw_clock_source_irq_0(void) { __hw_clock_source_irq(0); } -DECLARE_IRQ(MCHP_IRQ_TIMER32_0, __hw_clock_source_irq_0, 1); -void __hw_clock_source_irq_1(void) { __hw_clock_source_irq(1); } -DECLARE_IRQ(MCHP_IRQ_TIMER32_1, __hw_clock_source_irq_1, 1); - -static void configure_timer(int timer_id) -{ - uint32_t val; - - /* Ensure timer is not running */ - MCHP_TMR32_CTL(timer_id) &= ~BIT(5); - - /* Enable timer */ - MCHP_TMR32_CTL(timer_id) |= BIT(0); - - val = MCHP_TMR32_CTL(timer_id); - - /* Pre-scale = 48 -> 1MHz -> Period = 1us */ - val = (val & 0xffff) | (47 << 16); - - MCHP_TMR32_CTL(timer_id) = val; - - /* Set preload to use the full 32 bits of the timer */ - MCHP_TMR32_PRE(timer_id) = 0xffffffff; - - /* Enable interrupt */ - MCHP_TMR32_IEN(timer_id) |= 1; -} - -int __hw_clock_source_init(uint32_t start_t) -{ - MCHP_PCR_SLP_DIS_DEV_MASK(3, MCHP_PCR_SLP_EN3_BTMR32_0 + - MCHP_PCR_SLP_EN3_BTMR32_1); - - /* - * The timer can only fire interrupt when its value reaches zero. - * Therefore we need two timers: - * - Timer 0 as free running timer - * - Timer 1 as event timer - */ - configure_timer(0); - configure_timer(1); - - /* Override the count */ - MCHP_TMR32_CNT(0) = 0xffffffff - start_t; - - /* Auto restart */ - MCHP_TMR32_CTL(0) |= BIT(3); - - /* Start counting in timer 0 */ - MCHP_TMR32_CTL(0) |= BIT(5); - - /* Enable interrupt */ - task_enable_irq(MCHP_IRQ_TIMER32_0); - task_enable_irq(MCHP_IRQ_TIMER32_1); - MCHP_INT_ENABLE(MCHP_TMR32_GIRQ) = MCHP_TMR32_GIRQ_BIT(0) + - MCHP_TMR32_GIRQ_BIT(1); - /* - * Not needed when using direct mode interrupts - * MCHP_INT_BLK_EN |= BIT(MCHP_TMR32_GIRQ); - */ - return MCHP_IRQ_TIMER32_1; -} diff --git a/chip/mchp/i2c.c b/chip/mchp/i2c.c deleted file mode 100644 index 9891f4d41e..0000000000 --- a/chip/mchp/i2c.c +++ /dev/null @@ -1,1096 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* I2C port module for MCHP MEC */ - -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "i2c_chip.h" -#include "registers.h" -#include "task.h" -#include "tfdp_chip.h" -#include "timer.h" -#include "util.h" - -#define CPUTS(outstr) cputs(CC_I2C, outstr) -#define CPRINTF(format, args...) cprintf(CC_I2C, format, ##args) -#define CPRINTS(format, args...) cprints(CC_I2C, format, ##args) - -/* - * MCHP I2C BAUD clock source is 16 MHz. - */ -#define I2C_CLOCK 16000000UL -#define MCHP_I2C_SUPPORTED_BUS_CLOCKS 6 - -/* SMBus Timing values for 1MHz Speed */ -#define SPEED_1MHZ_BUS_CLOCK 0x0509ul -#define SPEED_1MHZ_DATA_TIMING 0x06060601ul -#define SPEED_1MHZ_DATA_TIMING_2 0x06ul -#define SPEED_1MHZ_IDLE_SCALING 0x01000050ul -#define SPEED_1MHZ_TIMEOUT_SCALING 0x149CC2C7ul -/* SMBus Timing values for 400kHz speed */ -#define SPEED_400KHZ_BUS_CLOCK 0x0F17ul -#define SPEED_400KHZ_DATA_TIMING 0x040A0F01ul -#define SPEED_400KHZ_DATA_TIMING_2 0x0Aul -#define SPEED_400KHZ_IDLE_SCALING 0x01000050ul -#define SPEED_400KHZ_TIMEOUT_SCALING 0x149CC2C7ul -/* SMBus Timing values for 100kHz speed */ -#define SPEED_100KHZ_BUS_CLOCK 0x4F4Ful -#define SPEED_100KHZ_DATA_TIMING 0x0C4D4306ul -#define SPEED_100KHZ_DATA_TIMING_2 0x4Dul -#define SPEED_100KHZ_IDLE_SCALING 0x01FC01EDul -#define SPEED_100KHZ_TIMEOUT_SCALING 0x4B9CC2C7ul -/* Bus clock dividers for 333, 80, and 40 kHz */ -#define SPEED_333KHZ_BUS_CLOCK 0x0F1Ful -#define SPEED_80KHZ_BUS_CLOCK 0x6363ul -#define SPEED_40KHZ_BUS_CLOCK 0xC7C7ul - -/* Status */ -#define STS_NBB BIT(0) /* Bus busy */ -#define STS_LAB BIT(1) /* Arbitration lost */ -#define STS_LRB BIT(3) /* Last received bit */ -#define STS_BER BIT(4) /* Bus error */ -#define STS_PIN BIT(7) /* Pending interrupt */ -/* Control */ -#define CTRL_ACK BIT(0) /* Acknowledge */ -#define CTRL_STO BIT(1) /* STOP */ -#define CTRL_STA BIT(2) /* START */ -#define CTRL_ENI BIT(3) /* Enable interrupt */ -#define CTRL_ESO BIT(6) /* Enable serial output */ -#define CTRL_PIN BIT(7) /* Pending interrupt not */ -/* Completion */ -#define COMP_DTEN BIT(2) /* enable device timeouts */ -#define COMP_MCEN BIT(3) /* enable ctrl. cumulative timeouts */ -#define COMP_SCEN BIT(4) /* enable periph. cumulative timeouts */ -#define COMP_BIDEN BIT(5) /* enable Bus idle timeouts */ -#define COMP_IDLE BIT(29) /* i2c bus is idle */ -#define COMP_RW_BITS_MASK 0x3C /* R/W bits mask */ -/* Configuration */ -#define CFG_PORT_MASK (0x0F) /* port selection field */ -#define CFG_TCEN BIT(4) /* Enable HW bus timeouts */ -#define CFG_FEN BIT(8) /* enable input filtering */ -#define CFG_RESET BIT(9) /* reset controller */ -#define CFG_ENABLE BIT(10) /* enable controller */ -#define CFG_GC_DIS BIT(14) /* disable general call address */ -#define CFG_ENIDI BIT(29) /* Enable I2C idle interrupt */ -/* Enable network layer controller done interrupt */ -#define CFG_ENMI BIT(30) -/* Enable network layer peripheral done interrupt */ -#define CFG_ENSI BIT(31) -/* Controller Command */ -#define MCMD_MRUN BIT(0) -#define MCMD_MPROCEED BIT(1) -#define MCMD_START0 BIT(8) -#define MCMD_STARTN BIT(9) -#define MCMD_STOP BIT(10) -#define MCMD_READM BIT(12) -#define MCMD_WCNT_BITPOS (16) -#define MCMD_WCNT_MASK0 (0xFF) -#define MCMD_WCNT_MASK (0xFF << 16) -#define MCMD_RCNT_BITPOS (24) -#define MCMD_RCNT_MASK0 (0xFF) -#define MCMD_RCNT_MASK (0xFF << 24) - -/* Maximum transfer of a SMBUS block transfer */ -#define SMBUS_MAX_BLOCK_SIZE 32 -/* - * Amount of time to blocking wait for i2c bus to finish. After this - * blocking timeout, if the bus is still not finished, then allow other - * tasks to run. - * Note: this is just long enough for a 400kHz bus to finish transmitting - * one byte assuming the bus isn't being held. - */ -#define I2C_WAIT_BLOCKING_TIMEOUT_US 25 - -enum i2c_transaction_state { - /* Stop condition was sent in previous transaction */ - I2C_TRANSACTION_STOPPED, - /* Stop condition was not sent in previous transaction */ - I2C_TRANSACTION_OPEN, -}; - -/* I2C controller state data - * NOTE: I2C_CONTROLLER_COUNT is defined at board level. - */ -static struct { - /* Transaction timeout, or 0 to use default. */ - uint32_t timeout_us; - /* Task waiting on port, or TASK_ID_INVALID if none. */ - /* - * MCHP Remove volatile. - * ISR only reads. - * Non-ISR only writes when interrupt is disabled. - */ - task_id_t task_waiting; - enum i2c_transaction_state transaction_state; - /* transaction context */ - int out_size; - const uint8_t *outp; - int in_size; - uint8_t *inp; - int xflags; - uint32_t i2c_complete; /* ISR write */ - uint32_t flags; - uint8_t port; - uint8_t periph_addr_8bit; - uint8_t ctrl; - uint8_t hwsts; - uint8_t hwsts2; - uint8_t hwsts3; /* ISR write */ - uint8_t hwsts4; - uint8_t lines; -} cdata[I2C_CONTROLLER_COUNT]; - -static const uint16_t i2c_ctrl_nvic_id[] = { - MCHP_IRQ_I2C_0, MCHP_IRQ_I2C_1, MCHP_IRQ_I2C_2, MCHP_IRQ_I2C_3, -#if defined(CHIP_FAMILY_MEC172X) - MCHP_IRQ_I2C_4 -#elif defined(CHIP_FAMILY_MEC152X) - MCHP_IRQ_I2C_4, MCHP_IRQ_I2C_5, MCHP_IRQ_I2C_6, MCHP_IRQ_I2C_7 -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(i2c_ctrl_nvic_id) == MCHP_I2C_CTRL_MAX); - -static const uint16_t i2c_controller_pcr[] = { - MCHP_PCR_I2C0, MCHP_PCR_I2C1, MCHP_PCR_I2C2, MCHP_PCR_I2C3, -#if defined(CHIP_FAMILY_MEC172X) - MCHP_PCR_I2C4 -#elif defined(CHIP_FAMILY_MEC152X) - MCHP_PCR_I2C4, MCHP_PCR_I2C5, MCHP_PCR_I2C6, MCHP_PCR_I2C7, -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(i2c_controller_pcr) == MCHP_I2C_CTRL_MAX); - -static uintptr_t i2c_ctrl_base_addr[] = { - MCHP_I2C0_BASE, MCHP_I2C1_BASE, MCHP_I2C2_BASE, MCHP_I2C3_BASE, -#if defined(CHIP_FAMILY_MEC172X) - MCHP_I2C4_BASE -#elif defined(CHIP_FAMILY_MEC152X) - MCHP_I2C4_BASE, - /* NOTE: 5-7 do not implement network layer hardware */ - MCHP_I2C5_BASE, MCHP_I2C6_BASE, MCHP_I2C7_BASE -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(i2c_ctrl_base_addr) == MCHP_I2C_CTRL_MAX); - -static bool chip_i2c_is_controller_valid(int controller) -{ - if ((controller < 0) || (controller >= MCHP_I2C_CTRL_MAX)) - return false; - return true; -} - -static uintptr_t chip_i2c_ctrl_base(int controller) -{ - if (!chip_i2c_is_controller_valid(controller)) - return 0; - - return i2c_ctrl_base_addr[controller]; -} - -static uint32_t chip_i2c_ctrl_nvic_id(int controller) -{ - if (!chip_i2c_is_controller_valid(controller)) - return 0; - - return (uint32_t)i2c_ctrl_nvic_id[controller]; -} - -static void i2c_ctrl_slp_en(int controller, int sleep_en) -{ - if (!chip_i2c_is_controller_valid(controller)) - return; - if (sleep_en) - MCHP_PCR_SLP_EN_DEV(i2c_controller_pcr[controller]); - else - MCHP_PCR_SLP_DIS_DEV(i2c_controller_pcr[controller]); -} - -uint32_t chip_i2c_get_ctx_flags(int port) -{ - int controller = i2c_port_to_controller(port); - - if (!chip_i2c_is_controller_valid(controller)) - return 0; - return cdata[controller].flags; -} - -/* - * MCHP I2C controller tuned bus clock values. - * MCHP I2C_SMB_Controller_3.6.pdf Table 6-3 - */ -struct i2c_bus_clk { - int freq_khz; - int bus_clk; -}; - -const struct i2c_bus_clk i2c_freq_tbl[] = { - { 40, SPEED_40KHZ_BUS_CLOCK }, { 80, SPEED_80KHZ_BUS_CLOCK }, - { 100, SPEED_100KHZ_BUS_CLOCK }, { 333, SPEED_333KHZ_BUS_CLOCK }, - { 400, SPEED_400KHZ_BUS_CLOCK }, { 1000, SPEED_1MHZ_BUS_CLOCK }, -}; -BUILD_ASSERT(ARRAY_SIZE(i2c_freq_tbl) == MCHP_I2C_SUPPORTED_BUS_CLOCKS); - -/* I2C controller assignment to a port */ -static int i2c_p2c[MCHP_I2C_PORT_COUNT]; - -static int get_closest(int lesser, int greater, int target) -{ - if (target - i2c_freq_tbl[lesser].freq_khz >= - i2c_freq_tbl[greater].freq_khz - target) - return greater; - else - return lesser; -} - -/* - * Return index in i2c_freq_tbl of supported frequencies - * closest to requested frequency. - */ -static const struct i2c_bus_clk *get_supported_speed_idx(int req_kbps) -{ - int i, limit, m, imax; - - if (req_kbps <= i2c_freq_tbl[0].freq_khz) - return &i2c_freq_tbl[0]; - - imax = ARRAY_SIZE(i2c_freq_tbl); - if (req_kbps >= i2c_freq_tbl[imax - 1].freq_khz) - return &i2c_freq_tbl[imax - 1]; - - /* we only get here if ARRAY_SIZE(...) > 1 - * and req_kbps is in range. - */ - i = 0; - limit = imax; - while (i < limit) { - m = (i + limit) / 2; - if (i2c_freq_tbl[m].freq_khz == req_kbps) - break; - - if (req_kbps < i2c_freq_tbl[m].freq_khz) { - if (m > 0 && req_kbps > i2c_freq_tbl[m - 1].freq_khz) { - m = get_closest(m - 1, m, req_kbps); - break; - } - limit = m; - } else { - if (m < imax - 1 && - req_kbps < i2c_freq_tbl[m + 1].freq_khz) { - m = get_closest(m, m + 1, req_kbps); - break; - } - i = m + 1; - } - } - - return &i2c_freq_tbl[m]; -} - -/* - * Refer to NXP UM10204 for minimum timing requirement of T_Low and T_High. - * http://www.nxp.com/documents/user_manual/UM10204.pdf - * I2C spec. timing value are used in recommended registers values - * in MCHP I2C_SMB_Controller_3.6.pdf - * Restrict frequencies to those in the above MCHP spec. - * 40, 80, 100, 333, 400, and 1000 kHz. - */ -static void configure_controller_speed(int controller, int kbps) -{ - const struct i2c_bus_clk *p; - uintptr_t raddr; - - raddr = chip_i2c_ctrl_base(controller); - - p = get_supported_speed_idx(kbps); - MCHP_I2C_BUS_CLK(raddr) = p->bus_clk; - - if (p->freq_khz > 400) { /* Fast mode plus */ - MCHP_I2C_DATA_TIM(raddr) = SPEED_1MHZ_DATA_TIMING; - MCHP_I2C_DATA_TIM_2(raddr) = SPEED_1MHZ_DATA_TIMING_2; - MCHP_I2C_IDLE_SCALE(raddr) = SPEED_1MHZ_IDLE_SCALING; - MCHP_I2C_TOUT_SCALE(raddr) = SPEED_1MHZ_TIMEOUT_SCALING; - } else if (p->freq_khz > 100) { /* Fast mode */ - MCHP_I2C_DATA_TIM(raddr) = SPEED_400KHZ_DATA_TIMING; - MCHP_I2C_DATA_TIM_2(raddr) = SPEED_400KHZ_DATA_TIMING_2; - MCHP_I2C_IDLE_SCALE(raddr) = SPEED_400KHZ_IDLE_SCALING; - MCHP_I2C_TOUT_SCALE(raddr) = SPEED_400KHZ_TIMEOUT_SCALING; - } else { /* Standard mode */ - MCHP_I2C_DATA_TIM(raddr) = SPEED_100KHZ_DATA_TIMING; - MCHP_I2C_DATA_TIM_2(raddr) = SPEED_100KHZ_DATA_TIMING_2; - MCHP_I2C_IDLE_SCALE(raddr) = SPEED_100KHZ_IDLE_SCALING; - MCHP_I2C_TOUT_SCALE(raddr) = SPEED_100KHZ_TIMEOUT_SCALING; - } -} - -/* - * NOTE: direct mode interrupts do not need GIRQn bit - * set in aggregator block enable register. - */ -static void enable_controller_irq(int controller) -{ - uint32_t nvic_id = chip_i2c_ctrl_nvic_id(controller); - - MCHP_INT_ENABLE(MCHP_I2C_GIRQ) = MCHP_I2C_GIRQ_BIT(controller); - task_enable_irq(nvic_id); -} - -static void disable_controller_irq(int controller) -{ - uint32_t nvic_id = chip_i2c_ctrl_nvic_id(controller); - - MCHP_INT_DISABLE(MCHP_I2C_GIRQ) = MCHP_I2C_GIRQ_BIT(controller); - /* read back into read-only reg. to insure disable takes effect */ - MCHP_INT_BLK_IRQ = MCHP_INT_DISABLE(MCHP_I2C_GIRQ); - task_disable_irq(nvic_id); - task_clear_pending_irq(nvic_id); -} - -/* - * Do NOT enable controller's IDLE interrupt in the configuration - * register. IDLE is meant for multi-controller and controller acting - * as a peripheral. - */ -static void configure_controller(int controller, int port, int kbps) -{ - uintptr_t raddr = chip_i2c_ctrl_base(controller); - - if (raddr == 0) - return; - - disable_controller_irq(controller); - MCHP_INT_SOURCE(MCHP_I2C_GIRQ) = MCHP_I2C_GIRQ_BIT(controller); - - /* set to default except for port select field b[3:0] */ - MCHP_I2C_CONFIG(raddr) = (uint32_t)(port & 0xf); - MCHP_I2C_CTRL(raddr) = CTRL_PIN; - - /* Set both controller peripheral addresses to 0 the - * general call address. We disable general call - * below. - */ - MCHP_I2C_OWN_ADDR(raddr) = 0; - - configure_controller_speed(controller, kbps); - - /* Controller timings done, clear RO status, enable - * output, and ACK generation. - */ - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | CTRL_ACK; - - /* filter enable, disable General Call */ - MCHP_I2C_CONFIG(raddr) |= CFG_FEN + CFG_GC_DIS; - /* enable controller */ - MCHP_I2C_CONFIG(raddr) |= CFG_ENABLE; -} - -static void reset_controller(int controller) -{ - int i; - uintptr_t raddr; - - raddr = chip_i2c_ctrl_base(controller); - if (raddr == 0) - return; - - /* Reset asserted for at least one AHB clock */ - MCHP_I2C_CONFIG(raddr) |= BIT(9); - MCHP_EC_ID_RO = 0; - MCHP_I2C_CONFIG(raddr) &= ~BIT(9); - - for (i = 0; i < i2c_ports_used; ++i) - if (controller == i2c_port_to_controller(i2c_ports[i].port)) { - configure_controller(controller, i2c_ports[i].port, - i2c_ports[i].kbps); - cdata[controller].transaction_state = - I2C_TRANSACTION_STOPPED; - break; - } -} - -/* - * !!! WARNING !!! - * We have observed task_wait_event_mask() returning 0 if the I2C - * controller IDLE interrupt is enabled. We believe it is due to the ISR - * post multiple events too quickly but don't have absolute proof. - */ -static int wait_for_interrupt(int controller, int timeout) -{ - int event; - - if (timeout <= 0) - return EC_ERROR_TIMEOUT; - - cdata[controller].task_waiting = task_get_current(); - enable_controller_irq(controller); - - /* Wait until I2C interrupt or timeout. */ - event = task_wait_event_mask(TASK_EVENT_I2C_IDLE, timeout); - - disable_controller_irq(controller); - cdata[controller].task_waiting = TASK_ID_INVALID; - - return (event & TASK_EVENT_TIMER) ? EC_ERROR_TIMEOUT : EC_SUCCESS; -} - -static int wait_idle(int controller) -{ - uintptr_t raddr = chip_i2c_ctrl_base(controller); - uint64_t block_timeout = get_time().val + I2C_WAIT_BLOCKING_TIMEOUT_US; - uint64_t task_timeout = block_timeout + cdata[controller].timeout_us; - int rv = 0; - uint8_t sts = MCHP_I2C_STATUS(raddr); - - while (!(sts & STS_NBB)) { - if (rv) - return rv; - if (get_time().val > block_timeout) - rv = wait_for_interrupt(controller, - task_timeout - get_time().val); - sts = MCHP_I2C_STATUS(raddr); - } - - if (sts & (STS_BER | STS_LAB)) - return EC_ERROR_UNKNOWN; - return EC_SUCCESS; -} - -/* - * Return EC_SUCCESS on ACK of byte else EC_ERROR_UNKNOWN. - * Record I2C.Status in cdata[controller] structure. - * Byte transmit finished with no I2C bus error or lost arbitration. - * PIN -> 0. LRB bit contains peripheral ACK/NACK bit. - * Peripheral ACK: I2C.Status == 0x00 - * Peripheral NACK: I2C.Status == 0x08 - * Byte transmit finished with I2C bus errors or lost arbitration. - * PIN -> 0 and BER and/or LAB set. - * - * Byte receive finished with no I2C bus errors or lost arbitration. - * PIN -> 0. LRB=0/1 based on ACK bit in I2C.Control. - * Controller receiver must NACK last byte it wants to receive. - * How do we handle this if we don't know direction of transfer? - * I2C.Control is write-only so we can't see Controller's ACK control - * bit. - */ -static int wait_byte_done(int controller, uint8_t mask, uint8_t expected) -{ - uint64_t block_timeout; - uint64_t task_timeout; - uintptr_t raddr; - int rv; - uint8_t sts; - - rv = 0; - raddr = chip_i2c_ctrl_base(controller); - block_timeout = get_time().val + I2C_WAIT_BLOCKING_TIMEOUT_US; - task_timeout = block_timeout + cdata[controller].timeout_us; - sts = MCHP_I2C_STATUS(raddr); - cdata[controller].hwsts = sts; - while (sts & STS_PIN) { - if (rv) - return rv; - if (get_time().val > block_timeout) { - rv = wait_for_interrupt(controller, - task_timeout - get_time().val); - } - sts = MCHP_I2C_STATUS(raddr); - cdata[controller].hwsts = sts; - } - - rv = EC_SUCCESS; - if ((sts & mask) != expected) - rv = EC_ERROR_UNKNOWN; - return rv; -} - -/* - * Select port on controller. If controller configured - * for port do nothing. - * Switch port by reset and reconfigure to handle cases where - * the peripheral on current port is driving line(s) low. - * NOTE: I2C hardware reset only requires one AHB clock, back to back - * writes is OK but we added an extra write as insurance. - */ -static void select_port(int port, int controller) -{ - uint32_t port_sel; - uintptr_t raddr; - - raddr = chip_i2c_ctrl_base(controller); - port_sel = (uint32_t)(port & 0x0f); - if ((MCHP_I2C_CONFIG(raddr) & 0x0f) == port_sel) - return; - - MCHP_I2C_CONFIG(raddr) |= BIT(9); - MCHP_EC_ID_RO = 0; /* extra write to read-only as delay */ - MCHP_I2C_CONFIG(raddr) &= ~BIT(9); - configure_controller(controller, port_sel, i2c_ports[port].kbps); -} - -/* - * Use safe method (reading GPIO.Control PAD input bit) - * to obtain SCL line state in bit[0] and SDA line state in bit[1]. - * NOTE: I2C controller bit-bang register is not safe. Using - * bit-bang requires timeouts be disabled and the controller in an - * idle state. Switching controller to bit-bang mode when the controller - * is not idle will cause problems. - */ -static uint32_t get_line_level(int port) -{ - uint32_t lines; - - lines = i2c_raw_get_scl(port) & 0x01; - lines |= (i2c_raw_get_sda(port) & 0x01) << 1; - return lines; -} - -/* - * Check if I2C port connected to controller has bus error or - * other issues such as stuck clock/data lines. - */ -static int i2c_check_recover(int port, int controller) -{ - uintptr_t raddr; - uint32_t lines; - uint8_t reg; - - raddr = chip_i2c_ctrl_base(controller); - lines = get_line_level(port); - reg = MCHP_I2C_STATUS(raddr); - - if ((((reg & (STS_BER | STS_LAB)) || !(reg & STS_NBB)) || - (lines != I2C_LINE_IDLE))) { - cdata[controller].flags |= (1ul << 16); - CPRINTS("I2C%d port%d recov status 0x%02x, SDA:SCL=0x%0x", - controller, port, reg, lines); - /* Attempt to unwedge the port. */ - if (lines != I2C_LINE_IDLE) - if (i2c_unwedge(port)) - return EC_ERROR_UNKNOWN; - - /* Bus error, bus busy, or arbitration lost. Try reset. */ - reset_controller(controller); - select_port(port, controller); - /* - * We don't know what edges the peripheral saw, so sleep long - * enough that the peripheral will see the new start condition - * below. - */ - usleep(1000); - reg = MCHP_I2C_STATUS(raddr); - lines = get_line_level(port); - if ((reg & (STS_BER | STS_LAB)) || !(reg & STS_NBB) || - (lines != I2C_LINE_IDLE)) - return EC_ERROR_UNKNOWN; - } - return EC_SUCCESS; -} - -static inline void push_in_buf(uint8_t **in, uint8_t val, int skip) -{ - if (!skip) { - **in = val; - (*in)++; - } -} - -/* - * I2C Controller transmit - * Caller has filled in cdata[ctrl] parameters - */ -static int i2c_mtx(int ctrl) -{ - uintptr_t raddr; - int i, rv; - - raddr = chip_i2c_ctrl_base(ctrl); - rv = EC_SUCCESS; - cdata[ctrl].flags |= (1ul << 1); - if (cdata[ctrl].xflags & I2C_XFER_START) { - cdata[ctrl].flags |= (1ul << 2); - MCHP_I2C_DATA(raddr) = cdata[ctrl].periph_addr_8bit; - /* Clock out the peripheral address, sending START bit */ - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | CTRL_ENI | - CTRL_ACK | CTRL_STA; - cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN; - } - - for (i = 0; i < cdata[ctrl].out_size; ++i) { - rv = wait_byte_done(ctrl, 0xff, 0x00); - if (rv) { - cdata[ctrl].flags |= (1ul << 17); - MCHP_I2C_CTRL(ctrl) = CTRL_PIN | CTRL_ESO | CTRL_ENI | - CTRL_STO | CTRL_ACK; - return rv; - } - cdata[ctrl].flags |= (1ul << 15); - MCHP_I2C_DATA(raddr) = cdata[ctrl].outp[i]; - } - - rv = wait_byte_done(ctrl, 0xff, 0x00); - if (rv) { - cdata[ctrl].flags |= (1ul << 18); - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | CTRL_ENI | - CTRL_STO | CTRL_ACK; - return rv; - } - - /* - * Send STOP bit if the stop flag is on, and caller - * doesn't expect to receive data. - */ - if ((cdata[ctrl].xflags & I2C_XFER_STOP) && - (cdata[ctrl].in_size == 0)) { - cdata[ctrl].flags |= (1ul << 3); - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | CTRL_STO | - CTRL_ACK; - cdata[ctrl].transaction_state = I2C_TRANSACTION_STOPPED; - } - return rv; -} - -/* - * I2C Controller-Receive helper routine for sending START or - * Repeated-START. - * This routine should only be called if a (Repeated-)START - * is required. - * If I2C controller is Idle or Stopped - * Send START by: - * Write read address to I2C.Data - * Write PIN=ESO=STA=ACK=1, STO=0 to I2C.Ctrl. This - * will trigger controller to output 8-bits of data. - * Else if I2C controller is Open (previous START sent) - * Send Repeated-START by: - * Write ESO=STA=ACK=1, PIN=STO=0 to I2C.Ctrl. Controller - * will generate START but not transmit data. - * Write read address to I2C.Data. Controller will transmit - * 8-bits of data - * NOTE: Controller clocks in address on SDA as its transmitting. - * Therefore 1-byte RX-FIFO will contain address plus R/nW bit. - * Controller will wait for peripheral to release SCL before transmitting - * 9th clock and latching (N)ACK on SDA. - * Spin on I2C.Status PIN -> 0. Enable I2C interrupt if spin time - * exceeds threshold. If a timeout occurs generate STOP and return - * an error. - * - * Because I2C generates clocks for next byte when reading I2C.Data - * register we must prepare control logic. - * If the caller requests STOP and read length is 1 then set - * clear ACK bit in I2C.Ctrl. Set ESO=ENI=1, PIN=STA=STO=ACK=0 - * in I2C.Ctrl. Controller must NACK last byte. - */ -static int i2c_mrx_start(int ctrl) -{ - uintptr_t raddr; - int rv; - uint8_t u8; - - raddr = chip_i2c_ctrl_base(ctrl); - - cdata[ctrl].flags |= (1ul << 4); - u8 = CTRL_ESO | CTRL_ENI | CTRL_STA | CTRL_ACK; - if (cdata[ctrl].transaction_state == I2C_TRANSACTION_OPEN) { - cdata[ctrl].flags |= (1ul << 5); - /* Repeated-START then address */ - MCHP_I2C_CTRL(raddr) = u8; - } - MCHP_I2C_DATA(raddr) = cdata[ctrl].periph_addr_8bit | 0x01; - if (cdata[ctrl].transaction_state == I2C_TRANSACTION_STOPPED) { - cdata[ctrl].flags |= (1ul << 6); - /* address then START */ - MCHP_I2C_CTRL(raddr) = u8 | CTRL_PIN; - } - cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN; - /* Controller generates START, transmits data(address) capturing - * 9-bits from SDA (8-bit address + (N)Ack bit). - * We leave captured address in I2C.Data register. - * Controller receive data read routine assumes data is pending - * in I2C.Data - */ - cdata[ctrl].flags |= (1ul << 7); - rv = wait_byte_done(ctrl, 0xff, 0x00); - if (rv) { - cdata[ctrl].flags |= (1ul << 19); - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | CTRL_STO | - CTRL_ACK; - return rv; - } - /* if STOP requested and last 1 or 2 bytes prepare controller - * to NACK last byte. Do this before read of extra data so - * controller is setup to NACK last byte. - */ - cdata[ctrl].flags |= (1ul << 8); - if (cdata[ctrl].xflags & I2C_XFER_STOP && (cdata[ctrl].in_size < 2)) { - cdata[ctrl].flags |= (1ul << 9); - MCHP_I2C_CTRL(raddr) = CTRL_ESO | CTRL_ENI; - } - /* - * Read & discard peripheral address. - * Generates clocks for next data - */ - cdata[ctrl].flags |= (1ul << 10); - u8 = MCHP_I2C_DATA(raddr); - return rv; -} -/* - * I2C Controller-Receive data read helper. - * Assumes I2C is in use, (Rpt-)START was previously sent. - * Reading I2C.Data generates clocks for the next byte. If caller - * requests STOP then we must clear I2C.Ctrl ACK before reading - * second to last byte from RX-FIFO data register. Before reading - * the last byte we must set I2C.Ctrl to generate a stop after - * the read from RX-FIFO register. - * NOTE: I2C.Status.LRB only records the (N)ACK bit in controller - * transmit mode, not in controller receive mode. - * NOTE2: Do not set ENI bit in I2C.Ctrl for STOP generation. - */ -static int i2c_mrx_data(int ctrl) -{ - uint32_t nrx = (uint32_t)cdata[ctrl].in_size; - uint32_t stop = (uint32_t)cdata[ctrl].xflags & I2C_XFER_STOP; - uint8_t *pdest = cdata[ctrl].inp; - int rv; - uintptr_t raddr; - - raddr = chip_i2c_ctrl_base(ctrl); - - cdata[ctrl].flags |= (1ul << 11); - while (nrx) { - rv = wait_byte_done(ctrl, 0xff, 0x00); - if (rv) { - cdata[ctrl].flags |= (1ul << 20); - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | CTRL_STO | - CTRL_ACK; - return rv; - } - if (stop) { - if (nrx == 2) { - cdata[ctrl].flags |= (1ul << 12); - MCHP_I2C_CTRL(raddr) = CTRL_ESO | CTRL_ENI; - } else if (nrx == 1) { - cdata[ctrl].flags |= (1ul << 13); - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | - CTRL_STO | CTRL_ACK; - } - } - *pdest++ = MCHP_I2C_DATA(raddr); - nrx--; - } - cdata[ctrl].flags |= (1ul << 14); - return EC_SUCCESS; -} - -/* - * Called from common I2C - */ -int chip_i2c_xfer(int port, uint16_t periph_addr_flags, const uint8_t *out, - int out_size, uint8_t *in, int in_size, int flags) -{ - int ctrl; - int ret_done; - uintptr_t raddr; - - if (out_size == 0 && in_size == 0) - return EC_SUCCESS; - - ctrl = i2c_port_to_controller(port); - if (ctrl < 0) - return EC_ERROR_INVAL; - - raddr = chip_i2c_ctrl_base(ctrl); - if (raddr == 0) - return EC_ERROR_INVAL; - - cdata[ctrl].flags = (1ul << 0); - disable_controller_irq(ctrl); - select_port(port, ctrl); - - /* store transfer context */ - cdata[ctrl].i2c_complete = 0; - cdata[ctrl].hwsts = 0; - cdata[ctrl].hwsts2 = 0; - cdata[ctrl].hwsts3 = 0; - cdata[ctrl].hwsts4 = 0; - cdata[ctrl].port = port & 0xff; - cdata[ctrl].periph_addr_8bit = I2C_STRIP_FLAGS(periph_addr_flags) << 1; - cdata[ctrl].out_size = out_size; - cdata[ctrl].outp = out; - cdata[ctrl].in_size = in_size; - cdata[ctrl].inp = in; - cdata[ctrl].xflags = flags; - - if ((flags & I2C_XFER_START) && - cdata[ctrl].transaction_state == I2C_TRANSACTION_STOPPED) { - wait_idle(ctrl); - ret_done = i2c_check_recover(port, ctrl); - if (ret_done) - goto err_chip_i2c_xfer; - } - - ret_done = EC_SUCCESS; - if (out_size) { - ret_done = i2c_mtx(ctrl); - if (ret_done) - goto err_chip_i2c_xfer; - } - - if (in_size) { - if (cdata[ctrl].xflags & I2C_XFER_START) { - ret_done = i2c_mrx_start(ctrl); - if (ret_done) - goto err_chip_i2c_xfer; - } - ret_done = i2c_mrx_data(ctrl); - if (ret_done) - goto err_chip_i2c_xfer; - } - - cdata[ctrl].flags |= (1ul << 15); - /* MCHP wait for STOP to complete */ - if (cdata[ctrl].xflags & I2C_XFER_STOP) - wait_idle(ctrl); - - /* Check for error conditions */ - if (MCHP_I2C_STATUS(raddr) & (STS_LAB | STS_BER)) { - cdata[ctrl].flags |= (1ul << 21); - goto err_chip_i2c_xfer; - } - cdata[ctrl].flags |= (1ul << 14); - return EC_SUCCESS; - -err_chip_i2c_xfer: - cdata[ctrl].flags |= (1ul << 22); - cdata[ctrl].hwsts2 = MCHP_I2C_STATUS(raddr); /* record status */ - /* NOTE: writing I2C.Ctrl.PIN=1 will clear all bits - * except NBB in I2C.Status - */ - MCHP_I2C_CTRL(raddr) = CTRL_PIN | CTRL_ESO | CTRL_STO | CTRL_ACK; - cdata[ctrl].transaction_state = I2C_TRANSACTION_STOPPED; - /* record status after STOP */ - cdata[ctrl].hwsts4 = MCHP_I2C_STATUS(raddr); - - /* record line levels. - * Note line levels may reflect STOP condition - */ - cdata[ctrl].lines = (uint8_t)get_line_level(cdata[ctrl].port); - if (cdata[ctrl].hwsts2 & STS_BER) { - cdata[ctrl].flags |= (1ul << 23); - reset_controller(ctrl); - } - return EC_ERROR_UNKNOWN; -} -/* - * A safe method of reading port's SCL pin level. - */ -int i2c_raw_get_scl(int port) -{ - enum gpio_signal g; - - /* If no SCL pin defined for this port, - * then return 1 to appear idle. - */ - if (get_scl_from_i2c_port(port, &g) != EC_SUCCESS) - return 1; - return gpio_get_level(g); -} - -/* - * A safe method of reading port's SDA pin level. - */ -int i2c_raw_get_sda(int port) -{ - enum gpio_signal g; - - /* If no SDA pin defined for this port, - * then return 1 to appear idle. - */ - if (get_sda_from_i2c_port(port, &g) != EC_SUCCESS) - return 1; - return gpio_get_level(g); -} - -/* - * Caller is responsible for locking the port. - */ -int i2c_get_line_levels(int port) -{ - int rv, controller; - - controller = i2c_port_to_controller(port); - if (controller < 0) - return 0x03; /* No controller, return high line levels */ - - select_port(port, controller); - rv = get_line_level(port); - return rv; -} - -/* - * this function returns the controller for I2C - * return mod of MCHP_I2C_CTRL_MAX - */ -__overridable int board_i2c_p2c(int port) -{ - if (port < 0 || port >= I2C_PORT_COUNT) - return -1; - return i2c_p2c[port]; -} - -/* - * I2C port must be a zero based number. - * MCHP I2C can map any port to any of the 4 controllers. - * Call board level function as board designs may choose - * to wire up and group ports differently. - */ -int i2c_port_to_controller(int port) -{ - return board_i2c_p2c(port); -} - -void i2c_set_timeout(int port, uint32_t timeout) -{ - /* Parameter is port, but timeout is stored by-controller. */ - cdata[i2c_port_to_controller(port)].timeout_us = - timeout ? timeout : I2C_TIMEOUT_DEFAULT_US; -} - -/* - * Initialize I2C controllers specified by the board configuration. - * If multiple ports are mapped to the same controller choose the - * lowest speed. - */ -void i2c_init(void) -{ - int i, controller, kbps; - int controller_kbps[MCHP_I2C_CTRL_MAX]; - const struct i2c_bus_clk *pbc; - - for (i = 0; i < MCHP_I2C_CTRL_MAX; i++) - controller_kbps[i] = 0; - - /* Configure GPIOs */ - gpio_config_module(MODULE_I2C, 1); - - memset(cdata, 0, sizeof(cdata)); - - for (i = 0; i < i2c_ports_used; ++i) { - /* Assign I2C controller to I2C port */ - i2c_p2c[i2c_ports[i].port] = i % MCHP_I2C_CTRL_MAX; - - controller = i2c_port_to_controller(i2c_ports[i].port); - kbps = i2c_ports[i].kbps; - - /* Clear PCR sleep enable for controller */ - i2c_ctrl_slp_en(controller, 0); - - if (controller_kbps[controller] && - (controller_kbps[controller] != kbps)) { - CPRINTF("I2C[%d] init speed conflict: %d != %d\n", - controller, kbps, controller_kbps[controller]); - kbps = MIN(kbps, controller_kbps[controller]); - } - - /* controller speed hardware limits */ - pbc = get_supported_speed_idx(kbps); - if (pbc->freq_khz != kbps) - CPRINTF("I2C[%d] init requested speed %d" - " using closest supported speed %d\n", - controller, kbps, pbc->freq_khz); - - controller_kbps[controller] = pbc->freq_khz; - configure_controller(controller, i2c_ports[i].port, - controller_kbps[controller]); - cdata[controller].task_waiting = TASK_ID_INVALID; - cdata[controller].transaction_state = I2C_TRANSACTION_STOPPED; - /* Use default timeout. */ - i2c_set_timeout(i2c_ports[i].port, 0); - } -} - -/* - * Handle I2C interrupts. - * I2C controller is configured to fire interrupts on - * anything causing PIN 1->0 and I2C IDLE (NBB -> 1). - * NVIC interrupt disable must clear NVIC pending bit. - */ -static void handle_interrupt(int controller) -{ - uint32_t r; - int id = cdata[controller].task_waiting; - uintptr_t raddr = chip_i2c_ctrl_base(controller); - - /* - * Write to control register interferes with I2C transaction. - * Instead, let's disable IRQ from the core until the next time - * we want to wait for STS_PIN/STS_NBB. - */ - disable_controller_irq(controller); - cdata[controller].hwsts3 = MCHP_I2C_STATUS(raddr); - /* Clear all interrupt status */ - r = MCHP_I2C_COMPLETE(raddr); - MCHP_I2C_COMPLETE(raddr) = r; - cdata[controller].i2c_complete = r; - MCHP_INT_SOURCE(MCHP_I2C_GIRQ) = MCHP_I2C_GIRQ_BIT(controller); - - /* Wake up the task which was waiting on the I2C interrupt, if any. */ - if (id != TASK_ID_INVALID) - task_set_event(id, TASK_EVENT_I2C_IDLE); -} - -void i2c0_interrupt(void) -{ - handle_interrupt(0); -} -void i2c1_interrupt(void) -{ - handle_interrupt(1); -} -void i2c2_interrupt(void) -{ - handle_interrupt(2); -} -void i2c3_interrupt(void) -{ - handle_interrupt(3); -} -#if defined(CHIP_FAMILY_MEC172X) -void i2c4_interrupt(void) -{ - handle_interrupt(4); -} -#elif defined(CHIP_FAMILY_MEC152X) -void i2c4_interrupt(void) -{ - handle_interrupt(4); -} -void i2c5_interrupt(void) -{ - handle_interrupt(5); -} -void i2c6_interrupt(void) -{ - handle_interrupt(6); -} -void i2c7_interrupt(void) -{ - handle_interrupt(7); -} -#endif - -DECLARE_IRQ(MCHP_IRQ_I2C_0, i2c0_interrupt, 2); -DECLARE_IRQ(MCHP_IRQ_I2C_1, i2c1_interrupt, 2); -DECLARE_IRQ(MCHP_IRQ_I2C_2, i2c2_interrupt, 2); -DECLARE_IRQ(MCHP_IRQ_I2C_3, i2c3_interrupt, 2); -#if defined(CHIP_FAMILY_MEC172X) -DECLARE_IRQ(MCHP_IRQ_I2C_4, i2c4_interrupt, 2); -#elif defined(CHIP_FAMILY_MEC152X) -DECLARE_IRQ(MCHP_IRQ_I2C_4, i2c4_interrupt, 2); -DECLARE_IRQ(MCHP_IRQ_I2C_5, i2c5_interrupt, 2); -DECLARE_IRQ(MCHP_IRQ_I2C_6, i2c6_interrupt, 2); -DECLARE_IRQ(MCHP_IRQ_I2C_7, i2c7_interrupt, 2); -#endif diff --git a/chip/mchp/i2c_chip.h b/chip/mchp/i2c_chip.h deleted file mode 100644 index c8ceb98d04..0000000000 --- a/chip/mchp/i2c_chip.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* MCHP-specific I2C module for Chrome EC */ - -#ifndef _I2C_CHIP_H -#define _I2C_CHIP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Place any C interfaces here */ - -/* - * Function returns the controller for I2C. - * - * Default function assigns controller for I2C port with modulo operation. If - * the I2C ports used are greater than MCHP_I2C_CTRL_MAX, then I2C ports will - * share the controller. Typically Type-C chips need individual controller per - * port because of heavy I2C transactions. Hence, define a board specific - * controller assignment when the I2C ports used are greater than - * MCHP_I2C_CTRL_MAX. - */ -__override_proto int board_i2c_p2c(int port); - -#ifdef __cplusplus -} -#endif - -#endif /* _I2C_CHIP_H */ diff --git a/chip/mchp/keyboard_raw.c b/chip/mchp/keyboard_raw.c deleted file mode 100644 index 946ea1ca90..0000000000 --- a/chip/mchp/keyboard_raw.c +++ /dev/null @@ -1,104 +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. - * - * Raw keyboard I/O layer for MCHP MEC - */ - -#include "gpio.h" -#include "keyboard_config.h" -#include "keyboard_raw.h" -#include "keyboard_scan.h" -#include "registers.h" -#include "task.h" -#include "util.h" -#include "tfdp_chip.h" - -/* - * Using direct mode interrupt, do not enable - * GIRQ bit in aggregator block enable register. - */ -void keyboard_raw_init(void) -{ - /* clear key scan PCR sleep enable */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_KEYSCAN); - - keyboard_raw_enable_interrupt(0); - gpio_config_module(MODULE_KEYBOARD_SCAN, 1); - - /* Enable keyboard scan interrupt */ - MCHP_INT_ENABLE(MCHP_KS_GIRQ) = MCHP_KS_GIRQ_BIT; - MCHP_KS_KSI_INT_EN = 0xff; -} - -void keyboard_raw_task_start(void) -{ - task_enable_irq(MCHP_IRQ_KSC_INT); -} - -test_mockable void keyboard_raw_drive_column(int out) -{ - if (out == KEYBOARD_COLUMN_ALL) { - MCHP_KS_KSO_SEL = BIT(5); /* KSEN=0, KSALL=1 */ -#ifdef CONFIG_KEYBOARD_COL2_INVERTED - gpio_set_level(GPIO_KBD_KSO2, 1); -#endif - } else if (out == KEYBOARD_COLUMN_NONE) { - MCHP_KS_KSO_SEL = BIT(6); /* KSEN=1 */ -#ifdef CONFIG_KEYBOARD_COL2_INVERTED - gpio_set_level(GPIO_KBD_KSO2, 0); -#endif - } else { -#ifdef CONFIG_KEYBOARD_COL2_INVERTED - if (out == 2) { - MCHP_KS_KSO_SEL = BIT(6); /* KSEN=1 */ - gpio_set_level(GPIO_KBD_KSO2, 1); - } else { - MCHP_KS_KSO_SEL = out + CONFIG_KEYBOARD_KSO_BASE; - gpio_set_level(GPIO_KBD_KSO2, 0); - } -#else - MCHP_KS_KSO_SEL = out + CONFIG_KEYBOARD_KSO_BASE; -#endif - } -} - -test_mockable int keyboard_raw_read_rows(void) -{ - uint8_t b1, b2; - - b1 = MCHP_KS_KSI_INPUT; - b2 = (b1 & 0xff) ^ 0xff; - - /* Invert it so 0=not pressed, 1=pressed */ - /* return (MCHP_KS_KSI_INPUT & 0xff) ^ 0xff; */ - return b2; -} - -void keyboard_raw_enable_interrupt(int enable) -{ - if (enable) { - MCHP_INT_SOURCE(MCHP_KS_GIRQ) = MCHP_KS_GIRQ_BIT; - task_clear_pending_irq(MCHP_IRQ_KSC_INT); - task_enable_irq(MCHP_IRQ_KSC_INT); - } else { - task_disable_irq(MCHP_IRQ_KSC_INT); - } -} - -void keyboard_raw_interrupt(void) -{ - /* Clear interrupt status bits */ - MCHP_KS_KSI_STATUS = 0xff; - - MCHP_INT_SOURCE(MCHP_KS_GIRQ) = MCHP_KS_GIRQ_BIT; - - /* Wake keyboard scan task to handle interrupt */ - task_wake(TASK_ID_KEYSCAN); -} -DECLARE_IRQ(MCHP_IRQ_KSC_INT, keyboard_raw_interrupt, 1); - -int keyboard_raw_is_input_low(int port, int id) -{ - return (MCHP_GPIO_CTL(port, id) & BIT(24)) == 0; -} diff --git a/chip/mchp/lfw/ec_lfw.c b/chip/mchp/lfw/ec_lfw.c deleted file mode 100644 index 6f34a33a8d..0000000000 --- a/chip/mchp/lfw/ec_lfw.c +++ /dev/null @@ -1,435 +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. - * - * MCHP MEC SoC little FW - * - */ - -#include <stdint.h> - -#include "config.h" -#include "cros_version.h" -#include "gpio.h" -#include "spi.h" -#include "spi_flash.h" -#include "util.h" -#include "timer.h" -#include "dma.h" -#include "registers.h" -#include "cpu.h" -#include "clock.h" -#include "system.h" -#include "hwtimer.h" -#include "gpio_list.h" -#include "tfdp_chip.h" - -#ifdef CONFIG_MCHP_LFW_DEBUG -#include "dma_chip.h" -#endif - -#include "ec_lfw.h" - -/* - * Check if LFW build is pulling in GPSPI which is not - * used for EC firmware SPI flash access. - */ -#ifdef CONFIG_MCHP_GPSPI -#error "FORCED BUILD ERROR: CONFIG_MCHP_GPSPI is defined" -#endif - -#define LFW_SPI_BYTE_TRANSFER_TIMEOUT_US (1 * MSEC) -#define LFW_SPI_BYTE_TRANSFER_POLL_INTERVAL_US 100 - -__attribute__ ((section(".intvector"))) -const struct int_vector_t hdr_int_vect = { - /* init sp, unused. set by MEC ROM loader */ - (void *)lfw_stack_top, /* preserve ROM log. was (void *)0x11FA00, */ - &lfw_main, /* was &lfw_main, */ /* reset vector */ - &fault_handler, /* NMI handler */ - &fault_handler, /* HardFault handler */ - &fault_handler, /* MPU fault handler */ - &fault_handler /* Bus fault handler */ -}; - -/* SPI devices - from board.c */ -const struct spi_device_t spi_devices[] = { - { CONFIG_SPI_FLASH_PORT, 4, GPIO_QMSPI_CS0 }, -}; -const unsigned int spi_devices_used = ARRAY_SIZE(spi_devices); - -/* - * At POR or EC reset MCHP Boot-ROM should only load LFW and jumps - * into LFW entry point located at offset 0x04 of LFW. - * Entry point is programmed into SPI Header by Python SPI image - * builder in chip/mchp/util. - * - * EC_RO/RW calling LFW should enter through this routine if you - * want the vector table updated. The stack should be set to - * LFW linker file parameter lfw_stack_top because we do not - * know if the callers stack is OK. - * - * Make sure lfw_stack_top will not overwrite panic data! - * from include/panic.h - * Panic data goes at the end of RAM. This is safe because we don't - * context switch away from the panic handler before rebooting, - * and stacks and data start at the beginning of RAM. - * - * chip level config_chip.h - * #define CONFIG_RAM_SIZE 0x00008000 - * #define CONFIG_RAM_BASE 0x120000 - 0x8000 = 0x118000 - * - * #define PANIC_DATA_PTR ((struct panic_data *)\ - * (CONFIG_RAM_BASE + CONFIG_RAM_SIZE - sizeof(struct panic_data))) - * - * LFW stack located by ec_lfw.ld linker file 256 bytes below top of - * data SRAM. - * PROVIDE( lfw_stack_top = 0x11F000 ); - * - * !!!WARNING!!! - * Current MEC BootROM's zeros all memory therefore any chip reset - * will destroy panic data. - */ - -/* - * Configure 32-bit basic timer 0 for 1MHz, auto-reload and - * no interrupt. - */ -void timer_init(void) -{ - uint32_t val = 0; - - /* Ensure timer is not running */ - MCHP_TMR32_CTL(0) &= ~BIT(5); - - /* Enable timer */ - MCHP_TMR32_CTL(0) |= BIT(0); - - val = MCHP_TMR32_CTL(0); - - /* Prescale = 48 -> 1MHz -> Period = 1 us */ - val = (val & 0xffff) | (47 << 16); - - MCHP_TMR32_CTL(0) = val; - - /* Set preload to use the full 32 bits of the timer */ - MCHP_TMR32_PRE(0) = 0xffffffff; - - /* Override the count */ - MCHP_TMR32_CNT(0) = 0xffffffff; - - /* Auto restart */ - MCHP_TMR32_CTL(0) |= BIT(3); - - /* Start counting in timer 0 */ - MCHP_TMR32_CTL(0) |= BIT(5); - -} - -/* - * Use copy of SPI flash read compiled for LFW (no semaphores). - * LFW timeout code does not use interrupts so reset timer - * before starting SPI read to minimize probability of - * timer wrap. - */ -static int spi_flash_readloc(uint8_t *buf_usr, - unsigned int offset, - unsigned int bytes) -{ - uint8_t cmd[4] = {SPI_FLASH_READ, - (offset >> 16) & 0xFF, - (offset >> 8) & 0xFF, - offset & 0xFF}; - - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - __hw_clock_source_set(0); /* restart free run timer */ - return spi_transaction(SPI_FLASH_DEVICE, cmd, 4, buf_usr, bytes); -} - -/* - * Load EC_RO/RW image from local SPI flash. - * If CONFIG_MEC_TEST_EC_RORW_CRC was define the last 4 bytes - * of the binary is IEEE 802.3 CRC32 of the previous bytes. - * Use DMA channel 0 CRC32 HW to check data integrity. - */ -int spi_image_load(uint32_t offset) -{ - uint8_t *buf = (uint8_t *) (CONFIG_RW_MEM_OFF + - CONFIG_PROGRAM_MEMORY_BASE); - uint32_t i; -#ifdef CONFIG_MCHP_LFW_DEBUG - uint32_t crc_calc, crc_exp; - int rc; -#endif - - BUILD_ASSERT(CONFIG_RO_SIZE == CONFIG_RW_SIZE); - - /* Why fill all but last 4-bytes? */ - memset((void *)buf, 0xFF, (CONFIG_RO_SIZE - 4)); - - for (i = 0; i < CONFIG_RO_SIZE; i += SPI_CHUNK_SIZE) -#ifdef CONFIG_MCHP_LFW_DEBUG - rc = spi_flash_readloc(&buf[i], offset + i, SPI_CHUNK_SIZE); - if (rc != EC_SUCCESS) { - trace2(0, LFW, 0, - "spi_flash_readloc block %d ret = %d", - i, rc); - while (MCHP_PCR_PROC_CLK_CTL) - MCHP_PCR_CHIP_OSC_ID &= 0x1FE; - } -#else - spi_flash_readloc(&buf[i], offset + i, SPI_CHUNK_SIZE); -#endif - -#ifdef CONFIG_MCHP_LFW_DEBUG - dma_crc32_start(buf, (CONFIG_RO_SIZE - 4), 0); - do { - MCHP_USEC_DELAY(31); /* delay(stall) CPU by 32 us */ - i = dma_is_done_chan(0); - } while (i == 0); - crc_calc = MCHP_DMA_CH0_CRC32_DATA; - crc_exp = *((uint32_t *)&buf[CONFIG_RO_SIZE - 4]); - trace12(0, LFW, 0, "EC image CRC32 = 0x%08x expected = 0x%08x", - crc_calc, crc_exp); -#endif - - return 0; -} - -void udelay(unsigned int us) -{ - uint32_t t0 = __hw_clock_source_read(); - - while (__hw_clock_source_read() - t0 < us) - ; -} - -void usleep(unsigned int us) -{ - udelay(us); -} - -int timestamp_expired(timestamp_t deadline, const timestamp_t *now) -{ - timestamp_t now_val; - - if (!now) { - now_val = get_time(); - now = &now_val; - } - - return ((int64_t)(now->val - deadline.val) >= 0); -} - -/* - * LFW does not use interrupts so no ISR will fire to - * increment high 32-bits of timestap_t. Force high - * word to zero. NOTE: There is a risk of false timeout - * errors due to timer wrap. We will reset timer before - * each SPI transaction. - */ -timestamp_t get_time(void) -{ - timestamp_t ts; - - ts.le.hi = 0; /* clksrc_high; */ - ts.le.lo = __hw_clock_source_read(); - return ts; -} - -#ifdef CONFIG_UART_CONSOLE - -BUILD_ASSERT(CONFIG_UART_CONSOLE < MCHP_UART_INSTANCES); - -void uart_write_c(char c) -{ - /* Put in carriage return prior to newline to mimic uart_vprintf() */ - if (c == '\n') - uart_write_c('\r'); - - /* Wait for space in transmit FIFO. */ - while (!(MCHP_UART_LSR(CONFIG_UART_CONSOLE) & BIT(5))) - ; - MCHP_UART_TB(CONFIG_UART_CONSOLE) = c; -} - -void uart_puts(const char *str) -{ - if (!str || !*str) - return; - - do { - uart_write_c(*str++); - } while (*str); -} - -void uart_init(void) -{ - /* Set UART to reset on VCC1_RESET instead of nSIO_RESET */ - MCHP_UART_CFG(CONFIG_UART_CONSOLE) &= ~BIT(1); - - /* Baud rate = 115200. 1.8432MHz clock. Divisor = 1 */ - - /* Set CLK_SRC = 0 */ - MCHP_UART_CFG(CONFIG_UART_CONSOLE) &= ~BIT(0); - - /* Set DLAB = 1 */ - MCHP_UART_LCR(CONFIG_UART_CONSOLE) |= BIT(7); - - /* PBRG0/PBRG1 */ - MCHP_UART_PBRG0(CONFIG_UART_CONSOLE) = 1; - MCHP_UART_PBRG1(CONFIG_UART_CONSOLE) = 0; - - /* Set DLAB = 0 */ - MCHP_UART_LCR(CONFIG_UART_CONSOLE) &= ~BIT(7); - - /* Set word length to 8-bit */ - MCHP_UART_LCR(CONFIG_UART_CONSOLE) |= BIT(0) | BIT(1); - - /* Enable FIFO */ - MCHP_UART_FCR(CONFIG_UART_CONSOLE) = BIT(0); - - /* Activate UART */ - MCHP_UART_ACT(CONFIG_UART_CONSOLE) |= BIT(0); - - gpio_config_module(MODULE_UART, 1); -} -#else -void uart_write_c(char c __attribute__((unused))) {} - -void uart_puts(const char *str __attribute__((unused))) {} - -void uart_init(void) {} -#endif /* #ifdef CONFIG_UART_CONSOLE */ - -void fault_handler(void) -{ - uart_puts("EXCEPTION!\nTriggering watchdog reset\n"); - /* trigger reset in 1 ms */ - usleep(1000); - MCHP_PCR_SYS_RST = MCHP_PCR_SYS_SOFT_RESET; - while (1) - ; - -} - -void jump_to_image(uintptr_t init_addr) -{ - void (*resetvec)(void) = (void(*)(void))init_addr; - - resetvec(); -} - -/* - * If any of VTR POR, VBAT POR, chip resets, or WDT reset are active - * force VBAT image type to none causing load of EC_RO. - */ -void system_init(void) -{ - uint32_t wdt_sts = MCHP_VBAT_STS & MCHP_VBAT_STS_ANY_RST; - uint32_t rst_sts = MCHP_PCR_PWR_RST_STS & - MCHP_PWR_RST_STS_SYS; - - trace12(0, LFW, 0, - "VBAT_STS = 0x%08x PCR_PWR_RST_STS = 0x%08x", - wdt_sts, rst_sts); - - if (rst_sts || wdt_sts) - MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX) - = EC_IMAGE_UNKNOWN; -} - -enum ec_image system_get_image_copy(void) -{ - return MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX); -} - - -/* - * lfw_main is entered by MEC BootROM or EC_RO/RW calling it directly. - * NOTE: Based on LFW from MEC1322 - * Upon chip reset, BootROM loads image = LFW+EC_RO and enters LFW. - * LFW checks reset type: - * VTR POR, chip reset, WDT reset then set VBAT Load type to Unknown. - * LFW reads VBAT Load type: - * EC_IMAGE_RO then read EC_RO from SPI flash and jump into it. - * EC_IMAGE_RO then read EC_RW from SPI flash and jump into it. - * Other then jump into EC image loaded by Boot-ROM. - */ -void lfw_main(void) -{ - - uintptr_t init_addr; - - /* install vector table */ - *((uintptr_t *) 0xe000ed08) = (uintptr_t) &hdr_int_vect; - - /* Use 48 MHz processor clock to power through boot */ - MCHP_PCR_PROC_CLK_CTL = 1; - -#ifdef CONFIG_WATCHDOG - /* Reload watchdog which may be running in case of sysjump */ - MCHP_WDG_KICK = 1; -#ifdef CONFIG_WATCHDOG_HELP - /* Stop aux timer */ - MCHP_TMR16_CTL(0) &= ~1; -#endif -#endif - /* - * TFDP functions will compile to nothing if CONFIG_MEC1701_TFDP - * is not defined. - */ - tfdp_power(1); - tfdp_enable(1, 1); - trace0(0, LFW, 0, "LFW first trace"); - - timer_init(); - clock_init(); - cpu_init(); - dma_init(); - uart_init(); - system_init(); - - spi_enable(SPI_FLASH_DEVICE, 1); - - uart_puts("littlefw "); - uart_puts(current_image_data.version); - uart_puts("\n"); - - switch (system_get_image_copy()) { - case EC_IMAGE_RW: - trace0(0, LFW, 0, "LFW EC_RW Load"); - uart_puts("lfw-RW load\n"); - - init_addr = CONFIG_RW_MEM_OFF + CONFIG_PROGRAM_MEMORY_BASE; - spi_image_load(CONFIG_EC_WRITABLE_STORAGE_OFF + - CONFIG_RW_STORAGE_OFF); - break; - case EC_IMAGE_RO: - trace0(0, LFW, 0, "LFW EC_RO Load"); - uart_puts("lfw-RO load\n"); - - init_addr = CONFIG_RO_MEM_OFF + CONFIG_PROGRAM_MEMORY_BASE; - spi_image_load(CONFIG_EC_PROTECTED_STORAGE_OFF + - CONFIG_RO_STORAGE_OFF); - break; - default: - trace0(0, LFW, 0, "LFW default: use EC_RO loaded by BootROM"); - uart_puts("lfw-default case\n"); - - MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX) = EC_IMAGE_RO; - - init_addr = CONFIG_RO_MEM_OFF + CONFIG_PROGRAM_MEMORY_BASE; - } - - trace11(0, LFW, 0, "Get EC reset handler from 0x%08x", (init_addr + 4)); - trace11(0, LFW, 0, "Jump to EC @ 0x%08x", - *((uint32_t *)(init_addr + 4))); - jump_to_image(*(uintptr_t *)(init_addr + 4)); - - /* should never get here */ - while (1) - ; -} diff --git a/chip/mchp/lfw/ec_lfw.h b/chip/mchp/lfw/ec_lfw.h deleted file mode 100644 index c989a3bc1b..0000000000 --- a/chip/mchp/lfw/ec_lfw.h +++ /dev/null @@ -1,41 +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. - * - * MCHP MEC SoC little FW - * - */ - -#include <stdint.h> -#include <stdnoreturn.h> - -/* Why naked? This is dangerous except for - * function/ISR wrappers using inline assembly. - * lfw_main() makes many calls and has one local variable. - * Naked C functions should not use local data unless the local - * data can fit in CPU registers. - * Note other C functions called by lfw_main() are not marked naked and - * do include compiler generated prolog and epilog code. - * We also do not know how much stack space is available when - * EC_RO calls lfw_main(). - * -noreturn void lfw_main(void) __attribute__ ((naked)); -*/ -noreturn void lfw_main(void); -void fault_handler(void) __attribute__((naked)); - -/* - * Defined in linker file ec_lfw.ld - */ -extern uint32_t lfw_stack_top[]; - -struct int_vector_t { - void *stack_ptr; - void *reset_vector; - void *nmi; - void *hard_fault; - void *bus_fault; - void *usage_fault; -}; - -#define SPI_CHUNK_SIZE 1024 diff --git a/chip/mchp/lfw/ec_lfw.ld b/chip/mchp/lfw/ec_lfw.ld deleted file mode 100644 index 8e8601a5ee..0000000000 --- a/chip/mchp/lfw/ec_lfw.ld +++ /dev/null @@ -1,85 +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. - * - * MCHP MEC parts with 256KB SRAM SoC little FW - * - */ - -/* - * Memory Spaces Definitions - * LFW occupies first 4KB of CODE SRAM. - * First 24 bytes contain a minimal Cortex-M4 - * vector table. - */ -MEMORY -{ - VECTOR(r ) : ORIGIN = 0x0E0000, LENGTH = 0x18 - SRAM (xrw) : ORIGIN = 0x0E0018, LENGTH = 0xFE8 -} - -/* - * ld does not allow mathematical expressions in ORIGIN/LENGTH, so check the - * values here. - */ -ASSERT(ORIGIN(VECTOR) + LENGTH(VECTOR) == ORIGIN(SRAM), "Invalid SRAM origin.") -ASSERT(LENGTH(VECTOR) + LENGTH(SRAM) == 0x1000, "Invalid VECTOR+SRAM length.") - -/* - * The entry point is informative, for debuggers and simulators, - * since the Cortex-M vector points to it anyway. - */ -ENTRY(lfw_main) - -/* - * MEC 256KB SRAM 0xE0000 - 0x11FFFF - * Data Top 32KB at 0x118000 - 0x11FFFF - * Boot-ROM log is 0x11FF00 - 0x11FFFF - * Set top of LFW stack 1KB below top of SRAM - * because EC panic and jump data live at - * top of SRAM. - * !!!WARNING!!! - * POR or any chip reset will cause MEC BootROM - * to run. BootROM will clear all CODE & DATA SRAM. - * Panic data will be lost. - * - */ -PROVIDE( lfw_stack_top = 0x11F000 ); - -/* Sections Definitions */ - -SECTIONS -{ - - /* - * The vector table goes first - */ - .intvector : - { - . = ALIGN(4); - KEEP(*(.intvector)) - } > VECTOR - - /* - * The program code is stored in the .text section, - * which goes to FLASH. - */ - - .text : - { - *(.text .text.*) /* all remaining code */ - *(.rodata .rodata.*) /* read-only data (constants) */ - } >SRAM - - . = ALIGN(4); - - /* Padding */ - - .fill : { - FILL(0xFF); - . = ORIGIN(SRAM) + LENGTH(SRAM) - 1; - BYTE(0xFF); /* emit at least a byte to make linker happy */ - } - - __image_size = LOADADDR(.text) + SIZEOF(.text) - ORIGIN(VECTOR); -} diff --git a/chip/mchp/lfw/ec_lfw_416kb.ld b/chip/mchp/lfw/ec_lfw_416kb.ld deleted file mode 100644 index 97be2fe06a..0000000000 --- a/chip/mchp/lfw/ec_lfw_416kb.ld +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * MCHP MEC parts with 416KB SRAM SoC little FW - * - */ - -/* - * Memory Spaces Definitions - * LFW occupies first 4KB of CODE SRAM. - * First 24 bytes contain a minimal Cortex-M4 - * vector table. - */ -MEMORY -{ - VECTOR(r ) : ORIGIN = 0x0C0000, LENGTH = 0x18 - SRAM (xrw) : ORIGIN = 0x0C0018, LENGTH = 0xFE8 -} - -/* - * ld does not allow mathematical expressions in ORIGIN/LENGTH, so check the - * values here. - */ -ASSERT(ORIGIN(VECTOR) + LENGTH(VECTOR) == ORIGIN(SRAM), "Invalid SRAM origin.") -ASSERT(LENGTH(VECTOR) + LENGTH(SRAM) == 0x1000, "Invalid VECTOR+SRAM length.") - -/* - * The entry point is informative, for debuggers and simulators, - * since the Cortex-M vector points to it anyway. - */ -ENTRY(lfw_main) - -/* - * MEC172xN has 416KB total SRAM: 352KB CODE 64KB DATA - * CODE: 0x0C0000 - 0x117FFF - * DATA: 0x118000 - 0x127FFF - * Boot-ROM log is 0x11FF00 - 0x11FFFF - * MEC172x Top 1KB is not cleared if OTP customer flag enabled. - * !!! TODO !!! Does presence of PUF feature move customer area? - * Boot-ROM spec states 3.5KB from top is lost. - * 0x12_7800 - 0x12_7fff 2KB used by PUF option - * 0x12_7400 - 0x12_77ff 1KB Customer use. Not cleared by Boot-ROM - * 0x12_7200 - 0x12_73ff 512 byte Boot-ROM log - * CrOS EC puts panic data at Top of RAM. - * We must set Top of RAM to be customer region far enough to - * hold panic data. - * Set Top of SRAM to 0x12_7800. - * This requires size of SRAM = 0x127800 - 0x118000 = 0xF800 (62 KB) - */ -PROVIDE( lfw_stack_top = 0x127800 ); - -/* Sections Definitions */ - -SECTIONS -{ - - /* - * The vector table goes first - */ - .intvector : - { - . = ALIGN(4); - KEEP(*(.intvector)) - } > VECTOR - - /* - * The program code is stored in the .text section, - * which goes to FLASH. - */ - - .text : - { - *(.text .text.*) /* all remaining code */ - *(.rodata .rodata.*) /* read-only data (constants) */ - } >SRAM - - . = ALIGN(4); - - /* Padding */ - - .fill : { - FILL(0xFF); - . = ORIGIN(SRAM) + LENGTH(SRAM) - 1; - BYTE(0xFF); /* emit at least a byte to make linker happy */ - } - - __image_size = LOADADDR(.text) + SIZEOF(.text) - ORIGIN(VECTOR); -} diff --git a/chip/mchp/lfw/gpio.inc b/chip/mchp/lfw/gpio.inc deleted file mode 100644 index 598a6044d7..0000000000 --- a/chip/mchp/lfw/gpio.inc +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- mode:c -*- - * - * Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Common GPIOs needed for LFW loader and main process FW - */ - -/* SPI - * External SPI chip select must be open drain and driven high or - * internal SPI chip select must be push-pull and driven high before - * SPI controller configuration. - * QMSPI external Shared CS0# is GPIO_0055 - * QMSPI internal CS0# is GPIO_0116 - */ -#if defined(CHIP_VARIANT_MEC1727SZ) -GPIO(QMSPI_CS0, PIN(0116), GPIO_PULL_UP | GPIO_HIGH) -#else -GPIO(QMSPI_CS0, PIN(055), GPIO_ODR_HIGH) -#endif - -/* Boot-ROM loads from external or internal SPI flash. - * There are two external ports: shared(default) and private. - * NOTE: QMSPI Shared SPI Port pins are on VTR2 - * SHD_CS0# = GPIO 0055 Func 2 bank 1 b[13] - * SHD_CLK = GPIO 0056 Func 2 bank 1 b[14] - * SHD_IO0 = GPIO 0223 Func 1 bank 4 b[19] - * SHD_IO1 = GPIO 0224 Func 2 bank 4 b[20] - * Not using IO2 and IO2 as data - * SHD_IO2 = GPIO 0227 Func 1 bank 4 b[23] - * SHD_IO3 = GPIO 0016 Func 2 bank 0 b[14] - * MEC1727 variants load from internal 512KB SPI flash(internal only pins) - * INT_CS# = GPIO 0116 Func 1 bank 2 14 - * INT_SCK = GPIO 0117 Func 1 bank 2 15 - * INT_IO0 = GPIO 0074 Func 1 bank 1 28 - * INT_IO1 = GPIO 0075 Func 1 bank 1 29 - * INT_WP# = GPIO 0076 Func 0 for WP# control - * Internal flash HOLD# connected to VTR1 rail. - */ -#if defined(CHIP_VARIANT_MEC1727SZ) -/* MEC1727 variants have internal SPI flash on internal only pins */ -ALTERNATE(PIN_MASK(2, 0x4000), 1, MODULE_SPI_FLASH, GPIO_PULL_UP) -ALTERNATE(PIN_MASK(2, 0x8000), 1, MODULE_SPI_FLASH, 0) -ALTERNATE(PIN_MASK(1, 0x30000000), 1, MODULE_SPI_FLASH, 0) -#else -/* external SPI flash on QMSPI SHD_xx pins */ -ALTERNATE(PIN_MASK(1, 0x2000), 2, MODULE_SPI_FLASH, GPIO_ODR_HIGH) -ALTERNATE(PIN_MASK(1, 0x4000), 2, MODULE_SPI_FLASH, 0) -ALTERNATE(PIN_MASK(4, 0x080000), 1, MODULE_SPI_FLASH, 0) -ALTERNATE(PIN_MASK(4, 0x100000), 2, MODULE_SPI_FLASH, 0) -#endif - -/* UART - * Per CONFIG_UART_CONSOLE and chip to configure UART pins - */ -#if CONFIG_UART_CONSOLE == 0 -/* select UART0 */ -/* MEC170X, MEC152X and MEC172X support same UART0 pins and ALT function */ -/* - * UART0 - * GPIO_0105 Func 1 = UART_RX - * GPIO_0104 Func 1 = UART_TX - * Bank 2 bits[5:4] - */ -ALTERNATE(PIN_MASK(2, 0x30), 1, MODULE_UART, 0) - -#elif CONFIG_UART_CONSOLE == 1 -/* select UART1 */ -/* MEC170X, MEC152X and MEC172X support same UART1 pins - * but ALT function 2 on MEC170X, function 1 on others - */ -#if defined(CHIP_FAMILY_MEC170X) -/* - * UART1 - * GPIO_0171 Func 2 = UART_RX - * GPIO_0170 Func 2 = UART_TX - * Bank 3 bits[25:24] - */ -ALTERNATE(PIN_MASK(3, 0x03000000), 2, MODULE_UART, 0) - -#else -/* - * UART1 - * GPIO_0171 Func 1 = UART_RX - * GPIO_0170 Func 1 = UART_TX - * Bank 3 bits[25:24] - */ -ALTERNATE(PIN_MASK(3, 0x03000000), 1, MODULE_UART, 0) - -#endif /* defined(CHIP_FAMILY_MEC170X) */ - -#else -/* select UART2 */ -/* only MEC152X supports UART2 pins */ -#if defined(CHIP_FAMILY_MEC152X) -/* - * UART2 - * GPIO_0145 Func 2 = UART_RX - * GPIO_0146 Func 2 = UART_TX - * Bank 3 bits[6:5] - */ -ALTERNATE(PIN_MASK(3, 0x60), 2, MODULE_UART, 0) - -#endif /* defined(CHIP_FAMILY_MEC152X) */ - -#endif /* CONFIG_UART_CONSOLE == 0 */ diff --git a/chip/mchp/lpc.c b/chip/mchp/lpc.c deleted file mode 100644 index b5db07b88f..0000000000 --- a/chip/mchp/lpc.c +++ /dev/null @@ -1,1022 +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. - */ - -/* LPC module for MCHP MEC family */ - -#include "common.h" -#include "acpi.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "keyboard_protocol.h" -#include "lpc.h" -#include "lpc_chip.h" -#include "espi.h" -#include "port80.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "chipset.h" -#include "tfdp_chip.h" - -/* Console output macros */ -#ifdef CONFIG_MCHP_DEBUG_LPC -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) -#else -#define CPUTS(...) -#define CPRINTS(...) -#endif - -static uint8_t -mem_mapped[0x200] __attribute__((section(".bss.big_align"))); - -static struct host_packet lpc_packet; -static struct host_cmd_handler_args host_cmd_args; -static uint8_t host_cmd_flags; /* Flags from host command */ - -static uint8_t params_copy[EC_LPC_HOST_PACKET_SIZE] __aligned(4); -static int init_done; - -static struct ec_lpc_host_args * const lpc_host_args = - (struct ec_lpc_host_args *)mem_mapped; - -#ifdef CONFIG_BOARD_ID_CMD_ACPI_EC1 -static uint8_t custom_acpi_cmd; -static uint8_t custom_acpi_ec2os_cnt; -static uint8_t custom_apci_ec2os[4]; -#endif - - -static void keyboard_irq_assert(void) -{ -#ifdef CONFIG_KEYBOARD_IRQ_GPIO - /* - * Enforce signal-high for long enough for the signal to be - * pulled high by the external pull up resistor. This ensures the - * host will see the following falling edge, regardless of the - * line state before this function call. - */ - gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1); - udelay(4); - /* Generate a falling edge */ - gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 0); - udelay(4); - - /* Set signal high, now that we've generated the edge */ - gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1); -#else - /* - * SERIRQ is automatically sent by KBC - */ -#endif -} - -/** - * 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 60 ns. 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 65 us. - */ -static void lpc_generate_smi(void) -{ - CPUTS("LPC Pulse SMI"); -#ifdef CONFIG_HOSTCMD_ESPI - /* eSPI: pulse SMI# Virtual Wire low */ - espi_vw_pulse_wire(VW_SMI_L, 0); -#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) -{ - CPUTS("LPC Pulse SCI"); -#ifdef CONFIG_SCI_GPIO - gpio_set_level(CONFIG_SCI_GPIO, 0); - udelay(65); - gpio_set_level(CONFIG_SCI_GPIO, 1); -#else -#ifdef CONFIG_HOSTCMD_ESPI - espi_vw_pulse_wire(VW_SCI_L, 0); -#else - MCHP_ACPI_PM_STS |= 1; - udelay(65); - MCHP_ACPI_PM_STS &= ~1; -#endif -#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); - -#ifdef CONFIG_HOSTCMD_ESPI - espi_vw_set_wire(VW_WAKE_L, !wake_events); -#else - /* Signal is asserted low when wake events is non-zero */ - gpio_set_level(GPIO_PCH_WAKE_L, !wake_events); -#endif -} - -static uint8_t *lpc_get_hostcmd_data_range(void) -{ - return mem_mapped; -} - - -/** - * Update the host event status. - * - * Sends a pulse if masked event status becomes non-zero: - * - SMI pulse via PCH_SMI_L GPIO - * - SCI pulse via PCH_SCI_L GPIO - */ -void lpc_update_host_event_status(void) -{ - int need_sci = 0; - int need_smi = 0; - - CPUTS("LPC update_host_event_status"); - - if (!init_done) - return; - - /* Disable LPC interrupt while updating status register */ - task_disable_irq(MCHP_IRQ_ACPIEC0_IBF); - - if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI)) { - /* Only generate SMI for first event */ - if (!(MCHP_ACPI_EC_STATUS(0) & EC_LPC_STATUS_SMI_PENDING)) - need_smi = 1; - MCHP_ACPI_EC_STATUS(0) |= EC_LPC_STATUS_SMI_PENDING; - } else { - MCHP_ACPI_EC_STATUS(0) &= ~EC_LPC_STATUS_SMI_PENDING; - } - - if (lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI)) { - /* Generate SCI for every event */ - need_sci = 1; - MCHP_ACPI_EC_STATUS(0) |= EC_LPC_STATUS_SCI_PENDING; - } else { - MCHP_ACPI_EC_STATUS(0) &= ~EC_LPC_STATUS_SCI_PENDING; - } - - /* Copy host events to mapped memory */ - *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = - lpc_get_host_events(); - - task_enable_irq(MCHP_IRQ_ACPIEC0_IBF); - - /* 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(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 parameter buffer */ - if (size > EC_PROTO2_MAX_PARAM_SIZE) - args->result = EC_RES_INVALID_RESPONSE; - - /* Write result to the data byte. */ - MCHP_ACPI_EC_EC2OS(1, 0) = args->result; - - /* - * Clear processing flag in hardware and - * sticky status in interrupt aggregator. - */ - MCHP_ACPI_EC_STATUS(1) &= ~EC_LPC_STATUS_PROCESSING; - MCHP_INT_SOURCE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_IBF_GIRQ_BIT(1); - -} - -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) { - /* CPRINTS("LPC EC_RES_IN_PROGRESS"); */ - return; - } - - CPRINTS("LPC Set EC2OS(1,0)=0x%02x", pkt->driver_result); - - /* Write result to the data byte. */ - MCHP_ACPI_EC_EC2OS(1, 0) = pkt->driver_result; - - /* Clear the busy bit, so the host knows the EC is done. */ - MCHP_ACPI_EC_STATUS(1) &= ~EC_LPC_STATUS_PROCESSING; - MCHP_INT_SOURCE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_IBF_GIRQ_BIT(1); -} - -uint8_t *lpc_get_memmap_range(void) -{ - return mem_mapped + 0x100; -} - -void lpc_mem_mapped_init(void) -{ - /* We support LPC arguments 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; -} - -const int acpi_ec_pcr_slp[] = { - MCHP_PCR_ACPI_EC0, - MCHP_PCR_ACPI_EC1, - MCHP_PCR_ACPI_EC2, - MCHP_PCR_ACPI_EC3, -#ifndef CHIP_FAMILY_MEC152X - MCHP_PCR_ACPI_EC4, -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(acpi_ec_pcr_slp) == MCHP_ACPI_EC_INSTANCES); - -const int acpi_ec_nvic_ibf[] = { - MCHP_IRQ_ACPIEC0_IBF, - MCHP_IRQ_ACPIEC1_IBF, - MCHP_IRQ_ACPIEC2_IBF, - MCHP_IRQ_ACPIEC3_IBF, -#ifndef CHIP_FAMILY_MEC152X - MCHP_IRQ_ACPIEC4_IBF, -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(acpi_ec_nvic_ibf) == MCHP_ACPI_EC_INSTANCES); - -#ifdef CONFIG_HOSTCMD_ESPI -const int acpi_ec_espi_bar_id[] = { - MCHP_ESPI_IO_BAR_ID_ACPI_EC0, - MCHP_ESPI_IO_BAR_ID_ACPI_EC1, - MCHP_ESPI_IO_BAR_ID_ACPI_EC2, - MCHP_ESPI_IO_BAR_ID_ACPI_EC3, -#ifndef CHIP_FAMILY_MEC152X - MCHP_ESPI_IO_BAR_ID_ACPI_EC4, -#endif -}; -BUILD_ASSERT(ARRAY_SIZE(acpi_ec_espi_bar_id) == MCHP_ACPI_EC_INSTANCES); -#endif - -void chip_acpi_ec_config(int instance, uint32_t io_base, uint8_t mask) -{ - if (instance >= MCHP_ACPI_EC_INSTANCES) { - CPUTS("ACPI EC CFG invalid"); - return; - } - - MCHP_PCR_SLP_DIS_DEV(acpi_ec_pcr_slp[instance]); - -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_ESPI_IO_BAR_CTL_MASK(acpi_ec_espi_bar_id[instance]) = - mask; - MCHP_ESPI_IO_BAR(acpi_ec_espi_bar_id[instance]) = - (io_base << 16) + 0x01ul; -#else - MCHP_LPC_ACPI_EC_BAR(instance) = (io_base << 16) + - (1ul << 15) + mask; -#endif - MCHP_ACPI_EC_STATUS(instance) &= ~EC_LPC_STATUS_PROCESSING; - MCHP_INT_ENABLE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_IBF_GIRQ_BIT(instance); - task_enable_irq(acpi_ec_nvic_ibf[instance]); -} - -/* - * 8042EM hardware decodes with fixed mask of 0x04 - * Example: io_base == 0x60 -> decodes 0x60/0x64 - * Enable both IBF and OBE interrupts. - */ -void chip_8042_config(uint32_t io_base) -{ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_8042); - -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_ID_8042) = 0x04; - MCHP_ESPI_IO_BAR(MCHP_ESPI_IO_BAR_ID_8042) = - (io_base << 16) + 0x01ul; -#else - /* Set up 8042 interface at 0x60/0x64 */ - MCHP_LPC_8042_BAR = (io_base << 16) + (1ul << 15); -#endif - /* Set up indication of Auxiliary status */ - MCHP_8042_KB_CTRL |= BIT(7); - - MCHP_8042_ACT |= 1; - - MCHP_INT_ENABLE(MCHP_8042_GIRQ) = MCHP_8042_OBE_GIRQ_BIT + - MCHP_8042_IBF_GIRQ_BIT; - - task_enable_irq(MCHP_IRQ_8042EM_IBF); - task_enable_irq(MCHP_IRQ_8042EM_OBE); - -#ifndef CONFIG_KEYBOARD_IRQ_GPIO - /* Set up SERIRQ for keyboard */ - MCHP_8042_KB_CTRL |= BIT(5); -#ifdef CONFIG_HOSTCMD_ESPI - /* Delivery 8042 keyboard interrupt as IRQ1 using eSPI SERIRQ */ - MCHP_ESPI_IO_SERIRQ_REG(MCHP_ESPI_SIRQ_8042_KB) = 1; -#else - MCHP_LPC_SIRQ(1) = 0x01; -#endif -#endif -} - -/* - * Access data RAM - * MCHP EMI Base address register = physical address of buffer - * in SRAM. EMI hardware adds 16-bit offset Host programs into - * EC_Address_LSB/MSB registers. - * Limit EMI read / write range. First 256 bytes are RW for host - * commands. Second 256 bytes are RO for memory-mapped data. - * Hardware decodes a fixed 16 byte IO range. - */ -void chip_emi0_config(uint32_t io_base) -{ -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_ID_EMI0) = 0x0F; - MCHP_ESPI_IO_BAR(MCHP_ESPI_IO_BAR_ID_EMI0) = - (io_base << 16) + 0x01ul; -#else - MCHP_LPC_EMI0_BAR = (io_base << 16) + (1ul << 15); -#endif - - MCHP_EMI_MBA0(0) = (uint32_t)mem_mapped; - - MCHP_EMI_MRL0(0) = 0x200; - MCHP_EMI_MWL0(0) = 0x100; - - MCHP_INT_ENABLE(MCHP_EMI_GIRQ) = MCHP_EMI_GIRQ_BIT(0); - task_enable_irq(MCHP_IRQ_EMI0); -} - -/* Setup Port 80 Debug Hardware ports. - * First instance for I/O 80h only. - * Clear FIFO's and time stamp. - * Set FIFO interrupt threshold to maximum of 14 bytes. - */ -#if defined(CHIP_FAMILY_MEC172X) -void chip_port80_config(uint32_t io_base) -{ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_BDP0); - - /* reset, configure, and enable */ - MCHP_BDP0_CONFIG = MCHP_BDP_CFG_SRST; - MCHP_BDP0_CONFIG = MCHP_BDP_CFG_FIFO_THRH_28; - MCHP_BDP0_INTR_EN = MCHP_BDP_IEN_THRH; - MCHP_BDP0_ACTV = 1; - - MCHP_INT_SOURCE(15) = MCHP_INT15_BDP0; - MCHP_INT_ENABLE(15) = MCHP_INT15_BDP0; - task_enable_irq(MCHP_IRQ_BDP0); - - /* Last: Enable Host access via eSPI IO BAR */ - MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_BDP0) = 0x00; - MCHP_ESPI_IO_BAR(MCHP_ESPI_IO_BAR_BDP0) = - (io_base << 16) + 0x01ul; -} -#else -void chip_port80_config(uint32_t io_base) -{ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_P80CAP0); - - MCHP_P80_CFG(0) = MCHP_P80_FLUSH_FIFO_WO + - MCHP_P80_RESET_TIMESTAMP_WO; - -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_P80_0) = 0x00; - MCHP_ESPI_IO_BAR(MCHP_ESPI_IO_BAR_P80_0) = - (io_base << 16) + 0x01ul; -#else - MCHP_LPC_P80DBG0_BAR = (io_base << 16) + (1ul << 15); -#endif - MCHP_P80_CFG(0) = MCHP_P80_FIFO_THRHOLD_14 + - MCHP_P80_TIMEBASE_1500KHZ + - MCHP_P80_TIMER_ENABLE; - - MCHP_P80_ACTIVATE(0) = 1; - - MCHP_INT_SOURCE(15) = MCHP_P80_GIRQ_BIT(0); - MCHP_INT_ENABLE(15) = MCHP_P80_GIRQ_BIT(0); - task_enable_irq(MCHP_IRQ_PORT80DBG0); -} -#endif - -#ifdef CONFIG_MCHP_DEBUG_LPC -static void chip_lpc_iobar_debug(void) -{ - CPRINTS("LPC ACPI EC0 IO BAR = 0x%08x", MCHP_LPC_ACPI_EC_BAR(0)); - CPRINTS("LPC ACPI EC1 IO BAR = 0x%08x", MCHP_LPC_ACPI_EC_BAR(1)); - CPRINTS("LPC 8042EM IO BAR = 0x%08x", MCHP_LPC_8042_BAR); - CPRINTS("LPC EMI0 IO BAR = 0x%08x", MCHP_LPC_EMI0_BAR); - CPRINTS("LPC Port80Dbg0 IO BAR = 0x%08x", MCHP_LPC_P80DBG0_BAR); -} -#endif - -/* - * Most registers in LPC module are reset when the host is off. - * We need to set up LPC again when the host is starting up. - * MCHP LRESET# can be one of two pins - * GPIO_0052 Function 2 - * GPIO_0064 Function 1 - * Use GPIO interrupt to detect LRESET# changes. - * Use GPIO_0064 for LRESET#. Must update board/board_name/gpio.inc - * - * For eSPI PLATFORM_RESET# virtual wire is used as LRESET# - * - */ -#ifndef CONFIG_HOSTCMD_ESPI -static void setup_lpc(void) -{ - MCHP_LPC_CFG_BAR |= (1ul << 15); - - /* Set up ACPI0 for 0x62/0x66 */ - chip_acpi_ec_config(0, 0x62, 0x04); - - /* Set up ACPI1 for 0x200 - 0x207 */ - chip_acpi_ec_config(1, 0x200, 0x07); - - /* Set up 8042 interface at 0x60/0x64 */ - chip_8042_config(0x60); - -#ifndef CONFIG_KEYBOARD_IRQ_GPIO - /* Set up SERIRQ for keyboard */ - MCHP_8042_KB_CTRL |= BIT(5); - MCHP_LPC_SIRQ(1) = 0x01; -#endif - /* EMI0 at IO 0x800 */ - chip_emi0_config(0x800); - - chip_port80_config(0x80); - - lpc_mem_mapped_init(); - - /* Activate LPC interface */ - MCHP_LPC_ACT |= 1; - - /* Sufficiently initialized */ - init_done = 1; - - /* Update host events now that we can copy them to memmap */ - lpc_update_host_event_status(); - -#ifdef CONFIG_MCHP_DEBUG_LPC - chip_lpc_iobar_debug(); -#endif -} -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, setup_lpc, HOOK_PRIO_FIRST); -#endif - -static void lpc_init(void) -{ - CPUTS("LPC HOOK_INIT"); - - /* Initialize host args and memory map to all zero */ - memset(lpc_host_args, 0, sizeof(*lpc_host_args)); - memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE); - - /* - * Clear PCR sleep enables for peripherals we are using for - * both LPC and eSPI. - * Global Configuration, ACPI EC0/1, 8042 Keyboard controller. - * NOTE: EMI doesn't have a sleep enable. - */ - MCHP_PCR_SLP_DIS_DEV_MASK(2, MCHP_PCR_SLP_EN2_GCFG + - MCHP_PCR_SLP_EN2_ACPI_EC0 + - MCHP_PCR_SLP_EN2_ACPI_EC0 + - MCHP_PCR_SLP_EN2_MIF8042); - -#ifdef CONFIG_HOSTCMD_ESPI - - espi_init(); - -#else - /* Clear PCR LPC sleep enable */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_LPC); - - /* configure pins */ - gpio_config_module(MODULE_LPC, 1); - - /* - * MCHP LRESET# interrupt is GPIO interrupt - * and configured by GPIO table in board level gpio.inc - * Refer to lpcrst_interrupt() in this file. - */ - gpio_enable_interrupt(GPIO_PCH_PLTRST_L); - - /* - * b[8]=1(LRESET# is platform reset), b[0]=0 VCC_PWRGD is - * asserted when LRESET# is 1(inactive) - */ - MCHP_PCR_PWR_RST_CTL = 0x100ul; - - /* - * Allow LPC sleep if Host CLKRUN# signals - * clock stop and there are no pending SERIRQ - * or LPC DMA. - */ - MCHP_LPC_EC_CLK_CTRL = - (MCHP_LPC_EC_CLK_CTRL & ~(0x03ul)) | 0x01ul; - - setup_lpc(); -#endif -} -/* - * Set priority 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); - -#ifdef CONFIG_CHIPSET_RESET_HOOK -static void lpc_chipset_reset(void) -{ - hook_notify(HOOK_CHIPSET_RESET); -} -DECLARE_DEFERRED(lpc_chipset_reset); -#endif - -void lpc_set_init_done(int val) -{ - init_done = val; -} - -/* - * MCHP MCHP family allows selecting one of two GPIO pins alternate - * functions as LRESET#. - * LRESET# can be monitored as bit[1](read-only) of the - * LPC Bus Monitor register. NOTE: Bus Monitor is synchronized with - * LPC clock. We have observed APL configurations where LRESET# - * changes while LPC clock is not running! - * bit[1]==0 -> LRESET# is high - * bit[1]==1 -> LRESET# is low (active) - * LRESET# active causes the EC to activate internal signal RESET_HOST. - * MCHP_PCR_PWR_RST_STS bit[3](read-only) = RESET_HOST_STATUS = - * 0 = Reset active - * 1 = Reset not active - * MCHP is different than MEC1322 in that LRESET# is not connected - * to a separate interrupt source. - * If using LPC the board design must select on of the two GPIO pins - * dedicated for LRESET# and this pin must be configured in the - * board level gpio.inc - */ -void lpcrst_interrupt(enum gpio_signal signal) -{ -#ifndef CONFIG_HOSTCMD_ESPI - /* Initialize LPC module when LRESET# is de-asserted */ - if (!lpc_get_pltrst_asserted()) { - setup_lpc(); - } else { - /* Store port 80 reset event */ - port_80_write(PORT_80_EVENT_RESET); - -#ifdef CONFIG_CHIPSET_RESET_HOOK - /* Notify HOOK_CHIPSET_RESET */ - hook_call_deferred(&lpc_chipset_reset_data, MSEC); -#endif - } -#ifdef CONFIG_MCHP_DEBUG_LPC - CPRINTS("LPC RESET# %sasserted", - lpc_get_pltrst_asserted() ? "" : "de"); -#endif -#endif -} - -/* - * TODO - Is this only for debug of EMI host communication - * or logging of EMI host communication? We don't observe - * this ISR so Host is not writing to MCHP_EMI_H2E_MBX(0). - */ -void emi0_interrupt(void) -{ - uint8_t h2e; - - h2e = MCHP_EMI_H2E_MBX(0); - CPRINTS("LPC Host 0x%02x -> EMI0 H2E(0)", h2e); - port_80_write(h2e); -} -DECLARE_IRQ(MCHP_IRQ_EMI0, emi0_interrupt, 1); - -/* - * ISR empties BIOS Debug 0 FIFO and - * writes data to circular buffer. How can we be - * sure this routine can read the last Port 80h byte? - * MEC172x BDP capture data is different. It returns a - * 16-bit value where bits [7:0] are the data and bits [15:7] - * are flags indicating if the data is part of a multi-byte - * write sequence by the host and read-only FIFO status bits. - * The capture HW in previous chips included an optional time - * stamp in bits[31:8] of the data register. - */ -int port_80_read(void) -{ - int data = PORT_80_IGNORE; - -#if defined(CHIP_FAMILY_MEC172X) - if (MCHP_BDP0_STATUS & MCHP_BDP_STATUS_NOT_EMPTY) - data = MCHP_BDP0_DATTR & 0xFFU; -#else - if (MCHP_P80_STS(0) & MCHP_P80_STS_NOT_EMPTY) - data = MCHP_P80_CAP(0) & 0xFF; -#endif - - return data; -} - -#ifdef CONFIG_BOARD_ID_CMD_ACPI_EC1 -/* - * Handle custom ACPI EC0 commands. - * Some chipset CoreBoot will send read board ID command expecting - * a two byte response. - */ -static int acpi_ec0_custom(int is_cmd, uint8_t value, - uint8_t *resultptr) -{ - int rval; - - rval = 0; - custom_acpi_ec2os_cnt = 0; - *resultptr = 0x00; - - if (is_cmd && (value == 0x0d)) { - MCHP_INT_SOURCE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_OBE_GIRQ_BIT(0); - /* Write two bytes sequence 0xC2, 0x04 to Host */ - if (MCHP_ACPI_EC_BYTE_CTL(0) & 0x01) { - /* Host enabled 4-byte mode */ - MCHP_ACPI_EC_EC2OS(0, 0) = 0x02; - MCHP_ACPI_EC_EC2OS(0, 1) = 0x04; - MCHP_ACPI_EC_EC2OS(0, 2) = 0x00; - /* Sets OBF */ - MCHP_ACPI_EC_EC2OS(0, 3) = 0x00; - } else { - /* single byte mode */ - *resultptr = 0x02; - custom_acpi_ec2os_cnt = 1; - custom_apci_ec2os[0] = 0x04; - MCHP_ACPI_EC_EC2OS(0, 0) = 0x02; - MCHP_INT_ENABLE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_OBE_GIRQ_BIT(0); - task_enable_irq(MCHP_IRQ_ACPIEC0_OBE); - } - custom_acpi_cmd = 0; - rval = 1; - } - - return rval; -} -#endif - -void acpi_0_interrupt(void) -{ - uint8_t value, result, is_cmd; - - is_cmd = MCHP_ACPI_EC_STATUS(0); - - /* Set the bust bi */ - MCHP_ACPI_EC_STATUS(0) |= EC_LPC_STATUS_PROCESSING; - - result = MCHP_ACPI_EC_BYTE_CTL(0); - - /* Read command/data; this clears the FRMH bit. */ - value = MCHP_ACPI_EC_OS2EC(0, 0); - - is_cmd &= EC_LPC_STATUS_LAST_CMD; - - /* Handle whatever this was. */ - result = 0; - if (acpi_ap_to_ec(is_cmd, value, &result)) - MCHP_ACPI_EC_EC2OS(0, 0) = result; -#ifdef CONFIG_BOARD_ID_CMD_ACPI_EC1 - else - acpi_ec0_custom(is_cmd, value, &result); -#endif - /* Clear the busy bit */ - MCHP_ACPI_EC_STATUS(0) &= ~EC_LPC_STATUS_PROCESSING; - - /* Clear R/W1C status bit in Aggregator */ - MCHP_INT_SOURCE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_IBF_GIRQ_BIT(0); - - /* - * ACPI 5.0-12.6.1: Generate SCI for Input Buffer Empty / - * Output Buffer Full condition on the kernel channel/ - */ - lpc_generate_sci(); -} -DECLARE_IRQ(MCHP_IRQ_ACPIEC0_IBF, acpi_0_interrupt, 1); - -#ifdef CONFIG_BOARD_ID_CMD_ACPI_EC1 -/* - * ACPI EC0 output buffer empty ISR. - * Used to handle custom ACPI EC0 command requiring - * two byte response. - */ -void acpi_0_obe_isr(void) -{ - uint8_t sts, data; - - MCHP_INT_SOURCE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_OBE_GIRQ_BIT(0); - - sts = MCHP_ACPI_EC_STATUS(0); - data = MCHP_ACPI_EC_BYTE_CTL(0); - data = sts; - if (custom_acpi_ec2os_cnt) { - custom_acpi_ec2os_cnt--; - data = custom_apci_ec2os[custom_acpi_ec2os_cnt]; - } - - if (custom_acpi_ec2os_cnt == 0) { /* was last byte? */ - MCHP_INT_DISABLE(MCHP_ACPI_EC_GIRQ) = - MCHP_ACPI_EC_OBE_GIRQ_BIT(0); - } - - lpc_generate_sci(); -} -DECLARE_IRQ(MCHP_IRQ_ACPIEC0_OBE, acpi_0_obe_isr, 1); -#endif - -void acpi_1_interrupt(void) -{ - uint8_t st = MCHP_ACPI_EC_STATUS(1); - - if (!(st & EC_LPC_STATUS_FROM_HOST) || - !(st & EC_LPC_STATUS_LAST_CMD)) - return; - - /* Set the busy bit */ - MCHP_ACPI_EC_STATUS(1) |= EC_LPC_STATUS_PROCESSING; - - /* - * Read the command byte. This clears the FRMH bit in - * the status byte. - */ - host_cmd_args.command = MCHP_ACPI_EC_OS2EC(1, 0); - - host_cmd_args.result = EC_RES_SUCCESS; - 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 *)lpc_get_hostcmd_data_range(); - 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 *)lpc_get_hostcmd_data_range(); - 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); - - } else { - /* Old style command unsupported */ - host_cmd_args.result = EC_RES_INVALID_COMMAND; - - /* Hand off to host command handler */ - host_command_received(&host_cmd_args); - } -} -DECLARE_IRQ(MCHP_IRQ_ACPIEC1_IBF, acpi_1_interrupt, 1); - -#ifdef HAS_TASK_KEYPROTO -/* - * Reading data out of input buffer clears read-only status - * in 8042EM. Next, we must clear aggregator status. - */ -void kb_ibf_interrupt(void) -{ - if (lpc_keyboard_input_pending()) - keyboard_host_write(MCHP_8042_H2E, - MCHP_8042_STS & BIT(3)); - - MCHP_INT_SOURCE(MCHP_8042_GIRQ) = MCHP_8042_IBF_GIRQ_BIT; - task_wake(TASK_ID_KEYPROTO); -} -DECLARE_IRQ(MCHP_IRQ_8042EM_IBF, kb_ibf_interrupt, 1); - -/* - * Interrupt generated when Host reads data byte from 8042EM - * output buffer. The 8042EM STATUS.OBF bit will clear when the - * Host reads the data and assert its OBE signal to interrupt - * aggregator. Clear aggregator 8042EM OBE R/WC status bit before - * invoking task. - */ -void kb_obe_interrupt(void) -{ - MCHP_INT_SOURCE(MCHP_8042_GIRQ) = MCHP_8042_OBE_GIRQ_BIT; - task_wake(TASK_ID_KEYPROTO); -} -DECLARE_IRQ(MCHP_IRQ_8042EM_OBE, kb_obe_interrupt, 1); -#endif - -/* - * Bit 0 of 8042EM STATUS register is OBF meaning EC has written - * data to EC2HOST data register. OBF is cleared when the host - * reads the data. - */ -int lpc_keyboard_has_char(void) -{ - return (MCHP_8042_STS & BIT(0)) ? 1 : 0; -} - -int lpc_keyboard_input_pending(void) -{ - return (MCHP_8042_STS & BIT(1)) ? 1 : 0; -} - -/* - * called from common/keyboard_8042.c - */ -void lpc_keyboard_put_char(uint8_t chr, int send_irq) -{ - MCHP_8042_E2H = chr; - if (send_irq) - keyboard_irq_assert(); -} - -/* - * Read 8042 register and write to read-only register - * insuring compiler does not optimize out the read. - */ -void lpc_keyboard_clear_buffer(void) -{ - MCHP_PCR_CHIP_OSC_ID = MCHP_8042_OBF_CLR; -} - -void lpc_keyboard_resume_irq(void) -{ - if (lpc_keyboard_has_char()) - keyboard_irq_assert(); -} - -void lpc_set_acpi_status_mask(uint8_t mask) -{ - MCHP_ACPI_EC_STATUS(0) |= mask; -} - -void lpc_clear_acpi_status_mask(uint8_t mask) -{ - MCHP_ACPI_EC_STATUS(0) &= ~mask; -} - -/* - * Read hardware to determine state of platform reset signal. - * LPC issue: Observed APL chipset changing LRESET# while LPC - * clock is not running. This violates original LPC specification. - * Unable to find information in APL chipset documentation - * stating APL can change LRESET# with LPC clock not running. - * Could this be a CoreBoot issue during CB LPC configuration? - * We work-around this issue by reading the GPIO state. - */ -int lpc_get_pltrst_asserted(void) -{ -#ifdef CONFIG_HOSTCMD_ESPI - /* - * eSPI PLTRST# a VWire or side-band signal - * Controlled by CONFIG_HOSTCMD_ESPI - */ - return !espi_vw_get_wire(VW_PLTRST_L); -#else - /* returns 1 if LRESET# pin is asserted(low) else 0 */ -#ifdef CONFIG_CHIPSET_APL_GLK - /* Use GPIO */ - return !gpio_get_level(GPIO_PCH_PLTRST_L); -#else - /* assumes LPC clock is running when host changes LRESET# */ - return (MCHP_LPC_BUS_MONITOR & (1<<1)) ? 1 : 0; -#endif -#endif -} - -/* Enable LPC ACPI-EC0 interrupts */ -void lpc_enable_acpi_interrupts(void) -{ - task_enable_irq(MCHP_IRQ_ACPIEC0_IBF); -} - -/* Disable LPC ACPI-EC0 interrupts */ -void lpc_disable_acpi_interrupts(void) -{ - task_disable_irq(MCHP_IRQ_ACPIEC0_IBF); -} - -/* On boards without a host, this command is used to set up LPC */ -static int lpc_command_init(int argc, char **argv) -{ - lpc_init(); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(lpcinit, lpc_command_init, NULL, NULL); - -/* 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; - - CPUTS("MEC1701 Handler EC_CMD_GET_PROTOCOL_INFO"); - - 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)); - -#ifdef CONFIG_MCHP_DEBUG_LPC -static int command_lpc(int argc, char **argv) -{ - if (argc == 1) - return EC_ERROR_PARAM1; - - if (!strcasecmp(argv[1], "sci")) - lpc_generate_sci(); - else if (!strcasecmp(argv[1], "smi")) - lpc_generate_smi(); - else if (!strcasecmp(argv[1], "wake")) - lpc_update_wake(-1); - else - return EC_ERROR_PARAM1; - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(lpc, command_lpc, "[sci|smi|wake]", - "Trigger SCI/SMI"); -#endif - diff --git a/chip/mchp/lpc_chip.h b/chip/mchp/lpc_chip.h deleted file mode 100644 index dcb5577fc1..0000000000 --- a/chip/mchp/lpc_chip.h +++ /dev/null @@ -1,49 +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. - */ - -/* Microchip MEC1701 specific module for Chrome EC */ - -#ifndef __CROS_EC_LPC_CHIP_H -#define __CROS_EC_LPC_CHIP_H - -#ifdef CONFIG_HOSTCMD_ESPI - -#include "espi.h" - -#define MCHP_HOST_IF_LPC (0) -#define MCHP_HOST_IF_ESPI (1) - -/* eSPI Initialization functions */ -void espi_init(void); - -/* eSPI ESPI_RESET# interrupt handler */ -void espi_reset_handler(void); - -/* - * - */ -int espi_vw_pulse_wire(enum espi_vw_signal signal, int pulse_level); - -void lpc_update_host_event_status(void); - -#endif - -/* LPC LRESET interrupt handler */ -void lpcrst_interrupt(enum gpio_signal signal); - -void lpc_set_init_done(int val); - -void lpc_mem_mapped_init(void); - -#ifndef CONFIG_HOSTCMD_ESPI -void lpcrst_interrupt(enum gpio_signal signal); -#endif - -void chip_acpi_ec_config(int instance, uint32_t io_base, uint8_t mask); -void chip_8042_config(uint32_t io_base); -void chip_emi0_config(uint32_t io_base); -void chip_port80_config(uint32_t io_base); - -#endif /* __CROS_EC_LPC_CHIP_H */ diff --git a/chip/mchp/port80.c b/chip/mchp/port80.c deleted file mode 100644 index ecfd0b5ebb..0000000000 --- a/chip/mchp/port80.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Port 80 Timer Interrupt for MCHP MEC family */ - -#include "common.h" -#include "console.h" -#include "hooks.h" -#include "lpc.h" -#include "port80.h" -#include "registers.h" -#include "task.h" -#include "tfdp_chip.h" - - -#if defined(CHIP_FAMILY_MEC172X) -/* - * MEC172x family implements a new Port 0x80 capture block. - * The BDP HW can capture 8, 16, and 32 bit writes. - * Interrupt fires when BDP FIFO threshold is reached. - * Data can be read from a 16-bit register containing: - * b[7:0] data byte - * b[9:8] = byte lane - * b[11:10]= flags indicating current byte is a single byte or part of - * a multi-byte sequence. - * b[14:12] = copy of bits[2:0] of the status register - * b[15] = 0 reserved - * NOTE: The overrun bit could be used to set a flag indicating EC could - * not keep up with the host. - */ -void port_80_interrupt(void) -{ - int d = MCHP_BDP0_DATTR; - - while (d & MCHP_BDP_DATTR_NE) { - port_80_write(d & 0xffU); - d = MCHP_BDP0_DATTR; - } - - MCHP_INT_SOURCE(MCHP_BDP0_GIRQ) = MCHP_BDP0_GIRQ_BIT; -} -DECLARE_IRQ(MCHP_IRQ_BDP0, port_80_interrupt, 3); -#else -/* - * Interrupt fires when number of bytes written - * to eSPI/LPC I/O 80h-81h exceeds Por80_0 FIFO level - * Issues: - * 1. eSPI will not break 16-bit I/O into two 8-bit writes - * as LPC does. This means Port 80h hardware will capture - * only bits[7:0] of data. - * 2. If Host performs write of 16-bit code as consecutive - * byte writes the Port 80h hardware will capture both but - * we do not know the order it was written. - * 3. If Host sometimes writes one byte code to I/O 80h and - * sometimes two byte code to I/O 80h/81h how do we determine - * what to do? - * - * An alternative is to document Host must write 16-bit codes - * to I/O 80h and 90h. LSB to 0x80 and MSB to 0x90. - * - */ -void port_80_interrupt(void) -{ - int d; - - while (MCHP_P80_STS(0) & MCHP_P80_STS_NOT_EMPTY) { - /* - * This masks off time stamp d = port_80_read(); - * b[7:0] = data, b[32:8] = time stamp - */ - d = MCHP_P80_CAP(0); - trace1(0, P80, 0, "Port80h = 0x%02x", (d & 0xff)); - port_80_write(d & 0xff); - } - - MCHP_INT_SOURCE(MCHP_P80_GIRQ) = MCHP_P80_GIRQ_BIT(0); -} -DECLARE_IRQ(MCHP_IRQ_PORT80DBG0, port_80_interrupt, 3); -#endif - diff --git a/chip/mchp/pwm.c b/chip/mchp/pwm.c deleted file mode 100644 index ae22f13ca5..0000000000 --- a/chip/mchp/pwm.c +++ /dev/null @@ -1,120 +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. - */ - -/* PWM control module for MCHP MEC family */ - -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "registers.h" -#include "util.h" -#include "tfdp_chip.h" - -#define CPUTS(outstr) cputs(CC_PWM, outstr) -#define CPRINTS(format, args...) cprints(CC_PWM, format, ## args) - -/* Bit map of PWM channels that must remain active during low power idle. */ -static uint32_t pwm_keep_awake_mask; - -/* Table of PWM PCR sleep enable register index and bit position. */ -static const uint16_t pwm_pcr[] = { - MCHP_PCR_PWM0, - MCHP_PCR_PWM1, - MCHP_PCR_PWM2, - MCHP_PCR_PWM3, - MCHP_PCR_PWM4, - MCHP_PCR_PWM5, - MCHP_PCR_PWM6, - MCHP_PCR_PWM7, - MCHP_PCR_PWM8, -}; -BUILD_ASSERT(ARRAY_SIZE(pwm_pcr) == MCHP_PWM_ID_MAX); - -void pwm_enable(enum pwm_channel ch, int enabled) -{ - int id = pwm_channels[ch].channel; - - if (enabled) { - MCHP_PWM_CFG(id) |= BIT(0); - if (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) - pwm_keep_awake_mask |= BIT(id); - } else { - MCHP_PWM_CFG(id) &= ~BIT(0); - pwm_keep_awake_mask &= ~BIT(id); - } -} - -int pwm_get_enabled(enum pwm_channel ch) -{ - return MCHP_PWM_CFG(pwm_channels[ch].channel) & 0x1; -} - -void pwm_set_duty(enum pwm_channel ch, int percent) -{ - int id = pwm_channels[ch].channel; - - if (percent < 0) - percent = 0; - else if (percent > 100) - percent = 100; - - MCHP_PWM_ON(id) = percent; - MCHP_PWM_OFF(id) = 100 - percent; -} - -int pwm_get_duty(enum pwm_channel ch) -{ - return MCHP_PWM_ON(pwm_channels[ch].channel); -} - -void pwm_keep_awake(void) -{ - if (pwm_keep_awake_mask) { - for (uint32_t i = 0; i < MCHP_PWM_ID_MAX; i++) - if (pwm_keep_awake_mask & BIT(i)) - MCHP_PCR_SLP_DIS_DEV(pwm_pcr[i]); - } else { - MCHP_PCR_SLOW_CLK_CTL &= ~(MCHP_PCR_SLOW_CLK_CTL_MASK); - } -} - -/* - * clock_low=0 selects the 48MHz Ring Oscillator source - * clock_low=1 selects the 100kHz_Clk source - */ -static void pwm_configure(int ch, int active_low, int clock_low) -{ - MCHP_PWM_CFG(ch) = (15 << 3) /* divider = 16 */ - | (active_low ? BIT(2) : 0) - | (clock_low ? BIT(1) : 0); -} - -static void pwm_slp_en(int pwm_id, int sleep_en) -{ - if ((pwm_id < 0) || (pwm_id > MCHP_PWM_ID_MAX)) - return; - - if (sleep_en) - MCHP_PCR_SLP_EN_DEV(pwm_pcr[pwm_id]); - else - MCHP_PCR_SLP_DIS_DEV(pwm_pcr[pwm_id]); -} - -static void pwm_init(void) -{ - int i; - - for (i = 0; i < PWM_CH_COUNT; ++i) { - pwm_slp_en(pwm_channels[i].channel, 0); - pwm_configure(pwm_channels[i].channel, - pwm_channels[i].flags & PWM_CONFIG_ACTIVE_LOW, - pwm_channels[i].flags & PWM_CONFIG_ALT_CLOCK); - pwm_set_duty(i, 0); - } -} -DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_DEFAULT); diff --git a/chip/mchp/pwm_chip.h b/chip/mchp/pwm_chip.h deleted file mode 100644 index f828a234a7..0000000000 --- a/chip/mchp/pwm_chip.h +++ /dev/null @@ -1,51 +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. - */ - -/* MEC1701H-specific PWM module for Chrome EC */ -#ifndef __CROS_EC_PWM_CHIP_H -#define __CROS_EC_PWM_CHIP_H - -/* - * MEC152x SZ 144-pin has 9 PWM and 4 TACH - * MEC170x SZ 144-pin has 9 PWM and 3 TACH - * MEC172x SZ 144-pin has 9 PWM and 4 TACH - */ -enum pwm_hw_id { - PWM_HW_CH_0 = 0, - PWM_HW_CH_1, - PWM_HW_CH_2, - PWM_HW_CH_3, - PWM_HW_CH_4, - PWM_HW_CH_5, - PWM_HW_CH_6, - PWM_HW_CH_7, - PWM_HW_CH_8, - PWM_HW_CH_COUNT -}; - -enum tach_hw_id { - TACH_HW_CH_0 = 0, - TACH_HW_CH_1, - TACH_HW_CH_2, -#ifndef CHIP_FAMILY_MEC170X - TACH_HW_CH_3, -#endif - TACH_HW_CH_COUNT -}; - -/* Data structure to define PWM channels. */ -struct pwm_t { - /* PWM Channel ID */ - int channel; - - /* PWM channel flags. See include/pwm.h */ - uint32_t flags; -}; - -extern const struct pwm_t pwm_channels[]; - -void pwm_keep_awake(void); - -#endif /* __CROS_EC_PWM_CHIP_H */ diff --git a/chip/mchp/qmspi.c b/chip/mchp/qmspi.c deleted file mode 100644 index 72eaa91d37..0000000000 --- a/chip/mchp/qmspi.c +++ /dev/null @@ -1,700 +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. - */ - -/* QMSPI master module for MCHP MEC family */ - -#include "common.h" -#include "console.h" -#include "dma.h" -#include "gpio.h" -#include "registers.h" -#include "spi.h" -#include "timer.h" -#include "util.h" -#include "hooks.h" -#include "task.h" -#include "dma_chip.h" -#include "spi_chip.h" -#include "qmspi_chip.h" -#include "tfdp_chip.h" - -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) - -#define QMSPI_TRANSFER_TIMEOUT (100 * MSEC) -#define QMSPI_BYTE_TRANSFER_TIMEOUT_US (3 * MSEC) -#define QMSPI_BYTE_TRANSFER_POLL_INTERVAL_US 20 - - - -#ifndef CONFIG_MCHP_QMSPI_TX_DMA -#ifdef LFW -/* - * MCHP 32-bit timer 0 configured for 1us count down mode and no - * interrupt in the LFW environment. Don't need to sleep CPU in LFW. - */ -static int qmspi_wait(uint32_t mask, uint32_t mval) -{ - uint32_t t1, t2, td; - - t1 = MCHP_TMR32_CNT(0); - - while ((MCHP_QMSPI0_STS & mask) != mval) { - t2 = MCHP_TMR32_CNT(0); - if (t1 >= t2) - td = t1 - t2; - else - td = t1 + (0xfffffffful - t2); - if (td > QMSPI_BYTE_TRANSFER_TIMEOUT_US) - return EC_ERROR_TIMEOUT; - } - return EC_SUCCESS; -} -#else -/* - * This version uses the full EC_RO/RW timer infrastructure and it needs - * a timer ISR to handle timer underflow. Without the ISR we observe false - * timeouts when debugging with JTAG. - * QMSPI_BYTE_TRANSFER_TIMEOUT_US currently 3ms - * QMSPI_BYTE_TRANSFER_POLL_INTERVAL_US currently 100 us - */ - -static int qmspi_wait(uint32_t mask, uint32_t mval) -{ - timestamp_t deadline; - - deadline.val = get_time().val + (QMSPI_BYTE_TRANSFER_TIMEOUT_US); - - while ((MCHP_QMSPI0_STS & mask) != mval) { - if (timestamp_expired(deadline, NULL)) - return EC_ERROR_TIMEOUT; - - usleep(QMSPI_BYTE_TRANSFER_POLL_INTERVAL_US); - } - return EC_SUCCESS; -} -#endif /* #ifdef LFW */ -#endif /* #ifndef CONFIG_MCHP_QMSPI_TX_DMA */ - -/* - * Wait for QMSPI read using DMA to finish. - * DMA subsystem has 100 ms timeout - */ -int qmspi_transaction_wait(const struct spi_device_t *spi_device) -{ - const struct dma_option *opdma; - - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - if (opdma != NULL) - return dma_wait(opdma->channel); - - return EC_ERROR_INVAL; -} - -/* - * Create QMSPI transmit data descriptor not using DMA. - * Transmit on MOSI pin (single/full-duplex) from TX FIFO. - * TX FIFO filled by CPU. - * Caller will apply close and last flags if applicable. - */ -#ifndef CONFIG_MCHP_QMSPI_TX_DMA -static uint32_t qmspi_build_tx_descr(uint32_t ntx, uint32_t ndid) -{ - uint32_t d; - - d = MCHP_QMSPI_C_1X + MCHP_QMSPI_C_TX_DATA; - d |= ((ndid & 0x0F) << MCHP_QMSPI_C_NEXT_DESCR_BITPOS); - - if (ntx <= MCHP_QMSPI_C_MAX_UNITS) - d |= MCHP_QMSPI_C_XFRU_1B; - else { - if ((ntx & 0x0f) == 0) { - ntx >>= 4; - d |= MCHP_QMSPI_C_XFRU_16B; - } else if ((ntx & 0x03) == 0) { - ntx >>= 2; - d |= MCHP_QMSPI_C_XFRU_4B; - } else - d |= MCHP_QMSPI_C_XFRU_1B; - - if (ntx > MCHP_QMSPI_C_MAX_UNITS) - return 0; /* overflow unit count field */ - } - - d |= (ntx << MCHP_QMSPI_C_NUM_UNITS_BITPOS); - - return d; -} - -/* - * Create QMSPI receive data descriptor using DMA. - * Receive data on MISO pin (single/full-duplex) and store in QMSPI - * RX FIFO. QMSPI triggers DMA channel to read from RX FIFO and write - * to memory. Return value is an uint64_t where low 32-bit word is the - * descriptor and upper 32-bit word is DMA channel unit length with - * value (1, 2, or 4). - * Caller will apply close and last flags if applicable. - */ -static uint64_t qmspi_build_rx_descr(uint32_t raddr, - uint32_t nrx, uint32_t ndid) -{ - uint32_t d, dmau, na; - uint64_t u; - - d = MCHP_QMSPI_C_1X + MCHP_QMSPI_C_RX_EN; - d |= ((ndid & 0x0F) << MCHP_QMSPI_C_NEXT_DESCR_BITPOS); - - dmau = 1; - na = (raddr | nrx) & 0x03; - if (na == 0) { - d |= MCHP_QMSPI_C_RX_DMA_4B; - dmau <<= 2; - } else if (na == 0x02) { - d |= MCHP_QMSPI_C_RX_DMA_2B; - dmau <<= 1; - } else { - d |= MCHP_QMSPI_C_RX_DMA_1B; - } - - if ((nrx & 0x0f) == 0) { - nrx >>= 4; - d |= MCHP_QMSPI_C_XFRU_16B; - } else if ((nrx & 0x03) == 0) { - nrx >>= 2; - d |= MCHP_QMSPI_C_XFRU_4B; - } else { - d |= MCHP_QMSPI_C_XFRU_1B; - } - - u = 0; - if (nrx <= MCHP_QMSPI_C_MAX_UNITS) { - d |= (nrx << MCHP_QMSPI_C_NUM_UNITS_BITPOS); - u = dmau; - u <<= 32; - u |= d; - } - - return u; -} -#endif - -#ifdef CONFIG_MCHP_QMSPI_TX_DMA - -#define QMSPI_ERR_ANY 0x80 -#define QMSPI_ERR_BAD_PTR 0x81 -#define QMSPI_ERR_OUT_OF_DESCR 0x85 - -/* - * bits[1:0] of word - * 1 -> 0 - * 2 -> 1 - * 4 -> 2 - */ -static uint32_t qmspi_pins_encoding(uint8_t npins) -{ - return (uint32_t)(npins >> 1) & 0x03; -} - -/* - * Clear status, FIFO's, and all descriptors. - * Enable descriptor mode. - */ -static void qmspi_descr_mode_ready(void) -{ - int i; - - MCHP_QMSPI0_CTRL = 0; - MCHP_QMSPI0_IEN = 0; - MCHP_QMSPI0_EXE = MCHP_QMSPI_EXE_CLR_FIFOS; - MCHP_QMSPI0_STS = 0xfffffffful; - MCHP_QMSPI0_CTRL = MCHP_QMSPI_C_DESCR_MODE_EN; - /* clear all descriptors */ - for (i = 0; i < MCHP_QMSPI_MAX_DESCR; i++) - MCHP_QMSPI0_DESCR(i) = 0; -} - -/* - * helper - * did = zero based index of start descriptor - * descr = descriptor configuration - * nb = number of bytes to transfer - * Return index of last descriptor allocated or 0xffff - * if out of descriptors. - * Algorithm: - * If requested number of bytes will fit in one descriptor then - * configure descriptor for QMSPI byte units and return. - * Otherwise allocate multiple descriptor using QMSPI 16-byte mode - * and remaining < 16 bytes in byte unit descriptor until all bytes - * exhausted or out of descriptors error. - */ -static uint32_t qmspi_descr_alloc(uint32_t did, - uint32_t descr, uint32_t nb) -{ - uint32_t nu; - - while (nb) { - if (did >= MCHP_QMSPI_MAX_DESCR) - return 0xffff; - - descr &= ~(MCHP_QMSPI_C_NUM_UNITS_MASK + - MCHP_QMSPI_C_XFRU_MASK); - - if (nb < (MCHP_QMSPI_C_MAX_UNITS + 1)) { - descr |= MCHP_QMSPI_C_XFRU_1B; - descr += (nb << MCHP_QMSPI_C_NUM_UNITS_BITPOS); - nb = 0; - } else { - descr |= MCHP_QMSPI_C_XFRU_16B; - nu = (nb >> 4) & MCHP_QMSPI_C_NUM_UNITS_MASK0; - descr += (nu << MCHP_QMSPI_C_NUM_UNITS_BITPOS); - nb -= (nu << 4); - } - - descr |= ((did+1) << MCHP_QMSPI_C_NEXT_DESCR_BITPOS); - MCHP_QMSPI0_DESCR(did) = descr; - if (nb) - did++; - } - - return did; -} - -/* - * Build one or more descriptors for command/data transmit. - * cfg b[7:0] = start descriptor index - * cfg b[15:8] = number of pins for transmit. - * If bytes to transmit will fit in TX FIFO then fill TX FIFO and build - * one descriptor. - * Otherwise build one or more descriptors to fill TX FIFO using DMA - * channel and configure the DMA channel for memory to device transfer. - */ -static uint32_t qmspi_xmit_data_descr(const struct dma_option *opdma, - uint32_t cfg, - const uint8_t *data, - uint32_t ndata) -{ - uint32_t d, d2, did, dma_cfg; - - did = cfg & 0x0f; - d = qmspi_pins_encoding((cfg >> 8) & 0x07); - - if (ndata <= MCHP_QMSPI_TX_FIFO_LEN) { - d2 = d + (ndata << MCHP_QMSPI_C_NUM_UNITS_BITPOS) + - MCHP_QMSPI_C_XFRU_1B + MCHP_QMSPI_C_TX_DATA; - d2 += ((did + 1) << MCHP_QMSPI_C_NEXT_DESCR_BITPOS); - MCHP_QMSPI0_DESCR(did) = d2; - while (ndata--) - MCHP_QMSPI0_TX_FIFO8 = *data++; - } else { // TX DMA - if (((uint32_t)data | ndata) & 0x03) { - dma_cfg = 1; - d |= (MCHP_QMSPI_C_TX_DATA + - MCHP_QMSPI_C_TX_DMA_1B); - } else { - dma_cfg = 4; - d |= (MCHP_QMSPI_C_TX_DATA + - MCHP_QMSPI_C_TX_DMA_4B); - } - did = qmspi_descr_alloc(did, d, ndata); - if (did == 0xffff) - return QMSPI_ERR_OUT_OF_DESCR; - - dma_clr_chan(opdma->channel); - dma_cfg_buffers(opdma->channel, data, ndata, - (void *)MCHP_QMSPI0_TX_FIFO_ADDR); - dma_cfg_xfr(opdma->channel, dma_cfg, - MCHP_DMA_QMSPI0_TX_REQ_ID, - (DMA_FLAG_M2D + DMA_FLAG_INCR_MEM)); - dma_run(opdma->channel); - } - - return did; -} - -/* - * QMSPI0 Start - * flags - * b[0] = 1 de-assert chip select when done - * b[1] = 1 enable QMSPI interrupts - * b[2] = 1 start - */ -void qmspi_cfg_irq_start(uint8_t flags) -{ - MCHP_INT_DISABLE(MCHP_QMSPI_GIRQ) = MCHP_QMSPI_GIRQ_BIT; - MCHP_INT_SOURCE(MCHP_QMSPI_GIRQ) = MCHP_QMSPI_GIRQ_BIT; - MCHP_QMSPI0_IEN = 0; - - if (flags & (1u << 1)) { - MCHP_QMSPI0_IEN = (MCHP_QMSPI_STS_DONE + - MCHP_QMSPI_STS_PROG_ERR); - MCHP_INT_ENABLE(MCHP_QMSPI_GIRQ) = MCHP_QMSPI_GIRQ_BIT; - } - - if (flags & (1u << 2)) - MCHP_QMSPI0_EXE = MCHP_QMSPI_EXE_START; -} - -/* - * QMSPI transmit and/or receive - * np_flags - * b[7:0] = flags - * b[0] = close(de-assert chip select when done) - * b[1] = enable Done and ProgError interrupt - * b[2] = start - * b[15:8] = number of tx pins - * b[24:16] = number of rx pins - * - * returns last descriptor 0 <= index < MCHP_QMSPI_MAX_DESCR - * or error (bit[7]==1) - */ -uint8_t qmspi_xfr(const struct spi_device_t *spi_device, - uint32_t np_flags, - const uint8_t *txdata, uint32_t ntx, - uint8_t *rxdata, uint32_t nrx) -{ - uint32_t d, did, dma_cfg; - const struct dma_option *opdma; - - qmspi_descr_mode_ready(); - - did = 0; - if (ntx) { - if (txdata == NULL) - return QMSPI_ERR_BAD_PTR; - - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_WR); - - d = qmspi_pins_encoding((np_flags >> 8) & 0xff); - dma_cfg = (np_flags & 0xFF00) + did; - did = qmspi_xmit_data_descr(opdma, dma_cfg, txdata, ntx); - if (did & QMSPI_ERR_ANY) - return (uint8_t)(did & 0xff); - - if (nrx) - did++; /* point to next descriptor */ - } - - if (nrx) { - if (rxdata == NULL) - return QMSPI_ERR_BAD_PTR; - - if (did >= MCHP_QMSPI_MAX_DESCR) - return QMSPI_ERR_OUT_OF_DESCR; - - d = qmspi_pins_encoding((np_flags >> 16) & 0xff); - /* compute DMA units: 1 or 4 */ - if (((uint32_t)rxdata | nrx) & 0x03) { - dma_cfg = 1; - d |= (MCHP_QMSPI_C_RX_EN + MCHP_QMSPI_C_RX_DMA_1B); - } else { - dma_cfg = 4; - d |= (MCHP_QMSPI_C_RX_EN + MCHP_QMSPI_C_RX_DMA_4B); - } - did = qmspi_descr_alloc(did, d, nrx); - if (did & QMSPI_ERR_ANY) - return (uint8_t)(did & 0xff); - - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - dma_clr_chan(opdma->channel); - dma_cfg_buffers(opdma->channel, rxdata, nrx, - (void *)MCHP_QMSPI0_RX_FIFO_ADDR); - dma_cfg_xfr(opdma->channel, dma_cfg, - MCHP_DMA_QMSPI0_RX_REQ_ID, - (DMA_FLAG_D2M + DMA_FLAG_INCR_MEM)); - dma_run(opdma->channel); - } - - if (ntx || nrx) { - d = MCHP_QMSPI0_DESCR(did); - d |= MCHP_QMSPI_C_DESCR_LAST; - if (np_flags & 0x01) - d |= MCHP_QMSPI_C_CLOSE; - MCHP_QMSPI0_DESCR(did) = d; - qmspi_cfg_irq_start(np_flags & 0xFF); - } - - return (uint8_t)(did & 0xFF); -} -#endif /* #ifdef CONFIG_MCHP_QMSPI_TX_DMA */ - -/* - * QMSPI controller must control chip select therefore this routine - * configures QMSPI to assert SPI CS# and de-assert when done. - * Transmit using QMSPI TX FIFO only when tx data fits in TX FIFO else - * use TX DMA. - * Transmit and receive will allocate as many QMSPI descriptors as - * needed for data size. This could result in an error if the maximum - * number of descriptors is exceeded. - * Descriptors are limited to 0x7FFF units where unit size is 1, 4, or - * 16 bytes. Code determines unit size based upon number of bytes and - * alignment of data buffer. - * DMA channel will move data in units of 1 or 4 bytes also based upon - * the number of data bytes and buffer alignment. - * The most efficient transfers are those where TX and RX buffers are - * aligned >= 4 bytes and the number of bytes is a multiple of 4. - * NOTE on SPI flash commands: - * This routine does NOT handle SPI flash commands requiring - * extra clocks or special mode bytes. Extra clocks and special mode - * bytes require additional descriptors. For example the flash read - * dual command (0x3B): - * 1. First descriptor transmits 4 bytes (opcode + 24-bit address) on - * one pin (IO0). - * 2. Second descriptor set for 2 IO pins, 2 bytes, TX disabled. When - * this descriptor is executed QMSPI will tri-state IO0 & IO1 and - * output 8 clocks (dual mode 4 clocks per byte). The SPI flash may - * turn on its output drivers on the first clock. - * 3. Third descriptor set for 2 IO pins, read data using DMA. Unit - * size and DMA unit size based on number of bytes to read and - * alignment of destination buffer. - * The common SPI API will be required to supply more information about - * SPI flash read commands. A further complication is some larger SPI - * flash devices support a 4-byte address mode. 4-byte address mode can - * be implemented as separate command code or a configuration bit in - * the SPI flash that changes the default 24-bit address command to - * require a 32-bit address. - * 0x03 is 1-1-1 - * 0x3B is 1-1-2 with 8 clocks - * 0x6B is 1-1-4 with 8 clocks - * 0xBB is 1-2-2 with 4 clocks - * Number of IO pins for command - * Number of IO pins for address - * Number of IO pins for data - * Number of bit/bytes for address (3 or 4) - * Number of clocks after address phase - */ -#ifdef CONFIG_MCHP_QMSPI_TX_DMA -int qmspi_transaction_async(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - uint32_t np_flags, ntx, nrx; - int ret; - uint8_t rc; - - ntx = 0; - if (txlen >= 0) - ntx = (uint32_t)txlen; - - nrx = 0; - if (rxlen >= 0) - nrx = (uint32_t)rxlen; - - np_flags = 0x010105; /* b[0]=1 close on done, b[2]=1 start */ - rc = qmspi_xfr(spi_device, np_flags, - txdata, ntx, - rxdata, nrx); - - if (rc & QMSPI_ERR_ANY) - return EC_ERROR_INVAL; - - ret = EC_SUCCESS; - return ret; -} -#else -/* - * Transmit using CPU and QMSPI TX FIFO(no DMA). - * Receive using DMA as above. - */ -int qmspi_transaction_async(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - const struct dma_option *opdma; - uint32_t d, did, dmau; - uint64_t u; - - if (spi_device == NULL) - return EC_ERROR_PARAM1; - - /* soft reset the controller */ - MCHP_QMSPI0_MODE_ACT_SRST = MCHP_QMSPI_M_SOFT_RESET; - d = spi_device->div; - d <<= MCHP_QMSPI_M_CLKDIV_BITPOS; - d += (MCHP_QMSPI_M_ACTIVATE + MCHP_QMSPI_M_SPI_MODE0); - MCHP_QMSPI0_MODE = d; - MCHP_QMSPI0_CTRL = MCHP_QMSPI_C_DESCR_MODE_EN; - - d = did = 0; - - if (txlen > 0) { - if (txdata == NULL) - return EC_ERROR_PARAM2; - - d = qmspi_build_tx_descr((uint32_t)txlen, 1); - if (d == 0) /* txlen too large */ - return EC_ERROR_OVERFLOW; - - MCHP_QMSPI0_DESCR(did) = d; - } - - if (rxlen > 0) { - if (rxdata == NULL) - return EC_ERROR_PARAM4; - - u = qmspi_build_rx_descr((uint32_t)rxdata, - (uint32_t)rxlen, 2); - - d = (uint32_t)u; - dmau = u >> 32; - - if (txlen > 0) - did++; - MCHP_QMSPI0_DESCR(did) = d; - - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - dma_xfr_start_rx(opdma, dmau, (uint32_t)rxlen, rxdata); - } - - MCHP_QMSPI0_DESCR(did) |= (MCHP_QMSPI_C_CLOSE + - MCHP_QMSPI_C_DESCR_LAST); - - MCHP_QMSPI0_EXE = MCHP_QMSPI_EXE_START; - - while (txlen--) { - if (MCHP_QMSPI0_STS & MCHP_QMSPI_STS_TX_BUFF_FULL) { - if (qmspi_wait(MCHP_QMSPI_STS_TX_BUFF_EMPTY, - MCHP_QMSPI_STS_TX_BUFF_EMPTY) != - EC_SUCCESS) { - MCHP_QMSPI0_EXE = MCHP_QMSPI_EXE_STOP; - return EC_ERROR_TIMEOUT; - } - } else - MCHP_QMSPI0_TX_FIFO8 = *txdata++; - } - - return EC_SUCCESS; -} -#endif /* #ifdef CONFIG_MCHP_QMSPI_TX_DMA */ - -/* - * Wait for QMSPI descriptor mode transfer to finish. - * QMSPI is configured to perform a complete transaction. - * Assert CS# - * optional transmit - * CPU keeps filling TX FIFO until all bytes are transmitted. - * optional receive - * QMSPI is configured to read rxlen bytes and uses a DMA channel - * to move data from its RX FIFO to memory. - * De-assert CS# - * This routine can be called with QMSPI hardware in four states: - * 1. Transmit only and QMSPI has finished (empty TX FIFO) by the time - * this routine is called. QMSPI.Status transfer done status will be - * set and QMSPI HW has de-asserted SPI CS#. - * 2. Transmit only and QMSPI TX FIFO is still transmitting. - * QMSPI transfer done status is not asserted and CS# is still - * asserted. QMSPI HW will de-assert CS# when done or firmware - * manually stops QMSPI. - * 3. Receive was enabled and DMA channel is moving data from - * QMSPI RX FIFO to memory. QMSPI.Status transfer done and DMA done - * status bits are not set. QMSPI SPI CS# will stay asserted until - * transaction finishes or firmware manually stops QMSPI. - * 4. Receive was enabled and DMA channel is finished. QMSPI RX FIFO - * should be empty and DMA channel is done. QMSPI.Status transfer - * done and DMA done status bits will be set. QMSPI HW has de-asserted - * SPI CS#. - * We are using QMSPI in descriptor mode. The definition of QMSPI.Status - * transfer complete bit in this mode is: complete will be set to 1 only - * when the last buffer completes its transfer. - * TX only sets complete when transfer unit count is matched and all units - * have been clocked out of the TX FIFO. - * RX DMA transfer complete will be set when the last transfer unit - * is out of the RX FIFO but DMA may not be complete until it finishes - * moving the transfer unit to memory. - * If TX only spin on QMSPI.Status Transfer_Complete bit. - * If RX used spin on QMsPI.Status Transfer_Complete and DMA_Complete. - * Search descriptors looking for RX DMA enabled. - * If RX DMA is enabled add DMA complete flag to status mask. - * Spin while QMSPI.Status & mask != mask or timeout. - * If timeout force QMSPI to stop and exit spin loop. - * if DMA was enabled disable DMA channel. - * Clear QMSPI.Status and FIFO's - */ -int qmspi_transaction_flush(const struct spi_device_t *spi_device) -{ - int ret; - uint32_t qsts, mask; - const struct dma_option *opdma; - timestamp_t deadline; - - if (spi_device == NULL) - return EC_ERROR_PARAM1; - - mask = MCHP_QMSPI_STS_DONE; - - ret = EC_SUCCESS; - deadline.val = get_time().val + QMSPI_TRANSFER_TIMEOUT; - - qsts = MCHP_QMSPI0_STS; - while ((qsts & mask) != mask) { - if (timestamp_expired(deadline, NULL)) { - MCHP_QMSPI0_EXE = MCHP_QMSPI_EXE_STOP; - ret = EC_ERROR_TIMEOUT; - break; - } - usleep(QMSPI_BYTE_TRANSFER_POLL_INTERVAL_US); - qsts = MCHP_QMSPI0_STS; - } - - /* clear transmit DMA channel */ - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_WR); - if (opdma == NULL) - return EC_ERROR_INVAL; - - dma_disable(opdma->channel); - dma_clear_isr(opdma->channel); - - /* clear receive DMA channel */ - opdma = spi_dma_option(spi_device, SPI_DMA_OPTION_RD); - if (opdma == NULL) - return EC_ERROR_INVAL; - - dma_disable(opdma->channel); - dma_clear_isr(opdma->channel); - - /* clear QMSPI FIFO's */ - MCHP_QMSPI0_EXE = MCHP_QMSPI_EXE_CLR_FIFOS; - MCHP_QMSPI0_STS = 0xffffffff; - - return ret; -} - -/** - * Enable QMSPI controller and MODULE_SPI_FLASH pins. - * - * @param hw_port b[3:0]=0 and b[7:4]=0 - * @param enable - * @return EC_SUCCESS or EC_ERROR_INVAL if port is unrecognized - * @note called by spi_enable in mec1701/spi.c - * - */ -int qmspi_enable(int hw_port, int enable) -{ - uint8_t unused __attribute__((unused)) = 0; - - trace2(0, QMSPI, 0, "qmspi_enable: port = %d enable = %d", - hw_port, enable); - - if (hw_port != QMSPI0_PORT) - return EC_ERROR_INVAL; - - gpio_config_module(MODULE_SPI_FLASH, (enable > 0)); - - if (enable) { - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_QMSPI); - MCHP_QMSPI0_MODE_ACT_SRST = MCHP_QMSPI_M_SOFT_RESET; - unused = MCHP_QMSPI0_MODE_ACT_SRST; - MCHP_QMSPI0_MODE = (MCHP_QMSPI_M_ACTIVATE + - MCHP_QMSPI_M_SPI_MODE0 + - MCHP_QMSPI_M_CLKDIV_12M); - } else { - MCHP_QMSPI0_MODE_ACT_SRST = MCHP_QMSPI_M_SOFT_RESET; - unused = MCHP_QMSPI0_MODE_ACT_SRST; - MCHP_QMSPI0_MODE_ACT_SRST = 0; - MCHP_PCR_SLP_EN_DEV(MCHP_PCR_QMSPI); - } - - return EC_SUCCESS; -} - diff --git a/chip/mchp/qmspi_chip.h b/chip/mchp/qmspi_chip.h deleted file mode 100644 index 1a1d764267..0000000000 --- a/chip/mchp/qmspi_chip.h +++ /dev/null @@ -1,67 +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. - * - * Register map for MEC17xx processor - */ -/** @file qmspi_chip.h - *MEC17xx Quad SPI Master - */ -/** @defgroup MCHP MEC qmspi - */ - -#ifndef _QMSPI_CHIP_H -#define _QMSPI_CHIP_H - -#include <stdint.h> -#include <stddef.h> - -/* struct spi_device_t */ -#include "spi.h" - - -int qmspi_transaction_flush(const struct spi_device_t *spi_device); - -int qmspi_transaction_wait(const struct spi_device_t *spi_device); - -int qmspi_transaction_sync(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen); - -int qmspi_transaction_async(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen); - -int qmspi_enable(int port, int enable); - -/* - * QMSPI0 Start - * flags - * b[0] = ignored - * b[1] = 1 enable QMSPI interrupts - * b[2] = 1 start - */ -void qmspi_cfg_irq_start(uint8_t flags); - -/* - * QMSPI transmit and/or receive - * np_flags - * b[7:0] = flags - * b[0] = close(de-assert chip select when done) - * b[1] = enable Done and ProgError interrupt - * b[2] = start - * b[15:8] = number of tx pins - * b[24:16] = number of rx pins - * - * returns last descriptor 0 <= index < MCHP_QMSPI_MAX_DESCR - * or error (bit[7]==1) - */ -uint8_t qmspi_xfr(const struct spi_device_t *spi_device, - uint32_t np_flags, - const uint8_t *txdata, uint32_t ntx, - uint8_t *rxdata, uint32_t nrx); - -#endif /* #ifndef _QMSPI_CHIP_H */ -/** @} - */ - diff --git a/chip/mchp/registers-mec152x.h b/chip/mchp/registers-mec152x.h deleted file mode 100644 index 10021ede8b..0000000000 --- a/chip/mchp/registers-mec152x.h +++ /dev/null @@ -1,1289 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Register map for Microchip MEC152x family controllers - */ - -#ifndef __CROS_EC_REGISTERS_H -#error "This header file should not be included directly." -#endif - -/* - * IRQ Numbers - * NOTE: GIRQ22 aggregated output and its sources are not connected to - * the NVIC. - */ -#define MCHP_IRQ_GIRQ8 0 -#define MCHP_IRQ_GIRQ9 1 -#define MCHP_IRQ_GIRQ10 2 -#define MCHP_IRQ_GIRQ11 3 -#define MCHP_IRQ_GIRQ12 4 -#define MCHP_IRQ_GIRQ13 5 -#define MCHP_IRQ_GIRQ14 6 -#define MCHP_IRQ_GIRQ15 7 -#define MCHP_IRQ_GIRQ16 8 -#define MCHP_IRQ_GIRQ17 9 -#define MCHP_IRQ_GIRQ18 10 -#define MCHP_IRQ_GIRQ19 11 -#define MCHP_IRQ_GIRQ20 12 -#define MCHP_IRQ_GIRQ21 13 -#define MCHP_IRQ_GIRQ23 14 -#define MCHP_IRQ_GIRQ24 15 -#define MCHP_IRQ_GIRQ25 16 -#define MCHP_IRQ_GIRQ26 17 -/* GIRQ13 direct sources */ -#define MCHP_IRQ_I2C_0 20 -#define MCHP_IRQ_I2C_1 21 -#define MCHP_IRQ_I2C_2 22 -#define MCHP_IRQ_I2C_3 23 -#define MCHP_IRQ_I2C_4 158 -#define MCHP_IRQ_I2C_5 168 -#define MCHP_IRQ_I2C_6 169 -#define MCHP_IRQ_I2C_7 170 -/* GIRQ14 direct sources */ -#define MCHP_IRQ_DMA_0 24 -#define MCHP_IRQ_DMA_1 25 -#define MCHP_IRQ_DMA_2 26 -#define MCHP_IRQ_DMA_3 27 -#define MCHP_IRQ_DMA_4 28 -#define MCHP_IRQ_DMA_5 29 -#define MCHP_IRQ_DMA_6 30 -#define MCHP_IRQ_DMA_7 31 -#define MCHP_IRQ_DMA_8 32 -#define MCHP_IRQ_DMA_9 33 -#define MCHP_IRQ_DMA_10 34 -#define MCHP_IRQ_DMA_11 35 -/* GIRQ15 direct sources */ -#define MCHP_IRQ_UART0 40 -#define MCHP_IRQ_UART1 41 -#define MCHP_IRQ_EMI0 42 -#define MCHP_IRQ_EMI1 43 -#define MCHP_IRQ_UART2 44 -#define MCHP_IRQ_ACPIEC0_IBF 45 -#define MCHP_IRQ_ACPIEC0_OBE 46 -#define MCHP_IRQ_ACPIEC1_IBF 47 -#define MCHP_IRQ_ACPIEC1_OBE 48 -#define MCHP_IRQ_ACPIEC2_IBF 49 -#define MCHP_IRQ_ACPIEC2_OBE 50 -#define MCHP_IRQ_ACPIEC3_IBF 51 -#define MCHP_IRQ_ACPIEC3_OBE 52 -#define MCHP_IRQ_ACPIPM1_CTL 55 -#define MCHP_IRQ_ACPIPM1_EN 56 -#define MCHP_IRQ_ACPIPM1_STS 57 -#define MCHP_IRQ_8042EM_OBE 58 -#define MCHP_IRQ_8042EM_IBF 59 -#define MCHP_IRQ_MAILBOX_DATA 60 -#define MCHP_IRQ_PORT80DBG0 62 -#define MCHP_IRQ_PORT80DBG1 63 -#define MCHP_IRQ_LASIC 64 -/* GIRQ16 direct sources */ -#define MCHP_IRQ_PKE_ERR 65 -#define MCHP_IRQ_PKE_END 66 -#define MCHP_IRQ_NDRNG 67 -#define MCHP_IRQ_AES 68 -#define MCHP_IRQ_HASH 69 -/* GIRQ17 direct sources */ -#define MCHP_IRQ_PECI_HOST 70 -#define MCHP_IRQ_TACH_0 71 -#define MCHP_IRQ_TACH_1 72 -#define MCHP_IRQ_TACH_2 73 -#define MCHP_IRQ_TACH_3 159 -#define MCHP_IRQ_HDMI_CEC 160 -#define MCHP_IRQ_ADC_SNGL 78 -#define MCHP_IRQ_ADC_RPT 79 -#define MCHP_IRQ_LED0_WDT 83 -#define MCHP_IRQ_LED1_WDT 84 -#define MCHP_IRQ_LED2_WDT 85 -#define MCHP_IRQ_PROCHOT 87 -/* GIRQ18 direct sources */ -#define MCHP_IRQ_SLAVE_SPI 90 -#define MCHP_IRQ_QMSPI0 91 -#define MCHP_IRQ_PS2_0 100 -#define MCHP_IRQ_PS2_1 101 -#define MCHP_IRQ_PSPI 155 -#define MCHP_IRQ_SGPIO_0 161 -#define MCHP_IRQ_SGPIO_1 162 -#define MCHP_IRQ_SGPIO_2 163 -#define MCHP_IRQ_SGPIO_3 164 -#define MCHP_IRQ_CCT_TMR 146 -#define MCHP_IRQ_CCT_CAP0 147 -#define MCHP_IRQ_CCT_CAP1 148 -#define MCHP_IRQ_CCT_CAP2 149 -#define MCHP_IRQ_CCT_CAP3 150 -#define MCHP_IRQ_CCT_CAP4 151 -#define MCHP_IRQ_CCT_CAP5 152 -#define MCHP_IRQ_CCT_CMP0 153 -#define MCHP_IRQ_CCT_CMP1 154 -/* GIRQ19 direct sources */ -#define MCHP_IRQ_ESPI_PC 103 -#define MCHP_IRQ_ESPI_BM1 104 -#define MCHP_IRQ_ESPI_BM2 105 -#define MCHP_IRQ_ESPI_LTR 106 -#define MCHP_IRQ_ESPI_OOB_UP 107 -#define MCHP_IRQ_ESPI_OOB_DN 108 -#define MCHP_IRQ_ESPI_FC 109 -#define MCHP_IRQ_ESPI_RESET 110 -#define MCHP_IRQ_ESPI_VW_EN 156 -/* GIRQ20 direct sources */ -#define MCHP_IRQ_OTP 173 -/* GIRQ21 direct sources */ -#define MCHP_IRQ_WDG 171 -#define MCHP_IRQ_WEEK_ALARM 114 -#define MCHP_IRQ_SUBWEEK 115 -#define MCHP_IRQ_WEEK_SEC 116 -#define MCHP_IRQ_WEEK_SUBSEC 117 -#define MCHP_IRQ_WEEK_SYSPWR 118 -#define MCHP_IRQ_RTC 119 -#define MCHP_IRQ_RTC_ALARM 120 -#define MCHP_IRQ_VCI_OVRD_IN 121 -#define MCHP_IRQ_VCI_IN0 122 -#define MCHP_IRQ_VCI_IN1 123 -#define MCHP_IRQ_VCI_IN2 124 -#define MCHP_IRQ_VCI_IN3 125 -#define MCHP_IRQ_PS20A_WAKE 129 -#define MCHP_IRQ_PS20B_WAKE 130 -#define MCHP_IRQ_PS21B_WAKE 132 -#define MCHP_IRQ_KSC_INT 135 -/* GIRQ23 direct sources */ -#define MCHP_IRQ_TIMER16_0 136 -#define MCHP_IRQ_TIMER16_1 137 -#define MCHP_IRQ_TIMER32_0 140 -#define MCHP_IRQ_TIMER32_1 141 -#define MCHP_IRQ_RTOS_TIMER 111 -#define MCHP_IRQ_HTIMER0 112 -#define MCHP_IRQ_HTIMER1 113 -/* Must match CONFIG_IRQ_COUNT in config_chip.h */ -#define MCHP_IRQ_MAX 174 - -/* Block base addresses */ -#define MCHP_WDG_BASE 0x40000400 -#define MCHP_TMR16_0_BASE 0x40000c00 -#define MCHP_TMR32_0_BASE 0x40000c80 -#define MCHP_DMA_BASE 0x40002400 -#define MCHP_PROCHOT_BASE 0x40003400 -#define MCHP_I2C0_BASE 0x40004000 -#define MCHP_I2C1_BASE 0x40004400 -#define MCHP_I2C2_BASE 0x40004800 -#define MCHP_I2C3_BASE 0x40004C00 -#define MCHP_I2C4_BASE 0x40005000 -#define MCHP_I2C5_BASE 0x40005100 -#define MCHP_I2C6_BASE 0x40005200 -#define MCHP_I2C7_BASE 0x40005300 -#define MCHP_QMSPI0_BASE 0x40070000 -#define MCHP_PWM_0_BASE 0x40005800 -#define MCHP_TACH_0_BASE 0x40006000 -#define MCHP_PECI_BASE 0x40006400 -#define MCHP_RTMR_BASE 0x40007400 -#define MCHP_ADC_BASE 0x40007c00 -#define MCHP_TFDP_BASE 0x40008c00 -#define MCHP_HTIMER_BASE 0x40009800 -#define MCHP_KEYSCAN_BASE 0x40009c00 -#define MCHP_VBAT_BASE 0x4000a400 -#define MCHP_VBAT_RAM_BASE 0x4000a800 -#define MCHP_WKTIMER_BASE 0x4000ac80 -#define MCHP_BBLED_0_BASE 0x4000B800 -#define MCHP_INT_BASE 0x4000e000 -#define MCHP_EC_BASE 0x4000fc00 - -#define MCHP_PCR_BASE 0x40080100 -#define MCHP_GPIO_BASE 0x40081000 - -#define MCHP_MBOX_BASE 0x400f0000 -#define MCHP_8042_BASE 0x400f0400 -#define MCHP_ACPI_EC_0_BASE 0x400f0800 -#define MCHP_ACPI_PM1_BASE 0x400f1c00 -#define MCHP_UART0_BASE 0x400f2400 -#define MCHP_UART1_BASE 0x400f2800 -#define MCHP_UART2_BASE 0x400f2c00 -#define MCHP_ESPI_IO_BASE 0x400f3400 -#define MCHP_ESPI_MEM_BASE 0x400f3800 -#define MCHP_EMI_0_BASE 0x400f4000 -#define MCHP_EMI_1_BASE 0x400f4400 -#define MCHP_P80CAP0_BASE 0x400f8000 -#define MCHP_P80CAP1_BASE 0x400f8400 -#define MCHP_ESPI_VW_BASE 0x400f9c00 -#define MCHP_CHIP_BASE 0x400fff00 - -#ifndef __ASSEMBLER__ - -/* - * Helper function for RAM address aliasing - * NOTE: MCHP AHB masters do NOT require aliasing. - * Cortex-M4 bit-banding does require aliasing of the - * DATA SRAM region. - */ -#define MCHP_RAM_ALIAS(x) \ - ((x) >= 0x118000 ? (x) - 0x118000 + 0x20000000 : (x)) - -/* EC Chip Configuration */ -/* 16-bit Device ID */ -#define MCHP_CHIP_DEV_ID REG16(MCHP_CHIP_BASE + 0x1E) -/* 8-bit Device Sub ID */ -#define MCHP_CHIP_DEV_SUB_ID REG8(MCHP_CHIP_BASE + 0x1D) -/* 8-bit Device Revision */ -#define MCHP_CHIP_DEV_REV REG8(MCHP_CHIP_BASE + 0x1C) -/* All in one */ -#define MCHP_CHIP_DEVRID32 REG32(MCHP_CHIP_BASE + 0x1C) -#define MCHP_CHIP_DEVID_POS 16 -#define MCHP_CHIP_DEVID_MASK (0xfffful << MCHP_CHIP_DEVID_POS) -#define MCHP_CHIP_SUBID_POS 8 -#define MCHP_CHIP_SUBID_MASK (0xfful << MCHP_CHIP_SUBID_POS) -#define MCHP_CHIP_REV_POS 0 -#define MCHP_CHIP_REV_MASK (0xfful << MCHP_CHIP_REV_POS) -#define MCHP_CHIP_EXTRACT_DEVID(d) \ - (((uint32_t)(d) & MCHP_CHIP_DEVID_MASK) >> MCHP_CHIP_DEVID_POS) -#define MCHP_CHIP_EXTRACT_SUBID(d) \ - (((uint32_t)(d) & MCHP_CHIP_SUBID_MASK) >> MCHP_CHIP_SUBID_POS) -#define MCHP_CHIP_EXTRACT_REV(d) \ - (((uint32_t)(d) & MCHP_CHIP_REV_MASK) >> MCHP_CHIP_REV_POS) - -/* PCR clock control dividers */ -#define MCHP_PCR_CLK_CTL_FASTEST 1U -#define MCHP_PCR_CLK_CTL_48MHZ 1U -#define MCHP_PCR_CLK_CTL_12MHZ 4U - -/* - * PCR Peripheral Reset Lock register - * MEC152x PCR Peripheral reset registers do not reset on - * peripheral sleep. The peripheral is reset immediately. - * Firmware must write an unlock value to this new lock - * register, write to PCR reset enable register(s), and - * write a lock value. - */ -#define MCHP_PCR_RST_LOCK REG32(MCHP_PCR_BASE + 0x84) -#define MCHP_PCR_RST_LOCK_VAL 0xa6382d4d -#define MCHP_PCR_RST_UNLOCK_VAL 0xa6382d4c - -/* Number of PCR Sleep Enable, Clock Required, and Reset registers */ -#define MCHP_PCR_SLP_RST_REG_MAX 5 - -/* MC152x new bit allow sleep entry when PLL is not locked */ -#define MCHP_PCR_SYS_SLP_NO_PLL BIT(8) - -/* Sleep 0: Sleep Enable, Clock Required, and Reset bits */ -#define MCHP_PCR_JTAG BIT(0) /* CLKREQ only */ -#define MCHP_PCR_OTP BIT(1) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN0_JTAG BIT(0) -#define MCHP_PCR_SLP_EN0_OTP BIT(1) -#define MCHP_PCR_SLP_EN0_SLEEP 0xffffffff - -/* - * Encode register number and bit position - * b[4:0] = bit number - * b[10:8] = zero based register number - */ -#define MCHP_PCR_ERB(rnum, bnum) \ - ((((rnum) & 0x0f) << 8) | ((bnum) & 0x1f)) - -/* PCR Sleep 1: Sleep Enable, Clock Required, and Reset bits */ -#define MCHP_PCR_BTMR16_1 MCHP_PCR_ERB(1, 31) -#define MCHP_PCR_BTMR16_0 MCHP_PCR_ERB(1, 30) -#define MCHP_PCR_ECS MCHP_PCR_ERB(1, 29) -#define MCHP_PCR_PWM8 MCHP_PCR_ERB(1, 27) -#define MCHP_PCR_PWM7 MCHP_PCR_ERB(1, 26) -#define MCHP_PCR_PWM6 MCHP_PCR_ERB(1, 25) -#define MCHP_PCR_PWM5 MCHP_PCR_ERB(1, 24) -#define MCHP_PCR_PWM4 MCHP_PCR_ERB(1, 23) -#define MCHP_PCR_PWM3 MCHP_PCR_ERB(1, 22) -#define MCHP_PCR_PWM2 MCHP_PCR_ERB(1, 21) -#define MCHP_PCR_PWM1 MCHP_PCR_ERB(1, 20) -#define MCHP_PCR_TACH3 MCHP_PCR_ERB(1, 13) -#define MCHP_PCR_TACH2 MCHP_PCR_ERB(1, 12) -#define MCHP_PCR_TACH1 MCHP_PCR_ERB(1, 11) -#define MCHP_PCR_I2C0 MCHP_PCR_ERB(1, 10) -#define MCHP_PCR_WDT MCHP_PCR_ERB(1, 9) -#define MCHP_PCR_CPU MCHP_PCR_ERB(1, 8) -#define MCHP_PCR_TFDP MCHP_PCR_ERB(1, 7) -#define MCHP_PCR_DMA MCHP_PCR_ERB(1, 6) -#define MCHP_PCR_PMC MCHP_PCR_ERB(1, 5) -#define MCHP_PCR_PWM0 MCHP_PCR_ERB(1, 4) -#define MCHP_PCR_TACH0 MCHP_PCR_ERB(1, 2) -#define MCHP_PCR_PECI MCHP_PCR_ERB(1, 1) -#define MCHP_PCR_ECIA MCHP_PCR_ERB(1, 0) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN1_BTMR16_1 BIT(31) -#define MCHP_PCR_SLP_EN1_BTMR16_0 BIT(30) -#define MCHP_PCR_SLP_EN1_ECS BIT(29) -#define MCHP_PCR_SLP_EN1_PWM_ALL (BIT(4) + (0xff << 20)) -#define MCHP_PCR_SLP_EN1_PWM8 BIT(27) -#define MCHP_PCR_SLP_EN1_PWM7 BIT(26) -#define MCHP_PCR_SLP_EN1_PWM6 BIT(25) -#define MCHP_PCR_SLP_EN1_PWM5 BIT(24) -#define MCHP_PCR_SLP_EN1_PWM4 BIT(23) -#define MCHP_PCR_SLP_EN1_PWM3 BIT(22) -#define MCHP_PCR_SLP_EN1_PWM2 BIT(21) -#define MCHP_PCR_SLP_EN1_PWM1 BIT(20) -#define MCHP_PCR_SLP_EN1_TACH3 BIT(13) -#define MCHP_PCR_SLP_EN1_TACH2 BIT(12) -#define MCHP_PCR_SLP_EN1_TACH1 BIT(11) -#define MCHP_PCR_SLP_EN1_I2C0 BIT(10) -#define MCHP_PCR_SLP_EN1_WDT BIT(9) -#define MCHP_PCR_SLP_EN1_CPU BIT(8) -#define MCHP_PCR_SLP_EN1_TFDP BIT(7) -#define MCHP_PCR_SLP_EN1_DMA BIT(6) -#define MCHP_PCR_SLP_EN1_PMC BIT(5) -#define MCHP_PCR_SLP_EN1_PWM0 BIT(4) -#define MCHP_PCR_SLP_EN1_TACH0 BIT(2) -#define MCHP_PCR_SLP_EN1_PECI BIT(1) -#define MCHP_PCR_SLP_EN1_ECIA BIT(0) -/* all sleep enable 1 bits */ -#define MCHP_PCR_SLP_EN1_SLEEP 0xffffffff -/* - * block not used by default - * Do not sleep ECIA, PMC, CPU and ECS - */ -#define MCHP_PCR_SLP_EN1_UNUSED_BLOCKS 0xdffffede - -/* PCR Sleep 2: Sleep Enable, Clock Required 2, Reset bits */ -#define MCHP_PCR_GLUE MCHP_PCR_ERB(2, 29) -#define MCHP_PCR_UART2 MCHP_PCR_ERB(2, 28) -#define MCHP_PCR_SAF MCHP_PCR_ERB(2, 27) -#define MCHP_PCR_P80CAP1 MCHP_PCR_ERB(2, 26) -#define MCHP_PCR_P80CAP0 MCHP_PCR_ERB(2, 25) -#define MCHP_PCR_ASIF MCHP_PCR_ERB(2, 24) -#define MCHP_PCR_ACPI_EC3 MCHP_PCR_ERB(2, 22) -#define MCHP_PCR_ACPI_EC2 MCHP_PCR_ERB(2, 21) -#define MCHP_PCR_ESPI_SCR MCHP_PCR_ERB(2, 20) -#define MCHP_PCR_ESPI MCHP_PCR_ERB(2, 19) -#define MCHP_PCR_RTC MCHP_PCR_ERB(2, 18) -#define MCHP_PCR_MBOX MCHP_PCR_ERB(2, 17) -#define MCHP_PCR_8042 MCHP_PCR_ERB(2, 26) -#define MCHP_PCR_ACPI_PM1 MCHP_PCR_ERB(2, 15) -#define MCHP_PCR_ACPI_EC1 MCHP_PCR_ERB(2, 14) -#define MCHP_PCR_ACPI_EC0 MCHP_PCR_ERB(2, 13) -#define MCHP_PCR_GCFG MCHP_PCR_ERB(2, 12) -#define MCHP_PCR_UART1 MCHP_PCR_ERB(2, 2) -#define MCHP_PCR_UART0 MCHP_PCR_ERB(2, 1) -#define MCHP_PCR_EMI0 MCHP_PCR_ERB(2, 0) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN2_GLUE BIT(29) -#define MCHP_PCR_SLP_EN2_UART2 BIT(28) -#define MCHP_PCR_SLP_EN2_SAF BIT(27) -#define MCHP_PCR_SLP_EN2_P80CAP1 BIT(26) -#define MCHP_PCR_SLP_EN2_P80CAP0 BIT(25) -#define MCHP_PCR_SLP_EN2_ASIF BIT(24) -#define MCHP_PCR_SLP_EN2_ACPI_EC3 BIT(22) -#define MCHP_PCR_SLP_EN2_ACPI_EC2 BIT(21) -#define MCHP_PCR_SLP_EN2_ESPI_SCR BIT(20) -#define MCHP_PCR_SLP_EN2_ESPI BIT(19) -#define MCHP_PCR_SLP_EN2_RTC BIT(18) -#define MCHP_PCR_SLP_EN2_MAILBOX BIT(17) -#define MCHP_PCR_SLP_EN2_MIF8042 BIT(16) -#define MCHP_PCR_SLP_EN2_ACPI_PM1 BIT(15) -#define MCHP_PCR_SLP_EN2_ACPI_EC1 BIT(14) -#define MCHP_PCR_SLP_EN2_ACPI_EC0 BIT(13) -#define MCHP_PCR_SLP_EN2_GCFG BIT(12) -#define MCHP_PCR_SLP_EN2_UART1 BIT(2) -#define MCHP_PCR_SLP_EN2_UART0 BIT(1) -#define MCHP_PCR_SLP_EN2_EMI0 BIT(0) -/* all sleep enable 2 bits */ -#define MCHP_PCR_SLP_EN2_SLEEP 0xffffffff - -/* PCR Sleep 3: Sleep Enable, Clock Required, and Reset */ -#define MCHP_PCR_CCT0 MCHP_PCR_ERB(3, 30) -#define MCHP_PCR_HTMR1 MCHP_PCR_ERB(3, 29) -#define MCHP_PCR_AESHASH MCHP_PCR_ERB(3, 28) -#define MCHP_PCR_RNG MCHP_PCR_ERB(3, 27) -#define MCHP_PCR_PKE MCHP_PCR_ERB(3, 26) -#define MCHP_PCR_BTMR32_1 MCHP_PCR_ERB(3, 24) -#define MCHP_PCR_BTMR32_0 MCHP_PCR_ERB(3, 23) -#define MCHP_PCR_I2C4 MCHP_PCR_ERB(3, 20) -#define MCHP_PCR_LED2 MCHP_PCR_ERB(3, 18) -#define MCHP_PCR_LED1 MCHP_PCR_ERB(3, 17) -#define MCHP_PCR_LED0 MCHP_PCR_ERB(3, 16) -#define MCHP_PCR_I2C3 MCHP_PCR_ERB(3, 15) -#define MCHP_PCR_I2C2 MCHP_PCR_ERB(3, 14) -#define MCHP_PCR_I2C1 MCHP_PCR_ERB(3, 13) -#define MCHP_PCR_KEYSCAN MCHP_PCR_ERB(3, 11) -#define MCHP_PCR_HTMR0 MCHP_PCR_ERB(3, 10) -#define MCHP_PCR_PS2_1 MCHP_PCR_ERB(3, 6) -#define MCHP_PCR_PS2_0 MCHP_PCR_ERB(3, 5) -#define MCHP_PCR_ADC MCHP_PCR_ERB(3, 3) -#define MCHP_PCR_HDMI_CEC MCHP_PCR_ERB(3, 1) - -/* Command blocks to sleep */ -#define MCHP_PCR_SLP_EN3_CCT0 BIT(30) -#define MCHP_PCR_SLP_EN3_HTMR1 BIT(29) -#define MCHP_PCR_SLP_EN3_AESHASH BIT(28) -#define MCHP_PCR_SLP_EN3_RNG BIT(27) -#define MCHP_PCR_SLP_EN3_PKE BIT(26) -#define MCHP_PCR_SLP_EN3_BTMR32_1 BIT(24) -#define MCHP_PCR_SLP_EN3_BTMR32_0 BIT(23) -#define MCHP_PCR_SLP_EN3_I2C4 BIT(20) -#define MCHP_PCR_SLP_EN3_LED2 BIT(18) -#define MCHP_PCR_SLP_EN3_LED1 BIT(17) -#define MCHP_PCR_SLP_EN3_LED0 BIT(16) -#define MCHP_PCR_SLP_EN3_I2C3 BIT(15) -#define MCHP_PCR_SLP_EN3_I2C2 BIT(14) -#define MCHP_PCR_SLP_EN3_I2C1 BIT(13) -#define MCHP_PCR_SLP_EN3_KEYSCAN BIT(11) -#define MCHP_PCR_SLP_EN3_HTMR0 BIT(10) -#define MCHP_PCR_SLP_EN3_PS2_1 BIT(6) -#define MCHP_PCR_SLP_EN3_PS2_0 BIT(5) -#define MCHP_PCR_SLP_EN3_ADC BIT(3) -#define MCHP_PCR_SLP_EN3_HDMI_CEC BIT(1) -#define MCHP_PCR_SLP_EN3_ALL_CRYPTO (0x07 << 26) -/* all sleep enable 3 bits */ -#define MCHP_PCR_SLP_EN3_SLEEP 0xfffffffd -#define MCHP_PCR_SLP_EN3_PWM_ALL 0 - -/* PCR Sleep 4: Sleep Enable, Clock Required, Reset */ -#define MCHP_PCR_SGPIO3 MCHP_PCR_ERB(4, 20) -#define MCHP_PCR_SGPIO2 MCHP_PCR_ERB(4, 19) -#define MCHP_PCR_SGPIO1 MCHP_PCR_ERB(4, 18) -#define MCHP_PCR_SGPIO0 MCHP_PCR_ERB(4, 17) -#define MCHP_PCR_SLV_SPI MCHP_PCR_ERB(4, 16) -#define MCHP_PCR_PSPI MCHP_PCR_ERB(4, 14) -#define MCHP_PCR_PROCHOT MCHP_PCR_ERB(4, 13) -#define MCHP_PCR_I2C7 MCHP_PCR_ERB(4, 12) -#define MCHP_PCR_I2C6 MCHP_PCR_ERB(4, 11) -#define MCHP_PCR_I2C5 MCHP_PCR_ERB(4, 10) -#define MCHP_PCR_QMSPI MCHP_PCR_ERB(4, 8) -#define MCHP_PCR_RTMR MCHP_PCR_ERB(4, 6) - -/* Command blocks to sleep */ -#define MCHP_PCR_SLP_EN4_SGPIO3 BIT(20) -#define MCHP_PCR_SLP_EN4_SGPIO2 BIT(19) -#define MCHP_PCR_SLP_EN4_SGPIO1 BIT(18) -#define MCHP_PCR_SLP_EN4_SGPIO0 BIT(17) -#define MCHP_PCR_SLP_EN4_SLV_SPI BIT(16) -#define MCHP_PCR_SLP_EN4_PSPI BIT(14) -#define MCHP_PCR_SLP_EN4_PROCHOT BIT(13) -#define MCHP_PCR_SLP_EN4_I2C7 BIT(12) -#define MCHP_PCR_SLP_EN4_I2C6 BIT(11) -#define MCHP_PCR_SLP_EN4_I2C5 BIT(10) -#define MCHP_PCR_SLP_EN4_QMSPI BIT(8) -#define MCHP_PCR_SLP_EN4_RTMR BIT(6) -/* all sleep enable 4 bits */ -#define MCHP_PCR_SLP_EN4_SLEEP 0xffffffff -#define MCHP_PCR_SLP_EN4_PWM_ALL 0 - -/* Allow all blocks to request clocks */ -#define MCHP_PCR_SLP_EN0_WAKE (~(MCHP_PCR_SLP_EN0_SLEEP)) -#define MCHP_PCR_SLP_EN1_WAKE (~(MCHP_PCR_SLP_EN1_SLEEP)) -#define MCHP_PCR_SLP_EN2_WAKE (~(MCHP_PCR_SLP_EN2_SLEEP)) -#define MCHP_PCR_SLP_EN3_WAKE (~(MCHP_PCR_SLP_EN3_SLEEP)) -#define MCHP_PCR_SLP_EN4_WAKE (~(MCHP_PCR_SLP_EN4_SLEEP)) - -/* Bit defines for MCHP_PCR_PWR_RST_STS */ -#define MCHP_PWR_RST_STS_MASK_RO 0xc8c -#define MCHP_PWR_RST_STS_MASK_RWC 0x170 -#define MCHP_PWR_RST_STS_MASK \ - ((MCHP_PWR_RST_STS_MASK_RO) | (MCHP_PWR_RST_STS_MASK_RWC)) - -#define MCHP_PWR_RST_STS_ESPI_CLK_ACT BIT(11) /* RO */ -#define MCHP_PWR_RST_STS_32K_ACT BIT(10) /* RO */ -#define MCHP_PWR_RST_STS_WDT BIT(8) /* R/WC */ -#define MCHP_PWR_RST_STS_JTAG_RSTN BIT(7) /* RO */ -#define MCHP_PWR_RST_STS_SYS BIT(6) /* R/WC */ -#define MCHP_PWR_RST_STS_VBAT BIT(5) /* R/WC */ -#define MCHP_PWR_RST_STS_VTR BIT(4) /* R/WC */ -#define MCHP_PWR_RST_STS_HOST BIT(3) /* RO */ -#define MCHP_PWR_RST_STS_VCC_PWRGD BIT(2) /* RO */ - -/* Bit defines for MCHP_PCR_PWR_RST_CTL */ -#define MCHP_PCR_PWR_HOST_RST_SEL_BITPOS 8 -#define MCHP_PCR_PWR_HOST_RST_PCI_RESET BIT(8) -#define MCHP_PCR_PWR_HOST_RST_ESPI_PLTRST (0 << 8) -#define MCHP_PCR_PWR_OK_INV_BITPOS 0 - -/* Bit defines for MCHP_PCR_SYS_RST */ -#define MCHP_PCR_SYS_SOFT_RESET BIT(8) - -/* EC Subsystem */ -#define MCHP_EC_AHB_ERR REG32(MCHP_EC_BASE + 0x04) -#define MCHP_EC_ID_RO REG32(MCHP_EC_BASE + 0x10) -#define MCHP_EC_AHB_ERR_EN REG32(MCHP_EC_BASE + 0x14) -#define MCHP_EC_INT_CTRL REG32(MCHP_EC_BASE + 0x18) -#define MCHP_EC_TRACE_EN REG32(MCHP_EC_BASE + 0x1c) -#define MCHP_EC_JTAG_EN REG32(MCHP_EC_BASE + 0x20) -#define MCHP_EC_WDT_CNT REG32(MCHP_EC_BASE + 0x28) -#define MCHP_EC_AES_SHA_SWAP_CTRL REG8(MCHP_EC_BASE + 0x2c) -#define MCHP_EC_VCI_FW_OVRD REG8(MCHP_EC_BASE + 0x50) -#define MCHP_EC_CRYPTO_SRESET REG8(MCHP_EC_BASE + 0x5c) -#define MCHP_EC_GPIO_BANK_PWR REG8(MCHP_EC_BASE + 0x64) -#define MCHP_EC_SLP_STS_MIRROR REG8(MCHP_EC_BASE + 0x114) - -/* AHB ERR Enable bit[0]=0(enable), 1(disable) */ -#define MCHP_EC_AHB_ERROR_ENABLE 0 -#define MCHP_EC_AHB_ERROR_DISABLE 1 - -/* MCHP_EC_JTAG_EN bit definitions */ -#define MCHP_JTAG_ENABLE 0x01 -/* bits [2:1] */ -#define MCHP_JTAG_MODE_4PIN 0x00 -/* ARM 2-pin SWD plus 1-pin Serial Wire Viewer (ITM) */ -#define MCHP_JTAG_MODE_SWD_SWV 0x02 -/* ARM 2-pin SWD with no SWV */ -#define MCHP_JTAG_MODE_SWD 0x04 - -/* MCHP_EC_CRYPTO_SRESET bit definitions. Bits cleared by HW */ -#define MCHP_CRYPTO_NDRNG_SRST 0x01 -#define MCHP_CRYPTO_PKE_SRST 0x02 -#define MCHP_CRYPTO_AES_SHA_SRST 0x04 -#define MCHP_CRYPTO_ALL_SRST 0x07 - -/* MCHP_GPIO_BANK_PWR bit definitions */ -#define MCHP_EC_GPIO_BANK_PWR_MASK 0x86 -#define MCHP_EC_GPIO_BANK_PWR_VTR2_18 0x02 -#define MCHP_EC_GPIO_BANK_PWR_VTR3_18 0x04 -#define MCHP_EC_GPIO_BANK_PWR_LOCK 0x80 - -/* EC Interrupt aggregator (ECIA) */ -#define MCHP_INT_GIRQ_LEN 20 /* 5 32-bit registers */ -#define MCHP_INT_GIRQ_FIRST 8 -#define MCHP_INT_GIRQ_LAST 26 -#define MCHP_INT_GIRQ_NUM (26-8+1) -/* MCHP_INT_GIRQ_FIRST <= x <= MCHP_INT_GIRQ_LAST */ -#define MCHP_INTx_BASE(x) (MCHP_INT_BASE + (((x) - 8) * MCHP_INT_GIRQ_LEN)) - -/* - * GPIO GIRQ's are not direct capable - * GIRQ08 GPIO 0140 - 0176 - * GIRQ09 GPIO 0100 - 0136 - * GIRQ10 GPIO 040 - 076 - * GIRQ11 GPIO 000 - 036 - * GIRQ12 GPIO 0200 - 0236 - * GIRQ26 GPIO 0240 - 0276 - * Other GIRQ's not direct capable: - * GIRQ22 wake peripheral clock only - * GIRQ24, GIRQ25 eSPI host to endpoint virtual wires - */ -#define MCHP_INT_AGGR_ONLY_BITMAP 0x07401F00U -#define MCHP_INT_DIRECT_CAPABLE_BITMAP 0x00BFE000U - -/* GIRQ13 I2C controllers. Direct capable */ -#define MCHP_INT13_I2C(x) (1ul << (x)) - -/* GIRQ14 DMA channels 0 - 11. Direct capable */ -#define MCHP_INT14_DMA(x) (1ul << (x)) - -/* GIQ15 interrupt sources. Direct capable */ -#define MCHP_INT15_UART_0 BIT(0) -#define MCHP_INT15_UART_1 BIT(1) -#define MCHP_INT15_UART_2 BIT(4) -#define MCHP_INT15_EMI_0 BIT(2) -#define MCHP_INT15_EMI_1 BIT(3) -#define MCHP_INT15_ACPI_EC0_IBF BIT(5) -#define MCHP_INT15_ACPI_EC0_OBE BIT(6) -#define MCHP_INT15_ACPI_EC1_IBF BIT(7) -#define MCHP_INT15_ACPI_EC1_OBE BIT(8) -#define MCHP_INT15_ACPI_EC2_IBF BIT(9) -#define MCHP_INT15_ACPI_EC2_OBE BIT(10) -#define MCHP_INT15_ACPI_EC3_IBF BIT(11) -#define MCHP_INT15_ACPI_EC3_OBE BIT(12) -#define MCHP_INT15_ACPI_PM1_CTL BIT(15) -#define MCHP_INT15_ACPI_PM1_EN BIT(16) -#define MCHP_INT15_ACPI_PM1_STS BIT(17) -#define MCHP_INT15_8042_OBE BIT(18) -#define MCHP_INT15_8042_IBF BIT(19) -#define MCHP_INT15_MAILBOX BIT(20) -#define MCHP_INT15_P80_0 BIT(22) -#define MCHP_INT15_P80_1 BIT(23) -#define MCHP_INT15_P80(x) BIT(22 + ((x) & 0x01U)) - -/* GIRQ16 interrupt sources. Direct capable */ -#define MCHP_INT16_PKE_ERR BIT(0) -#define MCHP_INT16_PKE_DONE BIT(1) -#define MCHP_INT16_RNG_DONE BIT(2) -#define MCHP_INT16_AES_DONE BIT(3) -#define MCHP_INT16_HASH_DONE BIT(4) - -/* GIR17 interrupt sources. Direct capable */ -#define MCHP_INT17_PECI BIT(0) -#define MCHP_INT17_TACH_0 BIT(1) -#define MCHP_INT17_TACH_1 BIT(2) -#define MCHP_INT17_TACH_2 BIT(3) -#define MCHP_INT17_TACH_3 BIT(4) -#define MCHP_INT17_HDMI_CEC BIT(5) -#define MCHP_INT17_ADC_SINGLE BIT(8) -#define MCHP_INT17_ADC_REPEAT BIT(9) -#define MCHP_INT17_LED_WDT_0 BIT(13) -#define MCHP_INT17_LED_WDT_1 BIT(14) -#define MCHP_INT17_LED_WDT_2 BIT(15) -#define MCHP_INT17_PROCHOT BIT(17) - -/* GIRQ18 interrupt sources. Direct capable */ -#define MCHP_INT18_SLV_SPI BIT(0) -#define MCHP_INT18_QMSPI BIT(1) -#define MCHP_INT18_PS2_0 BIT(10) -#define MCHP_INT18_PS2_1 BIT(11) -#define MCHP_INT18_CCT BIT(20) -#define MCHP_INT18_CCT_CAP0 BIT(21) -#define MCHP_INT18_CCT_CAP1 BIT(22) -#define MCHP_INT18_CCT_CAP2 BIT(23) -#define MCHP_INT18_CCT_CAP3 BIT(24) -#define MCHP_INT18_CCT_CAP4 BIT(25) -#define MCHP_INT18_CCT_CAP6 BIT(26) -#define MCHP_INT18_CCT_CMP0 BIT(27) -#define MCHP_INT18_CCT_CMP1 BIT(28) - -/* GIRQ19 interrupt sources. Direct capable */ -#define MCHP_INT19_ESPI_PC BIT(0) -#define MCHP_INT19_ESPI_BM1 BIT(1) -#define MCHP_INT19_ESPI_BM2 BIT(2) -#define MCHP_INT19_ESPI_LTR BIT(3) -#define MCHP_INT19_ESPI_OOB_TX BIT(4) -#define MCHP_INT19_ESPI_OOB_RX BIT(5) -#define MCHP_INT19_ESPI_FC BIT(6) -#define MCHP_INT19_ESPI_RESET BIT(7) -#define MCHP_INT19_ESPI_VW_EN BIT(8) -#define MCHP_INT19_ESPI_SAF BIT(9) -#define MCHP_INT19_ESPI_SAF_ERR BIT(10) - -/* GIRQ20 interrupt sources. Direct capable */ -#define MCHP_INT20_OPT BIT(3) - -/* GIRQ21 interrupt sources. Direct capable */ -#define MCHP_INT21_WDT BIT(2) -#define MCHP_INT21_WEEK_ALARM BIT(3) -#define MCHP_INT21_WEEK_SUB BIT(4) -#define MCHP_INT21_WEEK_1SEC BIT(5) -#define MCHP_INT21_WEEK_1SEC_SUB BIT(6) -#define MCHP_INT21_WEEK_PWR_PRES BIT(7) -#define MCHP_INT21_RTC BIT(8) -#define MCHP_INT21_RTC_ALARM BIT(9) -#define MCHP_INT21_VCI_OVRD BIT(10) -#define MCHP_INT21_VCI_IN0 BIT(11) -#define MCHP_INT21_VCI_IN1 BIT(12) -#define MCHP_INT21_VCI_IN2 BIT(13) -#define MCHP_INT21_VCI_IN3 BIT(14) -#define MCHP_INT21_PS2_0A_WAKE BIT(18) -#define MCHP_INT21_PS2_0B_WAKE BIT(19) -#define MCHP_INT21_PS2_1B_WAKE BIT(21) -#define MCHP_INT21_KEYSCAN BIT(25) - -/* GIRQ22 peripheral wake only. GIRQ22 not connected to NVIC */ -#define MCHP_INT22_WAKE_ONLY_SLV_SPI BIT(0) -#define MCHP_INT22_WAKE_ONLY_I2C0 BIT(1) -#define MCHP_INT22_WAKE_ONLY_I2C1 BIT(2) -#define MCHP_INT22_WAKE_ONLY_I2C2 BIT(3) -#define MCHP_INT22_WAKE_ONLY_I2C3 BIT(4) -#define MCHP_INT22_WAKE_ONLY_I2C4 BIT(5) -#define MCHP_INT22_WAKE_ONLY_I2C5 BIT(6) -#define MCHP_INT22_WAKE_ONLY_I2C6 BIT(7) -#define MCHP_INT22_WAKE_ONLY_I2C7 BIT(8) -#define MCHP_INT22_WAKE_ONLY_ESPI BIT(9) - -/* GIRQ23 sources. Direct capable */ -#define MCHP_INT23_BTMR16_0 BIT(0) -#define MCHP_INT23_BTMR16_1 BIT(1) -#define MCHP_INT23_BTMR32_0 BIT(4) -#define MCHP_INT23_BTMR32_1 BIT(5) -#define MCHP_INT23_RTMR BIT(10) -#define MCHP_INT23_HTMR_0 BIT(16) -#define MCHP_INT23_HTMR_1 BIT(17) - -/* GIRQ24 sources. Master-to-Slave v=[0:6], Source=[0:3] */ -#define MCHP_INT24_MSVW_SRC(v, s) (1ul << ((4 * (v)) + (s))) - -/* GIRQ25 sources Master-to-Slave v=[7:10], Source=[0:3] */ -#define MCHP_INT25_MSVW_SRC(v, s) (1ul << ((4 * ((v)-7)) + (s))) - -/* UART Peripheral 0 <= x <= 2 */ -#define MCHP_UART_INSTANCES 3 -#define MCHP_UART_SPACING 0x400 -#define MCHP_UART_CFG_OFS 0x300 -#define MCHP_UART_CONFIG_BASE(x) \ - (MCHP_UART0_BASE + MCHP_UART_CFG_OFS + ((x) * MCHP_UART_SPACING)) -#define MCHP_UART_RUNTIME_BASE(x) \ - (MCHP_UART0_BASE + ((x) * MCHP_UART_SPACING)) -#define MCHP_UART_GIRQ 15 -#define MCHP_UART0_GIRQ_BIT (MCHP_INT15_UART_0) -#define MCHP_UART1_GIRQ_BIT (MCHP_INT15_UART_1) -#define MCHP_UART2_GIRQ_BIT (MCHP_INT15_UART_2) -#define MCHP_UART_GIRQ_BIT(x) BIT(x) -/* BIT defines for MCHP_UARTx_LSR */ -#define MCHP_LSR_TX_EMPTY BIT(5) - -/* - * GPIO - * MCHP each Port contains 32 GPIO's. - * GPIO Control 1 registers are 32-bit registers starting at - * MCHP_GPIO_BASE. - * index = octal GPIO number from MCHP specification. - * port/bank = index >> 5 - * id = index & 0x1F - * - * The port/bank, id pair may also be used to access GPIO's via - * parallel I/O registers if GPIO control is configured for - * parallel I/O. - * - * From ec/chip/mec1701/config_chip.h - * #define GPIO_PIN(index) ((index) >> 5), ((index) & 0x1F) - * - * GPIO Control 1 Address = 0x40081000 + (((bank << 5) + id) << 2) - * - * Example: GPIO043, Control 1 register address = 0x4008108c - * port/bank = 0x23 >> 5 = 1 - * id = 0x23 & 0x1F = 0x03 - * Control 1 Address = 0x40081000 + ((BIT(5) + 0x03) << 2) = 0x4008108c - * - * Example: GPIO235, Control 1 register address = 0x40081274 - * port/bank = 0x9d >> 5 = 4 - * id = 0x9d & 0x1f = 0x1d - * Control 1 Address = 0x40081000 + (((4 << 5) + 0x1d) << 2) = 0x40081274 - */ -#define MCHP_GPIO_CTL(port, id) REG32(MCHP_GPIO_BASE + \ - (((port << 5) + id) << 2)) - -/* MCHP implements 6 GPIO ports */ -#define MCHP_GPIO_MAX_PORT 6 -#define UNIMPLEMENTED_GPIO_BANK MCHP_GPIO_MAX_PORT - -/* - * In MECxxxx documentation GPIO numbers are octal, each control - * register is located on a 32-bit boundary. - */ -#define MCHP_GPIO_CTRL(gpio_num) REG32(MCHP_GPIO_BASE + \ - ((gpio_num) << 2)) - -/* - * GPIO control register bit fields - */ -#define MCHP_GPIO_CTRL_PUD_BITPOS 0 -#define MCHP_GPIO_CTRL_PUD_MASK0 0x03 -#define MCHP_GPIO_CTRL_PUD_MASK 0x03 -#define MCHP_GPIO_CTRL_PUD_NONE 0x00 -#define MCHP_GPIO_CTRL_PUD_PU 0x01 -#define MCHP_GPIO_CTRL_PUD_PD 0x02 -#define MCHP_GPIO_CTRL_PUD_KEEPER 0x03 -#define MCHP_GPIO_CTRL_PWR_BITPOS 2 -#define MCHP_GPIO_CTRL_PWR_MASK0 0x03 -#define MCHP_GPIO_CTRL_PWR_MASK (0x03 << 2) -#define MCHP_GPIO_CTRL_PWR_VTR (0x00 << 2) -#define MCHP_GPIO_CTRL_PWR_OFF (0x02 << 2) -#define MCHP_GPIO_INTDET_MASK 0xF0 -#define MCHP_GPIO_INTDET_LVL_LO 0x00 -#define MCHP_GPIO_INTDET_LVL_HI 0x10 -#define MCHP_GPIO_INTDET_DISABLED 0x40 -#define MCHP_GPIO_INTDET_EDGE_RIS 0xD0 -#define MCHP_GPIO_INTDET_EDGE_FALL 0xE0 -#define MCHP_GPIO_INTDET_EDGE_BOTH 0xF0 -#define MCHP_GPIO_INTDET_EDGE_EN BIT(7) -#define MCHP_GPIO_PUSH_PULL 0u -#define MCHP_GPIO_OPEN_DRAIN BIT(8) -#define MCHP_GPIO_INPUT 0u -#define MCHP_GPIO_OUTPUT BIT(9) -#define MCHP_GPIO_OUTSET_CTRL 0u -#define MCHP_GPIO_OUTSEL_PAR BIT(10) -#define MCHP_GPIO_POLARITY_NINV 0u -#define MCHP_GPIO_POLARITY_INV BIT(11) -#define MCHP_GPIO_CTRL_ALT_FUNC_BITPOS 12 -#define MCHP_GPIO_CTRL_ALT_FUNC_MASK0 0x0F -#define MCHP_GPIO_CTRL_ALT_FUNC_MASK (0x0F << 12) -#define MCHP_GPIO_CTRL_FUNC_GPIO (0 << 12) -#define MCHP_GPIO_CTRL_FUNC_1 (1 << 12) -#define MCHP_GPIO_CTRL_FUNC_2 (2 << 12) -#define MCHP_GPIO_CTRL_FUNC_3 (3 << 12) -#define MCHP_GPIO_CTRL_OUT_LVL BIT(16) -/* MEC15xx only */ -#define MCHP_GPIO_CTRL_DIS_INPUT_BITPOS 15 -#define MCHP_GPIO_CTRL_DIS_INPUT_BIT BIT(15) - -/* - * GPIO Parallel Input and Output registers. - * gpio_bank in [0, 5] - */ -#define MCHP_GPIO_PARIN(bank) \ - REG32(MCHP_GPIO_BASE + 0x0300 + ((bank) << 2)) -#define MCHP_GPIO_PAROUT(bank) \ - REG32(MCHP_GPIO_BASE + 0x0380 + ((bank) << 2)) - -/* Basic timers */ -#define MCHP_TMR_SPACING 0x20 -#define MCHP_TMR16_INSTANCES 2 -#define MCHP_TMR32_INSTANCES 2 -#define MCHP_TMR16_MAX (MCHP_TMR16_INSTANCES) -#define MCHP_TMR32_MAX (MCHP_TMR32_INSTANCES) -#define MCHP_TMR16_BASE(n) \ - (MCHP_TMR16_0_BASE + (n) * MCHP_TMR_SPACING) -#define MCHP_TMR32_BASE(n) \ - (MCHP_TMR32_0_BASE + (n) * MCHP_TMR_SPACING) -#define MCHP_TMR16_GIRQ 23 -#define MCHP_TMR16_GIRQ_BIT(n) BIT(0 + (n)) -#define MCHP_TMR32_GIRQ 23 -#define MCHP_TMR32_GIRQ_BIT(n) BIT(4 + (n)) - -/* RTimer */ -#define MCHP_RTMR_GIRQ 23 -#define MCHP_RTMR_GIRQ_BIT(x) BIT(10) - -/* Watchdog */ -/* MEC152x specific registers */ -#define MCHP_WDG_STATUS REG32(MCHP_WDG_BASE + 0x10) -#define MCHP_WDG_IEN REG32(MCHP_WDG_BASE + 0x14) -/* Status */ -#define MCHP_WDG_STS_IRQ BIT(0) -/* Interrupt enable */ -#define MCHP_WDG_IEN_IRQ_EN BIT(0) -#define MCHP_WDG_GIRQ 21 -#define MCHP_WDG_GIRQ_BIT BIT(2) -/* Control register has a bit to enable IRQ generation */ -#define MCHP_WDG_RESET_IRQ_EN BIT(9) - -/* VBAT */ -#define MCHP_VBAT_STS REG32(MCHP_VBAT_BASE + 0x0) -#define MCHP_VBAT_CE REG32(MCHP_VBAT_BASE + 0x8) -#define MCHP_VBAT_SHDN_DIS REG32(MCHP_VBAT_BASE + 0xC) -#define MCHP_VBAT_MONOTONIC_CTR_LO REG32(MCHP_VBAT_BASE + 0x20) -#define MCHP_VBAT_MONOTONIC_CTR_HI REG32(MCHP_VBAT_BASE + 0x24) -/* read 32-bit word at 32-bit offset x where 0 <= x <= 16 */ -#define MCHP_VBAT_RAM_SIZE 64 -#define MCHP_VBAT_RAM(wnum) REG32(MCHP_VBAT_RAM_BASE + ((wnum) * 4)) -#define MCHP_VBAT_RAM8(bnum) REG8(MCHP_VBAT_RAM_BASE + (bnum)) -#define MCHP_VBAT_VWIRE_BACKUP 14 -/* - * Miscellaneous firmware control fields - * scratch pad index cannot be more than 32 as - * MEC152x has 64 bytes = 16 words of scratch pad RAM - */ -#define MCHP_IMAGETYPE_IDX 15 - -/* Bit definition for MCHP_VBAT_STS */ -#define MCHP_VBAT_STS_SOFTRESET BIT(2) -#define MCHP_VBAT_STS_RESETI BIT(4) -#define MCHP_VBAT_STS_WDT BIT(5) -#define MCHP_VBAT_STS_SYSRESETREQ BIT(6) -#define MCHP_VBAT_STS_VBAT_RST BIT(7) -#define MCHP_VBAT_STS_ANY_RST 0xF4u - -/* Bit definitions for MCHP_VBAT_CE */ -#define MCHP_VBAT_CE_XOSEL_BITPOS 3 -#define MCHP_VBAT_CE_XOSEL_MASK BIT(3) -#define MCHP_VBAT_CE_XOSEL_PAR 0 -#define MCHP_VBAT_CE_XOSEL_SE BIT(3) - -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_BITPOS 2 -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_MASK BIT(2) -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_INT 0 -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL BIT(2) - -#define MCHP_VBAT_CE_32K_DOMAIN_SRC_BITPOS 1 -#define MCHP_VBAT_CE_32K_DOMAIN_SRC_MASK BIT(1) -#define MCHP_VBAT_CE_32K_DOMAIN_ALWAYS_ON 0 -#define MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN BIT(1) - -/* Blinking-Breathing LED 0 <= n <= 2 */ -#define MCHP_BBLEB_INSTANCES 3 -#define MCHP_BBLED_BASE(n) (MCHP_BBLED_0_BASE + (((n) & 0x03) * 256)) - -/* EMI */ -#define MCHP_EMI_INSTANCES 2 -#define MCHP_EMI_SPACING 0x400 -#define MCHP_EMI_ECREG_OFS 0x100 -/* base of EMI registers only accessible by EC */ -#define MCHP_EMI_BASE(n) \ - (MCHP_EMI_0_BASE + MCHP_EMI_ECREG_OFS + ((n) * MCHP_EMI_SPACING)) -/* base of EMI registers accessible by EC and Host */ -#define MCHP_EMI_RT_BASE(n) (MCHP_EMI_0_BASE + ((n) * MCHP_EMI_SPACING)) -#define MCHP_EMI_GIRQ 15 -#define MCHP_EMI_GIRQ_BIT(n) BIT(2 + (n)) - -/* Mailbox */ -#define MCHP_MBX_ECREGS_OFS 0x100 -#define MCHP_MBX_RT_BASE MCHP_MBOX_BASE -#define MCHP_MBX_BASE (MCHP_MBOX_BASE + MCHP_MBX_ECREGS_OFS) -#define MCHP_MBX_GIRQ 15 -#define MCHP_MBX_GIRQ_BIT BIT(20) - -/* Port 80 Capture */ -#define MCHP_P80_SPACING 0x400 -#define MCHP_P80_BASE(n) \ - (MCHP_P80CAP0_BASE + ((n) * (MCHP_P80_SPACING))) -#define MCHP_P80_HOST_DATA(n) REG8(MCHP_P80_BASE(n)) -/* Data capture with time stamp register */ -#define MCHP_P80_CAP(n) REG32(MCHP_P80_BASE(n) + 0x100) -#define MCHP_P80_CFG(n) REG8(MCHP_P80_BASE(n) + 0x104) -#define MCHP_P80_STS(n) REG8(MCHP_P80_BASE(n) + 0x108) -#define MCHP_P80_CNT(n) REG32(MCHP_P80_BASE(n) + 0x10c) -#define MCHP_P80_CNT_GET(n) (REG32(MCHP_P80_BASE(n) + 0x10c) >> 8) -#define MCHP_P80_CNT_SET(n, c) \ - (REG32(MCHP_P80_BASE(n) + 0x10c) = ((c) << 8)) -#define MCHP_P80_ACTIVATE(n) REG8(MCHP_P80_BASE(n) + 0x330) -#define MCHP_P80_GIRQ 15 -#define MCHP_P80_GIRQ_BIT(n) BIT(22 + (n)) -/* - * Port 80 Data register bits - * bits[7:0] = data captured on Host write - * bits[31:8] = optional time stamp - */ -#define MCHP_P80_CAP_DATA_MASK 0xFFul -#define MCHP_P80_CAP_TS_BITPOS 8 -#define MCHP_P80_CAP_TS_MASK0 0xfffffful -#define MCHP_P80_CAP_TS_MASK \ - ((MCHP_P80_CAP_TS_MASK0) << (MCHP_P80_CAP_TS_BITPOS)) - -/* Port 80 Configuration register bits */ -#define MCHP_P80_FLUSH_FIFO_WO BIT(1) -#define MCHP_P80_RESET_TIMESTAMP_WO BIT(2) -#define MCHP_P80_TIMEBASE_BITPOS 3 -#define MCHP_P80_TIMEBASE_MASK0 0x03 -#define MCHP_P80_TIMEBASE_MASK \ - ((MCHP_P80_TIMEBASE_MASK0) << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_750KHZ \ - (0x03 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_1500KHZ \ - (0x02 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_3MHZ \ - (0x01 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_6MHZ \ - (0x00 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMER_ENABLE BIT(5) -#define MCHP_P80_FIFO_THRHOLD_MASK (3u << 6) -#define MCHP_P80_FIFO_THRHOLD_1 0u -#define MCHP_P80_FIFO_THRHOLD_4 (1u << 6) -#define MCHP_P80_FIFO_THRHOLD_8 (2u << 6) -#define MCHP_P80_FIFO_THRHOLD_14 (3u << 6) -#define MCHP_P80_FIFO_LEN 16 -/* Port 80 Status register bits, read-only */ -#define MCHP_P80_STS_NOT_EMPTY BIT(0) -#define MCHP_P80_STS_OVERRUN BIT(1) -/* Port 80 Count register bits */ -#define MCHP_P80_CNT_BITPOS 8 -#define MCHP_P80_CNT_MASK0 0xfffffful -#define MCHP_P80_CNT_MASK \ - ((MCHP_P80_CNT_MASK0) << (MCHP_P80_CNT_BITPOS)) - -/* PWM */ -#define MCHP_PWM_INSTANCES 9 -#define MCHP_PWM_ID_MAX (MCHP_PWM_INSTANCES) -#define MCHP_PWM_SPACING 16 -#define MCHP_PWM_BASE(x) (MCHP_PWM_0_BASE + ((x) * MCHP_PWM_SPACING)) - -/* TACH */ -#define MCHP_TACH_INSTANCES 4 -#define MCHP_TACH_SPACING 16 -#define MCHP_TACH_BASE(x) \ - (MCHP_TACH_0_BASE + ((x) * MCHP_TACH_SPACING)) -#define MCHP_TACH_GIRQ 17 -#define MCHP_TACH_GIRQ_BIT(x) BIT(1 + (x)) - -/* ACPI EC */ -#define MCHP_ACPI_EC_INSTANCES 4 -#define MCHP_ACPI_EC_MAX (ACPI_EC_INSTANCES) -#define MCHP_ACPI_EC_SPACING 0x400 -#define MCHP_ACPI_EC_BASE(x) \ - (MCHP_ACPI_EC_0_BASE + ((x) * MCHP_ACPI_EC_SPACING)) -#define MCHP_ACPI_EC_GIRQ 15 -#define MCHP_ACPI_EC_IBF_GIRQ_BIT(x) BIT(5 + ((x) * 2)) -#define MCHP_ACPI_EC_OBE_GIRQ_BIT(x) BIT(6 + ((x) * 2)) - -/* ACPI PM1 */ -#define MCHP_ACPI_PM1_ECREGS_OFS 0x100 -#define MCHP_ACPI_PM_RT_BASE MCHP_ACPI_PM1_BASE -#define MCHP_ACPI_PM_EC_BASE \ - (MCHP_ACPI_PM1_BASE + MCHP_ACPI_PM1_ECREGS_OFS) -#define MCHP_ACPI_PM1_CTL_GIRQ_BIT BIT(15) -#define MCHP_ACPI_PM1_EN_GIRQ_BIT BIT(16) -#define MCHP_ACPI_PM1_STS_GIRQ_BIT BIT(17) - -/* 8042 */ -#define MCHP_8042_ECREGS_OFS 0x100 -#define MCHP_8042_GIRQ 15 -#define MCHP_8042_OBE_GIRQ_BIT BIT(18) -#define MCHP_8042_IBF_GIRQ_BIT BIT(19) - -/* - * I2C controllers 0 - 4 include SMBus network layer functionality. - * I2C controllers 5 - 7 are I2C only and include slave mode - * promiscuous functionality. - */ -#define MCHP_I2C_CTRL0 0 -#define MCHP_I2C_CTRL1 1 -#define MCHP_I2C_CTRL2 2 -#define MCHP_I2C_CTRL3 3 -#define MCHP_I2C_CTRL4 4 -#define MCHP_I2C_CTRL5 5 -#define MCHP_I2C_CTRL6 6 -#define MCHP_I2C_CTRL7 7 -#define MCHP_I2C_CTRL_MAX 8 - -#define MCHP_I2C_SEP0 0x400 -#define MCHP_I2C_SEP1 0x100 - -/* - * MEC152xH 144-pin package has eight I2C controllers and sixteen ports. - * Any port can be mapped to any I2C controller. - * - * I2C port values must be zero based consecutive whole numbers due to - * port number used as an index for I2C mutex array, etc. - * - * Refer to chip i2c_port_to_controller function for mapping - * of port to controller. - * - * Locking must occur by-controller (not by-port). - * I2C00_SCL/SDA on GPIO004 F1, GPIO003 F1 - * I2C01_SCL/SDA on GPIO0131 F1, GPIO130 F1 - * Alternate pins: GPIO073 F2, GPIO072 F2 - * I2C02_SCL/SDA on GPIO0155 F1, GPIO0154 F1 - * I2C03_SCL/SDA on GPIO010 F1, GPIO007 F1 - * I2C04_SCL/SDA on GPIO0144 F1, GPIO0143 F1 - * I2C05_SCL/SDA on GPIO0142 F1, GPIO0141 F1 - * I2C06_SCL/SDA on GPIO0140 F1, GPIO0132 F1 - * I2C07_SCL/SDA on GPIO013 F1, GPIO012 F1 - * Alternate pins: GPIO0024 F3, GPIO0152 F3 - * I2C08_SCL/SDA on GPIO012 F1, GPIO0211 F1 - * I2C09_SCL/SDA on GPIO0146 F1, GPIO0145 F1 - * I2C10_SCL/SDA on GPIO0107 F3, GPIO030 F2 - * I2C11_SCL/SDA on GPIO062 F2, GPIO000 F3 - * I2C12_SCL/SDA on GPIO027 F3, GPIO026 F3 - * I2C13_SCL/SDA on GPIO065 F2, GPIO066 F2 - * I2C14_SCL/SDA on GPIO071 F2, GPIO070 F2 - * I2C15_SCL/SDA on GPIO0150 F1, GPIO0147 F1 - */ - -#define MCHP_MEC1521SZ_I2C_PORT_MASK 0xFEFFul -#define MCHP_MEC1523SZ_I2C_PORT_MASK 0xFFFFul - -#define MCHP_I2C_PORT_MASK MCHP_MEC1521SZ_I2C_PORT_MASK - -enum MCHP_i2c_port { - MCHP_I2C_PORT0 = 0, - MCHP_I2C_PORT1, - MCHP_I2C_PORT2, - MCHP_I2C_PORT3, - MCHP_I2C_PORT4, - MCHP_I2C_PORT5, - MCHP_I2C_PORT6, - MCHP_I2C_PORT7, - MCHP_I2C_PORT8, - MCHP_I2C_PORT9, - MCHP_I2C_PORT10, - MCHP_I2C_PORT11, - MCHP_I2C_PORT12, - MCHP_I2C_PORT13, - MCHP_I2C_PORT14, - MCHP_I2C_PORT15, - MCHP_I2C_PORT_COUNT, -}; - -/* I2C ports & Configs */ -#define I2C_CONTROLLER_COUNT MCHP_I2C_CTRL_MAX -#define I2C_PORT_COUNT MCHP_I2C_PORT_COUNT - -/* - * I2C controllers 0-4 implement network layer hardware. - * I2C controllers 5-7 do include network layer hardware. - * MEC152x has I2C promiscuous mode feature in the following - * additional registers. - */ -#define MCHP_I2C_SLAVE_ADDR(ctrl) REG32(MCHP_I2C_ADDR(ctrl, 0x6c)) -#define MCHP_I2C_PROM_INTR(ctrl) REG32(MCHP_I2C_ADDR(ctrl, 0x70)) -#define MCHP_I2C_PROM_INTR_EN(ctrl) REG32(MCHP_I2C_ADDR(ctrl, 0x74)) -#define MCHP_I2C_PROM_CTRL(ctrl) REG32(MCHP_I2C_ADDR(ctrl, 0x78)) - -/* All I2C controllers connected to GIRQ13 */ -#define MCHP_I2C_GIRQ 13 -/* I2C[0:7] -> GIRQ13 bits[0:7] */ -#define MCHP_I2C_GIRQ_BIT(n) BIT((n)) - -/* Keyboard scan matrix */ -#define MCHP_KS_GIRQ 21 -#define MCHP_KS_GIRQ_BIT BIT(25) -#define MCHP_KS_DIRECT_NVIC 135 - -/* ADC */ -#define MCHP_ADC_GIRQ 17 -#define MCHP_ADC_GIRQ_SINGLE_BIT BIT(8) -#define MCHP_ADC_GIRQ_REPEAT_BIT BIT(9) -#define MCHP_ADC_SINGLE_DIRECT_NVIC 78 -#define MCHP_ADC_REPEAT_DIRECT_NVIC 79 - -/* Hibernation timer */ -#define MCHP_HTIMER_SPACING 0x20 -#define MCHP_HTIMER_ADDR(n) \ - (MCHP_HTIMER_BASE + ((n) * MCHP_HTIMER_SPACING)) -#define MCHP_HTIMER_GIRQ 23 -/* HTIMER[0:1] -> GIRQ23 bits[16:17] */ -#define MCHP_HTIMER_GIRQ_BIT(n) BIT(16 + (n)) -#define MCHP_HTIMER_DIRECT_NVIC(n) (112 + (n)) - -/* - * Quad Master SPI (QMSPI) - * MEC152x implements 16 descriptors, support for two chip selects, - * and additional SPI signal timing registers. - */ -#define MCHP_QMSPI_MAX_DESCR 16 -/* - * Chip select implemented in bit[13:12] of the Mode register. - * These bits are reserved in earlier chips. - */ -#define MCHP_QMSPI_M_CS_POS 12 -#define MCHP_QMSPI_M_CS_MASK0 0x03 -#define MCHP_QMSPI_M_CS_MASK (0x03 << MCHP_QMSPI_M_CS_POS) -#define MCHP_QMSPI_M_CS0 (0x00 << MCHP_QMSPI_M_CS_POS) -#define MCHP_QMSPI_M_CS1 (0x01 << MCHP_QMSPI_M_CS_POS) - -/* New QMSPI chip select timing register */ -#define MCHP_QMSPI_CS_TIMING \ - REG32(MCHP_QMSPI0_BASE + 0x28) -#define MCHP_QMSPI_CST_DFLT_VAL 0x06060406 -#define MCHP_QMSPI_CST_ON2CLK_MASK 0x0f -#define MCHP_QMSPI_CST_ON2CLK_DFLT 0x06 -#define MCHP_QMSPI_CST_DLY_CLK2OFF_POS 8 -#define MCHP_QMSPI_CST_DLY_CLK2OFF_MASK0 0x0f -#define MCHP_QMSPI_CST_DLY_CLK2OFF_MASK 0x0f00 -#define MCHP_QMSPI_CST_DLY_CLK2OFF_DFLT 0x0400 -#define MCHP_QMSPI_CST_DLY_LDH_POS 16 -#define MCHP_QMSPI_CST_DLY_LDH_MASK0 0x0f -#define MCHP_QMSPI_CST_DLY_LDH_MASK 0xf0000 -#define MCHP_QMSPI_CST_DLY_LDH_DFLT 0x60000 -#define MCHP_QMSPI_CST_DLY_OFF2ON_POS 24 -#define MCHP_QMSPI_CST_DLY_OFF2ON_DFLT 0x06000000 -#define MCHP_QMSPI_CST_DLY_OFF2ON_MASK0 0xff -#define MCHP_QMSPI_CST_DLY_OFF2ON_MASK 0xff000000 - -#define MCHP_QMSPI_GIRQ 18 -#define MCHP_QMSPI_GIRQ_BIT BIT(1) -#define MCHP_QMSPI_DIRECT_NVIC 91 - -/* eSPI */ - -/* IO BAR defines. Use with MCHP_ESPI_IO_BAR_xxxx macros */ -#define MCHP_ESPI_IO_BAR_ID_CFG_PORT 0 -#define MCHP_ESPI_IO_BAR_ID_MEM_CMPNT 1 -#define MCHP_ESPI_IO_BAR_ID_MAILBOX 2 -#define MCHP_ESPI_IO_BAR_ID_8042 3 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC0 4 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC1 5 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC2 6 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC3 7 -#define MCHP_ESPI_IO_BAR_ID_ACPI_PM1 9 -#define MCHP_ESPI_IO_BAR_ID_P92 0xA -#define MCHP_ESPI_IO_BAR_ID_UART0 0xB -#define MCHP_ESPI_IO_BAR_ID_UART1 0xC -#define MCHP_ESPI_IO_BAR_ID_EMI0 0xD -#define MCHP_ESPI_IO_BAR_ID_EMI1 0xE -#define MCHP_ESPI_IO_BAR_P80_0 0x10 -#define MCHP_ESPI_IO_BAR_P80_1 0x11 -#define MCHP_ESPI_IO_BAR_RTC 0x12 -#define MCHP_ESPI_IO_BAR_ID_UART2 0x15 - -/* Use with MCHP_ESPI_MBAR_EC_xxxx(x) macros */ -#define MCHP_ESPI_MBAR_ID_MBOX 0 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_0 1 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_1 2 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_2 3 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_3 4 -#define MCHP_ESPI_MBAR_ID_EMI_0 6 -#define MCHP_ESPI_MBAR_ID_EMI_1 7 - -/* Use with MCHP_ESPI_IO_SERIRQ_REG(x) */ -#define MCHP_ESPI_SIRQ_MBOX 0 /* Host SIRQ */ -#define MCHP_ESPI_SIRQ_MBOX_SMI 1 /* Host SMI */ -#define MCHP_ESPI_SIRQ_8042_KB 2 /* KIRQ */ -#define MCHP_ESPI_SIRQ_8042_MS 3 /* MIRQ */ -#define MCHP_ESPI_SIRQ_ACPI_EC0_OBF 4 -#define MCHP_ESPI_SIRQ_ACPI_EC1_OBF 5 -#define MCHP_ESPI_SIRQ_ACPI_EC2_OBF 6 -#define MCHP_ESPI_SIRQ_ACPI_EC3_OBF 7 -#define MCHP_ESPI_SIRQ_UART0 9 -#define MCHP_ESPI_SIRQ_UART1 10 -#define MCHP_ESPI_SIRQ_EMI0_HEV 11 /* Host Event */ -#define MCHP_ESPI_SIRQ_EMI0_EC2H 12 /* EC to Host */ -#define MCHP_ESPI_SIRQ_EMI1_HEV 13 -#define MCHP_ESPI_SIRQ_EMI1_EC2H 14 -#define MCHP_ESPI_SIRQ_RTC 17 -#define MCHP_ESPI_SIRQ_EC 18 -#define MCHP_ESPI_SIRQ_UART2 19 - -#define MCHP_ESPI_MSVW_BASE (MCHP_ESPI_VW_BASE) -#define MCHP_ESPI_SMVW_BASE ((MCHP_ESPI_VW_BASE) + 0x200ul) - -/* - * eSPI RESET, channel enables and operations except Master-to-Slave - * WWires are all on GIRQ19 - */ -#define MCHP_ESPI_GIRQ 19 -#define MCHP_ESPI_PC_GIRQ_BIT BIT(0) -#define MCHP_ESPI_BM1_GIRQ_BIT BIT(1) -#define MCHP_ESPI_BM2_GIRQ_BIT BIT(2) -#define MCHP_ESPI_LTR_GIRQ_BIT BIT(3) -#define MCHP_ESPI_OOB_TX_GIRQ_BIT BIT(4) -#define MCHP_ESPI_OOB_RX_GIRQ_BIT BIT(5) -#define MCHP_ESPI_FC_GIRQ_BIT BIT(6) -#define MCHP_ESPI_RESET_GIRQ_BIT BIT(7) -#define MCHP_ESPI_VW_EN_GIRQ_BIT BIT(8) -#define MCHP_ESPI_SAF_DONE_GIRQ_BIT BIT(9) -#define MCHP_ESPI_SAF_ERR_GIRQ_BIT BIT(10) - -/* - * eSPI Master-to-Slave WWire interrupts are on GIRQ24 and GIRQ25 - */ -#define MCHP_ESPI_MSVW_0_6_GIRQ 24 -#define MCHP_ESPI_MSVW_7_10_GIRQ 25 -/* - * Four source bits, SRC[0:3] per Master-to-Slave register - * v = MSVW [0:10] - * n = VWire SRC bit = [0:3] - */ -#define MCHP_ESPI_MSVW_GIRQ(v) (24 + ((v) > 6 ? 1 : 0)) - -#define MCHP_ESPI_MSVW_SRC_GIRQ_BIT(v, n) \ - (((v) > 6) ? (1ul << (((v)-7)+(n))) : (1ul << ((v)+(n)))) - - -/* DMA */ -#define MCHP_DMA_MAX_CHAN 12 -#define MCHP_DMA_CH_OFS 0x40 -#define MCHP_DMA_CH_OFS_BITPOS 6 -#define MCHP_DMA_CH_BASE (MCHP_DMA_BASE + MCHP_DMA_CH_OFS) - -/* - * Available DMA channels. - * On MCHP, any DMA channel may serve any device. Since we have - * 12 channels and 12 devices request signals, we make each channel - * dedicated to the device of the same number. - */ -enum dma_channel { - /* Channel numbers */ - MCHP_DMAC_I2C0_SLAVE = 0, - MCHP_DMAC_I2C0_MASTER, - MCHP_DMAC_I2C1_SLAVE, - MCHP_DMAC_I2C1_MASTER, - MCHP_DMAC_I2C2_SLAVE, - MCHP_DMAC_I2C2_MASTER, - MCHP_DMAC_I2C3_SLAVE, - MCHP_DMAC_I2C3_MASTER, - MCHP_DMAC_I2C4_SLAVE, - MCHP_DMAC_I2C4_MASTER, - MCHP_DMAC_QMSPI0_TX, - MCHP_DMAC_QMSPI0_RX, - /* Channel count */ - MCHP_DMAC_COUNT, -}; - -/* - * Peripheral device DMA Device ID's for bits [15:9] - * in DMA channel control register. - */ -#define MCHP_DMA_I2C0_SLV_REQ_ID 0 -#define MCHP_DMA_I2C0_MTR_REQ_ID 1 -#define MCHP_DMA_I2C1_SLV_REQ_ID 2 -#define MCHP_DMA_I2C1_MTR_REQ_ID 3 -#define MCHP_DMA_I2C2_SLV_REQ_ID 4 -#define MCHP_DMA_I2C2_MTR_REQ_ID 5 -#define MCHP_DMA_I2C3_SLV_REQ_ID 6 -#define MCHP_DMA_I2C3_MTR_REQ_ID 7 -#define MCHP_DMA_I2C4_SLV_REQ_ID 8 -#define MCHP_DMA_I2C4_MTR_REQ_ID 9 -#define MCHP_DMA_QMSPI0_TX_REQ_ID 10 -#define MCHP_DMA_QMSPI0_RX_REQ_ID 11 - -/* - * Hardware delay register. - * Write of 0 <= n <= 31 will stall the Cortex-M4 - * for n+1 microseconds. Interrupts will not be - * serviced during the delay period. Reads have - * no effect. - */ -#define MCHP_USEC_DELAY_REG_ADDR 0x10000000 -#define MCHP_USEC_DELAY(x) (REG8(MCHP_USEC_DELAY_REG_ADDR) = (x)) - -#endif /* #ifndef __ASSEMBLER__ */ diff --git a/chip/mchp/registers-mec1701.h b/chip/mchp/registers-mec1701.h deleted file mode 100644 index bfe012a0d8..0000000000 --- a/chip/mchp/registers-mec1701.h +++ /dev/null @@ -1,1350 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Register map for Microchip MEC170x family controllers - */ - -#ifndef __CROS_EC_REGISTERS_H -#error "This header file should not be included directly." -#endif - -/* - * IRQ Numbers - * NOTE: GIRQ22 aggregated output and its sources are not connected to - * the NVIC. - */ -#define MCHP_IRQ_GIRQ8 0 -#define MCHP_IRQ_GIRQ9 1 -#define MCHP_IRQ_GIRQ10 2 -#define MCHP_IRQ_GIRQ11 3 -#define MCHP_IRQ_GIRQ12 4 -#define MCHP_IRQ_GIRQ13 5 -#define MCHP_IRQ_GIRQ14 6 -#define MCHP_IRQ_GIRQ15 7 -#define MCHP_IRQ_GIRQ16 8 -#define MCHP_IRQ_GIRQ17 9 -#define MCHP_IRQ_GIRQ18 10 -#define MCHP_IRQ_GIRQ19 11 -#define MCHP_IRQ_GIRQ20 12 -#define MCHP_IRQ_GIRQ21 13 -#define MCHP_IRQ_GIRQ23 14 -#define MCHP_IRQ_GIRQ24 15 -#define MCHP_IRQ_GIRQ25 16 -#define MCHP_IRQ_GIRQ26 17 -/* GIRQ13 direct sources */ -#define MCHP_IRQ_I2C_0 20 -#define MCHP_IRQ_I2C_1 21 -#define MCHP_IRQ_I2C_2 22 -#define MCHP_IRQ_I2C_3 23 -/* GIRQ14 direct sources */ -#define MCHP_IRQ_DMA_0 24 -#define MCHP_IRQ_DMA_1 25 -#define MCHP_IRQ_DMA_2 26 -#define MCHP_IRQ_DMA_3 27 -#define MCHP_IRQ_DMA_4 28 -#define MCHP_IRQ_DMA_5 29 -#define MCHP_IRQ_DMA_6 30 -#define MCHP_IRQ_DMA_7 31 -#define MCHP_IRQ_DMA_8 32 -#define MCHP_IRQ_DMA_9 33 -#define MCHP_IRQ_DMA_10 34 -#define MCHP_IRQ_DMA_11 35 -#define MCHP_IRQ_DMA_12 36 -#define MCHP_IRQ_DMA_13 37 -/* GIRQ15 direct sources */ -#define MCHP_IRQ_UART0 40 -#define MCHP_IRQ_UART1 41 -#define MCHP_IRQ_EMI0 42 -#define MCHP_IRQ_EMI1 43 -#define MCHP_IRQ_EMI2 44 -#define MCHP_IRQ_ACPIEC0_IBF 45 -#define MCHP_IRQ_ACPIEC0_OBE 46 -#define MCHP_IRQ_ACPIEC1_IBF 47 -#define MCHP_IRQ_ACPIEC1_OBE 48 -#define MCHP_IRQ_ACPIEC2_IBF 49 -#define MCHP_IRQ_ACPIEC2_OBE 50 -#define MCHP_IRQ_ACPIEC3_IBF 51 -#define MCHP_IRQ_ACPIEC3_OBE 52 -#define MCHP_IRQ_ACPIEC4_IBF 53 -#define MCHP_IRQ_ACPIEC4_OBE 54 -#define MCHP_IRQ_ACPIPM1_CTL 55 -#define MCHP_IRQ_ACPIPM1_EN 56 -#define MCHP_IRQ_ACPIPM1_STS 57 -#define MCHP_IRQ_8042EM_OBE 58 -#define MCHP_IRQ_8042EM_IBF 59 -#define MCHP_IRQ_MAILBOX_DATA 60 -#define MCHP_IRQ_PORT80DBG0 62 -#define MCHP_IRQ_PORT80DBG1 63 -/* GIRQ16 direct sources */ -#define MCHP_IRQ_PKE_ERR 65 -#define MCHP_IRQ_PKE_END 66 -#define MCHP_IRQ_NDRNG 67 -#define MCHP_IRQ_AES 68 -#define MCHP_IRQ_HASH 69 -/* GIRQ17 direct sources */ -#define MCHP_IRQ_PECI_HOST 70 -#define MCHP_IRQ_TACH_0 71 -#define MCHP_IRQ_TACH_1 72 -#define MCHP_IRQ_TACH_2 73 -#define MCHP_IRQ_FAN0_FAIL 74 -#define MCHP_IRQ_FAN0_STALL 75 -#define MCHP_IRQ_FAN1_FAIL 76 -#define MCHP_IRQ_FAN1_STALL 77 -#define MCHP_IRQ_ADC_SNGL 78 -#define MCHP_IRQ_ADC_RPT 79 -#define MCHP_IRQ_RCID0 80 -#define MCHP_IRQ_RCID1 81 -#define MCHP_IRQ_RCID2 82 -#define MCHP_IRQ_LED0_WDT 83 -#define MCHP_IRQ_LED1_WDT 84 -#define MCHP_IRQ_LED2_WDT 85 -#define MCHP_IRQ_LED3_WDT 86 -#define MCHP_IRQ_PHOT 87 -#define MCHP_IRQ_PWRGRD0 88 -#define MCHP_IRQ_PWRGRD1 89 -/* GIRQ18 direct sources */ -#define MCHP_IRQ_LPC 90 -#define MCHP_IRQ_QMSPI0 91 -#define MCHP_IRQ_SPI0_TX 92 -#define MCHP_IRQ_SPI0_RX 93 -#define MCHP_IRQ_SPI1_TX 94 -#define MCHP_IRQ_SPI1_RX 95 -#define MCHP_IRQ_BCM0_ERR 96 -#define MCHP_IRQ_BCM0_BUSY 97 -#define MCHP_IRQ_BCM1_ERR 98 -#define MCHP_IRQ_BCM1_BUSY 99 -#define MCHP_IRQ_PS2_0 100 -#define MCHP_IRQ_PS2_1 101 -#define MCHP_IRQ_PS2_2 102 -#define MCHP_IRQ_EEPROM 155 -/* GIRQ19 direct sources */ -#define MCHP_IRQ_ESPI_PC 103 -#define MCHP_IRQ_ESPI_BM1 104 -#define MCHP_IRQ_ESPI_BM2 105 -#define MCHP_IRQ_ESPI_LTR 106 -#define MCHP_IRQ_ESPI_OOB_UP 107 -#define MCHP_IRQ_ESPI_OOB_DN 108 -#define MCHP_IRQ_ESPI_FC 109 -#define MCHP_IRQ_ESPI_RESET 110 -#define MCHP_IRQ_ESPI_VW_EN 156 -/* GIRQ21 direct sources */ -#define MCHP_IRQ_RTOS_TIMER 111 -#define MCHP_IRQ_HTIMER0 112 -#define MCHP_IRQ_HTIMER1 113 -#define MCHP_IRQ_WEEK_ALARM 114 -#define MCHP_IRQ_SUBWEEK 115 -#define MCHP_IRQ_WEEK_SEC 116 -#define MCHP_IRQ_WEEK_SUBSEC 117 -#define MCHP_IRQ_WEEK_SYSPWR 118 -#define MCHP_IRQ_RTC 119 -#define MCHP_IRQ_RTC_ALARM 120 -#define MCHP_IRQ_VCI_OVRD_IN 121 -#define MCHP_IRQ_VCI_IN0 122 -#define MCHP_IRQ_VCI_IN1 123 -#define MCHP_IRQ_VCI_IN2 124 -#define MCHP_IRQ_VCI_IN3 125 -#define MCHP_IRQ_VCI_IN4 126 -#define MCHP_IRQ_VCI_IN5 127 -#define MCHP_IRQ_VCI_IN6 128 -#define MCHP_IRQ_PS20A_WAKE 129 -#define MCHP_IRQ_PS20B_WAKE 130 -#define MCHP_IRQ_PS21A_WAKE 131 -#define MCHP_IRQ_PS21B_WAKE 132 -#define MCHP_IRQ_PS2_2_WAKE 133 -#define MCHP_IRQ_ENVMON 134 -#define MCHP_IRQ_KSC_INT 135 -/* GIRQ23 direct sources */ -#define MCHP_IRQ_TIMER16_0 136 -#define MCHP_IRQ_TIMER16_1 137 -#define MCHP_IRQ_TIMER16_2 138 -#define MCHP_IRQ_TIMER16_3 139 -#define MCHP_IRQ_TIMER32_0 140 -#define MCHP_IRQ_TIMER32_1 141 -#define MCHP_IRQ_CNTR_TM0 142 -#define MCHP_IRQ_CNTR_TM1 143 -#define MCHP_IRQ_CNTR_TM2 144 -#define MCHP_IRQ_CNTR_TM3 145 -#define MCHP_IRQ_CCT_TMR 146 -#define MCHP_IRQ_CCT_CAP0 147 -#define MCHP_IRQ_CCT_CAP1 148 -#define MCHP_IRQ_CCT_CAP2 149 -#define MCHP_IRQ_CCT_CAP3 150 -#define MCHP_IRQ_CCT_CAP4 151 -#define MCHP_IRQ_CCT_CAP5 152 -#define MCHP_IRQ_CCT_CMP0 153 -#define MCHP_IRQ_CCT_CMP1 154 -/* Must match CONFIG_IRQ_COUNT in config_chip.h */ -#define MCHP_IRQ_MAX 157 - -/* Block base addresses */ -#define MCHP_WDG_BASE 0x40000000 -#define MCHP_TMR16_0_BASE 0x40000c00 -#define MCHP_TMR32_0_BASE 0x40000c80 -#define MCHP_CNT16_0_BASE 0x40000d00 -#define MCHP_DMA_BASE 0x40002400 -#define MCHP_PROCHOT_BASE 0x40003400 -#define MCHP_I2C0_BASE 0x40004000 -#define MCHP_I2C1_BASE 0x40004400 -#define MCHP_I2C2_BASE 0x40004800 -#define MCHP_I2C3_BASE 0x40004C00 -#define MCHP_QMSPI0_BASE 0x40005400 -#define MCHP_PWM_0_BASE 0x40005800 -#define MCHP_TACH_0_BASE 0x40006000 -#define MCHP_PECI_BASE 0x40006400 -#define MCHP_RTMR_BASE 0x40007400 -#define MCHP_ADC_BASE 0x40007c00 -#define MCHP_TFDP_BASE 0x40008c00 -#define MCHP_GPSPI0_BASE 0x40009400 -#define MCHP_GPSPI1_BASE 0x40009480 -#define MCHP_HTIMER_BASE 0x40009800 -#define MCHP_KEYSCAN_BASE 0x40009c00 -#define MCHP_RPM2PWM0_BASE 0x4000a000 -#define MCHP_RPM2PWM1_BASE 0x4000a080 -#define MCHP_VBAT_BASE 0x4000a400 -#define MCHP_VBAT_RAM_BASE 0x4000a800 -#define MCHP_WKTIMER_BASE 0x4000ac80 -#define MCHP_BBLED_0_BASE 0x4000B800 -#define MCHP_INT_BASE 0x4000e000 -#define MCHP_EC_BASE 0x4000fc00 - -#define MCHP_PCR_BASE 0x40080100 -#define MCHP_GPIO_BASE 0x40081000 - -#define MCHP_MBOX_BASE 0x400f0000 -#define MCHP_8042_BASE 0x400f0400 -#define MCHP_ACPI_EC_0_BASE 0x400f0800 -#define MCHP_ACPI_PM1_BASE 0x400f1c00 -#define MCHP_UART0_BASE 0x400f2400 -#define MCHP_UART1_BASE 0x400f2800 -#define MCHP_LPC_BASE 0x400f3000 -#define MCHP_ESPI_IO_BASE 0x400f3400 -#define MCHP_ESPI_MEM_BASE 0x400f3800 -#define MCHP_EMI_0_BASE 0x400f4000 -#define MCHP_EMI_1_BASE 0x400f4400 -#define MCHP_EMI_2_BASE 0x400f4800 -#define MCHP_P80CAP0_BASE 0x400f8000 -#define MCHP_P80CAP1_BASE 0x400f8400 -#define MCHP_ESPI_VW_BASE 0x400f9c00 -#define MCHP_CHIP_BASE 0x400fff00 - -#ifndef __ASSEMBLER__ - -/* - * Helper function for RAM address aliasing - * NOTE: MCHP AHB masters do NOT require aliasing. - * Cortex-M4 bit-banding does require aliasing of the - * DATA SRAM region. - */ -#define MCHP_RAM_ALIAS(x) \ - ((x) >= 0x118000 ? (x) - 0x118000 + 0x20000000 : (x)) - -/* EC Chip Configuration */ -/* 8-bit Device ID */ -#define MCHP_CHIP_DEV_ID REG8(MCHP_CHIP_BASE + 0x20) -/* 8-bit Device Revision */ -#define MCHP_CHIP_DEV_REV REG8(MCHP_CHIP_BASE + 0x21) - -/* PCR clock control dividers */ -#define MCHP_PCR_CLK_CTL_FASTEST 1U -#define MCHP_PCR_CLK_CTL_48MHZ 1U -#define MCHP_PCR_CLK_CTL_12MHZ 4U - -/* Number of PCR Sleep Enable, Clock Required, and Reset registers */ -#define MCHP_PCR_SLP_RST_REG_MAX 5 - -/* Sleep 0: Sleep Enable, Clock Required, and Reset bits */ -#define MCHP_PCR_JTAG BIT(0) /* CLKREQ only */ -#define MCHP_PCR_OTP BIT(1) -#define MCHP_PCR_ISPI BIT(2) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN0_JTAG BIT(0) -#define MCHP_PCR_SLP_EN0_OTP BIT(1) -#define MCHP_PCR_SLP_EN0_ISPI BIT(2) -#define MCHP_PCR_SLP_EN0_SLEEP 0xffffffff - -/* - * Encode register number and bit position - * b[4:0] = bit number - * b[10:8] = zero based register number - */ -#define MCHP_PCR_ERB(rnum, bnum) \ - ((((rnum) & 0x0f) << 8) | ((bnum) & 0x1f)) - -/* PCR Sleep 1: Sleep Enable, Clock Required, and Reset bits */ -#define MCHP_PCR_BTMR16_1 MCHP_PCR_ERB(1, 31) -#define MCHP_PCR_BTMR16_0 MCHP_PCR_ERB(1, 30) -#define MCHP_PCR_ECS MCHP_PCR_ERB(1, 29) -#define MCHP_PCR_PWM8 MCHP_PCR_ERB(1, 27) -#define MCHP_PCR_PWM7 MCHP_PCR_ERB(1, 26) -#define MCHP_PCR_PWM6 MCHP_PCR_ERB(1, 25) -#define MCHP_PCR_PWM5 MCHP_PCR_ERB(1, 24) -#define MCHP_PCR_PWM4 MCHP_PCR_ERB(1, 23) -#define MCHP_PCR_PWM3 MCHP_PCR_ERB(1, 22) -#define MCHP_PCR_PWM2 MCHP_PCR_ERB(1, 21) -#define MCHP_PCR_PWM1 MCHP_PCR_ERB(1, 20) -#define MCHP_PCR_TACH2 MCHP_PCR_ERB(1, 12) -#define MCHP_PCR_TACH1 MCHP_PCR_ERB(1, 11) -#define MCHP_PCR_I2C0 MCHP_PCR_ERB(1, 10) -#define MCHP_PCR_WDT MCHP_PCR_ERB(1, 9) -#define MCHP_PCR_CPU MCHP_PCR_ERB(1, 8) -#define MCHP_PCR_TFDP MCHP_PCR_ERB(1, 7) -#define MCHP_PCR_DMA MCHP_PCR_ERB(1, 6) -#define MCHP_PCR_PMC MCHP_PCR_ERB(1, 5) -#define MCHP_PCR_PWM0 MCHP_PCR_ERB(1, 4) -#define MCHP_PCR_TACH0 MCHP_PCR_ERB(1, 2) -#define MCHP_PCR_PECI MCHP_PCR_ERB(1, 1) -#define MCHP_PCR_ECIA MCHP_PCR_ERB(1, 0) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN1_BTMR16_1 BIT(31) -#define MCHP_PCR_SLP_EN1_BTMR16_0 BIT(30) -#define MCHP_PCR_SLP_EN1_ECS BIT(29) -#define MCHP_PCR_SLP_EN1_PWM_ALL (BIT(4) + (0xff << 20)) -#define MCHP_PCR_SLP_EN1_PWM8 BIT(27) -#define MCHP_PCR_SLP_EN1_PWM7 BIT(26) -#define MCHP_PCR_SLP_EN1_PWM6 BIT(25) -#define MCHP_PCR_SLP_EN1_PWM5 BIT(24) -#define MCHP_PCR_SLP_EN1_PWM4 BIT(23) -#define MCHP_PCR_SLP_EN1_PWM3 BIT(22) -#define MCHP_PCR_SLP_EN1_PWM2 BIT(21) -#define MCHP_PCR_SLP_EN1_PWM1 BIT(20) -#define MCHP_PCR_SLP_EN1_TACH2 BIT(12) -#define MCHP_PCR_SLP_EN1_TACH1 BIT(11) -#define MCHP_PCR_SLP_EN1_I2C0 BIT(10) -#define MCHP_PCR_SLP_EN1_WDT BIT(9) -#define MCHP_PCR_SLP_EN1_CPU BIT(8) -#define MCHP_PCR_SLP_EN1_TFDP BIT(7) -#define MCHP_PCR_SLP_EN1_DMA BIT(6) -#define MCHP_PCR_SLP_EN1_PMC BIT(5) -#define MCHP_PCR_SLP_EN1_PWM0 BIT(4) -#define MCHP_PCR_SLP_EN1_TACH0 BIT(2) -#define MCHP_PCR_SLP_EN1_PECI BIT(1) -#define MCHP_PCR_SLP_EN1_ECIA BIT(0) -/* all sleep enable 1 bits */ -#define MCHP_PCR_SLP_EN1_SLEEP 0xffffffff -/* - * block not used by default - * Do not sleep ECIA, PMC, CPU and ECS - */ -#define MCHP_PCR_SLP_EN1_UNUSED_BLOCKS 0xdffffede - -/* PCR Sleep 2: Sleep Enable, Clock Required 2, Reset bits */ -#define MCHP_PCR_P80CAP1 MCHP_PCR_ERB(2, 26) -#define MCHP_PCR_P80CAP0 MCHP_PCR_ERB(2, 25) -#define MCHP_PCR_ACPI_EC4 MCHP_PCR_ERB(2, 23) -#define MCHP_PCR_ACPI_EC3 MCHP_PCR_ERB(2, 22) -#define MCHP_PCR_ACPI_EC2 MCHP_PCR_ERB(2, 21) -#define MCHP_PCR_ESPI MCHP_PCR_ERB(2, 19) -#define MCHP_PCR_RTC MCHP_PCR_ERB(2, 18) -#define MCHP_PCR_MBOX MCHP_PCR_ERB(2, 17) -#define MCHP_PCR_8042 MCHP_PCR_ERB(2, 26) -#define MCHP_PCR_ACPI_PM1 MCHP_PCR_ERB(2, 15) -#define MCHP_PCR_ACPI_EC1 MCHP_PCR_ERB(2, 14) -#define MCHP_PCR_ACPI_EC0 MCHP_PCR_ERB(2, 13) -#define MCHP_PCR_GCFG MCHP_PCR_ERB(2, 12) -#define MCHP_PCR_UART1 MCHP_PCR_ERB(2, 2) -#define MCHP_PCR_UART0 MCHP_PCR_ERB(2, 1) -#define MCHP_PCR_LPC MCHP_PCR_ERB(2, 0) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN2_P80CAP1 BIT(26) -#define MCHP_PCR_SLP_EN2_P80CAP0 BIT(25) -#define MCHP_PCR_SLP_EN2_ACPI_EC4 BIT(23) -#define MCHP_PCR_SLP_EN2_ACPI_EC3 BIT(22) -#define MCHP_PCR_SLP_EN2_ACPI_EC2 BIT(21) -#define MCHP_PCR_SLP_EN2_ESPI_SCR BIT(20) -#define MCHP_PCR_SLP_EN2_ESPI BIT(19) -#define MCHP_PCR_SLP_EN2_RTC BIT(18) -#define MCHP_PCR_SLP_EN2_MAILBOX BIT(17) -#define MCHP_PCR_SLP_EN2_MIF8042 BIT(16) -#define MCHP_PCR_SLP_EN2_ACPI_PM1 BIT(15) -#define MCHP_PCR_SLP_EN2_ACPI_EC1 BIT(14) -#define MCHP_PCR_SLP_EN2_ACPI_EC0 BIT(13) -#define MCHP_PCR_SLP_EN2_GCFG BIT(12) -#define MCHP_PCR_SLP_EN2_UART1 BIT(2) -#define MCHP_PCR_SLP_EN2_UART0 BIT(1) -#define MCHP_PCR_SLP_EN2_LPC BIT(0) -/* all sleep enable 2 bits */ -#define MCHP_PCR_SLP_EN2_SLEEP 0xffffffff - -/* PCR Sleep 3: Sleep Enable, Clock Required, and Reset */ -#define MCHP_PCR_PWM9 MCHP_PCR_ERB(3, 31) -#define MCHP_PCR_CCT0 MCHP_PCR_ERB(3, 30) -#define MCHP_PCR_HTMR1 MCHP_PCR_ERB(3, 29) -#define MCHP_PCR_AESHASH MCHP_PCR_ERB(3, 28) -#define MCHP_PCR_RNG MCHP_PCR_ERB(3, 27) -#define MCHP_PCR_PKE MCHP_PCR_ERB(3, 26) -#define MCHP_PCR_LED3 MCHP_PCR_ERB(3, 25) -#define MCHP_PCR_BTMR32_1 MCHP_PCR_ERB(3, 24) -#define MCHP_PCR_BTMR32_0 MCHP_PCR_ERB(3, 23) -#define MCHP_PCR_BTMR16_3 MCHP_PCR_ERB(3, 22) -#define MCHP_PCR_BTMR16_2 MCHP_PCR_ERB(3, 21) -#define MCHP_PCR_GPSPI1 MCHP_PCR_ERB(3, 20) -#define MCHP_PCR_BCM0 MCHP_PCR_ERB(3, 19) -#define MCHP_PCR_LED2 MCHP_PCR_ERB(3, 18) -#define MCHP_PCR_LED1 MCHP_PCR_ERB(3, 17) -#define MCHP_PCR_LED0 MCHP_PCR_ERB(3, 16) -#define MCHP_PCR_I2C3 MCHP_PCR_ERB(3, 15) -#define MCHP_PCR_I2C2 MCHP_PCR_ERB(3, 14) -#define MCHP_PCR_I2C1 MCHP_PCR_ERB(3, 13) -#define MCHP_PCR_RPMPWM0 MCHP_PCR_ERB(3, 12) -#define MCHP_PCR_KEYSCAN MCHP_PCR_ERB(3, 11) -#define MCHP_PCR_HTMR0 MCHP_PCR_ERB(3, 10) -#define MCHP_PCR_GPSPI0 MCHP_PCR_ERB(3, 9) -#define MCHP_PCR_PS2_2 MCHP_PCR_ERB(3, 7) -#define MCHP_PCR_PS2_1 MCHP_PCR_ERB(3, 6) -#define MCHP_PCR_PS2_0 MCHP_PCR_ERB(3, 5) -#define MCHP_PCR_ADC MCHP_PCR_ERB(3, 3) - -/* Command blocks to sleep */ -#define MCHP_PCR_SLP_EN3_PWM9 BIT(31) -#define MCHP_PCR_SLP_EN3_CCT0 BIT(30) -#define MCHP_PCR_SLP_EN3_HTMR1 BIT(29) -#define MCHP_PCR_SLP_EN3_AESHASH BIT(28) -#define MCHP_PCR_SLP_EN3_RNG BIT(27) -#define MCHP_PCR_SLP_EN3_PKE BIT(26) -#define MCHP_PCR_SLP_EN3_LED3 BIT(25) -#define MCHP_PCR_SLP_EN3_BTMR32_1 BIT(24) -#define MCHP_PCR_SLP_EN3_BTMR32_0 BIT(23) -#define MCHP_PCR_SLP_EN3_BTMR16_3 BIT(22) -#define MCHP_PCR_SLP_EN3_BTMR16_2 BIT(21) -#define MCHP_PCR_SLP_EN3_I2C4 BIT(20) -#define MCHP_PCR_SLP_EN3_BCM0 BIT(19) -#define MCHP_PCR_SLP_EN3_LED2 BIT(18) -#define MCHP_PCR_SLP_EN3_LED1 BIT(17) -#define MCHP_PCR_SLP_EN3_LED0 BIT(16) -#define MCHP_PCR_SLP_EN3_I2C3 BIT(15) -#define MCHP_PCR_SLP_EN3_I2C2 BIT(14) -#define MCHP_PCR_SLP_EN3_I2C1 BIT(13) -#define MCHP_PCR_SLP_EN3_RPM2PWM0 BIT(12) -#define MCHP_PCR_SLP_EN3_KEYSCAN BIT(11) -#define MCHP_PCR_SLP_EN3_HTMR0 BIT(10) -#define MCHP_PCR_SLP_EN3_GPSPI0 BIT(9) -#define MCHP_PCR_SLP_EN3_PS2_2 BIT(7) -#define MCHP_PCR_SLP_EN3_PS2_1 BIT(6) -#define MCHP_PCR_SLP_EN3_PS2_0 BIT(5) -#define MCHP_PCR_SLP_EN3_ADC BIT(3) -#define MCHP_PCR_SLP_EN3_ALL_CRYPTO (0x07 << 26) -/* all sleep enable 3 bits */ -#define MCHP_PCR_SLP_EN3_SLEEP 0xffffffff -#define MCHP_PCR_SLP_EN3_PWM_ALL (MCHP_PCR_SLP_EN3_PWM9) - -/* PCR Sleep 4: Sleep Enable, Clock Required, Reset */ -#define MCHP_PCR_FJCL MCHP_PCR_ERB(4, 15) -#define MCHP_PCR_PSPI MCHP_PCR_ERB(4, 14) -#define MCHP_PCR_PROCHOT MCHP_PCR_ERB(4, 13) -#define MCHP_PCR_RCID2 MCHP_PCR_ERB(4, 12) -#define MCHP_PCR_RCID1 MCHP_PCR_ERB(4, 11) -#define MCHP_PCR_RCID0 MCHP_PCR_ERB(4, 10) -#define MCHP_PCR_BCM1 MCHP_PCR_ERB(4, 9) -#define MCHP_PCR_QMSPI MCHP_PCR_ERB(4, 8) -#define MCHP_PCR_RPMPWM1 MCHP_PCR_ERB(4, 7) -#define MCHP_PCR_RTMR MCHP_PCR_ERB(4, 6) -#define MCHP_PCR_CNT16_3 MCHP_PCR_ERB(4, 5) -#define MCHP_PCR_CNT16_2 MCHP_PCR_ERB(4, 4) -#define MCHP_PCR_CNT16_1 MCHP_PCR_ERB(4, 3) -#define MCHP_PCR_CNT16_0 MCHP_PCR_ERB(4, 2) -#define MCHP_PCR_PWM11 MCHP_PCR_ERB(4, 1) -#define MCHP_PCR_PWM10 MCHP_PCR_ERB(4, 0) - -/* Command blocks to sleep */ -#define MCHP_PCR_SLP_EN4_FJCL BIT(15) -#define MCHP_PCR_SLP_EN4_PSPI BIT(14) -#define MCHP_PCR_SLP_EN4_PROCHOT BIT(13) -#define MCHP_PCR_SLP_EN4_RCID2 BIT(12) -#define MCHP_PCR_SLP_EN4_RCID1 BIT(11) -#define MCHP_PCR_SLP_EN4_RCID0 BIT(10) -#define MCHP_PCR_SLP_EN4_QMSPI BIT(8) -#define MCHP_PCR_SLP_EN4_RPMPWM1 BIT(7) -#define MCHP_PCR_SLP_EN4_RTMR BIT(6) -#define MCHP_PCR_SLP_EN4_CNT16_3 BIT(5) -#define MCHP_PCR_SLP_EN4_CNT16_2 BIT(4) -#define MCHP_PCR_SLP_EN4_CNT16_1 BIT(3) -#define MCHP_PCR_SLP_EN4_CNT16_0 BIT(2) -#define MCHP_PCR_SLP_EN4_PWM11 BIT(1) -#define MCHP_PCR_SLP_EN4_PWM10 BIT(0) - -/* all sleep enable 4 bits */ -#define MCHP_PCR_SLP_EN4_SLEEP 0xffffffff -#define MCHP_PCR_SLP_EN4_PWM_ALL \ - (MCHP_PCR_SLP_EN4_PWM10 | MCHP_PCR_SLP_EN4_PWM11) - -/* Allow all blocks to request clocks */ -#define MCHP_PCR_SLP_EN0_WAKE (~(MCHP_PCR_SLP_EN0_SLEEP)) -#define MCHP_PCR_SLP_EN1_WAKE (~(MCHP_PCR_SLP_EN1_SLEEP)) -#define MCHP_PCR_SLP_EN2_WAKE (~(MCHP_PCR_SLP_EN2_SLEEP)) -#define MCHP_PCR_SLP_EN3_WAKE (~(MCHP_PCR_SLP_EN3_SLEEP)) -#define MCHP_PCR_SLP_EN4_WAKE (~(MCHP_PCR_SLP_EN4_SLEEP)) - -/* Bit defines for MCHP_PCR_PWR_RST_STS */ -#define MCHP_PWR_RST_STS_MASK_RO 0xc8c -#define MCHP_PWR_RST_STS_MASK_RWC 0x060 -#define MCHP_PWR_RST_STS_MASK \ - ((MCHP_PWR_RST_STS_MASK_RO) | (MCHP_PWR_RST_STS_MASK_RWC)) - -#define MCHP_PWR_RST_STS_ESPI_CLK_ACT BIT(11) /* RO */ -#define MCHP_PWR_RST_STS_32K_ACT BIT(10) /* RO */ -#define MCHP_PWR_RST_STS_JTAG_RSTN BIT(7) /* RO */ -#define MCHP_PWR_RST_STS_SYS BIT(6) /* R/WC */ -/* same function, old bit name */ -#define MCHP_PWR_RST_STS_VTR BIT(6) -#define MCHP_PWR_RST_STS_VBAT BIT(5) /* R/WC */ -#define MCHP_PWR_RST_STS_HOST BIT(3) /* RO */ -#define MCHP_PWR_RST_STS_VCC_PWRGD BIT(2) /* RO */ - -/* Bit defines for MCHP_PCR_PWR_RST_CTL */ -#define MCHP_PCR_PWR_HOST_RST_SEL_BITPOS 8 -#define MCHP_PCR_PWR_HOST_RST_PCI_RESET BIT(8) -#define MCHP_PCR_PWR_HOST_RST_ESPI_PLTRST (0 << 8) -#define MCHP_PCR_PWR_OK_INV_BITPOS 0 - -/* Bit defines for MCHP_PCR_SYS_RST */ -#define MCHP_PCR_SYS_SOFT_RESET BIT(8) - -/* EC Subsystem */ -#define MCHP_EC_AHB_ERR REG32(MCHP_EC_BASE + 0x04) -#define MCHP_EC_ID_RO REG32(MCHP_EC_BASE + 0x10) -#define MCHP_EC_AHB_ERR_EN REG32(MCHP_EC_BASE + 0x14) -#define MCHP_EC_INT_CTRL REG32(MCHP_EC_BASE + 0x18) -#define MCHP_EC_TRACE_EN REG32(MCHP_EC_BASE + 0x1c) -#define MCHP_EC_JTAG_EN REG32(MCHP_EC_BASE + 0x20) -#define MCHP_EC_WDT_CNT REG32(MCHP_EC_BASE + 0x28) -#define MCHP_EC_AES_SHA_SWAP_CTRL REG8(MCHP_EC_BASE + 0x2c) -#define MCHP_EC_PECI_DISABLE REG8(MCHP_EC_BASE + 0x40) -#define MCHP_EC_CRYPTO_SRESET REG8(MCHP_EC_BASE + 0x5c) -#define MCHP_EC_GPIO_BANK_PWR REG8(MCHP_EC_BASE + 0x64) - -/* AHB ERR Enable bit[0]=0(enable), 1(disable) */ -#define MCHP_EC_AHB_ERROR_ENABLE 0 -#define MCHP_EC_AHB_ERROR_DISABLE 1 - -/* MCHP_EC_JTAG_EN bit definitions */ -#define MCHP_JTAG_ENABLE 0x01 -/* bits [2:1] */ -#define MCHP_JTAG_MODE_4PIN 0x00 -/* ARM 2-pin SWD plus 1-pin Serial Wire Viewer (ITM) */ -#define MCHP_JTAG_MODE_SWD_SWV 0x02 -/* ARM 2-pin SWD with no SWV */ -#define MCHP_JTAG_MODE_SWD 0x04 - -/* MCHP_EC_CRYPTO_SRESET bit definitions. Bits cleared by HW */ -#define MCHP_CRYPTO_NDRNG_SRST 0x01 -#define MCHP_CRYPTO_PKE_SRST 0x02 -#define MCHP_CRYPTO_AES_SHA_SRST 0x04 -#define MCHP_CRYPTO_ALL_SRST 0x07 - -/* MCHP_GPIO_BANK_PWR bit definitions */ -#define MCHP_EC_GPIO_BANK_PWR_MASK 0x86 -#define MCHP_EC_GPIO_BANK_PWR_VTR2_18 0x02 -#define MCHP_EC_GPIO_BANK_PWR_VTR3_18 0x04 -#define MCHP_EC_GPIO_BANK_PWR_LOCK 0x80 - -/* EC Interrupt aggregator (ECIA) */ -#define MCHP_INT_GIRQ_LEN 20 /* 5 32-bit registers */ -#define MCHP_INT_GIRQ_FIRST 8 -#define MCHP_INT_GIRQ_LAST 26 -#define MCHP_INT_GIRQ_NUM (26-8+1) -/* MCHP_INT_GIRQ_FIRST <= x <= MCHP_INT_GIRQ_LAST */ -#define MCHP_INTx_BASE(x) (MCHP_INT_BASE + (((x) - 8) * MCHP_INT_GIRQ_LEN)) - -/* - * GPIO GIRQ's are not direct capable - * GIRQ08 GPIO 0140 - 0176 - * GIRQ09 GPIO 0100 - 0136 - * GIRQ10 GPIO 040 - 076 - * GIRQ11 GPIO 000 - 036 - * GIRQ12 GPIO 0200 - 0236 - * GIRQ26 GPIO 0240 - 0276 - * Other GIRQ's not direct capable: - * GIRQ22 wake peripheral clock only - * GIRQ24, GIRQ25 eSPI host to endpoint virtual wires - */ -#define MCHP_INT_AGGR_ONLY_BITMAP 0x07401F00U -#define MCHP_INT_DIRECT_CAPABLE_BITMAP 0x00BFE000U - -/* GIRQ13 I2C controllers. Direct capable */ -#define MCHP_INT13_I2C(x) (1ul << (x)) - -/* GIRQ14 DMA channels 0 - 13. Direct capable */ -#define MCHP_INT14_DMA(x) (1ul << (x)) - -/* GIQ15 interrupt sources. Direct capable */ -#define MCHP_INT15_UART_0 BIT(0) -#define MCHP_INT15_UART_1 BIT(1) -#define MCHP_INT15_EMI_0 BIT(2) -#define MCHP_INT15_EMI_1 BIT(3) -#define MCHP_INT15_EMI_2 BIT(4) -#define MCHP_INT15_ACPI_EC0_IBF BIT(5) -#define MCHP_INT15_ACPI_EC0_OBE BIT(6) -#define MCHP_INT15_ACPI_EC1_IBF BIT(7) -#define MCHP_INT15_ACPI_EC1_OBE BIT(8) -#define MCHP_INT15_ACPI_EC2_IBF BIT(9) -#define MCHP_INT15_ACPI_EC2_OBE BIT(10) -#define MCHP_INT15_ACPI_EC3_IBF BIT(11) -#define MCHP_INT15_ACPI_EC3_OBE BIT(12) -#define MCHP_INT15_ACPI_EC4_IBF BIT(13) -#define MCHP_INT15_ACPI_EC4_OBE BIT(14) -#define MCHP_INT15_ACPI_PM1_CTL BIT(15) -#define MCHP_INT15_ACPI_PM1_EN BIT(16) -#define MCHP_INT15_ACPI_PM1_STS BIT(17) -#define MCHP_INT15_8042_OBE BIT(18) -#define MCHP_INT15_8042_IBF BIT(19) -#define MCHP_INT15_MAILBOX BIT(20) -#define MCHP_INT15_P80_0 BIT(22) -#define MCHP_INT15_P80_1 BIT(23) -#define MCHP_INT15_P80(x) BIT(22 + ((x) & 0x01U)) - -/* GIRQ16 interrupt sources. Direct capable */ -#define MCHP_INT16_PKE_ERR BIT(0) -#define MCHP_INT16_PKE_DONE BIT(1) -#define MCHP_INT16_RNG_DONE BIT(2) -#define MCHP_INT16_AES_DONE BIT(3) -#define MCHP_INT16_HASH_DONE BIT(4) - -/* GIR17 interrupt sources. Direct capable */ -#define MCHP_INT17_PECI BIT(0) -#define MCHP_INT17_TACH_0 BIT(1) -#define MCHP_INT17_TACH_1 BIT(2) -#define MCHP_INT17_TACH_2 BIT(3) -#define MCHP_INT17_RPM2PWM0_FAIL BIT(4) -#define MCHP_INT17_RPM2PWM0_STALL BIT(5) -#define MCHP_INT17_RPM2PWM1_FAIL BIT(6) -#define MCHP_INT17_RPM2PWM1_STALL BIT(7) -#define MCHP_INT17_ADC_SINGLE BIT(8) -#define MCHP_INT17_ADC_REPEAT BIT(9) -#define MCHP_INT17_RCID_0 BIT(10) -#define MCHP_INT17_RCID_1 BIT(11) -#define MCHP_INT17_RCID_2 BIT(12) -#define MCHP_INT17_LED_WDT_0 BIT(13) -#define MCHP_INT17_LED_WDT_1 BIT(14) -#define MCHP_INT17_LED_WDT_2 BIT(15) -#define MCHP_INT17_LED_WDT_3 BIT(16) -#define MCHP_INT17_PROCHOT BIT(17) -#define MCHP_INT17_PWRGRD0 BIT(18) -#define MCHP_INT17_PWRGRD1 BIT(19) - -/* GIRQ18 interrupt sources. Direct capable */ -#define MCHP_INT18_LPC_ERR BIT(0) -#define MCHP_INT18_QMSPI BIT(1) -#define MCHP_INT18_GPSPI0_TXBE BIT(2) -#define MCHP_INT18_GPSPI0_RXBF BIT(3) -#define MCHP_INT18_GPSPI1_TXBE BIT(4) -#define MCHP_INT18_GPSPI1_RXBF BIT(5) -#define MCHP_INT18_BCM0_BUSY BIT(6) -#define MCHP_INT18_BCM0_ERR BIT(7) -#define MCHP_INT18_BCM1_BUSY BIT(8) -#define MCHP_INT18_BCM1_ERR BIT(9) -#define MCHP_INT18_PS2_0 BIT(10) -#define MCHP_INT18_PS2_1 BIT(11) -#define MCHP_INT18_PS2_2 BIT(12) -#define MCHP_INT18_PSPI BIT(13) - -/* GIRQ19 interrupt sources. Direct capable */ -#define MCHP_INT19_ESPI_PC BIT(0) -#define MCHP_INT19_ESPI_BM1 BIT(1) -#define MCHP_INT19_ESPI_BM2 BIT(2) -#define MCHP_INT19_ESPI_LTR BIT(3) -#define MCHP_INT19_ESPI_OOB_TX BIT(4) -#define MCHP_INT19_ESPI_OOB_RX BIT(5) -#define MCHP_INT19_ESPI_FC BIT(6) -#define MCHP_INT19_ESPI_RESET BIT(7) -#define MCHP_INT19_ESPI_VW_EN BIT(8) - -/* GIRQ20 interrupt sources. Direct capable */ -#define MCHP_INT20_STAP_OBF BIT(0) -#define MCHP_INT20_STAP_IBF BIT(1) -#define MCHP_INT20_STAP_WAKE BIT(2) -#define MCHP_INT20_ISPI BIT(8) - -/* GIRQ21 interrupt sources. Direct capable */ -#define MCHP_INT21_RTMR BIT(0) -#define MCHP_INT21_HTMR_0 BIT(1) -#define MCHP_INT21_HTMR_1 BIT(2) -#define MCHP_INT21_WEEK_ALARM BIT(3) -#define MCHP_INT21_WEEK_SUB BIT(4) -#define MCHP_INT21_WEEK_1SEC BIT(5) -#define MCHP_INT21_WEEK_1SEC_SUB BIT(6) -#define MCHP_INT21_WEEK_PWR_PRES BIT(7) -#define MCHP_INT21_RTC BIT(8) -#define MCHP_INT21_RTC_ALARM BIT(9) -#define MCHP_INT21_VCI_OVRD BIT(10) -#define MCHP_INT21_VCI_IN0 BIT(11) -#define MCHP_INT21_VCI_IN1 BIT(12) -#define MCHP_INT21_VCI_IN2 BIT(13) -#define MCHP_INT21_VCI_IN3 BIT(14) -#define MCHP_INT21_VCI_IN4 BIT(15) -#define MCHP_INT21_VCI_IN5 BIT(16) -#define MCHP_INT21_VCI_IN6 BIT(17) -#define MCHP_INT21_PS2_0A_WAKE BIT(18) -#define MCHP_INT21_PS2_0B_WAKE BIT(19) -#define MCHP_INT21_PS2_1A_WAKE BIT(20) -#define MCHP_INT21_PS2_1B_WAKE BIT(21) -#define MCHP_INT21_PS2_2_WAKE BIT(22) -#define MCHP_INT21_ENVMON BIT(24) -#define MCHP_INT21_KEYSCAN BIT(25) - -/* GIRQ22 peripheral wake only. GIRQ22 not connected to NVIC */ -#define MCHP_INT22_WAKE_ONLY_LPC BIT(0) -#define MCHP_INT22_WAKE_ONLY_I2C0 BIT(1) -#define MCHP_INT22_WAKE_ONLY_I2C1 BIT(2) -#define MCHP_INT22_WAKE_ONLY_I2C2 BIT(3) -#define MCHP_INT22_WAKE_ONLY_I2C3 BIT(4) -#define MCHP_INT22_WAKE_ONLY_ESPI BIT(9) - -/* GIRQ23 sources. Direct capable */ -#define MCHP_INT23_BTMR16_0 BIT(0) -#define MCHP_INT23_BTMR16_1 BIT(1) -#define MCHP_INT23_BTMR16_2 BIT(2) -#define MCHP_INT23_BTMR16_3 BIT(3) -#define MCHP_INT23_BTMR32_0 BIT(4) -#define MCHP_INT23_BTMR32_1 BIT(5) -#define MCHP_INT23_CNT16_0 BIT(6) -#define MCHP_INT23_CNT16_1 BIT(7) -#define MCHP_INT23_CNT16_2 BIT(8) -#define MCHP_INT23_CNT16_3 BIT(9) -#define MCHP_INT23_CCT BIT(10) -#define MCHP_INT23_CCT_CAP0 BIT(11) -#define MCHP_INT23_CCT_CAP1 BIT(12) -#define MCHP_INT23_CCT_CAP2 BIT(13) -#define MCHP_INT23_CCT_CAP3 BIT(14) -#define MCHP_INT23_CCT_CAP4 BIT(15) -#define MCHP_INT23_CCT_CAP6 BIT(16) -#define MCHP_INT23_CCT_CMP0 BIT(17) -#define MCHP_INT23_CCT_CMP1 BIT(18) - -/* GIRQ24 sources. Master-to-Slave v=[0:6], Source=[0:3] */ -#define MCHP_INT24_MSVW_SRC(v, s) (1ul << ((4 * (v)) + (s))) - -/* GIRQ25 sources Master-to-Slave v=[7:10], Source=[0:3] */ -#define MCHP_INT25_MSVW_SRC(v, s) (1ul << ((4 * ((v)-7)) + (s))) - -/* UART Peripheral 0 <= x <= 1 */ -#define MCHP_UART_INSTANCES 2 -#define MCHP_UART_SPACING 0x400 -#define MCHP_UART_CFG_OFS 0x300 -#define MCHP_UART_CONFIG_BASE(x) \ - (MCHP_UART0_BASE + MCHP_UART_CFG_OFS + ((x) * MCHP_UART_SPACING)) -#define MCHP_UART_RUNTIME_BASE(x) \ - (MCHP_UART0_BASE + ((x) * MCHP_UART_SPACING)) -#define MCHP_UART_GIRQ 15 -#define MCHP_UART0_GIRQ_BIT (MCHP_INT15_UART_0) -#define MCHP_UART1_GIRQ_BIT (MCHP_INT15_UART_1) -#define MCHP_UART_GIRQ_BIT(x) BIT(x) -/* Bit defines for MCHP_UARTx_LSR */ -#define MCHP_LSR_TX_EMPTY BIT(5) - -/* - * GPIO - * MCHP each Port contains 32 GPIO's. - * GPIO Control 1 registers are 32-bit registers starting at - * MCHP_GPIO_BASE. - * index = octal GPIO number from MCHP specification. - * port/bank = index >> 5 - * id = index & 0x1F - * - * The port/bank, id pair may also be used to access GPIO's via - * parallel I/O registers if GPIO control is configured for - * parallel I/O. - * - * From ec/chip/mec1701/config_chip.h - * #define GPIO_PIN(index) ((index) >> 5), ((index) & 0x1F) - * - * GPIO Control 1 Address = 0x40081000 + (((bank << 5) + id) << 2) - * - * Example: GPIO043, Control 1 register address = 0x4008108c - * port/bank = 0x23 >> 5 = 1 - * id = 0x23 & 0x1F = 0x03 - * Control 1 Address = 0x40081000 + ((BIT(5) + 0x03) << 2) = 0x4008108c - * - * Example: GPIO235, Control 1 register address = 0x40081274 - * port/bank = 0x9d >> 5 = 4 - * id = 0x9d & 0x1f = 0x1d - * Control 1 Address = 0x40081000 + (((4 << 5) + 0x1d) << 2) = 0x40081274 - * - */ -#define MCHP_GPIO_CTL(port, id) REG32(MCHP_GPIO_BASE + \ - (((port << 5) + id) << 2)) - -/* MCHP implements 6 GPIO ports */ -#define MCHP_GPIO_MAX_PORT 6 -#define UNIMPLEMENTED_GPIO_BANK MCHP_GPIO_MAX_PORT -/* - * In MECxxxx documentation GPIO numbers are octal, each control - * register is located on a 32-bit boundary. - */ -#define MCHP_GPIO_CTRL(gpio_num) REG32(MCHP_GPIO_BASE + \ - ((gpio_num) << 2)) - -/* - * GPIO control register bit fields - */ -#define MCHP_GPIO_CTRL_PUD_BITPOS 0 -#define MCHP_GPIO_CTRL_PUD_MASK0 0x03 -#define MCHP_GPIO_CTRL_PUD_MASK 0x03 -#define MCHP_GPIO_CTRL_PUD_NONE 0x00 -#define MCHP_GPIO_CTRL_PUD_PU 0x01 -#define MCHP_GPIO_CTRL_PUD_PD 0x02 -#define MCHP_GPIO_CTRL_PUD_KEEPER 0x03 -#define MCHP_GPIO_CTRL_PWR_BITPOS 2 -#define MCHP_GPIO_CTRL_PWR_MASK0 0x03 -#define MCHP_GPIO_CTRL_PWR_MASK (0x03 << 2) -#define MCHP_GPIO_CTRL_PWR_VTR 0 -#define MCHP_GPIO_CTRL_PWR_OFF (0x02 << 2) -#define MCHP_GPIO_INTDET_MASK 0xF0 -#define MCHP_GPIO_INTDET_LVL_LO 0x00 -#define MCHP_GPIO_INTDET_LVL_HI 0x10 -#define MCHP_GPIO_INTDET_DISABLED 0x40 -#define MCHP_GPIO_INTDET_EDGE_RIS 0xD0 -#define MCHP_GPIO_INTDET_EDGE_FALL 0xE0 -#define MCHP_GPIO_INTDET_EDGE_BOTH 0xF0 -#define MCHP_GPIO_INTDET_EDGE_EN BIT(7) -#define MCHP_GPIO_PUSH_PULL 0u -#define MCHP_GPIO_OPEN_DRAIN BIT(8) -#define MCHP_GPIO_INPUT 0u -#define MCHP_GPIO_OUTPUT BIT(9) -#define MCHP_GPIO_OUTSET_CTRL 0u -#define MCHP_GPIO_OUTSEL_PAR BIT(10) -#define MCHP_GPIO_POLARITY_NINV 0u -#define MCHP_GPIO_POLARITY_INV BIT(11) -#define MCHP_GPIO_CTRL_ALT_FUNC_BITPOS 12 -#define MCHP_GPIO_CTRL_ALT_FUNC_MASK0 0x0F -#define MCHP_GPIO_CTRL_ALT_FUNC_MASK (0x0F << 12) -#define MCHP_GPIO_CTRL_FUNC_GPIO (0 << 12) -#define MCHP_GPIO_CTRL_FUNC_1 (1 << 12) -#define MCHP_GPIO_CTRL_FUNC_2 (2 << 12) -#define MCHP_GPIO_CTRL_FUNC_3 (3 << 12) -#define MCHP_GPIO_CTRL_OUT_LVL BIT(16) -/* MEC170x reserved read-only 0 bit. Value set to 0 */ -#define MCHP_GPIO_CTRL_DIS_INPUT_BITPOS 15 -#define MCHP_GPIO_CTRL_DIS_INPUT_BIT 0 - -/* - * GPIO Parallel Input and Output registers. - * gpio_bank in [0, 5] - */ -#define MCHP_GPIO_PARIN(bank) \ - REG32(MCHP_GPIO_BASE + 0x0300 + ((bank) << 2)) -#define MCHP_GPIO_PAROUT(bank) \ - REG32(MCHP_GPIO_BASE + 0x0380 + ((bank) << 2)) - -/* Basic timers */ -#define MCHP_TMR_SPACING 0x20 -#define MCHP_TMR16_INSTANCES 4 -#define MCHP_TMR32_INSTANCES 2 -#define MCHP_TMR16_MAX (MCHP_TMR16_INSTANCES) -#define MCHP_TMR32_MAX (MCHP_TMR32_INSTANCES) -#define MCHP_TMR16_BASE(n) (MCHP_TMR16_0_BASE + (n) * MCHP_TMR_SPACING) -#define MCHP_TMR32_BASE(n) (MCHP_TMR32_0_BASE + (n) * MCHP_TMR_SPACING) -#define MCHP_TMR16_GIRQ 23 -#define MCHP_TMR16_GIRQ_BIT(n) BIT(0 + (n)) -#define MCHP_TMR32_GIRQ 23 -#define MCHP_TMR32_GIRQ_BIT(n) BIT(4 + (n)) - -/* 16-bit Counter/timer */ -#define MCHP_CNT16_SPACING 0x20 -#define MCHP_CNT16_INSTANCES 4 -#define MCHP_CNT16_BASE(n) \ - (MCHP_CNT16_0_BASE + (n) * MCHP_CNT16_SPACING) -#define MCHP_CNT16_GIRQ 23 -#define MCHP_CNT16_GIRQ_BIT(x) BIT(6 + (x)) - -/* RTimer */ -#define MCHP_RTMR_GIRQ 21 -#define MCHP_RTMR_GIRQ_BIT(x) MCHP_INT21_RTMR - -/* VBAT */ -#define MCHP_VBAT_STS REG32(MCHP_VBAT_BASE + 0x0) -#define MCHP_VBAT_CE REG32(MCHP_VBAT_BASE + 0x8) -#define MCHP_VBAT_SHDN_DIS REG32(MCHP_VBAT_BASE + 0xC) -#define MCHP_VBAT_MONOTONIC_CTR_LO REG32(MCHP_VBAT_BASE + 0x20) -#define MCHP_VBAT_MONOTONIC_CTR_HI REG32(MCHP_VBAT_BASE + 0x24) -/* read 32-bit word at 32-bit offset x where 0 <= x <= 32 */ -#define MCHP_VBAT_RAM_SIZE 128 -#define MCHP_VBAT_RAM(wnum) \ - REG32(MCHP_VBAT_RAM_BASE + ((wnum) * 4)) -#define MCHP_VBAT_RAM8(bnum) \ - REG8(MCHP_VBAT_RAM_BASE + (bnum)) -#define MCHP_VBAT_VWIRE_BACKUP 30 -/* - * Miscellaneous firmware control fields - * scratch pad index cannot be more than 32 as - * MEC152x has 64 bytes = 16 words of scratch RAM - */ -#define MCHP_IMAGETYPE_IDX 31 - -/* Bit definition for MCHP_VBAT_STS */ -#define MCHP_VBAT_STS_SOFTRESET BIT(2) -#define MCHP_VBAT_STS_RESETI BIT(4) -#define MCHP_VBAT_STS_WDT BIT(5) -#define MCHP_VBAT_STS_SYSRESETREQ BIT(6) -#define MCHP_VBAT_STS_VBAT_RST BIT(7) -#define MCHP_VBAT_STS_ANY_RST 0xF4u - -/* Bit definitions for MCHP_VBAT_CE */ -#define MCHP_VBAT_CE_XOSEL_BITPOS 3 -#define MCHP_VBAT_CE_XOSEL_MASK BIT(3) -#define MCHP_VBAT_CE_XOSEL_PAR 0 -#define MCHP_VBAT_CE_XOSEL_SE BIT(3) - -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_BITPOS 2 -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_MASK BIT(2) -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_INT 0 -#define MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL BIT(2) - -#define MCHP_VBAT_CE_32K_DOMAIN_SRC_BITPOS 1 -#define MCHP_VBAT_CE_32K_DOMAIN_SRC_MASK BIT(1) -#define MCHP_VBAT_CE_32K_DOMAIN_ALWAYS_ON 0 -#define MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN BIT(1) - -/* Blinking-Breathing LED 0 <= n <= 2 */ -#define MCHP_BBLEB_INSTANCES 4 -#define MCHP_BBLED_BASE(n) (MCHP_BBLED_0_BASE + (((n) & 0x03) * 256)) - -/* EMI */ -#define MCHP_EMI_INSTANCES 3 -#define MCHP_EMI_SPACING 0x400 -#define MCHP_EMI_ECREG_OFS 0x100 -/* base of EMI registers only accessible by EC */ -#define MCHP_EMI_BASE(n) \ - (MCHP_EMI_0_BASE + MCHP_EMI_ECREG_OFS + ((n) * MCHP_EMI_SPACING)) -/* base of EMI registers accessible by EC and Host */ -#define MCHP_EMI_RT_BASE(n) (MCHP_EMI_0_BASE + ((n) * MCHP_EMI_SPACING)) -#define MCHP_EMI_GIRQ 15 -#define MCHP_EMI_GIRQ_BIT(n) BIT(2 + (n)) - -/* Mailbox */ -#define MCHP_MBX_ECREGS_OFS 0x100 -#define MCHP_MBX_RT_BASE MCHP_MBOX_BASE -#define MCHP_MBX_BASE (MCHP_MBOX_BASE + MCHP_MBX_ECREGS_OFS) -#define MCHP_MBX_GIRQ 15 -#define MCHP_MBX_GIRQ_BIT BIT(20) - -/* Port 80 Capture */ -#define MCHP_P80_SPACING 0x400 -#define MCHP_P80_BASE(n) (MCHP_P80CAP0_BASE + ((n) * (MCHP_P80_SPACING))) -#define MCHP_P80_HOST_DATA(n) REG8(MCHP_P80_BASE(n)) -/* Data capture with time stamp register */ -#define MCHP_P80_CAP(n) REG32(MCHP_P80_BASE(n) + 0x100) -#define MCHP_P80_CFG(n) REG8(MCHP_P80_BASE(n) + 0x104) -#define MCHP_P80_STS(n) REG8(MCHP_P80_BASE(n) + 0x108) -#define MCHP_P80_CNT(n) REG32(MCHP_P80_BASE(n) + 0x10c) -#define MCHP_P80_CNT_GET(n) (REG32(MCHP_P80_BASE(n) + 0x10c) >> 8) -#define MCHP_P80_CNT_SET(n, c) \ - (REG32(MCHP_P80_BASE(n) + 0x10c) = ((c) << 8)) -#define MCHP_P80_ACTIVATE(n) REG8(MCHP_P80_BASE(n) + 0x330) -#define MCHP_P80_GIRQ 15 -#define MCHP_P80_GIRQ_BIT(n) BIT(22 + (n)) -/* - * Port 80 Data register bits - * bits[7:0] = data captured on Host write - * bits[31:8] = optional time stamp - */ -#define MCHP_P80_CAP_DATA_MASK 0xFFul -#define MCHP_P80_CAP_TS_BITPOS 8 -#define MCHP_P80_CAP_TS_MASK0 0xfffffful -#define MCHP_P80_CAP_TS_MASK \ - ((MCHP_P80_CAP_TS_MASK0) << (MCHP_P80_CAP_TS_BITPOS)) - -/* Port 80 Configuration register bits */ -#define MCHP_P80_FLUSH_FIFO_WO BIT(1) -#define MCHP_P80_RESET_TIMESTAMP_WO BIT(2) -#define MCHP_P80_TIMEBASE_BITPOS 3 -#define MCHP_P80_TIMEBASE_MASK0 0x03 -#define MCHP_P80_TIMEBASE_MASK \ - ((MCHP_P80_TIMEBASE_MASK0) << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_750KHZ \ - (0x03 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_1500KHZ \ - (0x02 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_3MHZ \ - (0x01 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMEBASE_6MHZ \ - (0x00 << (MCHP_P80_TIMEBASE_BITPOS)) -#define MCHP_P80_TIMER_ENABLE BIT(5) -#define MCHP_P80_FIFO_THRHOLD_MASK (3u << 6) -#define MCHP_P80_FIFO_THRHOLD_1 0u -#define MCHP_P80_FIFO_THRHOLD_4 (1u << 6) -#define MCHP_P80_FIFO_THRHOLD_8 (2u << 6) -#define MCHP_P80_FIFO_THRHOLD_14 (3u << 6) -#define MCHP_P80_FIFO_LEN 16 -/* Port 80 Status register bits, read-only */ -#define MCHP_P80_STS_NOT_EMPTY BIT(0) -#define MCHP_P80_STS_OVERRUN BIT(1) -/* Port 80 Count register bits */ -#define MCHP_P80_CNT_BITPOS 8 -#define MCHP_P80_CNT_MASK0 0xfffffful -#define MCHP_P80_CNT_MASK ((MCHP_P80_CNT_MASK0) << (MCHP_P80_CNT_BITPOS)) - -/* PWM SZ 144 pin package has 9 PWM's */ -#define MCHP_PWM_INSTANCES 9 -#define MCHP_PWM_ID_MAX (MCHP_PWM_INSTANCES) -#define MCHP_PWM_SPACING 16 -#define MCHP_PWM_BASE(x) (MCHP_PWM_0_BASE + ((x) * MCHP_PWM_SPACING)) - -/* TACH */ -#define MCHP_TACH_INSTANCES 3 -#define MCHP_TACH_SPACING 16 -#define MCHP_TACH_BASE(x) (MCHP_TACH_0_BASE + ((x) * MCHP_TACH_SPACING)) -#define MCHP_TACH_GIRQ 17 -#define MCHP_TACH_GIRQ_BIT(x) BIT(1 + (x)) - -/* FAN */ -#define MCHP_FAN_INSTANCES 2 -#define MCHP_FAN_SPACING 0x80U -#define MCHP_FAN_BASE(x) \ - (MCHP_RPM2PWM0_BASE + ((x) * MCHP_FAN_SPACING)) -#define MCHP_FAN_SETTING(x) REG16(MCHP_FAN_BASE(x) + 0x0) -#define MCHP_FAN_CFG1(x) REG8(MCHP_FAN_BASE(x) + 0x2) -#define MCHP_FAN_CFG2(x) REG8(MCHP_FAN_BASE(x) + 0x3) -#define MCHP_FAN_PWM_DIVIDE(x) REG8(MCHP_FAN_BASE(x) + 0x4) -#define MCHP_FAN_GAIN(x) REG8(MCHP_FAN_BASE(x) + 0x5) -#define MCHP_FAN_SPIN_UP(x) REG8(MCHP_FAN_BASE(x) + 0x6) -#define MCHP_FAN_STEP(x) REG8(MCHP_FAN_BASE(x) + 0x7) -#define MCHP_FAN_MIN_DRV(x) REG8(MCHP_FAN_BASE(x) + 0x8) -#define MCHP_FAN_VALID_CNT(x) REG8(MCHP_FAN_BASE(x) + 0x9) -#define MCHP_FAN_DRV_FAIL(x) REG16(MCHP_FAN_BASE(x) + 0xa) -#define MCHP_FAN_TARGET(x) REG16(MCHP_FAN_BASE(x) + 0xc) -#define MCHP_FAN_READING(x) REG16(MCHP_FAN_BASE(x) + 0xe) -#define MCHP_FAN_BASE_FREQ(x) REG8(MCHP_FAN_BASE(x) + 0x10) -#define MCHP_FAN_STATUS(x) REG8(MCHP_FAN_BASE(x) + 0x11) - -/* ACPI EC */ -#define MCHP_ACPI_EC_INSTANCES 5 -#define MCHP_ACPI_EC_MAX (MCHP_ACPI_EC_INSTANCES) -#define MCHP_ACPI_EC_SPACING 0x400 -#define MCHP_ACPI_EC_BASE(x) \ - (MCHP_ACPI_EC_0_BASE + ((x) * MCHP_ACPI_EC_SPACING)) -#define MCHP_ACPI_EC_GIRQ 15 -#define MCHP_ACPI_EC_IBF_GIRQ_BIT(x) BIT(5 + ((x) * 2)) -#define MCHP_ACPI_EC_OBE_GIRQ_BIT(x) BIT(6 + ((x) * 2)) - -/* ACPI PM1 */ -#define MCHP_ACPI_PM1_ECREGS_OFS 0x100 -#define MCHP_ACPI_PM_RT_BASE MCHP_ACPI_PM1_BASE -#define MCHP_ACPI_PM_EC_BASE (MCHP_ACPI_PM1_BASE + MCHP_ACPI_PM1_ECREGS_OFS) -#define MCHP_ACPI_PM1_CTL_GIRQ_BIT BIT(15) -#define MCHP_ACPI_PM1_EN_GIRQ_BIT BIT(16) -#define MCHP_ACPI_PM1_STS_GIRQ_BIT BIT(17) - -/* 8042 */ -#define MCHP_8042_ECREGS_OFS 0x100 -#define MCHP_8042_GIRQ 15 -#define MCHP_8042_OBE_GIRQ_BIT BIT(18) -#define MCHP_8042_IBF_GIRQ_BIT BIT(19) - -/* I2C controllers 0 - 4 include SMBus network layer functionality. */ -#define MCHP_I2C_CTRL0 0 -#define MCHP_I2C_CTRL1 1 -#define MCHP_I2C_CTRL2 2 -#define MCHP_I2C_CTRL3 3 -#define MCHP_I2C_CTRL_MAX 4 - -#define MCHP_I2C_SEP0 0x400 - -/* - * MEC1701H 144-pin package has four I2C controllers and eleven ports. - * Any port can be mapped to any I2C controller. - * NOTE: 144-pin package does not implement port 1. - * - * I2C port values must be zero based consecutive whole numbers due to - * port number used as an index for I2C mutex array, etc. - * - * Refer to chip i2c_port_to_controller function for mapping - * of port to controller. - * - * Locking must occur by-controller (not by-port). - */ -#define MCHP_I2C_PORT_MASK 0x07FDul -enum MCHP_i2c_port { - MCHP_I2C_PORT0 = 0, - MCHP_I2C_PORT1, /* port 1, do not use. pins not present */ - MCHP_I2C_PORT2, - MCHP_I2C_PORT3, - MCHP_I2C_PORT4, - MCHP_I2C_PORT5, - MCHP_I2C_PORT6, - MCHP_I2C_PORT7, - MCHP_I2C_PORT8, - MCHP_I2C_PORT9, - MCHP_I2C_PORT10, - MCHP_I2C_PORT_COUNT, -}; - -/* All I2C controllers connected to GIRQ13 */ -#define MCHP_I2C_GIRQ 13 -/* I2C[0:7] -> GIRQ13 bits[0:7] */ -#define MCHP_I2C_GIRQ_BIT(n) BIT((n)) - -/* Keyboard scan matrix */ -#define MCHP_KS_GIRQ 21 -#define MCHP_KS_GIRQ_BIT BIT(25) -#define MCHP_KS_DIRECT_NVIC 135 - -/* ADC */ -#define MCHP_ADC_GIRQ 17 -#define MCHP_ADC_GIRQ_SINGLE_BIT BIT(8) -#define MCHP_ADC_GIRQ_REPEAT_BIT BIT(9) -#define MCHP_ADC_SINGLE_DIRECT_NVIC 78 -#define MCHP_ADC_REPEAT_DIRECT_NVIC 79 - -/* Hibernation timer */ -#define MCHP_HTIMER_SPACING 0x20 -#define MCHP_HTIMER_ADDR(n) (MCHP_HTIMER_BASE + ((n) * MCHP_HTIMER_SPACING)) -#define MCHP_HTIMER_GIRQ 21 -/* HTIMER[0:1] -> GIRQ21 bits[1:2] */ -#define MCHP_HTIMER_GIRQ_BIT(n) BIT(1 + (n)) -#define MCHP_HTIMER_DIRECT_NVIC(n) (112 + (n)) - -/* General Purpose SPI (GP-SPI) */ -#define MCHP_SPI_BASE(port) (MCHP_GPSPI0_BASE + ((port) * 0x80)) -#define MCHP_SPI_AR(port) REG8(MCHP_SPI_BASE(port) + 0x00) -#define MCHP_SPI_CR(port) REG8(MCHP_SPI_BASE(port) + 0x04) -#define MCHP_SPI_SR(port) REG8(MCHP_SPI_BASE(port) + 0x08) -#define MCHP_SPI_TD(port) REG8(MCHP_SPI_BASE(port) + 0x0c) -#define MCHP_SPI_RD(port) REG8(MCHP_SPI_BASE(port) + 0x10) -#define MCHP_SPI_CC(port) REG8(MCHP_SPI_BASE(port) + 0x14) -#define MCHP_SPI_CG(port) REG8(MCHP_SPI_BASE(port) + 0x18) -/* Addresses of TX/RX register used in tables */ -#define MCHP_SPI_TD_ADDR(ctrl) (MCHP_SPI_BASE(ctrl) + 0x0c) -#define MCHP_SPI_RD_ADDR(ctrl) (MCHP_SPI_BASE(ctrl) + 0x10) -/* All GP-SPI controllers connected to GIRQ18 */ -#define MCHP_SPI_GIRQ 18 -#define MCHP_SPI_GIRQ_TXBE_BIT(x) BIT(2 + ((x) * 2)) -#define MCHP_SPI_GIRQ_RXBF_BIT(x) BIT(3 + ((x) * 2)) -#define MCHP_GPSPI0_ID 0 -#define MCHP_GPSPI1_ID 1 - -/* - * Quad Master SPI (QMSPI) - * MEC1701 implements 5 descriptors and a single chip select. - */ -#define MCHP_QMSPI_MAX_DESCR 5 -#define MCHP_QMSPI_GIRQ 18 -#define MCHP_QMSPI_GIRQ_BIT BIT(1) -#define MCHP_QMSPI_DIRECT_NVIC 91 - -/* LPC */ -#define MCHP_LPC_RT_BASE (MCHP_LPC_BASE + 0x100) -#define MCHP_LPC_CFG_BASE (MCHP_LPC_BASE + 0x300) -#define MCHP_LPC_ACT REG8(MCHP_LPC_CFG_BASE + 0x30) -#define MCHP_LPC_SIRQ(x) REG8(MCHP_LPC_CFG_BASE + 0x40 + (x)) -#define MCHP_LPC_CFG_BAR REG32(MCHP_LPC_CFG_BASE + 0x60) -#define MCHP_LPC_MAILBOX_BAR REG32(MCHP_LPC_CFG_BASE + 0x64) -#define MCHP_LPC_8042_BAR REG32(MCHP_LPC_CFG_BASE + 0x68) -#define MCHP_LPC_ACPI_EC0_BAR REG32(MCHP_LPC_CFG_BASE + 0x6C) -#define MCHP_LPC_ACPI_EC1_BAR REG32(MCHP_LPC_CFG_BASE + 0x70) -#define MCHP_LPC_ACPI_EC2_BAR REG32(MCHP_LPC_CFG_BASE + 0x74) -#define MCHP_LPC_ACPI_EC3_BAR REG32(MCHP_LPC_CFG_BASE + 0x78) -#define MCHP_LPC_ACPI_EC4_BAR REG32(MCHP_LPC_CFG_BASE + 0x7C) -#define MCHP_LPC_ACPI_PM1_BAR REG32(MCHP_LPC_CFG_BASE + 0x80) -#define MCHP_LPC_PORT92_BAR REG32(MCHP_LPC_CFG_BASE + 0x84) -#define MCHP_LPC_UART0_BAR REG32(MCHP_LPC_CFG_BASE + 0x88) -#define MCHP_LPC_UART1_BAR REG32(MCHP_LPC_CFG_BASE + 0x8C) -#define MCHP_LPC_EMI0_BAR REG32(MCHP_LPC_CFG_BASE + 0x90) -#define MCHP_LPC_EMI1_BAR REG32(MCHP_LPC_CFG_BASE + 0x94) -#define MCHP_LPC_EMI2_BAR REG32(MCHP_LPC_CFG_BASE + 0x98) -#define MCHP_LPC_P80DBG0_BAR REG32(MCHP_LPC_CFG_BASE + 0x9C) -#define MCHP_LPC_P80DBG1_BAR REG32(MCHP_LPC_CFG_BASE + 0xA0) -#define MCHP_LPC_RTC_BAR REG32(MCHP_LPC_CFG_BASE + 0xA4) -#define MCHP_LPC_ACPI_EC_BAR(x) REG32(MCHP_LPC_CFG_BASE + 0x6C + ((x)<<2)) -/* LPC BAR bits */ -#define MCHP_LPC_IO_BAR_ADDR_BITPOS (16) -#define MCHP_LPC_IO_BAR_EN (1ul << 15) -/* LPC Generic Memory BAR's, 64-bit registers */ -#define MCHP_LPC_SRAM0_BAR_LO REG32(MCHP_LPC_CFG_BASE + 0xB0) -#define MCHP_LPC_SRAM0_BAR_HI REG32(MCHP_LPC_CFG_BASE + 0xB4) -#define MCHP_LPC_SRAM1_BAR_LO REG32(MCHP_LPC_CFG_BASE + 0xB8) -#define MCHP_LPC_SRAM1_BAR_HI REG32(MCHP_LPC_CFG_BASE + 0xBC) -/* - * LPC Logical Device Memory BAR's, 48-bit registers - * Use 16-bit aligned access - */ -#define MCHP_LPC_MAILBOX_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xC0) -#define MCHP_LPC_MAILBOX_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xC2) -#define MCHP_LPC_MAILBOX_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xC4) -#define MCHP_LPC_ACPI_EC0_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xC6) -#define MCHP_LPC_ACPI_EC0_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xC8) -#define MCHP_LPC_ACPI_EC0_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xCA) -#define MCHP_LPC_ACPI_EC1_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xCC) -#define MCHP_LPC_ACPI_EC1_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xCE) -#define MCHP_LPC_ACPI_EC1_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xD0) -#define MCHP_LPC_ACPI_EC2_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xD2) -#define MCHP_LPC_ACPI_EC2_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xD4) -#define MCHP_LPC_ACPI_EC2_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xD6) -#define MCHP_LPC_ACPI_EC3_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xD8) -#define MCHP_LPC_ACPI_EC3_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xDA) -#define MCHP_LPC_ACPI_EC3_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xDC) -#define MCHP_LPC_ACPI_EC4_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xDE) -#define MCHP_LPC_ACPI_EC4_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xE0) -#define MCHP_LPC_ACPI_EC4_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xE2) -#define MCHP_LPC_ACPI_EMI0_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xE4) -#define MCHP_LPC_ACPI_EMI0_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xE6) -#define MCHP_LPC_ACPI_EMI0_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xE8) -#define MCHP_LPC_ACPI_EMI1_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xEA) -#define MCHP_LPC_ACPI_EMI1_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xEC) -#define MCHP_LPC_ACPI_EMI1_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xEE) -#define MCHP_LPC_ACPI_EMI2_MEM_BAR_H0 REG32(MCHP_LPC_CFG_BASE + 0xF0) -#define MCHP_LPC_ACPI_EMI2_MEM_BAR_H1 REG32(MCHP_LPC_CFG_BASE + 0xF2) -#define MCHP_LPC_ACPI_EMI2_MEM_BAR_H2 REG32(MCHP_LPC_CFG_BASE + 0xF4) - -#define MCHP_LPC_BUS_MONITOR REG32(MCHP_LPC_RT_BASE + 0x4) -#define MCHP_LPC_HOST_ERROR REG32(MCHP_LPC_RT_BASE + 0x8) -#define MCHP_LPC_EC_SERIRQ REG32(MCHP_LPC_RT_BASE + 0xC) -#define MCHP_LPC_EC_CLK_CTRL REG32(MCHP_LPC_RT_BASE + 0x10) -#define MCHP_LPC_BAR_INHIBIT REG32(MCHP_LPC_RT_BASE + 0x20) -#define MCHP_LPC_BAR_INIT REG32(MCHP_LPC_RT_BASE + 0x30) -#define MCHP_LPC_SRAM0_BAR REG32(MCHP_LPC_RT_BASE + 0xf8) -#define MCHP_LPC_SRAM1_BAR REG32(MCHP_LPC_RT_BASE + 0xfc) - -/* eSPI */ -/* IO BAR defines. Use with MCHP_ESPI_IO_BAR_xxxx macros */ -#define MCHP_ESPI_IO_BAR_ID_CFG_PORT 0 -#define MCHP_ESPI_IO_BAR_ID_MEM_CMPNT 1 -#define MCHP_ESPI_IO_BAR_ID_MAILBOX 2 -#define MCHP_ESPI_IO_BAR_ID_8042 3 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC0 4 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC1 5 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC2 6 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC3 7 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC4 8 -#define MCHP_ESPI_IO_BAR_ID_ACPI_PM1 9 -#define MCHP_ESPI_IO_BAR_ID_P92 0xA -#define MCHP_ESPI_IO_BAR_ID_UART0 0xB -#define MCHP_ESPI_IO_BAR_ID_UART1 0xC -#define MCHP_ESPI_IO_BAR_ID_EMI0 0xD -#define MCHP_ESPI_IO_BAR_ID_EMI1 0xE -#define MCHP_ESPI_IO_BAR_ID_EMI2 0xF -#define MCHP_ESPI_IO_BAR_P80_0 0x10 -#define MCHP_ESPI_IO_BAR_P80_1 0x11 -#define MCHP_ESPI_IO_BAR_RTC 0x12 - -/* Use with MCHP_ESPI_MBAR_EC_xxxx(x) macros */ -#define MCHP_ESPI_MBAR_ID_MBOX 0 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_0 1 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_1 2 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_2 3 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_3 4 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_4 5 -#define MCHP_ESPI_MBAR_ID_EMI_0 6 -#define MCHP_ESPI_MBAR_ID_EMI_1 7 -#define MCHP_ESPI_MBAR_ID_EMI_2 8 - -/* Use with MCHP_ESPI_IO_SERIRQ_REG(x) */ -#define MCHP_ESPI_SIRQ_MBOX 0 /* Host SIRQ */ -#define MCHP_ESPI_SIRQ_MBOX_SMI 1 /* Host SMI */ -#define MCHP_ESPI_SIRQ_8042_KB 2 /* KIRQ */ -#define MCHP_ESPI_SIRQ_8042_MS 3 /* MIRQ */ -#define MCHP_ESPI_SIRQ_ACPI_EC0_OBF 4 -#define MCHP_ESPI_SIRQ_ACPI_EC1_OBF 5 -#define MCHP_ESPI_SIRQ_ACPI_EC2_OBF 6 -#define MCHP_ESPI_SIRQ_ACPI_EC3_OBF 7 -#define MCHP_ESPI_SIRQ_ACPI_EC4_OBF 8 -#define MCHP_ESPI_SIRQ_UART0 9 -#define MCHP_ESPI_SIRQ_UART1 10 -#define MCHP_ESPI_SIRQ_EMI0_HEV 11 /* Host Event */ -#define MCHP_ESPI_SIRQ_EMI0_EC2H 12 /* EC to Host */ -#define MCHP_ESPI_SIRQ_EMI1_HEV 13 -#define MCHP_ESPI_SIRQ_EMI1_EC2H 14 -#define MCHP_ESPI_SIRQ_EMI2_HEV 15 -#define MCHP_ESPI_SIRQ_EMI2_EC2H 16 -#define MCHP_ESPI_SIRQ_RTC 17 -#define MCHP_ESPI_SIRQ_EC 18 - -#define MCHP_ESPI_MSVW_BASE (MCHP_ESPI_VW_BASE) -#define MCHP_ESPI_SMVW_BASE ((MCHP_ESPI_VW_BASE) + 0x200ul) - -/* - * eSPI RESET, channel enables and operations except Master-to-Slave - * WWires are all on GIRQ19 - */ -#define MCHP_ESPI_GIRQ 19 -#define MCHP_ESPI_PC_GIRQ_BIT BIT(0) -#define MCHP_ESPI_BM1_GIRQ_BIT BIT(1) -#define MCHP_ESPI_BM2_GIRQ_BIT BIT(2) -#define MCHP_ESPI_LTR_GIRQ_BIT BIT(3) -#define MCHP_ESPI_OOB_TX_GIRQ_BIT BIT(4) -#define MCHP_ESPI_OOB_RX_GIRQ_BIT BIT(5) -#define MCHP_ESPI_FC_GIRQ_BIT BIT(6) -#define MCHP_ESPI_RESET_GIRQ_BIT BIT(7) -#define MCHP_ESPI_VW_EN_GIRQ_BIT BIT(8) - -/* - * eSPI Master-to-Slave WWire interrupts are on GIRQ24 and GIRQ25 - */ -#define MCHP_ESPI_MSVW_0_6_GIRQ 24 -#define MCHP_ESPI_MSVW_7_10_GIRQ 25 -/* - * Four source bits, SRC[0:3] per Master-to-Slave register - * v = MSVW [0:10] - * n = VWire SRC bit = [0:3] - */ -#define MCHP_ESPI_MSVW_GIRQ(v) (24 + ((v) > 6 ? 1 : 0)) - -#define MCHP_ESPI_MSVW_SRC_GIRQ_BIT(v, n) \ - (((v) > 6) ? (1ul << (((v)-7)+(n))) : (1ul << ((v)+(n)))) - -/* DMA */ -#define MCHP_DMA_MAX_CHAN 14 -#define MCHP_DMA_CH_OFS 0x40 -#define MCHP_DMA_CH_OFS_BITPOS 6 -#define MCHP_DMA_CH_BASE (MCHP_DMA_BASE + MCHP_DMA_CH_OFS) - -/* - * Available DMA channels. - * - * On MCHP, any DMA channel may serve any device. Since we have - * 14 channels and 14 device request signals, we make each channel - * dedicated to the device of the same number. - */ -enum dma_channel { - /* Channel numbers */ - MCHP_DMAC_I2C0_SLAVE = 0, - MCHP_DMAC_I2C0_MASTER, - MCHP_DMAC_I2C1_SLAVE, - MCHP_DMAC_I2C1_MASTER, - MCHP_DMAC_I2C2_SLAVE, - MCHP_DMAC_I2C2_MASTER, - MCHP_DMAC_I2C3_SLAVE, - MCHP_DMAC_I2C3_MASTER, - MCHP_DMAC_SPI0_TX, - MCHP_DMAC_SPI0_RX, - MCHP_DMAC_SPI1_TX, - MCHP_DMAC_SPI1_RX, - MCHP_DMAC_QMSPI0_TX, - MCHP_DMAC_QMSPI0_RX, - /* Channel count */ - MCHP_DMAC_COUNT, -}; - -/* - * Peripheral device DMA Device ID's for bits [15:9] - * in DMA channel control register. - */ -#define MCHP_DMA_I2C0_SLV_REQ_ID 0 -#define MCHP_DMA_I2C0_MTR_REQ_ID 1 -#define MCHP_DMA_I2C1_SLV_REQ_ID 2 -#define MCHP_DMA_I2C1_MTR_REQ_ID 3 -#define MCHP_DMA_I2C2_SLV_REQ_ID 4 -#define MCHP_DMA_I2C2_MTR_REQ_ID 5 -#define MCHP_DMA_I2C3_SLV_REQ_ID 6 -#define MCHP_DMA_I2C3_MTR_REQ_ID 7 -#define MCHP_DMA_SPI0_TX_REQ_ID 8 -#define MCHP_DMA_SPI0_RX_REQ_ID 9 -#define MCHP_DMA_SPI1_TX_REQ_ID 10 -#define MCHP_DMA_SPI1_RX_REQ_ID 11 -#define MCHP_DMA_QMSPI0_TX_REQ_ID 12 -#define MCHP_DMA_QMSPI0_RX_REQ_ID 13 - -/* - * Hardware delay register. - * Write of 0 <= n <= 31 will stall the Cortex-M4 - * for n+1 microseconds. Interrupts will not be - * serviced during the delay period. Reads have - * no effect. - */ -#define MCHP_USEC_DELAY_REG_ADDR 0x10000000 -#define MCHP_USEC_DELAY(x) (REG8(MCHP_USEC_DELAY_REG_ADDR) = (x)) - -#endif /* #ifndef __ASSEMBLER__ */ diff --git a/chip/mchp/registers-mec172x.h b/chip/mchp/registers-mec172x.h deleted file mode 100644 index dc811ea3c7..0000000000 --- a/chip/mchp/registers-mec172x.h +++ /dev/null @@ -1,1503 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Register map for Microchip MEC172x family controllers - */ - -#ifndef __CROS_EC_REGISTERS_H -#error "This header file should not be included directly." -#endif - -/* - * IRQ Numbers - * NOTE: GIRQ22 aggregated output and its sources are not connected to - * the NVIC. - */ -#define MCHP_IRQ_GIRQ8 0 -#define MCHP_IRQ_GIRQ9 1 -#define MCHP_IRQ_GIRQ10 2 -#define MCHP_IRQ_GIRQ11 3 -#define MCHP_IRQ_GIRQ12 4 -#define MCHP_IRQ_GIRQ13 5 -#define MCHP_IRQ_GIRQ14 6 -#define MCHP_IRQ_GIRQ15 7 -#define MCHP_IRQ_GIRQ16 8 -#define MCHP_IRQ_GIRQ17 9 -#define MCHP_IRQ_GIRQ18 10 -#define MCHP_IRQ_GIRQ19 11 -#define MCHP_IRQ_GIRQ20 12 -#define MCHP_IRQ_GIRQ21 13 -#define MCHP_IRQ_GIRQ23 14 -#define MCHP_IRQ_GIRQ24 15 -#define MCHP_IRQ_GIRQ25 16 -#define MCHP_IRQ_GIRQ26 17 -/* GIRQ13 direct sources */ -#define MCHP_IRQ_I2C_0 20 -#define MCHP_IRQ_I2C_1 21 -#define MCHP_IRQ_I2C_2 22 -#define MCHP_IRQ_I2C_3 23 -#define MCHP_IRQ_I2C_4 158 -/* GIRQ14 direct sources */ -#define MCHP_IRQ_DMA_0 24 -#define MCHP_IRQ_DMA_1 25 -#define MCHP_IRQ_DMA_2 26 -#define MCHP_IRQ_DMA_3 27 -#define MCHP_IRQ_DMA_4 28 -#define MCHP_IRQ_DMA_5 29 -#define MCHP_IRQ_DMA_6 30 -#define MCHP_IRQ_DMA_7 31 -#define MCHP_IRQ_DMA_8 32 -#define MCHP_IRQ_DMA_9 33 -#define MCHP_IRQ_DMA_10 34 -#define MCHP_IRQ_DMA_11 35 -#define MCHP_IRQ_DMA_12 36 -#define MCHP_IRQ_DMA_13 37 -#define MCHP_IRQ_DMA_14 38 -#define MCHP_IRQ_DMA_15 39 -/* GIRQ15 direct sources */ -#define MCHP_IRQ_UART0 40 -#define MCHP_IRQ_UART1 41 -#define MCHP_IRQ_EMI0 42 -#define MCHP_IRQ_EMI1 43 -#define MCHP_IRQ_EMI2 44 -#define MCHP_IRQ_ACPIEC0_IBF 45 -#define MCHP_IRQ_ACPIEC0_OBE 46 -#define MCHP_IRQ_ACPIEC1_IBF 47 -#define MCHP_IRQ_ACPIEC1_OBE 48 -#define MCHP_IRQ_ACPIEC2_IBF 49 -#define MCHP_IRQ_ACPIEC2_OBE 50 -#define MCHP_IRQ_ACPIEC3_IBF 51 -#define MCHP_IRQ_ACPIEC3_OBE 52 -#define MCHP_IRQ_ACPIEC4_IBF 53 -#define MCHP_IRQ_ACPIEC4_OBE 54 -#define MCHP_IRQ_ACPIPM1_CTL 55 -#define MCHP_IRQ_ACPIPM1_EN 56 -#define MCHP_IRQ_ACPIPM1_STS 57 -#define MCHP_IRQ_8042EM_OBE 58 -#define MCHP_IRQ_8042EM_IBF 59 -#define MCHP_IRQ_MAILBOX_DATA 60 -#define MCHP_IRQ_BDP0 62 -/* GIRQ16 direct sources */ -#define MCHP_IRQ_PKE 65 -#define MCHP_IRQ_NDRNG 67 -#define MCHP_IRQ_AESH 68 -/* GIRQ17 direct sources */ -#define MCHP_IRQ_PECI_HOST 70 -#define MCHP_IRQ_TACH_0 71 -#define MCHP_IRQ_TACH_1 72 -#define MCHP_IRQ_TACH_2 73 -#define MCHP_IRQ_TACH_3 159 -#define MCHP_IRQ_FAN0_FAIL 74 -#define MCHP_IRQ_FAN0_STALL 75 -#define MCHP_IRQ_FAN1_FAIL 76 -#define MCHP_IRQ_FAN1_STALL 77 -#define MCHP_IRQ_ADC_SNGL 78 -#define MCHP_IRQ_ADC_RPT 79 -#define MCHP_IRQ_RCID0 80 -#define MCHP_IRQ_RCID1 81 -#define MCHP_IRQ_RCID2 82 -#define MCHP_IRQ_LED0_WDT 83 -#define MCHP_IRQ_LED1_WDT 84 -#define MCHP_IRQ_LED2_WDT 85 -#define MCHP_IRQ_LED3_WDT 86 -#define MCHP_IRQ_PHOT 87 -/* GIRQ18 direct sources */ -#define MCHP_IRQ_SLAVE_SPI 90 -#define MCHP_IRQ_QMSPI0 91 -#define MCHP_IRQ_SPI0_TX 92 -#define MCHP_IRQ_SPI0_RX 93 -#define MCHP_IRQ_SPI1_TX 94 -#define MCHP_IRQ_SPI1_RX 95 -#define MCHP_IRQ_BCM0_ERR 96 -#define MCHP_IRQ_BCM0_BUSY 97 -#define MCHP_IRQ_PS2_0 100 -#define MCHP_IRQ_EEPROM 155 -#define MCHP_IRQ_CCT_TMR 146 -#define MCHP_IRQ_CCT_CAP0 147 -#define MCHP_IRQ_CCT_CAP1 148 -#define MCHP_IRQ_CCT_CAP2 149 -#define MCHP_IRQ_CCT_CAP3 150 -#define MCHP_IRQ_CCT_CAP4 151 -#define MCHP_IRQ_CCT_CAP5 152 -#define MCHP_IRQ_CCT_CMP0 153 -#define MCHP_IRQ_CCT_CMP1 154 -/* GIRQ19 direct sources */ -#define MCHP_IRQ_ESPI_PC 103 -#define MCHP_IRQ_ESPI_BM1 104 -#define MCHP_IRQ_ESPI_BM2 105 -#define MCHP_IRQ_ESPI_LTR 106 -#define MCHP_IRQ_ESPI_OOB_UP 107 -#define MCHP_IRQ_ESPI_OOB_DN 108 -#define MCHP_IRQ_ESPI_FC 109 -#define MCHP_IRQ_ESPI_RESET 110 -#define MCHP_IRQ_ESPI_VW_EN 156 -#define MCHP_IRQ_ESPI_SAF_DONE 166 -#define MCHP_IRQ_ESPI_SAF_ERR 166 -#define MCHP_IRQ_ESPI_SAF_CACHE 169 -/* GIRQ20 direct sources */ -#define MCHP_IRQ_OTP 173 -#define MCHP_IRQ_CLK32K_MON 174 -/* GIRQ21 direct sources */ -#define MCHP_IRQ_WDG 171 -#define MCHP_IRQ_WEEK_ALARM 114 -#define MCHP_IRQ_SUBWEEK 115 -#define MCHP_IRQ_WEEK_SEC 116 -#define MCHP_IRQ_WEEK_SUBSEC 117 -#define MCHP_IRQ_WEEK_SYSPWR 118 -#define MCHP_IRQ_RTC 119 -#define MCHP_IRQ_RTC_ALARM 120 -#define MCHP_IRQ_VCI_OVRD_IN 121 -#define MCHP_IRQ_VCI_IN0 122 -#define MCHP_IRQ_VCI_IN1 123 -#define MCHP_IRQ_VCI_IN2 124 -#define MCHP_IRQ_VCI_IN3 125 -#define MCHP_IRQ_VCI_IN4 126 -#define MCHP_IRQ_PS20A_WAKE 129 -#define MCHP_IRQ_PS20B_WAKE 130 -#define MCHP_IRQ_KSC_INT 135 -#define MCHP_IRQ_GLUE 172 -/* GIRQ23 direct sources */ -#define MCHP_IRQ_TIMER16_0 136 -#define MCHP_IRQ_TIMER16_1 137 -#define MCHP_IRQ_TIMER16_2 138 -#define MCHP_IRQ_TIMER16_3 139 -#define MCHP_IRQ_TIMER32_0 140 -#define MCHP_IRQ_TIMER32_1 141 -#define MCHP_IRQ_CNTR_TM0 142 -#define MCHP_IRQ_CNTR_TM1 143 -#define MCHP_IRQ_CNTR_TM2 144 -#define MCHP_IRQ_CNTR_TM3 145 -#define MCHP_IRQ_RTOS_TIMER 111 -#define MCHP_IRQ_HTIMER0 112 -#define MCHP_IRQ_HTIMER1 113 -/* Must match CONFIG_IRQ_COUNT in config_chip.h */ -#define MCHP_IRQ_MAX 180 - -/* Block base addresses */ -#define MCHP_WDG_BASE 0x40000400 -#define MCHP_TMR16_0_BASE 0x40000c00 -#define MCHP_TMR32_0_BASE 0x40000c80 -#define MCHP_CNT16_0_BASE 0x40000d00 -#define MCHP_DMA_BASE 0x40002400 -#define MCHP_PROCHOT_BASE 0x40003400 -#define MCHP_I2C0_BASE 0x40004000 -#define MCHP_I2C1_BASE 0x40004400 -#define MCHP_I2C2_BASE 0x40004800 -#define MCHP_I2C3_BASE 0x40004C00 -#define MCHP_I2C4_BASE 0x40005000 -#define MCHP_CACHE_CTRL_BASE 0x40005400 -#define MCHP_PWM_0_BASE 0x40005800 -#define MCHP_TACH_0_BASE 0x40006000 -#define MCHP_PECI_BASE 0x40006400 -#define MCHP_SPIEP_BASE 0x40007000 -#define MCHP_RTMR_BASE 0x40007400 -#define MCHP_ADC_BASE 0x40007c00 -#define MCHP_ESPI_SAF_BASE 0x40008000 -#define MCHP_TFDP_BASE 0x40008c00 -#define MCHP_GPSPI0_BASE 0x40009400 -#define MCHP_GPSPI1_BASE 0x40009480 -#define MCHP_HTIMER_BASE 0x40009800 -#define MCHP_KEYSCAN_BASE 0x40009c00 -#define MCHP_RPM2PWM0_BASE 0x4000a000 -#define MCHP_RPM2PWM1_BASE 0x4000a080 -#define MCHP_VBAT_BASE 0x4000a400 -#define MCHP_VBAT_RAM_BASE 0x4000a800 -#define MCHP_WKTIMER_BASE 0x4000ac80 -#define MCHP_VCI_BASE 0x4000ae00 -#define MCHP_BBLED_0_BASE 0x4000B800 -#define MCHP_BCL_0_BASE 0x4000cd00 -#define MCHP_INT_BASE 0x4000e000 -#define MCHP_EC_BASE 0x4000fc00 - -#define MCHP_QMSPI0_BASE 0x40070000 -#define MCHP_ESPI_SAF_COMM_BASE 0x40071000 - -#define MCHP_PCR_BASE 0x40080100 -#define MCHP_GPIO_BASE 0x40081000 -#define MCHP_OTP_BASE 0x40082000 - -#define MCHP_MBOX_BASE 0x400f0000 -#define MCHP_8042_BASE 0x400f0400 -#define MCHP_ACPI_EC_0_BASE 0x400f0800 -#define MCHP_ACPI_PM1_BASE 0x400f1c00 -#define MCHP_PORT92_BASE 0x400f2000 -#define MCHP_UART0_BASE 0x400f2400 -#define MCHP_UART1_BASE 0x400f2800 -#define MCHP_LPC_BASE 0x400f3000 -#define MCHP_ESPI_IO_BASE 0x400f3400 -#define MCHP_ESPI_MEM_BASE 0x400f3800 -#define MCHP_GLUE_BASE 0x400f3c00 -#define MCHP_EMI_0_BASE 0x400f4000 -#define MCHP_EMI_1_BASE 0x400f4400 -#define MCHP_EMI_2_BASE 0x400f4800 -#define MCHP_RTC_BASE 0x400f5000 -#define MCHP_BDP0_BASE 0x400f8000 -#define MCHP_ESPI_VW_BASE 0x400f9c00 -#define MCHP_CHIP_BASE 0x400fff00 - -#ifndef __ASSEMBLER__ - -/* - * Helper function for RAM address aliasing - * NOTE: MEC17xx and MEC15xx AHB controllers do NOT require aliasing. - * Cortex-M4 bit-banding does require aliasing of the - * DATA SRAM region. - */ -#define MCHP_RAM_ALIAS(x) \ - ((x) >= 0x118000 ? (x) - 0x118000 + 0x20000000 : (x)) - -/* EC Chip Configuration */ -/* 16-bit Device ID */ -#define MCHP_CHIP_DEV_ID REG16(MCHP_CHIP_BASE + 0x1E) -/* 8-bit Device Sub ID */ -#define MCHP_CHIP_DEV_SUB_ID REG8(MCHP_CHIP_BASE + 0x1D) -/* 8-bit Device Revision */ -#define MCHP_CHIP_DEV_REV REG8(MCHP_CHIP_BASE + 0x1C) -/* All in one */ -#define MCHP_CHIP_DEVRID32 REG32(MCHP_CHIP_BASE + 0x1C) -#define MCHP_CHIP_DEVID_POS 16 -#define MCHP_CHIP_DEVID_MASK (0xfffful << MCHP_CHIP_DEVID_POS) -#define MCHP_CHIP_SUBID_POS 8 -#define MCHP_CHIP_SUBID_MASK (0xfful << MCHP_CHIP_SUBID_POS) -#define MCHP_CHIP_REV_POS 0 -#define MCHP_CHIP_REV_MASK (0xfful << MCHP_CHIP_REV_POS) -#define MCHP_CHIP_EXTRACT_DEVID(d) \ - (((uint32_t)(d) & MCHP_CHIP_DEVID_MASK) >> MCHP_CHIP_DEVID_POS) -#define MCHP_CHIP_EXTRACT_SUBID(d) \ - (((uint32_t)(d) & MCHP_CHIP_SUBID_MASK) >> MCHP_CHIP_SUBID_POS) -#define MCHP_CHIP_EXTRACT_REV(d) \ - (((uint32_t)(d) & MCHP_CHIP_REV_MASK) >> MCHP_CHIP_REV_POS) - -/* PCR clock control dividers */ -#define MCHP_PCR_CLK_CTL_FASTEST 1U -#define MCHP_PCR_CLK_CTL_96MHZ 1U -#define MCHP_PCR_CLK_CTL_48MHZ 2U -#define MCHP_PCR_CLK_CTL_24MHZ 4U -#define MCHP_PCR_CLK_CTL_12MHZ 8U - -/* Number of PCR Sleep Enable, Clock Required, and Reset registers */ -#define MCHP_PCR_SLP_RST_REG_MAX 5 - -/* Sleep 0: Sleep Enable, Clock Required, and Reset bits */ -#define MCHP_PCR_JTAG BIT(0) /* CLKREQ only */ -#define MCHP_PCR_OTP BIT(1) -#define MCHP_PCR_ISPI BIT(2) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN0_JTAG BIT(0) -#define MCHP_PCR_SLP_EN0_OTP BIT(1) -#define MCHP_PCR_SLP_EN0_ISPI BIT(2) -#define MCHP_PCR_SLP_EN0_SLEEP 0xffffffff - -/* - * Encode register number and bit position - * b[4:0] = bit number - * b[10:8] = zero based register number - */ -#define MCHP_PCR_ERB(rnum, bnum) \ - ((((rnum) & 0x0f) << 8) | ((bnum) & 0x1f)) - -/* PCR Sleep 1: Sleep Enable, Clock Required, and Reset bits */ -#define MCHP_PCR_BTMR16_1 MCHP_PCR_ERB(1, 31) -#define MCHP_PCR_BTMR16_0 MCHP_PCR_ERB(1, 30) -#define MCHP_PCR_ECS MCHP_PCR_ERB(1, 29) -#define MCHP_PCR_PWM8 MCHP_PCR_ERB(1, 27) -#define MCHP_PCR_PWM7 MCHP_PCR_ERB(1, 26) -#define MCHP_PCR_PWM6 MCHP_PCR_ERB(1, 25) -#define MCHP_PCR_PWM5 MCHP_PCR_ERB(1, 24) -#define MCHP_PCR_PWM4 MCHP_PCR_ERB(1, 23) -#define MCHP_PCR_PWM3 MCHP_PCR_ERB(1, 22) -#define MCHP_PCR_PWM2 MCHP_PCR_ERB(1, 21) -#define MCHP_PCR_PWM1 MCHP_PCR_ERB(1, 20) -#define MCHP_PCR_TACH3 MCHP_PCR_ERB(1, 13) -#define MCHP_PCR_TACH2 MCHP_PCR_ERB(1, 12) -#define MCHP_PCR_TACH1 MCHP_PCR_ERB(1, 11) -#define MCHP_PCR_I2C0 MCHP_PCR_ERB(1, 10) -#define MCHP_PCR_WDT MCHP_PCR_ERB(1, 9) -#define MCHP_PCR_CPU MCHP_PCR_ERB(1, 8) -#define MCHP_PCR_TFDP MCHP_PCR_ERB(1, 7) -#define MCHP_PCR_DMA MCHP_PCR_ERB(1, 6) -#define MCHP_PCR_PMC MCHP_PCR_ERB(1, 5) -#define MCHP_PCR_PWM0 MCHP_PCR_ERB(1, 4) -#define MCHP_PCR_TACH0 MCHP_PCR_ERB(1, 2) -#define MCHP_PCR_PECI MCHP_PCR_ERB(1, 1) -#define MCHP_PCR_ECIA MCHP_PCR_ERB(1, 0) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN1_BTMR16_1 BIT(31) -#define MCHP_PCR_SLP_EN1_BTMR16_0 BIT(30) -#define MCHP_PCR_SLP_EN1_ECS BIT(29) -#define MCHP_PCR_SLP_EN1_PWM_ALL (BIT(4) | BIT(20) | BIT(21) |\ - BIT(22) | BIT(23) | BIT(24) | BIT(25) | BIT(26) | BIT(27)) -#define MCHP_PCR_SLP_EN1_PWM8 BIT(27) -#define MCHP_PCR_SLP_EN1_PWM7 BIT(26) -#define MCHP_PCR_SLP_EN1_PWM6 BIT(25) -#define MCHP_PCR_SLP_EN1_PWM5 BIT(24) -#define MCHP_PCR_SLP_EN1_PWM4 BIT(23) -#define MCHP_PCR_SLP_EN1_PWM3 BIT(22) -#define MCHP_PCR_SLP_EN1_PWM2 BIT(21) -#define MCHP_PCR_SLP_EN1_PWM1 BIT(20) -#define MCHP_PCR_SLP_EN1_TACH3 BIT(13) -#define MCHP_PCR_SLP_EN1_TACH2 BIT(12) -#define MCHP_PCR_SLP_EN1_TACH1 BIT(11) -#define MCHP_PCR_SLP_EN1_I2C0 BIT(10) -#define MCHP_PCR_SLP_EN1_WDT BIT(9) -#define MCHP_PCR_SLP_EN1_CPU BIT(8) -#define MCHP_PCR_SLP_EN1_TFDP BIT(7) -#define MCHP_PCR_SLP_EN1_DMA BIT(6) -#define MCHP_PCR_SLP_EN1_PMC BIT(5) -#define MCHP_PCR_SLP_EN1_PWM0 BIT(4) -#define MCHP_PCR_SLP_EN1_TACH0 BIT(2) -#define MCHP_PCR_SLP_EN1_PECI BIT(1) -#define MCHP_PCR_SLP_EN1_ECIA BIT(0) -/* all sleep enable 1 bits */ -#define MCHP_PCR_SLP_EN1_SLEEP 0xffffffff -/* - * block not used by default - * Do not sleep ECIA, PMC, CPU and ECS - */ -#define MCHP_PCR_SLP_EN1_UNUSED_BLOCKS 0xdffffede - -/* PCR Sleep 2: Sleep Enable, Clock Required 2, Reset bits */ -#define MCHP_PCR_GLUE MCHP_PCR_ERB(2, 29) -#define MCHP_PCR_SAF MCHP_PCR_ERB(2, 27) -#define MCHP_PCR_BDP0 MCHP_PCR_ERB(2, 25) -#define MCHP_PCR_ACPI_EC4 MCHP_PCR_ERB(2, 23) -#define MCHP_PCR_ACPI_EC3 MCHP_PCR_ERB(2, 22) -#define MCHP_PCR_ACPI_EC2 MCHP_PCR_ERB(2, 21) -#define MCHP_PCR_ESPI_SCR MCHP_PCR_ERB(2, 20) -#define MCHP_PCR_ESPI MCHP_PCR_ERB(2, 19) -#define MCHP_PCR_RTC MCHP_PCR_ERB(2, 18) -#define MCHP_PCR_MBOX MCHP_PCR_ERB(2, 17) -#define MCHP_PCR_8042 MCHP_PCR_ERB(2, 16) -#define MCHP_PCR_ACPI_PM1 MCHP_PCR_ERB(2, 15) -#define MCHP_PCR_ACPI_EC1 MCHP_PCR_ERB(2, 14) -#define MCHP_PCR_ACPI_EC0 MCHP_PCR_ERB(2, 13) -#define MCHP_PCR_GCFG MCHP_PCR_ERB(2, 12) -#define MCHP_PCR_UART1 MCHP_PCR_ERB(2, 2) -#define MCHP_PCR_UART0 MCHP_PCR_ERB(2, 1) -#define MCHP_PCR_EMI0 MCHP_PCR_ERB(2, 0) - -/* Command all blocks to sleep */ -#define MCHP_PCR_SLP_EN2_GLUE BIT(29) -#define MCHP_PCR_SLP_EN2_SAF BIT(27) -#define MCHP_PCR_SLP_EN2_BDP0 BIT(25) -#define MCHP_PCR_SLP_EN2_ACPI_EC4 BIT(23) -#define MCHP_PCR_SLP_EN2_ACPI_EC3 BIT(22) -#define MCHP_PCR_SLP_EN2_ACPI_EC2 BIT(21) -#define MCHP_PCR_SLP_EN2_ESPI_SCR BIT(20) -#define MCHP_PCR_SLP_EN2_ESPI BIT(19) -#define MCHP_PCR_SLP_EN2_RTC BIT(18) -#define MCHP_PCR_SLP_EN2_MAILBOX BIT(17) -#define MCHP_PCR_SLP_EN2_MIF8042 BIT(16) -#define MCHP_PCR_SLP_EN2_ACPI_PM1 BIT(15) -#define MCHP_PCR_SLP_EN2_ACPI_EC1 BIT(14) -#define MCHP_PCR_SLP_EN2_ACPI_EC0 BIT(13) -#define MCHP_PCR_SLP_EN2_GCFG BIT(12) -#define MCHP_PCR_SLP_EN2_UART1 BIT(2) -#define MCHP_PCR_SLP_EN2_UART0 BIT(1) -#define MCHP_PCR_SLP_EN2_EMI0 BIT(0) -/* all sleep enable 2 bits */ -#define MCHP_PCR_SLP_EN2_SLEEP 0xffffffff - -/* PCR Sleep 3: Sleep Enable, Clock Required, and Reset */ -#define MCHP_PCR_PWM9 MCHP_PCR_ERB(3, 31) -#define MCHP_PCR_CCT0 MCHP_PCR_ERB(3, 30) -#define MCHP_PCR_HTMR1 MCHP_PCR_ERB(3, 29) -#define MCHP_PCR_CRYPTO MCHP_PCR_ERB(3, 26) -#define MCHP_PCR_LED3 MCHP_PCR_ERB(3, 25) -#define MCHP_PCR_BTMR32_1 MCHP_PCR_ERB(3, 24) -#define MCHP_PCR_BTMR32_0 MCHP_PCR_ERB(3, 23) -#define MCHP_PCR_BTMR16_3 MCHP_PCR_ERB(3, 22) -#define MCHP_PCR_BTMR16_2 MCHP_PCR_ERB(3, 21) -#define MCHP_PCR_I2C4 MCHP_PCR_ERB(3, 20) -#define MCHP_PCR_BCM0 MCHP_PCR_ERB(3, 19) -#define MCHP_PCR_LED2 MCHP_PCR_ERB(3, 18) -#define MCHP_PCR_LED1 MCHP_PCR_ERB(3, 17) -#define MCHP_PCR_LED0 MCHP_PCR_ERB(3, 16) -#define MCHP_PCR_I2C3 MCHP_PCR_ERB(3, 15) -#define MCHP_PCR_I2C2 MCHP_PCR_ERB(3, 14) -#define MCHP_PCR_I2C1 MCHP_PCR_ERB(3, 13) -#define MCHP_PCR_RPMPWM0 MCHP_PCR_ERB(3, 12) -#define MCHP_PCR_KEYSCAN MCHP_PCR_ERB(3, 11) -#define MCHP_PCR_HTMR0 MCHP_PCR_ERB(3, 10) -#define MCHP_PCR_GPSPI0 MCHP_PCR_ERB(3, 9) -#define MCHP_PCR_PS2_0 MCHP_PCR_ERB(3, 5) -#define MCHP_PCR_ADC MCHP_PCR_ERB(3, 3) - -/* Command blocks to sleep */ -#define MCHP_PCR_SLP_EN3_PWM9 BIT(31) -#define MCHP_PCR_SLP_EN3_CCT0 BIT(30) -#define MCHP_PCR_SLP_EN3_HTMR1 BIT(29) -#define MCHP_PCR_SLP_EN3_CRYPTO BIT(26) -#define MCHP_PCR_SLP_EN3_LED3 BIT(25) -#define MCHP_PCR_SLP_EN3_BTMR32_1 BIT(24) -#define MCHP_PCR_SLP_EN3_BTMR32_0 BIT(23) -#define MCHP_PCR_SLP_EN3_BTMR16_3 BIT(22) -#define MCHP_PCR_SLP_EN3_BTMR16_2 BIT(21) -#define MCHP_PCR_SLP_EN3_I2C4 BIT(20) -#define MCHP_PCR_SLP_EN3_BCM0 BIT(19) -#define MCHP_PCR_SLP_EN3_LED2 BIT(18) -#define MCHP_PCR_SLP_EN3_LED1 BIT(17) -#define MCHP_PCR_SLP_EN3_LED0 BIT(16) -#define MCHP_PCR_SLP_EN3_I2C3 BIT(15) -#define MCHP_PCR_SLP_EN3_I2C2 BIT(14) -#define MCHP_PCR_SLP_EN3_I2C1 BIT(13) -#define MCHP_PCR_SLP_EN3_RPM2PWM0 BIT(12) -#define MCHP_PCR_SLP_EN3_KEYSCAN BIT(11) -#define MCHP_PCR_SLP_EN3_HTMR0 BIT(10) -#define MCHP_PCR_SLP_EN3_GPSPI0 BIT(9) -#define MCHP_PCR_SLP_EN3_PS2_0 BIT(5) -#define MCHP_PCR_SLP_EN3_ADC BIT(3) -#define MCHP_PCR_SLP_EN3_ALL_CRYPTO BIT(26) -/* all sleep enable 3 bits */ -#define MCHP_PCR_SLP_EN3_SLEEP 0xffffffff -#define MCHP_PCR_SLP_EN3_PWM_ALL (MCHP_PCR_SLP_EN3_PWM9) - -/* PCR Sleep 4: Sleep Enable, Clock Required, Reset */ -#define MCHP_PCR_GPSPI1 MCHP_PCR_ERB(4, 22) -#define MCHP_PCR_PSPI MCHP_PCR_ERB(4, 14) -#define MCHP_PCR_PROCHOT MCHP_PCR_ERB(4, 13) -#define MCHP_PCR_RCID2 MCHP_PCR_ERB(4, 12) -#define MCHP_PCR_RCID1 MCHP_PCR_ERB(4, 11) -#define MCHP_PCR_RCID0 MCHP_PCR_ERB(4, 10) -#define MCHP_PCR_QMSPI MCHP_PCR_ERB(4, 8) -#define MCHP_PCR_RPMPWM1 MCHP_PCR_ERB(4, 7) -#define MCHP_PCR_RTMR MCHP_PCR_ERB(4, 6) -#define MCHP_PCR_CNT16_3 MCHP_PCR_ERB(4, 5) -#define MCHP_PCR_CNT16_2 MCHP_PCR_ERB(4, 4) -#define MCHP_PCR_CNT16_1 MCHP_PCR_ERB(4, 3) -#define MCHP_PCR_CNT16_0 MCHP_PCR_ERB(4, 2) -#define MCHP_PCR_PWM11 MCHP_PCR_ERB(4, 1) -#define MCHP_PCR_PWM10 MCHP_PCR_ERB(4, 0) - -/* Command blocks to sleep */ -#define MCHP_PCR_SLP_EN4_GPSPI1 BIT(22) -#define MCHP_PCR_SLP_EN4_PSPI BIT(14) -#define MCHP_PCR_SLP_EN4_PROCHOT BIT(13) -#define MCHP_PCR_SLP_EN4_RCID2 BIT(12) -#define MCHP_PCR_SLP_EN4_RCID1 BIT(11) -#define MCHP_PCR_SLP_EN4_RCID0 BIT(10) -#define MCHP_PCR_SLP_EN4_QMSPI BIT(8) -#define MCHP_PCR_SLP_EN4_RPMPWM1 BIT(7) -#define MCHP_PCR_SLP_EN4_RTMR BIT(6) -#define MCHP_PCR_SLP_EN4_CNT16_3 BIT(5) -#define MCHP_PCR_SLP_EN4_CNT16_2 BIT(4) -#define MCHP_PCR_SLP_EN4_CNT16_1 BIT(3) -#define MCHP_PCR_SLP_EN4_CNT16_0 BIT(2) -#define MCHP_PCR_SLP_EN4_PWM11 BIT(1) -#define MCHP_PCR_SLP_EN4_PWM10 BIT(0) - -/* all sleep enable 4 bits */ -#define MCHP_PCR_SLP_EN4_SLEEP 0xffffffff -#define MCHP_PCR_SLP_EN4_PWM_ALL \ - (MCHP_PCR_SLP_EN4_PWM10 | MCHP_PCR_SLP_EN4_PWM11) - -/* Allow all blocks to request clocks */ -#define MCHP_PCR_SLP_EN0_WAKE (~(MCHP_PCR_SLP_EN0_SLEEP)) -#define MCHP_PCR_SLP_EN1_WAKE (~(MCHP_PCR_SLP_EN1_SLEEP)) -#define MCHP_PCR_SLP_EN2_WAKE (~(MCHP_PCR_SLP_EN2_SLEEP)) -#define MCHP_PCR_SLP_EN3_WAKE (~(MCHP_PCR_SLP_EN3_SLEEP)) -#define MCHP_PCR_SLP_EN4_WAKE (~(MCHP_PCR_SLP_EN4_SLEEP)) - -/* Bit defines for MCHP_PCR_PWR_RST_STS */ -#define MCHP_PWR_RST_STS_MASK_RO 0xc8c -#define MCHP_PWR_RST_STS_MASK_RWC 0x170 -#define MCHP_PWR_RST_STS_MASK \ - ((MCHP_PWR_RST_STS_MASK_RO) | (MCHP_PWR_RST_STS_MASK_RWC)) - -#define MCHP_PWR_RST_STS_ESPI_CLK_ACT BIT(11) /* RO */ -#define MCHP_PWR_RST_STS_32K_ACT BIT(10) /* RO */ -#define MCHP_PWR_RST_STS_WDT BIT(8) /* R/WC */ -#define MCHP_PWR_RST_STS_JTAG_RSTN BIT(7) /* RO */ -#define MCHP_PWR_RST_STS_SYS BIT(6) /* R/WC */ -#define MCHP_PWR_RST_STS_VBAT BIT(5) /* R/WC */ -#define MCHP_PWR_RST_STS_VTR BIT(4) /* R/WC */ -#define MCHP_PWR_RST_STS_HOST BIT(3) /* RO */ -#define MCHP_PWR_RST_STS_VCC_PWRGD BIT(2) /* RO */ - -/* Bit defines for MCHP_PCR_PWR_RST_CTL */ -#define MCHP_PCR_PWR_HOST_RST_SEL_BITPOS 8 -#define MCHP_PCR_PWR_HOST_RST_PCI_RESET BIT(8) -#define MCHP_PCR_PWR_HOST_RST_ESPI_PLTRST 0 -#define MCHP_PCR_PWR_OK_INV_BITPOS 0 - -/* Bit defines for MCHP_PCR_SYS_RST */ -#define MCHP_PCR_SYS_SOFT_RESET BIT(8) - -/* - * PCR Peripheral Reset Lock register - * MEC152x PCR Peripheral reset registers do not reset on - * peripheral sleep. The peripheral is reset immediately. - * Firmware must write an unlock value to this new lock - * register, write to PCR reset enable register(s), and - * write a lock value. - */ -#define MCHP_PCR_RST_LOCK REG32(MCHP_PCR_BASE + 0x84) -#define MCHP_PCR_RST_LOCK_VAL 0xa6382d4d -#define MCHP_PCR_RST_UNLOCK_VAL 0xa6382d4c - -/* PCR VBAT soft reset. Trigger a VBAT reset */ -#define MCHP_PCR_VBAT_SRST REG32(MCHP_PCR_BASE + 0x88) -#define MCHP_PCR_VBAT_SRST_EN BIT(0) - -/* PCR 32KHz clock source select */ -#define MCHP_PCR_CK32_SS REG32(MCHP_PCR_BASE + 0x8c) -#define MCHP_PCR_CK32_SEL_MASK GENMASK(1, 0) -#define MCHP_PCR_CK32_SEL_SIL 0 -#define MCHP_PCR_CK32_SEL_XTAL 1 -#define MCHP_PCR_CK32_SEL_PIN 2 -#define MCHP_PCR_CK32_SEL_OFF 3 - -/* PCR 32KHz period count (RO) */ -#define MCHP_PCR_CK32_PER_CNT REG32(MCHP_PCR_BASE + 0xc0) -#define MCHP_PCR_CD32_PER_CNT_MSK GENMASK(15, 0) - -/* PCR 32KHz high pulse count (RO) */ -#define MCHP_PCR_CK32_HP_CNT REG32(MCHP_PCR_BASE + 0xc4) -#define MCHP_PCR_CK32_HP_CNT_MSK GENMASK(15, 0) - -/* PCR 32KHz minimum acceptable period count */ -#define MCHP_PCR_CK32_MIN_PER_CNT REG32(MCHP_PCR_BASE + 0xc8) -#define MCHP_PCR_CK32_MIN_PER_CNT_MSK GENMASK(15, 0) - -/* PCR 32KHz maximum acceptable period count */ -#define MCHP_PCR_CK32_MAX_PER_CNT REG32(MCHP_PCR_BASE + 0xcc) -#define MCHP_PCR_CK32_MAX_PER_CNT_MSK GENMASK(15, 0) - -/* PCR 32KHz duty cycle variation count (RO) */ -#define MCHP_PCR_CK32_DC_VAR_CNT REG32(MCHP_PCR_BASE + 0xd0) -#define MCHP_PCR_CK32_DC_VAR_CNT_MSK GENMASK(15, 0) - -/* PCR 32KHz duty cycle variation acceptable maximum */ -#define MCHP_PCR_CK32_DC_VAR_MAX REG32(MCHP_PCR_BASE + 0xd4) -#define MCHP_PCR_CK32_DC_VAR_MAX_MSK GENMASK(15, 0) - -/* PCR 32KHz valid count */ -#define MCHP_PCR_CK32_VAL_CNT REG32(MCHP_PCR_BASE + 0xd8) -#define MCHP_PCR_CK32_VAL_CNT_MSK GENMASK(7, 0) - -/* PCR 32KHz valid count minimum */ -#define MCHP_PCR_CK32_MIN_VAL_CNT REG32(MCHP_PCR_BASE + 0xdc) -#define MCHP_PCR_CK32_MIN_VAL_CNT_MSK GENMASK(7, 0) - -/* PCR 32KHz control */ -#define MCHP_PCR_CK32_CTRL REG32(MCHP_PCR_BASE + 0xe0) -#define MCHP_PCR_CK32_CTRL_MSK (GENMASK(2, 0) | BIT(4) | BIT(24)) -#define MCHP_PCR_CK32_CTRL_PER_EN BIT(0) -#define MCHP_PCR_CK32_CTRL_DC_EN BIT(1) -#define MCHP_PCR_CK32_CTRL_VAL_EN BIT(2) -#define MCHP_PCR_CK32_CTRL_SRC_SIL BIT(3) -#define MCHP_PCR_CK32_CTRL_CLR_CNT BIT(24) - -/* PCR 32KHz interrupt status */ -#define MCHP_PCR_CK32_INTR_STS REG8(MCHP_PCR_BASE + 0xe4) -/* PCR 32KHz interrupt enable */ -#define MCHP_PCR_CK32_INTR_EN REG8(MCHP_PCR_BASE + 0xe8) -#define MCHP_PCR_CK32_INTR_PULSE_RDY BIT(0) -#define MCHP_PCR_CK32_INTR_PASS_PER BIT(1) -#define MCHP_PCR_CK32_INTR_PASS_DUTY BIT(2) -#define MCHP_PCR_CK32_INTR_FAIL BIT(3) -#define MCHP_PCR_CK32_INTR_STALL BIT(4) -#define MCHP_PCR_CK32_INTR_VALID BIT(5) -#define MCHP_PCR_CK32_INTR_UNWELL BIT(6) - -/* EC Subsystem */ -#define MCHP_EC_AHB_ERR REG32(MCHP_EC_BASE + 0x04) -#define MCHP_EC_ID_RO REG32(MCHP_EC_BASE + 0x10) -#define MCHP_EC_AHB_ERR_EN REG32(MCHP_EC_BASE + 0x14) -#define MCHP_EC_INT_CTRL REG32(MCHP_EC_BASE + 0x18) -#define MCHP_EC_TRACE_EN REG32(MCHP_EC_BASE + 0x1c) -#define MCHP_EC_JTAG_EN REG32(MCHP_EC_BASE + 0x20) -#define MCHP_EC_WDT_CNT REG32(MCHP_EC_BASE + 0x28) -#define MCHP_EC_PECI_DISABLE REG8(MCHP_EC_BASE + 0x40) -#define MCHP_EC_VCI_FW_OVRD REG32(MCHP_EC_BASE + 0x50) -#define MCHP_EC_BROM_STS REG32(MCHP_EC_BASE + 0x54) -#define MCHP_EC_VW_SRC_CFG REG32(MCHP_EC_BASE + 0x90) -#define MCHP_EC_CMP_CTRL REG32(MCHP_EC_BASE + 0x94) -#define MCHP_EC_CMP_SLP_CTRL REG32(MCHP_EC_BASE + 0x98) - -/* AHB ERR Disable bit[0]=0(enable), 1(disable) */ -#define MCHP_EC_AHB_ERROR_ENABLE 0 -#define MCHP_EC_AHB_ERROR_DISABLE 1 - -/* MCHP_EC_JTAG_EN bit definitions */ -#define MCHP_JTAG_ENABLE 0x01 -/* bits [2:1] */ -#define MCHP_JTAG_MODE_4PIN 0x00 -/* ARM 2-pin SWD plus 1-pin Serial Wire Viewer (ITM) */ -#define MCHP_JTAG_MODE_SWD_SWV 0x02 -/* ARM 2-pin SWD with no SWV */ -#define MCHP_JTAG_MODE_SWD 0x04 - -/* EC Interrupt aggregator (ECIA) */ -#define MCHP_INT_GIRQ_LEN 20 /* 5 32-bit registers */ -#define MCHP_INT_GIRQ_FIRST 8 -#define MCHP_INT_GIRQ_LAST 26 -#define MCHP_INT_GIRQ_NUM (26-8+1) -/* MCHP_INT_GIRQ_FIRST <= x <= MCHP_INT_GIRQ_LAST */ -#define MCHP_INTx_BASE(x) (MCHP_INT_BASE + (((x) - 8) * MCHP_INT_GIRQ_LEN)) - -/* - * GPIO GIRQ's are not direct capable - * GIRQ08 GPIO 0140 - 0176 - * GIRQ09 GPIO 0100 - 0136 - * GIRQ10 GPIO 040 - 076 - * GIRQ11 GPIO 000 - 036 - * GIRQ12 GPIO 0200 - 0236 - * GIRQ26 GPIO 0240 - 0276 - * Other GIRQ's not direct capable: - * GIRQ22 wake peripheral clock only - * GIRQ24, GIRQ25 eSPI host to endpoint virtual wires - */ -#define MCHP_INT_AGGR_ONLY_BITMAP (BIT(8) | BIT(9) | BIT(10) | BIT(11) |\ - BIT(12) | BIT(22) | BIT(24) | BIT(25) | BIT(26)) - -#define MCHP_INT_DIRECT_CAPABLE_BITMAP (BIT(13) | BIT(14) | BIT(15) |\ - BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(23)) - -/* GIRQ13 I2C controllers 0 - 4. Direct capable */ -#define MCHP_INT13_I2C(x) BIT(x) - -/* GIRQ14 DMA channels 0 - 15. Direct capable */ -#define MCHP_INT14_DMA(x) BIT(x) - -/* GIQ15 interrupt sources. Direct capable */ -#define MCHP_INT15_UART_0 BIT(0) -#define MCHP_INT15_UART_1 BIT(1) -#define MCHP_INT15_EMI_0 BIT(2) -#define MCHP_INT15_EMI_1 BIT(3) -#define MCHP_INT15_EMI_2 BIT(4) -#define MCHP_INT15_ACPI_EC0_IBF BIT(5) -#define MCHP_INT15_ACPI_EC0_OBE BIT(6) -#define MCHP_INT15_ACPI_EC1_IBF BIT(7) -#define MCHP_INT15_ACPI_EC1_OBE BIT(8) -#define MCHP_INT15_ACPI_EC2_IBF BIT(9) -#define MCHP_INT15_ACPI_EC2_OBE BIT(10) -#define MCHP_INT15_ACPI_EC3_IBF BIT(11) -#define MCHP_INT15_ACPI_EC3_OBE BIT(12) -#define MCHP_INT15_ACPI_EC4_IBF BIT(13) -#define MCHP_INT15_ACPI_EC4_OBE BIT(14) -#define MCHP_INT15_ACPI_PM1_CTL BIT(15) -#define MCHP_INT15_ACPI_PM1_EN BIT(16) -#define MCHP_INT15_ACPI_PM1_STS BIT(17) -#define MCHP_INT15_8042_OBE BIT(18) -#define MCHP_INT15_8042_IBF BIT(19) -#define MCHP_INT15_MAILBOX BIT(20) -#define MCHP_INT15_BDP0 BIT(22) - -/* GIRQ16 interrupt sources. Direct capable */ -#define MCHP_INT16_PKE_DONE BIT(0) -#define MCHP_INT16_RNG_DONE BIT(2) -#define MCHP_INT16_AESH_DONE BIT(3) - -/* GIR17 interrupt sources. Direct capable */ -#define MCHP_INT17_PECI BIT(0) -#define MCHP_INT17_TACH_0 BIT(1) -#define MCHP_INT17_TACH_1 BIT(2) -#define MCHP_INT17_TACH_2 BIT(3) -#define MCHP_INT17_TACH_3 BIT(4) -#define MCHP_INT17_ADC_SINGLE BIT(8) -#define MCHP_INT17_ADC_REPEAT BIT(9) -#define MCHP_INT17_RCID_0 BIT(10) -#define MCHP_INT17_RCID_1 BIT(11) -#define MCHP_INT17_RCID_2 BIT(12) -#define MCHP_INT17_LED_WDT_0 BIT(13) -#define MCHP_INT17_LED_WDT_1 BIT(14) -#define MCHP_INT17_LED_WDT_2 BIT(15) -#define MCHP_INT17_LED_WDT_3 BIT(16) -#define MCHP_INT17_PROCHOT BIT(17) -#define MCHP_INT17_RPM2PWM0_FAIL BIT(20) -#define MCHP_INT17_RPM2PWM0_STALL BIT(21) -#define MCHP_INT17_RPM2PWM1_FAIL BIT(22) -#define MCHP_INT17_RPM2PWM1_STALL BIT(23) - -/* GIRQ18 interrupt sources. Direct capable */ -#define MCHP_INT18_SPIEP BIT(0) -#define MCHP_INT18_QMSPI BIT(1) -#define MCHP_INT18_GPSPI0_TXBE BIT(2) -#define MCHP_INT18_GPSPI0_RXBF BIT(3) -#define MCHP_INT18_GPSPI1_TXBE BIT(4) -#define MCHP_INT18_GPSPI1_RXBF BIT(5) -#define MCHP_INT18_BCM0_BUSY BIT(6) -#define MCHP_INT18_BCM0_ERR BIT(7) -#define MCHP_INT18_PS2_0 BIT(10) -#define MCHP_INT18_PSPI BIT(13) -#define MCHP_INT18_CCT BIT(20) -#define MCHP_INT18_CCT_CAP0 BIT(21) -#define MCHP_INT18_CCT_CAP1 BIT(22) -#define MCHP_INT18_CCT_CAP2 BIT(23) -#define MCHP_INT18_CCT_CAP3 BIT(24) -#define MCHP_INT18_CCT_CAP4 BIT(25) -#define MCHP_INT18_CCT_CAP6 BIT(26) -#define MCHP_INT18_CCT_CMP0 BIT(27) -#define MCHP_INT18_CCT_CMP1 BIT(28) - -/* GIRQ19 interrupt sources. Direct capable */ -#define MCHP_INT19_ESPI_PC BIT(0) -#define MCHP_INT19_ESPI_BM1 BIT(1) -#define MCHP_INT19_ESPI_BM2 BIT(2) -#define MCHP_INT19_ESPI_LTR BIT(3) -#define MCHP_INT19_ESPI_OOB_TX BIT(4) -#define MCHP_INT19_ESPI_OOB_RX BIT(5) -#define MCHP_INT19_ESPI_FC BIT(6) -#define MCHP_INT19_ESPI_RESET BIT(7) -#define MCHP_INT19_ESPI_VW_EN BIT(8) -#define MCHP_INT19_ESPI_SAF BIT(9) -#define MCHP_INT19_ESPI_SAF_ERR BIT(10) -#define MCHP_INT19_ESPI_SAF_CACHE BIT(11) - -/* GIRQ20 interrupt sources. Direct capable */ -#define MCHP_INT20_STAP_OBF BIT(0) -#define MCHP_INT20_STAP_IBF BIT(1) -#define MCHP_INT20_STAP_WAKE BIT(2) -#define MCHP_INT20_OTP BIT(3) -#define MCHP_INT20_ISPI BIT(8) -#define MCHP_INT20_CLK32K_MON BIT(9) - -/* GIRQ21 interrupt sources. Direct capable */ -#define MCHP_INT21_WDG BIT(2) -#define MCHP_INT21_WEEK_ALARM BIT(3) -#define MCHP_INT21_WEEK_SUB BIT(4) -#define MCHP_INT21_WEEK_1SEC BIT(5) -#define MCHP_INT21_WEEK_1SEC_SUB BIT(6) -#define MCHP_INT21_WEEK_PWR_PRES BIT(7) -#define MCHP_INT21_RTC BIT(8) -#define MCHP_INT21_RTC_ALARM BIT(9) -#define MCHP_INT21_VCI_OVRD BIT(10) -#define MCHP_INT21_VCI_IN0 BIT(11) -#define MCHP_INT21_VCI_IN1 BIT(12) -#define MCHP_INT21_VCI_IN2 BIT(13) -#define MCHP_INT21_VCI_IN3 BIT(14) -#define MCHP_INT21_VCI_IN4 BIT(15) -#define MCHP_INT21_PS2_0A_WAKE BIT(18) -#define MCHP_INT21_PS2_0B_WAKE BIT(19) -#define MCHP_INT21_KEYSCAN BIT(25) -#define MCHP_INT21_GLUE BIT(26) - -/* GIRQ22 peripheral wake only. GIRQ22 not connected to NVIC */ -#define MCHP_INT22_WAKE_ONLY_SPIEP BIT(0) -#define MCHP_INT22_WAKE_ONLY_I2C0 BIT(1) -#define MCHP_INT22_WAKE_ONLY_I2C1 BIT(2) -#define MCHP_INT22_WAKE_ONLY_I2C2 BIT(3) -#define MCHP_INT22_WAKE_ONLY_I2C3 BIT(4) -#define MCHP_INT22_WAKE_ONLY_I2C4 BIT(5) -#define MCHP_INT22_WAKE_ONLY_ESPI BIT(9) -#define MCHP_INT22_WAKE_ONLY_STAP BIT(15) - -/* GIRQ23 sources. Direct capable */ -#define MCHP_INT23_BTMR16_0 BIT(0) -#define MCHP_INT23_BTMR16_1 BIT(1) -#define MCHP_INT23_BTMR16_2 BIT(2) -#define MCHP_INT23_BTMR16_3 BIT(3) -#define MCHP_INT23_BTMR32_0 BIT(4) -#define MCHP_INT23_BTMR32_1 BIT(5) -#define MCHP_INT23_CNT16_0 BIT(6) -#define MCHP_INT23_CNT16_1 BIT(7) -#define MCHP_INT23_CNT16_2 BIT(8) -#define MCHP_INT23_CNT16_3 BIT(9) -#define MCHP_INT21_RTMR BIT(10) -#define MCHP_INT21_HTMR_0 BIT(16) -#define MCHP_INT21_HTMR_1 BIT(17) - -/* GIRQ24 sources. Master-to-Slave v=[0:6], Source=[0:3] */ -#define MCHP_INT24_MSVW_SRC(v, s) (1ul << ((4 * (v)) + (s))) - -/* GIRQ25 sources Master-to-Slave v=[7:10], Source=[0:3] */ -#define MCHP_INT25_MSVW_SRC(v, s) (1ul << ((4 * ((v)-7)) + (s))) - -/* UART Peripheral 0 <= x <= 1 */ -#define MCHP_UART_INSTANCES 2 -#define MCHP_UART_SPACING 0x400 -#define MCHP_UART_CFG_OFS 0x300 -#define MCHP_UART_CONFIG_BASE(x) \ - (MCHP_UART0_BASE + MCHP_UART_CFG_OFS + ((x) * MCHP_UART_SPACING)) -#define MCHP_UART_RUNTIME_BASE(x) \ - (MCHP_UART0_BASE + ((x) * MCHP_UART_SPACING)) -#define MCHP_UART_GIRQ 15 -#define MCHP_UART0_GIRQ_BIT (MCHP_INT15_UART_0) -#define MCHP_UART1_GIRQ_BIT (MCHP_INT15_UART_1) -#define MCHP_UART_GIRQ_BIT(x) BIT(x) -/* Bit defines for MCHP_UARTx_LSR */ -#define MCHP_LSR_TX_EMPTY BIT(5) - -/* - * GPIO - * MCHP each Port contains 32 GPIO's. - * GPIO Control 1 registers are 32-bit registers starting at - * MCHP_GPIO_BASE. - * index = octal GPIO number from MCHP specification. - * port/bank = index >> 5 - * id = index & 0x1F - * - * The port/bank, id pair may also be used to access GPIO's via - * parallel I/O registers if GPIO control is configured for - * parallel I/O. - * - * From ec/chip/mec1701/config_chip.h - * #define GPIO_PIN(index) ((index) >> 5), ((index) & 0x1F) - * - * GPIO Control 1 Address = 0x40081000 + (((bank << 5) + id) << 2) - * - * Example: GPIO043, Control 1 register address = 0x4008108c - * port/bank = 0x23 >> 5 = 1 - * id = 0x23 & 0x1F = 0x03 - * Control 1 Address = 0x40081000 + ((BIT(5) + 0x03) << 2) = 0x4008108c - * - * Example: GPIO235, Control 1 register address = 0x40081274 - * port/bank = 0x9d >> 5 = 4 - * id = 0x9d & 0x1f = 0x1d - * Control 1 Address = 0x40081000 + (((4 << 5) + 0x1d) << 2) = 0x40081274 - * - */ -#define MCHP_GPIO_CTL(port, id) REG32(MCHP_GPIO_BASE + \ - (((port << 5) + id) << 2)) - -/* MCHP implements 6 GPIO ports */ -#define MCHP_GPIO_MAX_PORT 6 -#define UNIMPLEMENTED_GPIO_BANK MCHP_GPIO_MAX_PORT -/* - * In MECxxxx documentation GPIO numbers are octal, each control - * register is located on a 32-bit boundary. - */ -#define MCHP_GPIO_CTRL(gpio_num) REG32(MCHP_GPIO_BASE + \ - ((gpio_num) << 2)) - -/* - * GPIO control register bit fields - */ -#define MCHP_GPIO_CTRL_PUD_BITPOS 0 -#define MCHP_GPIO_CTRL_PUD_MASK0 0x03 -#define MCHP_GPIO_CTRL_PUD_MASK 0x03 -#define MCHP_GPIO_CTRL_PUD_NONE 0x00 -#define MCHP_GPIO_CTRL_PUD_PU 0x01 -#define MCHP_GPIO_CTRL_PUD_PD 0x02 -#define MCHP_GPIO_CTRL_PUD_KEEPER 0x03 -#define MCHP_GPIO_CTRL_PWR_BITPOS 2 -#define MCHP_GPIO_CTRL_PWR_MASK0 0x03 -#define MCHP_GPIO_CTRL_PWR_MASK GENMASK(2, 1) -#define MCHP_GPIO_CTRL_PWR_VTR 0 -#define MCHP_GPIO_CTRL_PWR_OFF (0x02U << 2) -#define MCHP_GPIO_INTDET_MASK 0xF0U -#define MCHP_GPIO_INTDET_LVL_LO 0x00 -#define MCHP_GPIO_INTDET_LVL_HI 0x10U -#define MCHP_GPIO_INTDET_DISABLED 0x40U -#define MCHP_GPIO_INTDET_EDGE_RIS 0xD0U -#define MCHP_GPIO_INTDET_EDGE_FALL 0xE0U -#define MCHP_GPIO_INTDET_EDGE_BOTH 0xF0U -#define MCHP_GPIO_INTDET_EDGE_EN BIT(7) -#define MCHP_GPIO_PUSH_PULL 0U -#define MCHP_GPIO_OPEN_DRAIN BIT(8) -#define MCHP_GPIO_INPUT 0U -#define MCHP_GPIO_OUTPUT BIT(9) -#define MCHP_GPIO_OUTSET_CTRL 0U -#define MCHP_GPIO_OUTSEL_PAR BIT(10) -#define MCHP_GPIO_POLARITY_NINV 0U -#define MCHP_GPIO_POLARITY_INV BIT(11) -#define MCHP_GPIO_CTRL_ALT_FUNC_BITPOS 12 -#define MCHP_GPIO_CTRL_ALT_FUNC_MASK0 0x07U -#define MCHP_GPIO_CTRL_ALT_FUNC_MASK (0x07U << 12) -#define MCHP_GPIO_CTRL_FUNC_GPIO 0 -#define MCHP_GPIO_CTRL_FUNC_1 (1U << 12) -#define MCHP_GPIO_CTRL_FUNC_2 (2U << 12) -#define MCHP_GPIO_CTRL_FUNC_3 (3U << 12) -#define MCHP_GPIO_CTRL_FUNC_4 (4U << 12) -#define MCHP_GPIO_CTRL_FUNC_5 (5U << 12) -#define MCHP_GPIO_CTRL_OUT_LVL BIT(16) -/* MEC172x implements input pad disable */ -#define MCHP_GPIO_CTRL_DIS_INPUT_BITPOS 15 -#define MCHP_GPIO_CTRL_DIS_INPUT_BIT BIT(15) - -/* - * GPIO Parallel Input and Output registers. - * gpio_bank in [0, 5] - */ -#define MCHP_GPIO_PARIN(bank) \ - REG32(MCHP_GPIO_BASE + 0x0300 + ((bank) << 2)) -#define MCHP_GPIO_PAROUT(bank) \ - REG32(MCHP_GPIO_BASE + 0x0380 + ((bank) << 2)) - -/* Basic timers */ -#define MCHP_TMR_SPACING 0x20 -#define MCHP_TMR16_INSTANCES 4 -#define MCHP_TMR32_INSTANCES 2 -#define MCHP_TMR16_MAX (MCHP_TMR16_INSTANCES) -#define MCHP_TMR32_MAX (MCHP_TMR32_INSTANCES) -#define MCHP_TMR16_BASE(n) (MCHP_TMR16_0_BASE + (n) * MCHP_TMR_SPACING) -#define MCHP_TMR32_BASE(n) (MCHP_TMR32_0_BASE + (n) * MCHP_TMR_SPACING) -#define MCHP_TMR16_GIRQ 23 -#define MCHP_TMR16_GIRQ_BIT(n) BIT(0 + (n)) -#define MCHP_TMR32_GIRQ 23 -#define MCHP_TMR32_GIRQ_BIT(n) BIT(4 + (n)) - -/* 16-bit Counter/timer */ -#define MCHP_CNT16_SPACING 0x20 -#define MCHP_CNT16_INSTANCES 4 -#define MCHP_CNT16_BASE(n) \ - (MCHP_CNT16_0_BASE + (n) * MCHP_CNT16_SPACING) -#define MCHP_CNT16_GIRQ 23 -#define MCHP_CNT16_GIRQ_BIT(x) BIT(6 + (x)) - -/* RTimer */ -#define MCHP_RTMR_GIRQ 21 -#define MCHP_RTMR_GIRQ_BIT(x) MCHP_INT21_RTMR - -/* Watchdog */ -/* MEC152x specific registers */ -#define MCHP_WDG_STATUS REG32(MCHP_WDG_BASE + 0x10) -#define MCHP_WDG_IEN REG32(MCHP_WDG_BASE + 0x14) -/* Status */ -#define MCHP_WDG_STS_IRQ BIT(0) -/* Interrupt enable */ -#define MCHP_WDG_IEN_IRQ_EN BIT(0) -#define MCHP_WDG_GIRQ 21 -#define MCHP_WDG_GIRQ_BIT BIT(2) -/* Control register has a bit to enable IRQ generation */ -#define MCHP_WDG_RESET_IRQ_EN BIT(9) - -/* VBAT */ -#define MCHP_VBAT_STS REG32(MCHP_VBAT_BASE + 0x0) -#define MCHP_VBAT_CSS REG32(MCHP_VBAT_BASE + 0x8) -#define MCHP_VBAT_MONOTONIC_CTR_LO REG32(MCHP_VBAT_BASE + 0x20) -#define MCHP_VBAT_MONOTONIC_CTR_HI REG32(MCHP_VBAT_BASE + 0x24) -#define MCHP_VBAT_ROM_FEAT REG32(MCHP_VBAT_BASE + 0x28) -#define MCHP_VBAT_EMB_DEBOUNCE_EN REG32(MCHP_VBAT_BASE + 0x34) -/* read 32-bit word at 32-bit offset x where 0 <= x <= 32 */ -#define MCHP_VBAT_RAM_SIZE 128 -#define MCHP_VBAT_RAM(wnum) \ - REG32(MCHP_VBAT_RAM_BASE + ((wnum) * 4)) -#define MCHP_VBAT_RAM8(bnum) \ - REG8(MCHP_VBAT_RAM_BASE + (bnum)) -#define MCHP_VBAT_VWIRE_BACKUP 30 -/* - * Miscellaneous firmware control fields - * scratch pad index cannot be more than 32 as - * MEC152x has 64 bytes = 16 words of scratch RAM - */ -#define MCHP_IMAGETYPE_IDX 31 - -/* Bit definition for MCHP_VBAT_STS */ -#define MCHP_VBAT_STS_SOFTRESET BIT(2) -#define MCHP_VBAT_STS_RESETI BIT(4) -#define MCHP_VBAT_STS_WDT BIT(5) -#define MCHP_VBAT_STS_SYSRESETREQ BIT(6) -#define MCHP_VBAT_STS_VBAT_RST BIT(7) -#define MCHP_VBAT_STS_ANY_RST 0xF4u - -/* Bit definitions for MCHP_VBAT_CSS */ -#define MCHP_VBAT_CSS_SIL32K_EN BIT(0) -#define MCHP_VBAT_CSS_XTAL_EN BIT(8) -#define MCHP_VBAT_CSS_XTAL_SINGLE BIT(9) -#define MCHP_VBAT_CSS_XTAL_HSC_DIS BIT(10) -#define MCHP_VBAT_CSS_XTAL_CNT_POS 11 -#define MCHP_VBAT_CSS_XTAL_CNT_MASK (0x03U << 11) -#define MCHP_VBAT_CSS_SRC_POS 16 -#define MCHP_VBAT_CSS_SRC_MASK (0x03U << 16) -#define MCHP_VBAT_CSS_SRC_SIL_OSC 0 -#define MCHP_VBAT_CSS_SRC_XTAL (1U << 16) -/* Switch from 32KHZ_IN input to silicon OSC when VTR goes down */ -#define MCHP_VBAT_CSS_SRC_SWPS (2U << 16) -/* Switch from 32KHZ_IN input to XTAL on VBAT when VTR goes down */ -#define MCHP_VBAT_CSS_SRC_SWPX (3U << 16) -/* Disable 32Khz silicon oscillator when VBAT goes off */ -#define MCHP_VBAT_CSS_NVB_SUPS BIT(18) - -/* Blinking-Breathing LED 0 <= n <= 2 */ -#define MCHP_BBLEB_INSTANCES 4 -#define MCHP_BBLED_BASE(n) (MCHP_BBLED_0_BASE + (((n) & 0x03) * 256)) - -/* EMI */ -#define MCHP_EMI_INSTANCES 3 -#define MCHP_EMI_SPACING 0x400 -#define MCHP_EMI_ECREG_OFS 0x100 -/* base of EMI registers only accessible by EC */ -#define MCHP_EMI_BASE(n) \ - (MCHP_EMI_0_BASE + MCHP_EMI_ECREG_OFS + ((n) * MCHP_EMI_SPACING)) -/* base of EMI registers accessible by EC and Host */ -#define MCHP_EMI_RT_BASE(n) (MCHP_EMI_0_BASE + ((n) * MCHP_EMI_SPACING)) -#define MCHP_EMI_GIRQ 15 -#define MCHP_EMI_GIRQ_BIT(n) BIT(2 + (n)) - -/* Mailbox */ -#define MCHP_MBX_ECREGS_OFS 0x100 -#define MCHP_MBX_RT_BASE MCHP_MBOX_BASE -#define MCHP_MBX_BASE (MCHP_MBOX_BASE + MCHP_MBX_ECREGS_OFS) -#define MCHP_MBX_GIRQ 15 -#define MCHP_MBX_GIRQ_BIT BIT(20) - -/* MEC172x includes one instance of the BIOS Debug Port - * capable of capturing Host I/O port 0x80 and 0x90 writes. - * EC Data Value register: - * bits[7:0] oldest FIFO data from Host - * bits[15:16] data attributes/status - * Read with 16 or 32 access guarantees attributes/status bits - * correspond to data in bits[7:0]. - */ -#define MCHP_BDP0_HDATA REG32(MCHP_BDP0_BASE) -#define MCHP_BDP0_DATTR REG16(MCHP_BDP0_BASE + 0x100) -#define MCHP_BDP0_CONFIG REG32(MCHP_BDP0_BASE + 0x104) -#define MCHP_BDP0_STATUS REG8(MCHP_BDP0_BASE + 0x108) -#define MCHP_BDP0_INTR_EN REG8(MCHP_BDP0_BASE + 0x109) -#define MCHP_BDP0_STS_IEN REG16(MCHP_BDP0_BASE + 0x108) -#define MCHP_BDP0_SNAPSHOT REG32(MCHP_BDP0_BASE + 0x10C) -#define MCHP_BDP0_CAPTURE REG32(MCHP_BDP0_BASE + 0x110) -#define MCHP_BDP0_ACTV REG8(MCHP_BDP0_BASE + 0x330) -#define MCHP_BDP0_ALIAS_HDATA REG8(MCHP_BDP0_BASE + 0x400) -#define MCHP_BDP0_ALIAS_ACTV REG8(MCHP_BDP0_BASE + 0x730) -#define MCHP_BDP0_ALIAS_BLN REG8(MCHP_BDP0_BASE + 0x7F0) - -#define MCHP_BDP0_GIRQ 15 -#define MCHP_BDP0_GIRQ_BIT BIT(22) - -/* BDP DATATR as 16-bit value bit definitions */ -#define MCHP_BDP_DATTR_POS 0 -#define MCHP_BDP_DATTR_DATA_MASK 0xff -#define MCHP_BDP_DATTR_LANE_POS 8 -#define MCHP_BDP_DATTR_LANE_MASK GENMASK(9, 8) -#define MCHP_BDP_DATTR_LANE_0 0 -#define MCHP_BDP_DATTR_LANE_1 (1U << 8) -#define MCHP_BDP_DATTR_LANE_2 (2U << 8) -#define MCHP_BDP_DATTR_LANE_3 (3U << 8) -#define MCHP_BDP_DATTR_LEN_POS 10 -#define MCHP_BDP_DATTR_LEN_MASK GENMASK(11, 10) -#define MCHP_BDP_DATTR_LEN_1 0 -#define MCHP_BDP_DATTR_LEN_2 (1U << 10) -#define MCHP_BDP_DATTR_LEN_4 (2U << 10) -#define MCHP_BDP_DATTR_LEN_INVAL (3U << 10) -#define MCHP_BDP_DATTR_NE BIT(12) -#define MCHP_BDP_DATTR_OVR BIT(13) -#define MCHP_BDP_DATTR_THRH BIT(14) - -/* BDP Configuration */ -#define MCHP_BDP_CFG_FLUSH_FIFO BIT(0) -#define MCHP_BDP_CFG_SNAPSHOT_CLR BIT(1) -#define MCHP_BDP_CFG_FIFO_THRH_POS 8 -#define MCHP_BDP_CFG_FIFO_THRH_1 0 -#define MCHP_BDP_CFG_FIFO_THRH_4 (1U << 8) -#define MCHP_BDP_CFG_FIFO_THRH_8 (2U << 8) -#define MCHP_BDP_CFG_FIFO_THRH_16 (3U << 8) -#define MCHP_BDP_CFG_FIFO_THRH_20 (4U << 8) -#define MCHP_BDP_CFG_FIFO_THRH_24 (5U << 8) -#define MCHP_BDP_CFG_FIFO_THRH_28 (6U << 8) -#define MCHP_BDP_CFG_FIFO_THRH_30 (7U << 8) -#define MCHP_BDP_CFG_SRST BIT(31) - -/* BDP Status */ -#define MCHP_BDP_STATUS_MASK GENMASK(2, 0) -#define MCHP_BDP_STATUS_NOT_EMPTY BIT(0) -#define MCHP_BDP_STATUS_OVERRUN BIT(1) -#define MCHP_BDP_STATUS_THRH BIT(2) - -/* BDP Interrupt enable */ -#define MCHP_BDP_IEN_THRH BIT(0) - -/* PWM SZ 144 pin package has 9 PWM's */ -#define MCHP_PWM_INSTANCES 9 -#define MCHP_PWM_ID_MAX (MCHP_PWM_INSTANCES) -#define MCHP_PWM_SPACING 16 -#define MCHP_PWM_BASE(x) (MCHP_PWM_0_BASE + ((x) * MCHP_PWM_SPACING)) - -/* TACH */ -#define MCHP_TACH_INSTANCES 4 -#define MCHP_TACH_SPACING 16 -#define MCHP_TACH_BASE(x) (MCHP_TACH_0_BASE + ((x) * MCHP_TACH_SPACING)) -#define MCHP_TACH_GIRQ 17 -#define MCHP_TACH_GIRQ_BIT(x) BIT(1 + (x)) - -/* FAN */ -#define MCHP_FAN_INSTANCES 2 -#define MCHP_FAN_SPACING 0x80U -#define MCHP_FAN_BASE(x) \ - (MCHP_RPM2PWM0_BASE + ((x) * MCHP_FAN_SPACING)) -#define MCHP_FAN_SETTING(x) REG16(MCHP_FAN_BASE(x) + 0x0) -#define MCHP_FAN_CFG1(x) REG8(MCHP_FAN_BASE(x) + 0x2) -#define MCHP_FAN_CFG2(x) REG8(MCHP_FAN_BASE(x) + 0x3) -#define MCHP_FAN_PWM_DIVIDE(x) REG8(MCHP_FAN_BASE(x) + 0x4) -#define MCHP_FAN_GAIN(x) REG8(MCHP_FAN_BASE(x) + 0x5) -#define MCHP_FAN_SPIN_UP(x) REG8(MCHP_FAN_BASE(x) + 0x6) -#define MCHP_FAN_STEP(x) REG8(MCHP_FAN_BASE(x) + 0x7) -#define MCHP_FAN_MIN_DRV(x) REG8(MCHP_FAN_BASE(x) + 0x8) -#define MCHP_FAN_VALID_CNT(x) REG8(MCHP_FAN_BASE(x) + 0x9) -#define MCHP_FAN_DRV_FAIL(x) REG16(MCHP_FAN_BASE(x) + 0xa) -#define MCHP_FAN_TARGET(x) REG16(MCHP_FAN_BASE(x) + 0xc) -#define MCHP_FAN_READING(x) REG16(MCHP_FAN_BASE(x) + 0xe) -#define MCHP_FAN_BASE_FREQ(x) REG8(MCHP_FAN_BASE(x) + 0x10) -#define MCHP_FAN_STATUS(x) REG8(MCHP_FAN_BASE(x) + 0x11) - -/* ACPI EC */ -#define MCHP_ACPI_EC_INSTANCES 5 -#define MCHP_ACPI_EC_MAX (MCHP_ACPI_EC_INSTANCES) -#define MCHP_ACPI_EC_SPACING 0x400 -#define MCHP_ACPI_EC_BASE(x) \ - (MCHP_ACPI_EC_0_BASE + ((x) * MCHP_ACPI_EC_SPACING)) -#define MCHP_ACPI_EC_GIRQ 15 -#define MCHP_ACPI_EC_IBF_GIRQ_BIT(x) BIT(5 + ((x) * 2)) -#define MCHP_ACPI_EC_OBE_GIRQ_BIT(x) BIT(6 + ((x) * 2)) - -/* ACPI PM1 */ -#define MCHP_ACPI_PM1_ECREGS_OFS 0x100 -#define MCHP_ACPI_PM_RT_BASE MCHP_ACPI_PM1_BASE -#define MCHP_ACPI_PM_EC_BASE (MCHP_ACPI_PM1_BASE + MCHP_ACPI_PM1_ECREGS_OFS) -#define MCHP_ACPI_PM1_CTL_GIRQ_BIT BIT(15) -#define MCHP_ACPI_PM1_EN_GIRQ_BIT BIT(16) -#define MCHP_ACPI_PM1_STS_GIRQ_BIT BIT(17) - -/* 8042 */ -#define MCHP_8042_ECREGS_OFS 0x100 -#define MCHP_8042_GIRQ 15 -#define MCHP_8042_OBE_GIRQ_BIT BIT(18) -#define MCHP_8042_IBF_GIRQ_BIT BIT(19) - -/* I2C controllers 0 - 4 include SMBus network layer functionality. */ -#define MCHP_I2C_CTRL0 0 -#define MCHP_I2C_CTRL1 1 -#define MCHP_I2C_CTRL2 2 -#define MCHP_I2C_CTRL3 3 -#define MCHP_I2C_CTRL4 4 -#define MCHP_I2C_CTRL_MAX 5 - -#define MCHP_I2C_SEP0 0x400 - -/* - * MEC172x SZ(144-pin) package implements 15 ports. No Port 11. - * LJ(176-pin) package implements 16 ports. - * Any port can be mapped to any I2C controller. - * I2C port values must be zero based consecutive whole numbers due to - * port number used as an index for I2C the mutex list, etc. - * Refer to chip i2c_port_to_controller function for mapping - * of port to controller. - * Locking must occur by-controller (not by-port). - */ -#if (defined(CHIP_VARIANT_MEC1721LJ) || defined(CHIP_VARIANT_MEC1723LJ)\ - || defined(CHIP_VARIANT_MEC1727LJ)) -#define MCHP_I2C_PORT_MASK GENMASK(15, 0) -#else -#define MCHP_I2C_PORT_MASK (GENMASK(15, 0) & ~BIT(11)) -#endif -enum MCHP_i2c_port { - MCHP_I2C_PORT0 = 0, - MCHP_I2C_PORT1, - MCHP_I2C_PORT2, - MCHP_I2C_PORT3, - MCHP_I2C_PORT4, - MCHP_I2C_PORT5, - MCHP_I2C_PORT6, - MCHP_I2C_PORT7, - MCHP_I2C_PORT8, - MCHP_I2C_PORT9, - MCHP_I2C_PORT10, - MCHP_I2C_PORT11, - MCHP_I2C_PORT12, - MCHP_I2C_PORT13, - MCHP_I2C_PORT14, - MCHP_I2C_PORT15, - MCHP_I2C_PORT_COUNT, -}; - -/* I2C ports & Configs */ -#define I2C_CONTROLLER_COUNT MCHP_I2C_CTRL_MAX -#define I2C_PORT_COUNT MCHP_I2C_PORT_COUNT - -/* All I2C controllers connected to GIRQ13 */ -#define MCHP_I2C_GIRQ 13 -/* I2C[0:7] -> GIRQ13 bits[0:7] */ -#define MCHP_I2C_GIRQ_BIT(n) BIT((n)) - -/* Keyboard scan matrix */ -#define MCHP_KS_GIRQ 21 -#define MCHP_KS_GIRQ_BIT BIT(25) -#define MCHP_KS_DIRECT_NVIC 135 - -/* ADC */ -#if (defined(CHIP_VARIANT_MEC1721LJ) || defined(CHIP_VARIANT_MEC1723LJ)\ - || defined(CHIP_VARIANT_MEC1727LJ)) -#define MCHP_ADC_CHAN_MASK GENMASK(15, 0) -#else -#define MCHP_ADC_CHAN_MASK GENMASK(7, 0) -#endif -#define MCHP_ADC_GIRQ 17 -#define MCHP_ADC_GIRQ_SINGLE_BIT BIT(8) -#define MCHP_ADC_GIRQ_REPEAT_BIT BIT(9) -#define MCHP_ADC_SINGLE_DIRECT_NVIC 78 -#define MCHP_ADC_REPEAT_DIRECT_NVIC 79 -#define MCHP_ADC_CONFIG REG32(MCHP_ADC_BASE + 0x7c) -#define MCHP_ADC_CONFIG_DFLT 0x0101U -#define MCHP_ADC_CFG_CLK_LO_TM_MSK GENMASK(7, 0) -#define MCHP_ADC_CFG_CLK_HI_TM_MSK GENMASK(15, 8) -#define MCHP_ADC_VREF_CSEL REG32(MCHP_ADC_BASE + 0x80) -#define MCHP_ADC_VREF_CSEL_MSK(ch) (0x03U << ((ch) * 2U)) -#define MCHP_ADC_VREF_CSEL_GPIO(ch) BIT((ch) * 2U) -#define MCHP_ADC_VREF_CTRL REG32(MCHP_ADC_BASE + 0x84) -#define MCHP_ADC_VREF_CTRL_DFLT 0U -#define MCHP_ADC_VCTRL_CHRG_DLY_MSK GENMASK(15, 0) -#define MCHP_ADC_VCTRL_SW_DLY_MSK GENMASK(28, 16) -#define MCHP_ADC_VCTRL_DRV_UNUSED_LO BIT(29) -#define MCHP_ADC_VCTRL_SEL_STS_RO_POS 30 -#define MCHP_ADC_VCTRL_SEL_STS_RO_MSK GENMASK(31, 30) -#define MCHP_ADC_SAR_ADC_CTRL REG32(MCHP_ADC_BASE + 0x88) -#define MCHP_ADC_SAR_ADC_CTRL_DFLT ((0x202U << 7) | (0x03U << 1)) -#define MCHP_ADC_SAC_DIFF_INPUT BIT(0) -#define MCHP_ADC_SAC_RES_POS 1 -#define MCHP_ADC_SAC_RES_MSK GENMASK(2, 1) -#define MCHP_ADC_SAC_RES_10BIT (2U << 1) -#define MCHP_ADC_SAC_RES_12BIT (3U << 1) -#define MCHP_ADC_SAC_RJ_10BIT BIT(3) -#define MCHP_ADC_SAC_WU_DLY_POS 7 -#define MCHP_ADC_SAC_WU_DLY_MSK GENMASK(16, 7) -#define MCHP_ADC_SAC_WU_DLY_DLFT (0x202U << 7) - -/* Hibernation timer */ -#define MCHP_HTIMER_SPACING 0x20 -#define MCHP_HTIMER_ADDR(n) (MCHP_HTIMER_BASE + ((n) * MCHP_HTIMER_SPACING)) -#define MCHP_HTIMER_GIRQ 21 -/* HTIMER[0:1] -> GIRQ21 bits[1:2] */ -#define MCHP_HTIMER_GIRQ_BIT(n) BIT(1 + (n)) -#define MCHP_HTIMER_DIRECT_NVIC(n) (112 + (n)) - -/* General Purpose SPI (GP-SPI) */ -#define MCHP_SPI_BASE(port) (MCHP_GPSPI0_BASE + ((port) * 0x80)) -#define MCHP_SPI_AR(port) REG8(MCHP_SPI_BASE(port) + 0x00) -#define MCHP_SPI_CR(port) REG8(MCHP_SPI_BASE(port) + 0x04) -#define MCHP_SPI_SR(port) REG8(MCHP_SPI_BASE(port) + 0x08) -#define MCHP_SPI_TD(port) REG8(MCHP_SPI_BASE(port) + 0x0c) -#define MCHP_SPI_RD(port) REG8(MCHP_SPI_BASE(port) + 0x10) -#define MCHP_SPI_CC(port) REG8(MCHP_SPI_BASE(port) + 0x14) -#define MCHP_SPI_CG(port) REG8(MCHP_SPI_BASE(port) + 0x18) -/* Addresses of TX/RX register used in tables */ -#define MCHP_SPI_TD_ADDR(ctrl) (MCHP_SPI_BASE(ctrl) + 0x0c) -#define MCHP_SPI_RD_ADDR(ctrl) (MCHP_SPI_BASE(ctrl) + 0x10) -/* All GP-SPI controllers connected to GIRQ18 */ -#define MCHP_SPI_GIRQ 18 -#define MCHP_SPI_GIRQ_TXBE_BIT(x) BIT(2 + ((x) * 2)) -#define MCHP_SPI_GIRQ_RXBF_BIT(x) BIT(3 + ((x) * 2)) -#define MCHP_GPSPI0_ID 0 -#define MCHP_GPSPI1_ID 1 - -/* - * Quad Master SPI (QMSPI) - * MEC172x implements 16 descriptors, support for two chip selects, - * chip select timing and a local DMA unit with 3 RX channels and - * 3 TX channels. It retains support of the legacy DMA block. - */ -#define MCHP_QMSPI_MAX_DESCR 16 -#define MCHP_QMSPI_GIRQ 18 -#define MCHP_QMSPI_GIRQ_BIT BIT(1) -#define MCHP_QMSPI_DIRECT_NVIC 91 -/* SAF DMA mode when QMSPI when eSPI SAF is enabled */ -#define MCHP_QMSPI_M_SAF_EN BIT(2) -/* Local DMA enables in Mode register */ -#define MCHP_QMSPI_M_LDRX_EN BIT(3) -#define MCHP_QMSPI_M_LDTX_EN BIT(4) -/* Chip select implemented in bit[13:12] of the Mode register. */ -#define MCHP_QMSPI_M_CS_POS 12 -#define MCHP_QMSPI_M_CS_MASK0 0x03 -#define MCHP_QMSPI_M_CS_MASK GENMASK(13, 12) -#define MCHP_QMSPI_M_CS0 0U -#define MCHP_QMSPI_M_CS1 BIT(12) -/* QMSPI alternate clock divider when CS1 is active. */ -#define MCHP_QMSPI0_ALTM REG32(MCHP_QMSPI0_BASE + 0xc0) -#define MCHP_QMSPI0_ALTM_EN BIT(0) -/* QMSPI taps select */ -#define MCHP_QMSPI0_TAPS REG32(MCHP_QMSPI0_BASE + 0xd0) -/* QMSPI Taps adjust */ -#define MCHP_QMSPI0_TAPS_ADJ REG32(MCHP_QMSPI0_BASE + 0xd4) -#define MCHP_QMSPI0_TAPS_SCK_POS 0 -#define MCHP_QMSPI0_TAPS_SCK_MSK GENMASK(7, 0) -#define MCHP_QMSPI0_TAPS_CTL_POS 8 -#define MCHP_QMSPI0_TAPS_CTL_MSK GENMASK(15, 8) -/* QMSPI Taps control */ -#define MCHP_QMSPI0_TAPS_CTRL REG32(MCHP_QMSPI0_BASE + 0xd4) -#define MCHP_QMSPI0_TAPS_CTRL_MODE_POS 0 -#define MCHP_QMSPI0_TAPS_CTRL_MODE_MSK GENMASK(1, 0) -#define MCHP_QMSPI0_TAPS_CTRL_UPDATE BIT(2) -#define MCHP_QMSPI0_TAPS_CTRL_GO BIT(8) -#define MCHP_QMSPI0_TAPS_CTRL_MULT_POS 16 -#define MCHP_QMSPI0_TAPS_CTRL_MULT_MSK GENMASK(18, 16) -/* QMSPI LDMA descriptor enables */ -#define MCHP_QMSPI0_LDRX_DEN REG32(MCHP_QMSPI0_BASE + 0x100) -#define MCHP_QMSPI0_LDTX_DEN REG32(MCHP_QMSPI0_BASE + 0x104) -/* - * QMSPI LDMA channel registers. - * Each channel implement 3 32-bit registers: - * control, memory base address, and transfer length. - */ -#define MCHP_QMSPI0_LDRX_CHANS 3U -#define MCHP_QMSPI0_LDTX_CHANS 3U -#define MCHP_QMSPI0_LDRX_CTRL(n) REG32(MCHP_QMSPI0_BASE + 0x110 + ((n)*16U)) -#define MCHP_QMSPI0_LDRX_MBASE(n) REG32(MCHP_QMSPI0_BASE + 0x114 + ((n)*16U)) -#define MCHP_QMSPI0_LDRX_LEN(n) REG32(MCHP_QMSPI0_BASE + 0x118 + ((n)*16U)) -#define MCHP_QMSPI0_LDTX_CTRL(n) REG32(MCHP_QMSPI0_BASE + 0x140 + ((n)*16U)) -#define MCHP_QMSPI0_LDTX_MBASE(n) REG32(MCHP_QMSPI0_BASE + 0x144 + ((n)*16U)) -#define MCHP_QMSPI0_LDTX_LEN(n) REG32(MCHP_QMSPI0_BASE + 0x148 + ((n)*16U)) -/* LDMA RX or TX channel control register */ -#define MCHP_QMSPI_LDC_MSK GENMASK(6, 0) -#define MCHP_QMSPI_LDC_EN BIT(0) -#define MCHP_QMSPI_LDC_RSTART_EN BIT(1) -#define MCHP_QMSPI_LDC_RSTART_MA_EN BIT(2) -#define MCHP_QMSPI_LDC_LEN_EN BIT(3) -#define MCHP_QMSPI_LDC_ACC_SZ_POS 4 -#define MCHP_QMSPI_LDC_ACC_SZ_MSK GENMASK(5, 4) -#define MCHP_QMSPI_LDC_ACC_1BYTE 0 -#define MCHP_QMSPI_LDC_ACC_2BYTES (1U << 4) -#define MCHP_QMSPI_LDC_ACC_4BYTES (2U << 4) -#define MCHP_QMSPI_LDC_INCR_ADDR BIT(6) - -/* eSPI */ -/* IO BAR defines. Use with MCHP_ESPI_IO_BAR_xxxx macros */ -#define MCHP_ESPI_IO_BAR_ID_CFG_PORT 0 -#define MCHP_ESPI_IO_BAR_ID_MEM_CMPNT 1 -#define MCHP_ESPI_IO_BAR_ID_MAILBOX 2 -#define MCHP_ESPI_IO_BAR_ID_8042 3 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC0 4 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC1 5 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC2 6 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC3 7 -#define MCHP_ESPI_IO_BAR_ID_ACPI_EC4 8 -#define MCHP_ESPI_IO_BAR_ID_ACPI_PM1 9 -#define MCHP_ESPI_IO_BAR_ID_P92 0xA -#define MCHP_ESPI_IO_BAR_ID_UART0 0xB -#define MCHP_ESPI_IO_BAR_ID_UART1 0xC -#define MCHP_ESPI_IO_BAR_ID_EMI0 0xD -#define MCHP_ESPI_IO_BAR_ID_EMI1 0xE -#define MCHP_ESPI_IO_BAR_ID_EMI2 0xF -#define MCHP_ESPI_IO_BAR_BDP0 0x10 -#define MCHP_ESPI_IO_BAR_BDP0_ALT 0x11 -#define MCHP_ESPI_IO_BAR_RTC 0x12 -#define MCHP_ESPI_IO_BAR_TB32 0x14 -#define MCHP_ESPI_IO_BAR_GLUE 0x16 - -/* Use with MCHP_ESPI_MBAR_EC_xxxx(x) macros */ -#define MCHP_ESPI_MBAR_ID_MBOX 0 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_0 1 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_1 2 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_2 3 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_3 4 -#define MCHP_ESPI_MBAR_ID_ACPI_EC_4 5 -#define MCHP_ESPI_MBAR_ID_EMI_0 6 -#define MCHP_ESPI_MBAR_ID_EMI_1 7 -#define MCHP_ESPI_MBAR_ID_EMI_2 8 -#define MCHP_ESPI_MBAR_ID_TB32 9 - -/* Use with MCHP_ESPI_IO_SERIRQ_REG(x) */ -#define MCHP_ESPI_SIRQ_MBOX 0 /* Host SIRQ */ -#define MCHP_ESPI_SIRQ_MBOX_SMI 1 /* Host SMI */ -#define MCHP_ESPI_SIRQ_8042_KB 2 /* KIRQ */ -#define MCHP_ESPI_SIRQ_8042_MS 3 /* MIRQ */ -#define MCHP_ESPI_SIRQ_ACPI_EC0_OBF 4 -#define MCHP_ESPI_SIRQ_ACPI_EC1_OBF 5 -#define MCHP_ESPI_SIRQ_ACPI_EC2_OBF 6 -#define MCHP_ESPI_SIRQ_ACPI_EC3_OBF 7 -#define MCHP_ESPI_SIRQ_ACPI_EC4_OBF 8 -#define MCHP_ESPI_SIRQ_UART0 9 -#define MCHP_ESPI_SIRQ_UART1 10 -#define MCHP_ESPI_SIRQ_EMI0_HEV 11 /* Host Event */ -#define MCHP_ESPI_SIRQ_EMI0_EC2H 12 /* EC to Host */ -#define MCHP_ESPI_SIRQ_EMI1_HEV 13 -#define MCHP_ESPI_SIRQ_EMI1_EC2H 14 -#define MCHP_ESPI_SIRQ_EMI2_HEV 15 -#define MCHP_ESPI_SIRQ_EMI2_EC2H 16 -#define MCHP_ESPI_SIRQ_RTC 17 -#define MCHP_ESPI_SIRQ_EC 18 - -#define MCHP_ESPI_MSVW_BASE (MCHP_ESPI_VW_BASE) -#define MCHP_ESPI_SMVW_BASE ((MCHP_ESPI_VW_BASE) + 0x200ul) - -/* - * eSPI RESET, channel enables and operations except Master-to-Slave - * WWires are all on GIRQ19 - */ -#define MCHP_ESPI_GIRQ 19 -#define MCHP_ESPI_PC_GIRQ_BIT BIT(0) -#define MCHP_ESPI_BM1_GIRQ_BIT BIT(1) -#define MCHP_ESPI_BM2_GIRQ_BIT BIT(2) -#define MCHP_ESPI_LTR_GIRQ_BIT BIT(3) -#define MCHP_ESPI_OOB_TX_GIRQ_BIT BIT(4) -#define MCHP_ESPI_OOB_RX_GIRQ_BIT BIT(5) -#define MCHP_ESPI_FC_GIRQ_BIT BIT(6) -#define MCHP_ESPI_RESET_GIRQ_BIT BIT(7) -#define MCHP_ESPI_VW_EN_GIRQ_BIT BIT(8) -#define MCHP_ESPI_SAF_DONE_GIRQ_BIT BIT(9) -#define MCHP_ESPI_SAF_ERR_GIRQ_BIT BIT(10) -#define MCHP_ESPI_SAF_CACHE_GIRQ_BIT BIT(11) - -/* eSPI Master-to-Slave WWire interrupts are on GIRQ24 and GIRQ25 */ -#define MCHP_ESPI_MSVW_0_6_GIRQ 24 -#define MCHP_ESPI_MSVW_7_10_GIRQ 25 -/* - * Four source bits, SRC[0:3] per Master-to-Slave register - * v = MSVW [0:10] - * n = VWire SRC bit = [0:3] - */ -#define MCHP_ESPI_MSVW_GIRQ(v) (24 + ((v) > 6 ? 1 : 0)) - -#define MCHP_ESPI_MSVW_SRC_GIRQ_BIT(v, n) \ - (((v) > 6) ? (1ul << (((v)-7)+(n))) : (1ul << ((v)+(n)))) - -/* DMA */ -#define MCHP_DMA_MAX_CHAN 16 -#define MCHP_DMA_CH_OFS 0x40 -#define MCHP_DMA_CH_OFS_BITPOS 6 -#define MCHP_DMA_CH_BASE (MCHP_DMA_BASE + MCHP_DMA_CH_OFS) - -/* - * Available DMA channels. - * - * On MCHP, any DMA channel may serve any device. Since we have - * 14 channels and 14 device request signals, we make each channel - * dedicated to the device of the same number. - */ -enum dma_channel { - /* Channel numbers */ - MCHP_DMAC_I2C0_SLAVE = 0, - MCHP_DMAC_I2C0_MASTER, - MCHP_DMAC_I2C1_SLAVE, - MCHP_DMAC_I2C1_MASTER, - MCHP_DMAC_I2C2_SLAVE, - MCHP_DMAC_I2C2_MASTER, - MCHP_DMAC_I2C3_SLAVE, - MCHP_DMAC_I2C3_MASTER, - MCHP_DMAC_I2C4_SLAVE, - MCHP_DMAC_I2C5_MASTER, - MCHP_DMAC_QMSPI0_TX, - MCHP_DMAC_QMSPI0_RX, - MCHP_DMAC_SPI0_TX, - MCHP_DMAC_SPI0_RX, - MCHP_DMAC_SPI1_TX, - MCHP_DMAC_SPI1_RX, - /* Channel count */ - MCHP_DMAC_COUNT, -}; - -/* - * Peripheral device DMA Device ID's for bits [15:9] - * in DMA channel control register. - */ -#define MCHP_DMA_I2C0_SLV_REQ_ID 0 -#define MCHP_DMA_I2C0_MTR_REQ_ID 1 -#define MCHP_DMA_I2C1_SLV_REQ_ID 2 -#define MCHP_DMA_I2C1_MTR_REQ_ID 3 -#define MCHP_DMA_I2C2_SLV_REQ_ID 4 -#define MCHP_DMA_I2C2_MTR_REQ_ID 5 -#define MCHP_DMA_I2C3_SLV_REQ_ID 6 -#define MCHP_DMA_I2C3_MTR_REQ_ID 7 -#define MCHP_DMA_I2C4_SLV_REQ_ID 8 -#define MCHP_DMA_I2C4_MTR_REQ_ID 9 -#define MCHP_DMA_QMSPI0_TX_REQ_ID 10 -#define MCHP_DMA_QMSPI0_RX_REQ_ID 11 -#define MCHP_DMA_SPI0_TX_REQ_ID 12 -#define MCHP_DMA_SPI0_RX_REQ_ID 13 -#define MCHP_DMA_SPI1_TX_REQ_ID 14 -#define MCHP_DMA_SPI1_RX_REQ_ID 15 - -/* - * Hardware delay register. - * Write of 0 <= n <= 31 will stall the Cortex-M4 - * for n+1 microseconds. Interrupts will not be - * serviced during the delay period. Reads have - * no effect. - */ -#define MCHP_USEC_DELAY_REG_ADDR 0x08000000 -#define MCHP_USEC_DELAY(x) (REG8(MCHP_USEC_DELAY_REG_ADDR) = (x)) - -#endif /* #ifndef __ASSEMBLER__ */ diff --git a/chip/mchp/registers.h b/chip/mchp/registers.h deleted file mode 100644 index 65936caa2d..0000000000 --- a/chip/mchp/registers.h +++ /dev/null @@ -1,895 +0,0 @@ -/* Copyright 2018 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Register map for Microchip MEC family processors - */ -#ifndef __CROS_EC_REGISTERS_H -#define __CROS_EC_REGISTERS_H - -#include "common.h" -#include "compile_time_macros.h" - - -#if defined(CHIP_FAMILY_MEC152X) -#include "registers-mec152x.h" -#elif defined(CHIP_FAMILY_MEC170X) -#include "registers-mec1701.h" -#elif defined(CHIP_FAMILY_MEC172X) -#include "registers-mec172x.h" -#else -#error "Unsupported chip family" -#endif - -/* Common registers */ -/* EC Interrupt aggregator (ECIA) */ -#define MCHP_INT_SOURCE(x) REG32(MCHP_INTx_BASE(x) + 0x0) -#define MCHP_INT_ENABLE(x) REG32(MCHP_INTx_BASE(x) + 0x4) -#define MCHP_INT_RESULT(x) REG32(MCHP_INTx_BASE(x) + 0x8) -#define MCHP_INT_DISABLE(x) REG32(MCHP_INTx_BASE(x) + 0xc) -#define MCHP_INT_BLK_EN REG32(MCHP_INT_BASE + 0x200) -#define MCHP_INT_BLK_DIS REG32(MCHP_INT_BASE + 0x204) -#define MCHP_INT_BLK_IRQ REG32(MCHP_INT_BASE + 0x208) - -/* EC Chip Configuration */ -#define MCHP_CHIP_LEGACY_DEV_ID REG8(MCHP_CHIP_BASE + 0x20) -#define MCHP_CHIP_LEGACY_DEV_REV REG8(MCHP_CHIP_BASE + 0x21) - -/* Power/Clocks/Resets */ -#define MCHP_PCR_SYS_SLP_CTL REG32(MCHP_PCR_BASE + 0x00) -#define MCHP_PCR_PROC_CLK_CTL REG32(MCHP_PCR_BASE + 0x04) -#define MCHP_PCR_SLOW_CLK_CTL REG32(MCHP_PCR_BASE + 0x08) -#define MCHP_PCR_CHIP_OSC_ID REG32(MCHP_PCR_BASE + 0x0C) -#define MCHP_PCR_PWR_RST_STS REG32(MCHP_PCR_BASE + 0x10) -#define MCHP_PCR_PWR_RST_CTL REG32(MCHP_PCR_BASE + 0x14) -#define MCHP_PCR_SYS_RST REG32(MCHP_PCR_BASE + 0x18) -#define MCHP_PCR_SLP_EN0 REG32(MCHP_PCR_BASE + 0x30) -#define MCHP_PCR_SLP_EN1 REG32(MCHP_PCR_BASE + 0x34) -#define MCHP_PCR_SLP_EN2 REG32(MCHP_PCR_BASE + 0x38) -#define MCHP_PCR_SLP_EN3 REG32(MCHP_PCR_BASE + 0x3C) -#define MCHP_PCR_SLP_EN4 REG32(MCHP_PCR_BASE + 0x40) -#define MCHP_PCR_CLK_REQ0 REG32(MCHP_PCR_BASE + 0x50) -#define MCHP_PCR_CLK_REQ1 REG32(MCHP_PCR_BASE + 0x54) -#define MCHP_PCR_CLK_REQ2 REG32(MCHP_PCR_BASE + 0x58) -#define MCHP_PCR_CLK_REQ3 REG32(MCHP_PCR_BASE + 0x5C) -#define MCHP_PCR_CLK_REQ4 REG32(MCHP_PCR_BASE + 0x60) -#define MCHP_PCR_RST_EN0 REG32(MCHP_PCR_BASE + 0x70) -#define MCHP_PCR_RST_EN1 REG32(MCHP_PCR_BASE + 0x74) -#define MCHP_PCR_RST_EN2 REG32(MCHP_PCR_BASE + 0x78) -#define MCHP_PCR_RST_EN3 REG32(MCHP_PCR_BASE + 0x7C) -#define MCHP_PCR_RST_EN4 REG32(MCHP_PCR_BASE + 0x80) -#define MCHP_PCR_SLP_EN(x) REG32(MCHP_PCR_BASE + 0x30 + ((x)<<2)) -#define MCHP_PCR_CLK_REQ(x) REG32(MCHP_PCR_BASE + 0x50 + ((x)<<2)) -#define MCHP_PCR_RST_EN(x) REG32(MCHP_PCR_BASE + 0x70 + ((x)<<2)) - -/* Bit definitions for MCHP_PCR_SYS_SLP_CTL */ -#define MCHP_PCR_SYS_SLP_LIGHT (0ul << 0) -#define MCHP_PCR_SYS_SLP_HEAVY (1ul << 0) -#define MCHP_PCR_SYS_SLP_ALL (1ul << 3) -/* - * Set/clear PCR sleep enable bit for single device - * d bits[10:8] = register 0 - 4 - * d bits[4:0] = register bit position - */ -#define MCHP_PCR_SLP_EN_DEV(d) \ - (MCHP_PCR_SLP_EN(((d) >> 8) & 0x07) |= (1ul << ((d) & 0x1f))) -#define MCHP_PCR_SLP_DIS_DEV(d) \ - (MCHP_PCR_SLP_EN(((d) >> 8) & 0x07) &= ~(1ul << ((d) & 0x1f))) -/* - * Set/clear bit pattern specified by mask in a single PCR sleep enable - * register. - * id = zero based ID of sleep enable register (0-4) - * m = bit mask of bits to change - */ -#define MCHP_PCR_SLP_EN_DEV_MASK(id, m) (MCHP_PCR_SLP_EN((id)) |= (m)) -#define MCHP_PCR_SLP_DIS_DEV_MASK(id, m) (MCHP_PCR_SLP_EN((id)) &= ~(m)) -/* Slow Clock Control Mask */ -#define MCHP_PCR_SLOW_CLK_CTL_MASK 0x03FFul - -/* TFDP */ -#define MCHP_TFDP_DATA REG8(MCHP_TFDP_BASE + 0x00) -#define MCHP_TFDP_CTRL REG8(MCHP_TFDP_BASE + 0x04) - -/* UART */ -#define MCHP_UART_ACT(x) REG8(MCHP_UART_CONFIG_BASE(x) + 0x30) -#define MCHP_UART_CFG(x) REG8(MCHP_UART_CONFIG_BASE(x) + 0xf0) -/* DLAB=0 */ -#define MCHP_UART_RB(x) /*R*/ REG8(MCHP_UART_RUNTIME_BASE(x) + 0x0) -#define MCHP_UART_TB(x) /*W*/ REG8(MCHP_UART_RUNTIME_BASE(x) + 0x0) -#define MCHP_UART_IER(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x1) -/* DLAB=1 */ -#define MCHP_UART_PBRG0(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x0) -#define MCHP_UART_PBRG1(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x1) -#define MCHP_UART_FCR(x) /*W*/ REG8(MCHP_UART_RUNTIME_BASE(x) + 0x2) -#define MCHP_UART_IIR(x) /*R*/ REG8(MCHP_UART_RUNTIME_BASE(x) + 0x2) -#define MCHP_UART_LCR(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x3) -#define MCHP_UART_MCR(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x4) -#define MCHP_UART_LSR(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x5) -#define MCHP_UART_MSR(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x6) -#define MCHP_UART_SCR(x) REG8(MCHP_UART_RUNTIME_BASE(x) + 0x7) -/* Bit defines for MCHP_UARTx_LSR */ -#define MCHP_LSR_TX_EMPTY BIT(5) - -/* Timer */ -#define MCHP_TMR16_CNT(x) REG32(MCHP_TMR16_BASE(x) + 0x0) -#define MCHP_TMR16_PRE(x) REG32(MCHP_TMR16_BASE(x) + 0x4) -#define MCHP_TMR16_STS(x) REG32(MCHP_TMR16_BASE(x) + 0x8) -#define MCHP_TMR16_IEN(x) REG32(MCHP_TMR16_BASE(x) + 0xc) -#define MCHP_TMR16_CTL(x) REG32(MCHP_TMR16_BASE(x) + 0x10) -#define MCHP_TMR32_CNT(x) REG32(MCHP_TMR32_BASE(x) + 0x0) -#define MCHP_TMR32_PRE(x) REG32(MCHP_TMR32_BASE(x) + 0x4) -#define MCHP_TMR32_STS(x) REG32(MCHP_TMR32_BASE(x) + 0x8) -#define MCHP_TMR32_IEN(x) REG32(MCHP_TMR32_BASE(x) + 0xc) -#define MCHP_TMR32_CTL(x) REG32(MCHP_TMR32_BASE(x) + 0x10) - -/* RTimer */ -#define MCHP_RTMR_COUNTER REG32(MCHP_RTMR_BASE + 0x00) -#define MCHP_RTMR_PRELOAD REG32(MCHP_RTMR_BASE + 0x04) -#define MCHP_RTMR_CONTROL REG8(MCHP_RTMR_BASE + 0x08) -#define MCHP_RTMR_SOFT_INTR REG8(MCHP_RTMR_BASE + 0x0c) - -/* Watch dog timer */ -#define MCHP_WDG_LOAD REG16(MCHP_WDG_BASE + 0x0) -#define MCHP_WDG_CTL REG16(MCHP_WDG_BASE + 0x4) -#define MCHP_WDG_KICK REG8(MCHP_WDG_BASE + 0x8) -#define MCHP_WDG_CNT REG16(MCHP_WDG_BASE + 0xc) -#define MCHP_WDT_CTL_ENABLE BIT(0) -#define MCHP_WDT_CTL_HTMR_STALL_EN BIT(2) -#define MCHP_WDT_CTL_WKTMR_STALL_EN BIT(3) -#define MCHP_WDT_CTL_JTAG_STALL_EN BIT(4) - -/* Blinking-Breathing LED */ -#define MCHP_BBLED_CONFIG(x) REG32(MCHP_BBLED_BASE(x) + 0x00) -#define MCHP_BBLED_LIMITS(x) REG32(MCHP_BBLED_BASE(x) + 0x04) -#define MCHP_BBLED_LIMIT_MIN(x) REG8(MCHP_BBLED_BASE(x) + 0x04) -#define MCHP_BBLED_LIMIT_MAX(x) REG8(MCHP_BBLED_BASE(x) + 0x06) -#define MCHP_BBLED_DELAY(x) REG32(MCHP_BBLED_BASE(x) + 0x08) -#define MCHP_BBLED_UPDATE_STEP(x) REG32(MCHP_BBLED_BASE(x) + 0x0C) -#define MCHP_BBLED_UPDATE_INTV(x) REG32(MCHP_BBLED_BASE(x) + 0x10) -#define MCHP_BBLED_OUTPUT_DLY(x) REG8(MCHP_BBLED_BASE(x) + 0x14) -/* BBLED Configuration Register */ -#define MCHP_BBLED_ASYMMETRIC BIT(16) -#define MCHP_BBLED_WDT_RELOAD_BITPOS 8 -#define MCHP_BBLED_WDT_RELOAD_MASK0 0xFFul -#define MCHP_BBLED_WDT_RELOAD_MASK (0xFFul << 8) -#define MCHP_BBLED_RESET BIT(7) -#define MCHP_BBLED_EN_UPDATE BIT(6) -#define MCHP_BBLED_PWM_SIZE_BITPOS 4 -#define MCHP_BBLED_PWM_SIZE_MASK0 0x03ul -#define MCHP_BBLED_PWM_SIZE_MASK (0x03ul << 4) -#define MCHP_BBLED_PWM_SIZE_6BIT (0x02ul << 4) -#define MCHP_BBLED_PWM_SIZE_7BIT (0x01ul << 4) -#define MCHP_BBLED_PWM_SIZE_8BIT (0x00ul << 4) -#define MCHP_BBLED_SYNC BIT(3) -#define MCHP_BBLED_CLK_48M BIT(2) -#define MCHP_BBLED_CLK_32K 0 -#define MCHP_BBLED_CTRL_MASK 0x03ul -#define MCHP_BBLED_CTRL_ALWAYS_ON 0x03ul -#define MCHP_BBLED_CTRL_BLINK 0x02ul -#define MCHP_BBLED_CTRL_BREATHE 0x01ul -#define MCHP_BBLED_CTRL_OFF 0x00ul -/* BBLED Delay Register */ -#define MCHP_BBLED_DLY_MASK 0x0FFFul -#define MCHP_BBLED_DLY_LO_BITPOS 0 -#define MCHP_BBLED_DLY_LO_MASK 0x0FFFul -#define MCHP_BBLED_DLY_HI_BITPOS 12 -#define MCHP_BBLED_DLY_HI_MASK (0x0FFFul << 12) -/* - * BBLED Update Step Register - * 8 update fields numbered 0 - 7 - */ -#define MCHP_BBLED_UPD_STEP_MASK0 0x0Ful -#define MCHP_BBLED_UPD_STEP_MASK(u) (0x0Ful << (((u) & 0x07) + 4)) -/* - * BBLED Update Interval Register - * 8 interval fields numbered 0 - 7 - */ -#define MCHP_BBLED_UPD_INTV_MASK0 0x0Ful -#define MCHP_BBLED_UPD_INTV_MASK(i) (0x0Ful << (((i) & 0x07) + 4)) - -/* EMI */ -#define MCHP_EMI_H2E_MBX(n) REG8(MCHP_EMI_BASE(n) + 0x0) -#define MCHP_EMI_E2H_MBX(n) REG8(MCHP_EMI_BASE(n) + 0x1) -#define MCHP_EMI_MBA0(n) REG32(MCHP_EMI_BASE(n) + 0x4) -#define MCHP_EMI_MRL0(n) REG16(MCHP_EMI_BASE(n) + 0x8) -#define MCHP_EMI_MWL0(n) REG16(MCHP_EMI_BASE(n) + 0xa) -#define MCHP_EMI_MBA1(n) REG32(MCHP_EMI_BASE(n) + 0xc) -#define MCHP_EMI_MRL1(n) REG16(MCHP_EMI_BASE(n) + 0x10) -#define MCHP_EMI_MWL1(n) REG16(MCHP_EMI_BASE(n) + 0x12) -#define MCHP_EMI_ISR(n) REG16(MCHP_EMI_BASE(n) + 0x14) -#define MCHP_EMI_HCE(n) REG16(MCHP_EMI_BASE(n) + 0x16) -#define MCHP_EMI_ISR_B0(n) REG8(MCHP_EMI_RT_BASE(n) + 0x8) -#define MCHP_EMI_ISR_B1(n) REG8(MCHP_EMI_RT_BASE(n) + 0x9) -#define MCHP_EMI_IMR_B0(n) REG8(MCHP_EMI_RT_BASE(n) + 0xa) -#define MCHP_EMI_IMR_B1(n) REG8(MCHP_EMI_RT_BASE(n) + 0xb) - -/* Mailbox */ -#define MCHP_MBX_INDEX REG8(MCHP_MBX_RT_BASE + 0x0) -#define MCHP_MBX_DATA REG8(MCHP_MBX_RT_BASE + 0x1) -#define MCHP_MBX_H2E_MBX REG8(MCHP_MBX_BASE + 0x0) -#define MCHP_MBX_E2H_MBX REG8(MCHP_MBX_BASE + 0x4) -#define MCHP_MBX_ISR REG8(MCHP_MBX_BASE + 0x8) -#define MCHP_MBX_IMR REG8(MCHP_MBX_BASE + 0xc) -#define MCHP_MBX_REG(x) REG8(MCHP_MBX_BASE + 0x10 + (x)) - -/* PWM */ -#define MCHP_PWM_ON(x) REG32(MCHP_PWM_BASE(x) + 0x00) -#define MCHP_PWM_OFF(x) REG32(MCHP_PWM_BASE(x) + 0x04) -#define MCHP_PWM_CFG(x) REG32(MCHP_PWM_BASE(x) + 0x08) - -/* TACH */ -#define MCHP_TACH_CTRL(x) REG32(MCHP_TACH_BASE(x)) -#define MCHP_TACH_CTRL_LO(x) REG16(MCHP_TACH_BASE(x) + 0x00) -#define MCHP_TACH_CTRL_CNT(x) REG16(MCHP_TACH_BASE(x) + 0x02) -#define MCHP_TACH_STATUS(x) REG8(MCHP_TACH_BASE(x) + 0x04) -#define MCHP_TACH_LIMIT_HI(x) REG16(MCHP_TACH_BASE(x) + 0x08) -#define MCHP_TACH_LIMIT_LO(x) REG16(MCHP_TACH_BASE(x) + 0x0C) - -/* ACPI */ -#define MCHP_ACPI_EC_EC2OS(x, y) REG8(MCHP_ACPI_EC_BASE(x) + 0x100 + (y)) -#define MCHP_ACPI_EC_STATUS(x) REG8(MCHP_ACPI_EC_BASE(x) + 0x104) -#define MCHP_ACPI_EC_BYTE_CTL(x) REG8(MCHP_ACPI_EC_BASE(x) + 0x105) -#define MCHP_ACPI_EC_OS2EC(x, y) REG8(MCHP_ACPI_EC_BASE(x) + 0x108 + (y)) -#define MCHP_ACPI_PM1_STS1 REG8(MCHP_ACPI_PM_RT_BASE + 0x0) -#define MCHP_ACPI_PM1_STS2 REG8(MCHP_ACPI_PM_RT_BASE + 0x1) -#define MCHP_ACPI_PM1_EN1 REG8(MCHP_ACPI_PM_RT_BASE + 0x2) -#define MCHP_ACPI_PM1_EN2 REG8(MCHP_ACPI_PM_RT_BASE + 0x3) -#define MCHP_ACPI_PM1_CTL1 REG8(MCHP_ACPI_PM_RT_BASE + 0x4) -#define MCHP_ACPI_PM1_CTL2 REG8(MCHP_ACPI_PM_RT_BASE + 0x5) -#define MCHP_ACPI_PM2_CTL1 REG8(MCHP_ACPI_PM_RT_BASE + 0x6) -#define MCHP_ACPI_PM2_CTL2 REG8(MCHP_ACPI_PM_RT_BASE + 0x7) -#define MCHP_ACPI_PM_STS REG8(MCHP_ACPI_PM_EC_BASE + 0x10) - -/* 8042 */ -#define MCHP_8042_OBF_CLR REG8(MCHP_8042_BASE + 0x0) -#define MCHP_8042_H2E REG8(MCHP_8042_BASE + 0x100) -#define MCHP_8042_E2H REG8(MCHP_8042_BASE + 0x100) -#define MCHP_8042_STS REG8(MCHP_8042_BASE + 0x104) -#define MCHP_8042_KB_CTRL REG8(MCHP_8042_BASE + 0x108) -#define MCHP_8042_PCOBF REG8(MCHP_8042_BASE + 0x114) -#define MCHP_8042_ACT REG8(MCHP_8042_BASE + 0x330) - -/* PROCHOT */ -#define MCHP_PCHOT_CUM_CNT REG32(MCHP_PROCHOT_BASE + 0x00) -#define MCHP_PCHOT_DTY_CYC_CNT REG32(MCHP_PROCHOT_BASE + 0x04) -#define MCHP_PCHOT_DTY_PRD_CNT REG32(MCHP_PROCHOT_BASE + 0x08) -#define MCHP_PCHOT_STS_CTRL REG32(MCHP_PROCHOT_BASE + 0x0C) -#define MCHP_PCHOT_ASERT_CNT REG32(MCHP_PROCHOT_BASE + 0x10) -#define MCHP_PCHOT_ASERT_CNT_LMT REG32(MCHP_PROCHOT_BASE + 0x14) -#define MCHP_PCHOT_TEST REG32(MCHP_PROCHOT_BASE + 0x18) - -/* I2C registers access given controller base address */ -#define MCHP_I2C_CTRL(addr) REG8(addr) -#define MCHP_I2C_STATUS(addr) REG8(addr) -#define MCHP_I2C_OWN_ADDR(addr) REG16(addr + 0x4) -#define MCHP_I2C_DATA(addr) REG8(addr + 0x8) -#define MCHP_I2C_MASTER_CMD(addr) REG32(addr + 0xc) -#define MCHP_I2C_SLAVE_CMD(addr) REG32(addr + 0x10) -#define MCHP_I2C_PEC(addr) REG8(addr + 0x14) -#define MCHP_I2C_DATA_TIM_2(addr) REG8(addr + 0x18) -#define MCHP_I2C_COMPLETE(addr) REG32(addr + 0x20) -#define MCHP_I2C_IDLE_SCALE(addr) REG32(addr + 0x24) -#define MCHP_I2C_CONFIG(addr) REG32(addr + 0x28) -#define MCHP_I2C_BUS_CLK(addr) REG16(addr + 0x2c) -#define MCHP_I2C_BLK_ID(addr) REG8(addr + 0x30) -#define MCHP_I2C_REV(addr) REG8(addr + 0x34) -#define MCHP_I2C_BB_CTRL(addr) REG8(addr + 0x38) -#define MCHP_I2C_TST_DATA_TIM(addr) REG32(addr + 0x3c) -#define MCHP_I2C_DATA_TIM(addr) REG32(addr + 0x40) -#define MCHP_I2C_TOUT_SCALE(addr) REG32(addr + 0x44) -#define MCHP_I2C_SLAVE_TX_BUF(addr) REG8(addr + 0x48) -#define MCHP_I2C_SLAVE_RX_BUF(addr) REG8(addr + 0x4c) -#define MCHP_I2C_MASTER_TX_BUF(addr) REG8(addr + 0x50) -#define MCHP_I2C_MASTER_RX_BUF(addr) REG8(addr + 0x54) -#define MCHP_I2C_TEST_1(addr) REG32(addr + 0x58) -#define MCHP_I2C_TEST_2(addr) REG32(addr + 0x5c) -#define MCHP_I2C_WAKE_STS(addr) REG8(addr + 0x60) -#define MCHP_I2C_WAKE_EN(addr) REG8(addr + 0x64) -#define MCHP_I2C_TEST_3(addr) REG32(addr + 0x68) - -/* Keyboard scan matrix */ -#define MCHP_KS_KSO_SEL REG32(MCHP_KEYSCAN_BASE + 0x4) -#define MCHP_KS_KSI_INPUT REG32(MCHP_KEYSCAN_BASE + 0x8) -#define MCHP_KS_KSI_STATUS REG32(MCHP_KEYSCAN_BASE + 0xc) -#define MCHP_KS_KSI_INT_EN REG32(MCHP_KEYSCAN_BASE + 0x10) -#define MCHP_KS_EXT_CTRL REG32(MCHP_KEYSCAN_BASE + 0x14) - -/* ADC */ -#define MCHP_ADC_CTRL REG32(MCHP_ADC_BASE + 0x0) -#define MCHP_ADC_DELAY REG32(MCHP_ADC_BASE + 0x4) -#define MCHP_ADC_STS REG32(MCHP_ADC_BASE + 0x8) -#define MCHP_ADC_SINGLE REG32(MCHP_ADC_BASE + 0xc) -#define MCHP_ADC_REPEAT REG32(MCHP_ADC_BASE + 0x10) -#define MCHP_ADC_READ(x) REG32(MCHP_ADC_BASE + 0x14 + ((x) * 0x4)) - -/* Hibernation timer */ -#define MCHP_HTIMER_PRELOAD(x) REG16(MCHP_HTIMER_ADDR(x) + 0x0) -#define MCHP_HTIMER_CONTROL(x) REG16(MCHP_HTIMER_ADDR(x) + 0x4) -#define MCHP_HTIMER_COUNT(x) REG16(MCHP_HTIMER_ADDR(x) + 0x8) - -/* Week timer and BGPO control */ -#define MCHP_WKTIMER_CTRL REG32(MCHP_WKTIMER_BASE + 0) -#define MCHP_WKTIMER_ALARM_CNT REG32(MCHP_WKTIMER_BASE + 0x04) -#define MCHP_WKTIMER_COMPARE REG32(MCHP_WKTIMER_BASE + 0x08) -#define MCHP_WKTIMER_CLK_DIV REG32(MCHP_WKTIMER_BASE + 0x0c) -#define MCHP_WKTIMER_SUBSEC_ISEL REG32(MCHP_WKTIMER_BASE + 0x10) -#define MCHP_WKTIMER_SUBWK_CTRL REG32(MCHP_WKTIMER_BASE + 0x14) -#define MCHP_WKTIMER_SUBWK_ALARM REG32(MCHP_WKTIMER_BASE + 0x18) -#define MCHP_WKTIMER_BGPO_DATA REG32(MCHP_WKTIMER_BASE + 0x1c) -#define MCHP_WKTIMER_BGPO_POWER REG32(MCHP_WKTIMER_BASE + 0x20) -#define MCHP_WKTIMER_BGPO_RESET REG32(MCHP_WKTIMER_BASE + 0x24) - -/* Quad Master SPI (QMSPI) */ -#define MCHP_QMSPI0_MODE REG32(MCHP_QMSPI0_BASE + 0x00) -#define MCHP_QMSPI0_MODE_ACT_SRST REG8(MCHP_QMSPI0_BASE + 0x00) -#define MCHP_QMSPI0_MODE_SPI_MODE REG8(MCHP_QMSPI0_BASE + 0x01) -#define MCHP_QMSPI0_MODE_FDIV REG8(MCHP_QMSPI0_BASE + 0x02) -#define MCHP_QMSPI0_CTRL REG32(MCHP_QMSPI0_BASE + 0x04) -#define MCHP_QMSPI0_EXE REG8(MCHP_QMSPI0_BASE + 0x08) -#define MCHP_QMSPI0_IFCTRL REG8(MCHP_QMSPI0_BASE + 0x0C) -#define MCHP_QMSPI0_STS REG32(MCHP_QMSPI0_BASE + 0x10) -#define MCHP_QMSPI0_BUFCNT_STS REG32(MCHP_QMSPI0_BASE + 0x14) -#define MCHP_QMSPI0_IEN REG32(MCHP_QMSPI0_BASE + 0x18) -#define MCHP_QMSPI0_BUFCNT_TRIG REG32(MCHP_QMSPI0_BASE + 0x1C) -#define MCHP_QMSPI0_TX_FIFO_ADDR (MCHP_QMSPI0_BASE + 0x20) -#define MCHP_QMSPI0_TX_FIFO8 REG8(MCHP_QMSPI0_BASE + 0x20) -#define MCHP_QMSPI0_TX_FIFO16 REG16(MCHP_QMSPI0_BASE + 0x20) -#define MCHP_QMSPI0_TX_FIFO32 REG32(MCHP_QMSPI0_BASE + 0x20) -#define MCHP_QMSPI0_RX_FIFO_ADDR (MCHP_QMSPI0_BASE + 0x24) -#define MCHP_QMSPI0_RX_FIFO8 REG8(MCHP_QMSPI0_BASE + 0x24) -#define MCHP_QMSPI0_RX_FIFO16 REG16(MCHP_QMSPI0_BASE + 0x24) -#define MCHP_QMSPI0_RX_FIFO32 REG32(MCHP_QMSPI0_BASE + 0x24) -#define MCHP_QMSPI0_DESCR(x) \ - REG32(MCHP_QMSPI0_BASE + 0x30 + ((x) * 4)) -/* Bits in MCHP_QMSPI0_MODE */ -#define MCHP_QMSPI_M_ACTIVATE BIT(0) -#define MCHP_QMSPI_M_SOFT_RESET BIT(1) -#define MCHP_QMSPI_M_SPI_MODE_MASK (0x7ul << 8) -#define MCHP_QMSPI_M_SPI_MODE0 (0x0ul << 8) -#define MCHP_QMSPI_M_SPI_MODE3 (0x3ul << 8) -#define MCHP_QMSPI_M_SPI_MODE0_48M (0x4ul << 8) -#define MCHP_QMSPI_M_SPI_MODE3_48M (0x7ul << 8) -/* - * clock divider is 8-bit field in bits[23:16] - * [1, 255] -> 48MHz / [1, 255], 0 -> 48MHz / 256 - */ -#define MCHP_QMSPI_M_CLKDIV_BITPOS 16 -#define MCHP_QMSPI_M_CLKDIV_48M (1ul << 16) -#define MCHP_QMSPI_M_CLKDIV_24M (2ul << 16) -#define MCHP_QMSPI_M_CLKDIV_16M (3ul << 16) -#define MCHP_QMSPI_M_CLKDIV_12M (4ul << 16) -#define MCHP_QMSPI_M_CLKDIV_8M (6ul << 16) -#define MCHP_QMSPI_M_CLKDIV_6M (8ul << 16) -#define MCHP_QMSPI_M_CLKDIV_1M (48ul << 16) -#define MCHP_QMSPI_M_CLKDIV_188K (0x100ul << 16) -/* Bits in MCHP_QMSPI0_CTRL and MCHP_QMSPI_DESCR(x) */ -#define MCHP_QMSPI_C_1X (0ul << 0) /* Full Duplex */ -#define MCHP_QMSPI_C_2X (1ul << 0) /* Dual IO */ -#define MCHP_QMSPI_C_4X (2ul << 0) /* Quad IO */ -#define MCHP_QMSPI_C_TX_DIS (0ul << 2) -#define MCHP_QMSPI_C_TX_DATA (1ul << 2) -#define MCHP_QMSPI_C_TX_ZEROS (2ul << 2) -#define MCHP_QMSPI_C_TX_ONES (3ul << 2) -#define MCHP_QMSPI_C_TX_DMA_DIS (0ul << 4) -#define MCHP_QMSPI_C_TX_DMA_1B (1ul << 4) -#define MCHP_QMSPI_C_TX_DMA_2B (2ul << 4) -#define MCHP_QMSPI_C_TX_DMA_4B (3ul << 4) -#define MCHP_QMSPI_C_TX_DMA_MASK (3ul << 4) -#define MCHP_QMSPI_C_RX_DIS 0 -#define MCHP_QMSPI_C_RX_EN BIT(6) -#define MCHP_QMSPI_C_RX_DMA_DIS (0ul << 7) -#define MCHP_QMSPI_C_RX_DMA_1B (1ul << 7) -#define MCHP_QMSPI_C_RX_DMA_2B (2ul << 7) -#define MCHP_QMSPI_C_RX_DMA_4B (3ul << 7) -#define MCHP_QMSPI_C_RX_DMA_MASK (3ul << 7) -#define MCHP_QMSPI_C_NO_CLOSE 0 -#define MCHP_QMSPI_C_CLOSE BIT(9) -#define MCHP_QMSPI_C_XFRU_BITS (0ul << 10) -#define MCHP_QMSPI_C_XFRU_1B (1ul << 10) -#define MCHP_QMSPI_C_XFRU_4B (2ul << 10) -#define MCHP_QMSPI_C_XFRU_16B (3ul << 10) -#define MCHP_QMSPI_C_XFRU_MASK (3ul << 10) -/* Control */ -#define MCHP_QMSPI_C_START_DESCR_BITPOS 12 -#define MCHP_QMSPI_C_START_DESCR_MASK (0xFul << 12) -#define MCHP_QMSPI_C_DESCR_MODE_EN BIT(16) -/* Descriptors, indicates the current descriptor is the last */ -#define MCHP_QMSPI_C_NEXT_DESCR_BITPOS 12 -#define MCHP_QMSPI_C_NEXT_DESCR_MASK0 0xFul -#define MCHP_QMSPI_C_NEXT_DESCR_MASK \ - ((MCHP_QMSPI_C_NEXT_DESCR_MASK0) << 12) -#define MCHP_QMSPI_C_NXTD(n) ((n) << 12) -#define MCHP_QMSPI_C_DESCR_LAST BIT(16) -/* - * Total transfer length is the count in this field - * scaled by units in MCHP_QMSPI_CTRL_XFRU_xxxx - */ -#define MCHP_QMSPI_C_NUM_UNITS_BITPOS 17 -#define MCHP_QMSPI_C_MAX_UNITS 0x7ffful -#define MCHP_QMSPI_C_NUM_UNITS_MASK0 0x7ffful -#define MCHP_QMSPI_C_NUM_UNITS_MASK \ - ((MCHP_QMSPI_C_NUM_UNITS_MASK0) << 17) -/* Bits in MCHP_QMSPI0_EXE */ -#define MCHP_QMSPI_EXE_START BIT(0) -#define MCHP_QMSPI_EXE_STOP BIT(1) -#define MCHP_QMSPI_EXE_CLR_FIFOS BIT(2) -/* MCHP QMSPI FIFO Sizes */ -#define MCHP_QMSPI_TX_FIFO_LEN 8 -#define MCHP_QMSPI_RX_FIFO_LEN 8 -/* Bits in MCHP_QMSPI0_STS and MCHP_QMSPI0_IEN */ -#define MCHP_QMSPI_STS_DONE BIT(0) -#define MCHP_QMSPI_STS_DMA_DONE BIT(1) -#define MCHP_QMSPI_STS_TX_BUFF_ERR BIT(2) -#define MCHP_QMSPI_STS_RX_BUFF_ERR BIT(3) -#define MCHP_QMSPI_STS_PROG_ERR BIT(4) -#define MCHP_QMSPI_STS_TX_BUFF_FULL BIT(8) -#define MCHP_QMSPI_STS_TX_BUFF_EMPTY BIT(9) -#define MCHP_QMSPI_STS_TX_BUFF_REQ BIT(10) -#define MCHP_QMSPI_STS_TX_BUFF_STALL BIT(11) /* status only */ -#define MCHP_QMSPI_STS_RX_BUFF_FULL BIT(12) -#define MCHP_QMSPI_STS_RX_BUFF_EMPTY BIT(13) -#define MCHP_QMSPI_STS_RX_BUFF_REQ BIT(14) -#define MCHP_QMSPI_STS_RX_BUFF_STALL BIT(15) /* status only */ -#define MCHP_QMSPI_STS_ACTIVE BIT(16) /* status only */ -/* Bits in MCHP_QMSPI0_BUFCNT (read-only) */ -#define MCHP_QMSPI_BUFCNT_TX_BITPOS 0 -#define MCHP_QMSPI_BUFCNT_TX_MASK 0xFFFFul -#define MCHP_QMSPI_BUFCNT_RX_BITPOS 16 -#define MCHP_QMSPI_BUFCNT_RX_MASK (0xFFFFul << 16) -#define MCHP_QMSPI0_ID 0 - -/* eSPI */ -/* eSPI IO Component */ -/* Peripheral Channel Registers */ -#define MCHP_ESPI_PC_STATUS REG32(MCHP_ESPI_IO_BASE + 0x114) -#define MCHP_ESPI_PC_IEN REG32(MCHP_ESPI_IO_BASE + 0x118) -#define MCHP_ESPI_PC_BAR_INHIBIT_LO REG32(MCHP_ESPI_IO_BASE + 0x120) -#define MCHP_ESPI_PC_BAR_INHIBIT_HI REG32(MCHP_ESPI_IO_BASE + 0x124) -#define MCHP_ESPI_PC_BAR_INIT_LD_0C REG16(MCHP_ESPI_IO_BASE + 0x128) -#define MCHP_ESPI_PC_EC_IRQ REG8(MCHP_ESPI_IO_BASE + 0x12C) -/* LTR Registers */ -#define MCHP_ESPI_IO_LTR_STATUS REG16(MCHP_ESPI_IO_BASE + 0x220) -#define MCHP_ESPI_IO_LTR_IEN REG8(MCHP_ESPI_IO_BASE + 0x224) -#define MCHP_ESPI_IO_LTR_CTRL REG16(MCHP_ESPI_IO_BASE + 0x228) -#define MCHP_ESPI_IO_LTR_MSG REG16(MCHP_ESPI_IO_BASE + 0x22C) -/* OOB Channel Registers */ -#define MCHP_ESPI_OOB_RX_ADDR_LO REG32(MCHP_ESPI_IO_BASE + 0x240) -#define MCHP_ESPI_OOB_RX_ADDR_HI REG32(MCHP_ESPI_IO_BASE + 0x244) -#define MCHP_ESPI_OOB_TX_ADDR_LO REG32(MCHP_ESPI_IO_BASE + 0x248) -#define MCHP_ESPI_OOB_TX_ADDR_HI REG32(MCHP_ESPI_IO_BASE + 0x24C) -#define MCHP_ESPI_OOB_RX_LEN REG32(MCHP_ESPI_IO_BASE + 0x250) -#define MCHP_ESPI_OOB_TX_LEN REG32(MCHP_ESPI_IO_BASE + 0x254) -#define MCHP_ESPI_OOB_RX_CTL REG32(MCHP_ESPI_IO_BASE + 0x258) -#define MCHP_ESPI_OOB_RX_IEN REG8(MCHP_ESPI_IO_BASE + 0x25C) -#define MCHP_ESPI_OOB_RX_STATUS REG32(MCHP_ESPI_IO_BASE + 0x260) -#define MCHP_ESPI_OOB_TX_CTL REG32(MCHP_ESPI_IO_BASE + 0x264) -#define MCHP_ESPI_OOB_TX_IEN REG8(MCHP_ESPI_IO_BASE + 0x268) -#define MCHP_ESPI_OOB_TX_STATUS REG32(MCHP_ESPI_IO_BASE + 0x26C) -/* Flash Channel Registers */ -#define MCHP_ESPI_FC_ADDR_LO REG32(MCHP_ESPI_IO_BASE + 0x280) -#define MCHP_ESPI_FC_ADDR_HI REG32(MCHP_ESPI_IO_BASE + 0x284) -#define MCHP_ESPI_FC_BUF_ADDR_LO REG32(MCHP_ESPI_IO_BASE + 0x288) -#define MCHP_ESPI_FC_BUF_ADDR_HI REG32(MCHP_ESPI_IO_BASE + 0x28C) -#define MCHP_ESPI_FC_XFR_LEN REG32(MCHP_ESPI_IO_BASE + 0x290) -#define MCHP_ESPI_FC_CTL REG32(MCHP_ESPI_IO_BASE + 0x294) -#define MCHP_ESPI_FC_IEN REG8(MCHP_ESPI_IO_BASE + 0x298) -#define MCHP_ESPI_FC_CONFIG REG32(MCHP_ESPI_IO_BASE + 0x29C) -#define MCHP_ESPI_FC_STATUS REG32(MCHP_ESPI_IO_BASE + 0x2A0) -/* VWire Channel Registers */ -#define MCHP_ESPI_VW_STATUS REG8(MCHP_ESPI_IO_BASE + 0x2B0) -/* Global Registers */ -/* 32-bit register containing CAP_ID/CAP0/CAP1/PC_CAP */ -#define MCHP_ESPI_IO_REG32_A REG32(MCHP_ESPI_IO_BASE + 0x2E0) -#define MCHP_ESPI_IO_CAP_ID REG8(MCHP_ESPI_IO_BASE + 0x2E0) -#define MCHP_ESPI_IO_CAP0 REG8(MCHP_ESPI_IO_BASE + 0x2E1) -#define MCHP_ESPI_IO_CAP1 REG8(MCHP_ESPI_IO_BASE + 0x2E2) -#define MCHP_ESPI_IO_PC_CAP REG8(MCHP_ESPI_IO_BASE + 0x2E3) -/* 32-bit register containing VW_CAP/OOB_CAP/FC_CAP/PC_READY */ -#define MCHP_ESPI_IO_REG32_B REG32(MCHP_ESPI_IO_BASE + 0x2E4) -#define MCHP_ESPI_IO_VW_CAP REG8(MCHP_ESPI_IO_BASE + 0x2E4) -#define MCHP_ESPI_IO_OOB_CAP REG8(MCHP_ESPI_IO_BASE + 0x2E5) -#define MCHP_ESPI_IO_FC_CAP REG8(MCHP_ESPI_IO_BASE + 0x2E6) -#define MCHP_ESPI_IO_PC_READY REG8(MCHP_ESPI_IO_BASE + 0x2E7) -/* 32-bit register containing OOB_READY/FC_READY/RESET_STATUS/RESET_IEN */ -#define MCHP_ESPI_IO_REG32_C REG32(MCHP_ESPI_IO_BASE + 0x2E8) -#define MCHP_ESPI_IO_OOB_READY REG8(MCHP_ESPI_IO_BASE + 0x2E8) -#define MCHP_ESPI_IO_FC_READY REG8(MCHP_ESPI_IO_BASE + 0x2E9) -#define MCHP_ESPI_IO_RESET_STATUS REG8(MCHP_ESPI_IO_BASE + 0x2EA) -#define MCHP_ESPI_IO_RESET_IEN REG8(MCHP_ESPI_IO_BASE + 0x2EB) -/* 32-bit register containing PLTRST_SRC/VW_READY */ -#define MCHP_ESPI_IO_REG32_D REG32(MCHP_ESPI_IO_BASE + 0x2EC) -#define MCHP_ESPI_IO_PLTRST_SRC REG8(MCHP_ESPI_IO_BASE + 0x2EC) -#define MCHP_ESPI_IO_VW_READY REG8(MCHP_ESPI_IO_BASE + 0x2ED) -/* Bits in MCHP_ESPI_IO_CAP0 */ -#define MCHP_ESPI_CAP0_PC_SUPP 0x01 -#define MCHP_ESPI_CAP0_VW_SUPP 0x02 -#define MCHP_ESPI_CAP0_OOB_SUPP 0x04 -#define MCHP_ESPI_CAP0_FC_SUPP 0x08 -#define MCHP_ESPI_CAP0_ALL_CHAN_SUPP (MCHP_ESPI_CAP0_PC_SUPP | \ - MCHP_ESPI_CAP0_VW_SUPP | \ - MCHP_ESPI_CAP0_OOB_SUPP | \ - MCHP_ESPI_CAP0_FC_SUPP) -/* Bits in MCHP_ESPI_IO_CAP1 */ -#define MCHP_ESPI_CAP1_RW_MASK 0x37 -#define MCHP_ESPI_CAP1_MAX_FREQ_MASK 0x07 -#define MCHP_ESPI_CAP1_MAX_FREQ_20M 0 -#define MCHP_ESPI_CAP1_MAX_FREQ_25M 1 -#define MCHP_ESPI_CAP1_MAX_FREQ_33M 2 -#define MCHP_ESPI_CAP1_MAX_FREQ_50M 3 -#define MCHP_ESPI_CAP1_MAX_FREQ_66M 4 -#define MCHP_ESPI_CAP1_SINGLE_MODE 0 -#define MCHP_ESPI_CAP1_SINGLE_DUAL_MODE BIT(0) -#define MCHP_ESPI_CAP1_SINGLE_QUAD_MODE BIT(1) -#define MCHP_ESPI_CAP1_ALL_MODE (MCHP_ESPI_CAP1_SINGLE_MODE | \ - MCHP_ESPI_CAP1_SINGLE_DUAL_MODE | \ - MCHP_ESPI_CAP1_SINGLE_QUAD_MODE) -#define MCHP_ESPI_CAP1_IO_BITPOS 4 -#define MCHP_ESPI_CAP1_IO_MASK0 0x03 -#define MCHP_ESPI_CAP1_IO_MASK (0x03ul << MCHP_ESPI_CAP1_IO_BITPOS) -#define MCHP_ESPI_CAP1_IO1_VAL 0x00 -#define MCHP_ESPI_CAP1_IO12_VAL 0x01 -#define MCHP_ESPI_CAP1_IO24_VAL 0x02 -#define MCHP_ESPI_CAP1_IO124_VAL 0x03 -#define MCHP_ESPI_CAP1_IO1 (0x00 << 4) -#define MCHP_ESPI_CAP1_IO12 (0x01 << 4) -#define MCHP_ESPI_CAP1_IO24 (0x02 << 4) -#define MCHP_ESPI_CAP1_IO124 (0x03 << 4) -/* Bits in MCHP_ESPI_IO_RESET_STATUS and MCHP_ESPI_IO_RESET_IEN */ -#define MCHP_ESPI_RST_PIN_MASK BIT(1) -#define MCHP_ESPI_RST_CHG_STS BIT(0) -#define MCHP_ESPI_RST_IEN BIT(0) -/* Bits in MCHP_ESPI_IO_PLTRST_SRC */ -#define MCHP_ESPI_PLTRST_SRC_VW 0 -#define MCHP_ESPI_PLTRST_SRC_PIN 1 -/* - * eSPI Slave Activate Register - * bit[0] = 0 de-active block is clock-gates - * bit[0] = 1 block is powered and functional - */ -#define MCHP_ESPI_ACTIVATE REG8(MCHP_ESPI_IO_BASE + 0x330) -/* - * IO BAR's starting at offset 0x134 - * b[16]=virtualized R/W - * b[15:14]=0 reserved RO - * b[13:8]=Logical Device Number RO - * b[7:0]=mask - */ -#define MCHP_ESPI_IO_BAR_CTL(x) \ - REG32(MCHP_ESPI_IO_BASE + ((x) * 4) + 0x134) -/* access mask field of eSPI IO BAR Control register */ -#define MCHP_ESPI_IO_BAR_CTL_MASK(x) \ - REG8(MCHP_ESPI_IO_BASE + ((x) * 4) + 0x134) -/* - * IO BAR's starting at offset 0x334 - * b[31:16] = I/O address - * b[15:1]=0 reserved - * b[0] = valid - */ -#define MCHP_ESPI_IO_BAR(x) REG32(MCHP_ESPI_IO_BASE + ((x) * 4) + 0x334) -#define MCHP_ESPI_IO_BAR_VALID(x) \ - REG8(MCHP_ESPI_IO_BASE + ((x) * 4) + 0x334) -#define MCHP_ESPI_IO_BAR_ADDR_LSB(x) \ - REG8(MCHP_ESPI_IO_BASE + ((x) * 4) + 0x336) -#define MCHP_ESPI_IO_BAR_ADDR_MSB(x) \ - REG8(MCHP_ESPI_IO_BASE + ((x) * 4) + 0x337) -#define MCHP_ESPI_IO_BAR_ADDR(x) \ - REG16(MCHP_ESPI_IO_BASE + ((x) * 4) + 0x336) -/* eSPI Serial IRQ registers */ -#define MCHP_ESPI_IO_SERIRQ_REG(x) REG8(MCHP_ESPI_IO_BASE + 0x3ac + (x)) -/* eSPI Virtual Wire Error Register */ -#define MCHP_ESPI_IO_VW_ERROR REG8(MCHP_ESPI_IO_BASE + 0x3f0) -/* - * eSPI Logical Device Memory Host BAR's to specify Host memory - * base address and valid bit. - * Each Logical Device implementing memory access has an 80-bit register. - * b[0]=Valid - * b[15:1]=0(reserved) - * b[79:16]=eSPI bus memory address(Host address space) - */ -#define MCHP_ESPI_MBAR_VALID(x) \ - REG8(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x130) -#define MCHP_ESPI_MBAR_HOST_ADDR_0_15(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x132) -#define MCHP_ESPI_MBAR_HOST_ADDR_16_31(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x134) -#define MCHP_ESPI_MBAR_HOST_ADDR_32_47(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x136) -#define MCHP_ESPI_MBAR_HOST_ADDR_48_63(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x138) -/* - * eSPI SRAM BAR's - * b[0,3,8:15] = 0 reserved - * b[2:1] = access - * b[7:4] = size - * b[79:16] = Host address - */ -#define MCHP_ESPI_SRAM_BAR_CFG(x) \ - REG8(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x1ac) -#define MCHP_ESPI_SRAM_BAR_ADDR_0_15(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x1ae) -#define MCHP_ESPI_SRAM_BAR_ADDR_16_31(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x1b0) -#define MCHP_ESPI_SRAM_BAR_ADDR_32_47(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x1b2) -#define MCHP_ESPI_SRAM_BAR_ADDR_48_63(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x1b4) -/* eSPI Memory Bus Master Registers */ -#define MCHP_ESPI_BM_STATUS REG32(MCHP_ESPI_MEM_BASE + 0x200) -#define MCHP_ESPI_BM_IEN REG32(MCHP_ESPI_MEM_BASE + 0x204) -#define MCHP_ESPI_BM_CONFIG REG32(MCHP_ESPI_MEM_BASE + 0x208) -#define MCHP_ESPI_BM1_CTL REG32(MCHP_ESPI_MEM_BASE + 0x210) -#define MCHP_ESPI_BM1_HOST_ADDR_LO REG32(MCHP_ESPI_MEM_BASE + 0x214) -#define MCHP_ESPI_BM1_HOST_ADDR_HI REG32(MCHP_ESPI_MEM_BASE + 0x218) -#define MCHP_ESPI_BM1_EC_ADDR REG32(MCHP_ESPI_MEM_BASE + 0x21c) -#define MCHP_ESPI_BM2_CTL REG32(MCHP_ESPI_MEM_BASE + 0x224) -#define MCHP_ESPI_BM2_HOST_ADDR_LO REG32(MCHP_ESPI_MEM_BASE + 0x228) -#define MCHP_ESPI_BM2_HOST_ADDR_HI REG32(MCHP_ESPI_MEM_BASE + 0x22c) -#define MCHP_ESPI_BM2_EC_ADDR REG32(MCHP_ESPI_MEM_BASE + 0x230) -/* - * eSPI Memory BAR's for Logical Devices - * b[0] = Valid - * b[2:1] = access - * b[3] = 0 reserved - * b[7:4] = size - * b[15:8] = 0 reserved - * b[47:16] = EC SRAM Address where Host address is mapped - * b[79:48] = 0 reserved - * - * BAR's start at offset 0x330 - */ -#define MCHP_ESPI_MBAR_EC_VSIZE(x) \ - REG32(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x330) -#define MCHP_ESPI_MBAR_EC_ADDR_0_15(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x332) -#define MCHP_ESPI_MBAR_EC_ADDR_16_31(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x334) -#define MCHP_ESPI_MBAR_EC_ADDR_32_47(x) \ - REG16(MCHP_ESPI_MEM_BASE + ((x) * 10) + 0x336) - -/* eSPI Virtual Wire registers */ -#define MCHP_ESPI_MSVW_LEN 12 -#define MCHP_ESPI_SMVW_LEN 8 - -#define MCHP_ESPI_MSVW_ADDR(n) \ - ((MCHP_ESPI_MSVW_BASE) + ((n) * (MCHP_ESPI_MSVW_LEN))) - -#define MCHP_ESPI_MSVW_MTOS_BITPOS 4 - -#define MCHP_ESPI_MSVW_IRQSEL_LEVEL_LO 0 -#define MCHP_ESPI_MSVW_IRQSEL_LEVEL_HI 1 -#define MCHP_ESPI_MSVW_IRQSEL_DISABLED 4 -#define MCHP_ESPI_MSVW_IRQSEL_RISING 0x0d -#define MCHP_ESPI_MSVW_IRQSEL_FALLING 0x0e -#define MCHP_ESPI_MSVW_IRQSEL_BOTH_EDGES 0x0f - -/* - * Mapping of eSPI Master Host VWire group indices to - * MCHP eSPI Master to Slave 96-bit VWire registers. - * MSVW_xy where xy = PCH VWire number. - * Each PCH VWire number controls 4 virtual wires. - */ -#define MSVW_H02 0 -#define MSVW_H03 1 -#define MSVW_H07 2 -#define MSVW_H41 3 -#define MSVW_H42 4 -#define MSVW_H43 5 -#define MSVW_H44 6 -#define MSVW_H47 7 -#define MSVW_H4A 8 -#define MSVW_HSPARE0 9 -#define MSVW_HSPARE1 10 -#define MSVW_MAX 11 - -/* Access 32-bit word in 96-bit MSVW register. 0 <= w <= 2 */ -#define MSVW(id, w) \ - REG32(MCHP_ESPI_MSVW_BASE + ((id) * 12) + (((w) & 0x03) * 4)) -/* Access index value in byte 0 */ -#define MCHP_ESPI_VW_M2S_INDEX(id) REG8(MCHP_ESPI_VW_BASE + ((id) * 12)) -/* - * Access MTOS_SOURCE and MTOS_STATE in byte 1 - * MTOS_SOURCE = b[1:0] specifies reset source - * MTOS_STATE = b[7:4] are states loaded into SRC[0:3] on reset event - */ -#define MCHP_ESPI_VW_M2S_MTOS(id) \ - REG8(MCHP_ESPI_VW_BASE + 1 + ((id) * 12)) -/* - * Access Index, MTOS Source, and MTOS State as 16-bit quantity. - * Index in b[7:0] - * MTOS Source in b[9:8] - * MTOS State in b[15:12] - */ -#define MCHP_ESPI_VW_M2S_INDEX_MTOS(id) \ - REG16(MCHP_ESPI_VW_BASE + ((id) * 12)) -/* Access SRCn IRQ Select bit fields */ -#define MCHP_ESPI_VW_M2S_IRQSEL0(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 4) -#define MCHP_ESPI_VW_M2S_IRQSEL1(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 5) -#define MCHP_ESPI_VW_M2S_IRQSEL2(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 6) -#define MCHP_ESPI_VW_M2S_IRQSEL3(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 7) -#define MCHP_ESPI_VW_M2S_IRQSEL(id, src) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 4 + ((src) & 0x03)) -#define MCHP_ESPI_VW_M2S_IRQSEL_ALL(id) \ - REG32(MCHP_ESPI_VW_BASE + ((id) * 12) + 4) -/* Access individual source bits */ -#define MCHP_ESPI_VW_M2S_SRC0(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 8) -#define MCHP_ESPI_VW_M2S_SRC1(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 9) -#define MCHP_ESPI_VW_M2S_SRC2(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 10) -#define MCHP_ESPI_VW_M2S_SRC3(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 12) + 11) -/* - * Access all four Source bits as 32-bit value, Source bits are located - * at bits[0, 8, 16, 24] of 32-bit word. - */ -#define MCHP_ESPI_VW_M2S_SRC_ALL(id) \ - REG32(MCHP_ESPI_VW_BASE + 8 + ((id) * 12)) -/* - * Access an individual Source bit as byte where - * bit[0] contains the source bit. - */ -#define MCHP_ESPI_VW_M2S_SRC(id, src) \ - REG8(MCHP_ESPI_VW_BASE + 8 + ((id) * 8) + ((src) & 0x03)) - -/* - * Indices of Slave to Master Virtual Wire registers. - * Registers are 64-bit. - * Host chipset groups VWires into groups of 4 with - * a spec. defined index. - * SMVW_Ixy where xy = eSPI Master defined index. - * MCHP maps Host indices into its Slave to Master - * 64-bit registers. - */ -#define SMVW_H04 0 -#define SMVW_H05 1 -#define SMVW_H06 2 -#define SMVW_H40 3 -#define SMVW_H45 4 -#define SMVW_H46 5 -#define SMVW_HSPARE6 6 -#define SMVW_HSPARE7 7 -#define SMVW_HSPARE8 8 -#define SMVW_HSPARE9 9 -#define SMVW_HSPARE10 10 -#define SMVW_MAX 11 - -/* Access 32-bit word of 64-bit SMVW register, 0 <= w <= 1 */ -#define SMVW(id, w) \ - REG32(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x200 + (((w) & 0x01) * 4)) -/* Access Index in b[7:0] of byte 0 */ -#define MCHP_ESPI_VW_S2M_INDEX(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x200) -/* Access STOM_SOURCE and STOM_STATE in byte 1 - * STOM_SOURCE = b[1:0] - * STOM_STATE = b[7:4] - */ -#define MCHP_ESPI_VW_S2M_STOM(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x201) -/* Access Index, STOM_SOURCE, and STOM_STATE in bytes[1:0] - * Index = b[7:0] - * STOM_SOURCE = b[9:8] - * STOM_STATE = [15:12] - */ -#define MCHP_ESPI_VW_S2M_INDEX_STOM(id) \ - REG16(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x200) -/* Access Change[0:3] RO bits. Set to 1 if any of SRC[0:3] change */ -#define MCHP_ESPI_VW_S2M_CHANGE(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x202) -/* Access individual SRC bits - * bit[0] = SRCn - */ -#define MCHP_ESPI_VW_S2M_SRC0(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x204) -#define MCHP_ESPI_VW_S2M_SRC1(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x205) -#define MCHP_ESPI_VW_S2M_SRC2(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x206) -#define MCHP_ESPI_VW_S2M_SRC3(id) \ - REG8(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x207) -/* - * Access specified source bit as byte read/write. - * Source bit is in bit[0] of byte. - */ -#define MCHP_ESPI_VW_S2M_SRC(id, src) \ - REG8(MCHP_ESPI_VW_BASE + 0x204 + ((id) * 8) + ((src) & 0x03)) -/* Access SRC[0:3] as 32-bit word - * SRC0 = b[0] - * SRC1 = b[8] - * SRC2 = b[16] - * SRC3 = b[24] - */ -#define MCHP_ESPI_VW_S2M_SRC_ALL(id) \ - REG32(MCHP_ESPI_VW_BASE + ((id) * 8) + 0x204) - -/* DMA */ -#define MCHP_DMA_MAIN_CTRL REG8(MCHP_DMA_BASE + 0x00) -#define MCHP_DMA_MAIN_PKT_RO REG32(MCHP_DMA_BASE + 0x04) -#define MCHP_DMA_MAIN_FSM_RO REG8(MCHP_DMA_BASE + 0x08) -/* DMA Channel Registers */ -#define MCHP_DMA_CH_ACT(n) REG8(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS)) -#define MCHP_DMA_CH_MEM_START(n) \ - REG32(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS) + 0x04) -#define MCHP_DMA_CH_MEM_END(n) \ - REG32(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS) + 0x08) -#define MCHP_DMA_CH_DEV_ADDR(n) \ - REG32(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS) + 0x0c) -#define MCHP_DMA_CH_CTRL(n) \ - REG32(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS) + 0x10) -#define MCHP_DMA_CH_ISTS(n) \ - REG32(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS) + 0x14) -#define MCHP_DMA_CH_IEN(n) \ - REG32(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS) + 0x18) -#define MCHP_DMA_CH_FSM_RO(n) \ - REG32(MCHP_DMA_CH_BASE + ((n) * MCHP_DMA_CH_OFS) + 0x1c) -/* - * DMA Channel 0 implements CRC-32 feature - */ -#define MCHP_DMA_CH0_CRC32_EN REG8(MCHP_DMA_CH_BASE + 0x20) -#define MCHP_DMA_CH0_CRC32_DATA REG32(MCHP_DMA_CH_BASE + 0x24) -#define MCHP_DMA_CH0_CRC32_POST_STS REG8(MCHP_DMA_CH_BASE + 0x28) -/* - * DMA Channel 1 implements memory fill feature - */ -#define MCHP_DMA_CH1_FILL_EN \ - REG8(MCHP_DMA_CH_BASE + MCHP_DMA_CH_OFS + 0x20) -#define MCHP_DMA_CH1_FILL_DATA \ - REG32(MCHP_DMA_CH_BASE + MCHP_DMA_CH_OFS + 0x24) -/* Bits for DMA Main Control */ -#define MCHP_DMA_MAIN_CTRL_ACT BIT(0) -#define MCHP_DMA_MAIN_CTRL_SRST BIT(1) -/* Bits for DMA channel regs */ -#define MCHP_DMA_ACT_EN BIT(0) -/* DMA Channel Control */ -#define MCHP_DMA_ABORT BIT(25) -#define MCHP_DMA_SW_GO BIT(24) -#define MCHP_DMA_XFER_SIZE_MASK (7ul << 20) -#define MCHP_DMA_XFER_SIZE(x) ((x) << 20) -#define MCHP_DMA_DIS_HW_FLOW BIT(19) -#define MCHP_DMA_INC_DEV BIT(17) -#define MCHP_DMA_INC_MEM BIT(16) -#define MCHP_DMA_DEV(x) ((x) << 9) -#define MCHP_DMA_DEV_MASK0 (0x7f) -#define MCHP_DMA_DEV_MASK (0x7f << 9) -#define MCHP_DMA_TO_DEV BIT(8) -#define MCHP_DMA_DONE BIT(2) -#define MCHP_DMA_RUN BIT(0) -/* DMA Channel Status */ -#define MCHP_DMA_STS_ALU_DONE BIT(3) -#define MCHP_DMA_STS_DONE BIT(2) -#define MCHP_DMA_STS_HWFL_ERR BIT(1) -#define MCHP_DMA_STS_BUS_ERR BIT(0) - -/* - * Required structure typedef for common/dma.h interface - * !!! checkpatch.pl will not like this !!! - * structure moved to chip level dma.c - * We can't remove dma_chan_t as its used in DMA API header. - */ -struct MCHP_dma_chan { - uint32_t act; /* Activate */ - uint32_t mem_start; /* Memory start address */ - uint32_t mem_end; /* Memory end address */ - uint32_t dev; /* Device address */ - uint32_t ctrl; /* Control */ - uint32_t int_status; /* Interrupt status */ - uint32_t int_enabled; /* Interrupt enabled */ - uint32_t chfsm; /* channel fsm read-only */ - uint32_t alu_en; /* channels 0 & 1 only */ - uint32_t alu_data; /* channels 0 & 1 only */ - uint32_t alu_sts; /* channel 0 only */ - uint32_t alu_ro; /* channel 0 only */ - uint32_t rsvd[4]; /* 0x30 - 0x3F */ -}; - -/* Common code and header file must use this */ -typedef struct MCHP_dma_chan dma_chan_t; - -/* Wake pin definitions, defined at board-level */ -extern const enum gpio_signal hibernate_wake_pins[]; -extern const int hibernate_wake_pins_used; -#endif /* __CROS_EC_REGISTERS_H */ diff --git a/chip/mchp/spi.c b/chip/mchp/spi.c deleted file mode 100644 index 48712e8b7e..0000000000 --- a/chip/mchp/spi.c +++ /dev/null @@ -1,294 +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. - */ - -/* QMSPI master module for MCHP MEC family */ - -#include "common.h" -#include "console.h" -#include "dma.h" -#include "gpio.h" -#include "registers.h" -#include "spi.h" -#include "timer.h" -#include "util.h" -#include "hooks.h" -#include "task.h" -#include "spi_chip.h" -#include "qmspi_chip.h" -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) -#include "gpspi_chip.h" -#endif -#include "tfdp_chip.h" - -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) - -#define SPI_BYTE_TRANSFER_TIMEOUT_US (3 * MSEC) -#define SPI_BYTE_TRANSFER_POLL_INTERVAL_US 100 - -#if defined(CONFIG_MCHP_GPSPI) && defined(CHIP_FAMILY_MEC152X) -#error "FORCED BUILD ERROR: MEC152X does not implement GPSPI!" -#endif - -static const struct dma_option spi_rx_option[] = { - { - MCHP_DMAC_QMSPI0_RX, - (void *)(MCHP_QMSPI0_RX_FIFO_ADDR), - MCHP_DMA_XFER_SIZE(1) + MCHP_DMA_INC_MEM - }, -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) -#if CONFIG_MCHP_GPSPI & 0x01 - { - MCHP_DMAC_SPI0_RX, - (void *)&MCHP_SPI_RD(0), - MCHP_DMA_XFER_SIZE(1) + MCHP_DMA_INC_MEM - }, -#endif -#if CONFIG_MCHP_GPSPI & 0x02 - { - MCHP_DMAC_SPI1_RX, - (void *)&MCHP_SPI_RD(1), - MCHP_DMA_XFER_SIZE(1) + MCHP_DMA_INC_MEM - }, -#endif -#endif -}; - -static const struct dma_option spi_tx_option[] = { - { - MCHP_DMAC_QMSPI0_TX, - (void *)(MCHP_QMSPI0_TX_FIFO_ADDR), - MCHP_DMA_XFER_SIZE(1) + MCHP_DMA_INC_MEM - }, -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) -#if CONFIG_MCHP_GPSPI & 0x01 - { - MCHP_DMAC_SPI0_TX, - (void *)&MCHP_SPI_TD(0), - MCHP_DMA_XFER_SIZE(1) + MCHP_DMA_INC_MEM - }, -#endif -#if CONFIG_MCHP_GPSPI & 0x02 - { - MCHP_DMAC_SPI1_TX, - (void *)&MCHP_SPI_TD(1), - MCHP_DMA_XFER_SIZE(1) + MCHP_DMA_INC_MEM - }, -#endif -#endif -}; - -/* only regular image needs mutex, LFW does not have scheduling */ -#ifndef LFW -static struct mutex spi_mutex[ARRAY_SIZE(spi_rx_option)]; - -/* - * Acquire mutex for specified SPI controller/port. - * Note if mutex is owned by another task this routine - * will block until mutex is released. - */ -static void spi_mutex_lock(uint8_t hw_port) -{ - uint32_t n; - - n = 0; -#ifdef CONFIG_MCHP_GPSPI - if (hw_port & 0xF0) { -#if (CONFIG_MCHP_GPSPI & 0x03) == 0x03 - n = (hw_port & 0x0F) + 1; -#else - n = 1; -#endif - } -#endif - mutex_lock(&spi_mutex[n]); -} - -/* - * Release mutex for specified SPI controller/port. - */ -static void spi_mutex_unlock(uint8_t hw_port) -{ - uint32_t n; - - n = 0; -#ifdef CONFIG_MCHP_GPSPI - if (hw_port & 0xF0) { -#if (CONFIG_MCHP_GPSPI & 0x03) == 0x03 - n = (hw_port & 0x0F) + 1; -#else - n = 1; -#endif - } -#endif - mutex_unlock(&spi_mutex[n]); -} -#endif /* #ifndef LFW */ - -/* - * Public SPI interface - */ - -const void *spi_dma_option(const struct spi_device_t *spi_device, - int is_tx) -{ - uint32_t n; - - if (spi_device == NULL) - return NULL; - - n = 0; -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) - if (spi_device->port & 0xF0) { -#if (CONFIG_MCHP_GPSPI & 0x03) == 0x03 - n = (spi_device->port & 0x0F) + 1; -#else - n = 1; -#endif - } -#endif - - if (is_tx) - return &spi_tx_option[n]; - else - return &spi_rx_option[n]; -} - -int spi_transaction_async(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - int rc; - - if (spi_device == NULL) - return EC_ERROR_INVAL; - - switch (spi_device->port) { -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) - case GPSPI0_PORT: - case GPSPI1_PORT: - rc = gpspi_transaction_async(spi_device, txdata, - txlen, rxdata, rxlen); - break; -#endif - case QMSPI0_PORT: - rc = qmspi_transaction_async(spi_device, txdata, - txlen, rxdata, rxlen); - break; - default: - rc = EC_ERROR_INVAL; - } - - return rc; -} - -int spi_transaction_flush(const struct spi_device_t *spi_device) -{ - int rc; - - if (spi_device == NULL) - return EC_ERROR_INVAL; - - switch (spi_device->port) { -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) - case GPSPI0_PORT: - case GPSPI1_PORT: - rc = gpspi_transaction_flush(spi_device); - break; -#endif - case QMSPI0_PORT: - rc = qmspi_transaction_flush(spi_device); - break; - default: - rc = EC_ERROR_INVAL; - } - - return rc; -} - -/* Wait for async response received but do not de-assert chip select */ -int spi_transaction_wait(const struct spi_device_t *spi_device) -{ - int rc; - - if (spi_device == NULL) - return EC_ERROR_INVAL; - - switch (spi_device->port) { -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) -#ifndef LFW - case GPSPI0_PORT: - case GPSPI1_PORT: - rc = gpspi_transaction_wait(spi_device); - break; -#endif -#endif - case QMSPI0_PORT: - rc = qmspi_transaction_wait(spi_device); - break; - default: - rc = EC_ERROR_INVAL; - } - - return rc; -} - -/* - * called from common/spi_flash.c - * For tranfers reading less than the size of QMSPI RX FIFO call - * a routine where reads use FIFO only no DMA. - * GP-SPI only has a one byte RX FIFO but small data transfers will be OK - * without the overhead of DMA setup. - */ -int spi_transaction(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - int rc; - - if (spi_device == NULL) - return EC_ERROR_PARAM1; - -#ifndef LFW - spi_mutex_lock(spi_device->port); -#endif - - rc = spi_transaction_async(spi_device, txdata, txlen, rxdata, rxlen); - if (rc == EC_SUCCESS) - rc = spi_transaction_flush(spi_device); - -#ifndef LFW - spi_mutex_unlock(spi_device->port); -#endif - - return rc; -} - -/** - * Enable SPI port and associated controller - * - * @param spi_device SPI device - * @param enable - * @return EC_SUCCESS or EC_ERROR_INVAL if port is unrecognized - * @note called from common/spi_flash.c - * - * spi_device->port is defined as - * bits[3:0] = controller instance - * bits[7:4] = controller family 0 = QMSPI, 1 = GPSPI - */ -int spi_enable(const struct spi_device_t *spi_device, int enable) -{ - int rc; - uint8_t hw_port = spi_device->port; - rc = EC_ERROR_INVAL; - - if ((hw_port & 0xF0) == QMSPI_CLASS) - rc = qmspi_enable(hw_port, enable); -#if defined(CONFIG_MCHP_GPSPI) && !defined(LFW) - if ((hw_port & 0xF0) == GPSPI_CLASS) - rc = gpspi_enable(hw_port, enable); -#endif - return rc; -} diff --git a/chip/mchp/spi_chip.h b/chip/mchp/spi_chip.h deleted file mode 100644 index 75973e4a78..0000000000 --- a/chip/mchp/spi_chip.h +++ /dev/null @@ -1,60 +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. - * - * Register map for MCHP MEC processor - */ -/** @file qmpis_chip.h - *MCHP MEC Quad SPI Master - */ -/** @defgroup MCHP MEC qmspi - */ - -#ifndef _SPI_CHIP_H -#define _SPI_CHIP_H - -#include <stdint.h> -#include <stddef.h> - -/* struct spi_device_t */ -#include "spi.h" - -#define SPI_DMA_OPTION_RD 0 -#define SPI_DMA_OPTION_WR 1 - -/* - * bits[3:0] = controller instance - * bits[7:4] = controller family - * 0 = QMSPI, 1 = GPSPI - */ -#define QMSPI0_PORT 0x00 -#define GPSPI0_PORT 0x10 -#define GPSPI1_PORT 0x11 - - -#define QMSPI_CLASS0 0 -#define GPSPI_CLASS0 1 - -#define QMSPI_CLASS (0 << 4) -#define GPSPI_CLASS BIT(4) - -#define QMSPI_CTRL0 0 -#define GPSPI_CTRL0 0 -#define GPSPI_CTRL1 1 - -/* - * Encode zero based controller class and instance values - * in port value of spi_device_t. - */ -#define SPI_CTRL_ID(c, i) (((c & 0xf) << 4) + (i & 0xf)) - -/* - * helper to return pointer to QMSPI or GPSPI struct dma_option - */ -const void *spi_dma_option(const struct spi_device_t *spi_device, - int is_tx); - -#endif /* #ifndef _QMSPI_CHIP_H */ -/** @} - */ - diff --git a/chip/mchp/system.c b/chip/mchp/system.c deleted file mode 100644 index d67314d716..0000000000 --- a/chip/mchp/system.c +++ /dev/null @@ -1,591 +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. - */ - -/* System module for Chrome EC : MCHP hardware specific implementation */ - -#include <stdnoreturn.h> - -#include "common.h" /* includes config.h and board.h */ -#include "clock.h" -#include "clock_chip.h" -#include "console.h" -#include "cpu.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "lpc_chip.h" -#include "registers.h" -#include "shared_mem.h" -#include "spi.h" -#include "system.h" -#include "task.h" -#include "tfdp_chip.h" -#include "timer.h" -#include "util.h" - -#define CPUTS(outstr) cputs(CC_LPC, outstr) -#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) - -/* Index values for hibernate data registers (RAM backed by VBAT) */ -enum hibdata_index { - HIBDATA_INDEX_SCRATCHPAD = 0, /* General-purpose scratch pad */ - HIBDATA_INDEX_SAVED_RESET_FLAGS, /* Saved reset flags */ - HIBDATA_INDEX_PD0, /* USB-PD0 saved port state */ - HIBDATA_INDEX_PD1, /* USB-PD1 saved port state */ - HIBDATA_INDEX_PD2, /* USB-PD2 saved port state */ -}; - -/* - * Voltage rail configuration - * MEC172x VTR1 is 3.3V only, VTR2 is auto-detected 3.3 or 1.8V, and - * VTR3 is always 1.8V. - * MEC170x and MEC152x require manual selection of VTR3 for 1.8 or 3.3V. - * The eSPI pins are on VTR3 and require 1.8V - */ -#ifdef CHIP_FAMILY_MEC172X -static void vtr3_voltage_select(int use18v) -{ - (void) use18v; -} -#else -static void vtr3_voltage_select(int use18v) -{ - if (use18v) - MCHP_EC_GPIO_BANK_PWR |= MCHP_EC_GPIO_BANK_PWR_VTR3_18; - else - MCHP_EC_GPIO_BANK_PWR &= ~(MCHP_EC_GPIO_BANK_PWR_VTR3_18); -} -#endif - - -/* - * The current logic will set EC_RESET_FLAG_RESET_PIN flag - * even if the reset was caused by WDT. MEC170x/MEC152x HW RESET_SYS - * status goes active for any of the following: - * RESET_VTR: power rail change - * WDT Event: WDT timed out - * FW triggered chip reset: SYSRESETREQ or PCR sys reset bit - * The code does check WDT status in the VBAT PFR register. - * Is it correct to report both EC_RESET_FLAG_RESET_PIN and - * EC_RESET_FLAG_WATCHDOG on a WDT only reset? - */ -static void check_reset_cause(void) -{ - uint32_t status = MCHP_VBAT_STS; - uint32_t flags = 0; - uint32_t rst_sts = MCHP_PCR_PWR_RST_STS & - (MCHP_PWR_RST_STS_SYS | - MCHP_PWR_RST_STS_VBAT); - - /* Clear the reset causes now that we've read them */ - MCHP_VBAT_STS |= status; - MCHP_PCR_PWR_RST_STS |= rst_sts; - - /* - * BIT[6] indicates RESET_SYS asserted. - * RESET_SYS will assert on VTR reset, WDT reset, or - * firmware triggering a reset using Cortex-M4 SYSRESETREQ - * or MCHP PCR system reset register. - */ - if (rst_sts & MCHP_PWR_RST_STS_SYS) - flags |= EC_RESET_FLAG_RESET_PIN; - - - flags |= chip_read_reset_flags(); - chip_save_reset_flags(0); - - if ((status & MCHP_VBAT_STS_WDT) && !(flags & (EC_RESET_FLAG_SOFT | - EC_RESET_FLAG_HARD | - EC_RESET_FLAG_HIBERNATE))) - flags |= EC_RESET_FLAG_WATCHDOG; - - system_set_reset_flags(flags); -} - -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)) - return 0; - else - return 1; -} - -/* - * Sleep unused blocks to reduce power. - * Drivers/modules will clear PCR sleep enables for their blocks. - * Keep sleep enables cleared for required blocks: - * ECIA, PMC, CPU, ECS and optionally JTAG. - * SLEEP_ALL feature will set these upon sleep entry. - * Based on CONFIG_CHIPSET_DEBUG enable or disable ARM SWD - * 2-pin JTAG mode. - */ -static void chip_periph_sleep_control(void) -{ - uint32_t d; - - d = MCHP_PCR_SLP_EN0_SLEEP; - - if (IS_ENABLED(CONFIG_CHIPSET_DEBUG)) { - d &= ~(MCHP_PCR_SLP_EN0_JTAG); - MCHP_EC_JTAG_EN = MCHP_JTAG_MODE_SWD | MCHP_JTAG_ENABLE; - } else - MCHP_EC_JTAG_EN &= ~(MCHP_JTAG_ENABLE); - - MCHP_PCR_SLP_EN0 = d; - MCHP_PCR_SLP_EN1 = MCHP_PCR_SLP_EN1_UNUSED_BLOCKS; - MCHP_PCR_SLP_EN2 = MCHP_PCR_SLP_EN2_SLEEP; - MCHP_PCR_SLP_EN3 = MCHP_PCR_SLP_EN3_SLEEP; - MCHP_PCR_SLP_EN4 = MCHP_PCR_SLP_EN4_SLEEP; -} - -#ifdef CONFIG_CHIP_PRE_INIT -void chip_pre_init(void) -{ - chip_periph_sleep_control(); - - if (IS_ENABLED(CONFIG_MCHP_TFDP)) { - /* MCHP Enable TFDP for fast debug messages */ - tfdp_power(1); - tfdp_enable(1, 1); - CPRINTS("chip_pre_init: Image type = 0x%02x", - MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX)); - } -} -#endif - -void system_pre_init(void) -{ - /* - * Make sure AHB Error capture is enabled. - * Signals bus fault to Cortex-M4 core if an address presented - * to AHB is not claimed by any HW block. - */ - MCHP_EC_AHB_ERR = 0; /* write any value to clear */ - MCHP_EC_AHB_ERR_EN = 0; /* enable capture of address on error */ - - /* Manual voltage selection only required for MEC170x and MEC152x */ - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) - vtr3_voltage_select(1); - else - vtr3_voltage_select(0); - - if (!IS_ENABLED(CONFIG_CHIP_PRE_INIT)) - chip_periph_sleep_control(); - - /* Enable direct NVIC */ - MCHP_EC_INT_CTRL |= 1; - - /* Disable ARM TRACE debug port */ - MCHP_EC_TRACE_EN &= ~1; - - /* - * Enable aggregated only interrupt GIRQ's - * Make sure direct mode interrupt sources aggregated outputs - * are not enabled. - * Aggregated only GIRQ's 8,9,10,11,12,22,24,25,26 - * Direct GIRQ's = 13,14,15,16,17,18,19,21,23 - * These bits only need to be touched again on RESET_SYS. - * NOTE: GIRQ22 wake for AHB peripherals not processor. - */ - MCHP_INT_BLK_DIS = 0xfffffffful; - MCHP_INT_BLK_EN = MCHP_INT_AGGR_ONLY_BITMAP; - - spi_enable(SPI_FLASH_DEVICE, 1); -} - -uint32_t chip_read_reset_flags(void) -{ - return MCHP_VBAT_RAM(HIBDATA_INDEX_SAVED_RESET_FLAGS); -} - -void chip_save_reset_flags(uint32_t flags) -{ - MCHP_VBAT_RAM(HIBDATA_INDEX_SAVED_RESET_FLAGS) = flags; -} - -noreturn void _system_reset(int flags, int wake_from_hibernate) -{ - uint32_t save_flags = 0; - - /* DEBUG */ - CPRINTS("MEC system reset: flag = 0x%08x wake = %d", flags, - wake_from_hibernate); - - /* Disable interrupts to avoid task swaps during reboot */ - interrupt_disable(); - - /* Save current reset reasons if necessary */ - if (flags & SYSTEM_RESET_PRESERVE_FLAGS) - save_flags = system_get_reset_flags() | EC_RESET_FLAG_PRESERVED; - - if (flags & SYSTEM_RESET_LEAVE_AP_OFF) - save_flags |= EC_RESET_FLAG_AP_OFF; - - if (wake_from_hibernate) - save_flags |= EC_RESET_FLAG_HIBERNATE; - else if (flags & SYSTEM_RESET_HARD) - save_flags |= EC_RESET_FLAG_HARD; - else - save_flags |= EC_RESET_FLAG_SOFT; - - chip_save_reset_flags(save_flags); - - /* - * Trigger chip reset - */ - if (!IS_ENABLED(CONFIG_DEBUG_BRINGUP)) - MCHP_PCR_SYS_RST |= MCHP_PCR_SYS_SOFT_RESET; - - /* Spin and wait for reboot; should never return */ - while (1) - ; -} - -void system_reset(int flags) -{ - _system_reset(flags, 0); -} - -const char *system_get_chip_vendor(void) -{ - return "mchp"; -} - -#ifdef CHIP_VARIANT_MEC1701 -/* - * MEC1701H Chip ID = 0x2D - * Rev = 0x82 - */ -const char *system_get_chip_name(void) -{ - switch (MCHP_CHIP_DEV_ID) { - case 0x2D: - return "mec1701"; - default: - return "unknown"; - } -} -#endif - -#ifdef CHIP_FAMILY_MEC152X -/* - * MEC152x family implements chip ID as a 32-bit - * register where: - * b[31:16] = 16-bit Device ID - * b[15:8] = 8-bit Sub ID - * b[7:0] = Revision - * - * MEC1521-128 WFBGA 0023_33_xxh - * MEC1521-144 WFBGA 0023_34_xxh - * MEC1523-144 WFBGA 0023_B4_xxh - * MEC1527-144 WFBGA 0023_74_xxh - * MEC1527-128 WFBGA 0023_73_xxh - */ -const char *system_get_chip_name(void) -{ - switch (MCHP_CHIP_DEVRID32 & ~(MCHP_CHIP_REV_MASK)) { - case 0x00201400: /* 144 pin rev A? */ - return "mec1503_revA"; - case 0x00203400: /* 144 pin */ - return "mec1501"; - case 0x00207400: /* 144 pin */ - return "mec1507"; - case 0x00208400: /* 144 pin */ - return "mec1503"; - case 0x00233300: /* 128 pin */ - case 0x00233400: /* 144 pin */ - return "mec1521"; - case 0x0023B400: /* 144 pin */ - return "mec1523"; - case 0x00237300: /* 128 pin */ - case 0x00237400: /* 144 pin */ - return "mec1527"; - default: - return "unknown"; - } -} -#endif - -#ifdef CHIP_FAMILY_MEC172X -/* - * MEC172x family implements chip ID as a 32-bit - * register where: - * b[31:16] = 16-bit Device ID - * b[15:8] = 8-bit Sub ID - * b[7:0] = Revision - * - * MEC1723N-B0-I/SZ 144 pin: 0x0022_34_xx - * MEC1727N-B0-I/SZ 144 pin: 0x0022_74_xx - * MEC1721N-B0-I/LJ 176 pin: 0x0022_27_xx - * MEC1723N-B0-I/LJ 176 pin: 0x0022_37_xx - * MEC1727N-B0-I/LJ 176 pin: 0x0022_77_xx - */ -const char *system_get_chip_name(void) -{ - switch (MCHP_CHIP_DEVRID32 & ~(MCHP_CHIP_REV_MASK)) { - case 0x00223400: - return "MEC1723NSZ"; - case 0x00227400: - return "MEC1727NSZ"; - case 0x00222700: - return "MEC1721NLJ"; - case 0x00223700: - return "MEC1723NLJ"; - case 0x00227700: - return "MEC1727NLJ"; - default: - return "unknown"; - } -} -#endif - -static char to_hex(int x) -{ - if (x >= 0 && x <= 9) - return '0' + x; - return 'a' + x - 10; -} - -const char *system_get_chip_revision(void) -{ - static char buf[3]; - uint8_t rev = MCHP_CHIP_DEV_REV; - - buf[0] = to_hex(rev / 16); - buf[1] = to_hex(rev & 0xf); - buf[2] = '\0'; - return buf; -} - -static int bbram_idx_lookup(enum system_bbram_idx idx) -{ - switch (idx) { - case SYSTEM_BBRAM_IDX_PD0: - return HIBDATA_INDEX_PD0; - case SYSTEM_BBRAM_IDX_PD1: - return HIBDATA_INDEX_PD1; - case SYSTEM_BBRAM_IDX_PD2: - return HIBDATA_INDEX_PD2; - default: - return 1; - } -} - -int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) -{ - int hibdata = bbram_idx_lookup(idx); - - if (hibdata < 0) - return EC_ERROR_UNIMPLEMENTED; - - *value = MCHP_VBAT_RAM(hibdata); - return EC_SUCCESS; -} - -int system_set_bbram(enum system_bbram_idx idx, uint8_t value) -{ - int hibdata = bbram_idx_lookup(idx); - - if (hibdata < 0) - return EC_ERROR_UNIMPLEMENTED; - - MCHP_VBAT_RAM(hibdata) = value; - return EC_SUCCESS; -} - -int system_set_scratchpad(uint32_t value) -{ - MCHP_VBAT_RAM(HIBDATA_INDEX_SCRATCHPAD) = value; - return EC_SUCCESS; -} - -int system_get_scratchpad(uint32_t *value) -{ - *value = MCHP_VBAT_RAM(HIBDATA_INDEX_SCRATCHPAD); - return EC_SUCCESS; -} - -/* - * Local function to disable clocks in the chip's host interface - * so the chip can enter deep sleep. Only MEC170X has LPC. - * MEC152x and MEC172x only include eSPI and SPI host interfaces. - * NOTE: we do it this way because the LPC registers are only - * defined for MEC170x and the IS_ENABLED() macro causes the - * compiler to evaluate both true and false code paths. - */ -#if defined(CONFIG_HOSTCMD_ESPI) -static void disable_host_ifc_clocks(void) -{ - MCHP_ESPI_ACTIVATE &= ~0x01; -} -#else -static void disable_host_ifc_clocks(void) -{ - #ifdef CHIP_FAMILY_MEC170X - MCHP_LPC_ACT &= ~0x1; - #endif -} -#endif - - -/* - * Called when hibernation timer is not used in deep sleep. - * Switch 32 KHz clock logic from external 32KHz input to - * internal silicon OSC. - * NOTE: MEC172x auto-switches from external source to silicon - * oscillator. - */ -#ifdef CHIP_FAMILY_MEC172X -static void switch_32k_pin2sil(void) {} -#else -static void switch_32k_pin2sil(void) -{ - MCHP_VBAT_CE &= ~(MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN); -} -#endif - -void system_hibernate(uint32_t seconds, uint32_t microseconds) -{ - int i; - - if (IS_ENABLED(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); - } - - cflush(); - - if (board_hibernate) - board_hibernate(); - - /* Disable interrupts */ - interrupt_disable(); - for (i = 0; i < MCHP_IRQ_MAX; ++i) { - task_disable_irq(i); - task_clear_pending_irq(i); - } - - for (i = MCHP_INT_GIRQ_FIRST; i <= MCHP_INT_GIRQ_LAST; ++i) { - MCHP_INT_DISABLE(i) = 0xffffffff; - MCHP_INT_SOURCE(i) = 0xffffffff; - } - - /* Disable UART */ - MCHP_UART_ACT(0) &= ~0x1; - - disable_host_ifc_clocks(); - - /* Disable JTAG */ - MCHP_EC_JTAG_EN &= ~1; - - /* Stop watchdog */ - MCHP_WDG_CTL &= ~(MCHP_WDT_CTL_ENABLE); - - /* Stop timers */ - MCHP_TMR32_CTL(0) &= ~1; - MCHP_TMR32_CTL(1) &= ~1; - for (i = 0; i < MCHP_TMR16_INSTANCES; i++) - MCHP_TMR16_CTL(i) &= ~1; - - /* Power down ADC */ - /* - * If ADC is in middle of acquisition it will continue until finished - */ - MCHP_ADC_CTRL &= ~1; - - /* Disable blocks */ - MCHP_PCR_SLOW_CLK_CTL &= ~(MCHP_PCR_SLOW_CLK_CTL_MASK); - - /* Setup GPIOs for hibernate */ - if (board_hibernate_late) - board_hibernate_late(); - - if (hibernate_wake_pins_used > 0) { - for (i = 0; i < hibernate_wake_pins_used; ++i) { - const enum gpio_signal pin = hibernate_wake_pins[i]; - - gpio_reset(pin); - gpio_enable_interrupt(pin); - } - - interrupt_enable(); - task_enable_irq(MCHP_IRQ_GIRQ8); - task_enable_irq(MCHP_IRQ_GIRQ9); - task_enable_irq(MCHP_IRQ_GIRQ10); - task_enable_irq(MCHP_IRQ_GIRQ11); - task_enable_irq(MCHP_IRQ_GIRQ12); - task_enable_irq(MCHP_IRQ_GIRQ26); - } - - if (seconds || microseconds) { - htimer_init(); - system_set_htimer_alarm(seconds, microseconds); - interrupt_enable(); - } else - switch_32k_pin2sil(); - - /* - * Set sleep state - * arm sleep state to trigger on next WFI - */ - CPU_SCB_SYSCTRL |= 0x4; - MCHP_PCR_SYS_SLP_CTL = MCHP_PCR_SYS_SLP_HEAVY; - MCHP_PCR_SYS_SLP_CTL = MCHP_PCR_SYS_SLP_ALL; - - asm("dsb"); - asm("wfi"); - asm("isb"); - asm("nop"); - - /* Use fastest clock to speed through wake-up */ - MCHP_PCR_PROC_CLK_CTL = MCHP_PCR_CLK_CTL_FASTEST; - - /* Reboot */ - _system_reset(0, 1); - - /* We should never get here. */ - while (1) - ; -} - -void htimer_interrupt(void) -{ - /* Time to wake up */ -} -DECLARE_IRQ(MCHP_IRQ_HTIMER0, htimer_interrupt, 1); - -enum ec_image system_get_shrspi_image_copy(void) -{ - return MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX); -} - -uint32_t system_get_lfw_address(void) -{ - uint32_t * const lfw_vector = - (uint32_t * const)CONFIG_PROGRAM_MEMORY_BASE; - - return *(lfw_vector + 1); -} - -void system_set_image_copy(enum ec_image copy) -{ - MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX) = (copy == EC_IMAGE_RW) ? - EC_IMAGE_RW : EC_IMAGE_RO; -} - diff --git a/chip/mchp/tfdp.c b/chip/mchp/tfdp.c deleted file mode 100644 index b4368b46a8..0000000000 --- a/chip/mchp/tfdp.c +++ /dev/null @@ -1,499 +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. - */ - -/** @file tfdp.c - *MCHP Trace FIFO Data Port hardware access - */ -/** @defgroup MCHP Peripherals TFDP - * @{ - */ - -#include "common.h" -#include "gpio.h" -#include "registers.h" -#include "tfdp_chip.h" - -#ifdef CONFIG_MCHP_TFDP - - -static uint32_t get_disable_intr(void) -{ - uint32_t m; - - __asm__ __volatile__ ("mrs %0, primask;cpsid i" : "=r" (m)); - - return m; -} - -static void restore_intr(uint32_t m) -{ - if (!m) - __asm__ __volatile__ ("cpsie i" : : : "memory"); -} - - -/** - * tfdp_power - Gate clocks On/Off to TFDP block when idle - * - * @param pwr_on (0=Gate clocks when idle), (1=Do not gate - * clocks when idle) - */ -void tfdp_power(uint8_t pwr_on) -{ - if (pwr_on) - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_TFDP); - else - MCHP_PCR_SLP_EN_DEV(MCHP_PCR_TFDP); -} - - -/** - * tfdp_enable - Init Trace FIFO Data Port - * @param uint8_t non-zero=enable TFDP, false=disable TFDP - * @param uint8_t non-zero=change TFDP pin configuration. - * If TFDP is enabled then GPIO170/171 set to Alt. Func. 1 - * Else GPIO170/171 set to GPIO input, internal pull-up enabled. - * @note - - */ -#define MCHP_TFDP_DATA REG8(MCHP_TFDP_BASE + 0x00) -#define MCHP_TFDP_CTRL REG8(MCHP_TFDP_BASE + 0x04) - -void tfdp_enable(uint8_t en, uint8_t pin_cfg) -{ - if (en) { - MCHP_TFDP_CTRL = 0x01u; - if (pin_cfg) - gpio_config_module(MODULE_TFDP, 1); - } else { - MCHP_TFDP_CTRL = 0x00u; - if (pin_cfg) - gpio_config_module(MODULE_TFDP, 0); - } -} /* end tfdp_enable() */ - - -/** - * TFDPTrace0 - TRACE0: transmit 16-bit trace number lsb first - * over TFDP. - * - * @param nbr 16-bit trace number - * @param b unused - * - * @return uint8_t always TRUE - * @note Function implements critical section. - * Uses tool kit __disable_irq()/__enable_irq() pair which may use - * priviledged Cortex-Mx instructions. - */ -void TFDPTrace0(uint16_t nbr) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - - -/** - * TRDPTrace1 - TRACE1: transmit 16-bit trace number lsb first - * and 16-bit data lsb first over TFDP. - * - * @param nbr 16-bit trace number - * @param b unused - * @param uint32_t p1 16-bit data1 in b[15:0] - * - * @return uint8_t always TRUE - * @note Function implements critical section. - * Uses tool kit __disable_irq()/__enable_irq() pair which may use - * priviledged Cortex-Mx instructions. - */ -void TFDPTrace1(uint16_t nbr, uint32_t p1) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - - -/** - * TFDPTrace2 - TRACE2: transmit 16-bit trace number lsb first - * and two 16-bit data parameters lsb first over TFDP. - * - * @param nbr trace number - * @param b unused - * @param uint32_t p1 16-bit data1 in b[15:0] - * @param uint32_t p2 16-bit data2 in b[15:0] - * - * @return uint8_t always TRUE - * @note Uses tool kit functions to save/disable/restore - * interrupts for critical section. These may use - * priviledged instructions. - */ -void TFDPTrace2(uint16_t nbr, uint32_t p1, uint32_t p2) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p2; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 8); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - - -/** - * TFDPTrace3 - TRACE3: transmit 16-bit trace number lsb first - * and three 16-bit data parameters lsb first over TFDP. - * - * @param nbr trace number - * @param b unused - * @param uint32_t p1 16-bit data1 in b[15:0] - * @param uint32_t p2 16-bit data2 in b[15:0] - * @param uint32_t p3 16-bit data3 in b[15:0] - * - * @return uint8_t always TRUE - * @note Uses tool kit functions to save/disable/restore - * interrupts for critical section. These may use - * priviledged instructions. - */ -void TFDPTrace3(uint16_t nbr, uint32_t p1, - uint32_t p2, uint32_t p3) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p2; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p3; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 8); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - - -/** - * TFDPTrace4 - TRACE3: transmit 16-bit trace number lsb first - * and four 16-bit data parameters lsb first over TFDP. - * - * @param nbr trace number - * @param b unused - * @param uint32_t p1 16-bit data1 in b[15:0] - * @param uint32_t p2 16-bit data2 in b[15:0] - * @param uint32_t p3 16-bit data3 in b[15:0] - * @param uint32_t p4 16-bit data4 in b[15:0] - * - * @return uint8_t always TRUE - * @note Uses tool kit functions to save/disable/restore - * interrupts for critical section. These may use - * priviledged instructions. - */ -void TFDPTrace4(uint16_t nbr, uint32_t p1, uint32_t p2, - uint32_t p3, uint32_t p4) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p2; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p3; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p4; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p4 >> 8); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - - -/** - * TFDPTrace11 - Transmit one 32-bit data item over TFDP - * - * @param nbr trace number - * @param b unused - * @param uint32_t p1 32-bit data to be transmitted - * - */ -void TFDPTrace11(uint16_t nbr, uint32_t p1) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 24); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - - -/** - * TFDPTrace12 - Transmit two 32-bit data items over TFDP - * - * @param nbr trace number - * @param b unused - * @param uint32_t p1 32-bit data1 to be transmitted - * @param uint32_t p2 32-bit data2 to be transmitted - * - */ -void TFDPTrace12(uint16_t nbr, uint32_t p1, uint32_t p2) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 24); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p2; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 24); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - -/** - * TFDPTrace13 - Transmit three 32-bit data items over TFDP - * - * @param nbr trace number - * @param b unused - * @param uint32_t p1 32-bit data1 to be transmitted - * @param uint32_t p2 32-bit data2 to be transmitted - * @param uint32_t p3 32-bit data3 to be transmitted - * - */ -void TFDPTrace13(uint16_t nbr, uint32_t p1, - uint32_t p2, uint32_t p3) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 24); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p2; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 24); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p3; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 24); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - -/** - * TFDPTrace14 - Transmit four 32-bit data items over TFDP - * - * @param nbr trace number - * @param b unused - * @param uint32_t p1 32-bit data1 to be transmitted - * @param uint32_t p2 32-bit data2 to be transmitted - * @param uint32_t p3 32-bit data3 to be transmitted - * @param uint32_t p4 32-bit data4 to be transmitted - */ -void TFDPTrace14(uint16_t nbr, uint32_t p1, uint32_t p2, - uint32_t p3, uint32_t p4) -{ -#ifdef MCHP_TRACE_MASK_IRQ - uint32_t prim; - - prim = get_disable_intr(); -#endif - - MCHP_TFDP_DATA = (TFDP_FRAME_START); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)nbr; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(nbr >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p1; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p1 >> 24); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p2; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p2 >> 24); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p3; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p3 >> 24); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)p4; - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p4 >> 8); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p4 >> 16); - TFDP_DELAY(); - MCHP_TFDP_DATA = (uint8_t)(p4 >> 24); - TFDP_DELAY(); - -#ifdef MCHP_TRACE_MASK_IRQ - restore_intr(prim); -#endif -} - -#endif /* #ifdef CONFIG_MCHP_TFDP */ - - -/* end tfdp.c */ -/** @} - */ diff --git a/chip/mchp/tfdp_chip.h b/chip/mchp/tfdp_chip.h deleted file mode 100644 index 64d4d0b77e..0000000000 --- a/chip/mchp/tfdp_chip.h +++ /dev/null @@ -1,131 +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. - */ -/** @file tfdp_chip.h - *MCHP MEC TFDP Peripheral Library API - */ -/** @defgroup MCHP MEC Peripherals Trace - */ - -#ifndef _TFDP_CHIP_H -#define _TFDP_CHIP_H - -#include <stdint.h> - - -#ifdef CONFIG_MCHP_TFDP - -#undef TRACE0 -#undef TRACE1 -#undef TRACE2 -#undef TRACE3 -#undef TRACE4 -#undef TRACE11 -#undef TRACE12 -#undef TRACE13 -#undef TRACE14 -#undef trace0 -#undef trace1 -#undef trace2 -#undef trace3 -#undef trace4 -#undef trace11 -#undef trace12 -#undef trace13 -#undef trace14 - -#define MCHP_TFDP_BASE_ADDR (0x40008c00ul) - -#define TFDP_FRAME_START (0xFD) - -#define TFDP_POWER_ON (1u) -#define TFDP_POWER_OFF (0u) - -#define TFDP_ENABLE (1u) -#define TFDP_DISABLE (0u) -#define TFDP_CFG_PINS (1u) -#define TFDP_NO_CFG_PINS (0u) - -#define MCHP_TRACE_MASK_IRQ - -#define TFDP_DELAY() - -#ifdef __cplusplus -extern "C" { -#endif - -void tfdp_power(uint8_t pwr_on); -void tfdp_enable(uint8_t en, uint8_t pin_cfg); -void TFDPTrace0(uint16_t nbr); -void TFDPTrace1(uint16_t nbr, uint32_t p1); -void TFDPTrace2(uint16_t nbr, uint32_t p1, - uint32_t p2); -void TFDPTrace3(uint16_t nbr, uint32_t p1, - uint32_t p2, uint32_t p3); -void TFDPTrace4(uint16_t nbr, uint32_t p1, uint32_t p2, - uint32_t p3, uint32_t p4); -void TFDPTrace11(uint16_t nbr, uint32_t p1); -void TFDPTrace12(uint16_t nbr, uint32_t p1, uint32_t p2); -void TFDPTrace13(uint16_t nbr, uint32_t p1, uint32_t p2, - uint32_t p3); -void TFDPTrace14(uint16_t nbr, uint32_t p1, uint32_t p2, - uint32_t p3, uint32_t p4); - -#ifdef __cplusplus -} -#endif - -#define TRACE0(nbr, cat, b, str) TFDPTrace0(nbr) -#define TRACE1(nbr, cat, b, str, p1) TFDPTrace1(nbr, p1) -#define TRACE2(nbr, cat, b, str, p1, p2) TFDPTrace2(nbr, p1, p2) -#define TRACE3(nbr, cat, b, str, p1, p2, p3) TFDPTrace3(nbr, p1, p2, p3) -#define TRACE4(nbr, cat, b, str, p1, p2, p3, p4) TFDPTrace4(nbr, p1, p2, \ - p3, p4) -#define TRACE11(nbr, cat, b, str, p1) TFDPTrace11(nbr, p1) -#define TRACE12(nbr, cat, b, str, p1, p2) TFDPTrace12(nbr, p1, p2) -#define TRACE13(nbr, cat, b, str, p1, p2, p3) TFDPTrace13(nbr, p1, p2, p3) -#define TRACE14(nbr, cat, b, str, p1, p2, p3, p4) \ - TFDPTrace14(nbr, p1, p2, p3, p4) - - -#else /* #ifdef MCHP_TRACE */ - -/* !!! To prevent compiler warnings of unused parameters, - * when trace is disabled by TRGEN source processing, - * you can either: - * 1. Disable compiler's unused parameter warning - * 2. Change these macros to write parameters to a read-only - * register. - */ -#define tfdp_power(pwr_on) -#define tfdp_enable(en, pin_cfg) -#define TRACE0(nbr, cat, b, str) -#define TRACE1(nbr, cat, b, str, p1) -#define TRACE2(nbr, cat, b, str, p1, p2) -#define TRACE3(nbr, cat, b, str, p1, p2, p3) -#define TRACE4(nbr, cat, b, str, p1, p2, p3, p4) -#define TRACE11(nbr, cat, b, str, p1) -#define TRACE12(nbr, cat, b, str, p1, p2) -#define TRACE13(nbr, cat, b, str, p1, p2, p3) -#define TRACE14(nbr, cat, b, str, p1, p2, p3, p4) - -#endif /* #ifdef CONFIG_MCHP_TFDP */ - -/* - * Always define lower case traceN(...) as blank (fully removed) - */ -#define trace0(nbr, cat, b, str) -#define trace1(nbr, cat, b, str, p1) -#define trace2(nbr, cat, b, str, p1, p2) -#define trace3(nbr, cat, b, str, p1, p2, p3) -#define trace4(nbr, cat, b, str, p1, p2, p3, p4) -#define trace11(nbr, cat, b, str, p1) -#define trace12(nbr, cat, b, str, p1, p2) -#define trace13(nbr, cat, b, str, p1, p2, p3) -#define trace14(nbr, cat, b, str, p1, p2, p3, p4) - -#endif /* #ifndef _TFDP_CHIP_H */ -/* end tfdp_chip.h */ -/** @} - */ diff --git a/chip/mchp/uart.c b/chip/mchp/uart.c deleted file mode 100644 index 56c99646a4..0000000000 --- a/chip/mchp/uart.c +++ /dev/null @@ -1,274 +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. - */ - -/* UART module for MCHP MEC */ - -#include "clock.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "lpc.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "uart.h" -#include "util.h" -#include "tfdp_chip.h" - -#define TX_FIFO_SIZE 16 - -BUILD_ASSERT((CONFIG_UART_CONSOLE >= 0) && - (CONFIG_UART_CONSOLE < MCHP_UART_INSTANCES)); - -#if CONFIG_UART_CONSOLE == 2 - -#define UART_IRQ MCHP_IRQ_UART2 -#define UART_IRQ_BIT MCHP_UART2_GIRQ_BIT -#define UART_PCR MCHP_PCR_UART2 -#define GPIO_UART_RX GPIO_UART2_RX -/* MEC152x only. UART2 RX Pin = GPIO 0145 GIRQ08 bit[5] */ -#define UART_RX_PIN_GIRQ 8 -#define UART_RX_PIN_BIT BIT(5) - -#elif CONFIG_UART_CONSOLE == 1 - -#define UART_IRQ MCHP_IRQ_UART1 -#define UART_IRQ_BIT MCHP_UART1_GIRQ_BIT -#define UART_PCR MCHP_PCR_UART1 -#define GPIO_UART_RX GPIO_UART1_RX -/* MEC152x and MEC170x UART1 RX Pin = GPIO 0171. GIRQ08 bit[25] */ -#define UART_RX_PIN_GIRQ 8 -#define UART_RX_PIN_BIT BIT(25) - -#else - -#define UART_IRQ MCHP_IRQ_UART0 -#define UART_IRQ_BIT MCHP_UART0_GIRQ_BIT -#define UART_PCR MCHP_PCR_UART0 -#define GPIO_UART_RX GPIO_UART0_RX -/* MEC152x and MEC170x UART0 RX Pin = GPIO 0105. GIRQ09 bit[5] */ -#define UART_RX_PIN_GIRQ 9 -#define UART_RX_PIN_BIT BIT(5) - -#endif /* CONFIG_UART_CONSOLE == 2 */ - -static int init_done; -static int tx_fifo_used; - -int uart_init_done(void) -{ - return init_done; -} - -void uart_tx_start(void) -{ - /* If interrupt is already enabled, nothing to do */ - if (MCHP_UART_IER(CONFIG_UART_CONSOLE) & BIT(1)) - return; - - /* Do not allow deep sleep while transmit in progress */ - disable_sleep(SLEEP_MASK_UART); - - /* - * Re-enable the transmit interrupt, then forcibly trigger the - * interrupt. This works around a hardware problem with the - * UART where the FIFO only triggers the interrupt when its - * threshold is _crossed_, not just met. - */ - MCHP_UART_IER(CONFIG_UART_CONSOLE) |= BIT(1); - task_trigger_irq(UART_IRQ); -} - -void uart_tx_stop(void) -{ - MCHP_UART_IER(CONFIG_UART_CONSOLE) &= ~BIT(1); - - /* Re-allow deep sleep */ - enable_sleep(SLEEP_MASK_UART); -} - -void uart_tx_flush(void) -{ - /* Wait for transmit FIFO empty */ - while (!(MCHP_UART_LSR(CONFIG_UART_CONSOLE) & MCHP_LSR_TX_EMPTY)) - ; -} - -int uart_tx_ready(void) -{ - /* - * We have no indication of free space in transmit FIFO. To work around - * this, we check transmit FIFO empty bit every 16 characters written. - */ - return tx_fifo_used != 0 || - (MCHP_UART_LSR(CONFIG_UART_CONSOLE) & MCHP_LSR_TX_EMPTY); -} - -int uart_tx_in_progress(void) -{ - /* return 0: FIFO is empty, 1: FIFO NOT Empty */ - return !(MCHP_UART_LSR(CONFIG_UART_CONSOLE) & MCHP_LSR_TX_EMPTY); -} - -int uart_rx_available(void) -{ - return MCHP_UART_LSR(CONFIG_UART_CONSOLE) & BIT(0); -} - -void uart_write_char(char c) -{ - /* Wait for space in transmit FIFO. */ - while (!uart_tx_ready()) - ; - - tx_fifo_used = (tx_fifo_used + 1) % TX_FIFO_SIZE; - MCHP_UART_TB(CONFIG_UART_CONSOLE) = c; -} - -int uart_read_char(void) -{ - return MCHP_UART_RB(CONFIG_UART_CONSOLE); -} - -static void uart_clear_rx_fifo(int channel) -{ - MCHP_UART_FCR(channel) = BIT(0) | BIT(1); -} - -void uart_disable_interrupt(void) -{ - task_disable_irq(UART_IRQ); -} - -void uart_enable_interrupt(void) -{ - task_enable_irq(UART_IRQ); -} - -/** - * Interrupt handler for UART. - * Lower priority below other critical ISR's. - */ -void uart_ec_interrupt(void) -{ - /* Read input FIFO until empty, then fill output FIFO */ - uart_process_input(); - /* Trace statement to provide time marker for UART output? */ - uart_process_output(); -} -DECLARE_IRQ(UART_IRQ, uart_ec_interrupt, 2); - -void uart_init(void) -{ - /* Clear UART PCR sleep enable */ - MCHP_PCR_SLP_DIS_DEV(UART_PCR); - - /* Set UART to reset on VCC1_RESET instead of nSIO_RESET */ - MCHP_UART_CFG(CONFIG_UART_CONSOLE) &= ~BIT(1); - - /* Baud rate = 115200. 1.8432MHz clock. Divisor = 1 */ - - /* Set CLK_SRC = 0 */ - MCHP_UART_CFG(CONFIG_UART_CONSOLE) &= ~BIT(0); - - /* Set DLAB = 1 */ - MCHP_UART_LCR(CONFIG_UART_CONSOLE) |= BIT(7); - - /* PBRG0/PBRG1 */ - MCHP_UART_PBRG0(CONFIG_UART_CONSOLE) = 1; - MCHP_UART_PBRG1(CONFIG_UART_CONSOLE) = 0; - - /* Set DLAB = 0 */ - MCHP_UART_LCR(CONFIG_UART_CONSOLE) &= ~BIT(7); - - /* Set word length to 8-bit */ - MCHP_UART_LCR(CONFIG_UART_CONSOLE) |= BIT(0) | BIT(1); - - /* Enable FIFO */ - MCHP_UART_FCR(CONFIG_UART_CONSOLE) = BIT(0); - - /* Activate UART */ - MCHP_UART_ACT(CONFIG_UART_CONSOLE) |= BIT(0); - - gpio_config_module(MODULE_UART, 1); - - /* - * Enable interrupts for UART - */ - uart_clear_rx_fifo(CONFIG_UART_CONSOLE); - MCHP_UART_IER(CONFIG_UART_CONSOLE) |= BIT(0); - MCHP_UART_MCR(CONFIG_UART_CONSOLE) |= BIT(3); - - MCHP_INT_ENABLE(MCHP_UART_GIRQ) = UART_IRQ_BIT; - - task_enable_irq(UART_IRQ); - - init_done = 1; -} - -#ifdef CONFIG_LOW_POWER_IDLE -void uart_enter_dsleep(void) -{ - /* Disable the UART interrupt. */ - task_disable_irq(UART_IRQ); /* NVIC interrupt for UART=13 */ - - /* - * Set the UART0 RX pin to be a GPIO-162(fixed pin) interrupt - * with the flags defined in the gpio.inc file. - */ - gpio_reset(GPIO_UART_RX); - - /* power-down/deactivate UART */ - MCHP_UART_ACT(CONFIG_UART_CONSOLE) &= ~BIT(0); - - /* clear interrupt enable for UART */ - MCHP_INT_DISABLE(MCHP_UART_GIRQ) = UART_IRQ_BIT; - - /* Clear pending interrupts on UART RX pin */ - MCHP_INT_SOURCE(UART_RX_PIN_GIRQ) = UART_RX_PIN_BIT; - - /* Enable GPIO interrupts on the UART0 RX pin. */ - gpio_enable_interrupt(GPIO_UART_RX); -} - - -void uart_exit_dsleep(void) -{ - /* - * If the UART0 RX GPIO interrupt has not fired, then no edge has been - * detected. Disable the GPIO interrupt so that switching the pin over - * to a UART pin doesn't inadvertently cause a GPIO edge interrupt. - * Note: we can't disable this interrupt if it has already fired - * because then the IRQ will not run at all. - */ - if (!(BIT(5) & MCHP_INT_SOURCE(9))) /* if edge interrupt */ - gpio_disable_interrupt(GPIO_UART_RX); - - /* Configure UART0 pins for use in UART peripheral. */ - gpio_config_module(MODULE_UART, 1); - - /* Clear pending interrupts on UART peripheral and enable interrupts. */ - uart_clear_rx_fifo(CONFIG_UART_CONSOLE); - MCHP_INT_SOURCE(MCHP_UART_GIRQ) = UART_IRQ_BIT; - MCHP_INT_ENABLE(MCHP_UART_GIRQ) = UART_IRQ_BIT; - task_enable_irq(UART_IRQ); - - /* power-up/activate UART0 */ - MCHP_UART_ACT(CONFIG_UART_CONSOLE) |= BIT(0); -} - -void uart_deepsleep_interrupt(enum gpio_signal signal) -{ - /* - * Activity seen on UART RX pin while UART was disabled for deep sleep. - * The console won't see that character because the UART is disabled, - * so we need to inform the clock module of UART activity ourselves. - */ - clock_refresh_console_in_use(); - - /* Disable interrupts on UART0 RX pin to avoid repeated interrupts. */ - gpio_disable_interrupt(GPIO_UART_RX); -} -#endif /* CONFIG_LOW_POWER_IDLE */ diff --git a/chip/mchp/util/pack_ec.py b/chip/mchp/util/pack_ec.py deleted file mode 100755 index 7908b0bf37..0000000000 --- a/chip/mchp/util/pack_ec.py +++ /dev/null @@ -1,536 +0,0 @@ -#!/usr/bin/env python3 - -# 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. -# -# Ignore indention messages, since legacy scripts use 2 spaces instead of 4. -# pylint: disable=bad-indentation,docstring-section-indent -# pylint: disable=docstring-trailing-quotes - -# A script to pack EC binary into SPI flash image for MEC17xx -# Based on MEC170x_ROM_Description.pdf DS00002225C (07-28-17). -import argparse -import hashlib -import os -import struct -import subprocess -import tempfile -import zlib # CRC32 - -# MEC1701 has 256KB SRAM from 0xE0000 - 0x120000 -# SRAM is divided into contiguous CODE & DATA -# CODE at [0xE0000, 0x117FFF] DATA at [0x118000, 0x11FFFF] -# SPI flash size for board is 512KB -# Boot-ROM TAG is located at SPI offset 0 (two 4-byte tags) -# - -LFW_SIZE = 0x1000 -LOAD_ADDR = 0x0E0000 -LOAD_ADDR_RW = 0xE1000 -HEADER_SIZE = 0x40 -SPI_CLOCK_LIST = [48, 24, 16, 12] -SPI_READ_CMD_LIST = [0x3, 0xb, 0x3b, 0x6b] - -CRC_TABLE = [0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, - 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d] - -def mock_print(*args, **kwargs): - pass - -debug_print = mock_print - -def Crc8(crc, data): - """Update CRC8 value.""" - for v in data: - crc = ((crc << 4) & 0xff) ^ (CRC_TABLE[(crc >> 4) ^ (v >> 4)]); - crc = ((crc << 4) & 0xff) ^ (CRC_TABLE[(crc >> 4) ^ (v & 0xf)]); - return crc ^ 0x55 - -def GetEntryPoint(payload_file): - """Read entry point from payload EC image.""" - with open(payload_file, 'rb') as f: - f.seek(4) - s = f.read(4) - return struct.unpack('<I', s)[0] - -def GetPayloadFromOffset(payload_file, offset): - """Read payload and pad it to 64-byte aligned.""" - with open(payload_file, 'rb') as f: - f.seek(offset) - payload = bytearray(f.read()) - rem_len = len(payload) % 64 - if rem_len: - payload += b'\0' * (64 - rem_len) - return payload - -def GetPayload(payload_file): - """Read payload and pad it to 64-byte aligned.""" - return GetPayloadFromOffset(payload_file, 0) - -def GetPublicKey(pem_file): - """Extract public exponent and modulus from PEM file.""" - result = subprocess.run(['openssl', 'rsa', '-in', pem_file, '-text', - '-noout'], stdout=subprocess.PIPE, encoding='utf-8') - modulus_raw = [] - in_modulus = False - for line in result.stdout.splitlines(): - if line.startswith('modulus'): - in_modulus = True - elif not line.startswith(' '): - in_modulus = False - elif in_modulus: - modulus_raw.extend(line.strip().strip(':').split(':')) - if line.startswith('publicExponent'): - exp = int(line.split(' ')[1], 10) - modulus_raw.reverse() - modulus = bytearray((int(x, 16) for x in modulus_raw[:256])) - return struct.pack('<Q', exp), modulus - -def GetSpiClockParameter(args): - assert args.spi_clock in SPI_CLOCK_LIST, \ - "Unsupported SPI clock speed %d MHz" % args.spi_clock - return SPI_CLOCK_LIST.index(args.spi_clock) - -def GetSpiReadCmdParameter(args): - assert args.spi_read_cmd in SPI_READ_CMD_LIST, \ - "Unsupported SPI read command 0x%x" % args.spi_read_cmd - return SPI_READ_CMD_LIST.index(args.spi_read_cmd) - -def PadZeroTo(data, size): - data.extend(b'\0' * (size - len(data))) - -def BuildHeader(args, payload_len, load_addr, rorofile): - # Identifier and header version - header = bytearray(b'PHCM\0') - - # byte[5] - b = GetSpiClockParameter(args) - b |= (1 << 2) - header.append(b) - - # byte[6] - b = 0 - header.append(b) - - # byte[7] - header.append(GetSpiReadCmdParameter(args)) - - # bytes 0x08 - 0x0b - header.extend(struct.pack('<I', load_addr)) - # bytes 0x0c - 0x0f - header.extend(struct.pack('<I', GetEntryPoint(rorofile))) - # bytes 0x10 - 0x13 - header.append((payload_len >> 6) & 0xff) - header.append((payload_len >> 14) & 0xff) - PadZeroTo(header, 0x14) - # bytes 0x14 - 0x17 - header.extend(struct.pack('<I', args.payload_offset)) - - # bytes 0x14 - 0x3F all 0 - PadZeroTo(header, 0x40) - - # header signature is appended by the caller - - return header - - -def BuildHeader2(args, payload_len, load_addr, payload_entry): - # Identifier and header version - header = bytearray(b'PHCM\0') - - # byte[5] - b = GetSpiClockParameter(args) - b |= (1 << 2) - header.append(b) - - # byte[6] - b = 0 - header.append(b) - - # byte[7] - header.append(GetSpiReadCmdParameter(args)) - - # bytes 0x08 - 0x0b - header.extend(struct.pack('<I', load_addr)) - # bytes 0x0c - 0x0f - header.extend(struct.pack('<I', payload_entry)) - # bytes 0x10 - 0x13 - header.append((payload_len >> 6) & 0xff) - header.append((payload_len >> 14) & 0xff) - PadZeroTo(header, 0x14) - # bytes 0x14 - 0x17 - header.extend(struct.pack('<I', args.payload_offset)) - - # bytes 0x14 - 0x3F all 0 - PadZeroTo(header, 0x40) - - # header signature is appended by the caller - - return header - -# -# Compute SHA-256 of data and return digest -# as a bytearray -# -def HashByteArray(data): - hasher = hashlib.sha256() - hasher.update(data) - h = hasher.digest() - bah = bytearray(h) - return bah - -# -# Return 64-byte signature of byte array data. -# Signature is SHA256 of data with 32 0 bytes appended -# -def SignByteArray(data): - debug_print("Signature is SHA-256 of data") - sigb = HashByteArray(data) - sigb.extend(b'\0' * 32) - return sigb - - -# MEC1701H supports two 32-bit Tags located at offsets 0x0 and 0x4 -# in the SPI flash. -# Tag format: -# bits[23:0] correspond to bits[31:8] of the Header SPI address -# Header is always on a 256-byte boundary. -# bits[31:24] = CRC8-ITU of bits[23:0]. -# Notice there is no chip-select field in the Tag both Tag's point -# to the same flash part. -# -def BuildTag(args): - tag = bytearray([(args.header_loc >> 8) & 0xff, - (args.header_loc >> 16) & 0xff, - (args.header_loc >> 24) & 0xff]) - tag.append(Crc8(0, tag)) - return tag - -def BuildTagFromHdrAddr(header_loc): - tag = bytearray([(header_loc >> 8) & 0xff, - (header_loc >> 16) & 0xff, - (header_loc >> 24) & 0xff]) - tag.append(Crc8(0, tag)) - return tag - - -# -# Creates temporary file for read/write -# Reads binary file containing LFW image_size (loader_file) -# Writes LFW image to temporary file -# Reads RO image at beginning of rorw_file up to image_size -# (assumes RO/RW images have been padded with 0xFF -# Returns temporary file name -# -def PacklfwRoImage(rorw_file, loader_file, image_size): - """Create a temp file with the - first image_size bytes from the loader file and append bytes - from the rorw file. - return the filename""" - fo=tempfile.NamedTemporaryFile(delete=False) # Need to keep file around - with open(loader_file,'rb') as fin1: # read 4KB loader file - pro = fin1.read() - fo.write(pro) # write 4KB loader data to temp file - with open(rorw_file, 'rb') as fin: - ro = fin.read(image_size) - - fo.write(ro) - fo.close() - return fo.name - -# -# Generate a test EC_RW image of same size -# as original. -# Preserve image_data structure and fill all -# other bytes with 0xA5. -# useful for testing SPI read and EC build -# process hash generation. -# -def gen_test_ecrw(pldrw): - debug_print("gen_test_ecrw: pldrw type =", type(pldrw)) - debug_print("len pldrw =", len(pldrw), " = ", hex(len(pldrw))) - cookie1_pos = pldrw.find(b'\x99\x88\x77\xce') - cookie2_pos = pldrw.find(b'\xdd\xbb\xaa\xce', cookie1_pos+4) - t = struct.unpack("<L", pldrw[cookie1_pos+0x24:cookie1_pos+0x28]) - size = t[0] - debug_print("EC_RW size =", size, " = ", hex(size)) - - debug_print("Found cookie1 at ", hex(cookie1_pos)) - debug_print("Found cookie2 at ", hex(cookie2_pos)) - - if cookie1_pos > 0 and cookie2_pos > cookie1_pos: - for i in range(0, cookie1_pos): - pldrw[i] = 0xA5 - for i in range(cookie2_pos+4, len(pldrw)): - pldrw[i] = 0xA5 - - with open("ec_RW_test.bin", "wb") as fecrw: - fecrw.write(pldrw[:size]) - -def parseargs(): - rpath = os.path.dirname(os.path.relpath(__file__)) - - parser = argparse.ArgumentParser() - parser.add_argument("-i", "--input", - help="EC binary to pack, usually ec.bin or ec.RO.flat.", - metavar="EC_BIN", default="ec.bin") - parser.add_argument("-o", "--output", - help="Output flash binary file", - metavar="EC_SPI_FLASH", default="ec.packed.bin") - parser.add_argument("--loader_file", - help="EC loader binary", - default="ecloader.bin") - parser.add_argument("-s", "--spi_size", type=int, - help="Size of the SPI flash in KB", - default=512) - parser.add_argument("-l", "--header_loc", type=int, - help="Location of header in SPI flash", - default=0x1000) - parser.add_argument("-p", "--payload_offset", type=int, - help="The offset of payload from the start of header", - default=0x80) - parser.add_argument("-r", "--rw_loc", type=int, - help="Start offset of EC_RW. Default is -1 meaning 1/2 flash size", - default=-1) - parser.add_argument("--spi_clock", type=int, - help="SPI clock speed. 8, 12, 24, or 48 MHz.", - default=24) - parser.add_argument("--spi_read_cmd", type=int, - help="SPI read command. 0x3, 0xB, or 0x3B.", - default=0xb) - parser.add_argument("--image_size", type=int, - help="Size of a single image. Default 220KB", - default=(220 * 1024)) - parser.add_argument("--test_spi", action='store_true', - help="Test SPI data integrity by adding CRC32 in last 4-bytes of RO/RW binaries", - default=False) - parser.add_argument("--test_ecrw", action='store_true', - help="Use fixed pattern for EC_RW but preserve image_data", - default=False) - parser.add_argument("--verbose", action='store_true', - help="Enable verbose output", - default=False) - - return parser.parse_args() - -# Debug helper routine -def dumpsects(spi_list): - debug_print("spi_list has {0} entries".format(len(spi_list))) - for s in spi_list: - debug_print("0x{0:x} 0x{1:x} {2:s}".format(s[0],len(s[1]),s[2])) - -def printByteArrayAsHex(ba, title): - debug_print(title,"= ") - count = 0 - for b in ba: - count = count + 1 - debug_print("0x{0:02x}, ".format(b),end="") - if (count % 8) == 0: - debug_print("") - debug_print("\n") - -def print_args(args): - debug_print("parsed arguments:") - debug_print(".input = ", args.input) - debug_print(".output = ", args.output) - debug_print(".loader_file = ", args.loader_file) - debug_print(".spi_size (KB) = ", hex(args.spi_size)) - debug_print(".image_size = ", hex(args.image_size)) - debug_print(".header_loc = ", hex(args.header_loc)) - debug_print(".payload_offset = ", hex(args.payload_offset)) - if args.rw_loc < 0: - debug_print(".rw_loc = ", args.rw_loc) - else: - debug_print(".rw_loc = ", hex(args.rw_loc)) - debug_print(".spi_clock = ", args.spi_clock) - debug_print(".spi_read_cmd = ", args.spi_read_cmd) - debug_print(".test_spi = ", args.test_spi) - debug_print(".verbose = ", args.verbose) - -# -# Handle quiet mode build from Makefile -# Quiet mode when V is unset or V=0 -# Verbose mode when V=1 -# -def main(): - global debug_print - - args = parseargs() - - if args.verbose: - debug_print = print - - debug_print("Begin MEC17xx pack_ec.py script") - - - # MEC17xx maximum 192KB each for RO & RW - # mec1701 chip Makefile sets args.spi_size = 512 - # Tags at offset 0 - # - print_args(args) - - spi_size = args.spi_size * 1024 - debug_print("SPI Flash image size in bytes =", hex(spi_size)) - - # !!! IMPORTANT !!! - # These values MUST match chip/mec1701/config_flash_layout.h - # defines. - # MEC17xx Boot-ROM TAGs are at offset 0 and 4. - # lfw + EC_RO starts at beginning of second 4KB sector - # EC_RW starts at offset 0x40000 (256KB) - - spi_list = [] - - debug_print("args.input = ",args.input) - debug_print("args.loader_file = ",args.loader_file) - debug_print("args.image_size = ",hex(args.image_size)) - - rorofile=PacklfwRoImage(args.input, args.loader_file, args.image_size) - - payload = GetPayload(rorofile) - payload_len = len(payload) - # debug - debug_print("EC_LFW + EC_RO length = ",hex(payload_len)) - - # SPI image integrity test - # compute CRC32 of EC_RO except for last 4 bytes - # skip over 4KB LFW - # Store CRC32 in last 4 bytes - if args.test_spi == True: - crc = zlib.crc32(bytes(payload[LFW_SIZE:(payload_len - 4)])) - crc_ofs = payload_len - 4 - debug_print("EC_RO CRC32 = 0x{0:08x} @ 0x{1:08x}".format(crc, crc_ofs)) - for i in range(4): - payload[crc_ofs + i] = crc & 0xff - crc = crc >> 8 - - # Chromebooks are not using MEC BootROM ECDSA. - # We implemented the ECDSA disabled case where - # the 64-byte signature contains a SHA-256 of the binary plus - # 32 zeros bytes. - payload_signature = SignByteArray(payload) - # debug - printByteArrayAsHex(payload_signature, "LFW + EC_RO payload_signature") - - # MEC17xx Header is 0x80 bytes with an 64 byte signature - # (32 byte SHA256 + 32 zero bytes) - header = BuildHeader(args, payload_len, LOAD_ADDR, rorofile) - # debug - printByteArrayAsHex(header, "Header LFW + EC_RO") - - # MEC17xx payload ECDSA not used, 64 byte signature is - # SHA256 + 32 zero bytes - header_signature = SignByteArray(header) - # debug - printByteArrayAsHex(header_signature, "header_signature") - - tag = BuildTag(args) - # MEC17xx truncate RW length to args.image_size to not overwrite LFW - # offset may be different due to Header size and other changes - # MCHP we want to append a SHA-256 to the end of the actual payload - # to test SPI read routines. - debug_print("Call to GetPayloadFromOffset") - debug_print("args.input = ", args.input) - debug_print("args.image_size = ", hex(args.image_size)) - - payload_rw = GetPayloadFromOffset(args.input, args.image_size) - debug_print("type(payload_rw) is ", type(payload_rw)) - debug_print("len(payload_rw) is ", hex(len(payload_rw))) - - # truncate to args.image_size - rw_len = args.image_size - payload_rw = payload_rw[:rw_len] - payload_rw_len = len(payload_rw) - debug_print("Truncated size of EC_RW = ", hex(payload_rw_len)) - - payload_entry_tuple = struct.unpack_from('<I', payload_rw, 4) - debug_print("payload_entry_tuple = ", payload_entry_tuple) - - payload_entry = payload_entry_tuple[0] - debug_print("payload_entry = ", hex(payload_entry)) - - # Note: payload_rw is a bytearray therefore is mutable - if args.test_ecrw: - gen_test_ecrw(payload_rw) - - # SPI image integrity test - # compute CRC32 of EC_RW except for last 4 bytes - # Store CRC32 in last 4 bytes - if args.test_spi == True: - crc = zlib.crc32(bytes(payload_rw[:(payload_rw_len - 32)])) - crc_ofs = payload_rw_len - 4 - debug_print("EC_RW CRC32 = 0x{0:08x} at offset 0x{1:08x}".format(crc, crc_ofs)) - for i in range(4): - payload_rw[crc_ofs + i] = crc & 0xff - crc = crc >> 8 - - payload_rw_sig = SignByteArray(payload_rw) - # debug - printByteArrayAsHex(payload_rw_sig, "payload_rw_sig") - - os.remove(rorofile) # clean up the temp file - - # MEC170x Boot-ROM Tags are located at SPI offset 0 - spi_list.append((0, tag, "tag")) - - spi_list.append((args.header_loc, header, "header(lwf + ro)")) - spi_list.append((args.header_loc + HEADER_SIZE, header_signature, - "header(lwf + ro) signature")) - spi_list.append((args.header_loc + args.payload_offset, payload, - "payload(lfw + ro)")) - - offset = args.header_loc + args.payload_offset + payload_len - - # No SPI Header for EC_RW as its not loaded by BootROM - spi_list.append((offset, payload_signature, - "payload(lfw_ro) signature")) - - # EC_RW location - rw_offset = int(spi_size // 2) - if args.rw_loc >= 0: - rw_offset = args.rw_loc - - debug_print("rw_offset = 0x{0:08x}".format(rw_offset)) - - if rw_offset < offset + len(payload_signature): - print("ERROR: EC_RW overlaps EC_RO") - - spi_list.append((rw_offset, payload_rw, "payload(rw)")) - - # don't add to EC_RW. We don't know if Google will process - # EC SPI flash binary with other tools during build of - # coreboot and OS. - #offset = rw_offset + payload_rw_len - #spi_list.append((offset, payload_rw_sig, "payload(rw) signature")) - - spi_list = sorted(spi_list) - - dumpsects(spi_list) - - # - # MEC17xx Boot-ROM locates TAG at SPI offset 0 instead of end of SPI. - # - with open(args.output, 'wb') as f: - debug_print("Write spi list to file", args.output) - addr = 0 - for s in spi_list: - if addr < s[0]: - debug_print("Offset ",hex(addr)," Length", hex(s[0]-addr), - "fill with 0xff") - f.write(b'\xff' * (s[0] - addr)) - addr = s[0] - debug_print("Offset ",hex(addr), " Length", hex(len(s[1])), "write data") - - f.write(s[1]) - addr += len(s[1]) - - if addr < spi_size: - debug_print("Offset ",hex(addr), " Length", hex(spi_size - addr), - "fill with 0xff") - f.write(b'\xff' * (spi_size - addr)) - - f.flush() - -if __name__ == '__main__': - main() diff --git a/chip/mchp/util/pack_ec_mec152x.py b/chip/mchp/util/pack_ec_mec152x.py deleted file mode 100755 index 34846cd6ba..0000000000 --- a/chip/mchp/util/pack_ec_mec152x.py +++ /dev/null @@ -1,803 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Ignore indention messages, since legacy scripts use 2 spaces instead of 4. -# pylint: disable=bad-indentation,docstring-section-indent -# pylint: disable=docstring-trailing-quotes - -# A script to pack EC binary into SPI flash image for MEC152x -# Based on MEC1521/MEC1523_ROM_Description.pdf -import argparse -import hashlib -import os -import struct -import subprocess -import tempfile -import zlib # CRC32 - -# MEC152xH has 256KB SRAM from 0xE0000 - 0x120000 -# SRAM is divided into contiguous CODE & DATA -# CODE at [0xE0000, 0x117FFF] DATA at [0x118000, 0x11FFFF] -# SPI flash size for board is 512KB -# Boot-ROM TAG is located at SPI offset 0 (two 4-byte tags) - -LFW_SIZE = 0x1000 -LOAD_ADDR = 0x0E0000 -LOAD_ADDR_RW = 0xE1000 -MEC152X_HEADER_SIZE = 0x140 -MEC152X_HEADER_VERSION = 0x02 -PAYLOAD_PAD_BYTE = b'\xff' -SPI_ERASE_BLOCK_SIZE = 0x1000 -SPI_CLOCK_LIST = [48, 24, 16, 12] -SPI_READ_CMD_LIST = [0x3, 0xb, 0x3b, 0x6b] -SPI_DRIVE_STR_DICT = {2:0, 4:1, 8:2, 12:3} -CHIP_MAX_CODE_SRAM_KB = 224 - -MEC152X_DICT = { - "HEADER_SIZE":0x140, - "HEADER_VER":0x02, - "PAYLOAD_OFFSET":0x140, - "PAYLOAD_GRANULARITY":128, - "EC_INFO_BLK_SZ":128, - "ENCR_KEY_HDR_SZ":128, - "COSIG_SZ":96, - "TRAILER_SZ":160, - "TAILER_PAD_BYTE":b'\xff', - "PAD_SIZE":128 - } - -CRC_TABLE = [0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, - 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d] - -def mock_print(*args, **kwargs): - pass - -debug_print = mock_print - -# Debug helper routine -def dumpsects(spi_list): - debug_print("spi_list has {0} entries".format(len(spi_list))) - for s in spi_list: - debug_print("0x{0:x} 0x{1:x} {2:s}".format(s[0],len(s[1]),s[2])) - -def printByteArrayAsHex(ba, title): - debug_print(title,"= ") - if ba == None: - debug_print("None") - return - - count = 0 - for b in ba: - count = count + 1 - debug_print("0x{0:02x}, ".format(b),end="") - if (count % 8) == 0: - debug_print("") - debug_print("") - -def Crc8(crc, data): - """Update CRC8 value.""" - for v in data: - crc = ((crc << 4) & 0xff) ^ (CRC_TABLE[(crc >> 4) ^ (v >> 4)]); - crc = ((crc << 4) & 0xff) ^ (CRC_TABLE[(crc >> 4) ^ (v & 0xf)]); - return crc ^ 0x55 - -def GetEntryPoint(payload_file): - """Read entry point from payload EC image.""" - with open(payload_file, 'rb') as f: - f.seek(4) - s = f.read(4) - return int.from_bytes(s, byteorder='little') - -def GetPayloadFromOffset(payload_file, offset, padsize): - """Read payload and pad it to padsize.""" - with open(payload_file, 'rb') as f: - f.seek(offset) - payload = bytearray(f.read()) - rem_len = len(payload) % padsize - debug_print("GetPayload: padsize={0:0x} len(payload)={1:0x} rem={2:0x}".format(padsize,len(payload),rem_len)) - - if rem_len: - payload += PAYLOAD_PAD_BYTE * (padsize - rem_len) - debug_print("GetPayload: Added {0} padding bytes".format(padsize - rem_len)) - - return payload - -def GetPayload(payload_file, padsize): - """Read payload and pad it to padsize""" - return GetPayloadFromOffset(payload_file, 0, padsize) - -def GetPublicKey(pem_file): - """Extract public exponent and modulus from PEM file.""" - result = subprocess.run(['openssl', 'rsa', '-in', pem_file, '-text', - '-noout'], stdout=subprocess.PIPE, encoding='utf-8') - modulus_raw = [] - in_modulus = False - for line in result.stdout.splitlines(): - if line.startswith('modulus'): - in_modulus = True - elif not line.startswith(' '): - in_modulus = False - elif in_modulus: - modulus_raw.extend(line.strip().strip(':').split(':')) - if line.startswith('publicExponent'): - exp = int(line.split(' ')[1], 10) - modulus_raw.reverse() - modulus = bytearray((int(x, 16) for x in modulus_raw[:256])) - return struct.pack('<Q', exp), modulus - -def GetSpiClockParameter(args): - assert args.spi_clock in SPI_CLOCK_LIST, \ - "Unsupported SPI clock speed %d MHz" % args.spi_clock - return SPI_CLOCK_LIST.index(args.spi_clock) - -def GetSpiReadCmdParameter(args): - assert args.spi_read_cmd in SPI_READ_CMD_LIST, \ - "Unsupported SPI read command 0x%x" % args.spi_read_cmd - return SPI_READ_CMD_LIST.index(args.spi_read_cmd) - -def GetEncodedSpiDriveStrength(args): - assert args.spi_drive_str in SPI_DRIVE_STR_DICT, \ - "Unsupported SPI drive strength %d mA" % args.spi_drive_str - return SPI_DRIVE_STR_DICT.get(args.spi_drive_str) - -# Return 0=Slow slew rate or 1=Fast slew rate -def GetSpiSlewRate(args): - if args.spi_slew_fast == True: - return 1 - return 0 - -# Return SPI CPOL = 0 or 1 -def GetSpiCpol(args): - if args.spi_cpol == 0: - return 0 - return 1 - -# Return SPI CPHA_MOSI -# 0 = SPI Master drives data is stable on inactive to clock edge -# 1 = SPI Master drives data is stable on active to inactive clock edge -def GetSpiCphaMosi(args): - if args.spi_cpha_mosi == 0: - return 0 - return 1 - -# Return SPI CPHA_MISO 0 or 1 -# 0 = SPI Master samples data on inactive to active clock edge -# 1 = SPI Master samples data on active to inactive clock edge -def GetSpiCphaMiso(args): - if args.spi_cpha_miso == 0: - return 0 - return 1 - -def PadZeroTo(data, size): - data.extend(b'\0' * (size - len(data))) - -# -# Boot-ROM SPI image encryption not used with Chromebooks -# -def EncryptPayload(args, chip_dict, payload): - return None - -# -# Build SPI image header for MEC152x -# MEC152x image header size = 320(0x140) bytes -# -# Description using Python slice notation [start:start+len] -# -# header[0:4] = 'PHCM' -# header[4] = header version = 0x02(MEC152x) -# header[5] = SPI clock speed, drive strength, sampling mode -# bits[1:0] = SPI clock speed: 0=48, 1=24, 2=16, 3=12 -# bits[3:2] = SPI controller pins drive strength -# 00b=2mA, 01b=4mA, 10b=8mA, 11b=12mA -# bit[4] = SPI controller pins slew rate: 0=slow, 1=fast -# bit[5] = SPI CPOL: 0=SPI clock idle is low, 1=idle is high -# bit[6] = CHPHA_MOSI -# 1:data change on first inactive to active clock edge -# 0:data change on first active to inactive clock edge -# bit[7] = CHPHA_MISO: -# 1: Data captured on first inactive to active clock edge -# 0: Data captured on first active to inactive clock edge -# header[6] Boot-ROM loader flags -# bits[2:0] = VTR0,1,2 rails. 0=3.3V, 1=1.8V. NOTE VTR1=0 always -# bits[5:3] = 111b -# bit[6]: For MEC152x controls authentication -# 0=Authentication disabled. Signature is SHA-384 of FW payload -# 1=Authentication enabled. Signature is ECDSA P-384 -# bit[7]: 0=FW pyload not encrypted, 1=FW payload is encrypted -# header[7]: SPI Flash read command -# 0x03 1-1-1 read freq < 33MHz -# 0x0B 1-1-1 + 8 clocks(data tri-stated) -# 0x3B 1-1-2 + 8 clocks(data tri-stated). Data phase is dual I/O -# 0x6B 1-1-4 + 8 clocks(data tri-stated). Data phase is Quad I/O -# NOTE: Quad requires SPI flash device QE(quad enable) bit -# to be factory set. Enabling QE disables HOLD# and WP# -# functionality of the SPI flash device. -# header[0x8:0xC] SRAM Load address little-endian format -# header[0xC:0x10] SRAM FW entry point. Boot-ROM jumps to -# this address on successful load. (little-endian) -# header[0x10:0x12] little-endian format: FW binary size in units of -# 128 bytes(MEC152x) -# header[0x12:0x14] = 0 reserved -# header[0x14:0x18] = Little-ending format: Unsigned offset from start of -# header to FW payload. -# MEC152x: Offset must be a multiple of 128 -# Offset must be > header size. -# NOTE: If Authentication is enabled size includes -# the appended signature. -# MEC152x: -# header[0x18] = Authentication key select. Set to 0 for no Authentication. -# header[0x19:0x50] = 0 reserved. -# header[0x50:0x80] = ECDSA-384 public key x-coord. = 0 Auth. disabled -# header[0x80:0xB0] = ECDSA-384 public key y-coord. = 0 Auth. disabled -# header[0xB0:0xE0] = SHA-384 digest of header[0:0xB0] -# header[0xE0:0x110] = Header ECDSA-384 signature x-coord. = 0 Auth. disabled -# header[0x110:0x140] = Header ECDSA-384 signature y-coor. = 0 Auth. disabled -# -def BuildHeader2(args, chip_dict, payload_len, load_addr, payload_entry): - header_size = MEC152X_HEADER_SIZE - - # allocate zero filled header - header = bytearray(b'\x00' * header_size) - debug_print("len(header) = ", len(header)) - - # Identifier and header version - header[0:4] = b'PHCM' - header[4] = MEC152X_HEADER_VERSION - - # SPI frequency, drive strength, CPOL/CPHA encoding same for both chips - spiFreqMHz = GetSpiClockParameter(args) - header[5] = (int(spiFreqMHz // 48) - 1) & 0x03 - header[5] |= ((GetEncodedSpiDriveStrength(args) & 0x03) << 2) - header[5] |= ((GetSpiSlewRate(args) & 0x01) << 4) - header[5] |= ((GetSpiCpol(args) & 0x01) << 5) - header[5] |= ((GetSpiCphaMosi(args) & 0x01) << 6) - header[5] |= ((GetSpiCphaMiso(args) & 0x01) << 7) - - # b[0]=0 VTR1 must be 3.3V - # b[1]=0(VTR2 3.3V), 1(VTR2 1.8V) - # b[2]=0(VTR3 3.3V), 1(VTR3 1.8V) - # b[5:3]=111b - # b[6]=0 No ECDSA - # b[7]=0 No encrypted FW image - header[6] = 0x7 << 3 - if args.vtr2_V18 == True: - header[6] |= 0x02 - if args.vtr3_V18 == True: - header[6] |= 0x04 - - # SPI read command set same for both chips - header[7] = GetSpiReadCmdParameter(args) & 0xFF - - # bytes 0x08 - 0x0b - header[0x08:0x0C] = load_addr.to_bytes(4, byteorder='little') - # bytes 0x0c - 0x0f - header[0x0C:0x10] = payload_entry.to_bytes(4, byteorder='little') - # bytes 0x10 - 0x11 payload length in units of 128 bytes - - payload_units = int(payload_len // chip_dict["PAYLOAD_GRANULARITY"]) - assert payload_units < 0x10000, \ - print("Payload too large: len={0} units={1}".format(payload_len, payload_units)) - - header[0x10:0x12] = payload_units.to_bytes(2, 'little') - - # bytes 0x14 - 0x17 - header[0x14:0x18] = chip_dict["PAYLOAD_OFFSET"].to_bytes(4, 'little') - - # MEC152x: Disable ECDSA and encryption - header[0x18] = 0 - - # header[0xB0:0xE0] = SHA384(header[0:0xB0]) - header[0xB0:0xE0] = hashlib.sha384(header[0:0xB0]).digest() - # When ECDSA authentication is disabled MCHP SPI image generator - # is filling the last 48 bytes of the Header with 0xff - header[-48:] = b'\xff' * 48 - - debug_print("After hash: len(header) = ", len(header)) - - return header - -# -# MEC152x 128-byte EC Info Block appended to -# end of padded FW binary -# bytes 0 through 103 are undefined, we set to 0xFF -# bytes 104 through 119 are rollback permissions -# bytes 120 through 123 are key revocation permissions -# byte 124 = customer platform ID[7:0] -# byte 125 = customer platform ID[15:8] -# byte 126 = customer auto rollback flags -# byte 127 = customer current image revision -# -def GenEcInfoBlock(args, chip_dict): - ecinfo = bytearray(chip_dict["EC_INFO_BLK_SZ"]) - return ecinfo - -# -# Generate SPI FW image co-signature. -# MEC152X cosignature is 96 bytes used by OEM FW -# developer to sign their binary with ECDSA-P384-SHA384 or -# some other signature algorithm that fits in 96 bytes. -# At this time Cros-EC is not using this field, fill with 0xFF. -# If this feature is implemented we need to read the OEM's -# generated signature from a file and extract the binary -# signature. -# -def GenCoSignature(args, chip_dict, payload): - return bytearray(b'\xff' * chip_dict["COSIG_SZ"]) - -# -# Generate SPI FW Image trailer. -# MEC152X: Size = 160 bytes -# binary = payload || encryption_key_header || ec_info_block || cosignature -# trailer[0:48] = SHA384(binary) -# trailer[48:144] = 0xFF -# trailer[144:160] = 0xFF. Boot-ROM spec. says these bytes should be random. -# Authentication & encryption are not used therefore random data -# is not necessary. -def GenTrailer(args, chip_dict, payload, encryption_key_header, - ec_info_block, cosignature): - trailer = bytearray(chip_dict["TAILER_PAD_BYTE"] * chip_dict["TRAILER_SZ"]) - hasher = hashlib.sha384() - hasher.update(payload) - if ec_info_block != None: - hasher.update(ec_info_block) - if encryption_key_header != None: - hasher.update(encryption_key_header) - if cosignature != None: - hasher.update(cosignature) - trailer[0:48] = hasher.digest() - trailer[-16:] = 16 * b'\xff' - - return trailer - -# MEC152xH supports two 32-bit Tags located at offsets 0x0 and 0x4 -# in the SPI flash. -# Tag format: -# bits[23:0] correspond to bits[31:8] of the Header SPI address -# Header is always on a 256-byte boundary. -# bits[31:24] = CRC8-ITU of bits[23:0]. -# Notice there is no chip-select field in the Tag both Tag's point -# to the same flash part. -# -def BuildTag(args): - tag = bytearray([(args.header_loc >> 8) & 0xff, - (args.header_loc >> 16) & 0xff, - (args.header_loc >> 24) & 0xff]) - tag.append(Crc8(0, tag)) - return tag - -def BuildTagFromHdrAddr(header_loc): - tag = bytearray([(header_loc >> 8) & 0xff, - (header_loc >> 16) & 0xff, - (header_loc >> 24) & 0xff]) - tag.append(Crc8(0, tag)) - return tag - - -# FlashMap is an option for MEC152x -# It is a 32 bit structure -# bits[18:0] = bits[30:12] of second SPI flash base address -# bits[23:19] = 0 reserved -# bits[31:24] = CRC8 of bits[23:0] -# Input: -# integer containing base address of second SPI flash -# This value is usually equal to the size of the first -# SPI flash and should be a multiple of 4KB -# Output: -# bytearray of length 4 -def BuildFlashMap(secondSpiFlashBaseAddr): - flashmap = bytearray(4) - flashmap[0] = (secondSpiFlashBaseAddr >> 12) & 0xff - flashmap[1] = (secondSpiFlashBaseAddr >> 20) & 0xff - flashmap[2] = (secondSpiFlashBaseAddr >> 28) & 0xff - flashmap[3] = Crc8(0, flashmap) - return flashmap - -# -# Creates temporary file for read/write -# Reads binary file containing LFW image_size (loader_file) -# Writes LFW image to temporary file -# Reads RO image at beginning of rorw_file up to image_size -# (assumes RO/RW images have been padded with 0xFF -# Returns temporary file name -# -def PacklfwRoImage(rorw_file, loader_file, image_size): - """Create a temp file with the - first image_size bytes from the loader file and append bytes - from the rorw file. - return the filename""" - fo=tempfile.NamedTemporaryFile(delete=False) # Need to keep file around - with open(loader_file,'rb') as fin1: # read 4KB loader file - pro = fin1.read() - fo.write(pro) # write 4KB loader data to temp file - with open(rorw_file, 'rb') as fin: - ro = fin.read(image_size) - - fo.write(ro) - fo.close() - - return fo.name - -# -# Generate a test EC_RW image of same size -# as original. -# Preserve image_data structure and fill all -# other bytes with 0xA5. -# useful for testing SPI read and EC build -# process hash generation. -# -def gen_test_ecrw(pldrw): - debug_print("gen_test_ecrw: pldrw type =", type(pldrw)) - debug_print("len pldrw =", len(pldrw), " = ", hex(len(pldrw))) - cookie1_pos = pldrw.find(b'\x99\x88\x77\xce') - cookie2_pos = pldrw.find(b'\xdd\xbb\xaa\xce', cookie1_pos+4) - t = struct.unpack("<L", pldrw[cookie1_pos+0x24:cookie1_pos+0x28]) - size = t[0] - debug_print("EC_RW size =", size, " = ", hex(size)) - - debug_print("Found cookie1 at ", hex(cookie1_pos)) - debug_print("Found cookie2 at ", hex(cookie2_pos)) - - if cookie1_pos > 0 and cookie2_pos > cookie1_pos: - for i in range(0, cookie1_pos): - pldrw[i] = 0xA5 - for i in range(cookie2_pos+4, len(pldrw)): - pldrw[i] = 0xA5 - - with open("ec_RW_test.bin", "wb") as fecrw: - fecrw.write(pldrw[:size]) - -def parseargs(): - #TODO I commented this out. Why? - rpath = os.path.dirname(os.path.relpath(__file__)) - - parser = argparse.ArgumentParser() - parser.add_argument("-i", "--input", - help="EC binary to pack, usually ec.bin or ec.RO.flat.", - metavar="EC_BIN", default="ec.bin") - parser.add_argument("-o", "--output", - help="Output flash binary file", - metavar="EC_SPI_FLASH", default="ec.packed.bin") - parser.add_argument("--loader_file", - help="EC loader binary", - default="ecloader.bin") - parser.add_argument("-s", "--spi_size", type=int, - help="Size of the SPI flash in KB", - default=512) - parser.add_argument("-l", "--header_loc", type=int, - help="Location of header in SPI flash", - default=0x1000) - parser.add_argument("-r", "--rw_loc", type=int, - help="Start offset of EC_RW. Default is -1 meaning 1/2 flash size", - default=-1) - parser.add_argument("--spi_clock", type=int, - help="SPI clock speed. 8, 12, 24, or 48 MHz.", - default=24) - parser.add_argument("--spi_read_cmd", type=int, - help="SPI read command. 0x3, 0xB, or 0x3B.", - default=0xb) - parser.add_argument("--image_size", type=int, - help="Size of a single image. Default 220KB", - default=(220 * 1024)) - parser.add_argument("--test_spi", action='store_true', - help="Test SPI data integrity by adding CRC32 in last 4-bytes of RO/RW binaries", - default=False) - parser.add_argument("--test_ecrw", action='store_true', - help="Use fixed pattern for EC_RW but preserve image_data", - default=False) - parser.add_argument("--verbose", action='store_true', - help="Enable verbose output", - default=False) - parser.add_argument("--tag0_loc", type=int, - help="MEC152X TAG0 SPI offset", - default=0) - parser.add_argument("--tag1_loc", type=int, - help="MEC152X TAG1 SPI offset", - default=4) - parser.add_argument("--spi_drive_str", type=int, - help="Chip SPI drive strength in mA: 2, 4, 8, or 12", - default=4) - parser.add_argument("--spi_slew_fast", action='store_true', - help="SPI use fast slew rate. Default is False", - default=False) - parser.add_argument("--spi_cpol", type=int, - help="SPI clock polarity when idle. Defealt is 0(low)", - default=0) - parser.add_argument("--spi_cpha_mosi", type=int, - help="""SPI clock phase master drives data. - 0=Data driven on active to inactive clock edge, - 1=Data driven on inactive to active clock edge""", - default=0) - parser.add_argument("--spi_cpha_miso", type=int, - help="""SPI clock phase master samples data. - 0=Data sampled on inactive to active clock edge, - 1=Data sampled on active to inactive clock edge""", - default=0) - - parser.add_argument("--vtr2_V18", action='store_true', - help="Chip VTR2 rail is 1.8V. Default is False(3.3V)", - default=False) - - parser.add_argument("--vtr3_V18", action='store_true', - help="Chip VTR3 rail is 1.8V. Default is False(3.3V)", - default=False) - - return parser.parse_args() - -def print_args(args): - debug_print("parsed arguments:") - debug_print(".input = ", args.input) - debug_print(".output = ", args.output) - debug_print(".loader_file = ", args.loader_file) - debug_print(".spi_size (KB) = ", hex(args.spi_size)) - debug_print(".image_size = ", hex(args.image_size)) - debug_print(".tag0_loc = ", hex(args.tag0_loc)) - debug_print(".tag1_loc = ", hex(args.tag1_loc)) - debug_print(".header_loc = ", hex(args.header_loc)) - if args.rw_loc < 0: - debug_print(".rw_loc = ", args.rw_loc) - else: - debug_print(".rw_loc = ", hex(args.rw_loc)) - debug_print(".spi_clock (MHz) = ", args.spi_clock) - debug_print(".spi_read_cmd = ", hex(args.spi_read_cmd)) - debug_print(".test_spi = ", args.test_spi) - debug_print(".test_ecrw = ", args.test_ecrw) - debug_print(".verbose = ", args.verbose) - debug_print(".spi_drive_str = ", args.spi_drive_str) - debug_print(".spi_slew_fast = ", args.spi_slew_fast) - debug_print(".spi_cpol = ", args.spi_cpol) - debug_print(".spi_cpha_mosi = ", args.spi_cpha_mosi) - debug_print(".spi_cpha_miso = ", args.spi_cpha_miso) - debug_print(".vtr2_V18 = ", args.vtr2_V18) - debug_print(".vtr3_V18 = ", args.vtr3_V18) - -# -# Handle quiet mode build from Makefile -# Quiet mode when V is unset or V=0 -# Verbose mode when V=1 -# -# MEC152x SPI Image Generator -# No authentication -# No payload encryption -# -# SPI Offset 0x0 = TAG0 points to Header for EC-RO FW -# SPI Offset 0x4 = TAG1 points to Header for EC-RO FW -# TAG Size = 4 bytes -# bits[23:0] = bits[31:8] of Header SPI offset -# bits[31:24] = CRC8-ITU checksum of bits[23:0]. -# -# MEC152X SPI header and payload layout for minimum size -# header offset aligned on 256 byte boundary -# header_spi_address: -# header[0:0x4F] = Header data -# header[0x50:0x80] = ECDSA-P384 public key x for Header authentication -# header[0x80:0xB0] = ECDSA-P384 public key y for Header authentication -# header[0xB0:0xE0] = SHA384 digest of header[0:0xB0] -# header[0xE0:0x110] = ECDSA-P384-SHA384 Signature.R of header[0:0xB0] -# header[0x110:0x140] = ECDSA-P384-SHA384 Signature.S of header[0:0xB0] -# payload_spi_address = header_spi_address + len(Header) -# Payload had been padded such that len(padded_payload) % 128 == 0 -# padded_payload[padded_payload_len] -# payload_signature_address = payload_spi_address + len(padded_payload) -# payload_encryption_key_header[128] Not present if encryption disabled -# payload_cosignature[96] = 0 if Authentication is disabled -# payload_trailer[160] = SHA384(padded_payload || -# optional payload_encryption_key_header) -# || 48 * [0] -# || 48 * [0] -# -def main(): - global debug_print - - args = parseargs() - - if args.verbose: - debug_print = print - - debug_print("Begin pack_ec_mec152x.py script") - - print_args(args) - - chip_dict = MEC152X_DICT - - # Boot-ROM requires header location aligned >= 256 bytes. - # CrOS EC flash image update code requires EC_RO/RW location to be aligned - # on a flash erase size boundary and EC_RO/RW size to be a multiple of - # the smallest flash erase block size. - # - assert (args.header_loc % SPI_ERASE_BLOCK_SIZE) == 0, \ - "Header location %d is not on a flash erase block boundary boundary" % args.header_loc - - max_image_size = CHIP_MAX_CODE_SRAM_KB - LFW_SIZE - if args.test_spi: - max_image_size -= 32 # SHA256 digest - - assert args.image_size > max_image_size, \ - "Image size exceeds maximum" % args.image_size - - spi_size = args.spi_size * 1024 - debug_print("SPI Flash image size in bytes =", hex(spi_size)) - - # !!! IMPORTANT !!! - # These values MUST match chip/mchp/config_flash_layout.h - # defines. - # MEC152x Boot-ROM TAGs are at offset 0 and 4. - # lfw + EC_RO starts at beginning of second 4KB sector - # EC_RW starts at (flash size / 2) i.e. 0x40000 for a 512KB flash. - - spi_list = [] - - debug_print("args.input = ",args.input) - debug_print("args.loader_file = ",args.loader_file) - debug_print("args.image_size = ",hex(args.image_size)) - - rorofile=PacklfwRoImage(args.input, args.loader_file, args.image_size) - debug_print("Temporary file containing LFW + EC_RO is ", rorofile) - - lfw_ecro = GetPayload(rorofile, chip_dict["PAD_SIZE"]) - lfw_ecro_len = len(lfw_ecro) - debug_print("Padded LFW + EC_RO length = ", hex(lfw_ecro_len)) - - # SPI test mode compute CRC32 of EC_RO and store in last 4 bytes - if args.test_spi: - crc32_ecro = zlib.crc32(bytes(lfw_ecro[LFW_SIZE:-4])) - crc32_ecro_bytes = crc32_ecro.to_bytes(4, byteorder='little') - lfw_ecro[-4:] = crc32_ecro_bytes - debug_print("ecro len = ", hex(len(lfw_ecro) - LFW_SIZE)) - debug_print("CRC32(ecro-4) = ", hex(crc32_ecro)) - - # Reads entry point from offset 4 of file. - # This assumes binary has Cortex-M4 vector table at offset 0. - # 32-bit word at offset 0x0 initial stack pointer value - # 32-bit word at offset 0x4 address of reset handler - # NOTE: reset address will have bit[0]=1 to ensure thumb mode. - lfw_ecro_entry = GetEntryPoint(rorofile) - - # Chromebooks are not using MEC BootROM SPI header/payload authentication - # or payload encryption. In this case the header authentication signature - # is filled with the hash digest of the respective entity. - # BuildHeader2 computes the hash digest and stores it in the correct - # header location. - header = BuildHeader2(args, chip_dict, lfw_ecro_len, - LOAD_ADDR, lfw_ecro_entry) - printByteArrayAsHex(header, "Header(lfw_ecro)") - - # If payload encryption used then encrypt payload and - # generate Payload Key Header. If encryption not used - # payload is not modified and the method returns None - encryption_key_header = EncryptPayload(args, chip_dict, lfw_ecro) - printByteArrayAsHex(encryption_key_header, - "LFW + EC_RO encryption_key_header") - - ec_info_block = GenEcInfoBlock(args, chip_dict) - printByteArrayAsHex(ec_info_block, "EC Info Block") - - cosignature = GenCoSignature(args, chip_dict, lfw_ecro) - printByteArrayAsHex(cosignature, "LFW + EC_RO cosignature") - - trailer = GenTrailer(args, chip_dict, lfw_ecro, encryption_key_header, - ec_info_block, cosignature) - - printByteArrayAsHex(trailer, "LFW + EC_RO trailer") - - # Build TAG0. Set TAG1=TAG0 Boot-ROM is allowed to load EC-RO only. - tag0 = BuildTag(args) - tag1 = tag0 - - debug_print("Call to GetPayloadFromOffset") - debug_print("args.input = ", args.input) - debug_print("args.image_size = ", hex(args.image_size)) - - ecrw = GetPayloadFromOffset(args.input, args.image_size, - chip_dict["PAD_SIZE"]) - debug_print("type(ecrw) is ", type(ecrw)) - debug_print("len(ecrw) is ", hex(len(ecrw))) - - # truncate to args.image_size - ecrw_len = len(ecrw) - if ecrw_len > args.image_size: - debug_print("Truncate EC_RW len={0:0x} to image_size={1:0x}".format(ecrw_len,args.image_size)) - ecrw = ecrw[:args.image_size] - ecrw_len = len(ecrw) - - debug_print("len(EC_RW) = ", hex(ecrw_len)) - - # SPI test mode compute CRC32 of EC_RW and store in last 4 bytes - if args.test_spi: - crc32_ecrw = zlib.crc32(bytes(ecrw[0:-4])) - crc32_ecrw_bytes = crc32_ecrw.to_bytes(4, byteorder='little') - ecrw[-4:] = crc32_ecrw_bytes - debug_print("ecrw len = ", hex(len(ecrw))) - debug_print("CRC32(ecrw) = ", hex(crc32_ecrw)) - - # Assume FW layout is standard Cortex-M style with vector - # table at start of binary. - # 32-bit word at offset 0x0 = Initial stack pointer - # 32-bit word at offset 0x4 = Address of reset handler - ecrw_entry_tuple = struct.unpack_from('<I', ecrw, 4) - debug_print("ecrw_entry_tuple[0] = ", hex(ecrw_entry_tuple[0])) - - ecrw_entry = ecrw_entry_tuple[0] - debug_print("ecrw_entry = ", hex(ecrw_entry)) - - # Note: payload_rw is a bytearray therefore is mutable - if args.test_ecrw: - gen_test_ecrw(ecrw) - - os.remove(rorofile) # clean up the temp file - - # MEC152X Add TAG's - spi_list.append((args.tag0_loc, tag0, "tag0")) - spi_list.append((args.tag1_loc, tag1, "tag1")) - - # flashmap is non-zero only for systems with two external - # SPI flash chips. - flashmap = BuildFlashMap(0) - spi_list.append((8, flashmap, "flashmap")) - - # Boot-ROM SPI image header for LFW+EC-RO - spi_list.append((args.header_loc, header, "header(lfw + ro)")) - spi_list.append((args.header_loc + chip_dict["PAYLOAD_OFFSET"], lfw_ecro, - "lfw_ecro")) - - offset = args.header_loc + chip_dict["PAYLOAD_OFFSET"] + lfw_ecro_len - - if ec_info_block != None: - spi_list.append((offset, ec_info_block, "EC Info Block")) - offset += len(ec_info_block) - - if cosignature != None: - spi_list.append((offset, cosignature, "ECRO Cosignature")) - offset += len(cosignature) - - if trailer != None: - spi_list.append((offset, trailer, "ECRO Trailer")) - offset += len(trailer) - - # EC_RW location - rw_offset = int(spi_size // 2) - if args.rw_loc >= 0: - rw_offset = args.rw_loc - - debug_print("rw_offset = 0x{0:08x}".format(rw_offset)) - - assert rw_offset >= offset, \ - print("""Offset of EC_RW at {0:08x} overlaps end - of EC_RO at {0:08x}""".format(rw_offset, offset)) - - spi_list.append((rw_offset, ecrw, "ecrw")) - offset = rw_offset + len(ecrw) - - spi_list = sorted(spi_list) - - dumpsects(spi_list) - - # - # MEC152X Boot-ROM locates TAG0/1 at SPI offset 0 - # instead of end of SPI. - # - with open(args.output, 'wb') as f: - debug_print("Write spi list to file", args.output) - addr = 0 - for s in spi_list: - if addr < s[0]: - debug_print("Offset ",hex(addr)," Length", hex(s[0]-addr), - "fill with 0xff") - f.write(b'\xff' * (s[0] - addr)) - addr = s[0] - debug_print("Offset ",hex(addr), " Length", hex(len(s[1])), "write data") - - f.write(s[1]) - addr += len(s[1]) - - if addr < spi_size: - debug_print("Offset ",hex(addr), " Length", hex(spi_size - addr), - "fill with 0xff") - f.write(b'\xff' * (spi_size - addr)) - - f.flush() - -if __name__ == '__main__': - main() diff --git a/chip/mchp/util/pack_ec_mec172x.py b/chip/mchp/util/pack_ec_mec172x.py deleted file mode 100755 index 32747d3d9a..0000000000 --- a/chip/mchp/util/pack_ec_mec172x.py +++ /dev/null @@ -1,851 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Ignore indention messages, since legacy scripts use 2 spaces instead of 4. -# pylint: disable=bad-indentation,docstring-section-indent -# pylint: disable=docstring-trailing-quotes - -# A script to pack EC binary into SPI flash image for MEC172x -# Based on MEC172x_ROM_Description.pdf revision 6/8/2020 -import argparse -import hashlib -import os -import struct -import subprocess -import tempfile -import zlib # CRC32 - -# MEC172x has 416KB SRAM from 0xC0000 - 0x127FFF -# SRAM is divided into contiguous CODE & DATA -# CODE at [0xC0000, 0x117FFF] DATA at [0x118000, 0x127FFF] -# Google EC SPI flash size for board is currently 512KB -# split into 1/2. -# EC_RO: 0 - 0x3FFFF -# EC_RW: 0x40000 - 0x7FFFF -# -SPI_ERASE_BLOCK_SIZE = 0x1000 -SPI_CLOCK_LIST = [48, 24, 16, 12, 96] -SPI_READ_CMD_LIST = [0x3, 0xb, 0x3b, 0x6b] -SPI_DRIVE_STR_DICT = {2:0, 4:1, 8:2, 12:3} -# Maximum EC_RO/EC_RW code size is based upon SPI flash erase -# sector size, MEC172x Boot-ROM TAG, Header, Footer. -# SPI Offset Description -# 0x00 - 0x07 TAG0 and TAG1 -# 0x1000 - 0x113F Boot-ROM SPI Header -# 0x1140 - 0x213F 4KB LFW -# 0x2040 - 0x3EFFF -# 0x3F000 - 0x3FFFF BootROM EC_INFO_BLK || COSIG || ENCR_KEY_HDR(optional) || TRAILER -CHIP_MAX_CODE_SRAM_KB = (256 - 12) - -MEC172X_DICT = { - "LFW_SIZE": 0x1000, - "LOAD_ADDR": 0xC0000, - "TAG_SIZE": 4, - "KEY_BLOB_SIZE": 1584, - "HEADER_SIZE":0x140, - "HEADER_VER":0x03, - "PAYLOAD_GRANULARITY":128, - "PAYLOAD_PAD_BYTE":b'\xff', - "EC_INFO_BLK_SZ":128, - "ENCR_KEY_HDR_SZ":128, - "COSIG_SZ":96, - "TRAILER_SZ":160, - "TAILER_PAD_BYTE":b'\xff', - "PAD_SIZE":128 - } - -CRC_TABLE = [0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, - 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d] - -def mock_print(*args, **kwargs): - pass - -debug_print = mock_print - -# Debug helper routine -def dumpsects(spi_list): - debug_print("spi_list has {0} entries".format(len(spi_list))) - for s in spi_list: - debug_print("0x{0:x} 0x{1:x} {2:s}".format(s[0],len(s[1]),s[2])) - -def printByteArrayAsHex(ba, title): - debug_print(title,"= ") - if ba == None: - debug_print("None") - return - - count = 0 - for b in ba: - count = count + 1 - debug_print("0x{0:02x}, ".format(b),end="") - if (count % 8) == 0: - debug_print("") - debug_print("") - -def Crc8(crc, data): - """Update CRC8 value.""" - for v in data: - crc = ((crc << 4) & 0xff) ^ (CRC_TABLE[(crc >> 4) ^ (v >> 4)]); - crc = ((crc << 4) & 0xff) ^ (CRC_TABLE[(crc >> 4) ^ (v & 0xf)]); - return crc ^ 0x55 - -def GetEntryPoint(payload_file): - """Read entry point from payload EC image.""" - with open(payload_file, 'rb') as f: - f.seek(4) - s = f.read(4) - return int.from_bytes(s, byteorder='little') - -def GetPayloadFromOffset(payload_file, offset, padsize): - """Read payload and pad it to padsize.""" - with open(payload_file, 'rb') as f: - f.seek(offset) - payload = bytearray(f.read()) - rem_len = len(payload) % padsize - debug_print("GetPayload: padsize={0:0x} len(payload)={1:0x} rem={2:0x}".format(padsize,len(payload),rem_len)) - - if rem_len: - payload += PAYLOAD_PAD_BYTE * (padsize - rem_len) - debug_print("GetPayload: Added {0} padding bytes".format(padsize - rem_len)) - - return payload - -def GetPayload(payload_file, padsize): - """Read payload and pad it to padsize""" - return GetPayloadFromOffset(payload_file, 0, padsize) - -def GetPublicKey(pem_file): - """Extract public exponent and modulus from PEM file.""" - result = subprocess.run(['openssl', 'rsa', '-in', pem_file, '-text', - '-noout'], stdout=subprocess.PIPE, encoding='utf-8') - modulus_raw = [] - in_modulus = False - for line in result.stdout.splitlines(): - if line.startswith('modulus'): - in_modulus = True - elif not line.startswith(' '): - in_modulus = False - elif in_modulus: - modulus_raw.extend(line.strip().strip(':').split(':')) - if line.startswith('publicExponent'): - exp = int(line.split(' ')[1], 10) - modulus_raw.reverse() - modulus = bytearray((int(x, 16) for x in modulus_raw[:256])) - return struct.pack('<Q', exp), modulus - -def GetSpiClockParameter(args): - assert args.spi_clock in SPI_CLOCK_LIST, \ - "Unsupported SPI clock speed %d MHz" % args.spi_clock - return SPI_CLOCK_LIST.index(args.spi_clock) - -def GetSpiReadCmdParameter(args): - assert args.spi_read_cmd in SPI_READ_CMD_LIST, \ - "Unsupported SPI read command 0x%x" % args.spi_read_cmd - return SPI_READ_CMD_LIST.index(args.spi_read_cmd) - -def GetEncodedSpiDriveStrength(args): - assert args.spi_drive_str in SPI_DRIVE_STR_DICT, \ - "Unsupported SPI drive strength %d mA" % args.spi_drive_str - return SPI_DRIVE_STR_DICT.get(args.spi_drive_str) - -# Return 0=Slow slew rate or 1=Fast slew rate -def GetSpiSlewRate(args): - if args.spi_slew_fast == True: - return 1 - return 0 - -# Return SPI CPOL = 0 or 1 -def GetSpiCpol(args): - if args.spi_cpol == 0: - return 0 - return 1 - -# Return SPI CPHA_MOSI -# 0 = SPI Master drives data is stable on inactive to clock edge -# 1 = SPI Master drives data is stable on active to inactive clock edge -def GetSpiCphaMosi(args): - if args.spi_cpha_mosi == 0: - return 0 - return 1 - -# Return SPI CPHA_MISO 0 or 1 -# 0 = SPI Master samples data on inactive to active clock edge -# 1 = SPI Master samples data on active to inactive clock edge -def GetSpiCphaMiso(args): - if args.spi_cpha_miso == 0: - return 0 - return 1 - -def PadZeroTo(data, size): - data.extend(b'\0' * (size - len(data))) - -# -# Boot-ROM SPI image encryption not used with Chromebooks -# -def EncryptPayload(args, chip_dict, payload): - return None - -# -# Build SPI image header for MEC172x -# MEC172x image header size = 320(0x140) bytes -# -# Description using Python slice notation [start:start+len] -# -# header[0:4] = 'PHCM' -# header[4] = header version = 0x03(MEC172x) -# header[5] = SPI clock speed, drive strength, sampling mode -# bits[1:0] = SPI clock speed: 0=48, 1=24, 2=16, 3=12 -# bits[3:2] = SPI controller pins drive strength -# 00b=2mA, 01b=4mA, 10b=8mA, 11b=12mA -# bit[4] = SPI controller pins slew rate: 0=slow, 1=fast -# bit[5] = SPI CPOL: 0=SPI clock idle is low, 1=idle is high -# bit[6] = CHPHA_MOSI -# 1:data change on first inactive to active clock edge -# 0:data change on first active to inactive clock edge -# bit[7] = CHPHA_MISO: -# 1: Data captured on first inactive to active clock edge -# 0: Data captured on first active to inactive clock edge -# header[6] Boot-ROM loader flags -# bits[0] = 0(use header[5] b[1:0]), 1(96 MHz) -# bits[2:1] = 0 reserved -# bits[5:3] = 111b -# bit[6]: For MEC172x controls authentication -# 0=Authentication disabled. Signature is SHA-384 of FW payload -# 1=Authentication enabled. Signature is ECDSA P-384 -# bit[7]: 0=FW pyload not encrypted, 1=FW payload is encrypted -# header[7]: SPI Flash read command -# 0 -> 0x03 1-1-1 read freq < 33MHz -# 1 -> 0x0B 1-1-1 + 8 clocks(data tri-stated) -# 2 -> 0x3B 1-1-2 + 8 clocks(data tri-stated). Data phase is dual I/O -# 3 -> 0x6B 1-1-4 + 8 clocks(data tri-stated). Data phase is Quad I/O -# NOTE: Quad requires SPI flash device QE(quad enable) bit -# to be factory set. Enabling QE disables HOLD# and WP# -# functionality of the SPI flash device. -# header[0x8:0xC] SRAM Load address little-endian format -# header[0xC:0x10] SRAM FW entry point. Boot-ROM jumps to -# this address on successful load. (little-endian) -# header[0x10:0x12] little-endian format: FW binary size in units of -# 128 bytes(MEC172x) -# header[0x12:0x14] = 0 reserved -# header[0x14:0x18] = Little-ending format: Unsigned offset from start of -# header to FW payload. -# MEC172x: Offset must be a multiple of 128 -# Offset must be >= header size. -# NOTE: If Authentication is enabled size includes -# the appended signature. -# MEC172x: -# header[0x18] = Authentication key select. Set to 0 for no Authentication. -# header[0x19] = SPI flash device(s) drive strength feature flags -# b[0]=1 SPI flash device 0 has drive strength feature -# b[1]=SPI flash 0: DrvStr Write format(0=2 bytes, 1=1 byte) -# b[2]=1 SPI flash device 1 has drive strength feature -# b[3]=SPI flash 1: DrvStr Write format(0=2 bytes, 1=1 byte) -# b[7:4] = 0 reserved -# header[0x1A:0x20] = 0 reserved -# header[0x20] = SPI opcode to read drive strength from SPI flash 0 -# header[0x21] = SPI opcode to write drive strength to SPI flash 0 -# header[0x22] = SPI flash 0: drvStr value -# header[0x23] = SPI flash 0: drvStr mask -# header[0x24] = SPI opcode to read drive strength from SPI flash 1 -# header[0x25] = SPI opcode to write drive strength to SPI flash 1 -# header[0x26] = SPI flash 1: drvStr value -# header[0x27] = SPI flash 1: drvStr mask -# header[0x28:0x48] = reserved, may be any value -# header[0x48:0x50] = reserved for customer use -# header[0x50:0x80] = ECDSA-384 public key x-coord. = 0 Auth. disabled -# header[0x80:0xB0] = ECDSA-384 public key y-coord. = 0 Auth. disabled -# header[0xB0:0xE0] = SHA-384 digest of header[0:0xB0] -# header[0xE0:0x110] = Header ECDSA-384 signature x-coord. = 0 Auth. disabled -# header[0x110:0x140] = Header ECDSA-384 signature y-coor. = 0 Auth. disabled -# -def BuildHeader2(args, chip_dict, payload_len, load_addr, payload_entry): - header_size = chip_dict["HEADER_SIZE"] - - # allocate zero filled header - header = bytearray(b'\x00' * header_size) - debug_print("len(header) = ", len(header)) - - # Identifier and header version - header[0:4] = b'PHCM' - header[4] = chip_dict["HEADER_VER"] - - # SPI frequency, drive strength, CPOL/CPHA encoding same for both chips - spiFreqIndex = GetSpiClockParameter(args) - if spiFreqIndex > 3: - header[6] |= 0x01 - else: - header[5] = spiFreqIndex - - header[5] |= ((GetEncodedSpiDriveStrength(args) & 0x03) << 2) - header[5] |= ((GetSpiSlewRate(args) & 0x01) << 4) - header[5] |= ((GetSpiCpol(args) & 0x01) << 5) - header[5] |= ((GetSpiCphaMosi(args) & 0x01) << 6) - header[5] |= ((GetSpiCphaMiso(args) & 0x01) << 7) - - # header[6] - # b[0] value set above - # b[2:1] = 00b, b[5:3]=111b - # b[7]=0 No encryption of FW payload - header[6] |= 0x7 << 3 - - # SPI read command set same for both chips - header[7] = GetSpiReadCmdParameter(args) & 0xFF - - # bytes 0x08 - 0x0b - header[0x08:0x0C] = load_addr.to_bytes(4, byteorder='little') - # bytes 0x0c - 0x0f - header[0x0C:0x10] = payload_entry.to_bytes(4, byteorder='little') - - # bytes 0x10 - 0x11 payload length in units of 128 bytes - assert payload_len % chip_dict["PAYLOAD_GRANULARITY"] == 0, \ - print("Payload size not a multiple of {0}".format(chip_dict["PAYLOAD_GRANULARITY"])) - - payload_units = int(payload_len // chip_dict["PAYLOAD_GRANULARITY"]) - assert payload_units < 0x10000, \ - print("Payload too large: len={0} units={1}".format(payload_len, payload_units)) - - header[0x10:0x12] = payload_units.to_bytes(2, 'little') - - # bytes 0x14 - 0x17 TODO offset from start of payload to FW payload to be - # loaded by Boot-ROM. We ask Boot-ROM to load (LFW || EC_RO). - # LFW location provided on the command line. - assert (args.lfw_loc % 4096 == 0), \ - print("LFW location not on a 4KB boundary! 0x{0:0x}".format(args.lfw_loc)) - - assert args.lfw_loc >= (args.header_loc + chip_dict["HEADER_SIZE"]), \ - print("LFW location not greater than header location + header size") - - lfw_ofs = args.lfw_loc - args.header_loc - header[0x14:0x18] = lfw_ofs.to_bytes(4, 'little') - - # MEC172x: authentication key select. Authentication not used, set to 0. - header[0x18] = 0 - - # header[0x19], header[0x20:0x28] - # header[0x1A:0x20] reserved 0 - # MEC172x: supports SPI flash devices with drive strength settings - # TODO leave these fields at 0 for now. We must add 6 command line - # arguments. - - # header[0x28:0x48] reserve can be any value - # header[0x48:0x50] Customer use. TODO - # authentication disabled, leave these 0. - # header[0x50:0x80] ECDSA P384 Authentication Public key Rx - # header[0x80:0xB0] ECDSA P384 Authentication Public key Ry - - # header[0xB0:0xE0] = SHA384(header[0:0xB0]) - header[0xB0:0xE0] = hashlib.sha384(header[0:0xB0]).digest() - # When ECDSA authentication is disabled MCHP SPI image generator - # is filling the last 48 bytes of the Header with 0xff - header[-48:] = b'\xff' * 48 - - debug_print("After hash: len(header) = ", len(header)) - - return header - -# -# MEC172x 128-byte EC Info Block appended to end of padded FW binary. -# Python slice notation -# byte[0:0x64] are undefined, we set to 0xFF -# byte[0x64] = FW Build LSB -# byte[0x65] = FW Build MSB -# byte[0x66:0x68] = undefined, set to 0xFF -# byte[0x68:0x78] = Roll back permissions bit maps -# byte[0x78:0x7c] = key revocation bit maps -# byte[0x7c] = platform ID LSB -# byte[0x7d] = platform ID MSB -# byte[0x7e] = auto-rollback protection enable -# byte[0x7f] = current imeage revision -# -def GenEcInfoBlock(args, chip_dict): - # ecinfo = bytearray([0xff] * chip_dict["EC_INFO_BLK_SZ"]) - ecinfo = bytearray(chip_dict["EC_INFO_BLK_SZ"]) - return ecinfo - -# -# Generate SPI FW image co-signature. -# MEC172x cosignature is 96 bytes used by OEM FW -# developer to sign their binary with ECDSA-P384-SHA384 or -# some other signature algorithm that fits in 96 bytes. -# At this time Cros-EC is not using this field, fill with 0xFF. -# If this feature is implemented we need to read the OEM's -# generated signature from a file and extract the binary -# signature. -# -def GenCoSignature(args, chip_dict, payload): - return bytearray(b'\xff' * chip_dict["COSIG_SZ"]) - -# -# Generate SPI FW Image trailer. -# MEC172x: Size = 160 bytes -# binary = payload || encryption_key_header || ec_info_block || cosignature -# trailer[0:48] = SHA384(binary) -# trailer[48:144] = 0xFF -# trailer[144:160] = 0xFF. Boot-ROM spec. says these bytes should be random. -# Authentication & encryption are not used therefore random data -# is not necessary. -def GenTrailer(args, chip_dict, payload, encryption_key_header, - ec_info_block, cosignature): - debug_print("GenTrailer SHA384 computation") - trailer = bytearray(chip_dict["TAILER_PAD_BYTE"] * chip_dict["TRAILER_SZ"]) - hasher = hashlib.sha384() - hasher.update(payload) - debug_print(" Update: payload len=0x{0:0x}".format(len(payload))) - if ec_info_block != None: - hasher.update(ec_info_block) - debug_print(" Update: ec_info_block len=0x{0:0x}".format(len(ec_info_block))) - if encryption_key_header != None: - hasher.update(encryption_key_header) - debug_print(" Update: encryption_key_header len=0x{0:0x}".format(len(encryption_key_header))) - if cosignature != None: - hasher.update(cosignature) - debug_print(" Update: cosignature len=0x{0:0x}".format(len(cosignature))) - trailer[0:48] = hasher.digest() - trailer[-16:] = 16 * b'\xff' - - return trailer - -# MEC172x supports two 32-bit Tags located at offsets 0x0 and 0x4 -# in the SPI flash. -# Tag format: -# bits[23:0] correspond to bits[31:8] of the Header SPI address -# Header is always on a 256-byte boundary. -# bits[31:24] = CRC8-ITU of bits[23:0]. -# Notice there is no chip-select field in the Tag both Tag's point -# to the same flash part. -# -def BuildTag(args): - tag = bytearray([(args.header_loc >> 8) & 0xff, - (args.header_loc >> 16) & 0xff, - (args.header_loc >> 24) & 0xff]) - tag.append(Crc8(0, tag)) - return tag - -def BuildTagFromHdrAddr(header_loc): - tag = bytearray([(header_loc >> 8) & 0xff, - (header_loc >> 16) & 0xff, - (header_loc >> 24) & 0xff]) - tag.append(Crc8(0, tag)) - return tag - - -# FlashMap is an option for MEC172x -# It is a 32 bit structure -# bits[18:0] = bits[30:12] of second SPI flash base address -# bits[23:19] = 0 reserved -# bits[31:24] = CRC8 of bits[23:0] -# Input: -# integer containing base address of second SPI flash -# This value is usually equal to the size of the first -# SPI flash and should be a multiple of 4KB -# Output: -# bytearray of length 4 -def BuildFlashMap(secondSpiFlashBaseAddr): - flashmap = bytearray(4) - flashmap[0] = (secondSpiFlashBaseAddr >> 12) & 0xff - flashmap[1] = (secondSpiFlashBaseAddr >> 20) & 0xff - flashmap[2] = (secondSpiFlashBaseAddr >> 28) & 0xff - flashmap[3] = Crc8(0, flashmap) - return flashmap - -# -# Creates temporary file for read/write -# Reads binary file containing LFW image_size (loader_file) -# Writes LFW image to temporary file -# Reads RO image at beginning of rorw_file up to image_size -# (assumes RO/RW images have been padded with 0xFF -# Returns temporary file name -# -def PacklfwRoImage(rorw_file, loader_file, image_size): - """Create a temp file with the - first image_size bytes from the loader file and append bytes - from the rorw file. - return the filename""" - fo=tempfile.NamedTemporaryFile(delete=False) # Need to keep file around - with open(loader_file,'rb') as fin1: # read 4KB loader file - pro = fin1.read() - fo.write(pro) # write 4KB loader data to temp file - with open(rorw_file, 'rb') as fin: - ro = fin.read(image_size) - - fo.write(ro) - fo.close() - - return fo.name - -# -# Generate a test EC_RW image of same size -# as original. -# Preserve image_data structure and fill all -# other bytes with 0xA5. -# useful for testing SPI read and EC build -# process hash generation. -# -def gen_test_ecrw(pldrw): - debug_print("gen_test_ecrw: pldrw type =", type(pldrw)) - debug_print("len pldrw =", len(pldrw), " = ", hex(len(pldrw))) - cookie1_pos = pldrw.find(b'\x99\x88\x77\xce') - cookie2_pos = pldrw.find(b'\xdd\xbb\xaa\xce', cookie1_pos+4) - t = struct.unpack("<L", pldrw[cookie1_pos+0x24:cookie1_pos+0x28]) - size = t[0] - debug_print("EC_RW size =", size, " = ", hex(size)) - - debug_print("Found cookie1 at ", hex(cookie1_pos)) - debug_print("Found cookie2 at ", hex(cookie2_pos)) - - if cookie1_pos > 0 and cookie2_pos > cookie1_pos: - for i in range(0, cookie1_pos): - pldrw[i] = 0xA5 - for i in range(cookie2_pos+4, len(pldrw)): - pldrw[i] = 0xA5 - - with open("ec_RW_test.bin", "wb") as fecrw: - fecrw.write(pldrw[:size]) - -def parseargs(): - rpath = os.path.dirname(os.path.relpath(__file__)) - - parser = argparse.ArgumentParser() - parser.add_argument("-i", "--input", - help="EC binary to pack, usually ec.bin or ec.RO.flat.", - metavar="EC_BIN", default="ec.bin") - parser.add_argument("-o", "--output", - help="Output flash binary file", - metavar="EC_SPI_FLASH", default="ec.packed.bin") - parser.add_argument("--loader_file", - help="EC loader binary", - default="ecloader.bin") - parser.add_argument("--load_addr", type=int, - help="EC SRAM load address", - default=0xC0000) - parser.add_argument("-s", "--spi_size", type=int, - help="Size of the SPI flash in KB", - default=512) - parser.add_argument("-l", "--header_loc", type=int, - help="Location of header in SPI flash. Must be on a 256 byte boundary", - default=0x0100) - parser.add_argument("--lfw_loc", type=int, - help="Location of LFW in SPI flash. Must be on a 4KB boundary", - default=0x1000) - parser.add_argument("--lfw_size", type=int, - help="LFW size in bytes", - default=0x1000) - parser.add_argument("-r", "--rw_loc", type=int, - help="Start offset of EC_RW. Default is -1 meaning 1/2 flash size", - default=-1) - parser.add_argument("--spi_clock", type=int, - help="SPI clock speed. 8, 12, 24, or 48 MHz.", - default=24) - parser.add_argument("--spi_read_cmd", type=int, - help="SPI read command. 0x3, 0xB, 0x3B, or 0x6B.", - default=0xb) - parser.add_argument("--image_size", type=int, - help="Size of a single image. Default 244KB", - default=(244 * 1024)) - parser.add_argument("--test_spi", action='store_true', - help="Test SPI data integrity by adding CRC32 in last 4-bytes of RO/RW binaries", - default=False) - parser.add_argument("--test_ecrw", action='store_true', - help="Use fixed pattern for EC_RW but preserve image_data", - default=False) - parser.add_argument("--verbose", action='store_true', - help="Enable verbose output", - default=False) - parser.add_argument("--tag0_loc", type=int, - help="MEC172x TAG0 SPI offset", - default=0) - parser.add_argument("--tag1_loc", type=int, - help="MEC172x TAG1 SPI offset", - default=4) - parser.add_argument("--spi_drive_str", type=int, - help="Chip SPI drive strength in mA: 2, 4, 8, or 12", - default=4) - parser.add_argument("--spi_slew_fast", action='store_true', - help="SPI use fast slew rate. Default is False", - default=False) - parser.add_argument("--spi_cpol", type=int, - help="SPI clock polarity when idle. Defealt is 0(low)", - default=0) - parser.add_argument("--spi_cpha_mosi", type=int, - help="""SPI clock phase controller drives data. - 0=Data driven on active to inactive clock edge, - 1=Data driven on inactive to active clock edge""", - default=0) - parser.add_argument("--spi_cpha_miso", type=int, - help="""SPI clock phase controller samples data. - 0=Data sampled on inactive to active clock edge, - 1=Data sampled on active to inactive clock edge""", - default=0) - - return parser.parse_args() - -def print_args(args): - debug_print("parsed arguments:") - debug_print(".input = ", args.input) - debug_print(".output = ", args.output) - debug_print(".loader_file = ", args.loader_file) - debug_print(".spi_size (KB) = ", hex(args.spi_size)) - debug_print(".image_size = ", hex(args.image_size)) - debug_print(".load_addr", hex(args.load_addr)) - debug_print(".tag0_loc = ", hex(args.tag0_loc)) - debug_print(".tag1_loc = ", hex(args.tag1_loc)) - debug_print(".header_loc = ", hex(args.header_loc)) - debug_print(".lfw_loc = ", hex(args.lfw_loc)) - debug_print(".lfw_size = ", hex(args.lfw_size)) - if args.rw_loc < 0: - debug_print(".rw_loc = ", args.rw_loc) - else: - debug_print(".rw_loc = ", hex(args.rw_loc)) - debug_print(".spi_clock (MHz) = ", args.spi_clock) - debug_print(".spi_read_cmd = ", hex(args.spi_read_cmd)) - debug_print(".test_spi = ", args.test_spi) - debug_print(".test_ecrw = ", args.test_ecrw) - debug_print(".verbose = ", args.verbose) - debug_print(".spi_drive_str = ", args.spi_drive_str) - debug_print(".spi_slew_fast = ", args.spi_slew_fast) - debug_print(".spi_cpol = ", args.spi_cpol) - debug_print(".spi_cpha_mosi = ", args.spi_cpha_mosi) - debug_print(".spi_cpha_miso = ", args.spi_cpha_miso) - -def spi_list_append(mylist, loc, data, description): - """Append SPI data block tuple to list""" - t = (loc, data, description) - mylist.append(t) - debug_print("Add SPI entry: offset=0x{0:08x} len=0x{1:0x} descr={2}".format(loc, len(data), description)) - -# -# Handle quiet mode build from Makefile -# Quiet mode when V is unset or V=0 -# Verbose mode when V=1 -# -# MEC172x SPI Image Generator -# No authentication -# No payload encryption -# -# SPI Offset 0x0 = TAG0 points to Header for EC-RO FW -# SPI Offset 0x4 = TAG1 points to Header for EC-RO FW -# TAG Size = 4 bytes -# bits[23:0] = bits[31:8] of Header SPI offset -# bits[31:24] = CRC8-ITU checksum of bits[23:0]. -# -# MEC172x SPI header and payload layout for minimum size -# header offset aligned on 256 byte boundary -# header_spi_address: -# header[0:0x4F] = Header data -# header[0x50:0x80] = ECDSA-P384 public key x for Header authentication -# header[0x80:0xB0] = ECDSA-P384 public key y for Header authentication -# header[0xB0:0xE0] = SHA384 digest of header[0:0xB0] -# header[0xE0:0x110] = ECDSA-P384-SHA384 Signature.R of header[0:0xB0] -# header[0x110:0x140] = ECDSA-P384-SHA384 Signature.S of header[0:0xB0] -# payload_spi_address = header_spi_address + len(Header) -# Payload had been padded such that len(padded_payload) % 128 == 0 -# padded_payload[padded_payload_len] -# payload_signature_address = payload_spi_address + len(padded_payload) -# payload_encryption_key_header[128] Not present if encryption disabled -# payload_cosignature[96] = 0 if Authentication is disabled -# payload_trailer[160] = SHA384(padded_payload || -# optional payload_encryption_key_header) -# || 48 * [0] -# || 48 * [0] -# -def main(): - global debug_print - - args = parseargs() - - if args.verbose: - debug_print = print - - debug_print("Begin pack_ec_mec172x.py script") - - print_args(args) - - chip_dict = MEC172X_DICT - - # Boot-ROM requires header location aligned >= 256 bytes. - # CrOS EC flash image update code requires EC_RO/RW location to be aligned - # on a flash erase size boundary and EC_RO/RW size to be a multiple of - # the smallest flash erase block size. - - spi_size = args.spi_size * 1024 - spi_image_size = spi_size // 2 - - rorofile=PacklfwRoImage(args.input, args.loader_file, args.image_size) - debug_print("Temporary file containing LFW + EC_RO is ", rorofile) - - lfw_ecro = GetPayload(rorofile, chip_dict["PAD_SIZE"]) - lfw_ecro_len = len(lfw_ecro) - debug_print("Padded LFW + EC_RO length = ", hex(lfw_ecro_len)) - - # SPI test mode compute CRC32 of EC_RO and store in last 4 bytes - if args.test_spi: - crc32_ecro = zlib.crc32(bytes(lfw_ecro[LFW_SIZE:-4])) - crc32_ecro_bytes = crc32_ecro.to_bytes(4, byteorder='little') - lfw_ecro[-4:] = crc32_ecro_bytes - debug_print("ecro len = ", hex(len(lfw_ecro) - LFW_SIZE)) - debug_print("CRC32(ecro-4) = ", hex(crc32_ecro)) - - # Reads entry point from offset 4 of file. - # This assumes binary has Cortex-M4 vector table at offset 0. - # 32-bit word at offset 0x0 initial stack pointer value - # 32-bit word at offset 0x4 address of reset handler - # NOTE: reset address will have bit[0]=1 to ensure thumb mode. - lfw_ecro_entry = GetEntryPoint(rorofile) - debug_print("LFW Entry point from GetEntryPoint = 0x{0:08x}".format(lfw_ecro_entry)) - - # Chromebooks are not using MEC BootROM SPI header/payload authentication - # or payload encryption. In this case the header authentication signature - # is filled with the hash digest of the respective entity. - # BuildHeader2 computes the hash digest and stores it in the correct - # header location. - header = BuildHeader2(args, chip_dict, lfw_ecro_len, - args.load_addr, lfw_ecro_entry) - printByteArrayAsHex(header, "Header(lfw_ecro)") - - # If payload encryption used then encrypt payload and - # generate Payload Key Header. If encryption not used - # payload is not modified and the method returns None - encryption_key_header = EncryptPayload(args, chip_dict, lfw_ecro) - printByteArrayAsHex(encryption_key_header, - "LFW + EC_RO encryption_key_header") - - ec_info_block = GenEcInfoBlock(args, chip_dict) - printByteArrayAsHex(ec_info_block, "EC Info Block") - - cosignature = GenCoSignature(args, chip_dict, lfw_ecro) - printByteArrayAsHex(cosignature, "LFW + EC_RO cosignature") - - trailer = GenTrailer(args, chip_dict, lfw_ecro, encryption_key_header, - ec_info_block, cosignature) - - printByteArrayAsHex(trailer, "LFW + EC_RO trailer") - - # Build TAG0. Set TAG1=TAG0 Boot-ROM is allowed to load EC-RO only. - tag0 = BuildTag(args) - tag1 = tag0 - - debug_print("Call to GetPayloadFromOffset") - debug_print("args.input = ", args.input) - debug_print("args.image_size = ", hex(args.image_size)) - - ecrw = GetPayloadFromOffset(args.input, args.image_size, - chip_dict["PAD_SIZE"]) - debug_print("type(ecrw) is ", type(ecrw)) - debug_print("len(ecrw) is ", hex(len(ecrw))) - - # truncate to args.image_size - ecrw_len = len(ecrw) - if ecrw_len > args.image_size: - debug_print("Truncate EC_RW len={0:0x} to image_size={1:0x}".format(ecrw_len,args.image_size)) - ecrw = ecrw[:args.image_size] - ecrw_len = len(ecrw) - - debug_print("len(EC_RW) = ", hex(ecrw_len)) - - # SPI test mode compute CRC32 of EC_RW and store in last 4 bytes - if args.test_spi: - crc32_ecrw = zlib.crc32(bytes(ecrw[0:-4])) - crc32_ecrw_bytes = crc32_ecrw.to_bytes(4, byteorder='little') - ecrw[-4:] = crc32_ecrw_bytes - debug_print("ecrw len = ", hex(len(ecrw))) - debug_print("CRC32(ecrw) = ", hex(crc32_ecrw)) - - # Assume FW layout is standard Cortex-M style with vector - # table at start of binary. - # 32-bit word at offset 0x0 = Initial stack pointer - # 32-bit word at offset 0x4 = Address of reset handler - ecrw_entry_tuple = struct.unpack_from('<I', ecrw, 4) - debug_print("ecrw_entry_tuple[0] = ", hex(ecrw_entry_tuple[0])) - - ecrw_entry = ecrw_entry_tuple[0] - debug_print("ecrw_entry = ", hex(ecrw_entry)) - - # Note: payload_rw is a bytearray therefore is mutable - if args.test_ecrw: - gen_test_ecrw(ecrw) - - os.remove(rorofile) # clean up the temp file - - spi_list = [] - - # MEC172x Add TAG's - #spi_list.append((args.tag0_loc, tag0, "tag0")) - #spi_list.append((args.tag1_loc, tag1, "tag1")) - spi_list_append(spi_list, args.tag0_loc, tag0, "TAG0") - spi_list_append(spi_list, args.tag1_loc, tag1, "TAG1") - - # Boot-ROM SPI image header for LFW+EC-RO - #spi_list.append((args.header_loc, header, "header(lfw + ro)")) - spi_list_append(spi_list, args.header_loc, header, "LFW-EC_RO Header") - - spi_list_append(spi_list, args.lfw_loc, lfw_ecro, "LFW-EC_RO FW") - - offset = args.lfw_loc + len(lfw_ecro) - debug_print("SPI offset after LFW_ECRO = 0x{0:08x}".format(offset)) - - if ec_info_block != None: - spi_list_append(spi_list, offset, ec_info_block, "LFW-EC_RO Info Block") - offset += len(ec_info_block) - - debug_print("SPI offset after ec_info_block = 0x{0:08x}".format(offset)) - - if cosignature != None: - #spi_list.append((offset, co-signature, "ECRO Co-signature")) - spi_list_append(spi_list, offset, cosignature, "LFW-EC_RO Co-signature") - offset += len(cosignature) - - debug_print("SPI offset after co-signature = 0x{0:08x}".format(offset)) - - if trailer != None: - #spi_list.append((offset, trailer, "ECRO Trailer")) - spi_list_append(spi_list, offset, trailer, "LFW-EC_RO trailer") - offset += len(trailer) - - debug_print("SPI offset after trailer = 0x{0:08x}".format(offset)) - - # EC_RW location - rw_offset = int(spi_size // 2) - if args.rw_loc >= 0: - rw_offset = args.rw_loc - - debug_print("rw_offset = 0x{0:08x}".format(rw_offset)) - - #spi_list.append((rw_offset, ecrw, "ecrw")) - spi_list_append(spi_list, rw_offset, ecrw, "EC_RW") - offset = rw_offset + len(ecrw) - - spi_list = sorted(spi_list) - - debug_print("Display spi_list:") - dumpsects(spi_list) - - # - # MEC172x Boot-ROM locates TAG0/1 at SPI offset 0 - # instead of end of SPI. - # - with open(args.output, 'wb') as f: - debug_print("Write spi list to file", args.output) - addr = 0 - for s in spi_list: - if addr < s[0]: - debug_print("Offset ",hex(addr)," Length", hex(s[0]-addr), - "fill with 0xff") - f.write(b'\xff' * (s[0] - addr)) - addr = s[0] - debug_print("Offset ",hex(addr), " Length", hex(len(s[1])), "write data") - - f.write(s[1]) - addr += len(s[1]) - - if addr < spi_size: - debug_print("Offset ",hex(addr), " Length", hex(spi_size - addr), - "fill with 0xff") - f.write(b'\xff' * (spi_size - addr)) - - f.flush() - -if __name__ == '__main__': - main() diff --git a/chip/mchp/watchdog.c b/chip/mchp/watchdog.c deleted file mode 100644 index b8f986f5cd..0000000000 --- a/chip/mchp/watchdog.c +++ /dev/null @@ -1,212 +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. - */ - -/* Watchdog driver */ - -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "watchdog.h" -#include "tfdp_chip.h" - -void watchdog_reload(void) -{ - MCHP_WDG_KICK = 1; - - if (IS_ENABLED(CONFIG_WATCHDOG_HELP)) { - /* Reload the auxiliary timer */ - MCHP_TMR16_CTL(0) &= ~BIT(5); - MCHP_TMR16_CNT(0) = CONFIG_AUX_TIMER_PERIOD_MS; - MCHP_TMR16_CTL(0) |= BIT(5); - } -} -DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); - -#if defined(CHIP_FAMILY_MEC152X) || defined(CHIP_FAMILY_MEC172X) -static void wdg_intr_enable(int enable) -{ - if (enable) { - MCHP_WDG_STATUS = MCHP_WDG_STS_IRQ; - MCHP_WDG_IEN = MCHP_WDG_IEN_IRQ_EN; - MCHP_WDG_CTL |= MCHP_WDG_RESET_IRQ_EN; - MCHP_INT_ENABLE(MCHP_WDG_GIRQ) = MCHP_WDG_GIRQ_BIT; - task_enable_irq(MCHP_IRQ_WDG); - } else { - MCHP_WDG_IEN = 0U; - MCHP_WDG_CTL &= ~(MCHP_WDG_RESET_IRQ_EN); - MCHP_INT_DISABLE(MCHP_WDG_GIRQ) = MCHP_WDG_GIRQ_BIT; - task_disable_irq(MCHP_IRQ_WDG); - } -} -#else -static void wdg_intr_enable(int enable) -{ - (void) enable; -} -#endif - - -/* - * MEC1701 WDG asserts chip reset on LOAD count expiration. - * WDG interrupt is simulated using a 16-bit general purpose - * timer whose period is sufficiently less that the WDG timeout - * period allowing watchdog trace data to be saved. - * - * MEC152x adds interrupt capability to the WDT. - * Enable MEC152x WDG interrupt. WDG event will assert - * IRQ and kick itself starting another LOAD timeout. - * After the new LOAD expires WDG will assert chip reset. - * The WDG ISR calls watchdog trace save API, upon return we - * enter a spin loop waiting for the LOAD period to expire. - * WDG does not have a way to trigger an immediate reset except - * by re-programming it. - */ -int watchdog_init(void) -{ - if (IS_ENABLED(CONFIG_WATCHDOG_HELP)) { - /* - * MEC170x Watchdog does not warn us before expiring. - * Let's use a 16-bit timer as an auxiliary timer. - */ - - /* Clear 16-bit basic timer 0 PCR sleep enable */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_BTMR16_0); - - /* Stop the auxiliary timer if it's running */ - MCHP_TMR16_CTL(0) &= ~BIT(5); - - /* Enable auxiliary timer */ - MCHP_TMR16_CTL(0) |= BIT(0); - - /* Prescaler = 48000 -> 1kHz -> Period = 1 ms */ - MCHP_TMR16_CTL(0) = (MCHP_TMR16_CTL(0) & 0xffffU) - | (47999 << 16); - - /* No auto restart */ - MCHP_TMR16_CTL(0) &= ~BIT(3); - - /* Count down */ - MCHP_TMR16_CTL(0) &= ~BIT(2); - - /* Enable interrupt from auxiliary timer */ - MCHP_TMR16_IEN(0) |= BIT(0); - task_enable_irq(MCHP_IRQ_TIMER16_0); - MCHP_INT_ENABLE(MCHP_TMR16_GIRQ) = MCHP_TMR16_GIRQ_BIT(0); - - /* Load and start the auxiliary timer */ - MCHP_TMR16_CNT(0) = CONFIG_AUX_TIMER_PERIOD_MS; - MCHP_TMR16_CNT(0) |= BIT(5); - } - - MCHP_WDG_CTL = 0; - - /* Clear WDT PCR sleep enable */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_WDT); - - /* Set timeout. It takes 1007 us to decrement WDG_CNT by 1. */ - MCHP_WDG_LOAD = CONFIG_WATCHDOG_PERIOD_MS * 1000 / 1007; - - wdg_intr_enable(1); - - /* - * Start watchdog - * If chipset debug build enable feature to prevent watchdog from - * counting if a debug cable is attached to JTAG_RST#. - */ - if (IS_ENABLED(CONFIG_CHIPSET_DEBUG)) - MCHP_WDG_CTL |= (MCHP_WDT_CTL_ENABLE - | MCHP_WDT_CTL_JTAG_STALL_EN); - else - MCHP_WDG_CTL |= MCHP_WDT_CTL_ENABLE; - - return EC_SUCCESS; -} - -/* MEC152x Watchdog can fire an interrupt to CPU before system reset */ -#if defined(CHIP_FAMILY_MEC152X) || defined(CHIP_FAMILY_MEC172X) - -void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) -{ - /* Clear WDG first then aggregator */ - MCHP_WDG_STATUS = MCHP_WDG_STS_IRQ; - MCHP_INT_SOURCE(MCHP_WDG_GIRQ) = MCHP_WDG_GIRQ_BIT; - - /* Cause WDG to reload again. */ - MCHP_WDG_KICK = 1; - - watchdog_trace(excep_lr, excep_sp); - - /* Reset system by re-programing WDT to trigger after 2 32KHz clocks */ - MCHP_WDG_CTL = 0; /* clear enable to allow write to load register */ - MCHP_WDG_LOAD = 2; - MCHP_WDG_CTL |= MCHP_WDT_CTL_ENABLE; - -} - -/* ISR for watchdog warning naked will keep SP & LR */ -void -IRQ_HANDLER(MCHP_IRQ_WDG)(void) __keep __attribute__((naked)); -void IRQ_HANDLER(MCHP_IRQ_WDG)(void) -{ - /* Naked call so we can extract raw LR and SP */ - asm volatile("mov r0, lr\n" - "mov r1, sp\n" - /* - * Must push registers in pairs to keep 64-bit aligned - * stack for ARM EABI. This also conveniently saves - * R0=LR so we can pass it to task_resched_if_needed. - */ - "push {r0, lr}\n" - "bl watchdog_check\n" - "pop {r0, lr}\n" - "b task_resched_if_needed\n"); -} - -/* put the watchdog at the highest priority */ -const struct irq_priority __keep IRQ_PRIORITY(MCHP_IRQ_WDG) -__attribute__((section(".rodata.irqprio"))) -= {MCHP_IRQ_WDG, 0}; - -#else -/* - * MEC1701 watchdog only resets. Use a 16-bit timer to fire in interrupt - * for saving watchdog trace. - */ -#ifdef CONFIG_WATCHDOG_HELP -void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) -{ - /* Clear status */ - MCHP_TMR16_STS(0) |= 1; - /* clear aggregator status */ - MCHP_INT_SOURCE(MCHP_TMR16_GIRQ) = MCHP_TMR16_GIRQ_BIT(0); - - watchdog_trace(excep_lr, excep_sp); -} - -void -IRQ_HANDLER(MCHP_IRQ_TIMER16_0)(void) __keep __attribute__((naked)); -void IRQ_HANDLER(MCHP_IRQ_TIMER16_0)(void) -{ - /* Naked call so we can extract raw LR and SP */ - asm volatile("mov r0, lr\n" - "mov r1, sp\n" - /* - * Must push registers in pairs to keep 64-bit aligned - * stack for ARM EABI. This also conveniently saves - * R0=LR so we can pass it to task_resched_if_needed. - */ - "push {r0, lr}\n" - "bl watchdog_check\n" - "pop {r0, lr}\n" - "b task_resched_if_needed\n"); -} - -/* Put the watchdog at the highest interrupt priority. */ -const struct irq_priority __keep IRQ_PRIORITY(MCHP_IRQ_TIMER16_0) - __attribute__((section(".rodata.irqprio"))) - = {MCHP_IRQ_TIMER16_0, 0}; - -#endif /* #ifdef CONFIG_WATCHDOG_HELP */ -#endif /* #if defined(CHIP_FAMILY_MEC152X) || defined(CHIP_FAMILY_MEC172X) */ |