soc/intel/apollolake: Add PM methods to power gate PCIe
This implements GNVS variable to store the address of PERST_0, _ON/_OFF methods to power gate PCIe during S0ix entry, and PERST_0 assertion/de-assertion methods. BUG=chrome-os-partner:55877 TEST=Suspend and resume using 'echo freeze > /sys/power/state'. System should resume with PCIE and wifi functional. Change-Id: I9f63ca0b8a6565b6d21deaa6d3dfa34678714c19 Signed-off-by: Vaibhav Shankar <vaibhav.shankar@intel.com> Reviewed-on: https://review.coreboot.org/16351 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
This commit is contained in:
parent
9e81540b85
commit
ef8deaffcb
|
@ -29,6 +29,7 @@
|
||||||
#include <soc/nvs.h>
|
#include <soc/nvs.h>
|
||||||
#include <soc/pci_devs.h>
|
#include <soc/pci_devs.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <soc/gpio.h>
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
#define CSTATE_RES(address_space, width, offset, address) \
|
#define CSTATE_RES(address_space, width, offset, address) \
|
||||||
|
@ -175,6 +176,10 @@ static void acpi_create_gnvs(struct global_nvs_t *gnvs)
|
||||||
|
|
||||||
/* Enable DPTF based on mainboard configuration */
|
/* Enable DPTF based on mainboard configuration */
|
||||||
gnvs->dpte = cfg->dptf_enable;
|
gnvs->dpte = cfg->dptf_enable;
|
||||||
|
|
||||||
|
/* Assign address of PERST_0 if GPIO is defined in devicetree */
|
||||||
|
if (cfg->prt0_gpio != GPIO_PRT0_UDEF)
|
||||||
|
gnvs->prt0 = (uintptr_t)gpio_dwx_address(cfg->prt0_gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save wake source information for calculating ACPI _SWS values */
|
/* Save wake source information for calculating ACPI _SWS values */
|
||||||
|
|
|
@ -38,6 +38,7 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
|
||||||
GPEI, 64, // 0x11 - 0x18 - GPE Wake Source
|
GPEI, 64, // 0x11 - 0x18 - GPE Wake Source
|
||||||
NHLA, 64, // 0x19 - 0x20 - NHLT Address
|
NHLA, 64, // 0x19 - 0x20 - NHLT Address
|
||||||
NHLL, 32, // 0x21 - 0x24 - NHLT Length
|
NHLL, 32, // 0x21 - 0x24 - NHLT Length
|
||||||
|
PRT0, 32, // 0x25 - 0x28 - PERST_0 Address
|
||||||
|
|
||||||
/* ChromeOS stuff (0x100 -> 0xfff, size 0xeff) */
|
/* ChromeOS stuff (0x100 -> 0xfff, size 0xeff) */
|
||||||
Offset (0x100),
|
Offset (0x100),
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
#include <soc/gpio_defs.h>
|
#include <soc/gpio_defs.h>
|
||||||
|
#include "gpiolib.asl"
|
||||||
|
|
||||||
scope (\_SB) {
|
scope (\_SB) {
|
||||||
|
|
||||||
|
@ -141,6 +142,38 @@ scope (\_SB) {
|
||||||
Return(0xf)
|
Return(0xf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scope(\_SB.PCI0) {
|
||||||
|
/* PERST Assertion
|
||||||
|
* Note: PERST is Active High
|
||||||
|
*/
|
||||||
|
Method (PRAS, 0x1, Serialized)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Assert PERST
|
||||||
|
* local1 - to toggle Tx pin of Dw0
|
||||||
|
* local2 - Address of PERST
|
||||||
|
*/
|
||||||
|
Store (Arg0, Local2)
|
||||||
|
Store (\_SB.GPC0 (Local2), Local1)
|
||||||
|
Or (Local1, PAD_CFG0_TX_STATE, Local1)
|
||||||
|
\_SB.SPC0 (Local2, Local1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PERST DE-Assertion */
|
||||||
|
Method (PRDA, 0x1, Serialized)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* De-assert PERST
|
||||||
|
* local1 - to toggle Tx pin of Dw0
|
||||||
|
* local2 - Address of PERST
|
||||||
|
*/
|
||||||
|
Store (Arg0, Local2)
|
||||||
|
Store (\_SB.GPC0 (Local2), Local1)
|
||||||
|
And (Local1, Not (PAD_CFG0_TX_STATE), Local1)
|
||||||
|
\_SB.SPC0 (Local2, Local1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope(\_GPE)
|
Scope(\_GPE)
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Scope (\_SB)
|
||||||
|
{
|
||||||
|
/* Get Pad Configuration DW0 register value */
|
||||||
|
Method (GPC0, 0x1, Serialized)
|
||||||
|
{
|
||||||
|
/* Arg0 - GPIO DW0 address */
|
||||||
|
Store (Arg0, Local0)
|
||||||
|
OperationRegion (PDW0, SystemMemory, Local0, 4)
|
||||||
|
Field (PDW0, AnyAcc, NoLock, Preserve) {
|
||||||
|
TEMP, 32
|
||||||
|
}
|
||||||
|
Return (TEMP)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Pad Configuration DW0 register value */
|
||||||
|
Method (SPC0, 0x2, Serialized)
|
||||||
|
{
|
||||||
|
/* Arg0 - GPIO DW0 address */
|
||||||
|
/* Arg1 - Value for DW0 register */
|
||||||
|
Store (Arg0, Local0)
|
||||||
|
OperationRegion (PDW0, SystemMemory, Local0, 4)
|
||||||
|
Field (PDW0, AnyAcc, NoLock, Preserve) {
|
||||||
|
TEMP,32
|
||||||
|
}
|
||||||
|
Store (Arg1, TEMP)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Pad Configuration DW1 register value */
|
||||||
|
Method (GPC1, 0x1, Serialized)
|
||||||
|
{
|
||||||
|
/* Arg0 - GPIO DW0 address */
|
||||||
|
Store (Add (Arg0, 0x4), Local0)
|
||||||
|
OperationRegion (PDW1, SystemMemory, Local0, 4)
|
||||||
|
Field (PDW1, AnyAcc, NoLock, Preserve) {
|
||||||
|
TEMP, 32
|
||||||
|
}
|
||||||
|
Return (TEMP)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Pad Configuration DW1 register value */
|
||||||
|
Method (SPC1, 0x2, Serialized)
|
||||||
|
{
|
||||||
|
/* Arg0 - GPIO DW0 address */
|
||||||
|
/* Arg1 - Value for DW1 register */
|
||||||
|
Store (Add (Arg0, 0x4), Local0)
|
||||||
|
OperationRegion (PDW1, SystemMemory, Local0, 4)
|
||||||
|
Field(PDW1, AnyAcc, NoLock, Preserve) {
|
||||||
|
TEMP,32
|
||||||
|
}
|
||||||
|
Store (Arg1, TEMP)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Device (RP01)
|
||||||
|
{
|
||||||
|
Name (_ADR, 0x00140000)
|
||||||
|
Name (_DDN, "PCIe-B 0")
|
||||||
|
Name (PDST, 0) /* present Detect status */
|
||||||
|
|
||||||
|
/* lowest D-state supported by
|
||||||
|
* PCIe root port during S0 state
|
||||||
|
*/
|
||||||
|
Name (_S0W, 4)
|
||||||
|
|
||||||
|
/* Dynamic Opregion needed to access registers
|
||||||
|
* when the controller is in D3 cold
|
||||||
|
*/
|
||||||
|
OperationRegion (PX01, PCI_Config, 0x00, 0xFF)
|
||||||
|
Field (PX01, AnyAcc, NoLock, Preserve)
|
||||||
|
{
|
||||||
|
Offset(0x5A),
|
||||||
|
, 6,
|
||||||
|
PDS, 1, /* 6, Presence detect Change */
|
||||||
|
Offset(0xE2), /* RPPGEN - Root Port Power Gating Enable */
|
||||||
|
, 2,
|
||||||
|
L23E, 1, /* 2, L23_Rdy Entry Request (L23ER) */
|
||||||
|
L23R, 1, /* 3, L23_Rdy to Detect Transition (L23R2DT) */
|
||||||
|
Offset(0xF4), /* BLKPLLEN */
|
||||||
|
, 10,
|
||||||
|
BPLL, 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
OperationRegion (PX02, PCI_Config, 0x338, 0x4)
|
||||||
|
Field (PX02, AnyAcc, NoLock, Preserve)
|
||||||
|
{
|
||||||
|
, 26,
|
||||||
|
BDQA, 1 /* BLKDQDA */
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerResource (PXP, 0, 0)
|
||||||
|
{
|
||||||
|
/* Define the PowerResource for PCIe slot */
|
||||||
|
Method (_STA, 0, Serialized)
|
||||||
|
{
|
||||||
|
Store (PDS, PDST)
|
||||||
|
If (LEqual (PDS, 1)) {
|
||||||
|
Return (0xf)
|
||||||
|
} Else {
|
||||||
|
Return (0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (_ON, 0, Serialized)
|
||||||
|
{
|
||||||
|
If (LAnd (LEqual (PDST, 1), LNotEqual (\PRT0, 0))) {
|
||||||
|
/* Enter this condition if device
|
||||||
|
* is connected
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* De-assert PERST */
|
||||||
|
\_SB.PCI0.PRDA (\PRT0)
|
||||||
|
|
||||||
|
Store (0, BDQA) /* Set BLKDQDA to 0 */
|
||||||
|
Store (0, BPLL) /* Set BLKPLLEN to 0 */
|
||||||
|
|
||||||
|
/* Set L23_Rdy to Detect Transition
|
||||||
|
* (L23R2DT)
|
||||||
|
*/
|
||||||
|
Store (1, L23R)
|
||||||
|
Sleep (16)
|
||||||
|
Store (0, Local0)
|
||||||
|
|
||||||
|
/* Delay for transition Detect
|
||||||
|
* and link to train
|
||||||
|
*/
|
||||||
|
While (L23R) {
|
||||||
|
If (Lgreater (Local0, 4)) {
|
||||||
|
Break
|
||||||
|
}
|
||||||
|
Sleep (16)
|
||||||
|
Increment (Local0)
|
||||||
|
}
|
||||||
|
} /* End PDS condition check */
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (_OFF, 0, Serialized)
|
||||||
|
{
|
||||||
|
/* Set L23_Rdy Entry Request (L23ER) */
|
||||||
|
If (LAnd (LEqual (PDST, 1), LNotEqual (\PRT0, 0))) {
|
||||||
|
/* enter this condition if device
|
||||||
|
* is connected
|
||||||
|
*/
|
||||||
|
Store (1, L23E)
|
||||||
|
Sleep (16)
|
||||||
|
Store (0, Local0)
|
||||||
|
While (L23E) {
|
||||||
|
If (Lgreater (Local0, 4)) {
|
||||||
|
Break
|
||||||
|
}
|
||||||
|
Sleep (16)
|
||||||
|
Increment (Local0)
|
||||||
|
}
|
||||||
|
Store (1, BDQA) /* Set BLKDQDA to 1 */
|
||||||
|
Store (1, BPLL) /* Set BLKPLLEN to 1 */
|
||||||
|
|
||||||
|
/* Assert PERST */
|
||||||
|
\_SB.PCI0.PRAS (\PRT0)
|
||||||
|
} /* End PDS condition check */
|
||||||
|
} /* End of Method_OFF */
|
||||||
|
} /* End PXP */
|
||||||
|
|
||||||
|
Name(_PR0, Package() { PXP })
|
||||||
|
Name(_PR3, Package() { PXP })
|
||||||
|
}
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
#include <soc/gpe.h>
|
#include <soc/gpe.h>
|
||||||
|
|
||||||
|
/* PCIE device */
|
||||||
|
#include "pcie.asl"
|
||||||
|
|
||||||
/* LPSS device */
|
/* LPSS device */
|
||||||
#include "lpss.asl"
|
#include "lpss.asl"
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,9 @@ struct soc_intel_apollolake_config {
|
||||||
|
|
||||||
/* SLP S3 minimum assertion width. */
|
/* SLP S3 minimum assertion width. */
|
||||||
int slp_s3_assertion_width_usecs;
|
int slp_s3_assertion_width_usecs;
|
||||||
|
|
||||||
|
/* GPIO pin for PERST_0 */
|
||||||
|
uint16_t prt0_gpio;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _SOC_APOLLOLAKE_CHIP_H_ */
|
#endif /* _SOC_APOLLOLAKE_CHIP_H_ */
|
||||||
|
|
|
@ -414,6 +414,9 @@
|
||||||
#define LPC_CLKRUNB 243
|
#define LPC_CLKRUNB 243
|
||||||
#define LPC_FRAMEB 244
|
#define LPC_FRAMEB 244
|
||||||
|
|
||||||
|
/* PERST_0 not defined */
|
||||||
|
#define GPIO_PRT0_UDEF 0xFF
|
||||||
|
|
||||||
#define TOTAL_PADS 245
|
#define TOTAL_PADS 245
|
||||||
#define N_OFFSET GPIO_0
|
#define N_OFFSET GPIO_0
|
||||||
#define NW_OFFSET GPIO_187
|
#define NW_OFFSET GPIO_187
|
||||||
|
|
|
@ -38,7 +38,8 @@ typedef struct global_nvs_t {
|
||||||
uint64_t gpei; /* 0x11 - 0x18 - GPE Wake Source */
|
uint64_t gpei; /* 0x11 - 0x18 - GPE Wake Source */
|
||||||
uint64_t nhla; /* 0x19 - 0x20 - NHLT Address */
|
uint64_t nhla; /* 0x19 - 0x20 - NHLT Address */
|
||||||
uint32_t nhll; /* 0x21 - 0x24 - NHLT Length */
|
uint32_t nhll; /* 0x21 - 0x24 - NHLT Length */
|
||||||
uint8_t unused[219];
|
uint32_t prt0; /* 0x25 - 0x28 - PERST_0 Address */
|
||||||
|
uint8_t unused[215];
|
||||||
|
|
||||||
/* ChromeOS specific (0x100 - 0xfff) */
|
/* ChromeOS specific (0x100 - 0xfff) */
|
||||||
chromeos_acpi_t chromeos;
|
chromeos_acpi_t chromeos;
|
||||||
|
|
Loading…
Reference in New Issue