summaryrefslogtreecommitdiff
path: root/src/soc/intel/baytrail/lpss.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/baytrail/lpss.c')
-rw-r--r--src/soc/intel/baytrail/lpss.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/soc/intel/baytrail/lpss.c b/src/soc/intel/baytrail/lpss.c
index ccfab38a62..e009c7d010 100644
--- a/src/soc/intel/baytrail/lpss.c
+++ b/src/soc/intel/baytrail/lpss.c
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <arch/io.h>
+#include <cbmem.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
@@ -26,9 +27,49 @@
#include <reg_script.h>
#include <baytrail/iosf.h>
+#include <baytrail/nvs.h>
#include <baytrail/pci_devs.h>
#include <baytrail/ramstage.h>
+#include "chip.h"
+
+static void dev_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
+{
+ struct reg_script ops[] = {
+ REG_SCRIPT_SET_DEV(dev),
+ /* Disable PCI interrupt, enable Memory and Bus Master */
+ REG_PCI_OR32(PCI_COMMAND,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
+ /* Enable ACPI mode */
+ REG_IOSF_OR(IOSF_PORT_LPSS, iosf_reg,
+ LPSS_CTL_PCI_CFG_DIS | LPSS_CTL_ACPI_INT_EN),
+ REG_SCRIPT_END
+ };
+ struct resource *bar;
+ global_nvs_t *gnvs;
+
+ /* Find ACPI NVS to update BARs */
+ gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
+ if (!gnvs) {
+ printk(BIOS_ERR, "Unable to locate Global NVS\n");
+ return;
+ }
+
+ /* Save BAR0 and BAR1 to ACPI NVS */
+ bar = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (bar)
+ gnvs->dev.lpss_bar0[nvs_index] = (u32)bar->base;
+
+ bar = find_resource(dev, PCI_BASE_ADDRESS_1);
+ if (bar)
+ gnvs->dev.lpss_bar1[nvs_index] = (u32)bar->base;
+
+ /* Device is enabled in ACPI mode */
+ gnvs->dev.lpss_en[nvs_index] = 1;
+
+ /* Put device in ACPI mode */
+ reg_script_run(ops);
+}
static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg)
{
@@ -43,12 +84,14 @@ static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg)
reg_script_run(ops);
}
-static int dev_ctl_reg(device_t dev)
+static void dev_ctl_reg(device_t dev, int *iosf_reg, int *nvs_index)
{
- int iosf_reg = -1;
+ *iosf_reg = -1;
+ *nvs_index = -1;
#define SET_IOSF_REG(name_) \
case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \
- iosf_reg = LPSS_ ## name_ ## _CTL
+ *iosf_reg = LPSS_ ## name_ ## _CTL; \
+ *nvs_index = LPSS_NVS_ ## name_
switch (dev->path.pci.devfn) {
SET_IOSF_REG(SIO_DMA1);
@@ -80,7 +123,6 @@ static int dev_ctl_reg(device_t dev)
SET_IOSF_REG(SPI);
break;
}
- return iosf_reg;
}
static void i2c_disable_resets(device_t dev)
@@ -113,7 +155,10 @@ static void i2c_disable_resets(device_t dev)
static void lpss_init(device_t dev)
{
- int iosf_reg = dev_ctl_reg(dev);
+ struct soc_intel_baytrail_config *config = dev->chip_info;
+ int iosf_reg, nvs_index;
+
+ dev_ctl_reg(dev, &iosf_reg, &nvs_index);
if (iosf_reg < 0) {
int slot = PCI_SLOT(dev->path.pci.devfn);
@@ -124,6 +169,9 @@ static void lpss_init(device_t dev)
}
dev_enable_snoop_and_pm(dev, iosf_reg);
+ if (config->lpss_acpi_mode)
+ dev_enable_acpi_mode(dev, iosf_reg, nvs_index);
+
i2c_disable_resets(dev);
}