From patchwork Sat Dec 7 04:41:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1205343 X-Patchwork-Delegate: bmeng.cn@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="neUQYSoF"; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47VH4l0jJ9z9sPL for ; Sat, 7 Dec 2019 15:47:35 +1100 (AEDT) Received: from phobos.denx.de (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E62A381695; Sat, 7 Dec 2019 05:46:19 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="neUQYSoF"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 66AA581656; Sat, 7 Dec 2019 05:46:14 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-io1-xd42.google.com (mail-io1-xd42.google.com [IPv6:2607:f8b0:4864:20::d42]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 3FCC7809ED for ; Sat, 7 Dec 2019 05:46:11 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-io1-xd42.google.com with SMTP id v18so9527805iol.2 for ; Fri, 06 Dec 2019 20:46:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XDREPhwxnL46eKAEb3XeZK+nHCghpq3DXBYzdFy54xw=; b=neUQYSoFlTyfubSSroTCU7SinIkvhppCamjJ4XHS4jCLGVkq0SoU85JneZCu/dw8+6 XFXntLt2PcL/COiygeSRWuObmjg/dF/+ZVIwLoMLbdAQoBLlly3da4ywNo9BSiZzrFIv 17wh63q4eD5Wkd4J83UVcu53cNgBMudkvV7Vg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XDREPhwxnL46eKAEb3XeZK+nHCghpq3DXBYzdFy54xw=; b=nz8YoH2t5Tk9CDddYVDPlMxhiaZ9mrLOw2xYKKtxLRY70fci2o478YVLrx2g01cT97 FofEv+Vo1WaKAU1JRE6nOsYu3aa0AmRVBQBfCg4/vf+GFuHXPNtP/IZm7MIhSnOoxQBC E/U3scHzaS97lut7zJbQE0tOA36wkihIbA/SniRj01Snbtay6MIhGXBNuwx1m0zWHd/4 JZFQnL/w9Sloye8EYF5HqCFijuKPRb4UQ0hqS2ZoqFmI3/CZ1cE2BLxZKYJ+1cTH3QVq Ttlol8q5uq2RyWu3n6ZoWbPsApG5kGtC4hESCNpdZXcAU9LXd4Nf7ARw64uRZ7Pw6a10 waLA== X-Gm-Message-State: APjAAAUDweLgC/lksu4zGxPIbMA76QX5Kc/hAunQF4yXMBFITA339oDP Nnvc7g2okmJ0ZgnwRw30yiZZQLOKIrw= X-Google-Smtp-Source: APXvYqxqfSJG8h1SYR8JVH9XvflZz/xdYhB+4sMHttdvyCungx3/EzYweB9JSXzhNvIhA+dHY0NLGw== X-Received: by 2002:a6b:f81a:: with SMTP id o26mr12935753ioh.128.1575693969920; Fri, 06 Dec 2019 20:46:09 -0800 (PST) Received: from kiwi.bld.corp.google.com ([2620:15c:183:0:8223:87c:a681:66aa]) by smtp.gmail.com with ESMTPSA id o7sm4549410ilo.58.2019.12.06.20.46.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Dec 2019 20:46:09 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Subject: [PATCH v6 010/102] x86: spi: Add helper functions for Intel Fast SPI Date: Fri, 6 Dec 2019 21:41:43 -0700 Message-Id: <20191206213936.v6.10.I24ab1b373d29b4c5bf381f2e3a668c802e316a32@changeid> X-Mailer: git-send-email 2.24.0.393.g34dc348eaf-goog In-Reply-To: <20191207044315.51770-1-sjg@chromium.org> References: <20191207044315.51770-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.26 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jagannadha Sutradharudu Teki Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.101.4 at phobos.denx.de X-Virus-Status: Clean Most x86 CPUs use a mechanism where the SPI flash is mapped into the very top of 32-bit address space, so that it can be executed in place and read simply by copying from memory. For an 8MB ROM the mapping starts at 0xff800000. However some recent Intel CPUs do not use a simple 1:1 memory map. Instead the map starts at a different address and not all of the SPI flash is accessible through the map. This 'Fast SPI' feature requires that U-Boot check the location of the map. It is also possible (optionally) to read from the SPI flash using a driver. Add support for booting from Fast SPI. The memory-mapped version is used by both TPL and SPL on Apollo Lake. In respect of a SPI flash driver, the actual SPI driver is ich.c - this just adds a few helper functions and definitions. This is used by Apollo Lake. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: - Add support for of-platdata for TPL - Add the missing header file - Change Fast-SPI driver into a helper file used by ICH SPI - Don't include write() and erase() in TPL - Drop 'a4' comment for register offset - Merge in patch "x86: Add support for booting from Fast SPI" - Reorder file so that write() and erase() are together - Use pci_get_devfn() Changes in v2: None arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/fast_spi.c | 73 ++++++++++++++++++++++++++++ arch/x86/include/asm/fast_spi.h | 68 ++++++++++++++++++++++++++ arch/x86/include/asm/spl.h | 1 + 4 files changed, 143 insertions(+) create mode 100644 arch/x86/cpu/intel_common/fast_spi.c create mode 100644 arch/x86/include/asm/fast_spi.h diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index 07f27c29ec..dfbc29f047 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += report_platform.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += mrc.o endif obj-y += cpu.o +obj-y += fast_spi.o obj-y += lpc.o ifndef CONFIG_TARGET_EFI_APP obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o diff --git a/arch/x86/cpu/intel_common/fast_spi.c b/arch/x86/cpu/intel_common/fast_spi.c new file mode 100644 index 0000000000..a6e3d0a5bf --- /dev/null +++ b/arch/x86/cpu/intel_common/fast_spi.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include +#include +#include +#include +#include + +/* + * Returns bios_start and fills in size of the BIOS region. + */ +static ulong fast_spi_get_bios_region(struct fast_spi_regs *regs, + uint *bios_size) +{ + ulong bios_start, bios_end; + + /* + * BIOS_BFPREG provides info about BIOS-Flash Primary Region Base and + * Limit. Base and Limit fields are in units of 4K. + */ + u32 val = readl(®s->bfp); + + bios_start = (val & SPIBAR_BFPREG_PRB_MASK) << 12; + bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >> + SPIBAR_BFPREG_PRL_SHIFT) + 1) << 12; + *bios_size = bios_end - bios_start; + + return bios_start; +} + +int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, + uint *offsetp) +{ + struct fast_spi_regs *regs; + ulong bar, base, mmio_base; + + /* Special case to find mapping without probing the device */ + pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, &bar, PCI_SIZE_32); + mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK; + regs = (struct fast_spi_regs *)mmio_base; + base = fast_spi_get_bios_region(regs, map_sizep); + *map_basep = (u32)-*map_sizep - base; + *offsetp = base; + + return 0; +} + +int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base) +{ + /* Program Temporary BAR for SPI */ + pci_x86_write_config(pdev, PCI_BASE_ADDRESS_0, + mmio_base | PCI_BASE_ADDRESS_SPACE_MEMORY, + PCI_SIZE_32); + + /* Enable Bus Master and MMIO Space */ + pci_x86_clrset_config(pdev, PCI_COMMAND, 0, PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY, PCI_SIZE_8); + + /* + * Disable the BIOS write protect so write commands are allowed. + * Enable Prefetching and caching. + */ + pci_x86_clrset_config(pdev, SPIBAR_BIOS_CONTROL, + SPIBAR_BIOS_CONTROL_EISS | + SPIBAR_BIOS_CONTROL_CACHE_DISABLE, + SPIBAR_BIOS_CONTROL_WPD | + SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE, PCI_SIZE_8); + + return 0; +} diff --git a/arch/x86/include/asm/fast_spi.h b/arch/x86/include/asm/fast_spi.h new file mode 100644 index 0000000000..6894298526 --- /dev/null +++ b/arch/x86/include/asm/fast_spi.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017 Intel Corporation. + */ + +#ifndef ASM_FAST_SPI_H +#define ASM_FAST_SPI_H + +/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs { + u32 bfp; + u32 hsfsts_ctl; + u32 faddr; + u32 dlock; + + u32 fdata[0x10]; + + u32 fracc; + u32 freg[12]; + u32 fpr[5]; + u32 gpr0; + u32 spare2; + u32 sts_ctl; + u16 preop; + u16 optype; + u8 opmenu[8]; + + u32 spare3; + u32 fdoc; + u32 fdod; + u32 spare4; + u32 afc; + u32 vscc[2]; + u32 ptinx; + u32 ptdata; +}; +check_member(fast_spi_regs, ptdata, 0xd0); + +/* Bit definitions for BFPREG (0x00) register */ +#define SPIBAR_BFPREG_PRB_MASK 0x7fff +#define SPIBAR_BFPREG_PRL_SHIFT 16 +#define SPIBAR_BFPREG_PRL_MASK (0x7fff << SPIBAR_BFPREG_PRL_SHIFT) + +/* PCI configuration registers */ +#define SPIBAR_BIOS_CONTROL 0xdc +#define SPIBAR_BIOS_CONTROL_WPD BIT(0) +#define SPIBAR_BIOS_CONTROL_LOCK_ENABLE BIT(1) +#define SPIBAR_BIOS_CONTROL_CACHE_DISABLE BIT(2) +#define SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE BIT(3) +#define SPIBAR_BIOS_CONTROL_EISS BIT(5) +#define SPIBAR_BIOS_CONTROL_BILD BIT(7) + +/** + * fast_spi_get_bios_mmap() - Get memory map for SPI flash + * + * @pdev: PCI device to use (this is the Fast SPI device) + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 (always) + */ +int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, + uint *offsetp); + +int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base); + +#endif /* ASM_FAST_SPI_H */ diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h index 1bef4877eb..cc6cac08f2 100644 --- a/arch/x86/include/asm/spl.h +++ b/arch/x86/include/asm/spl.h @@ -11,6 +11,7 @@ enum { BOOT_DEVICE_SPI_MMAP = 10, + BOOT_DEVICE_FAST_SPI, BOOT_DEVICE_CROS_VBOOT, };