[coreboot] New patch to review for coreboot: 961ded0 lynxpoint: Add new GPIO interface for Lynxpoint-LP

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Mar 12 00:10:55 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/2648

-gerrit

commit 961ded07ce0c984b5a5a28253d0c1b9889a3132e
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Mon Dec 17 11:29:10 2012 -0800

    lynxpoint: Add new GPIO interface for Lynxpoint-LP
    
    The low power variant of the chipset introduces a completely
    new interface to the GPIOs.
    
    This is a 1KB region and so needs to be moved as well so it does
    not conflict with other IO regions.
    
    Also expose the gpio_get functions to ramstage and move the
    prototypes to pch.h so they can be used for both GPIO interfaces.
    
    Change-Id: I20bc18669525af16de8cdf99f0ccfa9612be63ad
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/southbridge/intel/lynxpoint/Makefile.inc |  10 ++-
 src/southbridge/intel/lynxpoint/acpi/lpc.asl |  17 +++-
 src/southbridge/intel/lynxpoint/gpio.c       |  20 ++++-
 src/southbridge/intel/lynxpoint/gpio.h       |  24 ++++--
 src/southbridge/intel/lynxpoint/lp_gpio.c    | 113 +++++++++++++++++++++++++++
 src/southbridge/intel/lynxpoint/lp_gpio.h    | 110 ++++++++++++++++++++++++++
 src/southbridge/intel/lynxpoint/lpc.c        |   9 ++-
 src/southbridge/intel/lynxpoint/pch.h        |  35 ++++-----
 8 files changed, 307 insertions(+), 31 deletions(-)

diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc
index d4522c3..c14a538 100644
--- a/src/southbridge/intel/lynxpoint/Makefile.inc
+++ b/src/southbridge/intel/lynxpoint/Makefile.inc
@@ -45,10 +45,18 @@ smm-$(CONFIG_SPI_FLASH_SMM) += spi.c
 ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
 smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c finalize.c
 
-romstage-y += early_usb.c early_smbus.c early_me.c me_status.c gpio.c
+romstage-y += early_usb.c early_smbus.c early_me.c me_status.c
 romstage-$(CONFIG_USBDEBUG) += usb_debug.c
 romstage-y += reset.c early_spi.c
 
+ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y)
+romstage-y += lp_gpio.c
+ramstage-y += lp_gpio.c
+else
+romstage-y += gpio.c
+ramstage-y += gpio.c
+endif
+
 lynxpoint_add_me: $(obj)/coreboot.pre $(IFDTOOL)
 	printf "    DD         Adding Intel Firmware Descriptor\n"
 	dd if=3rdparty/mainboard/$(MAINBOARDDIR)/descriptor.bin \
diff --git a/src/southbridge/intel/lynxpoint/acpi/lpc.asl b/src/southbridge/intel/lynxpoint/acpi/lpc.asl
index cc59850..03d61eb 100644
--- a/src/southbridge/intel/lynxpoint/acpi/lpc.asl
+++ b/src/southbridge/intel/lynxpoint/acpi/lpc.asl
@@ -194,7 +194,22 @@ Device (LPCB)
 			IO (Decode16, 0xb2, 0xb2, 0x1, 0x02)		// SWSMI
 			//IO (Decode16, 0x800, 0x800, 0x1, 0x10)		// ACPI I/O trap
 			IO (Decode16, DEFAULT_PMBASE, DEFAULT_PMBASE, 0x1, 0x80)	// ICH7-M ACPI
-			IO (Decode16, DEFAULT_GPIOBASE, DEFAULT_GPIOBASE, 0x1, 0x40)	// ICH7-M GPIO
+
+#if CONFIG_INTEL_LYNXPOINT_LP
+			// LynxPoint LP GPIO is 1KB
+			IO (Decode16, DEFAULT_GPIOBASE,
+			    DEFAULT_GPIOBASE, 0x1, 0xff)
+			IO (Decode16, Add(DEFAULT_GPIOBASE, 0x100),
+			     Add(DEFAULT_GPIOBASE, 0x100), 0x1, 0xff)
+			IO (Decode16, Add(DEFAULT_GPIOBASE, 0x200),
+			    Add(DEFAULT_GPIOBASE, 0x200), 0x1, 0xff)
+			IO (Decode16, Add(DEFAULT_GPIOBASE, 0x300),
+			    Add(DEFAULT_GPIOBASE, 0x300), 0x1, 0xff)
+#else
+			// LynxPoint GPIO is 128 bytes
+			IO (Decode16, DEFAULT_GPIOBASE,
+			    DEFAULT_GPIOBASE, 0x1, DEFAULT_GPIOSIZE)
+#endif
 		})
 	}
 
diff --git a/src/southbridge/intel/lynxpoint/gpio.c b/src/southbridge/intel/lynxpoint/gpio.c
index 25eda9a..9d36887 100644
--- a/src/southbridge/intel/lynxpoint/gpio.c
+++ b/src/southbridge/intel/lynxpoint/gpio.c
@@ -20,16 +20,32 @@
 #include <stdint.h>
 #include <string.h>
 #include <arch/io.h>
+
+#ifdef __PRE_RAM__
 #include <arch/romcc_io.h>
+#else
+#include <device/device.h>
+#include <device/pci.h>
+#endif
 
 #include "pch.h"
 #include "gpio.h"
 
 #define MAX_GPIO_NUMBER 75 /* zero based */
 
+static u16 get_gpio_base(void)
+{
+#ifdef __PRE_RAM__
+	return pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc;
+#else
+	return pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)),
+				 GPIO_BASE) & 0xfffc;
+#endif
+}
+
 void setup_pch_gpios(const struct pch_gpio_map *gpio)
 {
-	u16 gpiobase = pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc;
+	u16 gpiobase = get_gpio_base();
 
 	/* GPIO Set 1 */
 	if (gpio->set1.level)
@@ -69,7 +85,7 @@ void setup_pch_gpios(const struct pch_gpio_map *gpio)
 int get_gpio(int gpio_num)
 {
 	static const int gpio_reg_offsets[] = {0xc, 0x38, 0x48};
-	u16 gpio_base = pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc;
+	u16 gpio_base = get_gpio_base();
 	int index, bit;
 
 	if (gpio_num > MAX_GPIO_NUMBER)
diff --git a/src/southbridge/intel/lynxpoint/gpio.h b/src/southbridge/intel/lynxpoint/gpio.h
index a6f99f6..20e2eea 100644
--- a/src/southbridge/intel/lynxpoint/gpio.h
+++ b/src/southbridge/intel/lynxpoint/gpio.h
@@ -20,6 +20,22 @@
 #ifndef INTEL_LYNXPOINT_GPIO_H
 #define INTEL_LYNXPOINT_GPIO_H
 
+/* ICH7 GPIOBASE */
+#define GPIO_USE_SEL		0x00
+#define GP_IO_SEL		0x04
+#define GP_LVL			0x0c
+#define GPO_BLINK		0x18
+#define GPI_INV			0x2c
+#define GPIO_USE_SEL2		0x30
+#define GP_IO_SEL2		0x34
+#define GP_LVL2			0x38
+#define GPIO_USE_SEL3		0x40
+#define GP_IO_SEL3		0x44
+#define GP_LVL3			0x48
+#define GP_RST_SEL1		0x60
+#define GP_RST_SEL2		0x64
+#define GP_RST_SEL3		0x68
+
 #define GPIO_MODE_NATIVE	0
 #define GPIO_MODE_GPIO		1
 #define GPIO_MODE_NONE		1
@@ -150,12 +166,4 @@ struct pch_gpio_map {
 /* Configure GPIOs with mainboard provided settings */
 void setup_pch_gpios(const struct pch_gpio_map *gpio);
 
-/* get GPIO pin value */
-int get_gpio(int gpio_num);
-/*
- * get a number comprised of multiple GPIO values. gpio_num_array points to
- * the array of gpio pin numbers to scan, terminated by -1.
- */
-unsigned get_gpios(const int *gpio_num_array);
-
 #endif
diff --git a/src/southbridge/intel/lynxpoint/lp_gpio.c b/src/southbridge/intel/lynxpoint/lp_gpio.c
new file mode 100644
index 0000000..2d2e057
--- /dev/null
+++ b/src/southbridge/intel/lynxpoint/lp_gpio.c
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#ifdef __PRE_RAM__
+#include <arch/romcc_io.h>
+#else
+#include <device/device.h>
+#include <device/pci.h>
+#endif
+
+#include "pch.h"
+#include "lp_gpio.h"
+
+static u16 get_gpio_base(void)
+{
+#ifdef __PRE_RAM__
+	return pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc;
+#else
+	return pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)),
+				 GPIO_BASE) & 0xfffc;
+#endif
+}
+
+void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[])
+{
+	u16 gpio_base = get_gpio_base();
+	const struct pch_lp_gpio_map *config;
+	u32 owner[3] = {0};
+	u32 route[3] = {0};
+	u32 irqen[3] = {0};
+	u32 reset[3] = {0};
+	u32 blink = 0;
+	int set, bit;
+
+	for (config = map; config->gpio != GPIO_LIST_END; config++) {
+		if (config->gpio > MAX_GPIO_NUMBER)
+			continue;
+
+		/* Setup Configuration registers 1 and 2 */
+		outl(config->conf0, gpio_base + GPIO_CONFIG0(config->gpio));
+		outl(config->conf1, gpio_base + GPIO_CONFIG1(config->gpio));
+
+		/* Determine set and bit based on GPIO number */
+		set = config->gpio >> 5;
+		bit = config->gpio % 32;
+
+		/* Apply settings to set specific bits */
+		owner[set] |= config->owner << bit;
+		route[set] |= config->route << bit;
+		irqen[set] |= config->irqen << bit;
+		reset[set] |= config->reset << bit;
+
+		if (set == 0)
+			blink |= config->blink << bit;
+	}
+
+	for (set = 0; set <= 2; set++) {
+		outl(owner[set], gpio_base + GPIO_OWNER(set));
+		outl(route[set], gpio_base + GPIO_ROUTE(set));
+		outl(irqen[set], gpio_base + GPIO_IRQ_IE(set));
+		outl(reset[set], gpio_base + GPIO_RESET(set));
+	}
+
+	outl(blink, gpio_base + GPIO_BLINK);
+}
+
+int get_gpio(int gpio_num)
+{
+	u16 gpio_base = get_gpio_base();
+
+	if (gpio_num < MAX_GPIO_NUMBER)
+		return 0;
+
+	return !!(inl(gpio_base + GPIO_CONFIG0(gpio_num)) & GPI_LEVEL);
+}
+
+/*
+ * get a number comprised of multiple GPIO values. gpio_num_array points to
+ * the array of gpio pin numbers to scan, terminated by -1.
+ */
+unsigned get_gpios(const int *gpio_num_array)
+{
+	int gpio;
+	unsigned bitmask = 1;
+	unsigned vector = 0;
+
+	while (bitmask &&
+	       ((gpio = *gpio_num_array++) != -1)) {
+		if (get_gpio(gpio))
+			vector |= bitmask;
+		bitmask <<= 1;
+	}
+	return vector;
+}
diff --git a/src/southbridge/intel/lynxpoint/lp_gpio.h b/src/southbridge/intel/lynxpoint/lp_gpio.h
new file mode 100644
index 0000000..067b6e2
--- /dev/null
+++ b/src/southbridge/intel/lynxpoint/lp_gpio.h
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef INTEL_LYNXPOINT_LP_GPIO_H
+#define INTEL_LYNXPOINT_LP_GPIO_H
+
+/* LynxPoint LP GPIOBASE Registers */
+#define GPIO_OWNER(set)		(0x00 + ((set) * 4))
+#define GPIO_PIRQ_APIC_EN	0x10
+#define GPIO_BLINK		0x18
+#define GPIO_SER_BLINK		0x1c
+#define GPIO_SER_BLINK_CS	0x20
+#define GPIO_SER_BLINK_DATA	0x24
+#define GPIO_ROUTE(set)		(0x30 + ((set) * 4))
+#define GPIO_ALT_GPI_SMI_STS	0x50
+#define GPIO_ALT_GPI_SMI_EN	0x54
+#define GPIO_RESET(set)		(0x60 + ((set) * 4))
+#define GPIO_GLOBAL_CONFIG	0x7c
+#define GPIO_IRQ_IS(set)	(0x80 + ((set) * 4))
+#define GPIO_IRQ_IE(set)	(0x90 + ((set) * 4))
+#define GPIO_CONFIG0(gpio)	(0x100 + ((gpio) * 8))
+#define GPIO_CONFIG1(gpio)	(0x104 + ((gpio) * 8))
+
+#define MAX_GPIO_NUMBER		94 /* zero based */
+#define GPIO_LIST_END		0xff
+
+/* conf0 */
+
+#define GPIO_MODE_NATIVE	(0 << 0)
+#define GPIO_MODE_GPIO		(1 << 0)
+
+#define GPIO_DIR_OUTPUT		(0 << 2)
+#define GPIO_DIR_INPUT		(1 << 2)
+
+#define GPIO_NO_INVERT		(0 << 3)
+#define GPIO_INVERT		(1 << 3)
+
+#define GPIO_IRQ_EDGE		(0 << 4)
+#define GPIO_IRQ_LEVEL		(1 << 4)
+
+#define GPI_LEVEL		(1 << 30)
+
+#define GPO_LEVEL_LOW		(0 << 31)
+#define GPO_LEVEL_HIGH		(1 << 31)
+
+/* conf1 */
+
+#define GPIO_PULL_NONE		(0 << 0)
+#define GPIO_PULL_DOWN		(1 << 0)
+#define GPIO_PULL_UP		(2 << 0)
+
+#define GPIO_SENSE_ENABLE	(0 << 2)
+#define GPIO_SENSE_DISABLE	(1 << 2)
+
+/* owner */
+
+#define GPIO_OWNER_ACPI		0
+#define GPIO_OWNER_GPIO		1
+
+/* route */
+
+#define GPIO_ROUTE_SCI		0
+#define GPIO_ROUTE_SMI		1
+
+/* irqen */
+
+#define GPIO_IRQ_DISABLE	0
+#define GPIO_IRQ_ENABLE		1
+
+/* blink */
+
+#define GPO_NO_BLINK		0
+#define GPO_BLINK		1
+
+/* reset */
+
+#define GPIO_RESET_PWROK	0
+#define GPIO_RESET_RSMRST	1
+
+struct pch_lp_gpio_map {
+	u8 gpio;
+	u32 conf0;
+	u32 conf1;
+	u8 owner;
+	u8 route;
+	u8 irqen;
+	u8 reset;
+	u8 blink;
+} __attribute__ ((packed));
+
+/* Configure GPIOs with mainboard provided settings */
+void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[]);
+
+#endif
diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c
index a121e49..378d624 100644
--- a/src/southbridge/intel/lynxpoint/lpc.c
+++ b/src/southbridge/intel/lynxpoint/lpc.c
@@ -561,13 +561,20 @@ static void pch_lpc_read_resources(device_t dev)
 	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
 		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
 
+	/* GPIOBASE */
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
+	res->base = DEFAULT_GPIOBASE;
+	res->size = DEFAULT_GPIOSIZE;
+	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
 	res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
 	res->base = 0xff800000;
 	res->size = 0x00800000; /* 8 MB for flash */
 	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
 		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
 
-	res = new_resource(dev, 3); /* IOAPIC */
+	res = new_resource(dev, io_index++); /* IOAPIC */
 	res->base = IO_APIC_ADDR;
 	res->size = 0x00001000;
 	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
index 81e0131..fa8d75f 100644
--- a/src/southbridge/intel/lynxpoint/pch.h
+++ b/src/southbridge/intel/lynxpoint/pch.h
@@ -63,10 +63,16 @@
  */
 #define SMBUS_IO_BASE		0x0400
 #define SMBUS_SLAVE_ADDR	0x24
-/* TODO Make sure these don't get changed by stage2 */
-#define DEFAULT_GPIOBASE	0x0480
 #define DEFAULT_PMBASE		0x0500
 
+#if CONFIG_INTEL_LYNXPOINT_LP
+#define DEFAULT_GPIOBASE	0x1000
+#define DEFAULT_GPIOSIZE	0x400
+#else
+#define DEFAULT_GPIOBASE	0x480
+#define DEFAULT_GPIOSIZE	0x80
+#endif
+
 #define HPET_ADDR		0xfed00000
 #define DEFAULT_RCBA		0xfed1c000
 
@@ -97,6 +103,15 @@ void enable_usb_bar(void);
 int smbus_read_byte(unsigned device, unsigned address);
 int early_spi_read(u32 offset, u32 size, u8 *buffer);
 #endif
+/*
+ * get GPIO pin value
+ */
+int get_gpio(int gpio_num);
+/*
+ * get a number comprised of multiple GPIO values. gpio_num_array points to
+ * the array of gpio pin numbers to scan, terminated by -1.
+ */
+unsigned get_gpios(const int *gpio_num_array);
 #endif
 
 #define MAINBOARD_POWER_OFF	0
@@ -434,22 +449,6 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
 #define PCH_DISABLE_MEI1	(1 << 1)
 #define PCH_ENABLE_DBDF		(1 << 0)
 
-/* ICH7 GPIOBASE */
-#define GPIO_USE_SEL	0x00
-#define GP_IO_SEL	0x04
-#define GP_LVL		0x0c
-#define GPO_BLINK	0x18
-#define GPI_INV		0x2c
-#define GPIO_USE_SEL2	0x30
-#define GP_IO_SEL2	0x34
-#define GP_LVL2		0x38
-#define GPIO_USE_SEL3	0x40
-#define GP_IO_SEL3	0x44
-#define GP_LVL3		0x48
-#define GP_RST_SEL1	0x60
-#define GP_RST_SEL2	0x64
-#define GP_RST_SEL3	0x68
-
 /* ICH7 PMBASE */
 #define PM1_STS		0x00
 #define   WAK_STS	(1 << 15)



More information about the coreboot mailing list