diff options
author | Raul E Rangel <rrangel@chromium.org> | 2021-06-24 17:03:35 -0600 |
---|---|---|
committer | Raul Rangel <rrangel@chromium.org> | 2021-07-02 23:11:48 +0000 |
commit | 3ba21804ff8c374324ba57b84d04a29c657cb1f0 (patch) | |
tree | 269c72707740058642b99e77e5ff82479d76c914 /src | |
parent | e92a9825587ac1c4c6133603354f711344e742dd (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')
-rw-r--r-- | src/soc/amd/common/block/lpc/Kconfig | 6 | ||||
-rw-r--r-- | src/soc/amd/common/block/lpc/Makefile.inc | 10 | ||||
-rw-r--r-- | src/soc/amd/common/block/lpc/spi_dma.c | 62 |
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; +} |