/*
 * 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/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->max_peripherals; 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();

    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->max_peripherals &&
        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" PRIx64, 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 = ASPEED_SMC_GET_CLASS(s);

    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 = ASPEED_SMC_GET_CLASS(s);
    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 |= 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 |= 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);
    }

    /* Unselect all peripherals */
    for (i = 0; i < s->num_cs; ++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->max_peripherals; ++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->max_peripherals) ||
        (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->max_peripherals)) {

        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 + s->num_cs) {
        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->max_peripherals) {
        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->max_peripherals; 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;

    /* Enforce some real HW limits */
    if (s->num_cs > asc->max_peripherals) {
        aspeed_smc_error("num_cs cannot exceed: %d", asc->max_peripherals);
        s->num_cs = asc->max_peripherals;
    }

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

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

    /* Setup cs_lines for peripherals */
    s->cs_lines = g_new0(qemu_irq, s->num_cs);

    for (i = 0; i < s->num_cs; ++i) {
        sysbus_init_irq(sbd, &s->cs_lines[i]);
    }

    /* 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_io(&s->mmio_flash, OBJECT(s),
                          &aspeed_smc_flash_default_ops, s,
                          TYPE_ASPEED_SMC ".flash",
                          asc->flash_window_size);
    memory_region_init_alias(&s->mmio_flash_alias, OBJECT(s),
                             TYPE_ASPEED_SMC ".flash",
                             &s->mmio_flash, 0, asc->flash_window_size);
    sysbus_init_mmio(sbd, &s->mmio_flash_alias);

    /*
     * 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->max_peripherals; ++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 = (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_UINT32("num-cs", AspeedSMCState, num_cs, 1),
    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);
    AspeedSMCClass *asc;
    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;
    }

    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, 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->max_peripherals   = 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->max_peripherals   = 5;
    asc->segments          = aspeed_2400_fmc_segments;
    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->max_peripherals   = 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->max_peripherals   = 3;
    asc->segments          = aspeed_2500_fmc_segments;
    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->max_peripherals   = 2;
    asc->segments          = aspeed_2500_spi1_segments;
    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->max_peripherals   = 2;
    asc->segments          = aspeed_2500_spi2_segments;
    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->max_peripherals   = 3;
    asc->segments          = aspeed_2600_fmc_segments;
    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->max_peripherals   = 2;
    asc->segments          = aspeed_2600_spi1_segments;
    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->max_peripherals   = 3;
    asc->segments          = aspeed_2600_spi2_segments;
    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,
};

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_init(aspeed_smc_register_types)
