/*
 * ASPEED AST2400 SMC Controller (SPI Flash Only)
 *
 * Copyright (C) 2016 IBM Corp.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "hw/block/flash.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu/units.h"
#include "trace.h"

#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/ssi/aspeed_smc.h"

/* CE Type Setting Register */
#define R_CONF            (0x00 / 4)
#define   CONF_LEGACY_DISABLE  (1 << 31)
#define   CONF_ENABLE_W4       20
#define   CONF_ENABLE_W3       19
#define   CONF_ENABLE_W2       18
#define   CONF_ENABLE_W1       17
#define   CONF_ENABLE_W0       16
#define   CONF_FLASH_TYPE4     8
#define   CONF_FLASH_TYPE3     6
#define   CONF_FLASH_TYPE2     4
#define   CONF_FLASH_TYPE1     2
#define   CONF_FLASH_TYPE0     0
#define      CONF_FLASH_TYPE_NOR   0x0
#define      CONF_FLASH_TYPE_NAND  0x1
#define      CONF_FLASH_TYPE_SPI   0x2 /* AST2600 is SPI only */

/* CE Control Register */
#define R_CE_CTRL            (0x04 / 4)
#define   CTRL_EXTENDED4       4  /* 32 bit addressing for SPI */
#define   CTRL_EXTENDED3       3  /* 32 bit addressing for SPI */
#define   CTRL_EXTENDED2       2  /* 32 bit addressing for SPI */
#define   CTRL_EXTENDED1       1  /* 32 bit addressing for SPI */
#define   CTRL_EXTENDED0       0  /* 32 bit addressing for SPI */

/* Interrupt Control and Status Register */
#define R_INTR_CTRL       (0x08 / 4)
#define   INTR_CTRL_DMA_STATUS            (1 << 11)
#define   INTR_CTRL_CMD_ABORT_STATUS      (1 << 10)
#define   INTR_CTRL_WRITE_PROTECT_STATUS  (1 << 9)
#define   INTR_CTRL_DMA_EN                (1 << 3)
#define   INTR_CTRL_CMD_ABORT_EN          (1 << 2)
#define   INTR_CTRL_WRITE_PROTECT_EN      (1 << 1)

/* Command Control Register */
#define R_CE_CMD_CTRL      (0x0C / 4)
#define   CTRL_ADDR_BYTE0_DISABLE_SHIFT       4
#define   CTRL_DATA_BYTE0_DISABLE_SHIFT       0

#define aspeed_smc_addr_byte_enabled(s, i)                               \
    (!((s)->regs[R_CE_CMD_CTRL] & (1 << (CTRL_ADDR_BYTE0_DISABLE_SHIFT + (i)))))
#define aspeed_smc_data_byte_enabled(s, i)                               \
    (!((s)->regs[R_CE_CMD_CTRL] & (1 << (CTRL_DATA_BYTE0_DISABLE_SHIFT + (i)))))

/* CEx Control Register */
#define R_CTRL0           (0x10 / 4)
#define   CTRL_IO_QPI              (1 << 31)
#define   CTRL_IO_QUAD_DATA        (1 << 30)
#define   CTRL_IO_DUAL_DATA        (1 << 29)
#define   CTRL_IO_DUAL_ADDR_DATA   (1 << 28) /* Includes dummies */
#define   CTRL_IO_QUAD_ADDR_DATA   (1 << 28) /* Includes dummies */
#define   CTRL_CMD_SHIFT           16
#define   CTRL_CMD_MASK            0xff
#define   CTRL_DUMMY_HIGH_SHIFT    14
#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
#define CE_CTRL_CLOCK_FREQ_SHIFT   8
#define CE_CTRL_CLOCK_FREQ_MASK    0xf
#define CE_CTRL_CLOCK_FREQ(div)                                         \
    (((div) & CE_CTRL_CLOCK_FREQ_MASK) << CE_CTRL_CLOCK_FREQ_SHIFT)
#define   CTRL_DUMMY_LOW_SHIFT     6 /* 2 bits [7:6] */
#define   CTRL_CE_STOP_ACTIVE      (1 << 2)
#define   CTRL_CMD_MODE_MASK       0x3
#define     CTRL_READMODE          0x0
#define     CTRL_FREADMODE         0x1
#define     CTRL_WRITEMODE         0x2
#define     CTRL_USERMODE          0x3
#define R_CTRL1           (0x14 / 4)
#define R_CTRL2           (0x18 / 4)
#define R_CTRL3           (0x1C / 4)
#define R_CTRL4           (0x20 / 4)

/* CEx Segment Address Register */
#define R_SEG_ADDR0       (0x30 / 4)
#define   SEG_END_SHIFT        24   /* 8MB units */
#define   SEG_END_MASK         0xff
#define   SEG_START_SHIFT      16   /* address bit [A29-A23] */
#define   SEG_START_MASK       0xff
#define R_SEG_ADDR1       (0x34 / 4)
#define R_SEG_ADDR2       (0x38 / 4)
#define R_SEG_ADDR3       (0x3C / 4)
#define R_SEG_ADDR4       (0x40 / 4)

/* Misc Control Register #1 */
#define R_MISC_CTRL1      (0x50 / 4)

/* SPI dummy cycle data */
#define R_DUMMY_DATA      (0x54 / 4)

/* FMC_WDT2 Control/Status Register for Alternate Boot (AST2600) */
#define R_FMC_WDT2_CTRL   (0x64 / 4)
#define   FMC_WDT2_CTRL_ALT_BOOT_MODE    BIT(6) /* O: 2 chips 1: 1 chip */
#define   FMC_WDT2_CTRL_SINGLE_BOOT_MODE BIT(5)
#define   FMC_WDT2_CTRL_BOOT_SOURCE      BIT(4) /* O: primary 1: alternate */
#define   FMC_WDT2_CTRL_EN               BIT(0)

/* DMA Control/Status Register */
#define R_DMA_CTRL        (0x80 / 4)
#define   DMA_CTRL_REQUEST      (1 << 31)
#define   DMA_CTRL_GRANT        (1 << 30)
#define   DMA_CTRL_DELAY_MASK   0xf
#define   DMA_CTRL_DELAY_SHIFT  8
#define   DMA_CTRL_FREQ_MASK    0xf
#define   DMA_CTRL_FREQ_SHIFT   4
#define   DMA_CTRL_CALIB        (1 << 3)
#define   DMA_CTRL_CKSUM        (1 << 2)
#define   DMA_CTRL_WRITE        (1 << 1)
#define   DMA_CTRL_ENABLE       (1 << 0)

/* DMA Flash Side Address */
#define R_DMA_FLASH_ADDR  (0x84 / 4)

/* DMA DRAM Side Address */
#define R_DMA_DRAM_ADDR   (0x88 / 4)

/* DMA Length Register */
#define R_DMA_LEN         (0x8C / 4)

/* Checksum Calculation Result */
#define R_DMA_CHECKSUM    (0x90 / 4)

/* Read Timing Compensation Register */
#define R_TIMINGS         (0x94 / 4)

/* SPI controller registers and bits (AST2400) */
#define R_SPI_CONF        (0x00 / 4)
#define   SPI_CONF_ENABLE_W0   0
#define R_SPI_CTRL0       (0x4 / 4)
#define R_SPI_MISC_CTRL   (0x10 / 4)
#define R_SPI_TIMINGS     (0x14 / 4)

#define ASPEED_SMC_R_SPI_MAX (0x20 / 4)
#define ASPEED_SMC_R_SMC_MAX (0x20 / 4)

/*
 * DMA DRAM addresses should be 4 bytes aligned and the valid address
 * range is 0x40000000 - 0x5FFFFFFF (AST2400)
 *          0x80000000 - 0xBFFFFFFF (AST2500)
 *
 * DMA flash addresses should be 4 bytes aligned and the valid address
 * range is 0x20000000 - 0x2FFFFFFF.
 *
 * DMA length is from 4 bytes to 32MB
 *   0: 4 bytes
 *   0x7FFFFF: 32M bytes
 */
#define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
#define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
#define DMA_LENGTH(val)         ((val) & 0x01FFFFFC)

/* Flash opcodes. */
#define SPI_OP_READ       0x03    /* Read data bytes (low frequency) */

#define SNOOP_OFF         0xFF
#define SNOOP_START       0x0

/*
 * Default segments mapping addresses and size for each peripheral per
 * controller. These can be changed when board is initialized with the
 * Segment Address Registers.
 */
static const AspeedSegments aspeed_2500_spi1_segments[];
static const AspeedSegments aspeed_2500_spi2_segments[];

#define ASPEED_SMC_FEATURE_DMA       0x1
#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
#define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4

static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
{
    return !!(asc->features & ASPEED_SMC_FEATURE_DMA);
}

static inline bool aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
{
    return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
}

#define aspeed_smc_error(fmt, ...)                                      \
    qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__)

static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
                                     const AspeedSegments *new,
                                     int cs)
{
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
    AspeedSegments seg;
    int i;

    for (i = 0; i < asc->cs_num_max; i++) {
        if (i == cs) {
            continue;
        }

        asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + i], &seg);

        if (new->addr + new->size > seg.addr &&
            new->addr < seg.addr + seg.size) {
            aspeed_smc_error("new segment CS%d [ 0x%"
                             HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
                             "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
                             cs, new->addr, new->addr + new->size,
                             i, seg.addr, seg.addr + seg.size);
            return true;
        }
    }
    return false;
}

static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
                                                uint64_t regval)
{
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
    AspeedSMCFlash *fl = &s->flashes[cs];
    AspeedSegments seg;

    asc->reg_to_segment(s, regval, &seg);

    memory_region_transaction_begin();
    memory_region_set_size(&fl->mmio, seg.size);
    memory_region_set_address(&fl->mmio, seg.addr - asc->flash_window_base);
    memory_region_set_enabled(&fl->mmio, !!seg.size);
    memory_region_transaction_commit();

    if (asc->segment_addr_mask) {
        regval &= asc->segment_addr_mask;
    }

    s->regs[R_SEG_ADDR0 + cs] = regval;
}

static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
                                         uint64_t new)
{
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
    AspeedSegments seg;

    asc->reg_to_segment(s, new, &seg);

    trace_aspeed_smc_flash_set_segment(cs, new, seg.addr, seg.addr + seg.size);

    /* The start address of CS0 is read-only */
    if (cs == 0 && seg.addr != asc->flash_window_base) {
        aspeed_smc_error("Tried to change CS0 start address to 0x%"
                         HWADDR_PRIx, seg.addr);
        seg.addr = asc->flash_window_base;
        new = asc->segment_to_reg(s, &seg);
    }

    /*
     * The end address of the AST2500 spi controllers is also
     * read-only.
     */
    if ((asc->segments == aspeed_2500_spi1_segments ||
         asc->segments == aspeed_2500_spi2_segments) &&
        cs == asc->cs_num_max &&
        seg.addr + seg.size != asc->segments[cs].addr +
        asc->segments[cs].size) {
        aspeed_smc_error("Tried to change CS%d end address to 0x%"
                         HWADDR_PRIx, cs, seg.addr + seg.size);
        seg.size = asc->segments[cs].addr + asc->segments[cs].size -
            seg.addr;
        new = asc->segment_to_reg(s, &seg);
    }

    /* Keep the segment in the overall flash window */
    if (seg.size &&
        (seg.addr + seg.size <= asc->flash_window_base ||
         seg.addr > asc->flash_window_base + asc->flash_window_size)) {
        aspeed_smc_error("new segment for CS%d is invalid : "
                         "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
                         cs, seg.addr, seg.addr + seg.size);
        return;
    }

    /* Check start address vs. alignment */
    if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) {
        aspeed_smc_error("new segment for CS%d is not "
                         "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
                         cs, seg.addr, seg.addr + seg.size);
    }

    /* And segments should not overlap (in the specs) */
    aspeed_smc_flash_overlap(s, &seg, cs);

    /* All should be fine now to move the region */
    aspeed_smc_flash_set_segment_region(s, cs, new);
}

static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
                                              unsigned size)
{
    aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u", addr, size);
    return 0;
}

static void aspeed_smc_flash_default_write(void *opaque, hwaddr addr,
                                           uint64_t data, unsigned size)
{
    aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u: 0x%" PRIx64,
                     addr, size, data);
}

static const MemoryRegionOps aspeed_smc_flash_default_ops = {
    .read = aspeed_smc_flash_default_read,
    .write = aspeed_smc_flash_default_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static inline int aspeed_smc_flash_mode(const AspeedSMCFlash *fl)
{
    const AspeedSMCState *s = fl->controller;

    return s->regs[s->r_ctrl0 + fl->cs] & CTRL_CMD_MODE_MASK;
}

static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
{
    const AspeedSMCState *s = fl->controller;

    return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->cs));
}

static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
{
    const AspeedSMCState *s = fl->controller;
    int cmd = (s->regs[s->r_ctrl0 + fl->cs] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;

    /*
     * In read mode, the default SPI command is READ (0x3). In other
     * modes, the command should necessarily be defined
     *
     * TODO: add support for READ4 (0x13) on AST2600
     */
    if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
        cmd = SPI_OP_READ;
    }

    if (!cmd) {
        aspeed_smc_error("no command defined for mode %d",
                         aspeed_smc_flash_mode(fl));
    }

    return cmd;
}

static inline int aspeed_smc_flash_addr_width(const AspeedSMCFlash *fl)
{
    const AspeedSMCState *s = fl->controller;
    AspeedSMCClass *asc = fl->asc;

    if (asc->addr_width) {
        return asc->addr_width(s);
    } else {
        return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs)) ? 4 : 3;
    }
}

static void aspeed_smc_flash_do_select(AspeedSMCFlash *fl, bool unselect)
{
    AspeedSMCState *s = fl->controller;

    trace_aspeed_smc_flash_select(fl->cs, unselect ? "un" : "");

    qemu_set_irq(s->cs_lines[fl->cs], unselect);
}

static void aspeed_smc_flash_select(AspeedSMCFlash *fl)
{
    aspeed_smc_flash_do_select(fl, false);
}

static void aspeed_smc_flash_unselect(AspeedSMCFlash *fl)
{
    aspeed_smc_flash_do_select(fl, true);
}

static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
                                              uint32_t addr)
{
    const AspeedSMCState *s = fl->controller;
    AspeedSMCClass *asc = fl->asc;
    AspeedSegments seg;

    asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->cs], &seg);
    if ((addr % seg.size) != addr) {
        aspeed_smc_error("invalid address 0x%08x for CS%d segment : "
                         "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
                         addr, fl->cs, seg.addr, seg.addr + seg.size);
        addr %= seg.size;
    }

    return addr;
}

static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
{
    const AspeedSMCState *s = fl->controller;
    uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->cs];
    uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
    uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
    uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;

    if (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA) {
        dummies /= 2;
    }

    return dummies;
}

static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
{
    const AspeedSMCState *s = fl->controller;
    uint8_t cmd = aspeed_smc_flash_cmd(fl);
    int i = aspeed_smc_flash_addr_width(fl);

    /* Flash access can not exceed CS segment */
    addr = aspeed_smc_check_segment_addr(fl, addr);

    ssi_transfer(s->spi, cmd);
    while (i--) {
        if (aspeed_smc_addr_byte_enabled(s, i)) {
            ssi_transfer(s->spi, (addr >> (i * 8)) & 0xff);
        }
    }

    /*
     * Use fake transfers to model dummy bytes. The value should
     * be configured to some non-zero value in fast read mode and
     * zero in read mode. But, as the HW allows inconsistent
     * settings, let's check for fast read mode.
     */
    if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
        for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
            ssi_transfer(fl->controller->spi, s->regs[R_DUMMY_DATA] & 0xff);
        }
    }
}

static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
{
    AspeedSMCFlash *fl = opaque;
    AspeedSMCState *s = fl->controller;
    uint64_t ret = 0;
    int i;

    switch (aspeed_smc_flash_mode(fl)) {
    case CTRL_USERMODE:
        for (i = 0; i < size; i++) {
            ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
        }
        break;
    case CTRL_READMODE:
    case CTRL_FREADMODE:
        aspeed_smc_flash_select(fl);
        aspeed_smc_flash_setup(fl, addr);

        for (i = 0; i < size; i++) {
            ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
        }

        aspeed_smc_flash_unselect(fl);
        break;
    default:
        aspeed_smc_error("invalid flash mode %d", aspeed_smc_flash_mode(fl));
    }

    trace_aspeed_smc_flash_read(fl->cs, addr, size, ret,
                                aspeed_smc_flash_mode(fl));
    return ret;
}

/*
 * TODO (clg@kaod.org): stolen from xilinx_spips.c. Should move to a
 * common include header.
 */
typedef enum {
    READ = 0x3,         READ_4 = 0x13,
    FAST_READ = 0xb,    FAST_READ_4 = 0x0c,
    DOR = 0x3b,         DOR_4 = 0x3c,
    QOR = 0x6b,         QOR_4 = 0x6c,
    DIOR = 0xbb,        DIOR_4 = 0xbc,
    QIOR = 0xeb,        QIOR_4 = 0xec,

    PP = 0x2,           PP_4 = 0x12,
    DPP = 0xa2,
    QPP = 0x32,         QPP_4 = 0x34,
} FlashCMD;

static int aspeed_smc_num_dummies(uint8_t command)
{
    switch (command) { /* check for dummies */
    case READ: /* no dummy bytes/cycles */
    case PP:
    case DPP:
    case QPP:
    case READ_4:
    case PP_4:
    case QPP_4:
        return 0;
    case FAST_READ:
    case DOR:
    case QOR:
    case FAST_READ_4:
    case DOR_4:
    case QOR_4:
        return 1;
    case DIOR:
    case DIOR_4:
        return 2;
    case QIOR:
    case QIOR_4:
        return 4;
    default:
        return -1;
    }
}

static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl,  uint64_t data,
                                unsigned size)
{
    AspeedSMCState *s = fl->controller;
    uint8_t addr_width = aspeed_smc_flash_addr_width(fl);

    trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies,
                              (uint8_t) data & 0xff);

    if (s->snoop_index == SNOOP_OFF) {
        return false; /* Do nothing */

    } else if (s->snoop_index == SNOOP_START) {
        uint8_t cmd = data & 0xff;
        int ndummies = aspeed_smc_num_dummies(cmd);

        /*
         * No dummy cycles are expected with the current command. Turn
         * off snooping and let the transfer proceed normally.
         */
        if (ndummies <= 0) {
            s->snoop_index = SNOOP_OFF;
            return false;
        }

        s->snoop_dummies = ndummies * 8;

    } else if (s->snoop_index >= addr_width + 1) {

        /* The SPI transfer has reached the dummy cycles sequence */
        for (; s->snoop_dummies; s->snoop_dummies--) {
            ssi_transfer(s->spi, s->regs[R_DUMMY_DATA] & 0xff);
        }

        /* If no more dummy cycles are expected, turn off snooping */
        if (!s->snoop_dummies) {
            s->snoop_index = SNOOP_OFF;
        } else {
            s->snoop_index += size;
        }

        /*
         * Dummy cycles have been faked already. Ignore the current
         * SPI transfer
         */
        return true;
    }

    s->snoop_index += size;
    return false;
}

static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
                                   unsigned size)
{
    AspeedSMCFlash *fl = opaque;
    AspeedSMCState *s = fl->controller;
    int i;

    trace_aspeed_smc_flash_write(fl->cs, addr, size, data,
                                 aspeed_smc_flash_mode(fl));

    if (!aspeed_smc_is_writable(fl)) {
        aspeed_smc_error("flash is not writable at 0x%" HWADDR_PRIx, addr);
        return;
    }

    switch (aspeed_smc_flash_mode(fl)) {
    case CTRL_USERMODE:
        if (aspeed_smc_do_snoop(fl, data, size)) {
            break;
        }

        for (i = 0; i < size; i++) {
            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
        }
        break;
    case CTRL_WRITEMODE:
        aspeed_smc_flash_select(fl);
        aspeed_smc_flash_setup(fl, addr);

        for (i = 0; i < size; i++) {
            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
        }

        aspeed_smc_flash_unselect(fl);
        break;
    default:
        aspeed_smc_error("invalid flash mode %d", aspeed_smc_flash_mode(fl));
    }
}

static const MemoryRegionOps aspeed_smc_flash_ops = {
    .read = aspeed_smc_flash_read,
    .write = aspeed_smc_flash_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void aspeed_smc_flash_update_ctrl(AspeedSMCFlash *fl, uint32_t value)
{
    AspeedSMCState *s = fl->controller;
    bool unselect;

    /* User mode selects the CS, other modes unselect */
    unselect = (value & CTRL_CMD_MODE_MASK) != CTRL_USERMODE;

    /* A change of CTRL_CE_STOP_ACTIVE from 0 to 1, unselects the CS */
    if (!(s->regs[s->r_ctrl0 + fl->cs] & CTRL_CE_STOP_ACTIVE) &&
        value & CTRL_CE_STOP_ACTIVE) {
        unselect = true;
    }

    s->regs[s->r_ctrl0 + fl->cs] = value;

    s->snoop_index = unselect ? SNOOP_OFF : SNOOP_START;

    aspeed_smc_flash_do_select(fl, unselect);
}

static void aspeed_smc_reset(DeviceState *d)
{
    AspeedSMCState *s = ASPEED_SMC(d);
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
    int i;

    if (asc->resets) {
        memcpy(s->regs, asc->resets, sizeof s->regs);
    } else {
        memset(s->regs, 0, sizeof s->regs);
    }

    for (i = 0; i < asc->cs_num_max; i++) {
        DeviceState *dev = ssi_get_cs(s->spi, i);
        if (dev) {
            Object *o = OBJECT(dev);

            if (!object_dynamic_cast(o, TYPE_M25P80)) {
                warn_report("Aspeed SMC %s.%d : Invalid %s device type",
                            BUS(s->spi)->name, i, object_get_typename(o));
                continue;
            }

            qemu_irq cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
            qdev_connect_gpio_out_named(DEVICE(s), "cs", i, cs_line);
        }
    }

    /* Unselect all peripherals */
    for (i = 0; i < asc->cs_num_max; ++i) {
        s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
        qemu_set_irq(s->cs_lines[i], true);
    }

    /* setup the default segment register values and regions for all */
    for (i = 0; i < asc->cs_num_max; ++i) {
        aspeed_smc_flash_set_segment_region(s, i,
                    asc->segment_to_reg(s, &asc->segments[i]));
    }

    s->snoop_index = SNOOP_OFF;
    s->snoop_dummies = 0;
}

static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
{
    AspeedSMCState *s = ASPEED_SMC(opaque);
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(opaque);

    addr >>= 2;

    if (addr == s->r_conf ||
        (addr >= s->r_timings &&
         addr < s->r_timings + asc->nregs_timings) ||
        addr == s->r_ce_ctrl ||
        addr == R_CE_CMD_CTRL ||
        addr == R_INTR_CTRL ||
        addr == R_DUMMY_DATA ||
        (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) ||
        (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
        (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
        (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
        (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
        (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
        (addr >= R_SEG_ADDR0 &&
         addr < R_SEG_ADDR0 + asc->cs_num_max) ||
        (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max)) {

        trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);

        return s->regs[addr];
    } else {
        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
                      __func__, addr);
        return -1;
    }
}

static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
{
    /* HCLK/1 .. HCLK/16 */
    const uint8_t hclk_divisors[] = {
        15, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0
    };
    int i;

    for (i = 0; i < ARRAY_SIZE(hclk_divisors); i++) {
        if (hclk_mask == hclk_divisors[i]) {
            return i + 1;
        }
    }

    aspeed_smc_error("invalid HCLK mask %x", hclk_mask);
    return 0;
}

/*
 * When doing calibration, the SPI clock rate in the CE0 Control
 * Register and the read delay cycles in the Read Timing Compensation
 * Register are set using bit[11:4] of the DMA Control Register.
 */
static void aspeed_smc_dma_calibration(AspeedSMCState *s)
{
    uint8_t delay =
        (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
    uint8_t hclk_mask =
        (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
    uint8_t hclk_div = aspeed_smc_hclk_divisor(hclk_mask);
    uint32_t hclk_shift = (hclk_div - 1) << 2;
    uint8_t cs;

    /*
     * The Read Timing Compensation Register values apply to all CS on
     * the SPI bus and only HCLK/1 - HCLK/5 can have tunable delays
     */
    if (hclk_div && hclk_div < 6) {
        s->regs[s->r_timings] &= ~(0xf << hclk_shift);
        s->regs[s->r_timings] |= delay << hclk_shift;
    }

    /*
     * TODO: compute the CS from the DMA address and the segment
     * registers. This is not really a problem for now because the
     * Timing Register values apply to all CS and software uses CS0 to
     * do calibration.
     */
    cs = 0;
    s->regs[s->r_ctrl0 + cs] &=
        ~(CE_CTRL_CLOCK_FREQ_MASK << CE_CTRL_CLOCK_FREQ_SHIFT);
    s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
}

/*
 * Emulate read errors in the DMA Checksum Register for high
 * frequencies and optimistic settings of the Read Timing Compensation
 * Register. This will help in tuning the SPI timing calibration
 * algorithm.
 */
static bool aspeed_smc_inject_read_failure(AspeedSMCState *s)
{
    uint8_t delay =
        (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
    uint8_t hclk_mask =
        (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;

    /*
     * Typical values of a palmetto-bmc machine.
     */
    switch (aspeed_smc_hclk_divisor(hclk_mask)) {
    case 4 ... 16:
        return false;
    case 3: /* at least one HCLK cycle delay */
        return (delay & 0x7) < 1;
    case 2: /* at least two HCLK cycle delay */
        return (delay & 0x7) < 2;
    case 1: /* (> 100MHz) is above the max freq of the controller */
        return true;
    default:
        g_assert_not_reached();
    }
}

/*
 * Accumulate the result of the reads to provide a checksum that will
 * be used to validate the read timing settings.
 */
static void aspeed_smc_dma_checksum(AspeedSMCState *s)
{
    MemTxResult result;
    uint32_t data;

    if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
        aspeed_smc_error("invalid direction for DMA checksum");
        return;
    }

    if (s->regs[R_DMA_CTRL] & DMA_CTRL_CALIB) {
        aspeed_smc_dma_calibration(s);
    }

    while (s->regs[R_DMA_LEN]) {
        data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
                                    MEMTXATTRS_UNSPECIFIED, &result);
        if (result != MEMTX_OK) {
            aspeed_smc_error("Flash read failed @%08x",
                             s->regs[R_DMA_FLASH_ADDR]);
            return;
        }
        trace_aspeed_smc_dma_checksum(s->regs[R_DMA_FLASH_ADDR], data);

        /*
         * When the DMA is on-going, the DMA registers are updated
         * with the current working addresses and length.
         */
        s->regs[R_DMA_CHECKSUM] += data;
        s->regs[R_DMA_FLASH_ADDR] += 4;
        s->regs[R_DMA_LEN] -= 4;
    }

    if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
        s->regs[R_DMA_CHECKSUM] = 0xbadc0de;
    }

}

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],
                                        MEMTXATTRS_UNSPECIFIED, &result);
            if (result != MEMTX_OK) {
                aspeed_smc_error("DRAM read failed @%08x",
                                 s->regs[R_DMA_DRAM_ADDR]);
                return;
            }

            address_space_stl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
                                 data, MEMTXATTRS_UNSPECIFIED, &result);
            if (result != MEMTX_OK) {
                aspeed_smc_error("Flash write failed @%08x",
                                 s->regs[R_DMA_FLASH_ADDR]);
                return;
            }
        } else {
            data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
                                        MEMTXATTRS_UNSPECIFIED, &result);
            if (result != MEMTX_OK) {
                aspeed_smc_error("Flash read failed @%08x",
                                 s->regs[R_DMA_FLASH_ADDR]);
                return;
            }

            address_space_stl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
                                 data, MEMTXATTRS_UNSPECIFIED, &result);
            if (result != MEMTX_OK) {
                aspeed_smc_error("DRAM write failed @%08x",
                                 s->regs[R_DMA_DRAM_ADDR]);
                return;
            }
        }

        /*
         * When the DMA is on-going, the DMA registers are updated
         * with the current working addresses and length.
         */
        s->regs[R_DMA_FLASH_ADDR] += 4;
        s->regs[R_DMA_DRAM_ADDR] += 4;
        s->regs[R_DMA_LEN] -= 4;
        s->regs[R_DMA_CHECKSUM] += data;
    }
}

static void aspeed_smc_dma_stop(AspeedSMCState *s)
{
    /*
     * When the DMA is disabled, INTR_CTRL_DMA_STATUS=0 means the
     * engine is idle
     */
    s->regs[R_INTR_CTRL] &= ~INTR_CTRL_DMA_STATUS;
    s->regs[R_DMA_CHECKSUM] = 0;

    /*
     * Lower the DMA irq in any case. The IRQ control register could
     * have been cleared before disabling the DMA.
     */
    qemu_irq_lower(s->irq);
}

/*
 * When INTR_CTRL_DMA_STATUS=1, the DMA has completed and a new DMA
 * can start even if the result of the previous was not collected.
 */
static bool aspeed_smc_dma_in_progress(AspeedSMCState *s)
{
    return s->regs[R_DMA_CTRL] & DMA_CTRL_ENABLE &&
        !(s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_STATUS);
}

static void aspeed_smc_dma_done(AspeedSMCState *s)
{
    s->regs[R_INTR_CTRL] |= INTR_CTRL_DMA_STATUS;
    if (s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_EN) {
        qemu_irq_raise(s->irq);
    }
}

static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl)
{
    if (!(dma_ctrl & DMA_CTRL_ENABLE)) {
        s->regs[R_DMA_CTRL] = dma_ctrl;

        aspeed_smc_dma_stop(s);
        return;
    }

    if (aspeed_smc_dma_in_progress(s)) {
        aspeed_smc_error("DMA in progress !");
        return;
    }

    s->regs[R_DMA_CTRL] = dma_ctrl;

    if (s->regs[R_DMA_CTRL] & DMA_CTRL_CKSUM) {
        aspeed_smc_dma_checksum(s);
    } else {
        aspeed_smc_dma_rw(s);
    }

    aspeed_smc_dma_done(s);
}

static inline bool aspeed_smc_dma_granted(AspeedSMCState *s)
{
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);

    if (!(asc->features & ASPEED_SMC_FEATURE_DMA_GRANT)) {
        return true;
    }

    if (!(s->regs[R_DMA_CTRL] & DMA_CTRL_GRANT)) {
        aspeed_smc_error("DMA not granted");
        return false;
    }

    return true;
}

static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl)
{
    /* Preserve DMA bits  */
    dma_ctrl |= s->regs[R_DMA_CTRL] & (DMA_CTRL_REQUEST | DMA_CTRL_GRANT);

    if (dma_ctrl == 0xAEED0000) {
        /* automatically grant request */
        s->regs[R_DMA_CTRL] |= (DMA_CTRL_REQUEST | DMA_CTRL_GRANT);
        return;
    }

    /* clear request */
    if (dma_ctrl == 0xDEEA0000) {
        s->regs[R_DMA_CTRL] &= ~(DMA_CTRL_REQUEST | DMA_CTRL_GRANT);
        return;
    }

    if (!aspeed_smc_dma_granted(s)) {
        aspeed_smc_error("DMA not granted");
        return;
    }

    aspeed_smc_dma_ctrl(s, dma_ctrl);
    s->regs[R_DMA_CTRL] &= ~(DMA_CTRL_REQUEST | DMA_CTRL_GRANT);
}

static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
                             unsigned int size)
{
    AspeedSMCState *s = ASPEED_SMC(opaque);
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
    uint32_t value = data;

    trace_aspeed_smc_write(addr, size, data);

    addr >>= 2;

    if (addr == s->r_conf ||
        (addr >= s->r_timings &&
         addr < s->r_timings + asc->nregs_timings) ||
        addr == s->r_ce_ctrl) {
        s->regs[addr] = value;
    } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max) {
        int cs = addr - s->r_ctrl0;
        aspeed_smc_flash_update_ctrl(&s->flashes[cs], value);
    } else if (addr >= R_SEG_ADDR0 &&
               addr < R_SEG_ADDR0 + asc->cs_num_max) {
        int cs = addr - R_SEG_ADDR0;

        if (value != s->regs[R_SEG_ADDR0 + cs]) {
            aspeed_smc_flash_set_segment(s, cs, value);
        }
    } else if (addr == R_CE_CMD_CTRL) {
        s->regs[addr] = value & 0xff;
    } else if (addr == R_DUMMY_DATA) {
        s->regs[addr] = value & 0xff;
    } else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) {
        s->regs[addr] = value & FMC_WDT2_CTRL_EN;
    } else if (addr == R_INTR_CTRL) {
        s->regs[addr] = value;
    } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) {
        asc->dma_ctrl(s, value);
    } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR &&
               aspeed_smc_dma_granted(s)) {
        s->regs[addr] = DMA_DRAM_ADDR(asc, value);
    } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR &&
               aspeed_smc_dma_granted(s)) {
        s->regs[addr] = DMA_FLASH_ADDR(asc, value);
    } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN &&
               aspeed_smc_dma_granted(s)) {
        s->regs[addr] = DMA_LENGTH(value);
    } else {
        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
                      __func__, addr);
        return;
    }
}

static const MemoryRegionOps aspeed_smc_ops = {
    .read = aspeed_smc_read,
    .write = aspeed_smc_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void aspeed_smc_instance_init(Object *obj)
{
    AspeedSMCState *s = ASPEED_SMC(obj);
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
    int i;

    for (i = 0; i < asc->cs_num_max; i++) {
        object_initialize_child(obj, "flash[*]", &s->flashes[i],
                                TYPE_ASPEED_SMC_FLASH);
    }
}

/*
 * Initialize the custom address spaces for DMAs
 */
static void aspeed_smc_dma_setup(AspeedSMCState *s, Error **errp)
{
    if (!s->dram_mr) {
        error_setg(errp, TYPE_ASPEED_SMC ": 'dram' link not set");
        return;
    }

    address_space_init(&s->flash_as, &s->mmio_flash,
                       TYPE_ASPEED_SMC ".dma-flash");
    address_space_init(&s->dram_as, s->dram_mr,
                       TYPE_ASPEED_SMC ".dma-dram");
}

static void aspeed_smc_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    AspeedSMCState *s = ASPEED_SMC(dev);
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
    int i;
    hwaddr offset = 0;

    /* keep a copy under AspeedSMCState to speed up accesses */
    s->r_conf = asc->r_conf;
    s->r_ce_ctrl = asc->r_ce_ctrl;
    s->r_ctrl0 = asc->r_ctrl0;
    s->r_timings = asc->r_timings;
    s->conf_enable_w0 = asc->conf_enable_w0;

    /* DMA irq. Keep it first for the initialization in the SoC */
    sysbus_init_irq(sbd, &s->irq);

    s->spi = ssi_create_bus(dev, NULL);

    /* Setup cs_lines for peripherals */
    s->cs_lines = g_new0(qemu_irq, asc->cs_num_max);
    qdev_init_gpio_out_named(DEVICE(s), s->cs_lines, "cs", asc->cs_num_max);

    /* The memory region for the controller registers */
    memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
                          TYPE_ASPEED_SMC, asc->nregs * 4);
    sysbus_init_mmio(sbd, &s->mmio);

    /*
     * The container memory region representing the address space
     * window in which the flash modules are mapped. The size and
     * address depends on the SoC model and controller type.
     */
    memory_region_init(&s->mmio_flash_container, OBJECT(s),
                       TYPE_ASPEED_SMC ".container",
                       asc->flash_window_size);
    sysbus_init_mmio(sbd, &s->mmio_flash_container);

    memory_region_init_io(&s->mmio_flash, OBJECT(s),
                          &aspeed_smc_flash_default_ops, s,
                          TYPE_ASPEED_SMC ".flash",
                          asc->flash_window_size);
    memory_region_add_subregion(&s->mmio_flash_container, 0x0,
                                &s->mmio_flash);

    /*
     * Let's create a sub memory region for each possible peripheral. All
     * have a configurable memory segment in the overall flash mapping
     * window of the controller but, there is not necessarily a flash
     * module behind to handle the memory accesses. This depends on
     * the board configuration.
     */
    for (i = 0; i < asc->cs_num_max; ++i) {
        AspeedSMCFlash *fl = &s->flashes[i];

        if (!object_property_set_link(OBJECT(fl), "controller", OBJECT(s),
                                      errp)) {
            return;
        }
        if (!object_property_set_uint(OBJECT(fl), "cs", i, errp)) {
            return;
        }
        if (!sysbus_realize(SYS_BUS_DEVICE(fl), errp)) {
            return;
        }

        memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
        offset += asc->segments[i].size;
    }

    /* DMA support */
    if (aspeed_smc_has_dma(asc)) {
        aspeed_smc_dma_setup(s, errp);
    }
}

static const VMStateDescription vmstate_aspeed_smc = {
    .name = "aspeed.smc",
    .version_id = 2,
    .minimum_version_id = 2,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, AspeedSMCState, ASPEED_SMC_R_MAX),
        VMSTATE_UINT8(snoop_index, AspeedSMCState),
        VMSTATE_UINT8(snoop_dummies, AspeedSMCState),
        VMSTATE_END_OF_LIST()
    }
};

static Property aspeed_smc_properties[] = {
    DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
    DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
                     TYPE_MEMORY_REGION, MemoryRegion *),
    DEFINE_PROP_END_OF_LIST(),
};

static void aspeed_smc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = aspeed_smc_realize;
    dc->reset = aspeed_smc_reset;
    device_class_set_props(dc, aspeed_smc_properties);
    dc->vmsd = &vmstate_aspeed_smc;
}

static const TypeInfo aspeed_smc_info = {
    .name           = TYPE_ASPEED_SMC,
    .parent         = TYPE_SYS_BUS_DEVICE,
    .instance_init  = aspeed_smc_instance_init,
    .instance_size  = sizeof(AspeedSMCState),
    .class_size     = sizeof(AspeedSMCClass),
    .class_init     = aspeed_smc_class_init,
    .abstract       = true,
};

static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp)
{
    AspeedSMCFlash *s = ASPEED_SMC_FLASH(dev);
    g_autofree char *name = g_strdup_printf(TYPE_ASPEED_SMC_FLASH ".%d", s->cs);

    if (!s->controller) {
        error_setg(errp, TYPE_ASPEED_SMC_FLASH ": 'controller' link not set");
        return;
    }

    s->asc = ASPEED_SMC_GET_CLASS(s->controller);

    /*
     * Use the default segment value to size the memory region. This
     * can be changed by FW at runtime.
     */
    memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_flash_ops,
                          s, name, s->asc->segments[s->cs].size);
    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
}

static Property aspeed_smc_flash_properties[] = {
    DEFINE_PROP_UINT8("cs", AspeedSMCFlash, cs, 0),
    DEFINE_PROP_LINK("controller", AspeedSMCFlash, controller, TYPE_ASPEED_SMC,
                     AspeedSMCState *),
    DEFINE_PROP_END_OF_LIST(),
};

static void aspeed_smc_flash_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->desc = "Aspeed SMC Flash device region";
    dc->realize = aspeed_smc_flash_realize;
    device_class_set_props(dc, aspeed_smc_flash_properties);
}

static const TypeInfo aspeed_smc_flash_info = {
    .name           = TYPE_ASPEED_SMC_FLASH,
    .parent         = TYPE_SYS_BUS_DEVICE,
    .instance_size  = sizeof(AspeedSMCFlash),
    .class_init     = aspeed_smc_flash_class_init,
};

/*
 * The Segment Registers of the AST2400 and AST2500 have a 8MB
 * unit. The address range of a flash SPI peripheral is encoded with
 * absolute addresses which should be part of the overall controller
 * window.
 */
static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s,
                                          const AspeedSegments *seg)
{
    uint32_t reg = 0;
    reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
    reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
    return reg;
}

static void aspeed_smc_reg_to_segment(const AspeedSMCState *s,
                                      uint32_t reg, AspeedSegments *seg)
{
    seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
    seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
}

static const AspeedSegments aspeed_2400_smc_segments[] = {
    { 0x10000000, 32 * MiB },
};

static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2400 SMC Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 1;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 1;
    asc->segments          = aspeed_2400_smc_segments;
    asc->flash_window_base = 0x10000000;
    asc->flash_window_size = 0x6000000;
    asc->features          = 0x0;
    asc->nregs             = ASPEED_SMC_R_SMC_MAX;
    asc->segment_to_reg    = aspeed_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_smc_dma_ctrl;
}

static const TypeInfo aspeed_2400_smc_info = {
    .name =  "aspeed.smc-ast2400",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2400_smc_class_init,
};

static const uint32_t aspeed_2400_fmc_resets[ASPEED_SMC_R_MAX] = {
    /*
     * CE0 and CE1 types are HW strapped in SCU70. Do it here to
     * simplify the model.
     */
    [R_CONF] = CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0,
};

static const AspeedSegments aspeed_2400_fmc_segments[] = {
    { 0x20000000, 64 * MiB }, /* start address is readonly */
    { 0x24000000, 32 * MiB },
    { 0x26000000, 32 * MiB },
    { 0x28000000, 32 * MiB },
    { 0x2A000000, 32 * MiB }
};

static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2400 FMC Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 1;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 5;
    asc->segments          = aspeed_2400_fmc_segments;
    asc->segment_addr_mask = 0xffff0000;
    asc->resets            = aspeed_2400_fmc_resets;
    asc->flash_window_base = 0x20000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x1FFFFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_smc_dma_ctrl;
}

static const TypeInfo aspeed_2400_fmc_info = {
    .name =  "aspeed.fmc-ast2400",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2400_fmc_class_init,
};

static const AspeedSegments aspeed_2400_spi1_segments[] = {
    { 0x30000000, 64 * MiB },
};

static int aspeed_2400_spi1_addr_width(const AspeedSMCState *s)
{
    return s->regs[R_SPI_CTRL0] & CTRL_AST2400_SPI_4BYTE ? 4 : 3;
}

static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2400 SPI1 Controller";
    asc->r_conf            = R_SPI_CONF;
    asc->r_ce_ctrl         = 0xff;
    asc->r_ctrl0           = R_SPI_CTRL0;
    asc->r_timings         = R_SPI_TIMINGS;
    asc->nregs_timings     = 1;
    asc->conf_enable_w0    = SPI_CONF_ENABLE_W0;
    asc->cs_num_max        = 1;
    asc->segments          = aspeed_2400_spi1_segments;
    asc->flash_window_base = 0x30000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = 0x0;
    asc->nregs             = ASPEED_SMC_R_SPI_MAX;
    asc->segment_to_reg    = aspeed_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_smc_dma_ctrl;
    asc->addr_width        = aspeed_2400_spi1_addr_width;
}

static const TypeInfo aspeed_2400_spi1_info = {
    .name =  "aspeed.spi1-ast2400",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2400_spi1_class_init,
};

static const uint32_t aspeed_2500_fmc_resets[ASPEED_SMC_R_MAX] = {
    [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
                CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
};

static const AspeedSegments aspeed_2500_fmc_segments[] = {
    { 0x20000000, 128 * MiB }, /* start address is readonly */
    { 0x28000000,  32 * MiB },
    { 0x2A000000,  32 * MiB },
};

static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2600 FMC Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 1;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 3;
    asc->segments          = aspeed_2500_fmc_segments;
    asc->segment_addr_mask = 0xffff0000;
    asc->resets            = aspeed_2500_fmc_resets;
    asc->flash_window_base = 0x20000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x3FFFFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_smc_dma_ctrl;
}

static const TypeInfo aspeed_2500_fmc_info = {
    .name =  "aspeed.fmc-ast2500",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2500_fmc_class_init,
};

static const AspeedSegments aspeed_2500_spi1_segments[] = {
    { 0x30000000, 32 * MiB }, /* start address is readonly */
    { 0x32000000, 96 * MiB }, /* end address is readonly */
};

static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2600 SPI1 Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 1;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 2;
    asc->segments          = aspeed_2500_spi1_segments;
    asc->segment_addr_mask = 0xffff0000;
    asc->flash_window_base = 0x30000000;
    asc->flash_window_size = 0x8000000;
    asc->features          = 0x0;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_smc_dma_ctrl;
}

static const TypeInfo aspeed_2500_spi1_info = {
    .name =  "aspeed.spi1-ast2500",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2500_spi1_class_init,
};

static const AspeedSegments aspeed_2500_spi2_segments[] = {
    { 0x38000000, 32 * MiB }, /* start address is readonly */
    { 0x3A000000, 96 * MiB }, /* end address is readonly */
};

static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2600 SPI2 Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 1;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 2;
    asc->segments          = aspeed_2500_spi2_segments;
    asc->segment_addr_mask = 0xffff0000;
    asc->flash_window_base = 0x38000000;
    asc->flash_window_size = 0x8000000;
    asc->features          = 0x0;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_smc_dma_ctrl;
}

static const TypeInfo aspeed_2500_spi2_info = {
    .name =  "aspeed.spi2-ast2500",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2500_spi2_class_init,
};

/*
 * The Segment Registers of the AST2600 have a 1MB unit. The address
 * range of a flash SPI peripheral is encoded with offsets in the overall
 * controller window. The previous SoC AST2400 and AST2500 used
 * absolute addresses. Only bits [27:20] are relevant and the end
 * address is an upper bound limit.
 */
#define AST2600_SEG_ADDR_MASK 0x0ff00000

static uint32_t aspeed_2600_smc_segment_to_reg(const AspeedSMCState *s,
                                               const AspeedSegments *seg)
{
    uint32_t reg = 0;

    /* Disabled segments have a nil register */
    if (!seg->size) {
        return 0;
    }

    reg |= (seg->addr & AST2600_SEG_ADDR_MASK) >> 16; /* start offset */
    reg |= (seg->addr + seg->size - 1) & AST2600_SEG_ADDR_MASK; /* end offset */
    return reg;
}

static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
                                           uint32_t reg, AspeedSegments *seg)
{
    uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
    uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);

    if (reg) {
        seg->addr = asc->flash_window_base + start_offset;
        seg->size = end_offset + MiB - start_offset;
    } else {
        seg->addr = asc->flash_window_base;
        seg->size = 0;
    }
}

static const uint32_t aspeed_2600_fmc_resets[ASPEED_SMC_R_MAX] = {
    [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
                CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1 |
                CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE2),
};

static const AspeedSegments aspeed_2600_fmc_segments[] = {
    { 0x0, 128 * MiB }, /* start address is readonly */
    { 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
    { 0x0, 0 }, /* disabled */
};

static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2600 FMC Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 1;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 3;
    asc->segments          = aspeed_2600_fmc_segments;
    asc->segment_addr_mask = 0x0ff00ff0;
    asc->resets            = aspeed_2600_fmc_resets;
    asc->flash_window_base = 0x20000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA |
                             ASPEED_SMC_FEATURE_WDT_CONTROL;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x3FFFFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_2600_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_2600_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_2600_smc_dma_ctrl;
}

static const TypeInfo aspeed_2600_fmc_info = {
    .name =  "aspeed.fmc-ast2600",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2600_fmc_class_init,
};

static const AspeedSegments aspeed_2600_spi1_segments[] = {
    { 0x0, 128 * MiB }, /* start address is readonly */
    { 0x0, 0 }, /* disabled */
};

static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2600 SPI1 Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 2;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 2;
    asc->segments          = aspeed_2600_spi1_segments;
    asc->segment_addr_mask = 0x0ff00ff0;
    asc->flash_window_base = 0x30000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA |
                             ASPEED_SMC_FEATURE_DMA_GRANT;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x3FFFFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_2600_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_2600_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_2600_smc_dma_ctrl;
}

static const TypeInfo aspeed_2600_spi1_info = {
    .name =  "aspeed.spi1-ast2600",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2600_spi1_class_init,
};

static const AspeedSegments aspeed_2600_spi2_segments[] = {
    { 0x0, 128 * MiB }, /* start address is readonly */
    { 0x0, 0 }, /* disabled */
    { 0x0, 0 }, /* disabled */
};

static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 2600 SPI2 Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 3;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 3;
    asc->segments          = aspeed_2600_spi2_segments;
    asc->segment_addr_mask = 0x0ff00ff0;
    asc->flash_window_base = 0x50000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA |
                             ASPEED_SMC_FEATURE_DMA_GRANT;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x3FFFFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_2600_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_2600_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_2600_smc_dma_ctrl;
}

static const TypeInfo aspeed_2600_spi2_info = {
    .name =  "aspeed.spi2-ast2600",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_2600_spi2_class_init,
};

/*
 * The FMC Segment Registers of the AST1030 have a 512KB unit.
 * Only bits [27:19] are used for decoding.
 */
#define AST1030_SEG_ADDR_MASK 0x0ff80000

static uint32_t aspeed_1030_smc_segment_to_reg(const AspeedSMCState *s,
        const AspeedSegments *seg)
{
    uint32_t reg = 0;

    /* Disabled segments have a nil register */
    if (!seg->size) {
        return 0;
    }

    reg |= (seg->addr & AST1030_SEG_ADDR_MASK) >> 16; /* start offset */
    reg |= (seg->addr + seg->size - 1) & AST1030_SEG_ADDR_MASK; /* end offset */
    return reg;
}

static void aspeed_1030_smc_reg_to_segment(const AspeedSMCState *s,
        uint32_t reg, AspeedSegments *seg)
{
    uint32_t start_offset = (reg << 16) & AST1030_SEG_ADDR_MASK;
    uint32_t end_offset = reg & AST1030_SEG_ADDR_MASK;
    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);

    if (reg) {
        seg->addr = asc->flash_window_base + start_offset;
        seg->size = end_offset + (512 * KiB) - start_offset;
    } else {
        seg->addr = asc->flash_window_base;
        seg->size = 0;
    }
}

static const uint32_t aspeed_1030_fmc_resets[ASPEED_SMC_R_MAX] = {
    [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
                            CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
};

static const AspeedSegments aspeed_1030_fmc_segments[] = {
    { 0x0, 128 * MiB }, /* start address is readonly */
    { 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
    { 0x0, 0 }, /* disabled */
};

static void aspeed_1030_fmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 1030 FMC Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 2;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 2;
    asc->segments          = aspeed_1030_fmc_segments;
    asc->segment_addr_mask = 0x0ff80ff8;
    asc->resets            = aspeed_1030_fmc_resets;
    asc->flash_window_base = 0x80000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x000BFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_1030_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_1030_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_2600_smc_dma_ctrl;
}

static const TypeInfo aspeed_1030_fmc_info = {
    .name =  "aspeed.fmc-ast1030",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_1030_fmc_class_init,
};

static const AspeedSegments aspeed_1030_spi1_segments[] = {
    { 0x0, 128 * MiB }, /* start address is readonly */
    { 0x0, 0 }, /* disabled */
};

static void aspeed_1030_spi1_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 1030 SPI1 Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 2;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 2;
    asc->segments          = aspeed_1030_spi1_segments;
    asc->segment_addr_mask = 0x0ff00ff0;
    asc->flash_window_base = 0x90000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x000BFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_2600_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_2600_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_2600_smc_dma_ctrl;
}

static const TypeInfo aspeed_1030_spi1_info = {
    .name =  "aspeed.spi1-ast1030",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_1030_spi1_class_init,
};
static const AspeedSegments aspeed_1030_spi2_segments[] = {
    { 0x0, 128 * MiB }, /* start address is readonly */
    { 0x0, 0 }, /* disabled */
};

static void aspeed_1030_spi2_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);

    dc->desc               = "Aspeed 1030 SPI2 Controller";
    asc->r_conf            = R_CONF;
    asc->r_ce_ctrl         = R_CE_CTRL;
    asc->r_ctrl0           = R_CTRL0;
    asc->r_timings         = R_TIMINGS;
    asc->nregs_timings     = 2;
    asc->conf_enable_w0    = CONF_ENABLE_W0;
    asc->cs_num_max        = 2;
    asc->segments          = aspeed_1030_spi2_segments;
    asc->segment_addr_mask = 0x0ff00ff0;
    asc->flash_window_base = 0xb0000000;
    asc->flash_window_size = 0x10000000;
    asc->features          = ASPEED_SMC_FEATURE_DMA;
    asc->dma_flash_mask    = 0x0FFFFFFC;
    asc->dma_dram_mask     = 0x000BFFFC;
    asc->nregs             = ASPEED_SMC_R_MAX;
    asc->segment_to_reg    = aspeed_2600_smc_segment_to_reg;
    asc->reg_to_segment    = aspeed_2600_smc_reg_to_segment;
    asc->dma_ctrl          = aspeed_2600_smc_dma_ctrl;
}

static const TypeInfo aspeed_1030_spi2_info = {
    .name =  "aspeed.spi2-ast1030",
    .parent = TYPE_ASPEED_SMC,
    .class_init = aspeed_1030_spi2_class_init,
};

static void aspeed_smc_register_types(void)
{
    type_register_static(&aspeed_smc_flash_info);
    type_register_static(&aspeed_smc_info);
    type_register_static(&aspeed_2400_smc_info);
    type_register_static(&aspeed_2400_fmc_info);
    type_register_static(&aspeed_2400_spi1_info);
    type_register_static(&aspeed_2500_fmc_info);
    type_register_static(&aspeed_2500_spi1_info);
    type_register_static(&aspeed_2500_spi2_info);
    type_register_static(&aspeed_2600_fmc_info);
    type_register_static(&aspeed_2600_spi1_info);
    type_register_static(&aspeed_2600_spi2_info);
    type_register_static(&aspeed_1030_fmc_info);
    type_register_static(&aspeed_1030_spi1_info);
    type_register_static(&aspeed_1030_spi2_info);
}

type_init(aspeed_smc_register_types)
