The PCH (Peripheral 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 <s...@chromium.org>
---

 arch/x86/cpu/ivybridge/Makefile             |  1 +
 arch/x86/cpu/ivybridge/cpu.c                | 12 ++++++++
 arch/x86/cpu/ivybridge/lpc.c                | 48 +++++++++++++++++++++++++++++
 arch/x86/dts/link.dts                       |  3 +-
 arch/x86/include/asm/arch-ivybridge/pch.h   | 48 +++++++++++++++++++++++++++++
 doc/device-tree-bindings/misc/intel-lpc.txt | 23 ++++++++++++++
 6 files changed, 134 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/cpu/ivybridge/lpc.c
 create mode 100644 arch/x86/include/asm/arch-ivybridge/pch.h
 create mode 100644 doc/device-tree-bindings/misc/intel-lpc.txt

diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
index dbcd4bd..ce16697 100644
--- a/arch/x86/cpu/ivybridge/Makefile
+++ b/arch/x86/cpu/ivybridge/Makefile
@@ -6,4 +6,5 @@
 
 obj-y += car.o
 obj-y += cpu.o
+obj-y += lpc.o
 obj-y += sdram.o
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index 06f4d68..04708fb 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -11,14 +11,19 @@
  */
 
 #include <common.h>
+#include <errno.h>
+#include <fdtdec.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);
@@ -32,6 +37,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;
+}
diff --git a/arch/x86/dts/link.dts b/arch/x86/dts/link.dts
index f2fcb39..2e91631 100644
--- a/arch/x86/dts/link.dts
+++ b/arch/x86/dts/link.dts
@@ -53,9 +53,10 @@
                compatible = "intel,lpc";
                #address-cells = <1>;
                #size-cells = <1>;
+               reg = <0x204 1 0x200 1 0x880 0x80>;
+               gen-dec = <0x800 0xfc 0x900 0xfc>;
                cros-ec@200 {
                        compatible = "google,cros-ec";
-                       reg = <0x204 1 0x200 1 0x880 0x80>;
 
                        /* This describes the flash memory within the EC */
                        #address-cells = <1>;
diff --git a/arch/x86/include/asm/arch-ivybridge/pch.h 
b/arch/x86/include/asm/arch-ivybridge/pch.h
new file mode 100644
index 0000000..26ddeab
--- /dev/null
+++ b/arch/x86/include/asm/arch-ivybridge/pch.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * From Coreboot src/southbridge/intel/bd82x6x/pch.h
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2012 The Chromium OS Authors.  All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_PCH_H
+#define _ASM_ARCH_PCH_H
+
+#include <pci.h>
+
+/* PCI Configuration Space (D31:F0): LPC */
+#define PCH_LPC_DEV            PCI_BDF(0, 0x1f, 0)
+
+#define LPC_IO_DEC             0x80 /* IO Decode Ranges Register */
+#define LPC_EN                 0x82 /* LPC IF Enables Register */
+#define  CNF2_LPC_EN           (1 << 13) /* 0x4e/0x4f */
+#define  CNF1_LPC_EN           (1 << 12) /* 0x2e/0x2f */
+#define  MC_LPC_EN             (1 << 11) /* 0x62/0x66 */
+#define  KBC_LPC_EN            (1 << 10) /* 0x60/0x64 */
+#define  GAMEH_LPC_EN          (1 << 9)  /* 0x208/0x20f */
+#define  GAMEL_LPC_EN          (1 << 8)  /* 0x200/0x207 */
+#define  FDD_LPC_EN            (1 << 3)  /* LPC_IO_DEC[12] */
+#define  LPT_LPC_EN            (1 << 2)  /* LPC_IO_DEC[9:8] */
+#define  COMB_LPC_EN           (1 << 1)  /* LPC_IO_DEC[6:4] */
+#define  COMA_LPC_EN           (1 << 0)  /* LPC_IO_DEC[3:2] */
+#define LPC_GEN1_DEC           0x84 /* LPC IF Generic Decode Range 1 */
+#define LPC_GEN2_DEC           0x88 /* LPC IF Generic Decode Range 2 */
+#define LPC_GEN3_DEC           0x8c /* LPC IF Generic Decode Range 3 */
+#define LPC_GEN4_DEC           0x90 /* LPC IF Generic Decode Range 4 */
+#define LPC_GENX_DEC(x)                (0x84 + 4 * (x))
+
+/**
+ * lpc_early_init() - set up LPC serial ports and other early things
+ *
+ * @blob:      Device tree blob
+ * @node:      Offset of LPC node
+ * @dev:       PCH PCI device containing the LPC
+ * @return 0 if OK, -ve on error
+ */
+int lpc_early_init(const void *blob, int node, pci_dev_t dev);
+
+#endif
diff --git a/doc/device-tree-bindings/misc/intel-lpc.txt 
b/doc/device-tree-bindings/misc/intel-lpc.txt
new file mode 100644
index 0000000..7e1b389
--- /dev/null
+++ b/doc/device-tree-bindings/misc/intel-lpc.txt
@@ -0,0 +1,23 @@
+Intel LPC Device Binding
+========================
+
+The device tree node which describes the operation of the Intel Low Pin
+Count device is as follows:
+
+Required properties :
+- compatible = "intel,lpc"
+- gen-dec : Specifies the values for the gen-dec registers. Up to four cell
+   pairs can be provided - the first of each pair is the base address and
+   the second is the size. These are written into the GENx_DEC registers of
+   the LPC device
+
+
+Example
+-------
+
+lpc {
+       compatible = "intel,lpc";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       gen-dec = <0x800 0xfc 0x900 0xfc>;
+};
-- 
2.1.0.rc2.206.gedb03e5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to