aboutsummaryrefslogtreecommitdiff
path: root/src/southbridge/intel/lynxpoint/serialio.c
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2013-05-21 16:37:40 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-11-25 23:36:57 +0100
commit98c40622feeaf1d8f211501e8f337d5bde544d13 (patch)
treead8cecef27d3e2efe9338ce15019dc6d507099e5 /src/southbridge/intel/lynxpoint/serialio.c
parent8d1b132733ab82b689e9a7fd6677e317b1535c92 (diff)
lynxpoint: Enable SerialIO clock in PCI mode
The clock gating register at offset 0x800 is managed by the clock driver in the kernel when the devices are in ACPI mode. When in PCI mode we should force enable the clock here. When in ACPI mode or the device is disabled it should be put in D3Hot state. > i2cdetect -y -r 10 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- Change-Id: Ib93ffd41bf36386d5ce63bfc0ae6597f3e23bc48 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/56122 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/4180 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/southbridge/intel/lynxpoint/serialio.c')
-rw-r--r--src/southbridge/intel/lynxpoint/serialio.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/southbridge/intel/lynxpoint/serialio.c b/src/southbridge/intel/lynxpoint/serialio.c
index 11d6a36b44..8257cc2f6f 100644
--- a/src/southbridge/intel/lynxpoint/serialio.c
+++ b/src/southbridge/intel/lynxpoint/serialio.c
@@ -29,6 +29,22 @@
#include "pch.h"
#include "nvs.h"
+/* Set D3Hot Power State in ACPI mode */
+static void serialio_enable_d3hot(struct device *dev)
+{
+ u32 reg32 = pci_read_config32(dev, PCH_PCS);
+ reg32 |= PCH_PCS_PS_D3HOT;
+ pci_write_config32(dev, PCH_PCS, reg32);
+}
+
+/* Enable clock in PCI mode */
+static void serialio_enable_clock(struct resource *bar0)
+{
+ u32 reg32 = read32(bar0->base + SIO_REG_PPR_CLOCK);
+ reg32 |= SIO_REG_PPR_CLOCK_EN;
+ write32(bar0->base + SIO_REG_PPR_CLOCK, reg32);
+}
+
/* Put Serial IO D21:F0-F6 device into desired mode. */
static void serialio_d21_mode(int sio_index, int int_pin, int acpi_mode)
{
@@ -143,9 +159,15 @@ static void serialio_init(struct device *dev)
struct southbridge_intel_lynxpoint_config *config = dev->chip_info;
struct resource *bar0, *bar1;
int sio_index = -1;
+ u32 reg32;
printk(BIOS_DEBUG, "Initializing Serial IO device\n");
+ /* Ensure memory and bus master are enabled */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
/* Find BAR0 and BAR1 */
bar0 = find_resource(dev, PCI_BASE_ADDRESS_0);
if (!bar0)
@@ -154,6 +176,11 @@ static void serialio_init(struct device *dev)
if (!bar1)
return;
+ if (!config->sio_acpi_mode)
+ serialio_enable_clock(bar0);
+ else if (dev->path.pci.devfn != PCI_DEVFN(21, 0))
+ serialio_enable_d3hot(dev); /* all but SDMA */
+
switch (dev->path.pci.devfn) {
case PCI_DEVFN(21, 0): /* SDMA */
sio_index = SIO_ID_SDMA;
@@ -241,9 +268,9 @@ static struct pci_operations pci_ops = {
};
static struct device_operations device_ops = {
- .read_resources = pci_bus_read_resources,
+ .read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
+ .enable_resources = pci_dev_enable_resources,
.init = serialio_init,
.ops_pci = &pci_ops,
};