1
0
Fork 0

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>
utp
Simon Glass 2014-11-12 22:42:15 -07:00
parent 6fb3b72e87
commit 2b6051541b
6 changed files with 133 additions and 0 deletions

View File

@ -6,5 +6,6 @@
obj-y += car.o
obj-y += cpu.o
obj-y += lpc.o
obj-y += pci.o
obj-y += sdram.o

View File

@ -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;
}

View File

@ -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;
}

View File

@ -53,6 +53,7 @@
compatible = "intel,lpc";
#address-cells = <1>;
#size-cells = <1>;
gen-dec = <0x800 0xfc 0x900 0xfc>;
cros-ec@200 {
compatible = "google,cros-ec";
reg = <0x204 1 0x200 1 0x880 0x80>;

View File

@ -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

View File

@ -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>;
};