summaryrefslogtreecommitdiff
path: root/src/soc/amd
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2021-06-24 17:03:35 -0600
committerRaul Rangel <rrangel@chromium.org>2021-07-02 23:11:48 +0000
commit3ba21804ff8c374324ba57b84d04a29c657cb1f0 (patch)
tree269c72707740058642b99e77e5ff82479d76c914 /src/soc/amd
parente92a9825587ac1c4c6133603354f711344e742dd (diff)
soc/amd/common/block/lpc: Add custom SPI DMA boot device
This is a copy of mmap_boot.c and mem_rdev_ro_ops. I split it up so it was easier to review. The next patches will add support for the SPI DMA controller. This will provide a minor speed up vs using mmap reads. It will also provide the facilities to perform asynchronous SPI loading. BUG=b:179699789 TEST=Boot guybrush to OS Signed-off-by: Raul E Rangel <rrangel@chromium.org> Change-Id: Id26e2a69601d0f31e256d0010008904a447c8e21 Reviewed-on: https://review.coreboot.org/c/coreboot/+/55854 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc/amd')
-rw-r--r--src/soc/amd/common/block/lpc/Kconfig6
-rw-r--r--src/soc/amd/common/block/lpc/Makefile.inc10
-rw-r--r--src/soc/amd/common/block/lpc/spi_dma.c62
3 files changed, 78 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/lpc/Kconfig b/src/soc/amd/common/block/lpc/Kconfig
index bbc1650f24..23116a77ce 100644
--- a/src/soc/amd/common/block/lpc/Kconfig
+++ b/src/soc/amd/common/block/lpc/Kconfig
@@ -8,6 +8,12 @@ config PROVIDES_ROM_SHARING
help
Select this option if the LPC bridge supports ROM sharing.
+config SOC_AMD_COMMON_BLOCK_LPC_SPI_DMA
+ bool
+ select X86_CUSTOM_BOOTMEDIA
+ help
+ Select this option to enable SPI DMA support.
+
config SOC_AMD_COMMON_BLOCK_HAS_ESPI
bool
help
diff --git a/src/soc/amd/common/block/lpc/Makefile.inc b/src/soc/amd/common/block/lpc/Makefile.inc
index 4fbc06161e..7900b10d13 100644
--- a/src/soc/amd/common/block/lpc/Makefile.inc
+++ b/src/soc/amd/common/block/lpc/Makefile.inc
@@ -11,6 +11,16 @@ smm-y += lpc_util.c
endif # CONFIG_SOC_AMD_COMMON_BLOCK_LPC
+ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_LPC_SPI_DMA),y)
+bootblock-y += spi_dma.c
+ifneq ($(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK),y)
+verstage-y += spi_dma.c
+endif
+romstage-y += spi_dma.c
+ramstage-y += spi_dma.c
+smm-y += spi_dma.c
+endif # CONFIG_SOC_AMD_COMMON_BLOCK_LPC_SPI_DMA
+
ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_USE_ESPI),y)
bootblock-y += espi_util.c
diff --git a/src/soc/amd/common/block/lpc/spi_dma.c b/src/soc/amd/common/block/lpc/spi_dma.c
new file mode 100644
index 0000000000..470bfb1a96
--- /dev/null
+++ b/src/soc/amd/common/block/lpc/spi_dma.c
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <boot_device.h>
+#include <commonlib/helpers.h>
+#include <commonlib/region.h>
+#include <spi_flash.h>
+#include <string.h>
+#include <types.h>
+
+/* The ROM is memory mapped just below 4GiB. Form a pointer for the base. */
+#define rom_base ((void *)(uintptr_t)(0x100000000ULL - CONFIG_ROM_SIZE))
+
+static void *spi_dma_mmap(const struct region_device *rd, size_t offset, size_t size __unused)
+{
+ const struct mem_region_device *mdev;
+
+ mdev = container_of(rd, __typeof__(*mdev), rdev);
+
+ return &mdev->base[offset];
+}
+
+static int spi_dma_munmap(const struct region_device *rd __unused, void *mapping __unused)
+{
+ return 0;
+}
+
+static ssize_t spi_dma_readat_mmap(const struct region_device *rd, void *b, size_t offset,
+ size_t size)
+{
+ const struct mem_region_device *mdev;
+
+ mdev = container_of(rd, __typeof__(*mdev), rdev);
+
+ memcpy(b, &mdev->base[offset], size);
+
+ return size;
+}
+
+const struct region_device_ops spi_dma_rdev_ro_ops = {
+ .mmap = spi_dma_mmap,
+ .munmap = spi_dma_munmap,
+ .readat = spi_dma_readat_mmap,
+};
+
+static const struct mem_region_device boot_dev = {
+ .base = rom_base,
+ .rdev = REGION_DEV_INIT(&spi_dma_rdev_ro_ops, 0, CONFIG_ROM_SIZE),
+};
+
+const struct region_device *boot_device_ro(void)
+{
+ return &boot_dev.rdev;
+}
+
+uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
+{
+ table->flash_base = 0;
+ table->host_base = (uint32_t)(uintptr_t)rom_base;
+ table->size = CONFIG_ROM_SIZE;
+
+ return 1;
+}