/*
 * TI OMAP general purpose memory controller emulation.
 *
 * Copyright (C) 2007-2009 Nokia Corporation
 * Original code written by Andrzej Zaborowski <andrew@openedhand.com>
 * Enhancements for OMAP3 and NAND support written by Juha Riihimäki
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) any later version of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "hw.h"
#include "flash.h"
#include "omap.h"
#include "memory.h"
#include "exec-memory.h"

/* General-Purpose Memory Controller */
struct omap_gpmc_s {
    qemu_irq irq;
    qemu_irq drq;
    MemoryRegion iomem;
    int accept_256;

    uint8_t revision;
    uint8_t sysconfig;
    uint16_t irqst;
    uint16_t irqen;
    uint16_t lastirq;
    uint16_t timeout;
    uint16_t config;
    struct omap_gpmc_cs_file_s {
        uint32_t config[7];
        MemoryRegion *iomem;
        MemoryRegion container;
        MemoryRegion nandiomem;
        DeviceState *dev;
    } cs_file[8];
    int ecc_cs;
    int ecc_ptr;
    uint32_t ecc_cfg;
    ECCState ecc[9];
    struct prefetch {
        uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */
        uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */
        int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
        int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
        int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
        MemoryRegion iomem;
        uint8_t fifo[64];
    } prefetch;
};

#define OMAP_GPMC_8BIT 0
#define OMAP_GPMC_16BIT 1
#define OMAP_GPMC_NOR 0
#define OMAP_GPMC_NAND 2

static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f)
{
    return (f->config[0] >> 10) & 3;
}

static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
{
    /* devsize field is really 2 bits but we ignore the high
     * bit to ensure consistent behaviour if the guest sets
     * it (values 2 and 3 are reserved in the TRM)
     */
    return (f->config[0] >> 12) & 1;
}

/* Extract the chip-select value from the prefetch config1 register */
static int prefetch_cs(uint32_t config1)
{
    return (config1 >> 24) & 7;
}

static int prefetch_threshold(uint32_t config1)
{
    return (config1 >> 8) & 0x7f;
}

static void omap_gpmc_int_update(struct omap_gpmc_s *s)
{
    /* The TRM is a bit unclear, but it seems to say that
     * the TERMINALCOUNTSTATUS bit is set only on the
     * transition when the prefetch engine goes from
     * active to inactive, whereas the FIFOEVENTSTATUS
     * bit is held high as long as the fifo has at
     * least THRESHOLD bytes available.
     * So we do the latter here, but TERMINALCOUNTSTATUS
     * is set elsewhere.
     */
    if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) {
        s->irqst |= 1;
    }
    if ((s->irqen & s->irqst) != s->lastirq) {
        s->lastirq = s->irqen & s->irqst;
        qemu_set_irq(s->irq, s->lastirq);
    }
}

static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
{
    if (s->prefetch.config1 & 4) {
        qemu_set_irq(s->drq, value);
    }
}

/* Access functions for when a NAND-like device is mapped into memory:
 * all addresses in the region behave like accesses to the relevant
 * GPMC_NAND_DATA_i register (which is actually implemented to call these)
 */
static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr,
                               unsigned size)
{
    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
    uint64_t v;
    nand_setpins(f->dev, 0, 0, 0, 1, 0);
    switch (omap_gpmc_devsize(f)) {
    case OMAP_GPMC_8BIT:
        v = nand_getio(f->dev);
        if (size == 1) {
            return v;
        }
        v |= (nand_getio(f->dev) << 8);
        if (size == 2) {
            return v;
        }
        v |= (nand_getio(f->dev) << 16);
        v |= (nand_getio(f->dev) << 24);
        return v;
    case OMAP_GPMC_16BIT:
        v = nand_getio(f->dev);
        if (size == 1) {
            /* 8 bit read from 16 bit device : probably a guest bug */
            return v & 0xff;
        }
        if (size == 2) {
            return v;
        }
        v |= (nand_getio(f->dev) << 16);
        return v;
    default:
        abort();
    }
}

static void omap_nand_setio(DeviceState *dev, uint64_t value,
                            int nandsize, int size)
{
    /* Write the specified value to the NAND device, respecting
     * both size of the NAND device and size of the write access.
     */
    switch (nandsize) {
    case OMAP_GPMC_8BIT:
        switch (size) {
        case 1:
            nand_setio(dev, value & 0xff);
            break;
        case 2:
            nand_setio(dev, value & 0xff);
            nand_setio(dev, (value >> 8) & 0xff);
            break;
        case 4:
        default:
            nand_setio(dev, value & 0xff);
            nand_setio(dev, (value >> 8) & 0xff);
            nand_setio(dev, (value >> 16) & 0xff);
            nand_setio(dev, (value >> 24) & 0xff);
            break;
        }
        break;
    case OMAP_GPMC_16BIT:
        switch (size) {
        case 1:
            /* writing to a 16bit device with 8bit access is probably a guest
             * bug; pass the value through anyway.
             */
        case 2:
            nand_setio(dev, value & 0xffff);
            break;
        case 4:
        default:
            nand_setio(dev, value & 0xffff);
            nand_setio(dev, (value >> 16) & 0xffff);
            break;
        }
        break;
    }
}

static void omap_nand_write(void *opaque, target_phys_addr_t addr,
                            uint64_t value, unsigned size)
{
    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
    nand_setpins(f->dev, 0, 0, 0, 1, 0);
    omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
}

static const MemoryRegionOps omap_nand_ops = {
    .read = omap_nand_read,
    .write = omap_nand_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void fill_prefetch_fifo(struct omap_gpmc_s *s)
{
    /* Fill the prefetch FIFO by reading data from NAND.
     * We do this synchronously, unlike the hardware which
     * will do this asynchronously. We refill when the
     * FIFO has THRESHOLD bytes free, and we always refill
     * as much data as possible starting at the top end
     * of the FIFO.
     * (We have to refill at THRESHOLD rather than waiting
     * for the FIFO to empty to allow for the case where
     * the FIFO size isn't an exact multiple of THRESHOLD
     * and we're doing DMA transfers.)
     * This means we never need to handle wrap-around in
     * the fifo-reading code, and the next byte of data
     * to read is always fifo[63 - fifopointer].
     */
    int fptr;
    int cs = prefetch_cs(s->prefetch.config1);
    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
    int bytes;
    /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE
     * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND.
     * Instead believe the bit that says it is always a byte count.
     */
    bytes = 64 - s->prefetch.fifopointer;
    if (bytes > s->prefetch.count) {
        bytes = s->prefetch.count;
    }
    s->prefetch.count -= bytes;
    s->prefetch.fifopointer += bytes;
    fptr = 64 - s->prefetch.fifopointer;
    /* Move the existing data in the FIFO so it sits just
     * before what we're about to read in
     */
    while (fptr < (64 - bytes)) {
        s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes];
        fptr++;
    }
    while (fptr < 64) {
        if (is16bit) {
            uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2);
            s->prefetch.fifo[fptr++] = v & 0xff;
            s->prefetch.fifo[fptr++] = (v >> 8) & 0xff;
        } else {
            s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1);
        }
    }
    if (s->prefetch.startengine && (s->prefetch.count == 0)) {
        /* This was the final transfer: raise TERMINALCOUNTSTATUS */
        s->irqst |= 2;
        s->prefetch.startengine = 0;
    }
    /* If there are any bytes in the FIFO at this point then
     * we must raise a DMA request (either this is a final part
     * transfer, or we filled the FIFO in which case we certainly
     * have THRESHOLD bytes available)
     */
    if (s->prefetch.fifopointer != 0) {
        omap_gpmc_dma_update(s, 1);
    }
    omap_gpmc_int_update(s);
}

/* Access functions for a NAND-like device when the prefetch/postwrite
 * engine is enabled -- all addresses in the region behave alike:
 * data is read or written to the FIFO.
 */
static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr,
                                        unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    uint32_t data;
    if (s->prefetch.config1 & 1) {
        /* The TRM doesn't define the behaviour if you read from the
         * FIFO when the prefetch engine is in write mode. We choose
         * to always return zero.
         */
        return 0;
    }
    /* Note that trying to read an empty fifo repeats the last byte */
    if (s->prefetch.fifopointer) {
        s->prefetch.fifopointer--;
    }
    data = s->prefetch.fifo[63 - s->prefetch.fifopointer];
    if (s->prefetch.fifopointer ==
        (64 - prefetch_threshold(s->prefetch.config1))) {
        /* We've drained THRESHOLD bytes now. So deassert the
         * DMA request, then refill the FIFO (which will probably
         * assert it again.)
         */
        omap_gpmc_dma_update(s, 0);
        fill_prefetch_fifo(s);
    }
    omap_gpmc_int_update(s);
    return data;
}

static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr,
                                     uint64_t value, unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    int cs = prefetch_cs(s->prefetch.config1);
    if ((s->prefetch.config1 & 1) == 0) {
        /* The TRM doesn't define the behaviour of writing to the
         * FIFO when the prefetch engine is in read mode. We
         * choose to ignore the write.
         */
        return;
    }
    if (s->prefetch.count == 0) {
        /* The TRM doesn't define the behaviour of writing to the
         * FIFO if the transfer is complete. We choose to ignore.
         */
        return;
    }
    /* The only reason we do any data buffering in postwrite
     * mode is if we are talking to a 16 bit NAND device, in
     * which case we need to buffer the first byte of the
     * 16 bit word until the other byte arrives.
     */
    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
    if (is16bit) {
        /* fifopointer alternates between 64 (waiting for first
         * byte of word) and 63 (waiting for second byte)
         */
        if (s->prefetch.fifopointer == 64) {
            s->prefetch.fifo[0] = value;
            s->prefetch.fifopointer--;
        } else {
            value = (value << 8) | s->prefetch.fifo[0];
            omap_nand_write(&s->cs_file[cs], 0, value, 2);
            s->prefetch.count--;
            s->prefetch.fifopointer = 64;
        }
    } else {
        /* Just write the byte : fifopointer remains 64 at all times */
        omap_nand_write(&s->cs_file[cs], 0, value, 1);
        s->prefetch.count--;
    }
    if (s->prefetch.count == 0) {
        /* Final transfer: raise TERMINALCOUNTSTATUS */
        s->irqst |= 2;
        s->prefetch.startengine = 0;
    }
    omap_gpmc_int_update(s);
}

static const MemoryRegionOps omap_prefetch_ops = {
    .read = omap_gpmc_prefetch_read,
    .write = omap_gpmc_prefetch_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl.min_access_size = 1,
    .impl.max_access_size = 1,
};

static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
{
    /* Return the MemoryRegion* to map/unmap for this chipselect */
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
    if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
        return f->iomem;
    }
    if ((s->prefetch.config1 & 0x80) &&
        (prefetch_cs(s->prefetch.config1) == cs)) {
        /* The prefetch engine is enabled for this CS: map the FIFO */
        return &s->prefetch.iomem;
    }
    return &f->nandiomem;
}

static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
{
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
    uint32_t mask = (f->config[6] >> 8) & 0xf;
    uint32_t base = f->config[6] & 0x3f;
    uint32_t size;

    if (!f->iomem && !f->dev) {
        return;
    }

    if (!(f->config[6] & (1 << 6))) {
        /* Do nothing unless CSVALID */
        return;
    }

    /* TODO: check for overlapping regions and report access errors */
    if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf
         && !(s->accept_256 && !mask)) {
        fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n",
                 __func__, mask);
    }

    base <<= 24;
    size = (0x0fffffff & ~(mask << 24)) + 1;
    /* TODO: rather than setting the size of the mapping (which should be
     * constant), the mask should cause wrapping of the address space, so
     * that the same memory becomes accessible at every <i>size</i> bytes
     * starting from <i>base</i>.  */
    memory_region_init(&f->container, "omap-gpmc-file", size);
    memory_region_add_subregion(&f->container, 0,
                                omap_gpmc_cs_memregion(s, cs));
    memory_region_add_subregion(get_system_memory(), base,
                                &f->container);
}

static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
{
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
    if (!(f->config[6] & (1 << 6))) {
        /* Do nothing unless CSVALID */
        return;
    }
    if (!f->iomem && !f->dev) {
        return;
    }
    memory_region_del_subregion(get_system_memory(), &f->container);
    memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
    memory_region_destroy(&f->container);
}

void omap_gpmc_reset(struct omap_gpmc_s *s)
{
    int i;

    s->sysconfig = 0;
    s->irqst = 0;
    s->irqen = 0;
    omap_gpmc_int_update(s);
    s->timeout = 0;
    s->config = 0xa00;
    s->prefetch.config1 = 0x00004000;
    s->prefetch.transfercount = 0x00000000;
    s->prefetch.startengine = 0;
    s->prefetch.fifopointer = 0;
    s->prefetch.count = 0;
    for (i = 0; i < 8; i ++) {
        omap_gpmc_cs_unmap(s, i);
        s->cs_file[i].config[1] = 0x101001;
        s->cs_file[i].config[2] = 0x020201;
        s->cs_file[i].config[3] = 0x10031003;
        s->cs_file[i].config[4] = 0x10f1111;
        s->cs_file[i].config[5] = 0;
        s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);

        s->cs_file[i].config[6] = 0xf00;
        /* In theory we could probe attached devices for some CFG1
         * bits here, but we just retain them across resets as they
         * were set initially by omap_gpmc_attach().
         */
        if (i == 0) {
            s->cs_file[i].config[0] &= 0x00433e00;
            s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
            omap_gpmc_cs_map(s, i);
        } else {
            s->cs_file[i].config[0] &= 0x00403c00;
        }
    }
    s->ecc_cs = 0;
    s->ecc_ptr = 0;
    s->ecc_cfg = 0x3fcff000;
    for (i = 0; i < 9; i ++)
        ecc_reset(&s->ecc[i]);
}

static int gpmc_wordaccess_only(target_phys_addr_t addr)
{
    /* Return true if the register offset is to a register that
     * only permits word width accesses.
     * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND
     * for any chipselect.
     */
    if (addr >= 0x60 && addr <= 0x1d4) {
        int cs = (addr - 0x60) / 0x30;
        addr -= cs * 0x30;
        if (addr >= 0x7c && addr < 0x88) {
            /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */
            return 0;
        }
    }
    return 1;
}

static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
                               unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    int cs;
    struct omap_gpmc_cs_file_s *f;

    if (size != 4 && gpmc_wordaccess_only(addr)) {
        return omap_badwidth_read32(opaque, addr);
    }

    switch (addr) {
    case 0x000:	/* GPMC_REVISION */
        return s->revision;

    case 0x010:	/* GPMC_SYSCONFIG */
        return s->sysconfig;

    case 0x014:	/* GPMC_SYSSTATUS */
        return 1;						/* RESETDONE */

    case 0x018:	/* GPMC_IRQSTATUS */
        return s->irqst;

    case 0x01c:	/* GPMC_IRQENABLE */
        return s->irqen;

    case 0x040:	/* GPMC_TIMEOUT_CONTROL */
        return s->timeout;

    case 0x044:	/* GPMC_ERR_ADDRESS */
    case 0x048:	/* GPMC_ERR_TYPE */
        return 0;

    case 0x050:	/* GPMC_CONFIG */
        return s->config;

    case 0x054:	/* GPMC_STATUS */
        return 0x001;

    case 0x060 ... 0x1d4:
        cs = (addr - 0x060) / 0x30;
        addr -= cs * 0x30;
        f = s->cs_file + cs;
        switch (addr) {
        case 0x60:      /* GPMC_CONFIG1 */
            return f->config[0];
        case 0x64:      /* GPMC_CONFIG2 */
            return f->config[1];
        case 0x68:      /* GPMC_CONFIG3 */
            return f->config[2];
        case 0x6c:      /* GPMC_CONFIG4 */
            return f->config[3];
        case 0x70:      /* GPMC_CONFIG5 */
            return f->config[4];
        case 0x74:      /* GPMC_CONFIG6 */
            return f->config[5];
        case 0x78:      /* GPMC_CONFIG7 */
            return f->config[6];
        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                return omap_nand_read(f, 0, size);
            }
            return 0;
        }
        break;

    case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
        return s->prefetch.config1;
    case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
        return s->prefetch.transfercount;
    case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
        return s->prefetch.startengine;
    case 0x1f0:	/* GPMC_PREFETCH_STATUS */
        /* NB: The OMAP3 TRM is inconsistent about whether the GPMC
         * FIFOTHRESHOLDSTATUS bit should be set when
         * FIFOPOINTER > FIFOTHRESHOLD or when it is >= FIFOTHRESHOLD.
         * Apparently the underlying functional spec from which the TRM was
         * created states that the behaviour is ">=", and this also
         * makes more conceptual sense.
         */
        return (s->prefetch.fifopointer << 24) |
                ((s->prefetch.fifopointer >=
                  ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
                s->prefetch.count;

    case 0x1f4:	/* GPMC_ECC_CONFIG */
        return s->ecc_cs;
    case 0x1f8:	/* GPMC_ECC_CONTROL */
        return s->ecc_ptr;
    case 0x1fc:	/* GPMC_ECC_SIZE_CONFIG */
        return s->ecc_cfg;
    case 0x200 ... 0x220:	/* GPMC_ECC_RESULT */
        cs = (addr & 0x1f) >> 2;
        /* TODO: check correctness */
        return
                ((s->ecc[cs].cp    &  0x07) <<  0) |
                ((s->ecc[cs].cp    &  0x38) << 13) |
                ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
                ((s->ecc[cs].lp[1] & 0x1ff) << 19);

    case 0x230:	/* GPMC_TESTMODE_CTRL */
        return 0;
    case 0x234:	/* GPMC_PSA_LSB */
    case 0x238:	/* GPMC_PSA_MSB */
        return 0x00000000;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
                            uint64_t value, unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    int cs;
    struct omap_gpmc_cs_file_s *f;

    if (size != 4 && gpmc_wordaccess_only(addr)) {
        return omap_badwidth_write32(opaque, addr, value);
    }

    switch (addr) {
    case 0x000:	/* GPMC_REVISION */
    case 0x014:	/* GPMC_SYSSTATUS */
    case 0x054:	/* GPMC_STATUS */
    case 0x1f0:	/* GPMC_PREFETCH_STATUS */
    case 0x200 ... 0x220:	/* GPMC_ECC_RESULT */
    case 0x234:	/* GPMC_PSA_LSB */
    case 0x238:	/* GPMC_PSA_MSB */
        OMAP_RO_REG(addr);
        break;

    case 0x010:	/* GPMC_SYSCONFIG */
        if ((value >> 3) == 0x3)
            fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n",
                            __FUNCTION__, value >> 3);
        if (value & 2)
            omap_gpmc_reset(s);
        s->sysconfig = value & 0x19;
        break;

    case 0x018:	/* GPMC_IRQSTATUS */
        s->irqst &= ~value;
        omap_gpmc_int_update(s);
        break;

    case 0x01c:	/* GPMC_IRQENABLE */
        s->irqen = value & 0xf03;
        omap_gpmc_int_update(s);
        break;

    case 0x040:	/* GPMC_TIMEOUT_CONTROL */
        s->timeout = value & 0x1ff1;
        break;

    case 0x044:	/* GPMC_ERR_ADDRESS */
    case 0x048:	/* GPMC_ERR_TYPE */
        break;

    case 0x050:	/* GPMC_CONFIG */
        s->config = value & 0xf13;
        break;

    case 0x060 ... 0x1d4:
        cs = (addr - 0x060) / 0x30;
        addr -= cs * 0x30;
        f = s->cs_file + cs;
        switch (addr) {
        case 0x60:      /* GPMC_CONFIG1 */
            f->config[0] = value & 0xffef3e13;
            break;
        case 0x64:      /* GPMC_CONFIG2 */
            f->config[1] = value & 0x001f1f8f;
            break;
        case 0x68:      /* GPMC_CONFIG3 */
            f->config[2] = value & 0x001f1f8f;
            break;
        case 0x6c:      /* GPMC_CONFIG4 */
            f->config[3] = value & 0x1f8f1f8f;
            break;
        case 0x70:      /* GPMC_CONFIG5 */
            f->config[4] = value & 0x0f1f1f1f;
            break;
        case 0x74:      /* GPMC_CONFIG6 */
            f->config[5] = value & 0x00000fcf;
            break;
        case 0x78:      /* GPMC_CONFIG7 */
            if ((f->config[6] ^ value) & 0xf7f) {
                omap_gpmc_cs_unmap(s, cs);
                f->config[6] = value & 0x00000f7f;
                omap_gpmc_cs_map(s, cs);
            }
            break;
        case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */
                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
            }
            break;
        case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */
                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
            }
            break;
        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                omap_nand_write(f, 0, value, size);
            }
            break;
        default:
            goto bad_reg;
        }
        break;

    case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
        if (!s->prefetch.startengine) {
            uint32_t oldconfig1 = s->prefetch.config1;
            uint32_t changed;
            s->prefetch.config1 = value & 0x7f8f7fbf;
            changed = oldconfig1 ^ s->prefetch.config1;
            if (changed & (0x80 | 0x7000000)) {
                /* Turning the engine on or off, or mapping it somewhere else.
                 * cs_map() and cs_unmap() check the prefetch config and
                 * overall CSVALID bits, so it is sufficient to unmap-and-map
                 * both the old cs and the new one.
                 */
                int oldcs = prefetch_cs(oldconfig1);
                int newcs = prefetch_cs(s->prefetch.config1);
                omap_gpmc_cs_unmap(s, oldcs);
                omap_gpmc_cs_map(s, oldcs);
                if (newcs != oldcs) {
                    omap_gpmc_cs_unmap(s, newcs);
                    omap_gpmc_cs_map(s, newcs);
                }
            }
        }
        break;

    case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
        if (!s->prefetch.startengine) {
            s->prefetch.transfercount = value & 0x3fff;
        }
        break;

    case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
        if (s->prefetch.startengine != (value & 1)) {
            s->prefetch.startengine = value & 1;
            if (s->prefetch.startengine) {
                /* Prefetch engine start */
                s->prefetch.count = s->prefetch.transfercount;
                if (s->prefetch.config1 & 1) {
                    /* Write */
                    s->prefetch.fifopointer = 64;
                } else {
                    /* Read */
                    s->prefetch.fifopointer = 0;
                    fill_prefetch_fifo(s);
                }
            } else {
                /* Prefetch engine forcibly stopped. The TRM
                 * doesn't define the behaviour if you do this.
                 * We clear the prefetch count, which means that
                 * we permit no more writes, and don't read any
                 * more data from NAND. The CPU can still drain
                 * the FIFO of unread data.
                 */
                s->prefetch.count = 0;
            }
            omap_gpmc_int_update(s);
        }
        break;

    case 0x1f4:	/* GPMC_ECC_CONFIG */
        s->ecc_cs = 0x8f;
        break;
    case 0x1f8:	/* GPMC_ECC_CONTROL */
        if (value & (1 << 8))
            for (cs = 0; cs < 9; cs ++)
                ecc_reset(&s->ecc[cs]);
        s->ecc_ptr = value & 0xf;
        if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
            s->ecc_ptr = 0;
            s->ecc_cs &= ~1;
        }
        break;
    case 0x1fc:	/* GPMC_ECC_SIZE_CONFIG */
        s->ecc_cfg = value & 0x3fcff1ff;
        break;
    case 0x230:	/* GPMC_TESTMODE_CTRL */
        if (value & 7)
            fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
        break;

    default:
    bad_reg:
        OMAP_BAD_REG(addr);
        return;
    }
}

static const MemoryRegionOps omap_gpmc_ops = {
    .read = omap_gpmc_read,
    .write = omap_gpmc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
                                   target_phys_addr_t base,
                                   qemu_irq irq, qemu_irq drq)
{
    int cs;
    struct omap_gpmc_s *s = (struct omap_gpmc_s *)
            g_malloc0(sizeof(struct omap_gpmc_s));

    memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
    memory_region_add_subregion(get_system_memory(), base, &s->iomem);

    s->irq = irq;
    s->drq = drq;
    s->accept_256 = cpu_is_omap3630(mpu);
    s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
    s->lastirq = 0;
    omap_gpmc_reset(s);

    /* We have to register a different IO memory handler for each
     * chip select region in case a NAND device is mapped there. We
     * make the region the worst-case size of 256MB and rely on the
     * container memory region in cs_map to chop it down to the actual
     * guest-requested size.
     */
    for (cs = 0; cs < 8; cs++) {
        memory_region_init_io(&s->cs_file[cs].nandiomem,
                              &omap_nand_ops,
                              &s->cs_file[cs],
                              "omap-nand",
                              256 * 1024 * 1024);
    }

    memory_region_init_io(&s->prefetch.iomem, &omap_prefetch_ops, s,
                          "omap-gpmc-prefetch", 256 * 1024 * 1024);
    return s;
}

void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
{
    struct omap_gpmc_cs_file_s *f;
    assert(iomem);

    if (cs < 0 || cs >= 8) {
        fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
        exit(-1);
    }
    f = &s->cs_file[cs];

    omap_gpmc_cs_unmap(s, cs);
    f->config[0] &= ~(0xf << 10);
    f->iomem = iomem;
    omap_gpmc_cs_map(s, cs);
}

void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand)
{
    struct omap_gpmc_cs_file_s *f;
    assert(nand);

    if (cs < 0 || cs >= 8) {
        fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
        exit(-1);
    }
    f = &s->cs_file[cs];

    omap_gpmc_cs_unmap(s, cs);
    f->config[0] &= ~(0xf << 10);
    f->config[0] |= (OMAP_GPMC_NAND << 10);
    f->dev = nand;
    if (nand_getbuswidth(f->dev) == 16) {
        f->config[0] |= OMAP_GPMC_16BIT << 12;
    }
    omap_gpmc_cs_map(s, cs);
}
