/*
 * PXA270-based Intel Mainstone platforms.
 * FPGA driver
 *
 * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
 *                                    <akuster@mvista.com>
 *
 * This code is licensed under the GNU GPL v2.
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
 */

#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/module.h"

/* Mainstone FPGA for extern irqs */
#define FPGA_GPIO_PIN	0
#define MST_NUM_IRQS	16
#define MST_LEDDAT1		0x10
#define MST_LEDDAT2		0x14
#define MST_LEDCTRL		0x40
#define MST_GPSWR		0x60
#define MST_MSCWR1		0x80
#define MST_MSCWR2		0x84
#define MST_MSCWR3		0x88
#define MST_MSCRD		0x90
#define MST_INTMSKENA	0xc0
#define MST_INTSETCLR	0xd0
#define MST_PCMCIA0		0xe0
#define MST_PCMCIA1		0xe4

#define MST_PCMCIAx_READY	(1 << 10)
#define MST_PCMCIAx_nCD		(1 << 5)

#define MST_PCMCIA_CD0_IRQ	9
#define MST_PCMCIA_CD1_IRQ	13

#define TYPE_MAINSTONE_FPGA "mainstone-fpga"
#define MAINSTONE_FPGA(obj) \
    OBJECT_CHECK(mst_irq_state, (obj), TYPE_MAINSTONE_FPGA)

typedef struct mst_irq_state{
    SysBusDevice parent_obj;

    MemoryRegion iomem;

    qemu_irq parent;

    uint32_t prev_level;
    uint32_t leddat1;
    uint32_t leddat2;
    uint32_t ledctrl;
    uint32_t gpswr;
    uint32_t mscwr1;
    uint32_t mscwr2;
    uint32_t mscwr3;
    uint32_t mscrd;
    uint32_t intmskena;
    uint32_t intsetclr;
    uint32_t pcmcia0;
    uint32_t pcmcia1;
}mst_irq_state;

static void
mst_fpga_set_irq(void *opaque, int irq, int level)
{
	mst_irq_state *s = (mst_irq_state *)opaque;
	uint32_t oldint = s->intsetclr & s->intmskena;

	if (level)
		s->prev_level |= 1u << irq;
	else
		s->prev_level &= ~(1u << irq);

	switch(irq) {
	case MST_PCMCIA_CD0_IRQ:
		if (level)
			s->pcmcia0 &= ~MST_PCMCIAx_nCD;
		else
			s->pcmcia0 |=  MST_PCMCIAx_nCD;
		break;
	case MST_PCMCIA_CD1_IRQ:
		if (level)
			s->pcmcia1 &= ~MST_PCMCIAx_nCD;
		else
			s->pcmcia1 |=  MST_PCMCIAx_nCD;
		break;
	}

	if ((s->intmskena & (1u << irq)) && level)
		s->intsetclr |= 1u << irq;

	if (oldint != (s->intsetclr & s->intmskena))
		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
}


static uint64_t
mst_fpga_readb(void *opaque, hwaddr addr, unsigned size)
{
	mst_irq_state *s = (mst_irq_state *) opaque;

	switch (addr) {
	case MST_LEDDAT1:
		return s->leddat1;
	case MST_LEDDAT2:
		return s->leddat2;
	case MST_LEDCTRL:
		return s->ledctrl;
	case MST_GPSWR:
		return s->gpswr;
	case MST_MSCWR1:
		return s->mscwr1;
	case MST_MSCWR2:
		return s->mscwr2;
	case MST_MSCWR3:
		return s->mscwr3;
	case MST_MSCRD:
		return s->mscrd;
	case MST_INTMSKENA:
		return s->intmskena;
	case MST_INTSETCLR:
		return s->intsetclr;
	case MST_PCMCIA0:
		return s->pcmcia0;
	case MST_PCMCIA1:
		return s->pcmcia1;
	default:
		printf("Mainstone - mst_fpga_readb: Bad register offset "
			"0x" TARGET_FMT_plx "\n", addr);
	}
	return 0;
}

static void
mst_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
		unsigned size)
{
	mst_irq_state *s = (mst_irq_state *) opaque;
	value &= 0xffffffff;

	switch (addr) {
	case MST_LEDDAT1:
		s->leddat1 = value;
		break;
	case MST_LEDDAT2:
		s->leddat2 = value;
		break;
	case MST_LEDCTRL:
		s->ledctrl = value;
		break;
	case MST_GPSWR:
		s->gpswr = value;
		break;
	case MST_MSCWR1:
		s->mscwr1 = value;
		break;
	case MST_MSCWR2:
		s->mscwr2 = value;
		break;
	case MST_MSCWR3:
		s->mscwr3 = value;
		break;
	case MST_MSCRD:
		s->mscrd =  value;
		break;
	case MST_INTMSKENA:	/* Mask interrupt */
		s->intmskena = (value & 0xFEEFF);
		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
		break;
	case MST_INTSETCLR:	/* clear or set interrupt */
		s->intsetclr = (value & 0xFEEFF);
		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
		break;
		/* For PCMCIAx allow the to change only power and reset */
	case MST_PCMCIA0:
		s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f);
		break;
	case MST_PCMCIA1:
		s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f);
		break;
	default:
		printf("Mainstone - mst_fpga_writeb: Bad register offset "
			"0x" TARGET_FMT_plx "\n", addr);
	}
}

static const MemoryRegionOps mst_fpga_ops = {
	.read = mst_fpga_readb,
	.write = mst_fpga_writeb,
	.endianness = DEVICE_NATIVE_ENDIAN,
};

static int mst_fpga_post_load(void *opaque, int version_id)
{
	mst_irq_state *s = (mst_irq_state *) opaque;

	qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
	return 0;
}

static void mst_fpga_init(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
    mst_irq_state *s = MAINSTONE_FPGA(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
    s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;

    sysbus_init_irq(sbd, &s->parent);

    /* alloc the external 16 irqs */
    qdev_init_gpio_in(dev, mst_fpga_set_irq, MST_NUM_IRQS);

    memory_region_init_io(&s->iomem, obj, &mst_fpga_ops, s,
                          "fpga", 0x00100000);
    sysbus_init_mmio(sbd, &s->iomem);
}

static VMStateDescription vmstate_mst_fpga_regs = {
    .name = "mainstone_fpga",
    .version_id = 0,
    .minimum_version_id = 0,
    .post_load = mst_fpga_post_load,
    .fields = (VMStateField[]) {
		VMSTATE_UINT32(prev_level, mst_irq_state),
		VMSTATE_UINT32(leddat1, mst_irq_state),
		VMSTATE_UINT32(leddat2, mst_irq_state),
		VMSTATE_UINT32(ledctrl, mst_irq_state),
		VMSTATE_UINT32(gpswr, mst_irq_state),
		VMSTATE_UINT32(mscwr1, mst_irq_state),
		VMSTATE_UINT32(mscwr2, mst_irq_state),
		VMSTATE_UINT32(mscwr3, mst_irq_state),
		VMSTATE_UINT32(mscrd, mst_irq_state),
		VMSTATE_UINT32(intmskena, mst_irq_state),
		VMSTATE_UINT32(intsetclr, mst_irq_state),
		VMSTATE_UINT32(pcmcia0, mst_irq_state),
		VMSTATE_UINT32(pcmcia1, mst_irq_state),
		VMSTATE_END_OF_LIST(),
	},
};

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

    dc->desc = "Mainstone II FPGA";
    dc->vmsd = &vmstate_mst_fpga_regs;
}

static const TypeInfo mst_fpga_info = {
    .name          = TYPE_MAINSTONE_FPGA,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(mst_irq_state),
    .instance_init = mst_fpga_init,
    .class_init    = mst_fpga_class_init,
};

static void mst_fpga_register_types(void)
{
    type_register_static(&mst_fpga_info);
}

type_init(mst_fpga_register_types)
