aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/cpu')
-rw-r--r--arch/x86/cpu/Makefile3
-rw-r--r--arch/x86/cpu/baytrail/Kconfig1
-rw-r--r--arch/x86/cpu/baytrail/cpu.c2
-rw-r--r--arch/x86/cpu/intel_common/mrc.c5
-rw-r--r--arch/x86/cpu/irq.c127
-rw-r--r--arch/x86/cpu/ivybridge/Kconfig2
-rw-r--r--arch/x86/cpu/ivybridge/Makefile2
-rw-r--r--arch/x86/cpu/ivybridge/model_206ax.c15
-rw-r--r--arch/x86/cpu/quark/Makefile2
-rw-r--r--arch/x86/cpu/quark/irq.c48
-rw-r--r--arch/x86/cpu/quark/quark.c26
-rw-r--r--arch/x86/cpu/queensbay/Makefile2
-rw-r--r--arch/x86/cpu/queensbay/irq.c64
-rw-r--r--arch/x86/cpu/queensbay/tnc.c39
14 files changed, 182 insertions, 156 deletions
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index d5a17d0..af9e26c 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -18,7 +18,8 @@ obj-y += cpu.o cpu_x86.o
ifndef CONFIG_$(SPL_)X86_64
AFLAGS_REMOVE_call32.o := -mregparm=3 \
$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
-AFLAGS_call32.o := -fpic -fshort-wchar
+AFLAGS_call32.o := -fpic -fshort-wchar \
+ $(if $(CONFIG_EFI_STUB_64BIT),-m64)
extra-y += call32.o
endif
diff --git a/arch/x86/cpu/baytrail/Kconfig b/arch/x86/cpu/baytrail/Kconfig
index ac58b03..022a9f2 100644
--- a/arch/x86/cpu/baytrail/Kconfig
+++ b/arch/x86/cpu/baytrail/Kconfig
@@ -12,6 +12,7 @@ config INTEL_BAYTRAIL
imply AHCI_PCI
imply ICH_SPI
imply INTEL_ICH6_GPIO
+ imply PINCTRL_ICH6
imply MMC
imply MMC_PCI
imply MMC_SDHCI
diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
index 29baf08..56e9813 100644
--- a/arch/x86/cpu/baytrail/cpu.c
+++ b/arch/x86/cpu/baytrail/cpu.c
@@ -80,7 +80,7 @@ static void set_max_freq(void)
perf_ctl.lo = (msr.lo & 0x3f0000) >> 8;
/*
- * Set guaranteed vid [21:16] from IACORE_VIDS to bits [7:0] of
+ * Set guaranteed vid [22:16] from IACORE_VIDS to bits [7:0] of
* the PERF_CTL
*/
msr = msr_read(MSR_IACORE_VIDS);
diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c
index a5697a6..b35102a 100644
--- a/arch/x86/cpu/intel_common/mrc.c
+++ b/arch/x86/cpu/intel_common/mrc.c
@@ -242,11 +242,6 @@ static int sdram_initialise(struct udevice *dev, struct udevice *me_dev,
version >> 24 , (version >> 16) & 0xff,
(version >> 8) & 0xff, version & 0xff);
-#if CONFIG_USBDEBUG
- /* mrc.bin reconfigures USB, so reinit it to have debug */
- early_usbdebug_init();
-#endif
-
return 0;
}
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c
index 305cd3d..3adc155 100644
--- a/arch/x86/cpu/irq.c
+++ b/arch/x86/cpu/irq.c
@@ -16,16 +16,75 @@
DECLARE_GLOBAL_DATA_PTR;
+/**
+ * pirq_reg_to_linkno() - Convert a PIRQ routing register offset to link number
+ *
+ * @priv: IRQ router driver's priv data
+ * @reg: PIRQ routing register offset from the base address
+ * @return: PIRQ link number (0 for PIRQA, 1 for PIRQB, etc)
+ */
+static inline int pirq_reg_to_linkno(struct irq_router *priv, int reg)
+{
+ int linkno = 0;
+
+ if (priv->has_regmap) {
+ struct pirq_regmap *map = priv->regmap;
+ int i;
+
+ for (i = 0; i < priv->link_num; i++) {
+ if (reg - priv->link_base == map->offset) {
+ linkno = map->link;
+ break;
+ }
+ map++;
+ }
+ } else {
+ linkno = reg - priv->link_base;
+ }
+
+ return linkno;
+}
+
+/**
+ * pirq_linkno_to_reg() - Convert a PIRQ link number to routing register offset
+ *
+ * @priv: IRQ router driver's priv data
+ * @linkno: PIRQ link number (0 for PIRQA, 1 for PIRQB, etc)
+ * @return: PIRQ routing register offset from the base address
+ */
+static inline int pirq_linkno_to_reg(struct irq_router *priv, int linkno)
+{
+ int reg = 0;
+
+ if (priv->has_regmap) {
+ struct pirq_regmap *map = priv->regmap;
+ int i;
+
+ for (i = 0; i < priv->link_num; i++) {
+ if (linkno == map->link) {
+ reg = map->offset + priv->link_base;
+ break;
+ }
+ map++;
+ }
+ } else {
+ reg = linkno + priv->link_base;
+ }
+
+ return reg;
+}
+
bool pirq_check_irq_routed(struct udevice *dev, int link, u8 irq)
{
struct irq_router *priv = dev_get_priv(dev);
u8 pirq;
- int base = priv->link_base;
if (priv->config == PIRQ_VIA_PCI)
- dm_pci_read_config8(dev->parent, LINK_N2V(link, base), &pirq);
+ dm_pci_read_config8(dev->parent,
+ pirq_linkno_to_reg(priv, link), &pirq);
else
- pirq = readb((uintptr_t)priv->ibase + LINK_N2V(link, base));
+ pirq = readb((uintptr_t)priv->ibase +
+ pirq_linkno_to_reg(priv, link));
pirq &= 0xf;
@@ -40,22 +99,23 @@ int pirq_translate_link(struct udevice *dev, int link)
{
struct irq_router *priv = dev_get_priv(dev);
- return LINK_V2N(link, priv->link_base);
+ return pirq_reg_to_linkno(priv, link);
}
void pirq_assign_irq(struct udevice *dev, int link, u8 irq)
{
struct irq_router *priv = dev_get_priv(dev);
- int base = priv->link_base;
/* IRQ# 0/1/2/8/13 are reserved */
if (irq < 3 || irq == 8 || irq == 13)
return;
if (priv->config == PIRQ_VIA_PCI)
- dm_pci_write_config8(dev->parent, LINK_N2V(link, base), irq);
+ dm_pci_write_config8(dev->parent,
+ pirq_linkno_to_reg(priv, link), irq);
else
- writeb(irq, (uintptr_t)priv->ibase + LINK_N2V(link, base));
+ writeb(irq, (uintptr_t)priv->ibase +
+ pirq_linkno_to_reg(priv, link));
}
static struct irq_info *check_dup_entry(struct irq_info *slot_base,
@@ -78,7 +138,7 @@ static inline void fill_irq_info(struct irq_router *priv, struct irq_info *slot,
{
slot->bus = bus;
slot->devfn = (device << 3) | 0;
- slot->irq[pin - 1].link = LINK_N2V(pirq, priv->link_base);
+ slot->irq[pin - 1].link = pirq_linkno_to_reg(priv, pirq);
slot->irq[pin - 1].bitmap = priv->irq_mask;
}
@@ -89,6 +149,7 @@ static int create_pirq_routing_table(struct udevice *dev)
int node;
int len, count;
const u32 *cell;
+ struct pirq_regmap *map;
struct irq_routing_table *rt;
struct irq_info *slot, *slot_base;
int irq_entries = 0;
@@ -112,10 +173,43 @@ static int create_pirq_routing_table(struct udevice *dev)
return -EINVAL;
}
- ret = fdtdec_get_int(blob, node, "intel,pirq-link", -1);
- if (ret == -1)
- return ret;
- priv->link_base = ret;
+ cell = fdt_getprop(blob, node, "intel,pirq-link", &len);
+ if (!cell || len != 8)
+ return -EINVAL;
+ priv->link_base = fdt_addr_to_cpu(cell[0]);
+ priv->link_num = fdt_addr_to_cpu(cell[1]);
+ if (priv->link_num > CONFIG_MAX_PIRQ_LINKS) {
+ debug("Limiting supported PIRQ link number from %d to %d\n",
+ priv->link_num, CONFIG_MAX_PIRQ_LINKS);
+ priv->link_num = CONFIG_MAX_PIRQ_LINKS;
+ }
+
+ cell = fdt_getprop(blob, node, "intel,pirq-regmap", &len);
+ if (cell) {
+ if (len % sizeof(struct pirq_regmap))
+ return -EINVAL;
+
+ count = len / sizeof(struct pirq_regmap);
+ if (count < priv->link_num) {
+ printf("Number of pirq-regmap entires is wrong\n");
+ return -EINVAL;
+ }
+
+ count = priv->link_num;
+ priv->regmap = calloc(count, sizeof(struct pirq_regmap));
+ if (!priv->regmap)
+ return -ENOMEM;
+
+ priv->has_regmap = true;
+ map = priv->regmap;
+ for (i = 0; i < count; i++) {
+ map->link = fdt_addr_to_cpu(cell[0]);
+ map->offset = fdt_addr_to_cpu(cell[1]);
+
+ cell += sizeof(struct pirq_regmap) / sizeof(u32);
+ map++;
+ }
+ }
priv->irq_mask = fdtdec_get_int(blob, node,
"intel,pirq-mask", PIRQ_BITMAP);
@@ -199,7 +293,7 @@ static int create_pirq_routing_table(struct udevice *dev)
* routing information in the device tree.
*/
if (slot->irq[pr.pin - 1].link !=
- LINK_N2V(pr.pirq, priv->link_base))
+ pirq_linkno_to_reg(priv, pr.pirq))
debug("WARNING: Inconsistent PIRQ routing information\n");
continue;
}
@@ -237,7 +331,7 @@ static void irq_enable_sci(struct udevice *dev)
}
}
-int irq_router_common_init(struct udevice *dev)
+int irq_router_probe(struct udevice *dev)
{
int ret;
@@ -256,11 +350,6 @@ int irq_router_common_init(struct udevice *dev)
return 0;
}
-int irq_router_probe(struct udevice *dev)
-{
- return irq_router_common_init(dev);
-}
-
ulong write_pirq_routing_table(ulong addr)
{
if (!gd->arch.pirq_routing_table)
diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig
index 82d5489..5f0e608 100644
--- a/arch/x86/cpu/ivybridge/Kconfig
+++ b/arch/x86/cpu/ivybridge/Kconfig
@@ -13,11 +13,13 @@ config NORTHBRIDGE_INTEL_IVYBRIDGE
imply AHCI_PCI
imply ICH_SPI
imply INTEL_ICH6_GPIO
+ imply PINCTRL_ICH6
imply SCSI
imply SCSI_AHCI
imply SPI_FLASH
imply USB
imply USB_EHCI_HCD
+ imply USB_XHCI_HCD
imply VIDEO_VESA
if NORTHBRIDGE_INTEL_IVYBRIDGE
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
index 27cfb26..716134e 100644
--- a/arch/x86/cpu/ivybridge/Makefile
+++ b/arch/x86/cpu/ivybridge/Makefile
@@ -8,7 +8,6 @@ else
obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += cpu.o
obj-y += early_me.o
obj-y += lpc.o
-obj-y += model_206ax.o
obj-y += northbridge.o
ifndef CONFIG_SPL_BUILD
obj-y += sata.o
@@ -18,4 +17,5 @@ ifndef CONFIG_$(SPL_)X86_32BIT_INIT
obj-y += sdram_nop.o
endif
endif
+obj-y += model_206ax.o
obj-y += bd82x6x.o
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
index c5441aa..33e5c62 100644
--- a/arch/x86/cpu/ivybridge/model_206ax.c
+++ b/arch/x86/cpu/ivybridge/model_206ax.c
@@ -393,10 +393,6 @@ static void configure_mca(void)
msr_write(IA32_MC0_STATUS + (i * 4), msr);
}
-#if CONFIG_USBDEBUG
-static unsigned ehci_debug_addr;
-#endif
-
static int model_206ax_init(struct udevice *dev)
{
int ret;
@@ -404,17 +400,6 @@ static int model_206ax_init(struct udevice *dev)
/* Clear out pending MCEs */
configure_mca();
-#if CONFIG_USBDEBUG
- /* Is this caution really needed? */
- if (!ehci_debug_addr)
- ehci_debug_addr = get_ehci_debug();
- set_ehci_debug(0);
-#endif
-
-#if CONFIG_USBDEBUG
- set_ehci_debug(ehci_debug_addr);
-#endif
-
/* Enable the local cpu apics */
enable_lapic_tpr();
diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile
index 476e37c..7039f8b 100644
--- a/arch/x86/cpu/quark/Makefile
+++ b/arch/x86/cpu/quark/Makefile
@@ -2,6 +2,6 @@
#
# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
-obj-y += car.o dram.o irq.o msg_port.o quark.o
+obj-y += car.o dram.o msg_port.o quark.o
obj-y += mrc.o mrc_util.o hte.o smc.o
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o
diff --git a/arch/x86/cpu/quark/irq.c b/arch/x86/cpu/quark/irq.c
deleted file mode 100644
index 6928c33..0000000
--- a/arch/x86/cpu/quark/irq.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
- * Copyright (C) 2015 Google, Inc
- */
-
-#include <common.h>
-#include <dm.h>
-#include <asm/irq.h>
-#include <asm/arch/device.h>
-#include <asm/arch/quark.h>
-
-int quark_irq_router_probe(struct udevice *dev)
-{
- struct quark_rcba *rcba;
- u32 base;
-
- qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, &base);
- 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);
-
- return irq_router_common_init(dev);
-}
-
-static const struct udevice_id quark_irq_router_ids[] = {
- { .compatible = "intel,quark-irq-router" },
- { }
-};
-
-U_BOOT_DRIVER(quark_irq_router_drv) = {
- .name = "quark_intel_irq",
- .id = UCLASS_IRQ,
- .of_match = quark_irq_router_ids,
- .probe = quark_irq_router_probe,
-};
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index 46141c4..4fd6864 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -7,6 +7,7 @@
#include <mmc.h>
#include <asm/io.h>
#include <asm/ioapic.h>
+#include <asm/irq.h>
#include <asm/mrccache.h>
#include <asm/mtrr.h>
#include <asm/pci.h>
@@ -313,12 +314,37 @@ static void quark_usb_init(void)
writel((0xf << 16) | 0xf, bar + USBD_EP_INT_STS);
}
+static void quark_irq_init(void)
+{
+ struct quark_rcba *rcba;
+ u32 base;
+
+ qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, &base);
+ 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_early_init_r(void)
{
quark_pcie_init();
quark_usb_init();
+ quark_irq_init();
+
return 0;
}
diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile
index b535b2a..ac29613 100644
--- a/arch/x86/cpu/queensbay/Makefile
+++ b/arch/x86/cpu/queensbay/Makefile
@@ -2,5 +2,5 @@
#
# Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
-obj-y += fsp_configs.o irq.o
+obj-y += fsp_configs.o
obj-y += tnc.o
diff --git a/arch/x86/cpu/queensbay/irq.c b/arch/x86/cpu/queensbay/irq.c
deleted file mode 100644
index 208cd61..0000000
--- a/arch/x86/cpu/queensbay/irq.c
+++ /dev/null
@@ -1,64 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
- * Copyright (C) 2015 Google, Inc
- */
-
-#include <common.h>
-#include <dm.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/arch/device.h>
-#include <asm/arch/tnc.h>
-
-int queensbay_irq_router_probe(struct udevice *dev)
-{
- struct tnc_rcba *rcba;
- u32 base;
-
- dm_pci_read_config32(dev->parent, LPC_RCBA, &base);
- 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 have to route PCIe
- * root ports' INTx to PIRQ A/B/C/D as well. For other devices
- * on TunneCreek, route them to PIRQ E/F/G/H.
- */
- writew(PIRQE, &rcba->d02ir);
- writew(PIRQF, &rcba->d03ir);
- writew(PIRQG, &rcba->d27ir);
- writew(PIRQH, &rcba->d31ir);
- writew(PIRQA, &rcba->d23ir);
- writew(PIRQB, &rcba->d24ir);
- writew(PIRQC, &rcba->d25ir);
- writew(PIRQD, &rcba->d26ir);
-
- return irq_router_common_init(dev);
-}
-
-static const struct udevice_id queensbay_irq_router_ids[] = {
- { .compatible = "intel,queensbay-irq-router" },
- { }
-};
-
-U_BOOT_DRIVER(queensbay_irq_router_drv) = {
- .name = "queensbay_intel_irq",
- .id = UCLASS_IRQ,
- .of_match = queensbay_irq_router_ids,
- .probe = queensbay_irq_router_probe,
-};
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c
index 439c14d..76556fc 100644
--- a/arch/x86/cpu/queensbay/tnc.c
+++ b/arch/x86/cpu/queensbay/tnc.c
@@ -98,6 +98,43 @@ int arch_cpu_init(void)
return x86_cpu_init_f();
}
+static void tnc_irq_init(void)
+{
+ struct tnc_rcba *rcba;
+ u32 base;
+
+ pci_read_config32(TNC_LPC, LPC_RCBA, &base);
+ 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 have to route PCIe
+ * root ports' INTx to PIRQ A/B/C/D as well. For other devices
+ * on TunneCreek, route them to PIRQ E/F/G/H.
+ */
+ writew(PIRQE, &rcba->d02ir);
+ writew(PIRQF, &rcba->d03ir);
+ writew(PIRQG, &rcba->d27ir);
+ writew(PIRQH, &rcba->d31ir);
+ writew(PIRQA, &rcba->d23ir);
+ writew(PIRQB, &rcba->d24ir);
+ writew(PIRQC, &rcba->d25ir);
+ writew(PIRQD, &rcba->d26ir);
+}
+
int arch_early_init_r(void)
{
int ret = 0;
@@ -106,5 +143,7 @@ int arch_early_init_r(void)
ret = disable_igd();
#endif
+ tnc_irq_init();
+
return ret;
}