[coreboot-gerrit] Patch set updated for coreboot: sb/ich7: Use common/gpio.h to set up GPIOs

Arthur Heymans (arthur@aheymans.xyz) gerrit at coreboot.org
Wed Jan 4 12:41:10 CET 2017


Arthur Heymans (arthur at aheymans.xyz) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17639

-gerrit

commit f4c089ad76219b0113700e7d2335b8a2d3f3c877
Author: Arthur Heymans <arthur at aheymans.xyz>
Date:   Tue Nov 29 14:13:43 2016 +0100

    sb/ich7: Use common/gpio.h to set up GPIOs
    
    This is more consistent with newer Intel targets.
    
    This a static struct so it is initialized at 0 by default.
    To make it more readable:
    * only setting to GPIO mode is made explicit;
    * only pins in GPIO mode are either set to input or output since this
      is ignored in native mode;
    * only output pins are set high or low, since this is read-only on
      input;
    * blink is only operational on output pins, non-blink is not set
      explicitly;
    * invert is only operational in input pins, non-invert is not set
      explicitly.
    
    Change-Id: I05f9c52dee78b7120b225982c040e3dcc8ee3e4e
    Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
 src/mainboard/apple/macbook21/Makefile.inc        |   1 +
 src/mainboard/apple/macbook21/gpio.c              | 122 ++++++++++++++++++++
 src/mainboard/apple/macbook21/romstage.c          |  52 ---------
 src/mainboard/getac/p470/Makefile.inc             |   1 +
 src/mainboard/getac/p470/gpio.c                   | 115 +++++++++++++++++++
 src/mainboard/getac/p470/romstage.c               |  28 +----
 src/mainboard/gigabyte/ga-945gcm-s2l/Makefile.inc |   1 +
 src/mainboard/gigabyte/ga-945gcm-s2l/gpio.c       | 118 +++++++++++++++++++
 src/mainboard/gigabyte/ga-945gcm-s2l/romstage.c   |  17 ---
 src/mainboard/gigabyte/ga-g41m-es2l/Makefile.inc  |   1 +
 src/mainboard/gigabyte/ga-g41m-es2l/gpio.c        | 117 +++++++++++++++++++
 src/mainboard/gigabyte/ga-g41m-es2l/romstage.c    |  10 +-
 src/mainboard/ibase/mb899/Makefile.inc            |   1 +
 src/mainboard/ibase/mb899/gpio.c                  | 116 +++++++++++++++++++
 src/mainboard/ibase/mb899/romstage.c              |  16 ---
 src/mainboard/intel/d510mo/Makefile.inc           |   1 +
 src/mainboard/intel/d510mo/gpio.c                 | 125 ++++++++++++++++++++
 src/mainboard/intel/d510mo/romstage.c             |  10 +-
 src/mainboard/intel/d945gclf/Makefile.inc         |   1 +
 src/mainboard/intel/d945gclf/gpio.c               | 122 ++++++++++++++++++++
 src/mainboard/intel/d945gclf/romstage.c           |  17 ---
 src/mainboard/kontron/986lcd-m/Makefile.inc       |   1 +
 src/mainboard/kontron/986lcd-m/gpio.c             | 132 ++++++++++++++++++++++
 src/mainboard/kontron/986lcd-m/romstage.c         |  16 ---
 src/mainboard/lenovo/t60/Makefile.inc             |   1 +
 src/mainboard/lenovo/t60/gpio.c                   | 112 ++++++++++++++++++
 src/mainboard/lenovo/t60/romstage.c               |  36 +-----
 src/mainboard/lenovo/x60/Makefile.inc             |   1 +
 src/mainboard/lenovo/x60/gpio.c                   | 111 ++++++++++++++++++
 src/mainboard/lenovo/x60/romstage.c               |  43 +------
 src/mainboard/roda/rk886ex/Makefile.inc           |   1 +
 src/mainboard/roda/rk886ex/gpio.c                 | 117 +++++++++++++++++++
 src/mainboard/roda/rk886ex/romstage.c             |  30 -----
 src/northbridge/intel/i945/early_init.c           |   3 +-
 src/southbridge/intel/i82801gx/Kconfig            |   1 +
 35 files changed, 1332 insertions(+), 265 deletions(-)

diff --git a/src/mainboard/apple/macbook21/Makefile.inc b/src/mainboard/apple/macbook21/Makefile.inc
new file mode 100644
index 0000000..6048409
--- /dev/null
+++ b/src/mainboard/apple/macbook21/Makefile.inc
@@ -0,0 +1 @@
+romstage-y += gpio.c
\ No newline at end of file
diff --git a/src/mainboard/apple/macbook21/gpio.c b/src/mainboard/apple/macbook21/gpio.c
new file mode 100644
index 0000000..53c5c96
--- /dev/null
+++ b/src/mainboard/apple/macbook21/gpio.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio1 = GPIO_MODE_GPIO,
+	.gpio5 = GPIO_MODE_GPIO,
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio22 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio1 = GPIO_DIR_INPUT,
+	.gpio5 = GPIO_DIR_OUTPUT,
+	.gpio6 = GPIO_DIR_OUTPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_OUTPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_OUTPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio22 = GPIO_DIR_OUTPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_INPUT,
+	.gpio26 = GPIO_DIR_INPUT,
+	.gpio27 = GPIO_DIR_INPUT,
+	.gpio28 = GPIO_DIR_INPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+#if (CONFIG_BOARD_APPLE_MACBOOK11 || CONFIG_BOARD_APPLE_MACBOOK21)
+	.gpio5 = GPIO_LEVEL_LOW,
+#else /* CONFIG_BOARD_APPLE_IMAC52 */
+	.gpio5 = GPIO_LEVEL_HIGH,
+#endif
+	.gpio6 = GPIO_LEVEL_HIGH,
+	.gpio12 = GPIO_LEVEL_LOW,
+	.gpio14 = GPIO_LEVEL_HIGH,
+	.gpio22 = GPIO_LEVEL_HIGH,
+	.gpio24 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio1 = GPIO_INVERT,
+	.gpio7 = GPIO_INVERT,
+#if (CONFIG_BOARD_APPLE_MACBOOK11 || CONFIG_BOARD_APPLE_MACBOOK21)
+	.gpio13 = GPIO_INVERT,
+#endif
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+#if CONFIG_BOARD_APPLE_IMAC52
+	.gpio35 = GPIO_MODE_GPIO,
+#endif
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+	.gpio48 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+#if CONFIG_BOARD_APPLE_IMAC52
+	.gpio35 = GPIO_DIR_OUTPUT,
+#endif
+	.gpio38 = GPIO_DIR_OUTPUT,
+	.gpio39 = GPIO_DIR_OUTPUT,
+	.gpio48 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+#if CONFIG_BOARD_APPLE_IMAC52
+	.gpio35 = GPIO_LEVEL_LOW,
+#endif
+	.gpio38 = GPIO_LEVEL_HIGH,
+	.gpio39 = GPIO_LEVEL_HIGH,
+	.gpio48 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/apple/macbook21/romstage.c b/src/mainboard/apple/macbook21/romstage.c
index 391b09f..962ad41 100644
--- a/src/mainboard/apple/macbook21/romstage.c
+++ b/src/mainboard/apple/macbook21/romstage.c
@@ -35,58 +35,6 @@
 #include <northbridge/intel/i945/raminit.h>
 #include <southbridge/intel/i82801gx/i82801gx.h>
 
-void setup_ich7_gpios(void)
-{
-	printk(BIOS_DEBUG, " GPIOS...");
-
-	/* X60 GPIO:
-	 * 1: HDD_PRESENCE#
-	 * 6: Unknown (Pulled high by R215 to VCC3B)
-	 * 7: BDC_PRESENCE#
-	 * 8: H8_WAKE#
-	 * 9: RTC_BAT_IN#
-	 * 10: Unknown (Pulled high by R700 to VCC3M)
-	 * 12: H8SCI#
-	 * 13: SLICE_ON_3M#
-	 * 14: Unknown (Pulled high by R321 to VCC3)
-	 * 15: Unknown (Pulled high by R258 to VCC3)
-	 * 19: Unknown (Pulled low  by R594)
-	 * 21: Unknown (Pulled high by R145 to VCC3)
-	 * 22: FWH_WP#
-	 * 25: MDC_KILL#
-	 * 33: HDD_PRESENCE_2#
-	 * 35: CLKREQ_SATA#
-	 * 36: PLANARID0
-	 * 37: PLANARID1
-	 * 38: PLANARID2
-	 * 39: PLANARID3
-	 * 48: FWH_TBL#
-	 */
-#if (CONFIG_BOARD_APPLE_MACBOOK11 || CONFIG_BOARD_APPLE_MACBOOK21)
-	outl(0x1f40f7e2, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xfea8af83, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xfcc06bdf, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x00002082, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000100c0, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x00000030, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x000100c0, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL2 */
-#else /* CONFIG_BOARD_APPLE_IMAC52 */
-	outl(0x1f40f7c2, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xfea8af83, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xfcc06bff, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x00000082, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000100c8, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x00000030, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x000100c0, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL2 */
-#endif
-}
-
 static void ich7_enable_lpc(void)
 {
 	/* Enable Serial IRQ */
diff --git a/src/mainboard/getac/p470/Makefile.inc b/src/mainboard/getac/p470/Makefile.inc
index 07d9918..ed9d39c 100644
--- a/src/mainboard/getac/p470/Makefile.inc
+++ b/src/mainboard/getac/p470/Makefile.inc
@@ -14,3 +14,4 @@
 ##
 
 ramstage-y += cstates.c
+romstage-y += gpio.c
diff --git a/src/mainboard/getac/p470/gpio.c b/src/mainboard/getac/p470/gpio.c
new file mode 100644
index 0000000..be52a86
--- /dev/null
+++ b/src/mainboard/getac/p470/gpio.c
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio1 = GPIO_MODE_GPIO,
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio19 = GPIO_MODE_GPIO,
+	.gpio21 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio1 = GPIO_DIR_INPUT,
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_OUTPUT,
+	.gpio10 = GPIO_DIR_OUTPUT,
+	.gpio12 = GPIO_DIR_OUTPUT,
+	.gpio13 = GPIO_DIR_OUTPUT,
+	.gpio14 = GPIO_DIR_OUTPUT,
+	.gpio15 = GPIO_DIR_OUTPUT,
+	.gpio19 = GPIO_DIR_INPUT,
+	.gpio21 = GPIO_DIR_INPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio9 = GPIO_LEVEL_HIGH,
+	.gpio10 = GPIO_LEVEL_HIGH,
+	.gpio12 = GPIO_LEVEL_HIGH,
+	.gpio13 = GPIO_LEVEL_HIGH,
+	.gpio14 = GPIO_LEVEL_LOW,
+	.gpio15 = GPIO_LEVEL_LOW,
+	.gpio24 = GPIO_LEVEL_LOW,
+	.gpio25 = GPIO_LEVEL_HIGH,
+	.gpio26 = GPIO_LEVEL_HIGH,
+	.gpio27 = GPIO_LEVEL_HIGH,
+	.gpio28 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio33 = GPIO_MODE_GPIO,
+	.gpio34 = GPIO_MODE_GPIO,
+	.gpio37 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio33 = GPIO_DIR_OUTPUT,
+	.gpio34 = GPIO_DIR_OUTPUT,
+	.gpio37 = GPIO_DIR_OUTPUT,
+	.gpio38 = GPIO_DIR_INPUT,
+	.gpio39 = GPIO_DIR_INPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio33 = GPIO_LEVEL_LOW,
+	.gpio34 = GPIO_LEVEL_HIGH,
+	.gpio37 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/getac/p470/romstage.c b/src/mainboard/getac/p470/romstage.c
index db675dc..145d615 100644
--- a/src/mainboard/getac/p470/romstage.c
+++ b/src/mainboard/getac/p470/romstage.c
@@ -34,34 +34,10 @@
 #include <timestamp.h>
 #include "option_table.h"
 
-void setup_ich7_gpios(void)
+static void setup_special_ich7_gpios(void)
 {
 	u32 gpios;
 
-	printk(BIOS_DEBUG, " GPIOS...");
-	/* General Registers */
-	outl(0x1f28f7c2, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xe0e809c3, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	// Power On value is eede1fbf, we set: (TODO explain why)
-	//   -- [21] = 1
-	//   -- [20] = 0
-	//   -- [18] = 0
-	//   -- [17] = 0
-	//   -- [13] = 1
-	//   -- [05] = 0
-	//   -- [04] = 0
-	//   -- [03] = 0
-	//   -- [02] = 0
-	//   We should probably do this explicitly bitwise, see below.
-	outl(0xeee83f83, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x00000180, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000000e6, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x000000d0, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x00000034, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL2 */
-
 	printk(BIOS_SPEW, "\n  Initializing drive bay...\n");
 	gpios = inl(DEFAULT_GPIOBASE + 0x38); // GPIO Level 2
 	gpios |= (1 << 0); // GPIO33 = ODD
@@ -297,6 +273,8 @@ void mainboard_romstage_entry(unsigned long bist)
 	 */
 	i945_early_initialization();
 
+	setup_special_ich7_gpios();
+
 	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
diff --git a/src/mainboard/gigabyte/ga-945gcm-s2l/Makefile.inc b/src/mainboard/gigabyte/ga-945gcm-s2l/Makefile.inc
index f9621db..f3d7e76 100644
--- a/src/mainboard/gigabyte/ga-945gcm-s2l/Makefile.inc
+++ b/src/mainboard/gigabyte/ga-945gcm-s2l/Makefile.inc
@@ -1 +1,2 @@
 ramstage-y += cstates.c
+romstage-y += gpio.c
diff --git a/src/mainboard/gigabyte/ga-945gcm-s2l/gpio.c b/src/mainboard/gigabyte/ga-945gcm-s2l/gpio.c
new file mode 100644
index 0000000..38e0100
--- /dev/null
+++ b/src/mainboard/gigabyte/ga-945gcm-s2l/gpio.c
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio0 = GPIO_MODE_GPIO,
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio16 = GPIO_MODE_GPIO,
+	.gpio18 = GPIO_MODE_GPIO,
+	.gpio20 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio0 = GPIO_DIR_INPUT,
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_INPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio16 = GPIO_DIR_OUTPUT,
+	.gpio18 = GPIO_DIR_OUTPUT,
+	.gpio20 = GPIO_DIR_OUTPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio16 = GPIO_LEVEL_LOW,
+	.gpio18 = GPIO_LEVEL_HIGH,
+	.gpio20 = GPIO_LEVEL_HIGH,
+	.gpio24 = GPIO_LEVEL_LOW,
+	.gpio25 = GPIO_LEVEL_HIGH,
+	.gpio26 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_LOW,
+	.gpio28 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio0 = GPIO_INVERT,
+	.gpio6 = GPIO_INVERT,
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+	.gpio12 = GPIO_INVERT,
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio32 = GPIO_MODE_GPIO,
+	.gpio33 = GPIO_MODE_GPIO,
+	.gpio34 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio32 = GPIO_DIR_OUTPUT,
+	.gpio33 = GPIO_DIR_OUTPUT,
+	.gpio34 = GPIO_DIR_OUTPUT,
+	.gpio38 = GPIO_DIR_INPUT,
+	.gpio39 = GPIO_DIR_INPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio32 = GPIO_LEVEL_LOW,
+	.gpio33 = GPIO_LEVEL_HIGH,
+	.gpio34 = GPIO_LEVEL_LOW,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/gigabyte/ga-945gcm-s2l/romstage.c b/src/mainboard/gigabyte/ga-945gcm-s2l/romstage.c
index d84eae1..4dfff06 100644
--- a/src/mainboard/gigabyte/ga-945gcm-s2l/romstage.c
+++ b/src/mainboard/gigabyte/ga-945gcm-s2l/romstage.c
@@ -40,23 +40,6 @@
 #define EC_DEV PNP_DEV(0x2e, IT8718F_EC)
 #define SUPERIO_DEV PNP_DEV(0x2e, 0)
 
-void setup_ich7_gpios(void)
-{
-	/* TODO: This is highly board specific and should be moved */
-	printk(BIOS_DEBUG, " GPIOS...");
-	/* General Registers */
-	outl(0x1f15f7c1, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xe0e8ffc3, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xe2fefc03, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00400000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000000c7, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x000000f0, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x000000f2, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL2 */
-}
-
 static void setup_sio(void)
 {
 	/* Set default GPIOs on superio */
diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/Makefile.inc b/src/mainboard/gigabyte/ga-g41m-es2l/Makefile.inc
index f9621db..f3d7e76 100644
--- a/src/mainboard/gigabyte/ga-g41m-es2l/Makefile.inc
+++ b/src/mainboard/gigabyte/ga-g41m-es2l/Makefile.inc
@@ -1 +1,2 @@
 ramstage-y += cstates.c
+romstage-y += gpio.c
diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/gpio.c b/src/mainboard/gigabyte/ga-g41m-es2l/gpio.c
new file mode 100644
index 0000000..e06a8f1
--- /dev/null
+++ b/src/mainboard/gigabyte/ga-g41m-es2l/gpio.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio16 = GPIO_MODE_GPIO,
+	.gpio18 = GPIO_MODE_GPIO,
+	.gpio20 = GPIO_MODE_GPIO,
+	.gpio21 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_INPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio16 = GPIO_DIR_INPUT,
+	.gpio18 = GPIO_DIR_OUTPUT,
+	.gpio20 = GPIO_DIR_OUTPUT,
+	.gpio21 = GPIO_DIR_INPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_INPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio18 = GPIO_LEVEL_HIGH,
+	.gpio20 = GPIO_LEVEL_HIGH,
+	.gpio24 = GPIO_LEVEL_LOW,
+	.gpio26 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_LOW,
+	.gpio28 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio6 = GPIO_INVERT,
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+	.gpio12 = GPIO_INVERT,
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio32 = GPIO_MODE_GPIO,
+	.gpio33 = GPIO_MODE_GPIO,
+	.gpio34 = GPIO_MODE_GPIO,
+	.gpio37 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio32 = GPIO_DIR_OUTPUT,
+	.gpio33 = GPIO_DIR_OUTPUT,
+	.gpio34 = GPIO_DIR_OUTPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_INPUT,
+	.gpio39 = GPIO_DIR_INPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio32 = GPIO_LEVEL_HIGH,
+	.gpio33 = GPIO_LEVEL_HIGH,
+	.gpio34 = GPIO_LEVEL_LOW,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c b/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c
index 2503db9..0f43795 100644
--- a/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c
+++ b/src/mainboard/gigabyte/ga-g41m-es2l/romstage.c
@@ -21,6 +21,7 @@
 #include <device/pnp_def.h>
 #include <console/console.h>
 #include <southbridge/intel/i82801gx/i82801gx.h>
+#include <southbridge/intel/common/gpio.h>
 #include <northbridge/intel/x4x/x4x.h>
 #include <cpu/x86/bist.h>
 #include <cpu/intel/romstage.h>
@@ -50,14 +51,7 @@ static void mb_gpio_init(void)
 	pci_write_config32(dev, GPIO_BASE, (DEFAULT_GPIOBASE | 1));
 	pci_write_config8(dev, GPIO_CNTL, 0x10);
 
-	outl(0x1f35f7c0, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */
-	outl(0xe2e9ffc3, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */
-	outl(0xe0d7ec02, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18); /* GPO_BLINK */
-	outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */
-	outl(0x000000e7, DEFAULT_GPIOBASE + 0x30);
-	outl(0x000000f0, DEFAULT_GPIOBASE + 0x34);
-	outl(0x00000083, DEFAULT_GPIOBASE + 0x38);
+	setup_pch_gpios(&mainboard_gpio_map);
 
 	/* Set default GPIOs on superio */
 	ite_reg_write(GPIO_DEV, 0x25, 0x00);
diff --git a/src/mainboard/ibase/mb899/Makefile.inc b/src/mainboard/ibase/mb899/Makefile.inc
index 0b70b89..8db0ada 100644
--- a/src/mainboard/ibase/mb899/Makefile.inc
+++ b/src/mainboard/ibase/mb899/Makefile.inc
@@ -1,2 +1,3 @@
 ramstage-y += superio_hwm.c
 ramstage-y += cstates.c
+romstage-y += gpio.c
\ No newline at end of file
diff --git a/src/mainboard/ibase/mb899/gpio.c b/src/mainboard/ibase/mb899/gpio.c
new file mode 100644
index 0000000..110219e
--- /dev/null
+++ b/src/mainboard/ibase/mb899/gpio.c
@@ -0,0 +1,116 @@
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio16 = GPIO_MODE_GPIO,
+	.gpio17 = GPIO_MODE_GPIO,
+	.gpio18 = GPIO_MODE_GPIO,
+	.gpio19 = GPIO_MODE_GPIO,
+	.gpio20 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_OUTPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio16 = GPIO_DIR_OUTPUT,
+	.gpio17 = GPIO_DIR_OUTPUT,
+	.gpio18 = GPIO_DIR_OUTPUT,
+	.gpio19 = GPIO_DIR_INPUT,
+	.gpio20 = GPIO_DIR_OUTPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio12 = GPIO_LEVEL_LOW,
+	.gpio16 = GPIO_LEVEL_HIGH,
+	.gpio17 = GPIO_LEVEL_HIGH,
+	.gpio18 = GPIO_LEVEL_HIGH,
+	.gpio20 = GPIO_LEVEL_HIGH,
+	.gpio24 = GPIO_LEVEL_HIGH,
+	.gpio25 = GPIO_LEVEL_HIGH,
+	.gpio26 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_HIGH,
+	.gpio28 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio32 = GPIO_MODE_GPIO,
+	.gpio33 = GPIO_MODE_GPIO,
+	.gpio34 = GPIO_MODE_GPIO,
+	.gpio35 = GPIO_MODE_GPIO,
+	.gpio36 = GPIO_MODE_GPIO,
+	.gpio37 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+	.gpio48 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio32 = GPIO_DIR_OUTPUT,
+	.gpio33 = GPIO_DIR_OUTPUT,
+	.gpio34 = GPIO_DIR_OUTPUT,
+	.gpio35 = GPIO_DIR_OUTPUT,
+	.gpio36 = GPIO_DIR_INPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_OUTPUT,
+	.gpio39 = GPIO_DIR_OUTPUT,
+	.gpio48 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio32 = GPIO_LEVEL_HIGH,
+	.gpio33 = GPIO_LEVEL_LOW,
+	.gpio34 = GPIO_LEVEL_HIGH,
+	.gpio35 = GPIO_LEVEL_LOW,
+	.gpio38 = GPIO_LEVEL_LOW,
+	.gpio39 = GPIO_LEVEL_LOW,
+	.gpio48 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/ibase/mb899/romstage.c b/src/mainboard/ibase/mb899/romstage.c
index 2a8965e..dc9d622 100644
--- a/src/mainboard/ibase/mb899/romstage.c
+++ b/src/mainboard/ibase/mb899/romstage.c
@@ -38,22 +38,6 @@
 #define SERIAL_DEV PNP_DEV(0x4e, W83627EHG_SP1)
 #define DUMMY_DEV PNP_DEV(0x4e, 0)
 
-void setup_ich7_gpios(void)
-{
-	printk(BIOS_DEBUG, " GPIOS...");
-	/* General Registers */
-	outl(0x1f1ff7c0, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xe0e8efc3, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xebffeeff, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x00002180, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000100ff, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x00000030, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x00010035, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL */
-}
-
 static void ich7_enable_lpc(void)
 {
 	// Enable Serial IRQ
diff --git a/src/mainboard/intel/d510mo/Makefile.inc b/src/mainboard/intel/d510mo/Makefile.inc
index f9621db..f3d7e76 100644
--- a/src/mainboard/intel/d510mo/Makefile.inc
+++ b/src/mainboard/intel/d510mo/Makefile.inc
@@ -1 +1,2 @@
 ramstage-y += cstates.c
+romstage-y += gpio.c
diff --git a/src/mainboard/intel/d510mo/gpio.c b/src/mainboard/intel/d510mo/gpio.c
new file mode 100644
index 0000000..81e23ba
--- /dev/null
+++ b/src/mainboard/intel/d510mo/gpio.c
@@ -0,0 +1,125 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio0 = GPIO_MODE_GPIO,
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio16 = GPIO_MODE_GPIO,
+	.gpio19 = GPIO_MODE_GPIO,
+	.gpio20 = GPIO_MODE_GPIO,
+	.gpio21 = GPIO_MODE_GPIO,
+	.gpio22 = GPIO_MODE_GPIO,
+	.gpio23 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio0 = GPIO_DIR_INPUT,
+	.gpio6 = GPIO_DIR_OUTPUT,
+	.gpio7 = GPIO_DIR_OUTPUT,
+	.gpio8 = GPIO_DIR_OUTPUT,
+	.gpio9 = GPIO_DIR_OUTPUT,
+	.gpio10 = GPIO_DIR_OUTPUT,
+	.gpio12 = GPIO_DIR_OUTPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio16 = GPIO_DIR_INPUT,
+	.gpio19 = GPIO_DIR_INPUT,
+	.gpio20 = GPIO_DIR_OUTPUT,
+	.gpio21 = GPIO_DIR_INPUT,
+	.gpio22 = GPIO_DIR_INPUT,
+	.gpio23 = GPIO_DIR_INPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio6 = GPIO_LEVEL_HIGH,
+	.gpio7 = GPIO_LEVEL_LOW,
+	.gpio8 = GPIO_LEVEL_LOW,
+	.gpio9 = GPIO_LEVEL_LOW,
+	.gpio10 = GPIO_LEVEL_LOW,
+	.gpio12 = GPIO_LEVEL_LOW,
+	.gpio20 = GPIO_LEVEL_LOW,
+	.gpio24 = GPIO_LEVEL_LOW,
+	.gpio25 = GPIO_LEVEL_LOW,
+	.gpio26 = GPIO_LEVEL_HIGH,
+	.gpio27 = GPIO_LEVEL_HIGH,
+	.gpio28 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio33 = GPIO_MODE_GPIO,
+	.gpio34 = GPIO_MODE_GPIO,
+	.gpio35 = GPIO_MODE_GPIO,
+	.gpio36 = GPIO_MODE_GPIO,
+	.gpio37 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio33 = GPIO_DIR_INPUT,
+	.gpio34 = GPIO_DIR_INPUT,
+	.gpio35 = GPIO_DIR_INPUT,
+	.gpio36 = GPIO_DIR_INPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_INPUT,
+	.gpio39 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio39 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/intel/d510mo/romstage.c b/src/mainboard/intel/d510mo/romstage.c
index f73bf64..3209d81 100644
--- a/src/mainboard/intel/d510mo/romstage.c
+++ b/src/mainboard/intel/d510mo/romstage.c
@@ -21,6 +21,7 @@
 #include <device/pnp_def.h>
 #include <console/console.h>
 #include <southbridge/intel/i82801gx/i82801gx.h>
+#include <southbridge/intel/common/gpio.h>
 #include <northbridge/intel/pineview/raminit.h>
 #include <northbridge/intel/pineview/pineview.h>
 #include <cpu/x86/bist.h>
@@ -47,14 +48,7 @@ static void mb_gpio_init(void)
 	pci_write_config32(dev, GPIO_BASE, (DEFAULT_GPIOBASE | 1));
 	pci_write_config8(dev, GPIO_CNTL, 0x10);
 
-	outl(0x1ff9f7c1, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */
-	outl(0xe0e9e803, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */
-	outl(0xece9e842, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18); /* GPO_BLINK */
-	outl(0x00002000, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */
-	outl(0x000000fe, DEFAULT_GPIOBASE + 0x30);
-	outl(0x0000007e, DEFAULT_GPIOBASE + 0x34);
-	outl(0x000300f3, DEFAULT_GPIOBASE + 0x38);
+	setup_pch_gpios(&mainboard_gpio_map);
 }
 
 static void nm10_enable_lpc(void)
diff --git a/src/mainboard/intel/d945gclf/Makefile.inc b/src/mainboard/intel/d945gclf/Makefile.inc
index f9621db..f3d7e76 100644
--- a/src/mainboard/intel/d945gclf/Makefile.inc
+++ b/src/mainboard/intel/d945gclf/Makefile.inc
@@ -1 +1,2 @@
 ramstage-y += cstates.c
+romstage-y += gpio.c
diff --git a/src/mainboard/intel/d945gclf/gpio.c b/src/mainboard/intel/d945gclf/gpio.c
new file mode 100644
index 0000000..f5787f9
--- /dev/null
+++ b/src/mainboard/intel/d945gclf/gpio.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio0 = GPIO_MODE_GPIO,
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio16 = GPIO_MODE_GPIO,
+	.gpio18 = GPIO_MODE_GPIO,
+	.gpio19 = GPIO_MODE_GPIO,
+	.gpio20 = GPIO_MODE_GPIO,
+	.gpio21 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+	.gpio29 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio0 = GPIO_DIR_INPUT,
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_INPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_OUTPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio16 = GPIO_DIR_OUTPUT,
+	.gpio18 = GPIO_DIR_INPUT,
+	.gpio19 = GPIO_DIR_INPUT,
+	.gpio20 = GPIO_DIR_INPUT,
+	.gpio21 = GPIO_DIR_INPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_INPUT,
+	.gpio26 = GPIO_DIR_INPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+	.gpio29 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio14 = GPIO_LEVEL_HIGH,
+	.gpio16 = GPIO_LEVEL_LOW,
+	.gpio24 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_HIGH,
+	.gpio28 = GPIO_LEVEL_LOW,
+	.gpio29 = GPIO_LEVEL_HIGH,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio13 = GPIO_INVERT,
+	.gpio15 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio32 = GPIO_MODE_GPIO,
+	.gpio33 = GPIO_MODE_GPIO,
+	.gpio34 = GPIO_MODE_GPIO,
+	.gpio35 = GPIO_MODE_GPIO,
+	.gpio36 = GPIO_MODE_GPIO,
+	.gpio37 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio32 = GPIO_DIR_INPUT,
+	.gpio33 = GPIO_DIR_INPUT,
+	.gpio34 = GPIO_DIR_INPUT,
+	.gpio35 = GPIO_DIR_INPUT,
+	.gpio36 = GPIO_DIR_INPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_OUTPUT,
+	.gpio39 = GPIO_DIR_INPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio38 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/intel/d945gclf/romstage.c b/src/mainboard/intel/d945gclf/romstage.c
index 8077ba2..b61d3b9 100644
--- a/src/mainboard/intel/d945gclf/romstage.c
+++ b/src/mainboard/intel/d945gclf/romstage.c
@@ -36,23 +36,6 @@
 #define SERIAL_DEV PNP_DEV(0x2e, LPC47M15X_SP1)
 #define PME_DEV PNP_DEV(0x2e, LPC47M15X_PME)
 
-void setup_ich7_gpios(void)
-{
-	/* TODO: This is highly board specific and should be moved */
-	printk(BIOS_DEBUG, " GPIOS...");
-	/* General Registers */
-	outl(0x3f3df7c1, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xc6fcbfc3, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xecfefdff, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00040000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x0000a000, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000000ff, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x000000bf, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x000300fd, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL */
-}
-
 static void ich7_enable_lpc(void)
 {
 	// Enable Serial IRQ
diff --git a/src/mainboard/kontron/986lcd-m/Makefile.inc b/src/mainboard/kontron/986lcd-m/Makefile.inc
index f9621db..f3d7e76 100644
--- a/src/mainboard/kontron/986lcd-m/Makefile.inc
+++ b/src/mainboard/kontron/986lcd-m/Makefile.inc
@@ -1 +1,2 @@
 ramstage-y += cstates.c
+romstage-y += gpio.c
diff --git a/src/mainboard/kontron/986lcd-m/gpio.c b/src/mainboard/kontron/986lcd-m/gpio.c
new file mode 100644
index 0000000..c879a9c
--- /dev/null
+++ b/src/mainboard/kontron/986lcd-m/gpio.c
@@ -0,0 +1,132 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio6 = GPIO_MODE_GPIO,
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO,
+	.gpio16 = GPIO_MODE_GPIO,
+	.gpio17 = GPIO_MODE_GPIO,
+	.gpio18 = GPIO_MODE_GPIO,
+	.gpio19 = GPIO_MODE_GPIO,
+	.gpio20 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO,
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_OUTPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio16 = GPIO_DIR_OUTPUT,
+	.gpio17 = GPIO_DIR_OUTPUT,
+	.gpio18 = GPIO_DIR_OUTPUT,
+	.gpio19 = GPIO_DIR_INPUT,
+	.gpio20 = GPIO_DIR_OUTPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio12 = GPIO_LEVEL_LOW,
+	.gpio16 = GPIO_LEVEL_HIGH,
+	.gpio17 = GPIO_LEVEL_HIGH,
+	.gpio18 = GPIO_LEVEL_HIGH,
+	.gpio20 = GPIO_LEVEL_HIGH,
+	.gpio24 = GPIO_LEVEL_HIGH,
+	.gpio25 = GPIO_LEVEL_HIGH,
+	.gpio26 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_HIGH,
+	.gpio28 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio32 = GPIO_MODE_GPIO,
+	.gpio33 = GPIO_MODE_GPIO,
+	.gpio34 = GPIO_MODE_GPIO,
+	.gpio35 = GPIO_MODE_GPIO,
+	.gpio36 = GPIO_MODE_GPIO,
+	.gpio37 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+	.gpio48 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio32 = GPIO_DIR_OUTPUT,
+	.gpio33 = GPIO_DIR_OUTPUT,
+	.gpio34 = GPIO_DIR_OUTPUT,
+	.gpio35 = GPIO_DIR_OUTPUT,
+	.gpio36 = GPIO_DIR_OUTPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_OUTPUT,
+	.gpio39 = GPIO_DIR_OUTPUT,
+	.gpio48 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio32 = GPIO_LEVEL_HIGH,
+	.gpio33 = GPIO_LEVEL_LOW,
+	.gpio34 = GPIO_LEVEL_HIGH,
+	.gpio35 = GPIO_LEVEL_LOW,
+	.gpio36 = GPIO_LEVEL_HIGH,
+	.gpio38 = GPIO_LEVEL_LOW,
+	.gpio39 = GPIO_LEVEL_LOW,
+	.gpio48 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/kontron/986lcd-m/romstage.c b/src/mainboard/kontron/986lcd-m/romstage.c
index be51b7a..5fc4f76 100644
--- a/src/mainboard/kontron/986lcd-m/romstage.c
+++ b/src/mainboard/kontron/986lcd-m/romstage.c
@@ -37,22 +37,6 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627THG_SP1)
 
-void setup_ich7_gpios(void)
-{
-	printk(BIOS_DEBUG, " GPIOS...");
-	/* General Registers */
-	outl(0x1f1ff7c0, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xe0e8efc3, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xebffeeff, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x00002180, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000100ff, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x00000030, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x00010035, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL */
-}
-
 static void ich7_enable_lpc(void)
 {
 	int lpt_en = 0;
diff --git a/src/mainboard/lenovo/t60/Makefile.inc b/src/mainboard/lenovo/t60/Makefile.inc
index 065c423..8473a13 100644
--- a/src/mainboard/lenovo/t60/Makefile.inc
+++ b/src/mainboard/lenovo/t60/Makefile.inc
@@ -15,3 +15,4 @@
 
 smm-$(CONFIG_HAVE_SMI_HANDLER) += dock.c
 romstage-y += dock.c
+romstage-y += gpio.c
diff --git a/src/mainboard/lenovo/t60/gpio.c b/src/mainboard/lenovo/t60/gpio.c
new file mode 100644
index 0000000..f220b2b
--- /dev/null
+++ b/src/mainboard/lenovo/t60/gpio.c
@@ -0,0 +1,112 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio1 = GPIO_MODE_GPIO,
+	.gpio6 = GPIO_MODE_GPIO, /* LEGACYIO# */
+	.gpio7 = GPIO_MODE_GPIO, /* BDC_PRESENCE# */
+	.gpio8 = GPIO_MODE_GPIO, /* H8_WAKE# */
+	.gpio9 = GPIO_MODE_GPIO,
+	.gpio10 = GPIO_MODE_GPIO, /* MDI_DETECT */
+	.gpio12 = GPIO_MODE_GPIO, /* H8SCI# */
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO, /* CPUSB# */
+	.gpio15 = GPIO_MODE_GPIO, /* CPPE# */
+	.gpio19 = GPIO_MODE_GPIO,
+	.gpio22 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO, /* MDC_KILL# */
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO, /* EXC_PWR_CTRL */
+	.gpio28 = GPIO_MODE_GPIO, /* EXC_AUX_CTRL */
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio1 = GPIO_DIR_INPUT,
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_INPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio19 = GPIO_DIR_OUTPUT,
+	.gpio22 = GPIO_DIR_INPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio19 = GPIO_LEVEL_HIGH,
+	.gpio24 = GPIO_LEVEL_HIGH,
+	.gpio25 = GPIO_LEVEL_HIGH,
+	.gpio26 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_HIGH,
+	.gpio28 = GPIO_LEVEL_HIGH,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio1 = GPIO_INVERT,
+	.gpio6 = GPIO_INVERT,
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+	.gpio12 = GPIO_INVERT,
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio36 = GPIO_MODE_GPIO, /*PLANARID0 */
+	.gpio37 = GPIO_MODE_GPIO, /*PLANARID1 */
+	.gpio38 = GPIO_MODE_GPIO, /*PLANARID2 */
+	.gpio39 = GPIO_MODE_GPIO, /*PLANARID3 */
+	.gpio48 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio36 = GPIO_DIR_INPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_INPUT,
+	.gpio39 = GPIO_DIR_INPUT,
+	.gpio48 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio48 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/lenovo/t60/romstage.c b/src/mainboard/lenovo/t60/romstage.c
index d3cd90c..2686635 100644
--- a/src/mainboard/lenovo/t60/romstage.c
+++ b/src/mainboard/lenovo/t60/romstage.c
@@ -35,41 +35,9 @@
 #include <northbridge/intel/i945/i945.h>
 #include <northbridge/intel/i945/raminit.h>
 #include <southbridge/intel/i82801gx/i82801gx.h>
+#include <southbridge/intel/common/gpio.h>
 #include "dock.h"
 
-void setup_ich7_gpios(void)
-{
-	printk(BIOS_DEBUG, " GPIOS...");
-
-	/* T60 GPIO:
-	    6: LEGACYIO#
-	    7: BDC_PRESENCE#
-	    8: H8_WAKE#
-	   10: MDI_DETECT
-	   12: H8SCI#
-	   14: CPUSB#
-	   15: CPPE#
-	   25: MDC_KILL#
-	   27: EXC_PWR_CTRL
-	   28: EXC_AUX_CTRL
-	   35: CLKREQ_SATA#
-	   36: PLANARID0
-	   37: PLANARID1
-	   38: PLANARID2
-	   39: PLANARID3
-	*/
-	outl(0x1f48f7c2, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xe0e0ffc3, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xfbfefb7d, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00040000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000100f0, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x000000f1, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x000300a3, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL2 */
-}
-
 static void ich7_enable_lpc(void)
 {
 	// Enable Serial IRQ
@@ -224,7 +192,7 @@ void mainboard_romstage_entry(unsigned long bist)
 	pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIOBASE, DEFAULT_GPIOBASE | 1);
 	/* Enable GPIOs */
 	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x4c /* GC */ , 0x10);
-	setup_ich7_gpios();
+	setup_pch_gpios(&mainboard_gpio_map);
 
 	dock_err = dlpc_init();
 
diff --git a/src/mainboard/lenovo/x60/Makefile.inc b/src/mainboard/lenovo/x60/Makefile.inc
index 012ae7f..bea9c2e 100644
--- a/src/mainboard/lenovo/x60/Makefile.inc
+++ b/src/mainboard/lenovo/x60/Makefile.inc
@@ -16,3 +16,4 @@
 smm-$(CONFIG_HAVE_SMI_HANDLER) += dock.c
 romstage-y += dock.c
 ramstage-y += dock.c
+romstage-y += gpio.c
\ No newline at end of file
diff --git a/src/mainboard/lenovo/x60/gpio.c b/src/mainboard/lenovo/x60/gpio.c
new file mode 100644
index 0000000..0498443
--- /dev/null
+++ b/src/mainboard/lenovo/x60/gpio.c
@@ -0,0 +1,111 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio1 = GPIO_MODE_GPIO, /* HDD_PRESENCE# */
+	.gpio6 = GPIO_MODE_GPIO, /* Unknown (Pulled high by R215 to VCC3B) */
+	.gpio7 = GPIO_MODE_GPIO, /* BDC_PRESENCE# */
+	.gpio8 = GPIO_MODE_GPIO, /* H8_WAKE# */
+	.gpio9 = GPIO_MODE_GPIO, /* RTC_BAT_IN# */
+	.gpio10 = GPIO_MODE_GPIO, /* Unknown (Pulled high by R700 to VCC3M) */
+	.gpio12 = GPIO_MODE_GPIO, /* H8SCI# */
+	.gpio13 = GPIO_MODE_GPIO, /* SLICE_ON_3M# */
+	.gpio14 = GPIO_MODE_GPIO, /* Unknown (Pulled high by R321 to VCC3) */
+	.gpio15 = GPIO_MODE_GPIO, /* Unknown (Pulled high by R258 to VCC3) */
+	.gpio22 = GPIO_MODE_GPIO, /* FWH_WP# */
+	.gpio24 = GPIO_MODE_GPIO,
+	.gpio25 = GPIO_MODE_GPIO, /* MDC_KILL# */
+	.gpio26 = GPIO_MODE_GPIO,
+	.gpio27 = GPIO_MODE_GPIO,
+	.gpio28 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio1 = GPIO_DIR_INPUT,
+	.gpio6 = GPIO_DIR_INPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_INPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_INPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_INPUT,
+	.gpio22 = GPIO_DIR_INPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio24 = GPIO_LEVEL_HIGH,
+	.gpio25 = GPIO_LEVEL_HIGH,
+	.gpio26 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_HIGH,
+	.gpio28 = GPIO_LEVEL_HIGH,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio1 = GPIO_INVERT,
+	.gpio6 = GPIO_INVERT,
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+	.gpio12 = GPIO_INVERT,
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio33 = GPIO_MODE_GPIO, /* HDD_PRESENCE_2# */
+	.gpio36 = GPIO_MODE_GPIO, /* PLANARID0 */
+	.gpio37 = GPIO_MODE_GPIO, /* PLANARID1 */
+	.gpio38 = GPIO_MODE_GPIO, /* PLANARID2 */
+	.gpio39 = GPIO_MODE_GPIO, /* PLANARID3 */
+	.gpio48 = GPIO_MODE_GPIO, /* FWH_TBL# */
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio33 = GPIO_DIR_OUTPUT,
+	.gpio36 = GPIO_DIR_INPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_INPUT,
+	.gpio39 = GPIO_DIR_INPUT,
+	.gpio48 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio33 = GPIO_LEVEL_HIGH,
+	.gpio48 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/lenovo/x60/romstage.c b/src/mainboard/lenovo/x60/romstage.c
index c735ce2..17d9789 100644
--- a/src/mainboard/lenovo/x60/romstage.c
+++ b/src/mainboard/lenovo/x60/romstage.c
@@ -35,48 +35,9 @@
 #include <northbridge/intel/i945/i945.h>
 #include <northbridge/intel/i945/raminit.h>
 #include <southbridge/intel/i82801gx/i82801gx.h>
+#include <southbridge/intel/common/gpio.h>
 #include "dock.h"
 
-void setup_ich7_gpios(void)
-{
-	printk(BIOS_DEBUG, " GPIOS...");
-
-	/* X60 GPIO:
-	 * 1: HDD_PRESENCE#
-	 * 6: Unknown (Pulled high by R215 to VCC3B)
-	 * 7: BDC_PRESENCE#
-	 * 8: H8_WAKE#
-	 * 9: RTC_BAT_IN#
-	 * 10: Unknown (Pulled high by R700 to VCC3M)
-	 * 12: H8SCI#
-	 * 13: SLICE_ON_3M#
-	 * 14: Unknown (Pulled high by R321 to VCC3)
-	 * 15: Unknown (Pulled high by R258 to VCC3)
-	 * 19: Unknown (Pulled low  by R594)
-	 * 21: Unknown (Pulled high by R145 to VCC3)
-	 * 22: FWH_WP#
-	 * 25: MDC_KILL#
-	 * 33: HDD_PRESENCE_2#
-	 * 35: CLKREQ_SATA#
-	 * 36: PLANARID0
-	 * 37: PLANARID1
-	 * 38: PLANARID2
-	 * 39: PLANARID3
-	 * 48: FWH_TBL#
-	 */
-
-	outl(0x1f40f7c2, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0xe0e8ffc3, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	outl(0xfbf6ddfd, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* Output Control Registers */
-	outl(0x00040000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000100f2, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x000000f0, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	outl(0x00030043, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL */
-}
-
 static void ich7_enable_lpc(void)
 {
 	// Enable Serial IRQ
@@ -227,7 +188,7 @@ void mainboard_romstage_entry(unsigned long bist)
 	/* Enable GPIOs */
 	pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIOBASE, DEFAULT_GPIOBASE | 1);
 	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x4c, 0x10);  /* 0x4c == GC */
-	setup_ich7_gpios();
+	setup_pch_gpios(&mainboard_gpio_map);
 
 	ich7_enable_lpc();
 
diff --git a/src/mainboard/roda/rk886ex/Makefile.inc b/src/mainboard/roda/rk886ex/Makefile.inc
index 07db49d..2c68d38 100644
--- a/src/mainboard/roda/rk886ex/Makefile.inc
+++ b/src/mainboard/roda/rk886ex/Makefile.inc
@@ -15,3 +15,4 @@
 
 ramstage-y += m3885.c
 ramstage-y += cstates.c
+romstage-y += gpio.c
diff --git a/src/mainboard/roda/rk886ex/gpio.c b/src/mainboard/roda/rk886ex/gpio.c
new file mode 100644
index 0000000..72868ca
--- /dev/null
+++ b/src/mainboard/roda/rk886ex/gpio.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * 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.
+ */
+
+#include <southbridge/intel/common/gpio.h>
+
+static const struct pch_gpio_set1 pch_gpio_set1_mode = {
+	.gpio6 = GPIO_MODE_GPIO, /* Enable power of SATA channel 0 */
+	.gpio7 = GPIO_MODE_GPIO,
+	.gpio8 = GPIO_MODE_GPIO,
+	.gpio9 = GPIO_MODE_GPIO, /* Wireless LAN power on */
+	.gpio10 = GPIO_MODE_GPIO,
+	.gpio12 = GPIO_MODE_GPIO,
+	.gpio13 = GPIO_MODE_GPIO,
+	.gpio14 = GPIO_MODE_GPIO,
+	.gpio15 = GPIO_MODE_GPIO, /* FAN on */
+	.gpio22 = GPIO_MODE_GPIO, /* FWH WP */
+	.gpio23 = GPIO_MODE_GPIO,
+	.gpio24 = GPIO_MODE_GPIO, /* GPS on */
+	.gpio25 = GPIO_MODE_GPIO, /* External Antenna Mux on */
+	.gpio26 = GPIO_MODE_GPIO, /* BT on */
+	.gpio27 = GPIO_MODE_GPIO, /* GSM on */
+	.gpio28 = GPIO_MODE_GPIO,
+	.gpio29 = GPIO_MODE_GPIO,
+	.gpio31 = GPIO_MODE_GPIO,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_direction = {
+	.gpio6 = GPIO_DIR_OUTPUT,
+	.gpio7 = GPIO_DIR_INPUT,
+	.gpio8 = GPIO_DIR_INPUT,
+	.gpio9 = GPIO_DIR_OUTPUT,
+	.gpio10 = GPIO_DIR_INPUT,
+	.gpio12 = GPIO_DIR_INPUT,
+	.gpio13 = GPIO_DIR_INPUT,
+	.gpio14 = GPIO_DIR_INPUT,
+	.gpio15 = GPIO_DIR_OUTPUT,
+	.gpio22 = GPIO_DIR_OUTPUT,
+	.gpio23 = GPIO_DIR_INPUT,
+	.gpio24 = GPIO_DIR_OUTPUT,
+	.gpio25 = GPIO_DIR_OUTPUT,
+	.gpio26 = GPIO_DIR_OUTPUT,
+	.gpio27 = GPIO_DIR_OUTPUT,
+	.gpio28 = GPIO_DIR_INPUT,
+	.gpio29 = GPIO_DIR_INPUT,
+	.gpio31 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_level = {
+	.gpio6 = GPIO_LEVEL_LOW,
+	.gpio9 = GPIO_LEVEL_LOW,
+	.gpio15 = GPIO_LEVEL_LOW,
+	.gpio22 = GPIO_LEVEL_HIGH,
+	.gpio24 = GPIO_LEVEL_HIGH,
+	.gpio25 = GPIO_LEVEL_LOW,
+	.gpio26 = GPIO_LEVEL_LOW,
+	.gpio27 = GPIO_LEVEL_LOW,
+	.gpio31 = GPIO_LEVEL_LOW,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_invert = {
+	.gpio7 = GPIO_INVERT,
+	.gpio8 = GPIO_INVERT,
+	.gpio13 = GPIO_INVERT,
+};
+
+static const struct pch_gpio_set1 pch_gpio_set1_blink = {
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_mode = {
+	.gpio35 = GPIO_MODE_GPIO,
+	.gpio37 = GPIO_MODE_GPIO,
+	.gpio38 = GPIO_MODE_GPIO,
+	.gpio39 = GPIO_MODE_GPIO,
+	.gpio48 = GPIO_MODE_GPIO, /* FWH TLB# */
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_direction = {
+	.gpio35 = GPIO_DIR_OUTPUT,
+	.gpio37 = GPIO_DIR_INPUT,
+	.gpio38 = GPIO_DIR_OUTPUT,
+	.gpio39 = GPIO_DIR_OUTPUT,
+	.gpio48 = GPIO_DIR_OUTPUT,
+};
+
+static const struct pch_gpio_set2 pch_gpio_set2_level = {
+	.gpio35 = GPIO_LEVEL_LOW,
+	.gpio38 = GPIO_LEVEL_LOW,
+	.gpio39 = GPIO_LEVEL_LOW,
+	.gpio48 = GPIO_LEVEL_HIGH,
+};
+
+const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+	},
+};
diff --git a/src/mainboard/roda/rk886ex/romstage.c b/src/mainboard/roda/rk886ex/romstage.c
index 3d6ae19..1a7ce6b 100644
--- a/src/mainboard/roda/rk886ex/romstage.c
+++ b/src/mainboard/roda/rk886ex/romstage.c
@@ -35,36 +35,6 @@
 #include <southbridge/intel/i82801gx/i82801gx.h>
 #include "option_table.h"
 
-void setup_ich7_gpios(void)
-{
-	printk(BIOS_DEBUG, " GPIOS...");
-	/* General Registers */
-	outl(0xbfc0f7c0, DEFAULT_GPIOBASE + 0x00);	/* GPIO_USE_SEL */
-	outl(0x70a87d83, DEFAULT_GPIOBASE + 0x04);	/* GP_IO_SEL */
-	/* ------------------------------------------------------------
-	 * 0 - GPO6  - Enable power of SATA channel 0
-	 * 0 - GPO9  - Wireless LAN power on
-	 * 0 - GPO15 - FAN on
-	 * 1 - GPO22 - FWH WP
-	 * 1 - GPO24 - GPS on
-	 * 0 - GPO25 - External Antenna Mux on
-	 * 0 - GPO26 - BT on
-	 * 0 - GPO27 - GSM on
-	 */
-	outl(0x01400000, DEFAULT_GPIOBASE + 0x0c);	/* GP_LVL */
-	/* ------------------------------------------------------------ */
-	/* Output Control Registers */
-	outl(0x00000000, DEFAULT_GPIOBASE + 0x18);	/* GPO_BLINK */
-	/* Input Control Registers */
-	outl(0x00002180, DEFAULT_GPIOBASE + 0x2c);	/* GPI_INV */
-	outl(0x000100e8, DEFAULT_GPIOBASE + 0x30);	/* GPIO_USE_SEL2 */
-	outl(0x00000030, DEFAULT_GPIOBASE + 0x34);	/* GP_IO_SEL2 */
-	/* ------------------------------------------------------------ */
-	/* 1 - GPO48 - FWH TBL# */
-	outl(0x00010000, DEFAULT_GPIOBASE + 0x38);	/* GP_LVL */
-	/* ------------------------------------------------------------ */
-}
-
 static void ich7_enable_lpc(void)
 {
 	int lpt_en = 0;
diff --git a/src/northbridge/intel/i945/early_init.c b/src/northbridge/intel/i945/early_init.c
index 16ae55f..b38974c 100644
--- a/src/northbridge/intel/i945/early_init.c
+++ b/src/northbridge/intel/i945/early_init.c
@@ -24,6 +24,7 @@
 #include <string.h>
 #include "i945.h"
 #include <pc80/mc146818rtc.h>
+#include <southbridge/intel/common/gpio.h>
 
 int i945_silicon_revision(void)
 {
@@ -162,7 +163,7 @@ static void i945_setup_bars(void)
 
 	pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIOBASE, DEFAULT_GPIOBASE | 1);
 	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x4c /* GC */ , 0x10);	/* Enable GPIOs */
-	setup_ich7_gpios();
+	setup_pch_gpios(&mainboard_gpio_map);
 	printk(BIOS_DEBUG, " done.\n");
 
 	printk(BIOS_DEBUG, "Disabling Watchdog reboot...");
diff --git a/src/southbridge/intel/i82801gx/Kconfig b/src/southbridge/intel/i82801gx/Kconfig
index 1f22d05..b2265c4 100644
--- a/src/southbridge/intel/i82801gx/Kconfig
+++ b/src/southbridge/intel/i82801gx/Kconfig
@@ -23,6 +23,7 @@ config SOUTHBRIDGE_INTEL_I82801GX
 	select USE_WATCHDOG_ON_BOOT
 	select HAVE_SMI_HANDLER
 	select COMMON_FADT
+	select SOUTHBRIDGE_INTEL_COMMON_GPIO
 
 if SOUTHBRIDGE_INTEL_I82801GX
 



More information about the coreboot-gerrit mailing list