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

    for (i = 0; i < asc->cs_num_max; ++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(&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 = (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);
    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->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,
};

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)
