x86: Enable PCIe controller on quark/galileo

Quark SoC holds the PCIe controller in reset following a power on.
U-Boot needs to release the PCIe controller from reset. The PCIe
controller (D23:F0/F1) will not be visible in PCI configuration
space and any access to its PCI configuration registers will cause
system hang while it is held in reset.

Enable PCIe controller per Quark firmware writer guide.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
diff --git a/board/intel/galileo/galileo.c b/board/intel/galileo/galileo.c
index 746ab27..c1087ac 100644
--- a/board/intel/galileo/galileo.c
+++ b/board/intel/galileo/galileo.c
@@ -5,12 +5,68 @@
  */
 
 #include <common.h>
+#include <asm/io.h>
+#include <asm/arch/device.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/quark.h>
 
 int board_early_init_f(void)
 {
 	return 0;
 }
 
+/*
+ * Intel Galileo gen2 board uses GPIO Resume Well bank pin0 as the PERST# pin.
+ *
+ * We cannot use any public GPIO APIs in <asm-generic/gpio.h> to control this
+ * pin, as these APIs will eventually call into gpio_ich6_ofdata_to_platdata()
+ * in the Intel ICH6 GPIO driver where it calls PCI configuration space access
+ * APIs which will trigger PCI enumeration process.
+ *
+ * Check <asm/arch-quark/quark.h> for more details.
+ */
+void board_assert_perst(void)
+{
+	u32 base, port, val;
+
+	/* retrieve the GPIO IO base */
+	qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, PCI_CFG_GPIOBASE, &base);
+	base = (base & 0xffff) & ~0x7f;
+
+	/* enable the pin */
+	port = base + 0x20;
+	val = inl(port);
+	val |= (1 << 0);
+	outl(val, port);
+
+	/* configure the pin as output */
+	port = base + 0x24;
+	val = inl(port);
+	val &= ~(1 << 0);
+	outl(val, port);
+
+	/* pull it down (assert) */
+	port = base + 0x28;
+	val = inl(port);
+	val &= ~(1 << 0);
+	outl(val, port);
+}
+
+void board_deassert_perst(void)
+{
+	u32 base, port, val;
+
+	/* retrieve the GPIO IO base */
+	qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, PCI_CFG_GPIOBASE, &base);
+	base = (base & 0xffff) & ~0x7f;
+
+	/* pull it up (de-assert) */
+	port = base + 0x28;
+	val = inl(port);
+	val |= (1 << 0);
+	outl(val, port);
+}
+
 void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio)
 {
 	return;