summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/apollolake/acpi.c11
-rw-r--r--src/soc/intel/apollolake/acpi/globalnvs.asl4
-rw-r--r--src/soc/intel/apollolake/acpi/gpiolib.asl51
-rw-r--r--src/soc/intel/apollolake/acpi/scs.asl24
-rw-r--r--src/soc/intel/apollolake/gpio.c10
-rw-r--r--src/soc/intel/apollolake/include/soc/gpio.h4
-rw-r--r--src/soc/intel/apollolake/include/soc/nvs.h5
7 files changed, 99 insertions, 10 deletions
diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c
index 9f57206b38..2adb76e2c4 100644
--- a/src/soc/intel/apollolake/acpi.c
+++ b/src/soc/intel/apollolake/acpi.c
@@ -30,6 +30,7 @@
#include <soc/pci_devs.h>
#include <string.h>
#include <soc/gpio.h>
+#include <gpio.h>
#include "chip.h"
#define CSTATE_RES(address_space, width, offset, address) \
@@ -185,9 +186,13 @@ static void acpi_create_gnvs(struct global_nvs_t *gnvs)
if (cfg->prt0_gpio != GPIO_PRT0_UDEF)
gnvs->prt0 = (uintptr_t)gpio_dwx_address(cfg->prt0_gpio);
- /* Assign sdcard cd address if GPIO is defined in devicetree */
- if (cfg->sdcard_cd_gpio)
- gnvs->scd0 = (uintptr_t)gpio_dwx_address(cfg->sdcard_cd_gpio);
+ /* Get sdcard cd GPIO portid if GPIO is defined in devicetree.
+ * Get offset of sdcard cd pin.
+ */
+ if (cfg->sdcard_cd_gpio) {
+ gnvs->scdp = gpio_get_pad_portid(cfg->sdcard_cd_gpio);
+ gnvs->scdo = gpio_acpi_pin(cfg->sdcard_cd_gpio);
+ }
}
/* Save wake source information for calculating ACPI _SWS values */
diff --git a/src/soc/intel/apollolake/acpi/globalnvs.asl b/src/soc/intel/apollolake/acpi/globalnvs.asl
index 86a1a23fd6..bdba305081 100644
--- a/src/soc/intel/apollolake/acpi/globalnvs.asl
+++ b/src/soc/intel/apollolake/acpi/globalnvs.asl
@@ -39,8 +39,8 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
NHLA, 64, // 0x19 - 0x20 - NHLT Address
NHLL, 32, // 0x21 - 0x24 - NHLT Length
PRT0, 32, // 0x25 - 0x28 - PERST_0 Address
- SCD0, 32, // 0x29 - 0x2D - SD_CD Address
-
+ SCDP, 8, // 0x29 - SD_CD GPIO portid
+ SCDO, 8, // 0x2A - GPIO pad offset relative to the community
/* ChromeOS stuff (0x100 -> 0xfff, size 0xeff) */
Offset (0x100),
#include <vendorcode/google/chromeos/acpi/gnvs.asl>
diff --git a/src/soc/intel/apollolake/acpi/gpiolib.asl b/src/soc/intel/apollolake/acpi/gpiolib.asl
index cec6d36722..0acfb67016 100644
--- a/src/soc/intel/apollolake/acpi/gpiolib.asl
+++ b/src/soc/intel/apollolake/acpi/gpiolib.asl
@@ -64,4 +64,55 @@ Scope (\_SB)
}
Store (Arg1, TEMP)
}
+
+ /* Get DW0 address of a given pad */
+ Method (GDW0, 0x2, Serialized)
+ {
+ /* Arg0 - GPIO portid */
+ /* Arg1 - GPIO pad offset relative to the community */
+ Store (0, Local1)
+ Or( Or (ShiftLeft (Arg0, 16), CONFIG_IOSF_BASE_ADDRESS),
+ Local1, Local1)
+ Or( Add (PAD_CFG_BASE, Multiply (Arg1, 8)), Local1, Local1)
+ Return (Local1)
+ }
+
+ /* Calculate HOSTSW_REG address */
+ Method (CHSA, 0x1, Serialized)
+ {
+ /* Arg0 - GPIO pad offset relative to the community */
+ Add (HOSTSW_OWN_REG_BASE, Multiply (Divide (Arg0, 32), 4), Local1)
+ Return (Local1)
+ }
+
+ /* Get Host ownership register of GPIO Community */
+ Method (GHO, 0x2, Serialized)
+ {
+ /* Arg0 - GPIO portid */
+ /* Arg1 - GPIO pad offset relative to the community */
+ Store (CHSA (Arg1), Local1)
+
+ OperationRegion (SHO0, SystemMemory, Or ( Or
+ (CONFIG_IOSF_BASE_ADDRESS, ShiftLeft (Arg0, 16)), Local1), 4)
+ Field (SHO0, AnyAcc, NoLock, Preserve) {
+ TEMP, 32
+ }
+ Return (TEMP)
+ }
+
+ /* Set Host ownership register of GPIO Community */
+ Method (SHO, 0x3, Serialized)
+ {
+ /* Arg0 - GPIO portid */
+ /* Arg1 - GPIO pad offset relative to the community */
+ /* Arg2 - Value for Host own register */
+ Store (CHSA (Arg1), Local1)
+
+ OperationRegion (SHO0, SystemMemory, Or ( Or
+ (CONFIG_IOSF_BASE_ADDRESS, ShiftLeft (Arg0, 16)), Local1), 4)
+ Field (SHO0, AnyAcc, NoLock, Preserve) {
+ TEMP, 32
+ }
+ Store (Arg2, TEMP)
+ }
}
diff --git a/src/soc/intel/apollolake/acpi/scs.asl b/src/soc/intel/apollolake/acpi/scs.asl
index bb8b684ef3..5933d522c5 100644
--- a/src/soc/intel/apollolake/acpi/scs.asl
+++ b/src/soc/intel/apollolake/acpi/scs.asl
@@ -115,14 +115,32 @@ Scope (\_SB.PCI0) {
Device (SDCD)
{
Name (_ADR, 0x001B0000)
+ Name (_S0W, 4) /* _S0W: S0 Device Wake State */
+ Name (SCD0, 0) /* Store SD_CD DW0 address */
+
+ /* Set the host ownership of sdcard cd during kernel boot */
+ Method (_INI, 0)
+ {
+ /* Check SDCard CD port is valid */
+ If (LAnd (LNotEqual (\SCDP, 0), LNotEqual (\SCDO, 0) ))
+ {
+ /* Store DW0 address of SD_CD */
+ Store (GDW0 (\SCDP, \SCDO), SCD0)
+ /* Get the current SD_CD ownership */
+ Store (\_SB.GHO (\SCDP, \SCDO), Local0)
+ /* Set host ownership as GPIO in HOSTSW_OWN reg */
+ Or (Local0, ShiftLeft (1, Mod (\SCDO, 32)), Local0)
+ \_SB.SHO (\SCDP, \SCDO, Local0)
+ }
+ }
Method (_PS0, 0, NotSerialized)
{
- /* Check SDCard CD pin address is valid */
- If (LNotEqual (SCD0, 0))
+ /* Check SDCard CD port is valid */
+ If (LAnd (LNotEqual (\SCDP, 0), LNotEqual (\SCDO, 0) ))
{
/* Store DW0 into local0 to get rxstate of GPIO */
- Store (\_SB.GPC0 (\SCD0), Local0)
+ Store (\_SB.GPC0 (SCD0), Local0)
/* Extract rxstate [bit 1] of sdcard card detect pin */
And (Local0, PAD_CFG0_RX_STATE, Local0)
/* If the sdcard is present, rxstate is low.
diff --git a/src/soc/intel/apollolake/gpio.c b/src/soc/intel/apollolake/gpio.c
index cb41925cd4..d9957726eb 100644
--- a/src/soc/intel/apollolake/gpio.c
+++ b/src/soc/intel/apollolake/gpio.c
@@ -186,6 +186,16 @@ void *gpio_dwx_address(const uint16_t pad)
PAD_CFG_OFFSET(pad - comm->first_pad));
}
+uint8_t gpio_get_pad_portid(const uint16_t pad)
+{
+ /* Get the port id of given pad
+ * pad - GPIO number
+ * returns - given pad port id
+ */
+ const struct pad_community *comm = gpio_get_community(pad);
+ return comm->port;
+}
+
void gpio_input_pulldown(gpio_t gpio)
{
struct pad_config cfg = PAD_CFG_GPI(gpio, DN_20K, DEEP);
diff --git a/src/soc/intel/apollolake/include/soc/gpio.h b/src/soc/intel/apollolake/include/soc/gpio.h
index bdd39944d1..f1020f630a 100644
--- a/src/soc/intel/apollolake/include/soc/gpio.h
+++ b/src/soc/intel/apollolake/include/soc/gpio.h
@@ -162,6 +162,10 @@ void gpio_configure_pads(const struct pad_config *cfg, size_t num_pads);
/* Calculate GPIO DW0 address */
void *gpio_dwx_address(const uint16_t pad);
+
+/* Get the port id of given pad */
+uint8_t gpio_get_pad_portid(const uint16_t pad);
+
/*
* Set the GPIO groups for the GPE blocks. The values from PMC register GPE_CFG
* are passed which is then mapped to proper groups for MISCCFG. This basically
diff --git a/src/soc/intel/apollolake/include/soc/nvs.h b/src/soc/intel/apollolake/include/soc/nvs.h
index 21ac14e274..f9cc49d3ff 100644
--- a/src/soc/intel/apollolake/include/soc/nvs.h
+++ b/src/soc/intel/apollolake/include/soc/nvs.h
@@ -39,8 +39,9 @@ typedef struct global_nvs_t {
uint64_t nhla; /* 0x19 - 0x20 - NHLT Address */
uint32_t nhll; /* 0x21 - 0x24 - NHLT Length */
uint32_t prt0; /* 0x25 - 0x28 - PERST_0 Address */
- uint32_t scd0; /* 0x29 - 0x2D - SD_CD Address */
- uint8_t unused[211];
+ uint8_t scdp; /* 0x29 - SD_CD GPIO portid */
+ uint8_t scdo; /* 0x2A - GPIO pad offset relative to the community */
+ uint8_t unused[213];
/* ChromeOS specific (0x100 - 0xfff) */
chromeos_acpi_t chromeos;