aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig149
-rw-r--r--arch/x86/cpu/Makefile3
-rw-r--r--arch/x86/cpu/baytrail/pci.c2
-rw-r--r--arch/x86/cpu/coreboot/coreboot.c40
-rw-r--r--arch/x86/cpu/irq.c216
-rw-r--r--arch/x86/cpu/qemu/Kconfig21
-rw-r--r--arch/x86/cpu/qemu/Makefile8
-rw-r--r--arch/x86/cpu/qemu/car.S26
-rw-r--r--arch/x86/cpu/qemu/dram.c46
-rw-r--r--arch/x86/cpu/qemu/pci.c101
-rw-r--r--arch/x86/cpu/qemu/qemu.c45
-rw-r--r--arch/x86/cpu/quark/quark.c31
-rw-r--r--arch/x86/cpu/queensbay/Makefile2
-rw-r--r--arch/x86/cpu/queensbay/irq.c242
-rw-r--r--arch/x86/cpu/queensbay/tnc.c39
-rw-r--r--arch/x86/dts/Makefile4
-rw-r--r--arch/x86/dts/crownbay.dts54
-rw-r--r--arch/x86/dts/galileo.dts22
-rw-r--r--arch/x86/dts/minnowmax.dts23
-rw-r--r--arch/x86/dts/qemu-x86_i440fx.dts50
-rw-r--r--arch/x86/dts/qemu-x86_q35.dts67
-rw-r--r--arch/x86/include/asm/arch-qemu/device.h21
-rw-r--r--arch/x86/include/asm/arch-qemu/gpio.h13
-rw-r--r--arch/x86/include/asm/arch-qemu/qemu.h28
-rw-r--r--arch/x86/include/asm/arch-quark/device.h70
-rw-r--r--arch/x86/include/asm/arch-quark/quark.h15
-rw-r--r--arch/x86/include/asm/arch-queensbay/irq.h55
-rw-r--r--arch/x86/include/asm/gpio.h1
-rw-r--r--arch/x86/include/asm/irq.h76
-rw-r--r--arch/x86/include/asm/u-boot-x86.h1
-rw-r--r--arch/x86/lib/fsp/fsp_support.c2
-rw-r--r--board/coreboot/coreboot/Kconfig6
-rw-r--r--board/emulation/Kconfig25
-rw-r--r--board/emulation/qemu-x86/Kconfig24
-rw-r--r--board/emulation/qemu-x86/MAINTAINERS6
-rw-r--r--board/emulation/qemu-x86/Makefile7
-rw-r--r--board/emulation/qemu-x86/qemu-x86.c13
-rw-r--r--board/emulation/qemu-x86/start.S9
-rw-r--r--board/intel/crownbay/crownbay.c2
-rw-r--r--board/intel/galileo/galileo.c2
-rw-r--r--board/intel/minnowmax/minnowmax.c9
-rw-r--r--common/cmd_ide.c6
-rw-r--r--configs/coreboot-x86_defconfig2
-rw-r--r--configs/galileo_defconfig1
-rw-r--r--configs/minnowmax_defconfig1
-rw-r--r--configs/qemu-x86_defconfig10
-rw-r--r--doc/README.x8678
-rw-r--r--doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt31
-rw-r--r--doc/device-tree-bindings/misc/intel,irq-router.txt50
-rw-r--r--drivers/gpio/intel_ich6_gpio.c257
-rw-r--r--drivers/pci/pci.c66
-rw-r--r--drivers/pci/pci_auto.c15
-rw-r--r--drivers/pci/pci_common.c70
-rw-r--r--drivers/video/Kconfig139
-rw-r--r--include/configs/crownbay.h2
-rw-r--r--include/configs/galileo.h3
-rw-r--r--include/configs/minnowmax.h6
-rw-r--r--include/configs/qemu-x86.h77
-rw-r--r--include/configs/x86-chromebook.h1
-rw-r--r--include/configs/x86-common.h7
-rw-r--r--include/dt-bindings/gpio/x86-gpio.h31
-rw-r--r--include/dt-bindings/interrupt-router/intel-irq.h31
-rw-r--r--include/fdtdec.h2
-rw-r--r--include/pci_ids.h1
-rw-r--r--lib/fdtdec.c2
-rw-r--r--tools/ifdtool.c2
66 files changed, 1824 insertions, 643 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8e734fdfb4e..3506ba2946b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -12,11 +12,14 @@ config SYS_VSNPRINTF
choice
prompt "Mainboard vendor"
- default VENDOR_COREBOOT
+ default VENDOR_EMULATION
config VENDOR_COREBOOT
bool "coreboot"
+config VENDOR_EMULATION
+ bool "emulation"
+
config VENDOR_GOOGLE
bool "Google"
@@ -27,6 +30,7 @@ endchoice
# board-specific options below
source "board/coreboot/Kconfig"
+source "board/emulation/Kconfig"
source "board/google/Kconfig"
source "board/intel/Kconfig"
@@ -34,6 +38,7 @@ source "board/intel/Kconfig"
source "arch/x86/cpu/baytrail/Kconfig"
source "arch/x86/cpu/coreboot/Kconfig"
source "arch/x86/cpu/ivybridge/Kconfig"
+source "arch/x86/cpu/qemu/Kconfig"
source "arch/x86/cpu/quark/Kconfig"
source "arch/x86/cpu/queensbay/Kconfig"
@@ -182,147 +187,6 @@ config MARK_GRAPHICS_MEM_WRCOMB
memory is set as write-combining cache type. This option
enables marking the graphics memory as write-combining.
-menu "Display"
-
-config FRAMEBUFFER_SET_VESA_MODE
- prompt "Set framebuffer graphics resolution"
- bool
- help
- Set VESA/native framebuffer mode (needed for bootsplash and graphical framebuffer console)
-
-choice
- prompt "framebuffer graphics resolution"
- default FRAMEBUFFER_VESA_MODE_117
- depends on FRAMEBUFFER_SET_VESA_MODE
- help
- This option sets the resolution used for the coreboot framebuffer (and
- bootsplash screen).
-
-config FRAMEBUFFER_VESA_MODE_100
- bool "640x400 256-color"
-
-config FRAMEBUFFER_VESA_MODE_101
- bool "640x480 256-color"
-
-config FRAMEBUFFER_VESA_MODE_102
- bool "800x600 16-color"
-
-config FRAMEBUFFER_VESA_MODE_103
- bool "800x600 256-color"
-
-config FRAMEBUFFER_VESA_MODE_104
- bool "1024x768 16-color"
-
-config FRAMEBUFFER_VESA_MODE_105
- bool "1024x7686 256-color"
-
-config FRAMEBUFFER_VESA_MODE_106
- bool "1280x1024 16-color"
-
-config FRAMEBUFFER_VESA_MODE_107
- bool "1280x1024 256-color"
-
-config FRAMEBUFFER_VESA_MODE_108
- bool "80x60 text"
-
-config FRAMEBUFFER_VESA_MODE_109
- bool "132x25 text"
-
-config FRAMEBUFFER_VESA_MODE_10A
- bool "132x43 text"
-
-config FRAMEBUFFER_VESA_MODE_10B
- bool "132x50 text"
-
-config FRAMEBUFFER_VESA_MODE_10C
- bool "132x60 text"
-
-config FRAMEBUFFER_VESA_MODE_10D
- bool "320x200 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_10E
- bool "320x200 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_10F
- bool "320x200 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_110
- bool "640x480 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_111
- bool "640x480 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_112
- bool "640x480 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_113
- bool "800x600 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_114
- bool "800x600 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_115
- bool "800x600 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_116
- bool "1024x768 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_117
- bool "1024x768 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_118
- bool "1024x768 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_119
- bool "1280x1024 32k-color (1:5:5:5)"
-
-config FRAMEBUFFER_VESA_MODE_11A
- bool "1280x1024 64k-color (5:6:5)"
-
-config FRAMEBUFFER_VESA_MODE_11B
- bool "1280x1024 16.8M-color (8:8:8)"
-
-config FRAMEBUFFER_VESA_MODE_USER
- bool "Manually select VESA mode"
-
-endchoice
-
-# Map the config names to an integer (KB).
-config FRAMEBUFFER_VESA_MODE
- prompt "VESA mode" if FRAMEBUFFER_VESA_MODE_USER
- hex
- default 0x100 if FRAMEBUFFER_VESA_MODE_100
- default 0x101 if FRAMEBUFFER_VESA_MODE_101
- default 0x102 if FRAMEBUFFER_VESA_MODE_102
- default 0x103 if FRAMEBUFFER_VESA_MODE_103
- default 0x104 if FRAMEBUFFER_VESA_MODE_104
- default 0x105 if FRAMEBUFFER_VESA_MODE_105
- default 0x106 if FRAMEBUFFER_VESA_MODE_106
- default 0x107 if FRAMEBUFFER_VESA_MODE_107
- default 0x108 if FRAMEBUFFER_VESA_MODE_108
- default 0x109 if FRAMEBUFFER_VESA_MODE_109
- default 0x10A if FRAMEBUFFER_VESA_MODE_10A
- default 0x10B if FRAMEBUFFER_VESA_MODE_10B
- default 0x10C if FRAMEBUFFER_VESA_MODE_10C
- default 0x10D if FRAMEBUFFER_VESA_MODE_10D
- default 0x10E if FRAMEBUFFER_VESA_MODE_10E
- default 0x10F if FRAMEBUFFER_VESA_MODE_10F
- default 0x110 if FRAMEBUFFER_VESA_MODE_110
- default 0x111 if FRAMEBUFFER_VESA_MODE_111
- default 0x112 if FRAMEBUFFER_VESA_MODE_112
- default 0x113 if FRAMEBUFFER_VESA_MODE_113
- default 0x114 if FRAMEBUFFER_VESA_MODE_114
- default 0x115 if FRAMEBUFFER_VESA_MODE_115
- default 0x116 if FRAMEBUFFER_VESA_MODE_116
- default 0x117 if FRAMEBUFFER_VESA_MODE_117
- default 0x118 if FRAMEBUFFER_VESA_MODE_118
- default 0x119 if FRAMEBUFFER_VESA_MODE_119
- default 0x11A if FRAMEBUFFER_VESA_MODE_11A
- default 0x11B if FRAMEBUFFER_VESA_MODE_11B
- default 0x117 if FRAMEBUFFER_VESA_MODE_USER
-
-endmenu
-
config HAVE_FSP
bool "Add an Firmware Support Package binary"
help
@@ -356,6 +220,7 @@ config FSP_ADDR
config FSP_TEMP_RAM_ADDR
hex
+ depends on HAVE_FSP
default 0x2000000
help
Stack top address which is used in FspInit after DRAM is ready and
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 043bea258c4..7ff05e66284 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -14,11 +14,12 @@ obj-y += interrupts.o cpu.o call64.o
obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
obj-$(CONFIG_SYS_COREBOOT) += coreboot/
+obj-$(CONFIG_QEMU) += qemu/
obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
obj-$(CONFIG_INTEL_QUARK) += quark/
obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/
-obj-y += lapic.o
+obj-y += irq.o lapic.o
obj-$(CONFIG_SMP) += mp_init.o
obj-y += mtrr.o
obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/cpu/baytrail/pci.c b/arch/x86/cpu/baytrail/pci.c
index 6c291f9ee9c..48409de5c4d 100644
--- a/arch/x86/cpu/baytrail/pci.c
+++ b/arch/x86/cpu/baytrail/pci.c
@@ -39,7 +39,7 @@ void board_pci_setup_hose(struct pci_controller *hose)
pci_set_region(hose->regions + 3,
0,
0,
- gd->ram_size,
+ gd->ram_size < 0x80000000 ? gd->ram_size : 0x80000000,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
hose->region_count = 4;
diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index 4cdd0d40353..0e9f15fef68 100644
--- a/arch/x86/cpu/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -7,16 +7,11 @@
*/
#include <common.h>
-#include <asm/u-boot-x86.h>
-#include <flash.h>
+#include <fdtdec.h>
#include <netdev.h>
-#include <ns16550.h>
-#include <asm/msr.h>
-#include <asm/cache.h>
-#include <asm/cpu.h>
#include <asm/io.h>
+#include <asm/msr.h>
#include <asm/mtrr.h>
-#include <asm/arch/tables.h>
#include <asm/arch/sysinfo.h>
#include <asm/arch/timestamp.h>
@@ -53,13 +48,6 @@ int last_stage_init(void)
return 0;
}
-#ifndef CONFIG_SYS_NO_FLASH
-ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
-{
- return 0;
-}
-#endif
-
int board_eth_init(bd_t *bis)
{
return pci_eth_init(bis);
@@ -67,7 +55,8 @@ int board_eth_init(bd_t *bis)
void board_final_cleanup(void)
{
- /* Un-cache the ROM so the kernel has one
+ /*
+ * Un-cache the ROM so the kernel has one
* more MTRR available.
*
* Coreboot should have assigned this to the
@@ -86,21 +75,22 @@ void board_final_cleanup(void)
mtrr_close(&state);
}
- /* Issue SMI to Coreboot to lock down ME and registers */
- printf("Finalizing Coreboot\n");
- outb(0xcb, 0xb2);
+ if (!fdtdec_get_config_bool(gd->fdt_blob, "u-boot,no-apm-finalize")) {
+ /*
+ * Issue SMI to coreboot to lock down ME and registers
+ * when allowed via device tree
+ */
+ printf("Finalizing coreboot\n");
+ outb(0xcb, 0xb2);
+ }
}
-void panic_puts(const char *str)
+int misc_init_r(void)
{
- NS16550_t port = (NS16550_t)0x3f8;
-
- NS16550_init(port, 1);
- while (*str)
- NS16550_putc(port, *str++);
+ return 0;
}
-int misc_init_r(void)
+int arch_misc_init(void)
{
return 0;
}
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c
new file mode 100644
index 00000000000..74b89ad2ff6
--- /dev/null
+++ b/arch/x86/cpu/irq.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/pirq_routing.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct irq_router irq_router;
+static struct irq_routing_table *pirq_routing_table;
+
+bool pirq_check_irq_routed(int link, u8 irq)
+{
+ u8 pirq;
+ int base = irq_router.link_base;
+
+ if (irq_router.config == PIRQ_VIA_PCI)
+ pirq = x86_pci_read_config8(irq_router.bdf,
+ LINK_N2V(link, base));
+ else
+ pirq = readb(irq_router.ibase + LINK_N2V(link, base));
+
+ pirq &= 0xf;
+
+ /* IRQ# 0/1/2/8/13 are reserved */
+ if (pirq < 3 || pirq == 8 || pirq == 13)
+ return false;
+
+ return pirq == irq ? true : false;
+}
+
+int pirq_translate_link(int link)
+{
+ return LINK_V2N(link, irq_router.link_base);
+}
+
+void pirq_assign_irq(int link, u8 irq)
+{
+ int base = irq_router.link_base;
+
+ /* IRQ# 0/1/2/8/13 are reserved */
+ if (irq < 3 || irq == 8 || irq == 13)
+ return;
+
+ if (irq_router.config == PIRQ_VIA_PCI)
+ x86_pci_write_config8(irq_router.bdf,
+ LINK_N2V(link, base), irq);
+ else
+ writeb(irq, irq_router.ibase + LINK_N2V(link, base));
+}
+
+static inline void fill_irq_info(struct irq_info **slotp, int *entries, u8 bus,
+ u8 device, u8 func, u8 pin, u8 pirq)
+{
+ struct irq_info *slot = *slotp;
+
+ slot->bus = bus;
+ slot->devfn = (device << 3) | func;
+ slot->irq[pin - 1].link = LINK_N2V(pirq, irq_router.link_base);
+ slot->irq[pin - 1].bitmap = irq_router.irq_mask;
+ (*entries)++;
+ (*slotp)++;
+}
+
+__weak void cpu_irq_init(void)
+{
+ return;
+}
+
+static int create_pirq_routing_table(void)
+{
+ const void *blob = gd->fdt_blob;
+ struct fdt_pci_addr addr;
+ int node;
+ int len, count;
+ const u32 *cell;
+ struct irq_routing_table *rt;
+ struct irq_info *slot;
+ int irq_entries = 0;
+ int i;
+ int ret;
+
+ node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_IRQ_ROUTER);
+ if (node < 0) {
+ debug("%s: Cannot find irq router node\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = fdtdec_get_pci_addr(blob, node, FDT_PCI_SPACE_CONFIG,
+ "reg", &addr);
+ if (ret)
+ return ret;
+
+ /* extract the bdf from fdt_pci_addr */
+ irq_router.bdf = addr.phys_hi & 0xffff00;
+
+ ret = fdt_find_string(blob, node, "intel,pirq-config", "pci");
+ if (!ret) {
+ irq_router.config = PIRQ_VIA_PCI;
+ } else {
+ ret = fdt_find_string(blob, node, "intel,pirq-config", "ibase");
+ if (!ret)
+ irq_router.config = PIRQ_VIA_IBASE;
+ else
+ return -EINVAL;
+ }
+
+ ret = fdtdec_get_int_array(blob, node, "intel,pirq-link",
+ &irq_router.link_base, 1);
+ if (ret)
+ return ret;
+
+ irq_router.irq_mask = fdtdec_get_int(blob, node,
+ "intel,pirq-mask", PIRQ_BITMAP);
+
+ if (irq_router.config == PIRQ_VIA_IBASE) {
+ int ibase_off;
+
+ ibase_off = fdtdec_get_int(blob, node, "intel,ibase-offset", 0);
+ if (!ibase_off)
+ return -EINVAL;
+
+ /*
+ * Here we assume that the IBASE register has already been
+ * properly configured by U-Boot before.
+ *
+ * By 'valid' we mean:
+ * 1) a valid memory space carved within system memory space
+ * assigned to IBASE register block.
+ * 2) memory range decoding is enabled.
+ * Hence we don't do any santify test here.
+ */
+ irq_router.ibase = x86_pci_read_config32(irq_router.bdf,
+ ibase_off);
+ irq_router.ibase &= ~0xf;
+ }
+
+ cell = fdt_getprop(blob, node, "intel,pirq-routing", &len);
+ if (!cell)
+ return -EINVAL;
+
+ if ((len % sizeof(struct pirq_routing)) == 0)
+ count = len / sizeof(struct pirq_routing);
+ else
+ return -EINVAL;
+
+ rt = malloc(sizeof(struct irq_routing_table));
+ if (!rt)
+ return -ENOMEM;
+ memset((char *)rt, 0, sizeof(struct irq_routing_table));
+
+ /* Populate the PIRQ table fields */
+ rt->signature = PIRQ_SIGNATURE;
+ rt->version = PIRQ_VERSION;
+ rt->rtr_bus = 0;
+ rt->rtr_devfn = (PCI_DEV(irq_router.bdf) << 3) |
+ PCI_FUNC(irq_router.bdf);
+ rt->rtr_vendor = PCI_VENDOR_ID_INTEL;
+ rt->rtr_device = PCI_DEVICE_ID_INTEL_ICH7_31;
+
+ slot = rt->slots;
+
+ /* Now fill in the irq_info entries in the PIRQ table */
+ for (i = 0; i < count; i++) {
+ struct pirq_routing pr;
+
+ pr.bdf = fdt_addr_to_cpu(cell[0]);
+ pr.pin = fdt_addr_to_cpu(cell[1]);
+ pr.pirq = fdt_addr_to_cpu(cell[2]);
+
+ debug("irq_info %d: b.d.f %x.%x.%x INT%c PIRQ%c\n",
+ i, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
+ PCI_FUNC(pr.bdf), 'A' + pr.pin - 1,
+ 'A' + pr.pirq);
+ fill_irq_info(&slot, &irq_entries, PCI_BUS(pr.bdf),
+ PCI_DEV(pr.bdf), PCI_FUNC(pr.bdf),
+ pr.pin, pr.pirq);
+ cell += sizeof(struct pirq_routing) / sizeof(u32);
+ }
+
+ rt->size = irq_entries * sizeof(struct irq_info) + 32;
+
+ pirq_routing_table = rt;
+
+ return 0;
+}
+
+void pirq_init(void)
+{
+ cpu_irq_init();
+
+ if (create_pirq_routing_table()) {
+ debug("Failed to create pirq routing table\n");
+ } else {
+ /* Route PIRQ */
+ pirq_route_irqs(pirq_routing_table->slots,
+ get_irq_slot_count(pirq_routing_table));
+ }
+}
+
+u32 write_pirq_routing_table(u32 addr)
+{
+ if (!pirq_routing_table)
+ return addr;
+
+ return copy_pirq_routing_table(addr, pirq_routing_table);
+}
diff --git a/arch/x86/cpu/qemu/Kconfig b/arch/x86/cpu/qemu/Kconfig
new file mode 100644
index 00000000000..fb775d7d283
--- /dev/null
+++ b/arch/x86/cpu/qemu/Kconfig
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+config QEMU
+ bool
+ select TSC_CALIBRATION_BYPASS
+
+if QEMU
+
+config SYS_CAR_ADDR
+ hex
+ default 0xd0000
+
+config SYS_CAR_SIZE
+ hex
+ default 0x10000
+
+endif
diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile
new file mode 100644
index 00000000000..be79723a67b
--- /dev/null
+++ b/arch/x86/cpu/qemu/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += car.o dram.o qemu.o
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/cpu/qemu/car.S b/arch/x86/cpu/qemu/car.S
new file mode 100644
index 00000000000..13b3aea3ff0
--- /dev/null
+++ b/arch/x86/cpu/qemu/car.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/post.h>
+
+.globl car_init
+car_init:
+ /* Save the BIST result */
+ movl %eax, %ebp
+
+ post_code(POST_CAR_START)
+
+ /*
+ * Since we know we are running inside emulator,
+ * we can do nothing here for CAR initialization.
+ */
+
+ /* Restore the BIST result */
+ movl %ebp, %eax
+
+ post_code(POST_CAR_CPU_CACHE)
+ jmp car_init_ret
diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c
new file mode 100644
index 00000000000..a88d0d26547
--- /dev/null
+++ b/arch/x86/cpu/qemu/dram.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/post.h>
+#include <asm/arch/qemu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ u32 ram;
+
+ outb(HIGH_RAM_ADDR, CMOS_ADDR_PORT);
+ ram = ((u32)inb(CMOS_DATA_PORT)) << 14;
+ outb(LOW_RAM_ADDR, CMOS_ADDR_PORT);
+ ram |= ((u32)inb(CMOS_DATA_PORT)) << 6;
+ ram += 16 * 1024;
+
+ gd->ram_size = ram * 1024;
+ post_code(POST_DRAM);
+
+ return 0;
+}
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = 0;
+ gd->bd->bi_dram[0].size = gd->ram_size;
+}
+
+/*
+ * This function looks for the highest region of memory lower than 4GB which
+ * has enough space for U-Boot where U-Boot is aligned on a page boundary.
+ * It overrides the default implementation found elsewhere which simply
+ * picks the end of ram, wherever that may be. The location of the stack,
+ * the relocation address, and how far U-Boot is moved by relocation are
+ * set in the global data structure.
+ */
+ulong board_get_usable_ram_top(ulong total_size)
+{
+ return gd->ram_size;
+}
diff --git a/arch/x86/cpu/qemu/pci.c b/arch/x86/cpu/qemu/pci.c
new file mode 100644
index 00000000000..1a9140b46e0
--- /dev/null
+++ b/arch/x86/cpu/qemu/pci.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <pci_rom.h>
+#include <asm/pci.h>
+#include <asm/arch/device.h>
+#include <asm/arch/qemu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_pci_setup_hose(struct pci_controller *hose)
+{
+ hose->first_busno = 0;
+ hose->last_busno = 0;
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 0,
+ CONFIG_PCI_MEM_BUS,
+ CONFIG_PCI_MEM_PHYS,
+ CONFIG_PCI_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose->regions + 1,
+ CONFIG_PCI_IO_BUS,
+ CONFIG_PCI_IO_PHYS,
+ CONFIG_PCI_IO_SIZE,
+ PCI_REGION_IO);
+
+ pci_set_region(hose->regions + 2,
+ CONFIG_PCI_PREF_BUS,
+ CONFIG_PCI_PREF_PHYS,
+ CONFIG_PCI_PREF_SIZE,
+ PCI_REGION_PREFETCH);
+
+ pci_set_region(hose->regions + 3,
+ 0,
+ 0,
+ gd->ram_size,
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+ hose->region_count = 4;
+}
+
+int board_pci_post_scan(struct pci_controller *hose)
+{
+ int ret = 0;
+ u16 device;
+ int pam, i;
+ pci_dev_t vga;
+ ulong start;
+
+ /*
+ * i440FX and Q35 chipset have different PAM register offset, but with
+ * the same bitfield layout. Here we determine the offset based on its
+ * PCI device ID.
+ */
+ device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID);
+ pam = (device == PCI_DEVICE_ID_INTEL_82441) ? I440FX_PAM : Q35_PAM;
+
+ /*
+ * Initialize Programmable Attribute Map (PAM) Registers
+ *
+ * Configure legacy segments C/D/E/F to system RAM
+ */
+ for (i = 0; i < PAM_NUM; i++)
+ x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW);
+
+ if (device == PCI_DEVICE_ID_INTEL_82441) {
+ /*
+ * Enable legacy IDE I/O ports decode
+ *
+ * Note: QEMU always decode legacy IDE I/O port on PIIX chipset.
+ * However Linux ata_piix driver does sanity check on these two
+ * registers to see whether legacy ports decode is turned on.
+ * This is to make Linux ata_piix driver happy.
+ */
+ x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN);
+ x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN);
+ }
+
+ /*
+ * QEMU emulated graphic card shows in the PCI configuration space with
+ * PCI vendor id and device id as an artificial pair 0x1234:0x1111.
+ * It is on PCI bus 0, function 0, but device number is not consistent
+ * for the two x86 targets it supports. For i440FX and PIIX chipset
+ * board, it shows as device 2, while for Q35 and ICH9 chipset board,
+ * it shows as device 1.
+ */
+ vga = (device == PCI_DEVICE_ID_INTEL_82441) ? I440FX_VGA : Q35_VGA;
+ start = get_timer(0);
+ ret = pci_run_vga_bios(vga, NULL, PCI_ROM_USE_NATIVE);
+ debug("BIOS ran in %lums\n", get_timer(start));
+
+ return ret;
+}
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
new file mode 100644
index 00000000000..930d2b6c9d1
--- /dev/null
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/irq.h>
+#include <asm/post.h>
+#include <asm/processor.h>
+
+int arch_cpu_init(void)
+{
+ int ret;
+
+ post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
+ timer_set_base(rdtsc());
+#endif
+
+ ret = x86_cpu_init_f();
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int print_cpuinfo(void)
+{
+ post_code(POST_CPU_INFO);
+ return default_print_cpuinfo();
+}
+
+void reset_cpu(ulong addr)
+{
+ /* cold reset */
+ x86_full_reset();
+}
+
+int arch_misc_init(void)
+{
+ pirq_init();
+
+ return 0;
+}
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index e78a271c509..20cc09e113d 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -9,6 +9,7 @@
#include <netdev.h>
#include <phy.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/pci.h>
#include <asm/post.h>
#include <asm/processor.h>
@@ -147,3 +148,33 @@ int cpu_eth_init(bd_t *bis)
else
return 0;
}
+
+void cpu_irq_init(void)
+{
+ struct quark_rcba *rcba;
+ u32 base;
+
+ base = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, LB_RCBA);
+ base &= ~MEM_BAR_EN;
+ rcba = (struct quark_rcba *)base;
+
+ /*
+ * Route Quark PCI device interrupt pin to PIRQ
+ *
+ * Route device#23's INTA/B/C/D to PIRQA/B/C/D
+ * Route device#20,21's INTA/B/C/D to PIRQE/F/G/H
+ */
+ writew(PIRQC, &rcba->rmu_ir);
+ writew(PIRQA | (PIRQB << 4) | (PIRQC << 8) | (PIRQD << 12),
+ &rcba->d23_ir);
+ writew(PIRQD, &rcba->core_ir);
+ writew(PIRQE | (PIRQF << 4) | (PIRQG << 8) | (PIRQH << 12),
+ &rcba->d20d21_ir);
+}
+
+int arch_misc_init(void)
+{
+ pirq_init();
+
+ return 0;
+}
diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile
index 4599a4896df..d8761fdfbd2 100644
--- a/arch/x86/cpu/queensbay/Makefile
+++ b/arch/x86/cpu/queensbay/Makefile
@@ -5,5 +5,5 @@
#
obj-y += fsp_configs.o
-obj-y += irq.o tnc.o topcliff.o
+obj-y += tnc.o topcliff.o
obj-$(CONFIG_PCI) += tnc_pci.o
diff --git a/arch/x86/cpu/queensbay/irq.c b/arch/x86/cpu/queensbay/irq.c
deleted file mode 100644
index faf951544f3..00000000000
--- a/arch/x86/cpu/queensbay/irq.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <errno.h>
-#include <malloc.h>
-#include <asm/io.h>
-#include <asm/pci.h>
-#include <asm/post.h>
-#include <asm/processor.h>
-#include <asm/pirq_routing.h>
-#include <asm/arch/device.h>
-#include <asm/arch/tnc.h>
-#include <asm/arch/irq.h>
-
-static struct irq_routing_table *pirq_routing_table;
-
-bool pirq_check_irq_routed(int link, u8 irq)
-{
- u8 pirq;
-
- pirq = x86_pci_read_config8(TNC_LPC, LINK_N2V(link));
- pirq &= 0xf;
-
- /* IRQ# 0/1/2/8/13 are reserved */
- if (pirq < 3 || pirq == 8 || pirq == 13)
- return false;
-
- return pirq == irq ? true : false;
-}
-
-int pirq_translate_link(int link)
-{
- return LINK_V2N(link);
-}
-
-void pirq_assign_irq(int link, u8 irq)
-{
- /* IRQ# 0/1/2/8/13 are reserved */
- if (irq < 3 || irq == 8 || irq == 13)
- return;
-
- x86_pci_write_config8(TNC_LPC, LINK_N2V(link), irq);
-}
-
-static inline void fill_irq_info(struct irq_info **slotp, int *entries, u8 bus,
- u8 device, u8 func, u8 pin, u8 pirq)
-{
- struct irq_info *slot = *slotp;
-
- slot->bus = bus;
- slot->devfn = (device << 3) | func;
- slot->irq[pin - 1].link = LINK_N2V(pirq);
- slot->irq[pin - 1].bitmap = PIRQ_BITMAP;
- (*entries)++;
- (*slotp)++;
-}
-
-/* PCIe port downstream INTx swizzle */
-static inline u8 pin_swizzle(u8 pin, int port)
-{
- return (pin + port) % 4;
-}
-
-__weak int board_fill_irq_info(struct irq_info *slot)
-{
- return 0;
-}
-
-static int create_pirq_routing_table(void)
-{
- struct irq_routing_table *rt;
- struct irq_info *slot;
- int irq_entries = 0;
- pci_dev_t tcf_bdf;
- u8 tcf_bus, bus;
- int i;
-
- rt = malloc(sizeof(struct irq_routing_table));
- if (!rt)
- return -ENOMEM;
- memset((char *)rt, 0, sizeof(struct irq_routing_table));
-
- /* Populate the PIRQ table fields */
- rt->signature = PIRQ_SIGNATURE;
- rt->version = PIRQ_VERSION;
- rt->rtr_bus = 0;
- rt->rtr_devfn = (TNC_LPC_DEV << 3) | TNC_LPC_FUNC;
- rt->rtr_vendor = PCI_VENDOR_ID_INTEL;
- rt->rtr_device = PCI_DEVICE_ID_INTEL_ICH7_31;
-
- slot = rt->slots;
-
- /*
- * Now fill in the irq_info entries in the PIRQ table
- *
- * We start from internal TunnelCreek PCI devices first, then
- * followed by all the 4 PCIe ports downstream devices, including
- * the Queensbay platform Topcliff chipset devices.
- */
- fill_irq_info(&slot, &irq_entries, 0, TNC_IGD_DEV,
- TNC_IGD_FUNC, INTA, PIRQE);
- fill_irq_info(&slot, &irq_entries, 0, TNC_SDVO_DEV,
- TNC_SDVO_FUNC, INTA, PIRQF);
- fill_irq_info(&slot, &irq_entries, 0, TNC_HDA_DEV,
- TNC_HDA_FUNC, INTA, PIRQG);
- fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE0_DEV,
- TNC_PCIE0_FUNC, INTA, PIRQE);
- fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE1_DEV,
- TNC_PCIE1_FUNC, INTA, PIRQF);
- fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE2_DEV,
- TNC_PCIE2_FUNC, INTA, PIRQG);
- fill_irq_info(&slot, &irq_entries, 0, TNC_PCIE3_DEV,
- TNC_PCIE3_FUNC, INTA, PIRQH);
-
- /* Check which PCIe port the Topcliff chipset is connected to */
- tcf_bdf = pci_find_device(PCI_VENDOR_ID_INTEL, 0x8800, 0);
- tcf_bus = PCI_BUS(tcf_bdf);
- for (i = 0; i < 4; i++) {
- bus = x86_pci_read_config8(PCI_BDF(0, TNC_PCIE0_DEV + i, 0),
- PCI_SECONDARY_BUS);
- if (bus == tcf_bus)
- break;
- }
-
- /* Fill in the Topcliff chipset devices' irq info */
- if (i < 4) {
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_PCIE_PORT_DEV,
- TCF_PCIE_PORT_FUNC, INTA, pin_swizzle(PIRQA, i));
-
- tcf_bus++;
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_0,
- TCF_GBE_FUNC, INTA, pin_swizzle(PIRQA, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_0,
- TCF_GPIO_FUNC, INTA, pin_swizzle(PIRQA, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
- TCF_USB1_OHCI0_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
- TCF_USB1_OHCI1_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
- TCF_USB1_OHCI2_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
- TCF_USB1_EHCI_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_2,
- TCF_USB_DEVICE_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_4,
- TCF_SDIO0_FUNC, INTC, pin_swizzle(PIRQC, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_4,
- TCF_SDIO1_FUNC, INTC, pin_swizzle(PIRQC, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_6,
- TCF_SATA_FUNC, INTD, pin_swizzle(PIRQD, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
- TCF_USB2_OHCI0_FUNC, INTA, pin_swizzle(PIRQA, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
- TCF_USB2_OHCI1_FUNC, INTA, pin_swizzle(PIRQA, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
- TCF_USB2_OHCI2_FUNC, INTA, pin_swizzle(PIRQA, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_8,
- TCF_USB2_EHCI_FUNC, INTA, pin_swizzle(PIRQA, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
- TCF_DMA1_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
- TCF_UART0_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
- TCF_UART1_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
- TCF_UART2_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_10,
- TCF_UART3_FUNC, INTB, pin_swizzle(PIRQB, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
- TCF_DMA2_FUNC, INTC, pin_swizzle(PIRQC, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
- TCF_SPI_FUNC, INTC, pin_swizzle(PIRQC, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
- TCF_I2C_FUNC, INTC, pin_swizzle(PIRQC, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
- TCF_CAN_FUNC, INTC, pin_swizzle(PIRQC, i));
- fill_irq_info(&slot, &irq_entries, tcf_bus, TCF_DEV_12,
- TCF_1588_FUNC, INTC, pin_swizzle(PIRQC, i));
- }
-
- /* Call board-specific routine to fill in add-in card's irq info */
- irq_entries += board_fill_irq_info(slot);
-
- rt->size = irq_entries * sizeof(struct irq_info) + 32;
-
- pirq_routing_table = rt;
-
- return 0;
-}
-
-void pirq_init(void)
-{
- struct tnc_rcba *rcba;
- u32 base;
-
- base = x86_pci_read_config32(TNC_LPC, LPC_RCBA);
- base &= ~MEM_BAR_EN;
- rcba = (struct tnc_rcba *)base;
-
- /* Make sure all internal PCI devices are using INTA */
- writel(INTA, &rcba->d02ip);
- writel(INTA, &rcba->d03ip);
- writel(INTA, &rcba->d27ip);
- writel(INTA, &rcba->d31ip);
- writel(INTA, &rcba->d23ip);
- writel(INTA, &rcba->d24ip);
- writel(INTA, &rcba->d25ip);
- writel(INTA, &rcba->d26ip);
-
- /*
- * Route TunnelCreek PCI device interrupt pin to PIRQ
- *
- * Since PCIe downstream ports received INTx are routed to PIRQ
- * A/B/C/D directly and not configurable, we route internal PCI
- * device's INTx to PIRQ E/F/G/H.
- */
- writew(PIRQE, &rcba->d02ir);
- writew(PIRQF, &rcba->d03ir);
- writew(PIRQG, &rcba->d27ir);
- writew(PIRQH, &rcba->d31ir);
- writew(PIRQE, &rcba->d23ir);
- writew(PIRQF, &rcba->d24ir);
- writew(PIRQG, &rcba->d25ir);
- writew(PIRQH, &rcba->d26ir);
-
- if (create_pirq_routing_table()) {
- debug("Failed to create pirq routing table\n");
- } else {
- /* Route PIRQ */
- pirq_route_irqs(pirq_routing_table->slots,
- get_irq_slot_count(pirq_routing_table));
- }
-}
-
-u32 write_pirq_routing_table(u32 addr)
-{
- return copy_pirq_routing_table(addr, pirq_routing_table);
-}
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c
index b46a7e996f8..873de7be9dd 100644
--- a/arch/x86/cpu/queensbay/tnc.c
+++ b/arch/x86/cpu/queensbay/tnc.c
@@ -6,10 +6,11 @@
#include <common.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/pci.h>
#include <asm/post.h>
#include <asm/arch/device.h>
-#include <asm/arch/irq.h>
+#include <asm/arch/tnc.h>
#include <asm/fsp/fsp_support.h>
#include <asm/processor.h>
@@ -45,6 +46,42 @@ int arch_cpu_init(void)
return 0;
}
+void cpu_irq_init(void)
+{
+ struct tnc_rcba *rcba;
+ u32 base;
+
+ base = x86_pci_read_config32(TNC_LPC, LPC_RCBA);
+ base &= ~MEM_BAR_EN;
+ rcba = (struct tnc_rcba *)base;
+
+ /* Make sure all internal PCI devices are using INTA */
+ writel(INTA, &rcba->d02ip);
+ writel(INTA, &rcba->d03ip);
+ writel(INTA, &rcba->d27ip);
+ writel(INTA, &rcba->d31ip);
+ writel(INTA, &rcba->d23ip);
+ writel(INTA, &rcba->d24ip);
+ writel(INTA, &rcba->d25ip);
+ writel(INTA, &rcba->d26ip);
+
+ /*
+ * Route TunnelCreek PCI device interrupt pin to PIRQ
+ *
+ * Since PCIe downstream ports received INTx are routed to PIRQ
+ * A/B/C/D directly and not configurable, we route internal PCI
+ * device's INTx to PIRQ E/F/G/H.
+ */
+ writew(PIRQE, &rcba->d02ir);
+ writew(PIRQF, &rcba->d03ir);
+ writew(PIRQG, &rcba->d27ir);
+ writew(PIRQH, &rcba->d31ir);
+ writew(PIRQE, &rcba->d23ir);
+ writew(PIRQF, &rcba->d24ir);
+ writew(PIRQG, &rcba->d25ir);
+ writew(PIRQH, &rcba->d26ir);
+}
+
int arch_misc_init(void)
{
pirq_init();
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
index 431bbd8a0d6..f86514ce839 100644
--- a/arch/x86/dts/Makefile
+++ b/arch/x86/dts/Makefile
@@ -2,7 +2,9 @@ dtb-y += chromebook_link.dtb \
chromebox_panther.dtb \
crownbay.dtb \
galileo.dtb \
- minnowmax.dtb
+ minnowmax.dtb \
+ qemu-x86_i440fx.dtb \
+ qemu-x86_q35.dtb
targets += $(dtb-y)
diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts
index fbdeade0474..d68efda8dfd 100644
--- a/arch/x86/dts/crownbay.dts
+++ b/arch/x86/dts/crownbay.dts
@@ -6,6 +6,8 @@
/dts-v1/;
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
@@ -135,6 +137,58 @@
};
};
};
+
+ irq-router@1f,0 {
+ reg = <0x0000f800 0 0 0 0>;
+ compatible = "intel,irq-router";
+ intel,pirq-config = "pci";
+ intel,pirq-link = <0x60 8>;
+ intel,pirq-mask = <0xdee0>;
+ intel,pirq-routing = <
+ /* TunnelCreek PCI devices */
+ PCI_BDF(0, 2, 0) INTA PIRQE
+ PCI_BDF(0, 3, 0) INTA PIRQF
+ PCI_BDF(0, 23, 0) INTA PIRQE
+ PCI_BDF(0, 24, 0) INTA PIRQF
+ PCI_BDF(0, 25, 0) INTA PIRQG
+ PCI_BDF(0, 26, 0) INTA PIRQH
+ PCI_BDF(0, 27, 0) INTA PIRQG
+ /*
+ * Topcliff PCI devices
+ *
+ * Note on the Crown Bay board, Topcliff chipset
+ * is connected to TunnelCreek PCIe port 0, so
+ * its bus number is 1 for its PCIe port and 2
+ * for its PCI devices per U-Boot currnet PCI
+ * bus enumeration algorithm.
+ */
+ PCI_BDF(1, 0, 0) INTA PIRQA
+ PCI_BDF(2, 0, 1) INTA PIRQA
+ PCI_BDF(2, 0, 2) INTA PIRQA
+ PCI_BDF(2, 2, 0) INTB PIRQB
+ PCI_BDF(2, 2, 1) INTB PIRQB
+ PCI_BDF(2, 2, 2) INTB PIRQB
+ PCI_BDF(2, 2, 3) INTB PIRQB
+ PCI_BDF(2, 2, 4) INTB PIRQB
+ PCI_BDF(2, 4, 0) INTC PIRQC
+ PCI_BDF(2, 4, 1) INTC PIRQC
+ PCI_BDF(2, 6, 0) INTD PIRQD
+ PCI_BDF(2, 8, 0) INTA PIRQA
+ PCI_BDF(2, 8, 1) INTA PIRQA
+ PCI_BDF(2, 8, 2) INTA PIRQA
+ PCI_BDF(2, 8, 3) INTA PIRQA
+ PCI_BDF(2, 10, 0) INTB PIRQB
+ PCI_BDF(2, 10, 1) INTB PIRQB
+ PCI_BDF(2, 10, 2) INTB PIRQB
+ PCI_BDF(2, 10, 3) INTB PIRQB
+ PCI_BDF(2, 10, 4) INTB PIRQB
+ PCI_BDF(2, 12, 0) INTC PIRQC
+ PCI_BDF(2, 12, 1) INTC PIRQC
+ PCI_BDF(2, 12, 2) INTC PIRQC
+ PCI_BDF(2, 12, 3) INTC PIRQC
+ PCI_BDF(2, 12, 4) INTC PIRQC
+ >;
+ };
};
};
diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts
index 60dbc5f8a30..2ba081e9dc2 100644
--- a/arch/x86/dts/galileo.dts
+++ b/arch/x86/dts/galileo.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include <dt-bindings/mrc/quark.h>
+#include <dt-bindings/interrupt-router/intel-irq.h>
/include/ "skeleton.dtsi"
@@ -67,6 +68,27 @@
clock-frequency = <44236800>;
current-speed = <115200>;
};
+
+ irq-router@1f,0 {
+ reg = <0x0000f800 0 0 0 0>;
+ compatible = "intel,irq-router";
+ intel,pirq-config = "pci";
+ intel,pirq-link = <0x60 8>;
+ intel,pirq-mask = <0xdef8>;
+ intel,pirq-routing = <
+ PCI_BDF(0, 20, 0) INTA PIRQE
+ PCI_BDF(0, 20, 1) INTB PIRQF
+ PCI_BDF(0, 20, 2) INTC PIRQG
+ PCI_BDF(0, 20, 3) INTD PIRQH
+ PCI_BDF(0, 20, 4) INTA PIRQE
+ PCI_BDF(0, 20, 5) INTB PIRQF
+ PCI_BDF(0, 20, 6) INTC PIRQG
+ PCI_BDF(0, 20, 7) INTD PIRQH
+ PCI_BDF(0, 21, 0) INTA PIRQE
+ PCI_BDF(0, 21, 1) INTB PIRQF
+ PCI_BDF(0, 21, 2) INTC PIRQG
+ >;
+ };
};
gpioa {
diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
index 7103bc50777..bd21bfb0b4f 100644
--- a/arch/x86/dts/minnowmax.dts
+++ b/arch/x86/dts/minnowmax.dts
@@ -6,6 +6,8 @@
/dts-v1/;
+#include <dt-bindings/gpio/x86-gpio.h>
+
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
@@ -22,6 +24,27 @@
silent_console = <0>;
};
+ pch_pinctrl {
+ compatible = "intel,x86-pinctrl";
+ io-base = <0x4c>;
+
+ pin_usb_host_en0@0 {
+ gpio-offset = <0x80 8>;
+ pad-offset = <0x260>;
+ mode-gpio;
+ output-value = <1>;
+ direction = <PIN_OUTPUT>;
+ };
+
+ pin_usb_host_en1@0 {
+ gpio-offset = <0x80 9>;
+ pad-offset = <0x258>;
+ mode-gpio;
+ output-value = <1>;
+ direction = <PIN_OUTPUT>;
+ };
+ };
+
gpioa {
compatible = "intel,ich6-gpio";
u-boot,dm-pre-reloc;
diff --git a/arch/x86/dts/qemu-x86_i440fx.dts b/arch/x86/dts/qemu-x86_i440fx.dts
new file mode 100644
index 00000000000..557428a459c
--- /dev/null
+++ b/arch/x86/dts/qemu-x86_i440fx.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/include/ "skeleton.dtsi"
+/include/ "serial.dtsi"
+
+/ {
+ model = "QEMU x86 (I440FX)";
+ compatible = "qemu,x86";
+
+ config {
+ silent_console = <0>;
+ };
+
+ chosen {
+ stdout-path = "/serial";
+ };
+
+ pci {
+ compatible = "pci-x86";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ u-boot,dm-pre-reloc;
+ ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000
+ 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000
+ 0x01000000 0x0 0x2000 0x2000 0 0xe000>;
+
+ irq-router@1,0 {
+ reg = <0x00000800 0 0 0 0>;
+ compatible = "intel,irq-router";
+ intel,pirq-config = "pci";
+ intel,pirq-link = <0x60 4>;
+ intel,pirq-mask = <0x0e40>;
+ intel,pirq-routing = <
+ /* PIIX UHCI */
+ PCI_BDF(0, 1, 2) INTD PIRQD
+ /* e1000 NIC */
+ PCI_BDF(0, 3, 0) INTA PIRQC
+ >;
+ };
+ };
+
+};
diff --git a/arch/x86/dts/qemu-x86_q35.dts b/arch/x86/dts/qemu-x86_q35.dts
new file mode 100644
index 00000000000..c259f2a3d29
--- /dev/null
+++ b/arch/x86/dts/qemu-x86_q35.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/* ICH9 IRQ router has discrete PIRQ control registers */
+#undef PIRQE
+#undef PIRQF
+#undef PIRQG
+#undef PIRQH
+#define PIRQE 8
+#define PIRQF 9
+#define PIRQG 10
+#define PIRQH 11
+
+/include/ "skeleton.dtsi"
+/include/ "serial.dtsi"
+
+/ {
+ model = "QEMU x86 (Q35)";
+ compatible = "qemu,x86";
+
+ config {
+ silent_console = <0>;
+ u-boot,no-apm-finalize;
+ };
+
+ chosen {
+ stdout-path = "/serial";
+ };
+
+ pci {
+ compatible = "pci-x86";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ u-boot,dm-pre-reloc;
+ ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000
+ 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000
+ 0x01000000 0x0 0x2000 0x2000 0 0xe000>;
+
+ irq-router@1f,0 {
+ reg = <0x0000f800 0 0 0 0>;
+ compatible = "intel,irq-router";
+ intel,pirq-config = "pci";
+ intel,pirq-link = <0x60 8>;
+ intel,pirq-mask = <0x0e40>;
+ intel,pirq-routing = <
+ /* e1000 NIC */
+ PCI_BDF(0, 2, 0) INTA PIRQG
+ /* ICH9 UHCI */
+ PCI_BDF(0, 29, 0) INTA PIRQA
+ PCI_BDF(0, 29, 1) INTB PIRQB
+ PCI_BDF(0, 29, 2) INTC PIRQC
+ /* ICH9 EHCI */
+ PCI_BDF(0, 29, 7) INTD PIRQD
+ /* ICH9 SATA */
+ PCI_BDF(0, 31, 2) INTA PIRQA
+ >;
+ };
+ };
+
+};
diff --git a/arch/x86/include/asm/arch-qemu/device.h b/arch/x86/include/asm/arch-qemu/device.h
new file mode 100644
index 00000000000..75a435e67b9
--- /dev/null
+++ b/arch/x86/include/asm/arch-qemu/device.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _QEMU_DEVICE_H_
+#define _QEMU_DEVICE_H_
+
+#include <pci.h>
+
+#define QEMU_I440FX PCI_BDF(0, 0, 0)
+#define PIIX_ISA PCI_BDF(0, 1, 0)
+#define PIIX_IDE PCI_BDF(0, 1, 1)
+#define PIIX_USB PCI_BDF(0, 1, 2)
+#define I440FX_VGA PCI_BDF(0, 2, 0)
+
+#define QEMU_Q35 PCI_BDF(0, 0, 0)
+#define Q35_VGA PCI_BDF(0, 1, 0)
+
+#endif /* _QEMU_DEVICE_H_ */
diff --git a/arch/x86/include/asm/arch-qemu/gpio.h b/arch/x86/include/asm/arch-qemu/gpio.h
new file mode 100644
index 00000000000..ca8cba4f97c
--- /dev/null
+++ b/arch/x86/include/asm/arch-qemu/gpio.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _X86_ARCH_GPIO_H_
+#define _X86_ARCH_GPIO_H_
+
+/* Where in config space is the register that points to the GPIO registers? */
+#define PCI_CFG_GPIOBASE 0x44
+
+#endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/include/asm/arch-qemu/qemu.h b/arch/x86/include/asm/arch-qemu/qemu.h
new file mode 100644
index 00000000000..5cbfffffee5
--- /dev/null
+++ b/arch/x86/include/asm/arch-qemu/qemu.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ARCH_QEMU_H_
+#define _ARCH_QEMU_H_
+
+/* Programmable Attribute Map (PAM) Registers */
+#define I440FX_PAM 0x59
+#define Q35_PAM 0x90
+#define PAM_NUM 7
+#define PAM_RW 0x33
+
+/* IDE Timing Register */
+#define IDE0_TIM 0x40
+#define IDE1_TIM 0x42
+#define IDE_DECODE_EN 0x8000
+
+/* I/O Ports */
+#define CMOS_ADDR_PORT 0x70
+#define CMOS_DATA_PORT 0x71
+
+#define LOW_RAM_ADDR 0x34
+#define HIGH_RAM_ADDR 0x35
+
+#endif /* _ARCH_QEMU_H_ */
diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h
index 4af3dedc957..7882f339f0a 100644
--- a/arch/x86/include/asm/arch-quark/device.h
+++ b/arch/x86/include/asm/arch-quark/device.h
@@ -9,20 +9,60 @@
#include <pci.h>
-#define QUARK_HOST_BRIDGE PCI_BDF(0, 0, 0)
-#define QUARK_MMC_SDIO PCI_BDF(0, 20, 0)
-#define QUARK_UART0 PCI_BDF(0, 20, 1)
-#define QUARK_USB_DEVICE PCI_BDF(0, 20, 2)
-#define QUARK_USB_EHCI PCI_BDF(0, 20, 3)
-#define QUARK_USB_OHCI PCI_BDF(0, 20, 4)
-#define QUARK_UART1 PCI_BDF(0, 20, 5)
-#define QUARK_EMAC0 PCI_BDF(0, 20, 6)
-#define QUARK_EMAC1 PCI_BDF(0, 20, 7)
-#define QUARK_SPI0 PCI_BDF(0, 21, 0)
-#define QUARK_SPI1 PCI_BDF(0, 21, 1)
-#define QUARK_I2C_GPIO PCI_BDF(0, 21, 2)
-#define QUARK_PCIE0 PCI_BDF(0, 23, 0)
-#define QUARK_PCIE1 PCI_BDF(0, 23, 1)
-#define QUARK_LEGACY_BRIDGE PCI_BDF(0, 31, 0)
+#define QUARK_HOST_BRIDGE_DEV 0
+#define QUARK_HOST_BRIDGE_FUNC 0
+
+#define QUARK_DEV_20 20
+#define QUARK_MMC_SDIO_FUNC 0
+#define QUARK_UART0_FUNC 1
+#define QUARK_USB_DEVICE_FUNC 2
+#define QUARK_USB_EHCI_FUNC 3
+#define QUARK_USB_OHCI_FUNC 4
+#define QUARK_UART1_FUNC 5
+#define QUARK_EMAC0_FUNC 6
+#define QUARK_EMAC1_FUNC 7
+
+#define QUARK_DEV_21 21
+#define QUARK_SPI0_FUNC 0
+#define QUARK_SPI1_FUNC 1
+#define QUARK_I2C_GPIO_FUNC 2
+
+#define QUARK_DEV_23 23
+#define QUARK_PCIE0_FUNC 0
+#define QUARK_PCIE1_FUNC 1
+
+#define QUARK_LGC_BRIDGE_DEV 31
+#define QUARK_LGC_BRIDGE_FUNC 0
+
+#define QUARK_HOST_BRIDGE \
+ PCI_BDF(0, QUARK_HOST_BRIDGE_DEV, QUARK_HOST_BRIDGE_FUNC)
+#define QUARK_MMC_SDIO \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_MMC_SDIO_FUNC)
+#define QUARK_UART0 \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_UART0_FUNC)
+#define QUARK_USB_DEVICE \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_USB_DEVICE_FUNC)
+#define QUARK_USB_EHCI \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_USB_EHCI_FUNC)
+#define QUARK_USB_OHCI \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_USB_OHCI_FUNC)
+#define QUARK_UART1 \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_UART1_FUNC)
+#define QUARK_EMAC0 \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_EMAC0_FUNC)
+#define QUARK_EMAC1 \
+ PCI_BDF(0, QUARK_DEV_20, QUARK_EMAC1_FUNC)
+#define QUARK_SPI0 \
+ PCI_BDF(0, QUARK_DEV_21, QUARK_SPI0_FUNC)
+#define QUARK_SPI1 \
+ PCI_BDF(0, QUARK_DEV_21, QUARK_SPI1_FUNC)
+#define QUARK_I2C_GPIO \
+ PCI_BDF(0, QUARK_DEV_21, QUARK_I2C_GPIO_FUNC)
+#define QUARK_PCIE0 \
+ PCI_BDF(0, QUARK_DEV_23, QUARK_PCIE0_FUNC)
+#define QUARK_PCIE1 \
+ PCI_BDF(0, QUARK_DEV_23, QUARK_PCIE1_FUNC)
+#define QUARK_LEGACY_BRIDGE \
+ PCI_BDF(0, QUARK_LGC_BRIDGE_DEV, QUARK_LGC_BRIDGE_FUNC)
#endif /* _QUARK_DEVICE_H_ */
diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h
index 6dd02fd31ed..c9979280b62 100644
--- a/arch/x86/include/asm/arch-quark/quark.h
+++ b/arch/x86/include/asm/arch-quark/quark.h
@@ -76,4 +76,19 @@
#define LB_BC 0xd8
#define LB_RCBA 0xf0
+#ifndef __ASSEMBLY__
+
+/* Root Complex Register Block */
+struct quark_rcba {
+ u32 rctl;
+ u32 esd;
+ u32 rsvd1[3150];
+ u16 rmu_ir;
+ u16 d23_ir;
+ u16 core_ir;
+ u16 d20d21_ir;
+};
+
+#endif /* __ASSEMBLY__ */
+
#endif /* _QUARK_H_ */
diff --git a/arch/x86/include/asm/arch-queensbay/irq.h b/arch/x86/include/asm/arch-queensbay/irq.h
deleted file mode 100644
index e7f861623e3..00000000000
--- a/arch/x86/include/asm/arch-queensbay/irq.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef _ARCH_IRQ_H_
-#define _ARCH_IRQ_H_
-
-enum pci_int_pin {
- INTX,
- INTA,
- INTB,
- INTC,
- INTD
-};
-
-enum pirq_pin {
- PIRQA,
- PIRQB,
- PIRQC,
- PIRQD,
- PIRQE,
- PIRQF,
- PIRQG,
- PIRQH
-};
-
-/* PIRQ link number and value conversion */
-#define LINK_V2N(link) (link - 0x60)
-#define LINK_N2V(link) (link + 0x60)
-
-#define PIRQ_BITMAP 0xdee0
-
-struct irq_info;
-
-/**
- * board_fill_irq_info() - Board-specific irq_info fill routine
- *
- * This fills the irq_info table for any board-specific add-in cards.
- *
- * @slot: pointer to the struct irq_info that is to be filled in
- * @return: number of entries were written to the struct irq_info
- */
-int board_fill_irq_info(struct irq_info *slot);
-
-/**
- * pirq_init() - Initialize platform PIRQ routing
- *
- * This initializes the PIRQ routing on the platform and configures all PCI
- * devices' interrupt line register to a working IRQ number on the 8259 PIC.
- */
-void pirq_init(void);
-
-#endif /* _ARCH_IRQ_H_ */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
index 10994273881..ed85b08ce7f 100644
--- a/arch/x86/include/asm/gpio.h
+++ b/arch/x86/include/asm/gpio.h
@@ -147,6 +147,7 @@ struct pch_gpio_map {
} set3;
};
+int gpio_ich6_pinctrl_init(void);
void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio);
void ich_gpio_set_gpio_map(const struct pch_gpio_map *map);
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
new file mode 100644
index 00000000000..4de5512ce13
--- /dev/null
+++ b/arch/x86/include/asm/irq.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ARCH_IRQ_H_
+#define _ARCH_IRQ_H_
+
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/**
+ * Intel interrupt router configuration mechanism
+ *
+ * There are two known ways of Intel interrupt router configuration mechanism
+ * so far. On most cases, the IRQ routing configuraiton is controlled by PCI
+ * configuraiton registers on the legacy bridge, normally PCI BDF(0, 31, 0).
+ * On some newer platforms like BayTrail and Braswell, the IRQ routing is now
+ * in the IBASE register block where IBASE is memory-mapped.
+ */
+enum pirq_config {
+ PIRQ_VIA_PCI,
+ PIRQ_VIA_IBASE
+};
+
+/**
+ * Intel interrupt router control block
+ *
+ * Its members' value will be filled in based on device tree's input.
+ *
+ * @config: PIRQ_VIA_PCI or PIRQ_VIA_IBASE
+ * @link_base: link value base number
+ * @irq_mask: IRQ mask reprenting the 16 IRQs in 8259, bit N is 1 means
+ * IRQ N is available to be routed
+ * @lb_bdf: irq router's PCI bus/device/function number encoding
+ * @ibase: IBASE register block base address
+ */
+struct irq_router {
+ int config;
+ u32 link_base;
+ u16 irq_mask;
+ u32 bdf;
+ u32 ibase;
+};
+
+struct pirq_routing {
+ int bdf;
+ int pin;
+ int pirq;
+};
+
+/* PIRQ link number and value conversion */
+#define LINK_V2N(link, base) (link - base)
+#define LINK_N2V(link, base) (link + base)
+
+#define PIRQ_BITMAP 0xdef8
+
+/**
+ * cpu_irq_init() - Initialize CPU IRQ routing
+ *
+ * This initializes some platform-specific registers related to IRQ routing,
+ * like configuring internal PCI devices to use which PCI interrupt pin,
+ * and which PCI interrupt pin is mapped to which PIRQ line. Note on some
+ * platforms, such IRQ routing might be hard-coded thus cannot configure.
+ */
+void cpu_irq_init(void);
+
+/**
+ * pirq_init() - Initialize platform PIRQ routing
+ *
+ * This initializes the PIRQ routing on the platform and configures all PCI
+ * devices' interrupt line register to a working IRQ number on the 8259 PIC.
+ */
+void pirq_init(void);
+
+#endif /* _ARCH_IRQ_H_ */
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index be103c055c1..d1d21ed6606 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -16,7 +16,6 @@ void init_gd(gd_t *id, u64 *gdt_addr);
void setup_gdt(gd_t *id, u64 *gdt_addr);
int init_cache(void);
int cleanup_before_linux(void);
-void panic_puts(const char *str);
/* cpu/.../timer.c */
void timer_isr(void *);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
index 5f96da120ea..5809235b10a 100644
--- a/arch/x86/lib/fsp/fsp_support.c
+++ b/arch/x86/lib/fsp/fsp_support.c
@@ -279,7 +279,7 @@ u64 fsp_get_usable_highmem_top(const void *hob_list)
res_desc = (struct hob_res_desc *)hdr;
if (res_desc->type == RES_SYS_MEM) {
phys_start = res_desc->phys_start;
- /* Need memory above 1MB to be collected here */
+ /* Need memory above 4GB to be collected here */
if (phys_start >= (phys_addr_t)FSP_HIGHMEM_BASE)
top += (u32)(res_desc->len);
}
diff --git a/board/coreboot/coreboot/Kconfig b/board/coreboot/coreboot/Kconfig
index 6a04158f16a..3ff64f40844 100644
--- a/board/coreboot/coreboot/Kconfig
+++ b/board/coreboot/coreboot/Kconfig
@@ -16,21 +16,21 @@ comment "coreboot-specific options"
config SYS_CONFIG_NAME
string "Board configuration file"
- default "chromebook_link"
+ default "qemu-x86"
help
This option selects the board configuration file in include/configs/
directory to be used to build U-Boot for coreboot.
config DEFAULT_DEVICE_TREE
string "Board Device Tree Source (dts) file"
- default "chromebook_link"
+ default "qemu-x86_i440fx"
help
This option selects the board Device Tree Source (dts) file in
arch/x86/dts/ directory to be used to build U-Boot for coreboot.
config SYS_CAR_ADDR
hex "Board specific Cache-As-RAM (CAR) address"
- default 0x19200000
+ default 0x01920000
help
This option specifies the board specific Cache-As-RAM (CAR) address.
diff --git a/board/emulation/Kconfig b/board/emulation/Kconfig
new file mode 100644
index 00000000000..36809fd3761
--- /dev/null
+++ b/board/emulation/Kconfig
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+if VENDOR_EMULATION
+
+choice
+ prompt "Mainboard model"
+
+config TARGET_QEMU_X86
+ bool "QEMU x86"
+ help
+ This is the QEMU emulated x86 board. U-Boot supports running
+ as a coreboot payload as well as bare boot without coreboot.
+ There are two types of x86 boards supported by QEMU which are
+ supported by U-Boot. They are via QEMU '-M pc', an i440FX/PIIX
+ chipset platform and '-M q35', a Q35/ICH9 chipset platform.
+
+endchoice
+
+source "board/emulation/qemu-x86/Kconfig"
+
+endif
diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
new file mode 100644
index 00000000000..e777ef44090
--- /dev/null
+++ b/board/emulation/qemu-x86/Kconfig
@@ -0,0 +1,24 @@
+if TARGET_QEMU_X86
+
+config SYS_BOARD
+ default "qemu-x86"
+
+config SYS_VENDOR
+ default "emulation"
+
+config SYS_SOC
+ default "qemu"
+
+config SYS_CONFIG_NAME
+ default "qemu-x86"
+
+config SYS_TEXT_BASE
+ default 0xfff00000
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select X86_RESET_VECTOR
+ select QEMU
+ select BOARD_ROMSIZE_KB_1024
+
+endif
diff --git a/board/emulation/qemu-x86/MAINTAINERS b/board/emulation/qemu-x86/MAINTAINERS
new file mode 100644
index 00000000000..ea4dd193542
--- /dev/null
+++ b/board/emulation/qemu-x86/MAINTAINERS
@@ -0,0 +1,6 @@
+QEMU X86 BOARD
+M: Bin Meng <bmeng.cn@gmail.com>
+S: Maintained
+F: board/emulation/qemu-x86/
+F: include/configs/qemu-x86.h
+F: configs/qemu-x86_defconfig
diff --git a/board/emulation/qemu-x86/Makefile b/board/emulation/qemu-x86/Makefile
new file mode 100644
index 00000000000..ad2bbb94a2a
--- /dev/null
+++ b/board/emulation/qemu-x86/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += qemu-x86.o start.o
diff --git a/board/emulation/qemu-x86/qemu-x86.c b/board/emulation/qemu-x86/qemu-x86.c
new file mode 100644
index 00000000000..fedea81abc4
--- /dev/null
+++ b/board/emulation/qemu-x86/qemu-x86.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <netdev.h>
+
+int board_eth_init(bd_t *bis)
+{
+ return pci_eth_init(bis);
+}
diff --git a/board/emulation/qemu-x86/start.S b/board/emulation/qemu-x86/start.S
new file mode 100644
index 00000000000..a71db69be9c
--- /dev/null
+++ b/board/emulation/qemu-x86/start.S
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+.globl early_board_init
+early_board_init:
+ jmp early_board_init_ret
diff --git a/board/intel/crownbay/crownbay.c b/board/intel/crownbay/crownbay.c
index 31bb3202130..ad2d5b69d6e 100644
--- a/board/intel/crownbay/crownbay.c
+++ b/board/intel/crownbay/crownbay.c
@@ -12,8 +12,6 @@
#define SERIAL_DEV PNP_DEV(0x2e, 4)
-DECLARE_GLOBAL_DATA_PTR;
-
int board_early_init_f(void)
{
lpc47m_enable_serial(SERIAL_DEV, UART0_BASE, UART0_IRQ);
diff --git a/board/intel/galileo/galileo.c b/board/intel/galileo/galileo.c
index f2e74687ed4..746ab277cb3 100644
--- a/board/intel/galileo/galileo.c
+++ b/board/intel/galileo/galileo.c
@@ -6,8 +6,6 @@
#include <common.h>
-DECLARE_GLOBAL_DATA_PTR;
-
int board_early_init_f(void)
{
return 0;
diff --git a/board/intel/minnowmax/minnowmax.c b/board/intel/minnowmax/minnowmax.c
index fd2070afb28..383cae068bd 100644
--- a/board/intel/minnowmax/minnowmax.c
+++ b/board/intel/minnowmax/minnowmax.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <asm/gpio.h>
#include <asm/ibmpc.h>
#include <asm/pnp_def.h>
#include <netdev.h>
@@ -12,7 +13,13 @@
#define SERIAL_DEV PNP_DEV(0x2e, 4)
-DECLARE_GLOBAL_DATA_PTR;
+int arch_early_init_r(void)
+{
+ /* do the pin-muxing */
+ gpio_ich6_pinctrl_init();
+
+ return 0;
+}
int board_early_init_f(void)
{
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index 04a6d9b3983..ecd3e9d64f0 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -79,7 +79,7 @@ static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len
#ifdef CONFIG_ATAPI
static void atapi_inquiry(block_dev_desc_t *dev_desc);
-static ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt,
+static ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt,
void *buffer);
#endif
@@ -1388,13 +1388,13 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */
#define ATAPI_READ_MAX_BLOCK (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
-ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
+ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
{
ulong n = 0;
unsigned char ccb[12]; /* Command descriptor block */
ulong cnt;
- debug("atapi_read dev %d start %lX, blocks " LBAF " buffer at %lX\n",
+ debug("atapi_read dev %d start " LBAF " blocks " LBAF " buffer at %lX\n",
device, blknr, blkcnt, (ulong) buffer);
do {
diff --git a/configs/coreboot-x86_defconfig b/configs/coreboot-x86_defconfig
index 9bed74c3ca7..97ac1fa5528 100644
--- a/configs/coreboot-x86_defconfig
+++ b/configs/coreboot-x86_defconfig
@@ -1,5 +1,7 @@
CONFIG_X86=y
+CONFIG_VENDOR_COREBOOT=y
CONFIG_TARGET_COREBOOT=y
CONFIG_CMD_NET=y
CONFIG_OF_CONTROL=y
CONFIG_DM_PCI=y
+CONFIG_TSC_CALIBRATION_BYPASS=y
diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig
index c0a937f91e7..a3b564ec54f 100644
--- a/configs/galileo_defconfig
+++ b/configs/galileo_defconfig
@@ -6,3 +6,4 @@ CONFIG_TARGET_GALILEO=y
CONFIG_CMD_NET=y
CONFIG_OF_CONTROL=y
CONFIG_ETH_DESIGNWARE=y
+CONFIG_GENERATE_PIRQ_TABLE=y
diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig
index 87c99a83d05..744aca38821 100644
--- a/configs/minnowmax_defconfig
+++ b/configs/minnowmax_defconfig
@@ -3,6 +3,7 @@ CONFIG_VENDOR_INTEL=y
CONFIG_DEFAULT_DEVICE_TREE="minnowmax"
CONFIG_TARGET_MINNOWMAX=y
CONFIG_HAVE_INTEL_ME=y
+CONFIG_VIDEO_VESA=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
CONFIG_SMP=y
diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig
new file mode 100644
index 00000000000..901cbd72a9d
--- /dev/null
+++ b/configs/qemu-x86_defconfig
@@ -0,0 +1,10 @@
+CONFIG_X86=y
+CONFIG_VENDOR_EMULATION=y
+CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx"
+CONFIG_TARGET_QEMU_X86=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_CMD_NET=y
+CONFIG_OF_CONTROL=y
+CONFIG_VIDEO_VESA=y
+CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_FRAMEBUFFER_VESA_MODE_111=y
diff --git a/doc/README.x86 b/doc/README.x86
index ef13fb45f4c..c19f4a03ba0 100644
--- a/doc/README.x86
+++ b/doc/README.x86
@@ -14,12 +14,13 @@ including supported boards, build instructions, todo list, etc.
Status
------
U-Boot supports running as a coreboot [1] payload on x86. So far only Link
-(Chromebook Pixel) has been tested, but it should work with minimal adjustments
-on other x86 boards since coreboot deals with most of the low-level details.
+(Chromebook Pixel) and QEMU [2] x86 targets have been tested, but it should
+work with minimal adjustments on other x86 boards since coreboot deals with
+most of the low-level details.
U-Boot also supports booting directly from x86 reset vector without coreboot,
-aka raw support or bare support. Currently Link, Intel Crown Bay, Intel
-Minnowboard Max and Intel Galileo support running U-Boot 'bare metal'.
+aka raw support or bare support. Currently Link, QEMU x86 targets and all
+Intel boards support running U-Boot 'bare metal'.
As for loading an OS, U-Boot supports directly booting a 32-bit or 64-bit
Linux kernel as part of a FIT image. It also supports a compressed zImage.
@@ -32,15 +33,15 @@ on other architectures, like below:
$ make coreboot-x86_defconfig
$ make all
-Note this default configuration will build a U-Boot payload for the Link board.
+Note this default configuration will build a U-Boot payload for the QEMU board.
To build a coreboot payload against another board, you can change the build
configuration during the 'make menuconfig' process.
x86 architecture --->
...
- (chromebook_link) Board configuration file
- (chromebook_link) Board Device Tree Source (dts) file
- (0x19200000) Board specific Cache-As-RAM (CAR) address
+ (qemu-x86) Board configuration file
+ (qemu-x86_i440fx) Board Device Tree Source (dts) file
+ (0x01920000) Board specific Cache-As-RAM (CAR) address
(0x4000) Board specific Cache-As-RAM (CAR) size
Change the 'Board configuration file' and 'Board Device Tree Source (dts) file'
@@ -78,7 +79,7 @@ Find the following files:
* ./northbridge/intel/sandybridge/systemagent-r6.bin
The 3rd one should be renamed to mrc.bin.
-As for the video ROM, you can get it here [2].
+As for the video ROM, you can get it here [3].
Make sure all these binary blobs are put in the board directory.
Now you can build U-Boot and obtain u-boot.rom:
@@ -88,8 +89,8 @@ $ make all
Intel Crown Bay specific instructions:
-U-Boot support of Intel Crown Bay board [3] relies on a binary blob called
-Firmware Support Package [4] to perform all the necessary initialization steps
+U-Boot support of Intel Crown Bay board [4] relies on a binary blob called
+Firmware Support Package [5] to perform all the necessary initialization steps
as documented in the BIOS Writer Guide, including initialization of the CPU,
memory controller, chipset and certain bus interfaces.
@@ -178,6 +179,21 @@ Now you can build U-Boot and obtain u-boot.rom
$ make galileo_defconfig
$ make all
+QEMU x86 target instructions:
+
+To build u-boot.rom for QEMU x86 targets, just simply run
+
+$ make qemu-x86_defconfig
+$ make all
+
+Note this default configuration will build a U-Boot for the QEMU x86 i440FX
+board. To build a U-Boot against QEMU x86 Q35 board, you can change the build
+configuration during the 'make menuconfig' process like below:
+
+Device Tree Control --->
+ ...
+ (qemu-x86_q35) Default Device Tree for DT control
+
Test with coreboot
------------------
For testing U-Boot as the coreboot payload, there are things that need be paid
@@ -207,10 +223,38 @@ At present it seems that for Minnowboard Max, coreboot does not pass through
the video information correctly (it always says the resolution is 0x0). This
works correctly for link though.
+Test with QEMU
+--------------
+QEMU is a fancy emulator that can enable us to test U-Boot without access to
+a real x86 board. Please make sure your QEMU version is 2.3.0 or above test
+U-Boot. To launch QEMU with u-boot.rom, call QEMU as follows:
+
+$ qemu-system-i386 -nographic -bios path/to/u-boot.rom
+
+This will instantiate an emulated x86 board with i440FX and PIIX chipset. QEMU
+also supports emulating an x86 board with Q35 and ICH9 based chipset, which is
+also supported by U-Boot. To instantiate such a machine, call QEMU with:
+
+$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -M q35
+
+Note by default QEMU instantiated boards only have 128 MiB system memory. But
+it is enough to have U-Boot boot and function correctly. You can increase the
+system memory by pass '-m' parameter to QEMU if you want more memory:
+
+$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -m 1024
+
+This creates a board with 1 GiB system memory. Currently U-Boot for QEMU only
+supports 3 GiB maximum system memory and reserves the last 1 GiB address space
+for PCI device memory-mapped I/O and other stuff, so the maximum value of '-m'
+would be 3072.
+
+QEMU emulates a graphic card which U-Boot supports. Removing '-nographic' will
+show QEMU's VGA console window. Note this will disable QEMU's serial output.
+If you want to check both consoles, use '-serial stdio'.
CPU Microcode
-------------
-Modern CPUs usually require a special bit stream called microcode [5] to be
+Modern CPUs usually require a special bit stream called microcode [6] to be
loaded on the processor after power up in order to function properly. U-Boot
has already integrated these as hex dumps in the source tree.
@@ -227,7 +271,6 @@ arch/x86/dts/ for these device tree source files.
Useful Commands
---------------
-
In keeping with the U-Boot philosophy of providing functions to check and
adjust internal settings, there are several x86-specific commands that may be
useful:
@@ -314,7 +357,8 @@ TODO List
References
----------
[1] http://www.coreboot.org
-[2] http://www.coreboot.org/~stepan/pci8086,0166.rom
-[3] http://www.intel.com/content/www/us/en/embedded/design-tools/evaluation-platforms/atom-e660-eg20t-development-kit.html
-[4] http://www.intel.com/fsp
-[5] http://en.wikipedia.org/wiki/Microcode
+[2] http://www.qemu.org
+[3] http://www.coreboot.org/~stepan/pci8086,0166.rom
+[4] http://www.intel.com/content/www/us/en/embedded/design-tools/evaluation-platforms/atom-e660-eg20t-development-kit.html
+[5] http://www.intel.com/fsp
+[6] http://en.wikipedia.org/wiki/Microcode
diff --git a/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt
new file mode 100644
index 00000000000..45ab1afc395
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt
@@ -0,0 +1,31 @@
+Intel x86 PINCTRL/GPIO controller
+
+Pin-muxing on x86 can be described with a node for the PINCTRL master
+node and a set of child nodes for each pin on the SoC.
+
+The PINCTRL master node requires the following properties:
+- compatible : "intel,x86-pinctrl"
+
+Pin nodes must be children of the pinctrl master node and can
+contain the following properties:
+- pad-offset - (required) offset in the IOBASE for the pin to configured.
+- gpio-offset - (required) offset in the GPIOBASE for the pin to configured and
+ also the bit shift in this register.
+- mode-gpio - (optional) standalone property to force the pin into GPIO mode.
+- mode-func - (optional) function number to assign to the pin. if 'mode-gpio'
+ is set, this property will be ignored.
+in case of 'mode-gpio' property set:
+- output-value - (optional) this set the default output value of the GPIO.
+- direction - (optional) this set the direction of the gpio.
+- pull-str - (optional) this set the pull strength of the pin.
+- pull-assign - (optional) this set the pull assignement (up/down) of the pin.
+
+Example:
+
+pin_usb_host_en0@0 {
+ gpio-offset = <0x80 8>;
+ pad-offset = <0x260>;
+ mode-gpio;
+ output-value = <1>;
+ direction = <PIN_OUTPUT>;
+};
diff --git a/doc/device-tree-bindings/misc/intel,irq-router.txt b/doc/device-tree-bindings/misc/intel,irq-router.txt
new file mode 100644
index 00000000000..598b4b1c2f5
--- /dev/null
+++ b/doc/device-tree-bindings/misc/intel,irq-router.txt
@@ -0,0 +1,50 @@
+Intel Interrupt Router Device Binding
+=====================================
+
+The device tree node which describes the operation of the Intel Interrupt Router
+device is as follows:
+
+Required properties :
+- reg : Specifies the interrupt router's PCI configuration space address as
+ defined by the Open Firmware spec.
+- compatible = "intel,irq-router"
+- intel,pirq-config : Specifies the IRQ routing register programming mechanism.
+ Valid values are:
+ "pci": IRQ routing is controlled by PCI configuration registers
+ "ibase": IRQ routing is in the memory-mapped IBASE register block
+- intel,ibase-offset : IBASE register offset in the interrupt router's PCI
+ configuration space, required only if intel,pirq-config = "ibase".
+- intel,pirq-link : Specifies the PIRQ link information with two cells. The
+ first cell is the register offset that controls the first PIRQ link routing.
+ The second cell is the total number of PIRQ links the router supports.
+- intel,pirq-mask : Specifies the IRQ mask reprenting the 16 IRQs in 8259 PIC.
+ Bit N is 1 means IRQ N is available to be routed.
+- intel,pirq-routing : Specifies all PCI devices' IRQ routing information,
+ encoded as 3 cells a group for a device. The first cell is the device's PCI
+ bus number, device number and function number encoding with PCI_BDF() macro.
+ The second cell is the PCI interrupt pin used by this device. The last cell
+ is which PIRQ line the PCI interrupt pin is routed to.
+
+
+Example
+-------
+
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+ irq-router@1f,0 {
+ reg = <0x0000f800 0 0 0 0>;
+ compatible = "intel,irq-router";
+ intel,pirq-config = "pci";
+ intel,pirq-link = <0x60 8>;
+ intel,pirq-mask = <0xdef8>;
+ intel,pirq-routing = <
+ PCI_BDF(0, 2, 0) INTA PIRQA
+ PCI_BDF(0, 3, 0) INTA PIRQB
+ PCI_BDF(0, 8, 0) INTA PIRQC
+ PCI_BDF(0, 8, 1) INTB PIRQD
+ PCI_BDF(1, 6, 0) INTA PIRQE
+ PCI_BDF(1, 6, 1) INTB PIRQF
+ PCI_BDF(1, 6, 2) INTC PIRQG
+ PCI_BDF(1, 6, 3) INTD PIRQH
+ >;
+ };
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7e679a086e3..8a108f3805a 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -44,21 +44,28 @@ struct ich6_bank_priv {
uint16_t lvl;
};
+#define GPIO_USESEL_OFFSET(x) (x)
+#define GPIO_IOSEL_OFFSET(x) (x + 4)
+#define GPIO_LVL_OFFSET(x) (x + 8)
+
+#define IOPAD_MODE_MASK 0x7
+#define IOPAD_PULL_ASSIGN_SHIFT 7
+#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT)
+#define IOPAD_PULL_STRENGTH_SHIFT 9
+#define IOPAD_PULL_STRENGTH_MASK (0x3 << IOPAD_PULL_STRENGTH_SHIFT)
+
/* TODO: Move this to device tree, or platform data */
void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
{
gd->arch.gpio_map = map;
}
-static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
+static int gpio_ich6_get_base(unsigned long base)
{
- struct ich6_bank_platdata *plat = dev_get_platdata(dev);
pci_dev_t pci_dev; /* handle for 0:1f:0 */
u8 tmpbyte;
u16 tmpword;
u32 tmplong;
- u16 gpiobase;
- int offset;
/* Where should it be? */
pci_dev = PCI_BDF(0, 0x1f, 0);
@@ -123,9 +130,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
* while on the Ivybridge the bit0 is used to indicate it is an
* I/O space.
*/
- tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
+ tmplong = x86_pci_read_config32(pci_dev, base);
if (tmplong == 0x00000000 || tmplong == 0xffffffff) {
- debug("%s: unexpected GPIOBASE value\n", __func__);
+ debug("%s: unexpected BASE value\n", __func__);
return -ENODEV;
}
@@ -135,7 +142,215 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
* at the offset that we just read. Bit 0 indicates that it's
* an I/O address, not a memory address, so mask that off.
*/
- gpiobase = tmplong & 0xfffe;
+ return tmplong & 0xfffc;
+}
+
+static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value)
+{
+ u32 val;
+
+ val = inl(base);
+ if (value)
+ val |= (1UL << offset);
+ else
+ val &= ~(1UL << offset);
+ outl(val, base);
+
+ return 0;
+}
+
+static int _ich6_gpio_set_function(uint16_t base, unsigned offset, int func)
+{
+ u32 val;
+
+ if (func) {
+ val = inl(base);
+ val |= (1UL << offset);
+ outl(val, base);
+ } else {
+ val = inl(base);
+ val &= ~(1UL << offset);
+ outl(val, base);
+ }
+
+ return 0;
+}
+
+static int _ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir)
+{
+ u32 val;
+
+ if (!dir) {
+ val = inl(base);
+ val |= (1UL << offset);
+ outl(val, base);
+ } else {
+ val = inl(base);
+ val &= ~(1UL << offset);
+ outl(val, base);
+ }
+
+ return 0;
+}
+
+static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node)
+{
+ u32 gpio_offset[2];
+ int pad_offset;
+ int val;
+ int ret;
+ const void *prop;
+
+ /*
+ * GPIO node is not mandatory, so we only do the
+ * pinmuxing if the node exist.
+ */
+ ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset",
+ gpio_offset, 2);
+ if (!ret) {
+ /* Do we want to force the GPIO mode? */
+ prop = fdt_getprop(gd->fdt_blob, pin_node, "mode-gpio",
+ NULL);
+ if (prop)
+ _ich6_gpio_set_function(GPIO_USESEL_OFFSET
+ (gpiobase) +
+ gpio_offset[0],
+ gpio_offset[1], 1);
+
+ val =
+ fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1);
+ if (val != -1)
+ _ich6_gpio_set_direction(GPIO_IOSEL_OFFSET
+ (gpiobase) +
+ gpio_offset[0],
+ gpio_offset[1], val);
+
+ val =
+ fdtdec_get_int(gd->fdt_blob, pin_node, "output-value", -1);
+ if (val != -1)
+ _ich6_gpio_set_value(GPIO_LVL_OFFSET(gpiobase)
+ + gpio_offset[0],
+ gpio_offset[1], val);
+ }
+
+ /* if iobase is present, let's configure the pad */
+ if (iobase != -1) {
+ int iobase_addr;
+
+ /*
+ * The offset for the same pin for the IOBASE and GPIOBASE are
+ * different, so instead of maintaining a lookup table,
+ * the device tree should provide directly the correct
+ * value for both mapping.
+ */
+ pad_offset =
+ fdtdec_get_int(gd->fdt_blob, pin_node, "pad-offset", -1);
+ if (pad_offset == -1) {
+ debug("%s: Invalid register io offset %d\n",
+ __func__, pad_offset);
+ return -EINVAL;
+ }
+
+ /* compute the absolute pad address */
+ iobase_addr = iobase + pad_offset;
+
+ /*
+ * Do we need to set a specific function mode?
+ * If someone put also 'mode-gpio', this option will
+ * be just ignored by the controller
+ */
+ val = fdtdec_get_int(gd->fdt_blob, pin_node, "mode-func", -1);
+ if (val != -1)
+ clrsetbits_le32(iobase_addr, IOPAD_MODE_MASK, val);
+
+ /* Configure the pull-up/down if needed */
+ val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-assign", -1);
+ if (val != -1)
+ clrsetbits_le32(iobase_addr,
+ IOPAD_PULL_ASSIGN_MASK,
+ val << IOPAD_PULL_ASSIGN_SHIFT);
+
+ val =
+ fdtdec_get_int(gd->fdt_blob, pin_node, "pull-strength", -1);
+ if (val != -1)
+ clrsetbits_le32(iobase_addr,
+ IOPAD_PULL_STRENGTH_MASK,
+ val << IOPAD_PULL_STRENGTH_SHIFT);
+
+ debug("%s: pad cfg [0x%x]: %08x\n", __func__, pad_offset,
+ readl(iobase_addr));
+ }
+
+ return 0;
+}
+
+int gpio_ich6_pinctrl_init(void)
+{
+ int pin_node;
+ int node;
+ int ret;
+ int gpiobase;
+ int iobase_offset;
+ int iobase = -1;
+
+ /*
+ * Get the memory/io base address to configure every pins.
+ * IOBASE is used to configure the mode/pads
+ * GPIOBASE is used to configure the direction and default value
+ */
+ gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE);
+ if (gpiobase < 0) {
+ debug("%s: invalid GPIOBASE address (%08x)\n", __func__,
+ gpiobase);
+ return -EINVAL;
+ }
+
+ /* This is not an error to not have a pinctrl node */
+ node =
+ fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_INTEL_X86_PINCTRL);
+ if (node <= 0) {
+ debug("%s: no pinctrl node\n", __func__);
+ return 0;
+ }
+
+ /*
+ * Get the IOBASE, this is not mandatory as this is not
+ * supported by all the CPU
+ */
+ iobase_offset = fdtdec_get_int(gd->fdt_blob, node, "io-base", -1);
+ if (iobase_offset == -1) {
+ debug("%s: io-base offset not present\n", __func__);
+ } else {
+ iobase = gpio_ich6_get_base(iobase_offset);
+ if (iobase < 0) {
+ debug("%s: invalid IOBASE address (%08x)\n", __func__,
+ iobase);
+ return -EINVAL;
+ }
+ }
+
+ for (pin_node = fdt_first_subnode(gd->fdt_blob, node);
+ pin_node > 0;
+ pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) {
+ /* Configure the pin */
+ ret = _gpio_ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node);
+ if (ret != 0) {
+ debug("%s: invalid configuration for the pin %d\n",
+ __func__, pin_node);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ich6_bank_platdata *plat = dev_get_platdata(dev);
+ u16 gpiobase;
+ int offset;
+
+ gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE);
offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
if (offset == -1) {
debug("%s: Invalid register offset %d\n", __func__, offset);
@@ -192,30 +407,24 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset,
static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct ich6_bank_priv *bank = dev_get_priv(dev);
- u32 tmplong;
- tmplong = inl(bank->io_sel);
- tmplong |= (1UL << offset);
- outl(bank->io_sel, tmplong);
- return 0;
+ return _ich6_gpio_set_direction(inl(bank->io_sel), offset, 0);
}
static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
+ int ret;
struct ich6_bank_priv *bank = dev_get_priv(dev);
- u32 tmplong;
- gpio_set_value(offset, value);
+ ret = _ich6_gpio_set_direction(inl(bank->io_sel), offset, 1);
+ if (ret)
+ return ret;
- tmplong = inl(bank->io_sel);
- tmplong &= ~(1UL << offset);
- outl(bank->io_sel, tmplong);
- return 0;
+ return _ich6_gpio_set_value(bank->lvl, offset, value);
}
static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
-
{
struct ich6_bank_priv *bank = dev_get_priv(dev);
u32 tmplong;
@@ -230,15 +439,7 @@ static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct ich6_bank_priv *bank = dev_get_priv(dev);
- u32 tmplong;
-
- tmplong = inl(bank->lvl);
- if (value)
- tmplong |= (1UL << offset);
- else
- tmplong &= ~(1UL << offset);
- outl(bank->lvl, tmplong);
- return 0;
+ return _ich6_gpio_set_value(bank->lvl, offset, value);
}
static int ich6_gpio_get_function(struct udevice *dev, unsigned offset)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5b6c6bc34eb..157491c52da 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -186,72 +186,6 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
return -1;
}
-/*
- *
- */
-
-int __pci_hose_phys_to_bus(struct pci_controller *hose,
- phys_addr_t phys_addr,
- unsigned long flags,
- unsigned long skip_mask,
- pci_addr_t *ba)
-{
- struct pci_region *res;
- pci_addr_t bus_addr;
- int i;
-
- for (i = 0; i < hose->region_count; i++) {
- res = &hose->regions[i];
-
- if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
- continue;
-
- if (res->flags & skip_mask)
- continue;
-
- bus_addr = phys_addr - res->phys_start + res->bus_start;
-
- if (bus_addr >= res->bus_start &&
- bus_addr < res->bus_start + res->size) {
- *ba = bus_addr;
- return 0;
- }
- }
-
- return 1;
-}
-
-pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
- phys_addr_t phys_addr,
- unsigned long flags)
-{
- pci_addr_t bus_addr = 0;
- int ret;
-
- if (!hose) {
- puts("pci_hose_phys_to_bus: invalid hose\n");
- return bus_addr;
- }
-
- /*
- * if PCI_REGION_MEM is set we do a two pass search with preference
- * on matches that don't have PCI_REGION_SYS_MEMORY set
- */
- if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
- ret = __pci_hose_phys_to_bus(hose, phys_addr,
- flags, PCI_REGION_SYS_MEMORY, &bus_addr);
- if (!ret)
- return bus_addr;
- }
-
- ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
-
- if (ret)
- puts("pci_hose_phys_to_bus: invalid physical address\n");
-
- return bus_addr;
-}
-
int pci_hose_config_device(struct pci_controller *hose,
pci_dev_t dev,
unsigned long io,
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index e8da9776731..7c109832f6d 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -14,15 +14,12 @@
#include <errno.h>
#include <pci.h>
-#undef DEBUG
#ifdef DEBUG
#define DEBUGF(x...) printf(x)
#else
#define DEBUGF(x...)
#endif /* DEBUG */
-#define PCIAUTO_IDE_MODE_MASK 0x05
-
/* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */
#ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE
#define CONFIG_SYS_PCI_CACHE_LINE_SIZE 8
@@ -425,7 +422,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
{
unsigned int sub_bus = PCI_BUS(dev);
unsigned short class;
- unsigned char prg_iface;
int n;
pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
@@ -461,17 +457,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
#endif
break;
- case PCI_CLASS_STORAGE_IDE:
- pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prg_iface);
- if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
- DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
- return sub_bus;
- }
-
- pciauto_setup_device(hose, dev, 6, hose->pci_mem,
- hose->pci_prefetch, hose->pci_io);
- break;
-
case PCI_CLASS_BRIDGE_CARDBUS:
/*
* just do a minimal setup of the bridge,
diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c
index 24c66bbef2f..b9ff23f35bc 100644
--- a/drivers/pci/pci_common.c
+++ b/drivers/pci/pci_common.c
@@ -182,10 +182,10 @@ u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
}
int __pci_hose_bus_to_phys(struct pci_controller *hose,
- pci_addr_t bus_addr,
- unsigned long flags,
- unsigned long skip_mask,
- phys_addr_t *pa)
+ pci_addr_t bus_addr,
+ unsigned long flags,
+ unsigned long skip_mask,
+ phys_addr_t *pa)
{
struct pci_region *res;
int i;
@@ -240,6 +240,68 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
return phys_addr;
}
+int __pci_hose_phys_to_bus(struct pci_controller *hose,
+ phys_addr_t phys_addr,
+ unsigned long flags,
+ unsigned long skip_mask,
+ pci_addr_t *ba)
+{
+ struct pci_region *res;
+ pci_addr_t bus_addr;
+ int i;
+
+ for (i = 0; i < hose->region_count; i++) {
+ res = &hose->regions[i];
+
+ if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+ continue;
+
+ if (res->flags & skip_mask)
+ continue;
+
+ bus_addr = phys_addr - res->phys_start + res->bus_start;
+
+ if (bus_addr >= res->bus_start &&
+ bus_addr < res->bus_start + res->size) {
+ *ba = bus_addr;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+pci_addr_t pci_hose_phys_to_bus(struct pci_controller *hose,
+ phys_addr_t phys_addr,
+ unsigned long flags)
+{
+ pci_addr_t bus_addr = 0;
+ int ret;
+
+ if (!hose) {
+ puts("pci_hose_phys_to_bus: invalid hose\n");
+ return bus_addr;
+ }
+
+ /*
+ * if PCI_REGION_MEM is set we do a two pass search with preference
+ * on matches that don't have PCI_REGION_SYS_MEMORY set
+ */
+ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+ ret = __pci_hose_phys_to_bus(hose, phys_addr,
+ flags, PCI_REGION_SYS_MEMORY, &bus_addr);
+ if (!ret)
+ return bus_addr;
+ }
+
+ ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
+
+ if (ret)
+ puts("pci_hose_phys_to_bus: invalid physical address\n");
+
+ return bus_addr;
+}
+
pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
{
struct pci_device_id ids[2] = { {}, {0, 0} };
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 25443016142..9ae23e8dd04 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1,6 +1,5 @@
config VIDEO_VESA
bool "Enable VESA video driver support"
- depends on X86
default n
help
Turn on this option to enable a very simple driver which uses vesa
@@ -8,6 +7,144 @@ config VIDEO_VESA
by U-Boot. This can in principle be used with any platform that
supports PCI and video cards that support VESA BIOS Extension (VBE).
+config FRAMEBUFFER_SET_VESA_MODE
+ bool "Set framebuffer graphics resolution"
+ depends on VIDEO_VESA
+ help
+ Set VESA/native framebuffer mode (needed for bootsplash and graphical
+ framebuffer console)
+
+choice
+ prompt "framebuffer graphics resolution"
+ default FRAMEBUFFER_VESA_MODE_117
+ depends on FRAMEBUFFER_SET_VESA_MODE
+ help
+ This option sets the resolution used for the U-Boot framebuffer (and
+ bootsplash screen).
+
+config FRAMEBUFFER_VESA_MODE_100
+ bool "640x400 256-color"
+
+config FRAMEBUFFER_VESA_MODE_101
+ bool "640x480 256-color"
+
+config FRAMEBUFFER_VESA_MODE_102
+ bool "800x600 16-color"
+
+config FRAMEBUFFER_VESA_MODE_103
+ bool "800x600 256-color"
+
+config FRAMEBUFFER_VESA_MODE_104
+ bool "1024x768 16-color"
+
+config FRAMEBUFFER_VESA_MODE_105
+ bool "1024x7686 256-color"
+
+config FRAMEBUFFER_VESA_MODE_106
+ bool "1280x1024 16-color"
+
+config FRAMEBUFFER_VESA_MODE_107
+ bool "1280x1024 256-color"
+
+config FRAMEBUFFER_VESA_MODE_108
+ bool "80x60 text"
+
+config FRAMEBUFFER_VESA_MODE_109
+ bool "132x25 text"
+
+config FRAMEBUFFER_VESA_MODE_10A
+ bool "132x43 text"
+
+config FRAMEBUFFER_VESA_MODE_10B
+ bool "132x50 text"
+
+config FRAMEBUFFER_VESA_MODE_10C
+ bool "132x60 text"
+
+config FRAMEBUFFER_VESA_MODE_10D
+ bool "320x200 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_10E
+ bool "320x200 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_10F
+ bool "320x200 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_110
+ bool "640x480 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_111
+ bool "640x480 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_112
+ bool "640x480 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_113
+ bool "800x600 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_114
+ bool "800x600 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_115
+ bool "800x600 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_116
+ bool "1024x768 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_117
+ bool "1024x768 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_118
+ bool "1024x768 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_119
+ bool "1280x1024 32k-color (1:5:5:5)"
+
+config FRAMEBUFFER_VESA_MODE_11A
+ bool "1280x1024 64k-color (5:6:5)"
+
+config FRAMEBUFFER_VESA_MODE_11B
+ bool "1280x1024 16.8M-color (8:8:8)"
+
+config FRAMEBUFFER_VESA_MODE_USER
+ bool "Manually select VESA mode"
+
+endchoice
+
+# Map the config names to an integer (KB).
+config FRAMEBUFFER_VESA_MODE
+ prompt "VESA mode" if FRAMEBUFFER_VESA_MODE_USER
+ hex
+ default 0x100 if FRAMEBUFFER_VESA_MODE_100
+ default 0x101 if FRAMEBUFFER_VESA_MODE_101
+ default 0x102 if FRAMEBUFFER_VESA_MODE_102
+ default 0x103 if FRAMEBUFFER_VESA_MODE_103
+ default 0x104 if FRAMEBUFFER_VESA_MODE_104
+ default 0x105 if FRAMEBUFFER_VESA_MODE_105
+ default 0x106 if FRAMEBUFFER_VESA_MODE_106
+ default 0x107 if FRAMEBUFFER_VESA_MODE_107
+ default 0x108 if FRAMEBUFFER_VESA_MODE_108
+ default 0x109 if FRAMEBUFFER_VESA_MODE_109
+ default 0x10A if FRAMEBUFFER_VESA_MODE_10A
+ default 0x10B if FRAMEBUFFER_VESA_MODE_10B
+ default 0x10C if FRAMEBUFFER_VESA_MODE_10C
+ default 0x10D if FRAMEBUFFER_VESA_MODE_10D
+ default 0x10E if FRAMEBUFFER_VESA_MODE_10E
+ default 0x10F if FRAMEBUFFER_VESA_MODE_10F
+ default 0x110 if FRAMEBUFFER_VESA_MODE_110
+ default 0x111 if FRAMEBUFFER_VESA_MODE_111
+ default 0x112 if FRAMEBUFFER_VESA_MODE_112
+ default 0x113 if FRAMEBUFFER_VESA_MODE_113
+ default 0x114 if FRAMEBUFFER_VESA_MODE_114
+ default 0x115 if FRAMEBUFFER_VESA_MODE_115
+ default 0x116 if FRAMEBUFFER_VESA_MODE_116
+ default 0x117 if FRAMEBUFFER_VESA_MODE_117
+ default 0x118 if FRAMEBUFFER_VESA_MODE_118
+ default 0x119 if FRAMEBUFFER_VESA_MODE_119
+ default 0x11A if FRAMEBUFFER_VESA_MODE_11A
+ default 0x11B if FRAMEBUFFER_VESA_MODE_11B
+ default 0x117 if FRAMEBUFFER_VESA_MODE_USER
+
config VIDEO_LCD_SSD2828
bool "SSD2828 bridge chip"
default n
diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h
index 4fef433252c..0e1f0467c78 100644
--- a/include/configs/crownbay.h
+++ b/include/configs/crownbay.h
@@ -17,8 +17,6 @@
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_ARCH_MISC_INIT
-#define CONFIG_NR_DRAM_BANKS 1
-
#define CONFIG_X86_SERIAL
#define CONFIG_SMSC_LPC47M
diff --git a/include/configs/galileo.h b/include/configs/galileo.h
index f780b8fa512..fd89bf30ef3 100644
--- a/include/configs/galileo.h
+++ b/include/configs/galileo.h
@@ -15,8 +15,7 @@
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
#define CONFIG_BOARD_EARLY_INIT_F
-
-#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_ARCH_MISC_INIT
#define CONFIG_X86_SERIAL
diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h
index 2a1915d8722..547765d1376 100644
--- a/include/configs/minnowmax.h
+++ b/include/configs/minnowmax.h
@@ -15,8 +15,7 @@
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
#define CONFIG_BOARD_EARLY_INIT_F
-
-#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_ARCH_EARLY_INIT_R
#define CONFIG_X86_SERIAL
#define CONFIG_SMSC_LPC47M
@@ -56,9 +55,6 @@
#define CONFIG_X86_OPTION_ROM_FILE vga.bin
#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000
-#ifndef CONFIG_SYS_COREBOOT
-#define CONFIG_VIDEO_VESA
-#endif
#define VIDEO_IO_OFFSET 0
#define CONFIG_X86EMU_RAW_IO
#define CONFIG_VGA_AS_SINGLE_DEVICE
diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h
new file mode 100644
index 00000000000..78c296f5ad6
--- /dev/null
+++ b/include/configs/qemu-x86.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/x86-common.h>
+
+#define CONFIG_SYS_MONITOR_LEN (1 << 20)
+#define CONFIG_ARCH_MISC_INIT
+
+#define CONFIG_X86_SERIAL
+
+#define CONFIG_PCI_MEM_BUS 0xc0000000
+#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS
+#define CONFIG_PCI_MEM_SIZE 0x10000000
+
+#define CONFIG_PCI_PREF_BUS 0xd0000000
+#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS
+#define CONFIG_PCI_PREF_SIZE 0x10000000
+
+#define CONFIG_PCI_IO_BUS 0x2000
+#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
+#define CONFIG_PCI_IO_SIZE 0xe000
+
+#define CONFIG_PCI_CONFIG_HOST_BRIDGE
+#define CONFIG_PCI_PNP
+#define CONFIG_E1000
+
+#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga\0" \
+ "stdout=serial,vga\0" \
+ "stderr=serial,vga\0"
+
+/*
+ * ATA/SATA support for QEMU x86 targets
+ * - Only legacy IDE controller is supported for QEMU '-M pc' target
+ * - AHCI controller is supported for QEMU '-M q35' target
+ *
+ * Default configuraion is to support the QEMU default x86 target
+ * Undefine CONFIG_CMD_IDE to support q35 target
+ */
+#define CONFIG_CMD_IDE
+#ifdef CONFIG_CMD_IDE
+#define CONFIG_SYS_IDE_MAXBUS 2
+#define CONFIG_SYS_IDE_MAXDEVICE 4
+#define CONFIG_SYS_ATA_BASE_ADDR 0
+#define CONFIG_SYS_ATA_DATA_OFFSET 0
+#define CONFIG_SYS_ATA_REG_OFFSET 0
+#define CONFIG_SYS_ATA_ALT_OFFSET 0
+#define CONFIG_SYS_ATA_IDE0_OFFSET 0x1f0
+#define CONFIG_SYS_ATA_IDE1_OFFSET 0x170
+#define CONFIG_ATAPI
+
+#undef CONFIG_SCSI_AHCI
+#undef CONFIG_CMD_SCSI
+#else
+#define CONFIG_SCSI_DEV_LIST \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_AHCI}
+#endif
+
+/* GPIO is not supported */
+#undef CONFIG_INTEL_ICH6_GPIO
+#undef CONFIG_CMD_GPIO
+
+/* SPI is not supported */
+#undef CONFIG_ICH_SPI
+#undef CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_IS_NOWHERE
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h
index b6a76fe0755..e0e7fca9f86 100644
--- a/include/configs/x86-chromebook.h
+++ b/include/configs/x86-chromebook.h
@@ -14,7 +14,6 @@
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_MISC_INIT_R
-#define CONFIG_NR_DRAM_BANKS 8
#define CONFIG_X86_MRC_ADDR 0xfffa0000
#define CONFIG_CACHE_MRC_SIZE_KB 512
diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h
index bf4758e3b38..1917d87ac58 100644
--- a/include/configs/x86-common.h
+++ b/include/configs/x86-common.h
@@ -21,6 +21,7 @@
#define CONFIG_DISPLAY_BOARDINFO_LATE
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_LAST_STAGE_INIT
+#define CONFIG_NR_DRAM_BANKS 8
#define CONFIG_LMB
#define CONFIG_OF_LIBFDT
@@ -36,6 +37,7 @@
#define CONFIG_SCSI_AHCI
#ifdef CONFIG_SCSI_AHCI
#define CONFIG_LIBATA
+#define CONFIG_LBA48
#define CONFIG_SYS_64BIT_LBA
#define CONFIG_SYS_SCSI_MAX_SCSI_ID 2
@@ -75,10 +77,6 @@
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_SUPPORT_VFAT
-/************************************************************
- * ATAPI support (experimental)
- ************************************************************/
-#define CONFIG_ATAPI
/************************************************************
* DISK Partition support
@@ -246,6 +244,7 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
CONFIG_STD_DEVICES_SETTINGS \
+ "pciconfighost=1\0" \
"netdev=eth0\0" \
"consoledev=ttyS0\0" \
"othbootargs=acpi=off\0" \
diff --git a/include/dt-bindings/gpio/x86-gpio.h b/include/dt-bindings/gpio/x86-gpio.h
new file mode 100644
index 00000000000..7f1de30c0bf
--- /dev/null
+++ b/include/dt-bindings/gpio/x86-gpio.h
@@ -0,0 +1,31 @@
+/*
+ * This header provides constants for binding intel,x86-pinctrl.
+ */
+
+#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H
+#define _DT_BINDINGS_GPIO_X86_GPIO_H
+
+#include <dt-bindings/gpio/gpio.h>
+
+#define GPIO_MODE_NATIVE 0
+#define GPIO_MODE_GPIO 1
+
+#define GPIO_MODE_FUNC0 0
+#define GPIO_MODE_FUNC1 1
+#define GPIO_MODE_FUNC2 2
+#define GPIO_MODE_FUNC3 3
+#define GPIO_MODE_FUNC4 4
+#define GPIO_MODE_FUNC5 5
+#define GPIO_MODE_FUNC6 6
+
+#define PIN_INPUT 0
+#define PIN_OUTPUT 1
+
+#define PIN_INPUT_NOPULL 0
+#define PIN_INPUT_PULLUP 1
+#define PIN_INPUT_PULLDOWN 2
+
+#define PULL_STR_2K 0
+#define PULL_STR_20K 2
+
+#endif
diff --git a/include/dt-bindings/interrupt-router/intel-irq.h b/include/dt-bindings/interrupt-router/intel-irq.h
new file mode 100644
index 00000000000..5092f33dfa0
--- /dev/null
+++ b/include/dt-bindings/interrupt-router/intel-irq.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_INTEL_IRQ_H_
+#define _DT_BINDINGS_INTEL_IRQ_H_
+
+/* PCI interrupt pin */
+#define INTA 1
+#define INTB 2
+#define INTC 3
+#define INTD 4
+
+/* PIRQs */
+#define PIRQA 0
+#define PIRQB 1
+#define PIRQC 2
+#define PIRQD 3
+#define PIRQE 4
+#define PIRQF 5
+#define PIRQG 6
+#define PIRQH 7
+
+/* PCI bdf encoding */
+#ifndef PCI_BDF
+#define PCI_BDF(b, d, f) ((b) << 16 | (d) << 11 | (f) << 8)
+#endif
+
+#endif /* _DT_BINDINGS_INTEL_IRQ_H_ */
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 6bf5f614e8b..4fb8a2a1ba5 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -176,8 +176,10 @@ enum fdt_compat_id {
COMPAT_AMS_AS3722, /* AMS AS3722 PMIC */
COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */
COMPAT_INTEL_QRK_MRC, /* Intel Quark MRC */
+ COMPAT_INTEL_X86_PINCTRL, /* Intel ICH7/9 pin control */
COMPAT_SOCIONEXT_XHCI, /* Socionext UniPhier xHCI */
COMPAT_INTEL_PCH, /* Intel PCH */
+ COMPAT_INTEL_IRQ_ROUTER, /* Intel Interrupt Router */
COMPAT_COUNT,
};
diff --git a/include/pci_ids.h b/include/pci_ids.h
index 2e6685112b6..5771e12e729 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -2838,6 +2838,7 @@
#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
+#define PCI_DEVICE_ID_INTEL_ICH9_AHCI 0x2922
#define PCI_DEVICE_ID_INTEL_I7_MCR 0x2c18
#define PCI_DEVICE_ID_INTEL_I7_MC_TAD 0x2c19
#define PCI_DEVICE_ID_INTEL_I7_MC_RAS 0x2c1a
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index b586da2a563..46dfcb675cc 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -75,8 +75,10 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(AMS_AS3722, "ams,as3722"),
COMPAT(INTEL_ICH_SPI, "intel,ich-spi"),
COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
+ COMPAT(INTEL_X86_PINCTRL, "intel,x86-pinctrl"),
COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"),
COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
+ COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
diff --git a/tools/ifdtool.c b/tools/ifdtool.c
index 590ccc914b0..1d61df19f23 100644
--- a/tools/ifdtool.c
+++ b/tools/ifdtool.c
@@ -462,7 +462,7 @@ static int write_regions(char *image, int size)
if (ret)
return ret;
dump_region(i, frba);
- if (region.size == 0)
+ if (region.size <= 0)
continue;
region_fd = open(region_filename(i),
O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |