soc/intel/cannonlake: Enable common PMC code for CNL
This update changes Cannonlake to use the new common PMC code. This will help to reduce code duplication and streamline code bring up. Change-Id: Ia69fee8985e1c39b0e4b104c51439bca1a5493ac Signed-off-by: Lijian Zhao <lijian.zhao@intel.com> Reviewed-on: https://review.coreboot.org/21062 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
7a357eb865
commit
b3dfcb863c
|
@ -7,6 +7,7 @@ if SOC_INTEL_CANNONLAKE
|
|||
|
||||
config CPU_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
select ACPI_INTEL_HARDWARE_SLEEP_VALUES
|
||||
select ARCH_BOOTBLOCK_X86_32
|
||||
select ARCH_RAMSTAGE_X86_32
|
||||
select ARCH_ROMSTAGE_X86_32
|
||||
|
@ -34,6 +35,7 @@ config CPU_SPECIFIC_OPTIONS
|
|||
select SOC_INTEL_COMMON_BLOCK_GSPI
|
||||
select SOC_INTEL_COMMON_BLOCK_LPSS
|
||||
select SOC_INTEL_COMMON_BLOCK_PCR
|
||||
select SOC_INTEL_COMMON_BLOCK_PMC
|
||||
select SOC_INTEL_COMMON_BLOCK_RTC
|
||||
select SOC_INTEL_COMMON_BLOCK_SA
|
||||
select SOC_INTEL_COMMON_BLOCK_SMBUS
|
||||
|
|
|
@ -9,6 +9,7 @@ bootblock-$(CONFIG_DRIVERS_UART_8250MEM) += uart.c
|
|||
bootblock-y += bootblock/bootblock.c
|
||||
bootblock-y += bootblock/cpu.c
|
||||
bootblock-y += bootblock/pch.c
|
||||
bootblock-y += pmutil.c
|
||||
bootblock-y += bootblock/report_platform.c
|
||||
bootblock-y += gpio.c
|
||||
bootblock-y += gspi.c
|
||||
|
@ -18,6 +19,7 @@ bootblock-$(CONFIG_UART_DEBUG) += uart.c
|
|||
|
||||
romstage-y += gspi.c
|
||||
romstage-y += memmap.c
|
||||
romstage-y += pmutil.c
|
||||
romstage-y += reset.c
|
||||
romstage-y += spi.c
|
||||
romstage-$(CONFIG_UART_DEBUG) += uart.c
|
||||
|
@ -25,12 +27,14 @@ romstage-$(CONFIG_UART_DEBUG) += uart.c
|
|||
ramstage-y += chip.c
|
||||
ramstage-y += gspi.c
|
||||
ramstage-y += memmap.c
|
||||
ramstage-y += pmutil.c
|
||||
ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c
|
||||
ramstage-y += spi.c
|
||||
ramstage-y += systemagent.c
|
||||
ramstage-$(CONFIG_UART_DEBUG) += uart.c
|
||||
|
||||
postcar-y += memmap.c
|
||||
postcar-y += pmutil.c
|
||||
postcar-y += spi.c
|
||||
postcar-$(CONFIG_UART_DEBUG) += uart.c
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <soc/p2sb.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pcr_ids.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/smbus.h>
|
||||
|
||||
#define PCR_PSF3_TO_SHDW_PMC_REG_BASE 0x1400
|
||||
|
|
|
@ -24,6 +24,13 @@
|
|||
struct soc_intel_cannonlake_config {
|
||||
/* GSPI */
|
||||
struct gspi_cfg gspi[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX];
|
||||
|
||||
/* Gpio group routed to each dword of the GPE0 block. Values are
|
||||
* of the form GPP_[A:G] or GPD. */
|
||||
uint8_t gpe0_dw0; /* GPE0_31_0 STS/EN */
|
||||
uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */
|
||||
uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */
|
||||
|
||||
};
|
||||
|
||||
typedef struct soc_intel_cannonlake_config config_t;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SOC_GPE_H_
|
||||
#define _SOC_GPE_H_
|
||||
|
||||
/* GPE_31_0 */
|
||||
#define GPE0_DW0_00 0
|
||||
#define GPE0_DW0_01 1
|
||||
#define GPE0_DW0_02 2
|
||||
#define GPE0_DW0_03 3
|
||||
#define GPE0_DW0_04 4
|
||||
#define GPE0_DW0_05 5
|
||||
#define GPE0_DW0_06 6
|
||||
#define GPE0_DW0_07 7
|
||||
#define GPE0_DW0_08 8
|
||||
#define GPE0_DW0_09 9
|
||||
#define GPE0_DW0_10 10
|
||||
#define GPE0_DW0_11 11
|
||||
#define GPE0_DW0_12 12
|
||||
#define GPE0_DW0_13 13
|
||||
#define GPE0_DW0_14 14
|
||||
#define GPE0_DW0_15 15
|
||||
#define GPE0_DW0_16 16
|
||||
#define GPE0_DW0_17 17
|
||||
#define GPE0_DW0_18 18
|
||||
#define GPE0_DW0_19 19
|
||||
#define GPE0_DW0_20 20
|
||||
#define GPE0_DW0_21 21
|
||||
#define GPE0_DW0_22 22
|
||||
#define GPE0_DW0_23 23
|
||||
#define GPE0_DW0_24 24
|
||||
#define GPE0_DW0_25 25
|
||||
#define GPE0_DW0_26 26
|
||||
#define GPE0_DW0_27 27
|
||||
#define GPE0_DW0_28 28
|
||||
#define GPE0_DW0_29 29
|
||||
#define GPE0_DW0_30 30
|
||||
#define GPE0_DW0_31 31
|
||||
/* GPE_63_32 */
|
||||
#define GPE0_DW1_00 32
|
||||
#define GPE0_DW1_01 33
|
||||
#define GPE0_DW1_02 34
|
||||
#define GPE0_DW1_03 36
|
||||
#define GPE0_DW1_04 36
|
||||
#define GPE0_DW1_05 37
|
||||
#define GPE0_DW1_06 38
|
||||
#define GPE0_DW1_07 39
|
||||
#define GPE0_DW1_08 40
|
||||
#define GPE0_DW1_09 41
|
||||
#define GPE0_DW1_10 42
|
||||
#define GPE0_DW1_11 43
|
||||
#define GPE0_DW1_12 44
|
||||
#define GPE0_DW1_13 45
|
||||
#define GPE0_DW1_14 46
|
||||
#define GPE0_DW1_15 47
|
||||
#define GPE0_DW1_16 48
|
||||
#define GPE0_DW1_17 49
|
||||
#define GPE0_DW1_18 50
|
||||
#define GPE0_DW1_19 51
|
||||
#define GPE0_DW1_20 52
|
||||
#define GPE0_DW1_21 53
|
||||
#define GPE0_DW1_22 54
|
||||
#define GPE0_DW1_23 55
|
||||
#define GPE0_DW1_24 56
|
||||
#define GPE0_DW1_25 57
|
||||
#define GPE0_DW1_26 58
|
||||
#define GPE0_DW1_27 59
|
||||
#define GPE0_DW1_28 60
|
||||
#define GPE0_DW1_29 61
|
||||
#define GPE0_DW1_30 62
|
||||
#define GPE0_DW1_31 63
|
||||
/* GPE_95_64 */
|
||||
#define GPE0_DW2_00 64
|
||||
#define GPE0_DW2_01 65
|
||||
#define GPE0_DW2_02 66
|
||||
#define GPE0_DW2_03 67
|
||||
#define GPE0_DW2_04 68
|
||||
#define GPE0_DW2_05 69
|
||||
#define GPE0_DW2_06 70
|
||||
#define GPE0_DW2_07 71
|
||||
#define GPE0_DW2_08 72
|
||||
#define GPE0_DW2_09 73
|
||||
#define GPE0_DW2_10 74
|
||||
#define GPE0_DW2_11 75
|
||||
#define GPE0_DW2_12 76
|
||||
#define GPE0_DW2_13 77
|
||||
#define GPE0_DW2_14 78
|
||||
#define GPE0_DW2_15 79
|
||||
#define GPE0_DW2_16 80
|
||||
#define GPE0_DW2_17 81
|
||||
#define GPE0_DW2_18 82
|
||||
#define GPE0_DW2_19 83
|
||||
#define GPE0_DW2_20 84
|
||||
#define GPE0_DW2_21 85
|
||||
#define GPE0_DW2_22 86
|
||||
#define GPE0_DW2_23 87
|
||||
#define GPE0_DW2_24 88
|
||||
#define GPE0_DW2_25 89
|
||||
#define GPE0_DW2_26 90
|
||||
#define GPE0_DW2_27 91
|
||||
#define GPE0_DW2_28 92
|
||||
#define GPE0_DW2_29 93
|
||||
#define GPE0_DW2_30 94
|
||||
#define GPE0_DW2_31 95
|
||||
/* GPE_STD */
|
||||
#define GPE0_HOT_PLUG 97
|
||||
#define GPE0_SWGPE 98
|
||||
#define GPE0_TCOSCI 102
|
||||
#define GPE0_SMB_WAK 103
|
||||
#define GPE0_PCI_EXP 105
|
||||
#define GPE0_BATLOW 106
|
||||
#define GPE0_PME 107
|
||||
#define GPE0_ME_SCI 108
|
||||
#define GPE0_PME_B0 109
|
||||
#define GPE0_ESPI 110
|
||||
#define GPE0_GPIO_T2 111
|
||||
#define GPE0_LAN_WAK 112
|
||||
#define GPE0_WADT 114
|
||||
|
||||
#define GPE_MAX GPE0_WADT
|
||||
#endif /* _SOC_GPE_H_ */
|
|
@ -18,22 +18,124 @@
|
|||
#define _SOC_PM_H_
|
||||
|
||||
#include <arch/acpi.h>
|
||||
#include <arch/io.h>
|
||||
#include <soc/gpe.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/smbus.h>
|
||||
#include <soc/pmc.h>
|
||||
|
||||
#define PM1_STS 0x00
|
||||
#define WAK_STS (1 << 15)
|
||||
#define PCIEXPWAK_STS (1 << 14)
|
||||
#define PRBTNOR_STS (1 << 11)
|
||||
#define RTC_STS (1 << 10)
|
||||
#define PWRBTN_STS (1 << 8)
|
||||
#define GBL_STS (1 << 5)
|
||||
#define BM_STS (1 << 4)
|
||||
#define TMROF_STS (1 << 0)
|
||||
#define PM1_EN 0x02
|
||||
#define PCIEXPWAK_DIS (1 << 14)
|
||||
#define RTC_EN (1 << 10)
|
||||
#define PWRBTN_EN (1 << 8)
|
||||
#define GBL_EN (1 << 5)
|
||||
#define TMROF_EN (1 << 0)
|
||||
#define PM1_CNT 0x04
|
||||
#define GBL_RLS (1 << 2)
|
||||
#define BM_RLD (1 << 1)
|
||||
#define SCI_EN (1 << 0)
|
||||
#define PM1_TMR 0x08
|
||||
#define SMI_EN 0x30
|
||||
#define XHCI_SMI_EN (1 << 31)
|
||||
#define ME_SMI_EN (1 << 30)
|
||||
#define ESPI_SMI_EN (1 << 28)
|
||||
#define GPIO_UNLOCK_SMI_EN (1 << 27)
|
||||
#define INTEL_USB2_EN (1 << 18)
|
||||
#define LEGACY_USB2_EN (1 << 17)
|
||||
#define PERIODIC_EN (1 << 14)
|
||||
#define TCO_SMI_EN (1 << 13)
|
||||
#define MCSMI_EN (1 << 11)
|
||||
#define BIOS_RLS (1 << 7)
|
||||
#define SWSMI_TMR_EN (1 << 6)
|
||||
#define APMC_EN (1 << 5)
|
||||
#define SLP_SMI_EN (1 << 4)
|
||||
#define LEGACY_USB_EN (1 << 3)
|
||||
#define BIOS_EN (1 << 2)
|
||||
#define EOS (1 << 1)
|
||||
#define GBL_SMI_EN (1 << 0)
|
||||
#define SMI_STS 0x34
|
||||
#define SMI_STS_BITS 32
|
||||
#define XHCI_SMI_STS_BIT 31
|
||||
#define ME_SMI_STS_BIT 30
|
||||
#define ESPI_SMI_STS_BIT 28
|
||||
#define GPIO_UNLOCK_SMI_STS_BIT 27
|
||||
#define SPI_SMI_STS_BIT 26
|
||||
#define SCC_SMI_STS_BIT 25
|
||||
#define MONITOR_STS_BIT 21
|
||||
#define PCI_EXP_SMI_STS_BIT 20
|
||||
#define SMBUS_SMI_STS_BIT 16
|
||||
#define SERIRQ_SMI_STS_BIT 15
|
||||
#define PERIODIC_STS_BIT 14
|
||||
#define TCO_STS_BIT 13
|
||||
#define DEVMON_STS_BIT 12
|
||||
#define MCSMI_STS_BIT 11
|
||||
#define GPIO_STS_BIT 10
|
||||
#define GPE0_STS_BIT 9
|
||||
#define PM1_STS_BIT 8
|
||||
#define SWSMI_TMR_STS_BIT 6
|
||||
#define APM_STS_BIT 5
|
||||
#define SMI_ON_SLP_EN_STS_BIT 4
|
||||
#define LEGACY_USB_STS_BIT 3
|
||||
#define BIOS_STS_BIT 2
|
||||
#define GPE_CNTL 0x42
|
||||
#define SWGPE_CTRL (1 << 1)
|
||||
#define DEVACT_STS 0x44
|
||||
#define PM2_CNT 0x50
|
||||
|
||||
|
||||
#define GPE0_REG_MAX 4
|
||||
#define GPE0_REG_SIZE 32
|
||||
#define GPE0_STS(x) (0x60 + ((x) * 4))
|
||||
#define GPE_31_0 0 /* 0x60/0x70 = GPE[31:0] */
|
||||
#define GPE_63_32 1 /* 0x64/0x74 = GPE[63:32] */
|
||||
#define GPE_95_64 2 /* 0x68/0x78 = GPE[95:64] */
|
||||
#define GPE_STD 3 /* 0x6c/0x7c = Standard GPE */
|
||||
#define GPE_STS_RSVD GPE_STD
|
||||
#define WADT_STS (1 << 18)
|
||||
#define GPIO_T2_STS (1 << 15)
|
||||
#define ESPI_STS (1 << 14)
|
||||
#define PME_B0_STS (1 << 13)
|
||||
#define ME_SCI_STS (1 << 12)
|
||||
#define PME_STS (1 << 11)
|
||||
#define BATLOW_STS (1 << 10)
|
||||
#define PCI_EXP_STS (1 << 9)
|
||||
#define SMB_WAK_STS (1 << 7)
|
||||
#define TCOSCI_STS (1 << 6)
|
||||
#define SWGPE_STS (1 << 2)
|
||||
#define HOT_PLUG_STS (1 << 1)
|
||||
#define GPE0_EN(x) (0x70 + ((x) * 4))
|
||||
#define PME_B0_EN (1 << 13)
|
||||
#define WADT_EN (1 << 18)
|
||||
#define GPIO_T2_EN (1 << 15)
|
||||
#define ESPI_EN (1 << 14)
|
||||
#define PME_B0_EN (1 << 13)
|
||||
#define ME_SCI_EN (1 << 12)
|
||||
#define PME_EN (1 << 11)
|
||||
#define BATLOW_EN (1 << 10)
|
||||
#define PCI_EXP_EN (1 << 9)
|
||||
#define TCOSCI_EN (1 << 6)
|
||||
#define SWGPE_EN (1 << 2)
|
||||
#define HOT_PLUG_EN (1 << 1)
|
||||
|
||||
#define EN_BLOCK 3
|
||||
|
||||
/*
|
||||
* Enable SMI generation:
|
||||
* - on APMC writes (io 0xb2)
|
||||
* - on writes to SLP_EN (sleep states)
|
||||
* - on writes to GBL_RLS (bios commands)
|
||||
* - on eSPI events (does nothing on LPC systems)
|
||||
* No SMIs:
|
||||
* - on microcontroller writes (io 0x62/0x66)
|
||||
* - on TCO events
|
||||
*/
|
||||
#define ENABLE_SMI_PARAMS \
|
||||
(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS)
|
||||
|
||||
|
@ -51,6 +153,16 @@ struct chipset_power_state {
|
|||
uint32_t prev_sleep_state;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct chipset_power_state *fill_power_state(void);
|
||||
/* Return the selected ACPI SCI IRQ */
|
||||
int acpi_sci_irq(void);
|
||||
|
||||
/* Get base address PMC memory mapped registers. */
|
||||
uint8_t *pmc_mmio_regs(void);
|
||||
|
||||
/* Get base address of TCO I/O registers. */
|
||||
uint16_t smbus_tco_regs(void);
|
||||
|
||||
/* Set the DISB after DRAM init */
|
||||
void pmc_set_disb(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,9 +71,9 @@
|
|||
#define SMI_LOCK (1 << 4)
|
||||
#define RTC_BATTERY_DEAD (1 << 2)
|
||||
|
||||
#define ETR3 0x1048
|
||||
#define ETR3_CF9LOCK (1 << 31)
|
||||
#define ETR3_CF9GR (1 << 20)
|
||||
#define ETR 0x1048
|
||||
#define CF9_LOCK (1 << 31)
|
||||
#define CF9_GLB_RST (1 << 20)
|
||||
|
||||
#define SSML 0x104C
|
||||
#define SSML_SSL_DS (0 << 0)
|
||||
|
@ -85,6 +85,8 @@
|
|||
#define SSMD 0x1054
|
||||
#define SSMD_SSD_MASK (0xffff << 0)
|
||||
|
||||
#define PRSTS 0x1810
|
||||
|
||||
#define S3_PWRGATE_POL 0x1828
|
||||
#define S3DC_GATE_SUS (1 << 1)
|
||||
#define S3AC_GATE_SUS (1 << 0)
|
||||
|
@ -109,11 +111,9 @@
|
|||
#define PCH2CPU_TT_EN (1 << 26)
|
||||
|
||||
#define PCH_PWRM_ACPI_TMR_CTL 0x18FC
|
||||
#define GPIO_CFG 0x1920
|
||||
#define GPE0_DWX_MASK 0xf
|
||||
#define GPE0_DW0_SHIFT 0
|
||||
#define GPE0_DW1_SHIFT 4
|
||||
#define GPE0_DW2_SHIFT 8
|
||||
#define GPIO_GPE_CFG 0x1920
|
||||
#define GPE0_DWX_MASK 0xf
|
||||
#define GPE0_DW_SHIFT(x) (4*(x))
|
||||
|
||||
#define GBLRST_CAUSE0 0x1924
|
||||
#define GBLRST_CAUSE0_THERMTRIP (1 << 5)
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
|
||||
/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */
|
||||
#define TCO1_STS 0x04
|
||||
#define TCO_TIMEOUT (1 << 3)
|
||||
#define TCO2_STS 0x06
|
||||
#define TCO2_STS_SECOND_TO 0x02
|
||||
#define TCO2_STS_BOOT 0x04
|
||||
#define TCO2_STS_SECOND_TO (1 << 1)
|
||||
#define TCO1_CNT 0x08
|
||||
#define TCO_LOCK (1 << 12)
|
||||
#define TCO_TMR_HLT (1 << 11)
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helper functions for dealing with power management registers
|
||||
* and the differences between PCH variants.
|
||||
*/
|
||||
|
||||
#define __SIMPLE_DEVICE__
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <console/console.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <halt.h>
|
||||
#include <rules.h>
|
||||
#include <stdlib.h>
|
||||
#include <soc/gpe.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/smbus.h>
|
||||
#include <timer.h>
|
||||
#include "chip.h"
|
||||
|
||||
/*
|
||||
* SMI
|
||||
*/
|
||||
|
||||
const char *const *soc_smi_sts_array(size_t *a)
|
||||
{
|
||||
static const char *const smi_sts_bits[] = {
|
||||
[BIOS_STS_BIT] = "BIOS",
|
||||
[LEGACY_USB_STS_BIT] = "LEGACY_USB",
|
||||
[SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI",
|
||||
[APM_STS_BIT] = "APM",
|
||||
[SWSMI_TMR_STS_BIT] = "SWSMI_TMR",
|
||||
[PM1_STS_BIT] = "PM1",
|
||||
[GPE0_STS_BIT] = "GPE0",
|
||||
[GPIO_STS_BIT] = "GPI",
|
||||
[MCSMI_STS_BIT] = "MCSMI",
|
||||
[DEVMON_STS_BIT] = "DEVMON",
|
||||
[TCO_STS_BIT] = "TCO",
|
||||
[PERIODIC_STS_BIT] = "PERIODIC",
|
||||
[SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI",
|
||||
[SMBUS_SMI_STS_BIT] = "SMBUS_SMI",
|
||||
[PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI",
|
||||
[MONITOR_STS_BIT] = "MONITOR",
|
||||
[SPI_SMI_STS_BIT] = "SPI",
|
||||
[GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK",
|
||||
[ESPI_SMI_STS_BIT] = "ESPI_SMI",
|
||||
};
|
||||
|
||||
*a = ARRAY_SIZE(smi_sts_bits);
|
||||
return smi_sts_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
* TCO
|
||||
*/
|
||||
|
||||
const char *const *soc_tco_sts_array(size_t *a)
|
||||
{
|
||||
static const char *const tco_sts_bits[] = {
|
||||
[0] = "NMI2SMI",
|
||||
[1] = "SW_TCO",
|
||||
[2] = "TCO_INT",
|
||||
[3] = "TIMEOUT",
|
||||
[7] = "NEWCENTURY",
|
||||
[8] = "BIOSWR",
|
||||
[9] = "DMISCI",
|
||||
[10] = "DMISMI",
|
||||
[12] = "DMISERR",
|
||||
[13] = "SLVSEL",
|
||||
[16] = "INTRD_DET",
|
||||
[17] = "SECOND_TO",
|
||||
[18] = "BOOT",
|
||||
[20] = "SMLINK_SLV"
|
||||
};
|
||||
|
||||
*a = ARRAY_SIZE(tco_sts_bits);
|
||||
return tco_sts_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPE0
|
||||
*/
|
||||
|
||||
const char *const *soc_gpe_sts_array(size_t *a)
|
||||
{
|
||||
static const char *const gpe_sts_bits[] = {
|
||||
[1] = "HOTPLUG",
|
||||
[2] = "SWGPE",
|
||||
[6] = "TCO_SCI",
|
||||
[7] = "SMB_WAK",
|
||||
[9] = "PCI_EXP",
|
||||
[10] = "BATLOW",
|
||||
[11] = "PME",
|
||||
[12] = "ME",
|
||||
[13] = "PME_B0",
|
||||
[14] = "eSPI",
|
||||
[15] = "GPIO Tier-2",
|
||||
[16] = "LAN_WAKE",
|
||||
[18] = "WADT"
|
||||
};
|
||||
|
||||
*a = ARRAY_SIZE(gpe_sts_bits);
|
||||
return gpe_sts_bits;
|
||||
}
|
||||
|
||||
int acpi_sci_irq(void)
|
||||
{
|
||||
int scis = pci_read_config32(PCH_DEV_PMC, ACTL) & SCI_IRQ_SEL;
|
||||
int sci_irq = 9;
|
||||
|
||||
/* Determine how SCI is routed. */
|
||||
switch (scis) {
|
||||
case SCIS_IRQ9:
|
||||
case SCIS_IRQ10:
|
||||
case SCIS_IRQ11:
|
||||
sci_irq = scis - SCIS_IRQ9 + 9;
|
||||
break;
|
||||
case SCIS_IRQ20:
|
||||
case SCIS_IRQ21:
|
||||
case SCIS_IRQ22:
|
||||
case SCIS_IRQ23:
|
||||
sci_irq = scis - SCIS_IRQ20 + 20;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n");
|
||||
sci_irq = 9;
|
||||
break;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq);
|
||||
return sci_irq;
|
||||
}
|
||||
|
||||
uint8_t *pmc_mmio_regs(void)
|
||||
{
|
||||
uint32_t reg32;
|
||||
|
||||
reg32 = pci_read_config32(PCH_DEV_PMC, PWRMBASE);
|
||||
|
||||
return (void *)(uintptr_t)ALIGN_DOWN(reg32, 4 * KiB);
|
||||
}
|
||||
|
||||
uint16_t smbus_tco_regs(void)
|
||||
{
|
||||
uint16_t reg16;
|
||||
|
||||
reg16 = pci_read_config16(PCH_DEV_SMBUS, TCOBASE);
|
||||
|
||||
return ALIGN_DOWN(reg16, 0x20);
|
||||
}
|
||||
|
||||
uint32_t soc_reset_tco_status(void)
|
||||
{
|
||||
u16 tco1_sts;
|
||||
u16 tco2_sts;
|
||||
u16 tcobase;
|
||||
|
||||
tcobase = smbus_tco_regs();
|
||||
|
||||
/* TCO Status 2 register */
|
||||
tco2_sts = inw(tcobase + TCO2_STS);
|
||||
tco2_sts |= TCO2_STS_SECOND_TO;
|
||||
outw(tco2_sts, tcobase + TCO2_STS);
|
||||
|
||||
/* TCO Status 1 register */
|
||||
tco1_sts = inw(tcobase + TCO1_STS);
|
||||
|
||||
/* Clear SECOND_TO_STS bit */
|
||||
if (tco2_sts & TCO2_STS_SECOND_TO)
|
||||
outw(tco2_sts & ~TCO2_STS_SECOND_TO, tcobase + TCO2_STS);
|
||||
|
||||
return (tco2_sts << 16) | tco1_sts;
|
||||
}
|
||||
|
||||
uintptr_t soc_read_pmc_base(void)
|
||||
{
|
||||
return (uintptr_t)pmc_mmio_regs();
|
||||
}
|
||||
|
||||
void soc_get_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
|
||||
{
|
||||
DEVTREE_CONST struct soc_intel_cannonlake_config *config;
|
||||
|
||||
/* Look up the device in devicetree */
|
||||
DEVTREE_CONST struct device *dev = dev_find_slot(0, PCH_DEVFN_PMC);
|
||||
if (!dev || !dev->chip_info) {
|
||||
printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
|
||||
}
|
||||
config = dev->chip_info;
|
||||
|
||||
/* Assign to out variable */
|
||||
*dw0 = config->gpe0_dw0;
|
||||
*dw1 = config->gpe0_dw1;
|
||||
*dw2 = config->gpe0_dw2;
|
||||
}
|
|
@ -18,14 +18,94 @@
|
|||
#include <arch/io.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <string.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
|
||||
static struct chipset_power_state power_state CAR_GLOBAL;
|
||||
|
||||
/* Fill power state structure from ACPI PM registers */
|
||||
struct chipset_power_state *fill_power_state(void)
|
||||
static void migrate_power_state(int is_recovery)
|
||||
{
|
||||
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
|
||||
struct chipset_power_state *ps_cbmem;
|
||||
struct chipset_power_state *ps_car;
|
||||
|
||||
return ps;
|
||||
ps_car = car_get_var_ptr(&power_state);
|
||||
ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
|
||||
|
||||
if (ps_cbmem == NULL) {
|
||||
printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
|
||||
return;
|
||||
}
|
||||
memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
|
||||
}
|
||||
|
||||
ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state)
|
||||
|
||||
static inline int deep_s3_enabled(void)
|
||||
{
|
||||
uint32_t deep_s3_pol;
|
||||
|
||||
deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL);
|
||||
return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS));
|
||||
}
|
||||
|
||||
/* Return 0, 3, or 5 to indicate the previous sleep state. */
|
||||
int soc_prev_sleep_state(const struct chipset_power_state *ps,
|
||||
int prev_sleep_state)
|
||||
{
|
||||
|
||||
/*
|
||||
* Check for any power failure to determine if this a wake from
|
||||
* S5 because the PCH does not set the WAK_STS bit when waking
|
||||
* from a true G3 state.
|
||||
*/
|
||||
if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR))
|
||||
prev_sleep_state = ACPI_S5;
|
||||
|
||||
/*
|
||||
* If waking from S3 determine if deep S3 is enabled. If not,
|
||||
* need to check both deep sleep well and normal suspend well.
|
||||
* Otherwise just check deep sleep well.
|
||||
*/
|
||||
if (prev_sleep_state == ACPI_S3) {
|
||||
/* PWR_FLR represents deep sleep power well loss. */
|
||||
uint32_t mask = PWR_FLR;
|
||||
|
||||
/* If deep s3 isn't enabled check the suspend well too. */
|
||||
if (!deep_s3_enabled())
|
||||
mask |= SUS_PWR_FLR;
|
||||
|
||||
if (ps->gen_pmcon_b & mask)
|
||||
prev_sleep_state = ACPI_S5;
|
||||
}
|
||||
|
||||
return prev_sleep_state;
|
||||
}
|
||||
|
||||
void soc_fill_power_state(struct chipset_power_state *ps)
|
||||
{
|
||||
uint16_t tcobase;
|
||||
uint8_t *pmc;
|
||||
|
||||
tcobase = smbus_tco_regs();
|
||||
|
||||
ps->tco1_sts = inw(tcobase + TCO1_STS);
|
||||
ps->tco2_sts = inw(tcobase + TCO2_STS);
|
||||
|
||||
printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n",
|
||||
ps->tco1_sts, ps->tco2_sts);
|
||||
|
||||
pmc = pmc_mmio_regs();
|
||||
ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A);
|
||||
ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B);
|
||||
ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
|
||||
ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
|
||||
|
||||
printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
|
||||
ps->gen_pmcon_a, ps->gen_pmcon_b);
|
||||
|
||||
printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
|
||||
ps->gblrst_cause[0], ps->gblrst_cause[1]);
|
||||
}
|
||||
|
|
|
@ -14,30 +14,33 @@
|
|||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <arch/early_variables.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <fsp/util.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <memory_info.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/romstage.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
static struct chipset_power_state power_state CAR_GLOBAL;
|
||||
|
||||
asmlinkage void car_stage_entry(void)
|
||||
{
|
||||
bool s3wake;
|
||||
struct postcar_frame pcf;
|
||||
uintptr_t top_of_ram;
|
||||
struct chipset_power_state *ps;
|
||||
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
|
||||
|
||||
console_init();
|
||||
|
||||
/* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */
|
||||
systemagent_early_init();
|
||||
|
||||
ps = fill_power_state();
|
||||
timestamp_add_now(TS_START_ROMSTAGE);
|
||||
s3wake = ps->prev_sleep_state == ACPI_S3;
|
||||
s3wake = pmc_fill_power_state(ps) == ACPI_S3;
|
||||
fsp_memory_init(s3wake);
|
||||
if (postcar_frame_init(&pcf, 1 * KiB))
|
||||
die("Unable to initialize postcar frame.\n");
|
||||
|
|
Loading…
Reference in New Issue