[U-Boot] [PATCH 20/69] x86: Move common LPC code to its own place
Bin Meng
bmeng.cn at gmail.com
Fri Mar 11 06:05:45 CET 2016
Hi Simon,
On Mon, Mar 7, 2016 at 10:28 AM, Simon Glass <sjg at chromium.org> wrote:
> Some of the LPC code is common to several Intel LPC devices. Move it into a
> common location.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> arch/x86/cpu/intel_common/Makefile | 1 +
> arch/x86/cpu/intel_common/lpc_common.c | 102 ++++++++++++++++++++++++++++++
> arch/x86/cpu/ivybridge/bd82x6x.c | 16 +----
> arch/x86/cpu/ivybridge/lpc.c | 73 ++-------------------
> arch/x86/include/asm/arch-ivybridge/pch.h | 2 -
> arch/x86/include/asm/lpc_common.h | 59 +++++++++++++++++
> 6 files changed, 168 insertions(+), 85 deletions(-)
> create mode 100644 arch/x86/cpu/intel_common/lpc_common.c
> create mode 100644 arch/x86/include/asm/lpc_common.h
>
> diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile
> index bc7c3ff..36c150d 100644
> --- a/arch/x86/cpu/intel_common/Makefile
> +++ b/arch/x86/cpu/intel_common/Makefile
> @@ -5,6 +5,7 @@
> #
>
> obj-$(CONFIG_HAVE_MRC) += car.o
> +obj-y += lpc_common.o
> ifndef CONFIG_TARGET_EFI
> obj-y += microcode_intel.o
> endif
> diff --git a/arch/x86/cpu/intel_common/lpc_common.c b/arch/x86/cpu/intel_common/lpc_common.c
> new file mode 100644
> index 0000000..2a3b941
> --- /dev/null
> +++ b/arch/x86/cpu/intel_common/lpc_common.c
> @@ -0,0 +1,102 @@
> +/*
> + * Copyright (c) 2016 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <fdtdec.h>
> +#include <pch.h>
> +#include <pci.h>
> +#include <asm/intel_regs.h>
> +#include <asm/io.h>
> +#include <asm/lpc_common.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/*
> + * Enable Prefetching and Caching.
> + */
nits: single-line comment format
> +static void enable_spi_prefetch(struct udevice *pch)
> +{
> + u8 reg8;
> +
> + dm_pci_read_config8(pch, 0xdc, ®8);
> + reg8 &= ~(3 << 2);
> + reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
> + dm_pci_write_config8(pch, 0xdc, reg8);
> +}
> +
> +static void enable_port80_on_lpc(struct udevice *pch)
> +{
> + /* Enable port 80 POST on LPC */
> + dm_pci_write_config32(pch, PCH_RCBA_BASE, RCB_BASE_ADDRESS | 1);
> + clrbits_le32(RCB_REG(GCS), 4);
> +}
> +
> +/**
> + * lpc_early_init() - set up LPC serial ports and other early things
> + *
> + * @dev: LPC device
> + * @return 0 if OK, -ve on error
> + */
> +int lpc_common_early_init(struct udevice *dev)
> +{
> + struct udevice *pch = dev->parent;
> + struct reg_info {
> + u32 base;
> + u32 size;
> + } values[4], *ptr;
> + int count;
> + int i;
> +
> + count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
> + "intel,gen-dec", (u32 *)values,
> + sizeof(values) / sizeof(u32));
> + if (count < 0)
> + return -EINVAL;
> +
> + /* Set COM1/COM2 decode range */
> + dm_pci_write_config16(pch, LPC_IO_DEC, 0x0010);
> +
> + /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */
> + dm_pci_write_config16(pch, 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);
> + dm_pci_write_config32(pch, LPC_GENX_DEC(i), reg);
> + }
> +
> + enable_spi_prefetch(pch);
> +
> + /* This is already done in start.S, but let's do it in C */
> + enable_port80_on_lpc(pch);
> +
> + return 0;
> +}
> +
> +int lpc_set_spi_protect(struct udevice *dev, int bios_ctrl, bool protect)
> +{
> + uint8_t bios_cntl;
> +
> + /* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */
> + dm_pci_read_config8(dev, bios_ctrl, &bios_cntl);
> + if (protect) {
> + bios_cntl &= ~BIOS_CTRL_BIOSWE;
> + bios_cntl |= BIT(5);
> + } else {
> + bios_cntl |= BIOS_CTRL_BIOSWE;
> + bios_cntl &= ~BIT(5);
> + }
> + dm_pci_write_config8(dev, bios_ctrl, bios_cntl);
> +
> + return 0;
> +}
> diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
> index 55057e0..4c039ac 100644
> --- a/arch/x86/cpu/ivybridge/bd82x6x.c
> +++ b/arch/x86/cpu/ivybridge/bd82x6x.c
> @@ -14,6 +14,7 @@
> #include <asm/intel_regs.h>
> #include <asm/io.h>
> #include <asm/lapic.h>
> +#include <asm/lpc_common.h>
> #include <asm/pci.h>
> #include <asm/arch/bd82x6x.h>
> #include <asm/arch/model_206ax.h>
> @@ -188,20 +189,7 @@ static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep)
>
> static int bd82x6x_set_spi_protect(struct udevice *dev, bool protect)
> {
> - uint8_t bios_cntl;
> -
> - /* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */
> - dm_pci_read_config8(dev, BIOS_CTRL, &bios_cntl);
> - if (protect) {
> - bios_cntl &= ~BIOS_CTRL_BIOSWE;
> - bios_cntl |= BIT(5);
> - } else {
> - bios_cntl |= BIOS_CTRL_BIOSWE;
> - bios_cntl &= ~BIT(5);
> - }
> - dm_pci_write_config8(dev, BIOS_CTRL, bios_cntl);
> -
> - return 0;
> + return lpc_set_spi_protect(dev, BIOS_CTRL, protect);
> }
>
> static int bd82x6x_get_gpio_base(struct udevice *dev, u32 *gbasep)
> diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
> index 26ffaa0..88ab797 100644
> --- a/arch/x86/cpu/ivybridge/lpc.c
> +++ b/arch/x86/cpu/ivybridge/lpc.c
> @@ -17,6 +17,7 @@
> #include <asm/interrupt.h>
> #include <asm/io.h>
> #include <asm/ioapic.h>
> +#include <asm/lpc_common.h>
> #include <asm/pci.h>
> #include <asm/arch/pch.h>
>
> @@ -405,26 +406,6 @@ static void pch_fixups(struct udevice *pch)
> setbits_le32(RCB_REG(0x21a8), 0x3);
> }
>
> -/*
> - * Enable Prefetching and Caching.
> - */
> -static void enable_spi_prefetch(struct udevice *pch)
> -{
> - u8 reg8;
> -
> - dm_pci_read_config8(pch, 0xdc, ®8);
> - reg8 &= ~(3 << 2);
> - reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
> - dm_pci_write_config8(pch, 0xdc, reg8);
> -}
> -
> -static void enable_port80_on_lpc(struct udevice *pch)
> -{
> - /* Enable port 80 POST on LPC */
> - dm_pci_write_config32(pch, PCH_RCBA_BASE, RCB_BASE_ADDRESS | 1);
> - clrbits_le32(RCB_REG(GCS), 4);
> -}
> -
> static void set_spi_speed(void)
> {
> u32 fdod;
> @@ -441,54 +422,6 @@ static void set_spi_speed(void)
> clrsetbits_8(RCB_REG(SPI_FREQ_SWSEQ), 7, fdod);
> }
>
> -/**
> - * lpc_early_init() - set up LPC serial ports and other early things
> - *
> - * @dev: LPC device
> - * @return 0 if OK, -ve on error
> - */
> -static int lpc_early_init(struct udevice *dev)
> -{
> - struct reg_info {
> - u32 base;
> - u32 size;
> - } values[4], *ptr;
> - int count;
> - int i;
> -
> - count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
> - "intel,gen-dec", (u32 *)values,
> - sizeof(values) / sizeof(u32));
> - if (count < 0)
> - return -EINVAL;
> -
> - /* Set COM1/COM2 decode range */
> - dm_pci_write_config16(dev->parent, LPC_IO_DEC, 0x0010);
> -
> - /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */
> - dm_pci_write_config16(dev->parent, 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);
> - dm_pci_write_config32(dev->parent, LPC_GENX_DEC(i), reg);
> - }
> -
> - enable_spi_prefetch(dev->parent);
> -
> - /* This is already done in start.S, but let's do it in C */
> - enable_port80_on_lpc(dev->parent);
> -
> - set_spi_speed();
> -
> - return 0;
> -}
> -
> static int lpc_init_extra(struct udevice *dev)
> {
> struct udevice *pch = dev->parent;
> @@ -551,6 +484,8 @@ static int lpc_init_extra(struct udevice *dev)
>
> static int bd82x6x_lpc_early_init(struct udevice *dev)
> {
> + set_spi_speed();
> +
> /* Setting up Southbridge. In the northbridge code. */
> debug("Setting up static southbridge registers\n");
> dm_pci_write_config32(dev->parent, PCH_RCBA_BASE,
> @@ -575,7 +510,7 @@ static int bd82x6x_lpc_probe(struct udevice *dev)
> int ret;
>
> if (!(gd->flags & GD_FLG_RELOC)) {
> - ret = lpc_early_init(dev);
> + ret = lpc_common_early_init(dev);
> if (ret) {
> debug("%s: lpc_early_init() failed\n", __func__);
> return ret;
> diff --git a/arch/x86/include/asm/arch-ivybridge/pch.h b/arch/x86/include/asm/arch-ivybridge/pch.h
> index 628b517..f96dc2b 100644
> --- a/arch/x86/include/asm/arch-ivybridge/pch.h
> +++ b/arch/x86/include/asm/arch-ivybridge/pch.h
> @@ -211,8 +211,6 @@
>
> #define SMBUS_TIMEOUT (10 * 1000 * 100)
>
> -#define PCH_RCBA_BASE 0xf0
> -
> #define VCH 0x0000 /* 32bit */
> #define VCAP1 0x0004 /* 32bit */
> #define VCAP2 0x0008 /* 32bit */
> diff --git a/arch/x86/include/asm/lpc_common.h b/arch/x86/include/asm/lpc_common.h
> new file mode 100644
> index 0000000..bcfccaf
> --- /dev/null
> +++ b/arch/x86/include/asm/lpc_common.h
> @@ -0,0 +1,59 @@
> +/*
> + * Copyright (c) 2016 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0
nits: GPL-2.0+?
> + */
> +
> +#ifndef __asm_lpc_common_h
> +#define __asm_lpc_common_h
nits: all capital letters
> +
> +#define PCH_RCBA_BASE 0xf0
> +
> +#define RC 0x3400 /* 32bit */
> +#define GCS 0x3410 /* 32bit */
> +
> +#define PMBASE 0x40
> +#define ACPI_CNTL 0x44
> +
> +#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */
> +#define COMB_DEC_RANGE (1 << 4) /* 0x2f8-0x2ff (COM2) */
> +#define COMA_DEC_RANGE (0 << 0) /* 0x3f8-0x3ff (COM1) */
> +#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))
> +#define GEN_DEC_RANGE_256B 0xfc0000 /* 256 Bytes */
> +#define GEN_DEC_RANGE_128B 0x7c0000 /* 128 Bytes */
> +#define GEN_DEC_RANGE_64B 0x3c0000 /* 64 Bytes */
> +#define GEN_DEC_RANGE_32B 0x1c0000 /* 32 Bytes */
> +#define GEN_DEC_RANGE_16B 0x0c0000 /* 16 Bytes */
> +#define GEN_DEC_RANGE_8B 0x040000 /* 8 Bytes */
> +#define GEN_DEC_RANGE_4B 0x000000 /* 4 Bytes */
> +#define GEN_DEC_RANGE_EN (1 << 0) /* Range Enable */
> +
> +/**
> + * lpc_common_early_init() - Set up common LPC init
> + *
> + * This sets up the legacy decode areas, GEN_DEC, SPI prefetch and Port80. It
> + * also puts the RCB in the correct place so that RCB_REG() works.
> + *
> + * @dev: LPC device (a child of the PCH)
> + * @return 0 on success, -ve on error
> + */
> +int lpc_common_early_init(struct udevice *dev);
> +
> +int lpc_set_spi_protect(struct udevice *dev, int bios_ctrl, bool protect);
> +
> +#endif
> --
Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
Regards,
Bin
More information about the U-Boot
mailing list