diff mbox

[v2,4/5] ast2400: create SPI flash slaves

Message ID 1466165724-7620-5-git-send-email-clg@kaod.org (mailing list archive)
State New, archived
Headers show

Commit Message

Cédric Le Goater June 17, 2016, 12:15 p.m. UTC
A set of SPI flash slaves is attached under the flash controllers of
the palmetto platform. "n25q256a" flash modules are used for the BMC
and "mx25l25635e" for the host. These types are common in the
OpenPower ecosystem.

The segment addresses used for the memory mappings are the defaults
provided by the specs. They can be changed with the Segment Address
Register but this is not supported in the current implementation.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes since v1:
 
 - use the "drive" property to define the flash backend 

 hw/arm/palmetto-bmc.c       |  3 ++
 hw/ssi/aspeed_smc.c         | 69 +++++++++++++++++++++++++++++++++++++++++++--
 include/hw/ssi/aspeed_smc.h | 10 +++++++
 3 files changed, 79 insertions(+), 3 deletions(-)

Comments

Peter Maydell June 20, 2016, 3:38 p.m. UTC | #1
On 17 June 2016 at 13:15, Cédric Le Goater <clg@kaod.org> wrote:
> A set of SPI flash slaves is attached under the flash controllers of
> the palmetto platform. "n25q256a" flash modules are used for the BMC
> and "mx25l25635e" for the host. These types are common in the
> OpenPower ecosystem.
>
> The segment addresses used for the memory mappings are the defaults
> provided by the specs. They can be changed with the Segment Address
> Register but this is not supported in the current implementation.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---

> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index 6a02906c8f97..a8337eb81975 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c

> +void aspeed_smc_init_flashes(AspeedSMCState *s, const char *flashtype,
> +                             Error **errp)
> +{
> +    int i ;
> +    char name[32];
> +
> +    for (i = 0; i < s->num_cs; ++i) {
> +        Object *obj = object_new(TYPE_ASPEED_SMC_FLASH);
> +        AspeedSMCFlashState *fl = ASPEED_SMC_FLASH(obj);
> +        DriveInfo *dinfo = drive_get_next(IF_MTD);

You don't want to be calling drive_get_next() in code in
hw/ssi -- that should be done at the board level, and then
the board creates the flash device and sets its drive property
and connects the flash device up to the SSI controller.

thanks
-- PMM
Cédric Le Goater June 20, 2016, 4:02 p.m. UTC | #2
On 06/20/2016 05:38 PM, Peter Maydell wrote:
> On 17 June 2016 at 13:15, Cédric Le Goater <clg@kaod.org> wrote:
>> A set of SPI flash slaves is attached under the flash controllers of
>> the palmetto platform. "n25q256a" flash modules are used for the BMC
>> and "mx25l25635e" for the host. These types are common in the
>> OpenPower ecosystem.
>>
>> The segment addresses used for the memory mappings are the defaults
>> provided by the specs. They can be changed with the Segment Address
>> Register but this is not supported in the current implementation.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
> 
>> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
>> index 6a02906c8f97..a8337eb81975 100644
>> --- a/hw/ssi/aspeed_smc.c
>> +++ b/hw/ssi/aspeed_smc.c
> 
>> +void aspeed_smc_init_flashes(AspeedSMCState *s, const char *flashtype,
>> +                             Error **errp)
>> +{
>> +    int i ;
>> +    char name[32];
>> +
>> +    for (i = 0; i < s->num_cs; ++i) {
>> +        Object *obj = object_new(TYPE_ASPEED_SMC_FLASH);
>> +        AspeedSMCFlashState *fl = ASPEED_SMC_FLASH(obj);
>> +        DriveInfo *dinfo = drive_get_next(IF_MTD);
> 
> You don't want to be calling drive_get_next() in code in
> hw/ssi -- that should be done at the board level, and then
> the board creates the flash device and sets its drive property
> and connects the flash device up to the SSI controller.

OK. I will rework that part.
 
Thanks,

C.
diff mbox

Patch

diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
index a51d960510ee..0aed97a7d9cf 100644
--- a/hw/arm/palmetto-bmc.c
+++ b/hw/arm/palmetto-bmc.c
@@ -47,6 +47,9 @@  static void palmetto_bmc_init(MachineState *machine)
     object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
                              &error_abort);
 
+    aspeed_smc_init_flashes(&bmc->soc.smc, "n25q256a", &error_abort);
+    aspeed_smc_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
+
     palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
     palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
     palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 6a02906c8f97..a8337eb81975 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -28,6 +28,8 @@ 
 #include "qemu/log.h"
 #include "include/qemu/error-report.h"
 #include "exec/address-spaces.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
 
 #include "hw/ssi/aspeed_smc.h"
 
@@ -98,13 +100,32 @@ 
 #define R_SPI_MISC_CRTL   (0x10 / 4)
 #define R_SPI_TIMINGS     (0x14 / 4)
 
+/*
+ * Default segments mappings and size for each slave
+ */
+static const AspeedSegments aspeed_segments_legacy[] = {
+    { 0x14000000, 32 * 1024 * 1024 },
+};
+
+static const AspeedSegments aspeed_segments_fmc[] = {
+    { 0x20000000, 64 * 1024 * 1024 },
+    { 0x24000000, 32 * 1024 * 1024 },
+    { 0x26000000, 32 * 1024 * 1024 },
+    { 0x28000000, 32 * 1024 * 1024 },
+    { 0x2A000000, 32 * 1024 * 1024 }
+};
+
+static const AspeedSegments aspeed_segments_spi[] = {
+    { 0x30000000, 64 * 1024 * 1024 },
+};
+
 static const AspeedSMCController controllers[] = {
     { "aspeed.smc.smc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5 },
+      CONF_ENABLE_W0, 5, aspeed_segments_legacy },
     { "aspeed.smc.fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5 },
+      CONF_ENABLE_W0, 5, aspeed_segments_fmc },
     { "aspeed.smc.spi", R_SPI_CONF, 0xff, R_SPI_CTRL0, R_SPI_TIMINGS,
-      SPI_CONF_ENABLE_W0, 1 },
+      SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi },
 };
 
 static bool aspeed_smc_is_ce_stop_active(AspeedSMCState *s, int cs)
@@ -254,6 +275,8 @@  static int aspeed_smc_init(SysBusDevice *sbd)
     memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
                           s->ctrl->name, ASPEED_SMC_R_MAX * 4);
     sysbus_init_mmio(sbd, &s->mmio);
+
+    s->flashes = g_new0(AspeedSMCFlashState *, s->num_cs);
     return 0;
 }
 
@@ -395,3 +418,43 @@  static void aspeed_smc_flash_register_types(void)
 }
 
 type_init(aspeed_smc_flash_register_types)
+
+void aspeed_smc_init_flashes(AspeedSMCState *s, const char *flashtype,
+                             Error **errp)
+{
+    int i ;
+    char name[32];
+
+    for (i = 0; i < s->num_cs; ++i) {
+        Object *obj = object_new(TYPE_ASPEED_SMC_FLASH);
+        AspeedSMCFlashState *fl = ASPEED_SMC_FLASH(obj);
+        DriveInfo *dinfo = drive_get_next(IF_MTD);
+        qemu_irq cs_line;
+
+        s->flashes[i] = fl;
+
+        snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);
+
+        fl->id = i;
+        fl->controller = s;
+        fl->size = s->ctrl->segments[i].size;
+
+        /* backing region */
+        memory_region_init_io(&fl->mmio, obj, &aspeed_smc_flash_ops, fl, name,
+                              fl->size);
+        sysbus_init_mmio(SYS_BUS_DEVICE(fl), &fl->mmio);
+
+        /* SPI Flash module */
+        fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
+        if (dinfo) {
+            qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo),
+                                errp);
+        }
+        qdev_init_nofail(fl->flash);
+
+        cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
+        sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
+
+        sysbus_mmio_map(SYS_BUS_DEVICE(fl), 0, s->ctrl->segments[i].addr);
+    }
+}
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index abd0005b01c2..2636c775c90f 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -43,6 +43,11 @@  typedef struct AspeedSMCFlashState {
 #define ASPEED_SMC_FLASH(obj) \
     OBJECT_CHECK(AspeedSMCFlashState, (obj), TYPE_ASPEED_SMC_FLASH)
 
+typedef struct AspeedSegments {
+    hwaddr addr;
+    uint32_t size;
+} AspeedSegments;
+
 typedef struct AspeedSMCController {
     const char *name;
     uint8_t r_conf;
@@ -51,6 +56,7 @@  typedef struct AspeedSMCController {
     uint8_t r_timings;
     uint8_t conf_enable_w0;
     uint8_t max_slaves;
+    const AspeedSegments *segments;
 } AspeedSMCController;
 
 #define TYPE_ASPEED_SMC "aspeed.smc"
@@ -90,6 +96,10 @@  typedef struct AspeedSMCState {
     uint8_t r_ctrl0;
     uint8_t r_timings;
     uint8_t conf_enable_w0;
+
+    AspeedSMCFlashState **flashes;
 } AspeedSMCState;
 
+extern void aspeed_smc_init_flashes(AspeedSMCState *s, const char *flashtype,
+                                    Error **errp);
 #endif /* ASPEED_SMC_H */