From patchwork Mon Mar 7 02:28:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 592642 X-Patchwork-Delegate: bmeng.cn@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 0A591140BAF for ; Mon, 7 Mar 2016 13:35:13 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b=MVHyjSaB; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DEFB0A775B; Mon, 7 Mar 2016 03:33:27 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sDCEC3Sk3f5I; Mon, 7 Mar 2016 03:33:27 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C07F6A775F; Mon, 7 Mar 2016 03:32:23 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9EF00A76F4 for ; Mon, 7 Mar 2016 03:32:06 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7UdC-XnfbMMI for ; Mon, 7 Mar 2016 03:32:06 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ig0-f181.google.com (mail-ig0-f181.google.com [209.85.213.181]) by theia.denx.de (Postfix) with ESMTPS id 299EAA76F3 for ; Mon, 7 Mar 2016 03:31:44 +0100 (CET) Received: by mail-ig0-f181.google.com with SMTP id ig19so9377791igb.1 for ; Sun, 06 Mar 2016 18:31:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=UAEeka1Bj5m51AT7t3LAwGgBIPy5EEISV4Au57bhDWw=; b=MVHyjSaBkJddyQILxO4T2VDEElRJpAqLrrI/CWCMKPUWtD7MWuPtb7UXBrReZ7hDzM gSIruE9Q8X62MBtVpy1W0FmynyqnW1L7DjIufedM5XqAoPujBXSq/Rf9uJU6IOgQsNo6 spE069gT0wvMxO1RZc5F+1QLWj8SW0nzcO+qMITNrboY/r9105+trI2VAaP/TczhpTXM 8eIuiHP4BiwLk/7DE6oCTupV6UOFe655qo67P+Yc4n4rp+pd0XWAzl1hQy62TWuR5HNQ P8xoBhszyXk/cNS5LB8KLi/9IO7hVhnT2ordsfqNr5/ououe25K/vu4FLbHqJAFg7Pkq HjhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=UAEeka1Bj5m51AT7t3LAwGgBIPy5EEISV4Au57bhDWw=; b=a0xUe+pBJOXrUligWM2vilhHTQ31L6HWBnMA2lrGWT0/BW0LAWIRt8O4ig82R2s8PK 11xKPaKWs//ZgHiEJUdDtsvhjYPcUiETX664GbD2p4KdVqQtaVNlsvQM78XdRS7dzuU5 RLPXsBk01YBDi/BQfJKlVqIoIJAZvHFOUeLY2EdLiq0gxlQXwppX/QF8DNRHVlv+4SCd DChSO/EhS9n4t9RaKnXUS7vn29FcO89NZyPqqDOfzwvQCeeuR6Mb0DjRstq8AwCK4Npx Pfxhy/2WwwTWhP2ehg2ktppnJlCwT8ER0z+sBinwhBkn8Cqu4TFRvQ/J6uJVUuxfH4jO N4Bw== X-Gm-Message-State: AD7BkJJ//cd+qJQG1LIrD+9WJT7ta0LCACQ5FTND08T1a4DJUG7VjAlguW42pbuXmMHiXDZM X-Received: by 10.50.137.66 with SMTP id qg2mr9147000igb.25.1457317903359; Sun, 06 Mar 2016 18:31:43 -0800 (PST) Received: from kaki.bld.corp.google.com ([2620:0:1005:1100:4a7:6f3d:4be:bc56]) by smtp.gmail.com with ESMTPSA id h22sm919943iod.25.2016.03.06.18.31.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 06 Mar 2016 18:31:43 -0800 (PST) Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 25C7722221B; Sun, 6 Mar 2016 19:31:37 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Sun, 6 Mar 2016 19:28:03 -0700 Message-Id: <1457317732-18406-21-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 In-Reply-To: <1457317732-18406-1-git-send-email-sjg@chromium.org> References: <1457317732-18406-1-git-send-email-sjg@chromium.org> Subject: [U-Boot] [PATCH 20/69] x86: Move common LPC code to its own place X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Some of the LPC code is common to several Intel LPC devices. Move it into a common location. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- 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 +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * 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); +} + +/** + * 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include @@ -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 + */ + +#ifndef __asm_lpc_common_h +#define __asm_lpc_common_h + +#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