diff mbox series

aspeed/smc: Fix DMA support for AST2600

Message ID 20200320053923.20565-1-clg@kaod.org
State New
Headers show
Series aspeed/smc: Fix DMA support for AST2600 | expand

Commit Message

Cédric Le Goater March 20, 2020, 5:39 a.m. UTC
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 <clg@kaod.org>
---
 hw/arm/aspeed_ast2600.c |  6 ++++++
 hw/ssi/aspeed_smc.c     | 15 +++++++++++++--
 hw/ssi/trace-events     |  1 +
 3 files changed, 20 insertions(+), 2 deletions(-)

Comments

Joel Stanley March 20, 2020, 5:42 a.m. UTC | #1
On Fri, 20 Mar 2020 at 05:39, Cédric Le Goater <clg@kaod.org> wrote:
>
> 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 <clg@kaod.org>

I gave this a spin with the Tacoma machine and it resolved the issue I
saw. Thanks for fixing it.

Reviewed-by: Joel Stanley <joel@jms.id.au>


> ---
>  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 446b44d31cf1..1a869e09b96a 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 9d5c696d5a17..2edccef2d54d 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 0a70629801a9..0ea498de910b 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"
> --
> 2.21.1
>
Peter Maydell March 23, 2020, 9:14 a.m. UTC | #2
On Fri, 20 Mar 2020 at 05:39, Cédric Le Goater <clg@kaod.org> wrote:
>
> 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 <clg@kaod.org>
> ---
>  hw/arm/aspeed_ast2600.c |  6 ++++++
>  hw/ssi/aspeed_smc.c     | 15 +++++++++++++--
>  hw/ssi/trace-events     |  1 +
>  3 files changed, 20 insertions(+), 2 deletions(-)
>



Applied to target-arm.next, thanks.

-- PMM
diff mbox series

Patch

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 446b44d31cf1..1a869e09b96a 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 9d5c696d5a17..2edccef2d54d 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 0a70629801a9..0ea498de910b 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"