diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc index 7b27c574c5..98f2718fb7 100644 --- a/src/soc/intel/skylake/Makefile.inc +++ b/src/soc/intel/skylake/Makefile.inc @@ -12,16 +12,19 @@ subdirs-y += ../../../cpu/x86/tsc bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/cache_as_ram.S bootblock-y += bootblock/cpu.c +bootblock-y += bootblock/i2c.c bootblock-y += bootblock/pch.c +bootblock-y += bootblock/report_platform.c +bootblock-y += bootblock/smbus.c bootblock-y += bootblock/systemagent.c bootblock-$(CONFIG_UART_DEBUG) += bootblock/uart.c +bootblock-$(CONFIG_UART_DEBUG) += uart_debug.c bootblock-y += gpio.c bootblock-y += monotonic_timer.c bootblock-y += pch.c bootblock-y += pcr.c bootblock-y += pmutil.c bootblock-y += tsc_freq.c -bootblock-$(CONFIG_UART_DEBUG) += uart_debug.c verstage-$(CONFIG_UART_DEBUG) += uart_debug.c diff --git a/src/soc/intel/skylake/bootblock/bootblock.c b/src/soc/intel/skylake/bootblock/bootblock.c index f644d1f638..b00fcf74ab 100644 --- a/src/soc/intel/skylake/bootblock/bootblock.c +++ b/src/soc/intel/skylake/bootblock/bootblock.c @@ -15,7 +15,6 @@ #include #include -#include void asmlinkage bootblock_c_entry(uint64_t base_timestamp) { diff --git a/src/soc/intel/skylake/bootblock/cpu.c b/src/soc/intel/skylake/bootblock/cpu.c index 8c1e58a65f..3cea8bdcfc 100644 --- a/src/soc/intel/skylake/bootblock/cpu.c +++ b/src/soc/intel/skylake/bootblock/cpu.c @@ -17,9 +17,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -105,3 +107,27 @@ void bootblock_cpu_init(void) set_flex_ratio_to_tdp_nominal(); intel_update_microcode_from_cbfs(); } + +void set_max_freq(void) +{ + msr_t msr, perf_ctl, platform_info; + + /* Check for configurable TDP option */ + platform_info = rdmsr(MSR_PLATFORM_INFO); + + if ((platform_info.hi >> 1) & 3) { + /* Set to nominal TDP ratio */ + msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else { + /* Platform Info bits 15:8 give max ratio */ + msr = rdmsr(MSR_PLATFORM_INFO); + perf_ctl.lo = msr.lo & 0xff00; + } + + perf_ctl.hi = 0; + wrmsr(IA32_PERF_CTL, perf_ctl); + + printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n", + ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); +} diff --git a/src/soc/intel/skylake/romstage/i2c.c b/src/soc/intel/skylake/bootblock/i2c.c similarity index 99% rename from src/soc/intel/skylake/romstage/i2c.c rename to src/soc/intel/skylake/bootblock/i2c.c index f6d1384a4b..64b1fb57e7 100644 --- a/src/soc/intel/skylake/romstage/i2c.c +++ b/src/soc/intel/skylake/bootblock/i2c.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include "chip.h" diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c index e7f414b721..22ab1090b8 100644 --- a/src/soc/intel/skylake/bootblock/pch.c +++ b/src/soc/intel/skylake/bootblock/pch.c @@ -15,13 +15,22 @@ * GNU General Public License for more details. */ #include +#include +#include +#include #include #include #include #include +#include #include #include -#include +#include +#include +#include + +/* Max PXRC registers in ITSS*/ +#define MAX_PXRC_CONFIG 0x08 /* * Enable Prefetching and Caching. @@ -65,7 +74,6 @@ static void enable_p2sbbar(void) /* Enable P2SB MSE */ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); - /* * Enable decoding for HPET memory address range. * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode @@ -81,3 +89,196 @@ void bootblock_pch_early_init(void) enable_spi_prefetch(); enable_p2sbbar(); } + +static void pch_enable_lpc(void) +{ + /* Lookup device tree in romstage */ + const struct device *dev; + const config_t *config; + u16 lpc_en; + + /* IO Decode Range */ + lpc_en = COMA_RANGE | (COMB_RANGE << 4); + pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, lpc_en); + pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOD, lpc_en); + + /* IO Decode Enable */ + lpc_en = COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN; + pci_write_config16(PCH_DEV_LPC, LPC_EN, lpc_en); + pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOE, lpc_en); + + dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); + if (!dev || !dev->chip_info) + return; + config = dev->chip_info; + + /* Set in PCI generic decode range registers */ + pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec); + pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec); + pci_write_config32(PCH_DEV_LPC, LPC_GEN3_DEC, config->gen3_dec); + pci_write_config32(PCH_DEV_LPC, LPC_GEN4_DEC, config->gen4_dec); + + /* Mirror these same settings in DMI PCR */ + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR1, config->gen1_dec); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR2, config->gen2_dec); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR3, config->gen3_dec); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR4, config->gen4_dec); +} + +static void pch_interrupt_init(void) +{ + const struct device *dev; + const config_t *config; + u8 index = 0; + u8 pch_interrupt_routing[MAX_PXRC_CONFIG]; + + dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); + if (!dev || !dev->chip_info) + return; + config = dev->chip_info; + + pch_interrupt_routing[0] = config->pirqa_routing; + pch_interrupt_routing[1] = config->pirqb_routing; + pch_interrupt_routing[2] = config->pirqc_routing; + pch_interrupt_routing[3] = config->pirqd_routing; + pch_interrupt_routing[4] = config->pirqe_routing; + pch_interrupt_routing[5] = config->pirqf_routing; + pch_interrupt_routing[6] = config->pirqg_routing; + pch_interrupt_routing[7] = config->pirqh_routing; + + for (index = 0; index < MAX_PXRC_CONFIG; index++) { + if (pch_interrupt_routing[index] < 16 && + pch_interrupt_routing[index] > 2 && + pch_interrupt_routing[index] != 8 && + pch_interrupt_routing[index] != 13) { + pcr_write8(PID_ITSS, + (R_PCH_PCR_ITSS_PIRQA_ROUT + index), + pch_interrupt_routing[index]); + } + } +} + +static void soc_config_acpibase(void) +{ + uint32_t reg32; + + /* Disable ABASE in PMC Device first before changing Base Address */ + reg32 = pci_read_config32(PCH_DEV_PMC, ACTL); + pci_write_config32(PCH_DEV_PMC, ACTL, reg32 & ~ACPI_EN); + + /* Program ACPI Base */ + pci_write_config32(PCH_DEV_PMC, ABASE, ACPI_BASE_ADDRESS); + + /* Enable ACPI in PMC */ + pci_write_config32(PCH_DEV_PMC, ACTL, reg32 | ACPI_EN); + + /* + * Program "ACPI Base Address" PCR[DMI] + 27B4h[23:18, 15:2, 0] + * to [0x3F, PMC PCI Offset 40h bit[15:2], 1] + */ + reg32 = ((0x3f << 18) | ACPI_BASE_ADDRESS | 1); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_ACPIBA, reg32); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_ACPIBDID, 0x23A0); +} + +static void soc_config_pwrmbase(void) +{ + uint32_t reg32; + + /* Disable PWRMBASE in PMC Device first before changing Base address */ + reg32 = pci_read_config32(PCH_DEV_PMC, ACTL); + pci_write_config32(PCH_DEV_PMC, ACTL, reg32 & ~PWRM_EN); + + /* Program PWRM Base */ + pci_write_config32(PCH_DEV_PMC, PWRMBASE, PCH_PWRM_BASE_ADDRESS); + + /* Enable PWRM in PMC */ + pci_write_config32(PCH_DEV_PMC, ACTL, reg32 | PWRM_EN); + + /* + * Program "PM Base Address Memory Range Base" PCR[DMI] + 27ACh[15:0] + * to the same value programmed in PMC PCI Offset 48h bit[31:16], + * this has an implication of making sure the PWRMBASE to be + * 64KB aligned. + * + * Program "PM Base Address Memory Range Limit" PCR[DMI] + 27ACh[31:16] + * to the value programmed in PMC PCI Offset 48h bit[31:16], this has an + * implication of making sure the memory allocated to PWRMBASE to be 64KB + * in size. + */ + pcr_write32(PID_DMI, R_PCH_PCR_DMI_PMBASEA, + ((PCH_PWRM_BASE_ADDRESS & 0xFFFF0000) | + (PCH_PWRM_BASE_ADDRESS >> 16))); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_PMBASEC, 0x800023A0); +} + +static void soc_config_tco(void) +{ + uint32_t reg32 = 0; + uint16_t tcobase; + uint16_t tcocnt; + + /* Disable TCO in SMBUS Device first before changing Base Address */ + reg32 = pci_read_config32(PCH_DEV_SMBUS, TCOCTL); + reg32 &= ~SMBUS_TCO_EN; + pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32); + + /* Program TCO Base */ + pci_write_config32(PCH_DEV_SMBUS, TCOBASE, TCO_BASE_ADDDRESS); + + /* Enable TCO in SMBUS */ + pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32 | SMBUS_TCO_EN); + + /* + * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] + * to [SMBUS PCI offset 50h[15:5], 1]. + */ + pcr_write32(PID_DMI, R_PCH_PCR_DMI_TCOBASE, + (TCO_BASE_ADDDRESS | (1 << 1))); + + /* Program TCO timer halt */ + tcobase = pci_read_config16(PCH_DEV_SMBUS, TCOBASE); + tcobase &= ~0x1f; + tcocnt = inw(tcobase + TCO1_CNT); + tcocnt |= TCO_TMR_HLT; + outw(tcocnt, tcobase + TCO1_CNT); +} + +static void soc_config_rtc(void) +{ + /* Enable upper 128 bytes of CMOS */ + pcr_andthenor32(PID_RTC, R_PCH_PCR_RTC_CONF, ~0, + B_PCH_PCR_RTC_CONF_UCMOS_EN); +} + +void pch_early_init(void) +{ + /* + * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT, + * GPE0_STS, GPE0_EN registers. + */ + soc_config_acpibase(); + + /* + * Enabling PWRM Base for accessing + * Global Reset Cause Register. + */ + soc_config_pwrmbase(); + + /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */ + soc_config_tco(); + + /* + * Interrupt Configuration Register Programming + * PIRQx to IRQ Programming + */ + pch_interrupt_init(); + + /* Program generic IO Decode Range */ + pch_enable_lpc(); + + /* Program SMBUS_BASE_ADDRESS and Enable it */ + enable_smbus(); + + soc_config_rtc(); +} diff --git a/src/soc/intel/skylake/romstage/report_platform.c b/src/soc/intel/skylake/bootblock/report_platform.c similarity index 99% rename from src/soc/intel/skylake/romstage/report_platform.c rename to src/soc/intel/skylake/bootblock/report_platform.c index e841359f3b..2610940859 100644 --- a/src/soc/intel/skylake/romstage/report_platform.c +++ b/src/soc/intel/skylake/bootblock/report_platform.c @@ -19,10 +19,10 @@ #include #include #include +#include #include #include #include -#include #include #include diff --git a/src/soc/intel/skylake/romstage/smbus.c b/src/soc/intel/skylake/bootblock/smbus.c similarity index 90% rename from src/soc/intel/skylake/romstage/smbus.c rename to src/soc/intel/skylake/bootblock/smbus.c index ca9c6adf06..bb305d5192 100644 --- a/src/soc/intel/skylake/romstage/smbus.c +++ b/src/soc/intel/skylake/bootblock/smbus.c @@ -20,10 +20,10 @@ #include #include #include +#include #include #include #include -#include static const struct reg_script smbus_init_script[] = { /* Set SMBUS I/O base address */ @@ -45,7 +45,3 @@ void enable_smbus(void) reg_script_run_on_dev(PCH_DEV_SMBUS, smbus_init_script); } -int smbus_read_byte(unsigned device, unsigned address) -{ - return do_smbus_read_byte(SMBUS_BASE_ADDRESS, device, address); -} diff --git a/src/soc/intel/skylake/include/soc/bootblock.h b/src/soc/intel/skylake/include/soc/bootblock.h index e57c369d14..bacbef8cff 100644 --- a/src/soc/intel/skylake/include/soc/bootblock.h +++ b/src/soc/intel/skylake/include/soc/bootblock.h @@ -26,9 +26,14 @@ inline void bootblock_fsp_temp_ram_init(void) {} void bootblock_cpu_init(void); void bootblock_pch_early_init(void); void bootblock_systemagent_early_init(void); - void pch_uart_init(void); + /* Bootblock post console init programing */ -void pch_enable_lpc(void); +void enable_smbus(void); +void i2c_early_init(void); +void pch_early_init(void); +void report_platform_info(void); +void report_memory_config(void); +void set_max_freq(void); #endif diff --git a/src/soc/intel/skylake/include/soc/romstage.h b/src/soc/intel/skylake/include/soc/romstage.h index 71887aa165..6c40bd626d 100644 --- a/src/soc/intel/skylake/include/soc/romstage.h +++ b/src/soc/intel/skylake/include/soc/romstage.h @@ -19,13 +19,8 @@ #include -void i2c_early_init(void); void systemagent_early_init(void); -void pch_early_init(void); void intel_early_me_status(void); -void report_platform_info(void); -void set_max_freq(void); - void enable_smbus(void); int smbus_read_byte(unsigned device, unsigned address); diff --git a/src/soc/intel/skylake/romstage/Makefile.inc b/src/soc/intel/skylake/romstage/Makefile.inc index 7a13084bf5..31a452ff63 100644 --- a/src/soc/intel/skylake/romstage/Makefile.inc +++ b/src/soc/intel/skylake/romstage/Makefile.inc @@ -1,17 +1,7 @@ -bootblock-y += cpu.c -bootblock-y += i2c.c -bootblock-y += pch.c -bootblock-y += report_platform.c -bootblock-y += smbus.c verstage-y += power_state.c -romstage-y += cpu.c -romstage-y += i2c.c -romstage-y += pch.c romstage-y += power_state.c -romstage-y += report_platform.c romstage-y += romstage.c -romstage-y += smbus.c romstage-y += spi.c romstage-y += systemagent.c diff --git a/src/soc/intel/skylake/romstage/cpu.c b/src/soc/intel/skylake/romstage/cpu.c deleted file mode 100644 index 1b5db73a00..0000000000 --- a/src/soc/intel/skylake/romstage/cpu.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * Copyright (C) 2015 Intel Corporation. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -u32 cpu_family_model(void) -{ - return cpuid_eax(1) & 0x0fff0ff0; -} - -void set_max_freq(void) -{ - msr_t msr, perf_ctl, platform_info; - - /* Check for configurable TDP option */ - platform_info = rdmsr(MSR_PLATFORM_INFO); - - if ((platform_info.hi >> 1) & 3) { - /* Set to nominal TDP ratio */ - msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); - perf_ctl.lo = (msr.lo & 0xff) << 8; - } else { - /* Platform Info bits 15:8 give max ratio */ - msr = rdmsr(MSR_PLATFORM_INFO); - perf_ctl.lo = msr.lo & 0xff00; - } - - perf_ctl.hi = 0; - wrmsr(IA32_PERF_CTL, perf_ctl); - - printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n", - ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); -} diff --git a/src/soc/intel/skylake/romstage/pch.c b/src/soc/intel/skylake/romstage/pch.c deleted file mode 100644 index dd52b40bf3..0000000000 --- a/src/soc/intel/skylake/romstage/pch.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * Copyright (C) 2015 Intel Corporation. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Max PXRC registers in ITSS*/ -#define MAX_PXRC_CONFIG 0x08 - -static const u8 pch_interrupt_routing[] = { - 11, /* PARC: PIRQA -> IRQ11 */ - 10, /* PBRC: PIRQB -> IRQ10 */ - 11, /* PCRC: PIRQC -> IRQ11 */ - 11, /* PDRC: PIRQD -> IRQ11 */ - 11, /* PERC: PIRQE -> IRQ11 */ - 11, /* PFRC: PIRQF -> IRQ11 */ - 11, /* PGRC: PIRQG -> IRQ11 */ - 11 /* PHRC: PIRQH -> IRQ11 */ -}; - -static void pch_enable_lpc(void) -{ - /* Lookup device tree in romstage */ - const struct device *dev; - const config_t *config; - u16 lpc_en; - - /* IO Decode Range */ - lpc_en = COMA_RANGE | (COMB_RANGE << 4); - pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, lpc_en); - pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOD, lpc_en); - - /* IO Decode Enable */ - lpc_en = COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN; - pci_write_config16(PCH_DEV_LPC, LPC_EN, lpc_en); - pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOE, lpc_en); - - dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); - if (!dev || !dev->chip_info) - return; - config = dev->chip_info; - - /* Set in PCI generic decode range registers */ - pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec); - pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec); - pci_write_config32(PCH_DEV_LPC, LPC_GEN3_DEC, config->gen3_dec); - pci_write_config32(PCH_DEV_LPC, LPC_GEN4_DEC, config->gen4_dec); - - /* Mirror these same settings in DMI PCR */ - pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR1, config->gen1_dec); - pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR2, config->gen2_dec); - pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR3, config->gen3_dec); - pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR4, config->gen4_dec); -} - -static void pch_interrupt_init(void) -{ - u8 index = 0; - - for (index = 0; index < MAX_PXRC_CONFIG; index++) { - if (pch_interrupt_routing[index] < 16 && - pch_interrupt_routing[index] > 2 && - pch_interrupt_routing[index] != 8 && - pch_interrupt_routing[index] != 13) { - pcr_write8(PID_ITSS, - (R_PCH_PCR_ITSS_PIRQA_ROUT + index), - pch_interrupt_routing[index]); - } - } -} - -static void soc_config_acpibase(void) -{ - uint32_t reg32; - - /* Disable ABASE in PMC Device first before changing Base Address*/ - reg32 = pci_read_config32(PCH_DEV_PMC, ACTL); - pci_write_config32(PCH_DEV_PMC, ACTL, reg32 & ~ACPI_EN); - - /* Program ACPI Base */ - pci_write_config32(PCH_DEV_PMC, ABASE, ACPI_BASE_ADDRESS); - - /* Enable ACPI in PMC */ - pci_write_config32(PCH_DEV_PMC, ACTL, reg32 | ACPI_EN); - - /* - * Program "ACPI Base Address" PCR[DMI] + 27B4h[23:18, 15:2, 0] - * to [0x3F, PMC PCI Offset 40h bit[15:2], 1] - */ - reg32 = ((0x3f << 18) | ACPI_BASE_ADDRESS | 1); - pcr_write32(PID_DMI, R_PCH_PCR_DMI_ACPIBA, reg32); - pcr_write32(PID_DMI, R_PCH_PCR_DMI_ACPIBDID, 0x23A0); -} - -static void soc_config_pwrmbase(void) -{ - uint32_t reg32; - - /* Disable PWRMBASE in PMC Device first before changing Base address */ - reg32 = pci_read_config32(PCH_DEV_PMC, ACTL); - pci_write_config32(PCH_DEV_PMC, ACTL, reg32 & ~PWRM_EN); - - /* Program PWRM Base */ - pci_write_config32(PCH_DEV_PMC, PWRMBASE, PCH_PWRM_BASE_ADDRESS); - - /* Enable PWRM in PMC */ - pci_write_config32(PCH_DEV_PMC, ACTL, reg32 | PWRM_EN); - - /* - * Program "PM Base Address Memory Range Base" PCR[DMI] + 27ACh[15:0] - * to the same value programmed in PMC PCI Offset 48h bit[31:16], - * this has an implication of making sure the PWRMBASE to be - * 64KB aligned. - * - * Program "PM Base Address Memory Range Limit" PCR[DMI] + 27ACh[31:16] - * to the value programmed in PMC PCI Offset 48h bit[31:16], this has an - * implication of making sure the memory allocated to PWRMBASE to be 64KB - * in size. - */ - pcr_write32(PID_DMI, R_PCH_PCR_DMI_PMBASEA, - ((PCH_PWRM_BASE_ADDRESS & 0xFFFF0000) | - (PCH_PWRM_BASE_ADDRESS >> 16))); - pcr_write32(PID_DMI, R_PCH_PCR_DMI_PMBASEC, 0x800023A0); -} - -static void soc_config_tco(void) -{ - uint32_t reg32 = 0; - uint16_t tcobase; - uint16_t tcocnt; - - /* Disable TCO in SMBUS Device first before changing Base Address */ - reg32 = pci_read_config32(PCH_DEV_SMBUS, TCOCTL); - reg32 &= ~SMBUS_TCO_EN; - pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32); - - /* Program TCO Base */ - pci_write_config32(PCH_DEV_SMBUS, TCOBASE, TCO_BASE_ADDDRESS); - - /* Enable TCO in SMBUS */ - pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32 | SMBUS_TCO_EN); - - /* - * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] - * to [SMBUS PCI offset 50h[15:5], 1]. - */ - pcr_write32(PID_DMI, R_PCH_PCR_DMI_TCOBASE, - (TCO_BASE_ADDDRESS | (1 << 1))); - - /* Program TCO timer halt */ - tcobase = pci_read_config16(PCH_DEV_SMBUS, TCOBASE); - tcobase &= ~0x1f; - tcocnt = inw(tcobase + TCO1_CNT); - tcocnt |= TCO_TMR_HLT; - outw(tcocnt, tcobase + TCO1_CNT); -} - -static void soc_config_rtc(void) -{ - /* Enable upper 128 bytes of CMOS */ - pcr_andthenor32(PID_RTC, R_PCH_PCR_RTC_CONF, ~0, - B_PCH_PCR_RTC_CONF_UCMOS_EN); -} - -void pch_early_init(void) -{ - /* - * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT, - * GPE0_STS, GPE0_EN registers. - */ - soc_config_acpibase(); - - /* - * Enabling PWRM Base for accessing - * Global Reset Cause Register. - */ - soc_config_pwrmbase(); - - /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */ - soc_config_tco(); - - /* - * Interrupt Configuration Register Programming - * PIRQx to IRQ Programming - */ - pch_interrupt_init(); - - /* Program generic IO Decode Range */ - pch_enable_lpc(); - - /* Program SMBUS_BASE_ADDRESS and Enable it */ - enable_smbus(); - - soc_config_rtc(); -}