From acb9c0b6616f96357c303964678eac05177a078d Mon Sep 17 00:00:00 2001 From: Lee Leahy Date: Thu, 2 Jul 2015 11:55:18 -0700 Subject: Braswell: Update to end of June. Remove some CamelCase in acpi.c Add FSP PcdDvfsEnable configuration parameter. Add lpc_init and lpc_set_low_power routines. Remove Braswell reference to make code easier to port to another SOC. BRANCH=none BUG=None TEST=Build and run on cyan Change-Id: I5063215fc5d19b4a07f3161f76bf3d58e30f6f02 Signed-off-by: Lee Leahy Reviewed-on: http://review.coreboot.org/10768 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/intel/braswell/Kconfig | 2 + src/soc/intel/braswell/Makefile.inc | 2 + src/soc/intel/braswell/acpi.c | 9 +- src/soc/intel/braswell/chip.h | 1 + src/soc/intel/braswell/cpu.c | 53 ++++++++++- src/soc/intel/braswell/include/soc/gpio.h | 3 + src/soc/intel/braswell/include/soc/iosf.h | 1 + src/soc/intel/braswell/include/soc/nvs.h | 3 +- src/soc/intel/braswell/include/soc/pei_data.h | 2 +- src/soc/intel/braswell/lpc_init.c | 125 ++++++++++++++++++++++++++ src/soc/intel/braswell/pmutil.c | 7 +- src/soc/intel/braswell/romstage/romstage.c | 4 + src/soc/intel/braswell/spi.c | 9 +- src/soc/intel/braswell/tsc_freq.c | 5 +- 14 files changed, 210 insertions(+), 16 deletions(-) create mode 100644 src/soc/intel/braswell/lpc_init.c (limited to 'src') diff --git a/src/soc/intel/braswell/Kconfig b/src/soc/intel/braswell/Kconfig index 5b6fa109e1..4f7ed6a7ca 100644 --- a/src/soc/intel/braswell/Kconfig +++ b/src/soc/intel/braswell/Kconfig @@ -27,7 +27,9 @@ config CPU_SPECIFIC_OPTIONS select RELOCATABLE_MODULES select PARALLEL_MP select PCIEXP_ASPM + select PCIEXP_CLK_PM select PCIEXP_COMMON_CLOCK + select PCIEXP_L1_SUB_STATE select PLATFORM_USES_FSP1_1 select REG_SCRIPT select SOC_INTEL_COMMON diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index 540ac84ed8..207f17d579 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -13,6 +13,7 @@ subdirs-y += ../../../cpu/intel/turbo romstage-y += gpio_support.c romstage-y += iosf.c +romstage-y += lpc_init.c romstage-y += memmap.c romstage-y += tsc_freq.c @@ -46,6 +47,7 @@ ramstage-y += tsc_freq.c # Remove as ramstage gets fleshed out ramstage-y += placeholders.c +smm-y += lpc_init.c smm-y += pmutil.c smm-y += smihandler.c smm-y += spi.c diff --git a/src/soc/intel/braswell/acpi.c b/src/soc/intel/braswell/acpi.c index ab83cf485b..e1065e22d1 100644 --- a/src/soc/intel/braswell/acpi.c +++ b/src/soc/intel/braswell/acpi.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -269,7 +270,7 @@ static acpi_tstate_t soc_tss_table[] = { { 13, 125, 0, 0x12, 0 }, }; -static void generate_T_state_entries(int core, int cores_per_package) +static void generate_t_state_entries(int core, int cores_per_package) { /* Indicate SW_ALL coordination for T-states */ acpigen_write_TSD_package(core, cores_per_package, SW_ALL); @@ -306,7 +307,7 @@ static int calculate_power(int tdp, int p1_ratio, int ratio) return (int)power; } -static void generate_P_state_entries(int core, int cores_per_package) +static void generate_p_state_entries(int core, int cores_per_package) { int ratio_min, ratio_max, ratio_turbo, ratio_step, ratio_range_2; int coord_type, power_max, power_unit, num_entries; @@ -438,7 +439,7 @@ void generate_cpu_entries(device_t device) core, pcontrol_blk, plen); /* Generate P-state tables */ - generate_P_state_entries( + generate_p_state_entries( core, pattrs->num_cpus); /* Generate C-state tables */ @@ -446,7 +447,7 @@ void generate_cpu_entries(device_t device) cstate_map, ARRAY_SIZE(cstate_map)); /* Generate T-state tables */ - generate_T_state_entries( + generate_t_state_entries( core, pattrs->num_cpus); acpigen_pop_len(); diff --git a/src/soc/intel/braswell/chip.h b/src/soc/intel/braswell/chip.h index fde508c394..d70aa9b117 100644 --- a/src/soc/intel/braswell/chip.h +++ b/src/soc/intel/braswell/chip.h @@ -70,6 +70,7 @@ struct soc_intel_braswell_config { UINT8 PcdApertureSize; UINT8 PcdGttSize; UINT8 PcdLegacySegDecode; + UINT8 PcdDvfsEnable; /* * The following fields come from fsp_vpd.h .aka. VpdHeader.h. diff --git a/src/soc/intel/braswell/cpu.c b/src/soc/intel/braswell/cpu.c index 3abec6b53c..e648ce04a3 100644 --- a/src/soc/intel/braswell/cpu.c +++ b/src/soc/intel/braswell/cpu.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,31 @@ static int adjust_apic_id(int index, int apic_id) return 2 * index; } +/* Package level MSRs */ +const struct reg_script package_msr_script[] = { + /* Set Package TDP to ~7W */ + REG_MSR_WRITE(MSR_PKG_POWER_LIMIT, 0x3880fa), + REG_MSR_RMW(MSR_PP1_POWER_LIMIT, ~(0x7f << 17), 0), + REG_MSR_WRITE(MSR_PKG_TURBO_CFG1, 0x702), + REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG1, 0x200b), + REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG2, 0), + REG_MSR_WRITE(MSR_CPU_THERM_CFG1, 0x00000305), + REG_MSR_WRITE(MSR_CPU_THERM_CFG2, 0x0405500d), + REG_MSR_WRITE(MSR_CPU_THERM_SENS_CFG, 0x27), + REG_SCRIPT_END +}; + +/* Core level MSRs */ +const struct reg_script core_msr_script[] = { + /* Dynamic L2 shrink enable and threshold, clear SINGLE_PCTL bit 11 */ + REG_MSR_RMW(MSR_PMG_CST_CONFIG_CONTROL, ~0x3f080f, 0xe0008), + REG_MSR_RMW(MSR_POWER_MISC, + ~(ENABLE_ULFM_AUTOCM_MASK | ENABLE_INDP_AUTOCM_MASK), 0), + /* Disable C1E */ + REG_MSR_RMW(MSR_POWER_CTL, ~0x2, 0), + REG_MSR_OR(MSR_POWER_MISC, 0x44), + REG_SCRIPT_END +}; void soc_init_cpus(device_t dev) { @@ -78,6 +104,10 @@ void soc_init_cpus(device_t dev) default_smm_area = backup_default_smm_area(); + /* Set package MSRs */ + reg_script_run(package_msr_script); + + /* Enable Turbo Mode on BSP and siblings of the BSP's building block. */ enable_turbo(); if (mp_init(cpu_bus, &mp_params)) @@ -86,9 +116,30 @@ void soc_init_cpus(device_t dev) restore_default_smm_area(default_smm_area); } +static void soc_core_init(device_t cpu) +{ + printk(BIOS_SPEW, "%s/%s ( %s )\n", + __FILE__, __func__, dev_name(cpu)); + printk(BIOS_DEBUG, "Init Braswell core.\n"); + + /* + * The turbo disable bit is actually scoped at building + * block level -- not package. For non-bsp cores that are within a + * building block enable turbo. The cores within the BSP's building + * block will just see it already enabled and move on. + */ + if (lapicid()) + enable_turbo(); + + /* Set core MSRs */ + reg_script_run(core_msr_script); + + /* Set this core to max frequency ratio */ + set_max_freq(); +} static struct device_operations cpu_dev_ops = { - .init = NULL, + .init = soc_core_init, }; static struct cpu_device_id cpu_table[] = { diff --git a/src/soc/intel/braswell/include/soc/gpio.h b/src/soc/intel/braswell/include/soc/gpio.h index 20a4d51180..5dda732ea0 100644 --- a/src/soc/intel/braswell/include/soc/gpio.h +++ b/src/soc/intel/braswell/include/soc/gpio.h @@ -573,4 +573,7 @@ int get_gpio(int community_base, int pad0_offset); uint16_t gpio_family_number(uint8_t community, uint8_t pad); uint32_t *gpio_pad_config_reg(uint8_t community, uint8_t pad); +void lpc_init(void); +void lpc_set_low_power(void); + #endif /* _SOC_GPIO_H_ */ diff --git a/src/soc/intel/braswell/include/soc/iosf.h b/src/soc/intel/braswell/include/soc/iosf.h index 60763d9304..1cdfb8f587 100644 --- a/src/soc/intel/braswell/include/soc/iosf.h +++ b/src/soc/intel/braswell/include/soc/iosf.h @@ -21,6 +21,7 @@ #ifndef _SOC_IOSF_H_ #define _SOC_IOSF_H_ +#include #include #if ENV_RAMSTAGE #include diff --git a/src/soc/intel/braswell/include/soc/nvs.h b/src/soc/intel/braswell/include/soc/nvs.h index 1c25cb295f..9492f2c61b 100644 --- a/src/soc/intel/braswell/include/soc/nvs.h +++ b/src/soc/intel/braswell/include/soc/nvs.h @@ -22,6 +22,7 @@ #ifndef _SOC_NVS_H_ #define _SOC_NVS_H_ +#include #include #include @@ -73,7 +74,7 @@ typedef struct { } __attribute__((packed)) global_nvs_t; void acpi_create_gnvs(global_nvs_t *gnvs); -#ifdef __SMM__ +#if ENV_SMM /* Used in SMM to find the ACPI GNVS address */ global_nvs_t *smm_get_gnvs(void); #endif diff --git a/src/soc/intel/braswell/include/soc/pei_data.h b/src/soc/intel/braswell/include/soc/pei_data.h index 67e34f7c98..50aabed66e 100644 --- a/src/soc/intel/braswell/include/soc/pei_data.h +++ b/src/soc/intel/braswell/include/soc/pei_data.h @@ -1,5 +1,5 @@ /* - * Braswell UEFI PEI wrapper + * UEFI PEI wrapper * * Copyright (C) 2014 Google Inc. * diff --git a/src/soc/intel/braswell/lpc_init.c b/src/soc/intel/braswell/lpc_init.c new file mode 100644 index 0000000000..91816e746e --- /dev/null +++ b/src/soc/intel/braswell/lpc_init.c @@ -0,0 +1,125 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include +#include +#include + +#define SUSPEND_CYCLE 1 +#define RESUME_CYCLE 0 +#define LPC_FAMILY_NUMBER(gpio_pad) (gpio_pad / MAX_FAMILY_PAD_GPIO_NO) +#define LPC_INTERNAL_PAD_NUM(gpio_pad) (gpio_pad % MAX_FAMILY_PAD_GPIO_NO) +#define LPC_GPIO_OFFSET(gpio_pad) (FAMILY_PAD_REGS_OFF \ + + (FAMILY_PAD_REGS_SIZE * LPC_FAMILY_NUMBER(gpio_pad) \ + + (GPIO_REGS_SIZE * LPC_INTERNAL_PAD_NUM(gpio_pad)))) + +#define LPC_AD2_MMIO_OFFSET LPC_GPIO_OFFSET(45) +#define LPC_CLKRUN_MMIO_OFFSET LPC_GPIO_OFFSET(46) +#define LPC_AD0_MMIO_OFFSET LPC_GPIO_OFFSET(47) +#define LPC_FRAME_MMIO_OFFSET LPC_GPIO_OFFSET(48) +#define LPC_AD3_MMIO_OFFSET LPC_GPIO_OFFSET(50) +#define LPC_AD1_MMIO_OFFSET LPC_GPIO_OFFSET(52) + + +/* Value written into pad control reg 0 in early init */ +#define PAD_CFG0_NATIVE(mode, term, inv_rx_tx) (PAD_GPIO_DISABLE \ + | PAD_GPIOFG_HI_Z \ + | PAD_MODE_SELECTION(mode) | PAD_PULL(term)) + +#define PAD_CFG0_NATIVE_PU20K(mode) PAD_CFG0_NATIVE(mode, 9, 0) /* PU 20K */ +#define PAD_CFG0_NATIVE_PD20K(mode) PAD_CFG0_NATIVE(mode, 1, 0) /* PD 20K */ +#define PAD_CFG0_NATIVE_M1 PAD_CFG0_NATIVE(1, 0, 0) /* no pull */ + +/* + * Configure value in LPC GPIO PADCFG0 registers. This function would be called + * to configure for low power/restore LPC GPIO lines + */ +static void lpc_gpio_config(u32 cycle) +{ + if (cycle == SUSPEND_CYCLE) { /* Suspend cycle */ + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_FRAME_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD0_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD1_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD2_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD3_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_CLKRUN_MMIO_OFFSET), + PAD_CFG0_NATIVE_PD20K(1)); + } else { /* Resume cycle */ + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_FRAME_MMIO_OFFSET), + PAD_CFG0_NATIVE_M1); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD0_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD1_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD2_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_AD3_MMIO_OFFSET), + PAD_CFG0_NATIVE_PU20K(1)); + write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + + LPC_CLKRUN_MMIO_OFFSET), + PAD_CFG0_NATIVE_M1); + } +} + +/* + * configure LPC GPIO lines for low power + */ +void lpc_set_low_power(void) +{ + lpc_gpio_config(SUSPEND_CYCLE); +} + +/* + * Configure GPIO lines early during romstage. + */ +void lpc_init(void) +{ + uint16_t pm1_sts; + uint32_t pm1_cnt; + int slp_type = 0; + + /* + * On S3 resume re-initialize GPIO lines which were + * configured for low power during S3 entry. + */ + pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS); + pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); + + if (pm1_sts & WAK_STS) + slp_type = (pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT; + + if ((slp_type == SLP_TYP_S3) || (slp_type == SLP_TYP_S5)) + lpc_gpio_config(RESUME_CYCLE); +} diff --git a/src/soc/intel/braswell/pmutil.c b/src/soc/intel/braswell/pmutil.c index 2cdeaafdef..fe5be64d68 100644 --- a/src/soc/intel/braswell/pmutil.c +++ b/src/soc/intel/braswell/pmutil.c @@ -20,13 +20,14 @@ #include #include +#include #include #include #include #include #include -#if defined(__SMM__) +#if ENV_SMM static const device_t pcu_dev = PCI_DEV(0, PCU_DEV, 0); @@ -35,7 +36,7 @@ static inline device_t get_pcu_dev(void) return pcu_dev; } -#else /* !__SMM__ */ +#else /* ENV_SMM */ #include #include @@ -46,7 +47,7 @@ static device_t get_pcu_dev(void) pcu_dev = dev_find_slot(0, PCI_DEVFN(PCU_DEV, 0)); return pcu_dev; } -#endif +#endif /* ENV_SMM */ uint16_t get_pmbase(void) { diff --git a/src/soc/intel/braswell/romstage/romstage.c b/src/soc/intel/braswell/romstage/romstage.c index df6efd8bf2..64a3deee9a 100644 --- a/src/soc/intel/braswell/romstage/romstage.c +++ b/src/soc/intel/braswell/romstage/romstage.c @@ -187,6 +187,7 @@ void soc_romstage_init(struct romstage_params *params) /* Ensure the EC is in the right mode for recovery */ google_chromeec_early_init(); #endif + lpc_init(); } /* SOC initialization after RAM is enabled */ @@ -220,6 +221,7 @@ void soc_memory_init_params(MEMORY_INIT_UPD *params) params->PcdApertureSize = config->PcdApertureSize; params->PcdGttSize = config->PcdGttSize; params->PcdLegacySegDecode = config->PcdLegacySegDecode; + params->PcdDvfsEnable = config->PcdDvfsEnable; } void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, @@ -249,4 +251,6 @@ void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, old->PcdGttSize, new->PcdGttSize); soc_display_upd_value("PcdLegacySegDecode", 1, old->PcdLegacySegDecode, new->PcdLegacySegDecode); + soc_display_upd_value("PcdDvfsEnable", 1, + old->PcdDvfsEnable, new->PcdDvfsEnable); } diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index 16fb465037..afc288a36a 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,7 @@ #include #include -#ifdef __SMM__ +#if ENV_SMM #define pci_read_config_byte(dev, reg, targ)\ *(targ) = pci_read_config8(dev, reg) #define pci_read_config_word(dev, reg, targ)\ @@ -46,7 +47,7 @@ pci_write_config16(dev, reg, val) #define pci_write_config_dword(dev, reg, val)\ pci_write_config32(dev, reg, val) -#else /* !__SMM__ */ +#else /* ENV_SMM */ #include #include #define pci_read_config_byte(dev, reg, targ)\ @@ -61,7 +62,7 @@ pci_write_config16(dev, reg, val) #define pci_write_config_dword(dev, reg, val)\ pci_write_config32(dev, reg, val) -#endif /* !__SMM__ */ +#endif /* ENV_SMM */ typedef struct spi_slave ich_spi_slave; @@ -255,7 +256,7 @@ static ich9_spi_regs *spi_regs(void) device_t dev; uint32_t sbase; -#ifdef __SMM__ +#if ENV_SMM dev = PCI_DEV(0, LPC_DEV, LPC_FUNC); #else dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC)); diff --git a/src/soc/intel/braswell/tsc_freq.c b/src/soc/intel/braswell/tsc_freq.c index e7a1c13f51..34e610f60b 100644 --- a/src/soc/intel/braswell/tsc_freq.c +++ b/src/soc/intel/braswell/tsc_freq.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #if ENV_RAMSTAGE @@ -37,7 +38,7 @@ unsigned long tsc_freq_mhz(void) return (BUS_FREQ_KHZ * ((ia_core_ratios.lo >> 16) & 0x3f)) / 1000; } -#if !defined(__SMM__) +#if !ENV_SMM void set_max_freq(void) { @@ -67,4 +68,4 @@ void set_max_freq(void) wrmsr(MSR_IA32_PERF_CTL, perf_ctl); } -#endif /* __SMM__ */ +#endif /* ENV_SMM */ -- cgit v1.2.3