diff options
author | Havard Skinnemoen <hskinnemoen@google.com> | 2020-09-10 22:20:57 -0700 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-09-14 14:24:59 +0100 |
commit | b821242c7b3b174bbf7c01a19c93c4e52fedab5d (patch) | |
tree | 836833c9a3f007182c6896056517375fa2222ca0 /hw/arm | |
parent | 1351f892467bd8d9655b43b8fbf10a8d08890612 (diff) |
hw/ssi: NPCM7xx Flash Interface Unit device model
This implements a device model for the NPCM7xx SPI flash controller.
Direct reads and writes, and user-mode transactions have been tested in
various modes. Protection features are not implemented yet.
All the FIU instances are available in the SoC's address space,
regardless of whether or not they're connected to actual flash chips.
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
Message-id: 20200911052101.2602693-11-hskinnemoen@google.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/arm')
-rw-r--r-- | hw/arm/Kconfig | 1 | ||||
-rw-r--r-- | hw/arm/npcm7xx.c | 58 |
2 files changed, 59 insertions, 0 deletions
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index cd74642034..f303c6bead 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -361,6 +361,7 @@ config NPCM7XX select ARM_GIC select PL310 # cache controller select SERIAL + select SSI select UNIMP config FSL_IMX25 diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index 6bb1693833..7884b2b03d 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -99,6 +99,39 @@ static const hwaddr npcm7xx_uart_addr[] = { 0xf0004000, }; +/* Direct memory-mapped access to SPI0 CS0-1. */ +static const hwaddr npcm7xx_fiu0_flash_addr[] = { + 0x80000000, /* CS0 */ + 0x88000000, /* CS1 */ +}; + +/* Direct memory-mapped access to SPI3 CS0-3. */ +static const hwaddr npcm7xx_fiu3_flash_addr[] = { + 0xa0000000, /* CS0 */ + 0xa8000000, /* CS1 */ + 0xb0000000, /* CS2 */ + 0xb8000000, /* CS3 */ +}; + +static const struct { + const char *name; + hwaddr regs_addr; + int cs_count; + const hwaddr *flash_addr; +} npcm7xx_fiu[] = { + { + .name = "fiu0", + .regs_addr = 0xfb000000, + .cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr), + .flash_addr = npcm7xx_fiu0_flash_addr, + }, { + .name = "fiu3", + .regs_addr = 0xc0000000, + .cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr), + .flash_addr = npcm7xx_fiu3_flash_addr, + }, +}; + static void npcm7xx_write_secondary_boot(ARMCPU *cpu, const struct arm_boot_info *info) { @@ -192,6 +225,12 @@ static void npcm7xx_init(Object *obj) for (i = 0; i < ARRAY_SIZE(s->tim); i++) { object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER); } + + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu)); + for (i = 0; i < ARRAY_SIZE(s->fiu); i++) { + object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i], + TYPE_NPCM7XX_FIU); + } } static void npcm7xx_realize(DeviceState *dev, Error **errp) @@ -291,6 +330,25 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) serial_hd(i), DEVICE_LITTLE_ENDIAN); } + /* + * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects + * specified, but this is a programming error. + */ + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu)); + for (i = 0; i < ARRAY_SIZE(s->fiu); i++) { + SysBusDevice *sbd = SYS_BUS_DEVICE(&s->fiu[i]); + int j; + + object_property_set_int(OBJECT(sbd), "cs-count", + npcm7xx_fiu[i].cs_count, &error_abort); + sysbus_realize(sbd, &error_abort); + + sysbus_mmio_map(sbd, 0, npcm7xx_fiu[i].regs_addr); + for (j = 0; j < npcm7xx_fiu[i].cs_count; j++) { + sysbus_mmio_map(sbd, j + 1, npcm7xx_fiu[i].flash_addr[j]); + } + } + /* RAM2 (SRAM) */ memory_region_init_ram(&s->sram, OBJECT(dev), "ram2", NPCM7XX_RAM2_SZ, &error_abort); |