[coreboot-gerrit] Patch set updated for coreboot: d13f5e9 lynxpoint: Enable SerialIO clock in PCI mode

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Wed Nov 20 01:11:24 CET 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4180

-gerrit

commit d13f5e9ff43d7a198545d5e098af9b1446e2f77a
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Tue May 21 16:37:40 2013 -0700

    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 at chromium.org>
    Reviewed-on: https://gerrit.chromium.org/gerrit/56122
    Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/southbridge/intel/lynxpoint/pch.c      | 26 ++++++++++++++++++++-----
 src/southbridge/intel/lynxpoint/pch.h      |  6 ++++++
 src/southbridge/intel/lynxpoint/serialio.c | 31 ++++++++++++++++++++++++++++--
 3 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/src/southbridge/intel/lynxpoint/pch.c b/src/southbridge/intel/lynxpoint/pch.c
index cc3718d..58c68cd 100644
--- a/src/southbridge/intel/lynxpoint/pch.c
+++ b/src/southbridge/intel/lynxpoint/pch.c
@@ -83,10 +83,18 @@ u16 get_gpiobase(void)
 
 #ifndef __SMM__
 
+/* Put device in D3Hot Power State */
+static void pch_enable_d3hot(device_t dev)
+{
+	u32 reg32 = pci_read_config32(dev, PCH_PCS);
+	reg32 |= PCH_PCS_PS_D3HOT;
+	pci_write_config32(dev, PCH_PCS, reg32);
+}
+
 /* Set bit in Function Disble register to hide this device */
-static void pch_hide_devfn(unsigned devfn)
+static void pch_hide_devfn(device_t dev)
 {
-	switch (devfn) {
+	switch (dev->path.pci.devfn) {
 	case PCI_DEVFN(19, 0): /* Audio DSP */
 		RCBA32_OR(FD, PCH_DISABLE_ADSPD);
 		break;
@@ -94,24 +102,31 @@ static void pch_hide_devfn(unsigned devfn)
 		RCBA32_OR(FD, PCH_DISABLE_XHCI);
 		break;
 	case PCI_DEVFN(21, 0): /* DMA */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS0, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(21, 1): /* I2C0 */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS1, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(21, 2): /* I2C1 */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS2, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(21, 3): /* SPI0 */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS3, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(21, 4): /* SPI1 */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS4, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(21, 5): /* UART0 */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS5, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(21, 6): /* UART1 */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS6, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(22, 0): /* MEI #1 */
@@ -127,6 +142,7 @@ static void pch_hide_devfn(unsigned devfn)
 		RCBA32_OR(FD2, PCH_DISABLE_KT);
 		break;
 	case PCI_DEVFN(23, 0): /* SDIO */
+		pch_enable_d3hot(dev);
 		pch_iobp_update(SIO_IOBP_FUNCDIS7, ~0UL, SIO_IOBP_FUNCDIS_DIS);
 		break;
 	case PCI_DEVFN(25, 0): /* Gigabit Ethernet */
@@ -146,7 +162,7 @@ static void pch_hide_devfn(unsigned devfn)
 	case PCI_DEVFN(28, 5): /* PCI Express Root Port 6 */
 	case PCI_DEVFN(28, 6): /* PCI Express Root Port 7 */
 	case PCI_DEVFN(28, 7): /* PCI Express Root Port 8 */
-		RCBA32_OR(FD, PCH_DISABLE_PCIE(PCI_FUNC(devfn)));
+		RCBA32_OR(FD, PCH_DISABLE_PCIE(PCI_FUNC(dev->path.pci.devfn)));
 		break;
 	case PCI_DEVFN(29, 0): /* EHCI #1 */
 		RCBA32_OR(FD, PCH_DISABLE_EHCI1);
@@ -404,7 +420,7 @@ static void pch_pcie_enable(device_t dev)
 		new_rpfn |= RPFN_HIDE(PCI_FUNC(dev->path.pci.devfn));
 
 		/* Hide this device if possible */
-		pch_hide_devfn(dev->path.pci.devfn);
+		pch_hide_devfn(dev);
 	} else {
 		int fn;
 
@@ -463,7 +479,7 @@ void pch_enable(device_t dev)
 		pci_write_config32(dev, PCI_COMMAND, reg32);
 
 		/* Hide this device if possible */
-		pch_hide_devfn(dev->path.pci.devfn);
+		pch_hide_devfn(dev);
 	} else {
 		/* Enable SERR */
 		reg32 = pci_read_config32(dev, PCI_COMMAND);
diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
index ca1d8b1..b01fdc0 100644
--- a/src/southbridge/intel/lynxpoint/pch.h
+++ b/src/southbridge/intel/lynxpoint/pch.h
@@ -218,6 +218,10 @@ void set_gpio(int gpio_num, int value);
 #define   SEE	(1 << 1)
 #define   PERE	(1 << 0)
 
+/* Power Management Control and Status */
+#define PCH_PCS			0x84
+#define  PCH_PCS_PS_D3HOT	3
+
 #define PCH_EHCI1_DEV		PCI_DEV(0, 0x1d, 0)
 #define PCH_EHCI2_DEV		PCI_DEV(0, 0x1a, 0)
 #define PCH_ME_DEV		PCI_DEV(0, 0x16, 0)
@@ -377,6 +381,8 @@ void set_gpio(int gpio_num, int value);
 #define SIO_ID_UART1		6 /* D21:F6 */
 #define SIO_ID_SDIO		7 /* D23:F0 */
 
+#define SIO_REG_PPR_CLOCK		0x800
+#define  SIO_REG_PPR_CLOCK_EN		 (1 << 0)
 #define SIO_REG_PPR_RST			0x804
 #define  SIO_REG_PPR_RST_ASSERT		 0x3
 #define SIO_REG_PPR_GEN			0x808
diff --git a/src/southbridge/intel/lynxpoint/serialio.c b/src/southbridge/intel/lynxpoint/serialio.c
index 11d6a36..8257cc2 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,
 };



More information about the coreboot-gerrit mailing list