summaryrefslogtreecommitdiff
path: root/arch/x86/cpu/ivybridge
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2014-11-12 22:42:15 -0700
committerSimon Glass <sjg@chromium.org>2014-11-21 07:34:12 +0100
commit2b6051541b562b72d2cf784376a84552da18318d (patch)
treec21b6ae92539eb63628f15b52044dd164471aed7 /arch/x86/cpu/ivybridge
parent6fb3b72e8745073465b4a5875b7750cc43cbd1af (diff)
downloadu-boot-imx-2b6051541b562b72d2cf784376a84552da18318d.zip
u-boot-imx-2b6051541b562b72d2cf784376a84552da18318d.tar.gz
u-boot-imx-2b6051541b562b72d2cf784376a84552da18318d.tar.bz2
x86: ivybridge: Add early LPC init so that serial works
The PCH (Platform Controller Hub) includes an LPC (Low Pin Count) device which provides a serial port. This is accessible on Chromebooks, so enable it early in the boot process. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch/x86/cpu/ivybridge')
-rw-r--r--arch/x86/cpu/ivybridge/Makefile1
-rw-r--r--arch/x86/cpu/ivybridge/cpu.c12
-rw-r--r--arch/x86/cpu/ivybridge/lpc.c48
3 files changed, 61 insertions, 0 deletions
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
index 6d0a78d..4b77c9c 100644
--- a/arch/x86/cpu/ivybridge/Makefile
+++ b/arch/x86/cpu/ivybridge/Makefile
@@ -6,5 +6,6 @@
obj-y += car.o
obj-y += cpu.o
+obj-y += lpc.o
obj-y += pci.o
obj-y += sdram.o
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index ff6b7b3..5d7640b 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -11,16 +11,21 @@
*/
#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
#include <asm/cpu.h>
#include <asm/pci.h>
#include <asm/post.h>
#include <asm/processor.h>
+#include <asm/arch/pch.h>
DECLARE_GLOBAL_DATA_PTR;
int arch_cpu_init(void)
{
+ const void *blob = gd->fdt_blob;
struct pci_controller *hose;
+ int node;
int ret;
post_code(POST_CPU_INIT);
@@ -34,6 +39,13 @@ int arch_cpu_init(void)
if (ret)
return ret;
+ node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC);
+ if (node < 0)
+ return -ENOENT;
+ ret = lpc_early_init(gd->fdt_blob, node, PCH_LPC_DEV);
+ if (ret)
+ return ret;
+
return 0;
}
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
new file mode 100644
index 0000000..621ef2c
--- /dev/null
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -0,0 +1,48 @@
+/*
+ * From coreboot southbridge/intel/bd82x6x/lpc.c
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <pci.h>
+#include <asm/pci.h>
+#include <asm/arch/pch.h>
+
+int lpc_early_init(const void *blob, int node, pci_dev_t dev)
+{
+ struct reg_info {
+ u32 base;
+ u32 size;
+ } values[4], *ptr;
+ int count;
+ int i;
+
+ count = fdtdec_get_int_array_count(blob, node, "gen-dec",
+ (u32 *)values, sizeof(values) / sizeof(u32));
+ if (count < 0)
+ return -EINVAL;
+
+ /* Set COM1/COM2 decode range */
+ pci_write_config16(dev, LPC_IO_DEC, 0x0010);
+
+ /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */
+ pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
+ GAMEL_LPC_EN | COMA_LPC_EN);
+
+ /* Write all registers but use 0 if we run out of data */
+ count = count * sizeof(u32) / sizeof(values[0]);
+ for (i = 0, ptr = values; i < ARRAY_SIZE(values); i++, ptr++) {
+ u32 reg = 0;
+
+ if (i < count)
+ reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16);
+ pci_write_config32(dev, LPC_GENX_DEC(i), reg);
+ }
+
+ return 0;
+}