lynxpoint: Add power management helper functions
There are subtle yet significant differences in some of the registers in the power management region between LynxPoint-H and LynxPoint-LP. In order to reduce code that is accessing these registers and would need special cases this adds a number of helper functions that can be used in both ramstage and SMM. This commit just adds the new functions, subsequent commits will start to use them. Change-Id: I411da75da519f5b3198a408078cbf3114e426992 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/2813 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
1ad5564dd6
commit
55cdf55190
|
@ -44,8 +44,9 @@ ramstage-$(CONFIG_ELOG) += elog.c
|
|||
ramstage-y += spi.c
|
||||
smm-$(CONFIG_SPI_FLASH_SMM) += spi.c
|
||||
|
||||
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
|
||||
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c
|
||||
smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c finalize.c pch.c
|
||||
smm-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c
|
||||
|
||||
romstage-y += early_usb.c early_smbus.c early_me.c me_status.c early_pch.c
|
||||
romstage-$(CONFIG_USBDEBUG) += usb_debug.c
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#define GPIO_SER_BLINK_CS 0x20
|
||||
#define GPIO_SER_BLINK_DATA 0x24
|
||||
#define GPIO_ROUTE(set) (0x30 + ((set) * 4))
|
||||
#define GPIO_ALT_GPI_SMI_STS 0x50
|
||||
#define GPIO_ALT_GPI_SMI_EN 0x54
|
||||
#define GPIO_RESET(set) (0x60 + ((set) * 4))
|
||||
#define GPIO_GLOBAL_CONFIG 0x7c
|
||||
#define GPIO_IRQ_IS(set) (0x80 + ((set) * 4))
|
||||
|
|
|
@ -132,6 +132,32 @@ int pch_silicon_type(void);
|
|||
int pch_is_lp(void);
|
||||
u16 get_pmbase(void);
|
||||
u16 get_gpiobase(void);
|
||||
|
||||
/* Power Management register handling in pmutil.c */
|
||||
/* PM1_CNT */
|
||||
void enable_pm1_control(u32 mask);
|
||||
void disable_pm1_control(u32 mask);
|
||||
/* PM1 */
|
||||
u16 clear_pm1_status(void);
|
||||
void enable_pm1(u32 mask);
|
||||
u32 clear_smi_status(void);
|
||||
/* SMI */
|
||||
void enable_smi(u32 mask);
|
||||
void disable_smi(u32 mask);
|
||||
/* ALT_GP_SMI */
|
||||
u32 clear_alt_smi_status(void);
|
||||
void enable_alt_smi(u32 mask);
|
||||
/* TCO */
|
||||
u32 clear_tco_status(void);
|
||||
void enable_tco_sci(void);
|
||||
/* GPE0 */
|
||||
u32 clear_gpe_status(void);
|
||||
void clear_gpe_enable(void);
|
||||
void enable_all_gpe(u32 set1, u32 set2, u32 set3, u32 set4);
|
||||
void disable_all_gpe(void);
|
||||
void enable_gpe(u32 mask);
|
||||
void disable_gpe(u32 mask);
|
||||
|
||||
#if !defined(__PRE_RAM__) && !defined(__SMM__)
|
||||
#include <device/device.h>
|
||||
#include <arch/acpi.h>
|
||||
|
@ -590,10 +616,12 @@ unsigned get_gpios(const int *gpio_num_array);
|
|||
#define TCOSCI_STS (1 << 6)
|
||||
#define SWGPE_STS (1 << 2)
|
||||
#define HOT_PLUG_STS (1 << 1)
|
||||
#define GPE0_STS_2 0x24
|
||||
#define GPE0_EN 0x28
|
||||
#define PME_B0_EN (1 << 13)
|
||||
#define PME_EN (1 << 11)
|
||||
#define TCOSCI_EN (1 << 6)
|
||||
#define GPE0_EN_2 0x2c
|
||||
#define SMI_EN 0x30
|
||||
#define INTEL_USB2_EN (1 << 18) // Intel-Specific USB2 SMI logic
|
||||
#define LEGACY_USB2_EN (1 << 17) // Legacy USB2 SMI logic
|
||||
|
@ -618,6 +646,18 @@ unsigned get_gpios(const int *gpio_num_array);
|
|||
#define TCO1_STS 0x64
|
||||
#define DMISCI_STS (1 << 9)
|
||||
#define TCO2_STS 0x66
|
||||
#define ALT_GP_SMI_EN2 0x5c
|
||||
#define ALT_GP_SMI_STS2 0x5e
|
||||
|
||||
/* Lynxpoint LP */
|
||||
#define LP_GPE0_STS_1 0x80 /* GPIO 0-31 */
|
||||
#define LP_GPE0_STS_2 0x84 /* GPIO 32-63 */
|
||||
#define LP_GPE0_STS_3 0x88 /* GPIO 64-94 */
|
||||
#define LP_GPE0_STS_4 0x8c /* Standard GPE */
|
||||
#define LP_GPE0_EN_1 0x90
|
||||
#define LP_GPE0_EN_2 0x94
|
||||
#define LP_GPE0_EN_3 0x98
|
||||
#define LP_GPE0_EN_4 0x9c
|
||||
|
||||
/*
|
||||
* SPI Opcode Menu setup for SPIBAR lockdown
|
||||
|
|
|
@ -0,0 +1,567 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 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.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helper functions for dealing with power management registers
|
||||
* and the differences between LynxPoint-H and LynxPoint-LP.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#ifdef __SMM__
|
||||
#include <arch/romcc_io.h>
|
||||
#include <device/pci_def.h>
|
||||
#else /* !__SMM__ */
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#endif
|
||||
|
||||
#include <console/console.h>
|
||||
#include "pch.h"
|
||||
|
||||
#if CONFIG_INTEL_LYNXPOINT_LP
|
||||
#include "lp_gpio.h"
|
||||
#endif
|
||||
|
||||
/* These defines are here to handle the LP variant code dynamically. If these
|
||||
* values are defined in lp_gpio.h but when a non-LP board is being built, the
|
||||
* build will fail. */
|
||||
#define GPIO_ALT_GPI_SMI_STS 0x50
|
||||
#define GPIO_ALT_GPI_SMI_EN 0x54
|
||||
|
||||
/* Print status bits with descriptive names */
|
||||
static void print_status_bits(u32 status, const char *bit_names[])
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
for (i=31; i>=0; i--) {
|
||||
if (status & (1 << i)) {
|
||||
if (bit_names[i])
|
||||
printk(BIOS_DEBUG, "%s ", bit_names[i]);
|
||||
else
|
||||
printk(BIOS_DEBUG, "BIT%d ", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Print status bits as GPIO numbers */
|
||||
static void print_gpio_status(u32 status, int start)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
for (i=31; i>=0; i--) {
|
||||
if (status & (1 << i))
|
||||
printk(BIOS_DEBUG, "GPIO%d ", start + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PM1_CNT
|
||||
*/
|
||||
|
||||
/* Enable events in PM1 control register */
|
||||
void enable_pm1_control(u32 mask)
|
||||
{
|
||||
u32 pm1_cnt = inl(get_pmbase() + PM1_CNT);
|
||||
pm1_cnt |= mask;
|
||||
outl(pm1_cnt, get_pmbase() + PM1_CNT);
|
||||
}
|
||||
|
||||
/* Disable events in PM1 control register */
|
||||
void disable_pm1_control(u32 mask)
|
||||
{
|
||||
u32 pm1_cnt = inl(get_pmbase() + PM1_CNT);
|
||||
pm1_cnt &= ~mask;
|
||||
outl(pm1_cnt, get_pmbase() + PM1_CNT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PM1
|
||||
*/
|
||||
|
||||
/* Clear and return PM1 status register */
|
||||
static u16 reset_pm1_status(void)
|
||||
{
|
||||
u16 pm1_sts = inw(get_pmbase() + PM1_STS);
|
||||
outw(pm1_sts, get_pmbase() + PM1_STS);
|
||||
return pm1_sts;
|
||||
}
|
||||
|
||||
/* Print PM1 status bits */
|
||||
static u16 print_pm1_status(u16 pm1_sts)
|
||||
{
|
||||
const char *pm1_sts_bits[] = {
|
||||
[0] = "TMROF",
|
||||
[4] = "BM",
|
||||
[5] = "GBL",
|
||||
[8] = "PWRBTN",
|
||||
[10] = "RTC",
|
||||
[11] = "PRBTNOR",
|
||||
[14] = "PCIEXPWAK",
|
||||
[15] = "WAK",
|
||||
};
|
||||
|
||||
if (!pm1_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_SPEW, "PM1_STS: ");
|
||||
print_status_bits(pm1_sts, pm1_sts_bits);
|
||||
printk(BIOS_SPEW, "\n");
|
||||
|
||||
return pm1_sts;
|
||||
}
|
||||
|
||||
/* Print, clear, and return PM1 status */
|
||||
u16 clear_pm1_status(void)
|
||||
{
|
||||
return print_pm1_status(reset_pm1_status());
|
||||
}
|
||||
|
||||
/* Enable PM1 event */
|
||||
void enable_pm1(u32 mask)
|
||||
{
|
||||
u32 pm1_en = inl(get_pmbase() + PM1_EN);
|
||||
pm1_en |= mask;
|
||||
outl(pm1_en, get_pmbase() + PM1_EN);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SMI
|
||||
*/
|
||||
|
||||
/* Clear and return SMI status register */
|
||||
static u32 reset_smi_status(void)
|
||||
{
|
||||
u32 smi_sts = inl(get_pmbase() + SMI_STS);
|
||||
outl(smi_sts, get_pmbase() + SMI_STS);
|
||||
return smi_sts;
|
||||
}
|
||||
|
||||
/* Print SMI status bits */
|
||||
static u32 print_smi_status(u32 smi_sts)
|
||||
{
|
||||
const char *smi_sts_bits[] = {
|
||||
[2] = "BIOS",
|
||||
[3] = "LEGACY_USB",
|
||||
[4] = "SLP_SMI",
|
||||
[5] = "APM",
|
||||
[6] = "SWSMI_TMR",
|
||||
[8] = "PM1",
|
||||
[9] = "GPE0",
|
||||
[10] = "GPI",
|
||||
[11] = "MCSMI",
|
||||
[12] = "DEVMON",
|
||||
[13] = "TCO",
|
||||
[14] = "PERIODIC",
|
||||
[15] = "SERIRQ_SMI",
|
||||
[16] = "SMBUS_SMI",
|
||||
[17] = "LEGACY_USB2",
|
||||
[18] = "INTEL_USB2",
|
||||
[20] = "PCI_EXP_SMI",
|
||||
[21] = "MONITOR",
|
||||
[26] = "SPI",
|
||||
[27] = "GPIO_UNLOCK"
|
||||
};
|
||||
|
||||
if (!smi_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_DEBUG, "SMI_STS: ");
|
||||
print_status_bits(smi_sts, smi_sts_bits);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return smi_sts;
|
||||
}
|
||||
|
||||
/* Print, clear, and return SMI status */
|
||||
u32 clear_smi_status(void)
|
||||
{
|
||||
return print_smi_status(reset_smi_status());
|
||||
}
|
||||
|
||||
/* Enable SMI event */
|
||||
void enable_smi(u32 mask)
|
||||
{
|
||||
u32 smi_en = inl(get_pmbase() + SMI_EN);
|
||||
smi_en |= mask;
|
||||
outl(smi_en, get_pmbase() + SMI_EN);
|
||||
}
|
||||
|
||||
/* Disable SMI event */
|
||||
void disable_smi(u32 mask)
|
||||
{
|
||||
u32 smi_en = inl(get_pmbase() + SMI_EN);
|
||||
smi_en &= ~mask;
|
||||
outl(smi_en, get_pmbase() + SMI_EN);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ALT_GP_SMI
|
||||
*/
|
||||
|
||||
/* Clear GPIO SMI status and return events that are enabled and active */
|
||||
static u32 reset_alt_smi_status(void)
|
||||
{
|
||||
u32 alt_sts, alt_en;
|
||||
|
||||
if (pch_is_lp()) {
|
||||
/* LynxPoint-LP moves this to GPIO region as dword */
|
||||
alt_sts = inl(get_gpiobase() + GPIO_ALT_GPI_SMI_STS);
|
||||
outl(alt_sts, get_gpiobase() + GPIO_ALT_GPI_SMI_STS);
|
||||
|
||||
alt_en = inl(get_gpiobase() + GPIO_ALT_GPI_SMI_EN);
|
||||
} else {
|
||||
u16 pmbase = get_pmbase();
|
||||
|
||||
/* LynxPoint-H adds a second enable/status word */
|
||||
alt_sts = inw(pmbase + ALT_GP_SMI_STS2);
|
||||
outw(alt_sts & 0xffff, pmbase + ALT_GP_SMI_STS2);
|
||||
|
||||
alt_sts <<= 16;
|
||||
alt_sts |= inw(pmbase + ALT_GP_SMI_STS);
|
||||
outw(alt_sts & 0xffff, pmbase + ALT_GP_SMI_STS);
|
||||
|
||||
alt_en = inw(pmbase + ALT_GP_SMI_EN2);
|
||||
alt_en <<= 16;
|
||||
alt_en |= inw(pmbase + ALT_GP_SMI_EN);
|
||||
}
|
||||
|
||||
/* Only report enabled events */
|
||||
return alt_sts & alt_en;
|
||||
}
|
||||
|
||||
/* Print GPIO SMI status bits */
|
||||
static u32 print_alt_smi_status(u32 alt_sts)
|
||||
{
|
||||
if (!alt_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_DEBUG, "ALT_STS: ");
|
||||
|
||||
if (pch_is_lp()) {
|
||||
/* First 16 events are GPIO 32-47 */
|
||||
print_gpio_status(alt_sts & 0xffff, 32);
|
||||
} else {
|
||||
const char *alt_sts_bits_high[] = {
|
||||
[0] = "GPIO17",
|
||||
[1] = "GPIO19",
|
||||
[2] = "GPIO21",
|
||||
[3] = "GPIO22",
|
||||
[4] = "GPIO43",
|
||||
[5] = "GPIO56",
|
||||
[6] = "GPIO57",
|
||||
[7] = "GPIO60",
|
||||
};
|
||||
|
||||
/* First 16 events are GPIO 0-15 */
|
||||
print_gpio_status(alt_sts & 0xffff, 0);
|
||||
print_status_bits(alt_sts >> 16, alt_sts_bits_high);
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return alt_sts;
|
||||
}
|
||||
|
||||
/* Print, clear, and return GPIO SMI status */
|
||||
u32 clear_alt_smi_status(void)
|
||||
{
|
||||
return print_alt_smi_status(reset_alt_smi_status());
|
||||
}
|
||||
|
||||
/* Enable GPIO SMI events */
|
||||
void enable_alt_smi(u32 mask)
|
||||
{
|
||||
if (pch_is_lp()) {
|
||||
u32 alt_en;
|
||||
|
||||
alt_en = inl(get_gpiobase() + GPIO_ALT_GPI_SMI_EN);
|
||||
alt_en |= mask;
|
||||
outl(alt_en, get_gpiobase() + GPIO_ALT_GPI_SMI_EN);
|
||||
} else {
|
||||
u16 pmbase = get_pmbase();
|
||||
u16 alt_en;
|
||||
|
||||
/* Lower enable register */
|
||||
alt_en = inw(pmbase + ALT_GP_SMI_EN);
|
||||
alt_en |= mask & 0xffff;
|
||||
outw(alt_en, pmbase + ALT_GP_SMI_EN);
|
||||
|
||||
/* Upper enable register */
|
||||
alt_en = inw(pmbase + ALT_GP_SMI_EN2);
|
||||
alt_en |= (mask >> 16) & 0xffff;
|
||||
outw(alt_en, pmbase + ALT_GP_SMI_EN2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* TCO
|
||||
*/
|
||||
|
||||
/* Clear TCO status and return events that are enabled and active */
|
||||
static u32 reset_tco_status(void)
|
||||
{
|
||||
u32 tcobase = get_pmbase() + 0x60;
|
||||
u32 tco_sts = inl(tcobase + 0x04);
|
||||
u32 tco_en = inl(get_pmbase() + 0x68);
|
||||
|
||||
/* Don't clear BOOT_STS before SECOND_TO_STS */
|
||||
outl(tco_sts & ~(1 << 18), tcobase + 0x04);
|
||||
|
||||
/* Clear BOOT_STS */
|
||||
if (tco_sts & (1 << 18))
|
||||
outl(tco_sts & (1 << 18), tcobase + 0x04);
|
||||
|
||||
return tco_sts & tco_en;
|
||||
}
|
||||
|
||||
/* Print TCO status bits */
|
||||
static u32 print_tco_status(u32 tco_sts)
|
||||
{
|
||||
const char *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"
|
||||
};
|
||||
|
||||
if (!tco_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_DEBUG, "TCO_STS: ");
|
||||
print_status_bits(tco_sts, tco_sts_bits);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return tco_sts;
|
||||
}
|
||||
|
||||
/* Print, clear, and return TCO status */
|
||||
u32 clear_tco_status(void)
|
||||
{
|
||||
return print_tco_status(reset_tco_status());
|
||||
}
|
||||
|
||||
/* Enable TCO SCI */
|
||||
void enable_tco_sci(void)
|
||||
{
|
||||
u16 gpe0_sts = pch_is_lp() ? LP_GPE0_STS_4 : GPE0_STS;
|
||||
|
||||
/* Clear pending events */
|
||||
outl(get_pmbase() + gpe0_sts, TCOSCI_STS);
|
||||
|
||||
/* Enable TCO SCI events */
|
||||
enable_gpe(TCOSCI_EN);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GPE0
|
||||
*/
|
||||
|
||||
/* Clear a GPE0 status and return events that are enabled and active */
|
||||
static u32 reset_gpe_status(u16 sts_reg, u16 en_reg)
|
||||
{
|
||||
u32 gpe0_sts = inl(get_pmbase() + sts_reg);
|
||||
u32 gpe0_en = inl(get_pmbase() + en_reg);
|
||||
|
||||
outl(gpe0_sts, get_pmbase() + sts_reg);
|
||||
|
||||
/* Only report enabled events */
|
||||
return gpe0_sts & gpe0_en;
|
||||
}
|
||||
|
||||
/* Print GPE0 status bits */
|
||||
static u32 print_gpe_status(u32 gpe0_sts, const char *bit_names[])
|
||||
{
|
||||
if (!gpe0_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_DEBUG, "GPE0_STS: ");
|
||||
print_status_bits(gpe0_sts, bit_names);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return gpe0_sts;
|
||||
}
|
||||
|
||||
/* Print GPE0 GPIO status bits */
|
||||
static u32 print_gpe_gpio(u32 gpe0_sts, int start)
|
||||
{
|
||||
if (!gpe0_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_DEBUG, "GPE0_STS: ");
|
||||
print_gpio_status(gpe0_sts, start);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return gpe0_sts;
|
||||
}
|
||||
|
||||
/* Print, clear, and return LynxPoint-H GPE0 status */
|
||||
static u32 clear_lpt_gpe_status(void)
|
||||
{
|
||||
const char *gpe0_sts_bits_low[] = {
|
||||
[1] = "HOTPLUG",
|
||||
[2] = "SWGPE",
|
||||
[6] = "TCO_SCI",
|
||||
[7] = "SMB_WAK",
|
||||
[8] = "RI",
|
||||
[9] = "PCI_EXP",
|
||||
[10] = "BATLOW",
|
||||
[11] = "PME",
|
||||
[13] = "PME_B0",
|
||||
[16] = "GPIO0",
|
||||
[17] = "GPIO1",
|
||||
[18] = "GPIO2",
|
||||
[19] = "GPIO3",
|
||||
[20] = "GPIO4",
|
||||
[21] = "GPIO5",
|
||||
[22] = "GPIO6",
|
||||
[23] = "GPIO7",
|
||||
[24] = "GPIO8",
|
||||
[25] = "GPIO9",
|
||||
[26] = "GPIO10",
|
||||
[27] = "GPIO11",
|
||||
[28] = "GPIO12",
|
||||
[29] = "GPIO13",
|
||||
[30] = "GPIO14",
|
||||
[31] = "GPIO15",
|
||||
};
|
||||
const char *gpe0_sts_bits_high[] = {
|
||||
[3] = "GPIO27",
|
||||
[6] = "WADT",
|
||||
[24] = "GPIO17",
|
||||
[25] = "GPIO19",
|
||||
[26] = "GPIO21",
|
||||
[27] = "GPIO22",
|
||||
[28] = "GPIO43",
|
||||
[29] = "GPIO56",
|
||||
[30] = "GPIO57",
|
||||
[31] = "GPIO60",
|
||||
};
|
||||
|
||||
/* High bits */
|
||||
print_gpe_status(reset_gpe_status(GPE0_STS_2, GPE0_EN_2),
|
||||
gpe0_sts_bits_high);
|
||||
|
||||
/* Standard GPE and GPIO 0-31 */
|
||||
return print_gpe_status(reset_gpe_status(GPE0_STS, GPE0_EN),
|
||||
gpe0_sts_bits_low);
|
||||
}
|
||||
|
||||
/* Print, clear, and return LynxPoint-LP GPE0 status */
|
||||
static u32 clear_lpt_lp_gpe_status(void)
|
||||
{
|
||||
const char *gpe0_sts_4_bits[] = {
|
||||
[1] = "HOTPLUG",
|
||||
[2] = "SWGPE",
|
||||
[6] = "TCO_SCI",
|
||||
[7] = "SMB_WAK",
|
||||
[9] = "PCI_EXP",
|
||||
[10] = "BATLOW",
|
||||
[11] = "PME",
|
||||
[12] = "ME",
|
||||
[13] = "PME_B0",
|
||||
[16] = "GPIO27",
|
||||
[18] = "WADT"
|
||||
};
|
||||
|
||||
/* GPIO 0-31 */
|
||||
print_gpe_gpio(reset_gpe_status(LP_GPE0_STS_1, LP_GPE0_EN_1), 0);
|
||||
|
||||
/* GPIO 32-63 */
|
||||
print_gpe_gpio(reset_gpe_status(LP_GPE0_STS_2, LP_GPE0_EN_2), 32);
|
||||
|
||||
/* GPIO 64-94 */
|
||||
print_gpe_gpio(reset_gpe_status(LP_GPE0_STS_3, LP_GPE0_EN_3), 64);
|
||||
|
||||
/* Standard GPE */
|
||||
return print_gpe_status(reset_gpe_status(LP_GPE0_STS_4, LP_GPE0_EN_4),
|
||||
gpe0_sts_4_bits);
|
||||
}
|
||||
|
||||
/* Clear all GPE status and return "standard" GPE event status */
|
||||
u32 clear_gpe_status(void)
|
||||
{
|
||||
if (pch_is_lp())
|
||||
return clear_lpt_lp_gpe_status();
|
||||
else
|
||||
return clear_lpt_gpe_status();
|
||||
}
|
||||
|
||||
/* Enable all requested GPE */
|
||||
void enable_all_gpe(u32 set1, u32 set2, u32 set3, u32 set4)
|
||||
{
|
||||
u16 pmbase = get_pmbase();
|
||||
|
||||
if (pch_is_lp()) {
|
||||
outl(set1, pmbase + LP_GPE0_EN_1);
|
||||
outl(set2, pmbase + LP_GPE0_EN_2);
|
||||
outl(set3, pmbase + LP_GPE0_EN_3);
|
||||
outl(set4, pmbase + LP_GPE0_EN_4);
|
||||
} else {
|
||||
outl(set1, pmbase + GPE0_EN);
|
||||
outl(set2, pmbase + GPE0_EN_2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable all GPE */
|
||||
void disable_all_gpe(void)
|
||||
{
|
||||
enable_all_gpe(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Enable a standard GPE */
|
||||
void enable_gpe(u32 mask)
|
||||
{
|
||||
u32 gpe0_reg = pch_is_lp() ? LP_GPE0_EN_4 : GPE0_EN;
|
||||
u32 gpe0_en = inl(get_pmbase() + gpe0_reg);
|
||||
gpe0_en |= mask;
|
||||
outl(gpe0_en, get_pmbase() + gpe0_reg);
|
||||
}
|
||||
|
||||
/* Disable a standard GPE */
|
||||
void disable_gpe(u32 mask)
|
||||
{
|
||||
u32 gpe0_reg = pch_is_lp() ? LP_GPE0_EN_4 : GPE0_EN;
|
||||
u32 gpe0_en = inl(get_pmbase() + gpe0_reg);
|
||||
gpe0_en &= ~mask;
|
||||
outl(gpe0_en, get_pmbase() + gpe0_reg);
|
||||
}
|
Loading…
Reference in New Issue