From 4dabf39592e92d692c6f2a1633571114ae25d843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 23 Mar 2020 17:22:30 +0000 Subject: [PATCH] aspeed/smc: Fix DMA support for AST2600 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recent firmwares uses SPI DMA transfers in U-Boot to load the different images (kernel, initrd, dtb) in the SoC DRAM. The AST2600 FMC model is missing the masks to be applied on the DMA registers which resulted in incorrect values. Fix that and wire the SPI controllers which have DMA support on the AST2600. Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support") Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Message-id: 20200320053923.20565-1-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed_ast2600.c | 6 ++++++ hw/ssi/aspeed_smc.c | 15 +++++++++++++-- hw/ssi/trace-events | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 446b44d31c..1a869e09b9 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -411,6 +411,12 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) /* SPI */ for (i = 0; i < sc->spis_num; i++) { + object_property_set_link(OBJECT(&s->spi[i]), OBJECT(s->dram_mr), + "dram", &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err); object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &local_err); diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index 9d5c696d5a..2edccef2d5 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -364,6 +364,8 @@ static const AspeedSMCController controllers[] = { .flash_window_base = ASPEED26_SOC_FMC_FLASH_BASE, .flash_window_size = 0x10000000, .has_dma = true, + .dma_flash_mask = 0x0FFFFFFC, + .dma_dram_mask = 0x3FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_2600_smc_segment_to_reg, .reg_to_segment = aspeed_2600_smc_reg_to_segment, @@ -379,7 +381,9 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2600_spi1, .flash_window_base = ASPEED26_SOC_SPI_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = false, + .has_dma = true, + .dma_flash_mask = 0x0FFFFFFC, + .dma_dram_mask = 0x3FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_2600_smc_segment_to_reg, .reg_to_segment = aspeed_2600_smc_reg_to_segment, @@ -395,7 +399,9 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2600_spi2, .flash_window_base = ASPEED26_SOC_SPI2_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = false, + .has_dma = true, + .dma_flash_mask = 0x0FFFFFFC, + .dma_dram_mask = 0x3FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_2600_smc_segment_to_reg, .reg_to_segment = aspeed_2600_smc_reg_to_segment, @@ -1135,6 +1141,11 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s) MemTxResult result; uint32_t data; + trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ? + "write" : "read", + s->regs[R_DMA_FLASH_ADDR], + s->regs[R_DMA_DRAM_ADDR], + s->regs[R_DMA_LEN]); while (s->regs[R_DMA_LEN]) { if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) { data = address_space_ldl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR], diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events index 0a70629801..0ea498de91 100644 --- a/hw/ssi/trace-events +++ b/hw/ssi/trace-events @@ -6,5 +6,6 @@ aspeed_smc_do_snoop(int cs, int index, int dummies, int data) "CS%d index:0x%x d aspeed_smc_flash_write(int cs, uint64_t addr, uint32_t size, uint64_t data, int mode) "CS%d @0x%" PRIx64 " size %u: 0x%" PRIx64" mode:%d" aspeed_smc_read(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64 aspeed_smc_dma_checksum(uint32_t addr, uint32_t data) "0x%08x: 0x%08x" +aspeed_smc_dma_rw(const char *dir, uint32_t flash_addr, uint32_t dram_addr, uint32_t size) "%s flash:@0x%08x dram:@0x%08x size:0x%08x" aspeed_smc_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64 aspeed_smc_flash_select(int cs, const char *prefix) "CS%d %sselect"