/*
 * Samsung exynos4210 Interrupt Combiner
 *
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 * All rights reserved.
 *
 * Evgeny Voevodin <e.voevodin@samsung.com>
 *
 * 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 of the License, or (at your
 * option) any later version.
 *
 * 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/>.
 */

/*
 * Exynos4210 Combiner represents an OR gate for SOC's IRQ lines. It combines
 * IRQ sources into groups and provides signal output to GIC from each group. It
 * is driven by common mask and enable/disable logic. Take a note that not all
 * IRQs are passed to GIC through Combiner.
 */

#include "sysbus.h"

#include "exynos4210.h"

//#define DEBUG_COMBINER

#ifdef DEBUG_COMBINER
#define DPRINTF(fmt, ...) \
        do { fprintf(stdout, "COMBINER: [%s:%d] " fmt, __func__ , __LINE__, \
                ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) do {} while (0)
#endif

#define    IIC_NGRP        64            /* Internal Interrupt Combiner
                                            Groups number */
#define    IIC_NIRQ        (IIC_NGRP * 8)/* Internal Interrupt Combiner
                                            Interrupts number */
#define IIC_REGION_SIZE    0x108         /* Size of memory mapped region */
#define IIC_REGSET_SIZE    0x41

/*
 * State for each output signal of internal combiner
 */
typedef struct CombinerGroupState {
    uint8_t src_mask;            /* 1 - source enabled, 0 - disabled */
    uint8_t src_pending;        /* Pending source interrupts before masking */
} CombinerGroupState;

typedef struct Exynos4210CombinerState {
    SysBusDevice busdev;
    MemoryRegion iomem;

    struct CombinerGroupState group[IIC_NGRP];
    uint32_t reg_set[IIC_REGSET_SIZE];
    uint32_t icipsr[2];
    uint32_t external;          /* 1 means that this combiner is external */

    qemu_irq output_irq[IIC_NGRP];
} Exynos4210CombinerState;

static const VMStateDescription vmstate_exynos4210_combiner_group_state = {
    .name = "exynos4210.combiner.groupstate",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(src_mask, CombinerGroupState),
        VMSTATE_UINT8(src_pending, CombinerGroupState),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_exynos4210_combiner = {
    .name = "exynos4210.combiner",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT_ARRAY(group, Exynos4210CombinerState, IIC_NGRP, 0,
                vmstate_exynos4210_combiner_group_state, CombinerGroupState),
        VMSTATE_UINT32_ARRAY(reg_set, Exynos4210CombinerState,
                IIC_REGSET_SIZE),
        VMSTATE_UINT32_ARRAY(icipsr, Exynos4210CombinerState, 2),
        VMSTATE_UINT32(external, Exynos4210CombinerState),
        VMSTATE_END_OF_LIST()
    }
};

/*
 * Get Combiner input GPIO into irqs structure
 */
void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
        int ext)
{
    int n;
    int bit;
    int max;
    qemu_irq *irq;

    max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
        EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
    irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;

    /*
     * Some IRQs of Int/External Combiner are going to two Combiners groups,
     * so let split them.
     */
    for (n = 0; n < max; n++) {

        bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);

        switch (n) {
        /* MDNIE_LCD1 INTG1 */
        case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
             EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
            irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
                    irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
            continue;

        /* TMU INTG3 */
        case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
            irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
                    irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
            continue;

        /* LCD1 INTG12 */
        case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
             EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
            irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
                    irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
            continue;

        /* Multi-Core Timer INTG12 */
        case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
             EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
               irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
                       irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
            continue;

        /* Multi-Core Timer INTG35 */
        case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
             EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
            irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
                    irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
            continue;

        /* Multi-Core Timer INTG51 */
        case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
             EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
            irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
                    irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
            continue;

        /* Multi-Core Timer INTG53 */
        case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
             EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
            irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
                    irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
            continue;
        }

        irq[n] = qdev_get_gpio_in(dev, n);
    }
}

static uint64_t
exynos4210_combiner_read(void *opaque, target_phys_addr_t offset, unsigned size)
{
    struct Exynos4210CombinerState *s =
            (struct Exynos4210CombinerState *)opaque;
    uint32_t req_quad_base_n;    /* Base of registers quad. Multiply it by 4 and
                                   get a start of corresponding group quad */
    uint32_t grp_quad_base_n;    /* Base of group quad */
    uint32_t reg_n;              /* Register number inside the quad */
    uint32_t val;

    if (s->external && (offset > 0x3c && offset != 0x100)) {
        hw_error("exynos4210.combiner: unallowed read access at offset 0x"
                TARGET_FMT_plx "\n", offset);
    }

    req_quad_base_n = offset >> 4;
    grp_quad_base_n = req_quad_base_n << 2;
    reg_n = (offset - (req_quad_base_n << 4)) >> 2;

    if (req_quad_base_n >= IIC_NGRP) {
        /* Read of ICIPSR register */
        return s->icipsr[reg_n];
    }

    val = 0;

    switch (reg_n) {
    /* IISTR */
    case 2:
        val |= s->group[grp_quad_base_n].src_pending;
        val |= s->group[grp_quad_base_n + 1].src_pending << 8;
        val |= s->group[grp_quad_base_n + 2].src_pending << 16;
        val |= s->group[grp_quad_base_n + 3].src_pending << 24;
        break;
    /* IIMSR */
    case 3:
        val |= s->group[grp_quad_base_n].src_mask &
        s->group[grp_quad_base_n].src_pending;
        val |= (s->group[grp_quad_base_n + 1].src_mask &
                s->group[grp_quad_base_n + 1].src_pending) << 8;
        val |= (s->group[grp_quad_base_n + 2].src_mask &
                s->group[grp_quad_base_n + 2].src_pending) << 16;
        val |= (s->group[grp_quad_base_n + 3].src_mask &
                s->group[grp_quad_base_n + 3].src_pending) << 24;
        break;
    default:
        if (offset >> 2 >= IIC_REGSET_SIZE) {
            hw_error("exynos4210.combiner: overflow of reg_set by 0x"
                    TARGET_FMT_plx "offset\n", offset);
        }
        val = s->reg_set[offset >> 2];
        return 0;
    }
    return val;
}

static void exynos4210_combiner_update(void *opaque, uint8_t group_n)
{
    struct Exynos4210CombinerState *s =
            (struct Exynos4210CombinerState *)opaque;

    /* Send interrupt if needed */
    if (s->group[group_n].src_mask & s->group[group_n].src_pending) {
#ifdef DEBUG_COMBINER
        if (group_n != 26) {
            /* skip uart */
            DPRINTF("%s raise IRQ[%d]\n", s->external ? "EXT" : "INT", group_n);
        }
#endif

        /* Set Combiner interrupt pending status after masking */
        if (group_n >= 32) {
            s->icipsr[1] |= 1 << (group_n - 32);
        } else {
            s->icipsr[0] |= 1 << group_n;
        }

        qemu_irq_raise(s->output_irq[group_n]);
    } else {
#ifdef DEBUG_COMBINER
        if (group_n != 26) {
            /* skip uart */
            DPRINTF("%s lower IRQ[%d]\n", s->external ? "EXT" : "INT", group_n);
        }
#endif

        /* Set Combiner interrupt pending status after masking */
        if (group_n >= 32) {
            s->icipsr[1] &= ~(1 << (group_n - 32));
        } else {
            s->icipsr[0] &= ~(1 << group_n);
        }

        qemu_irq_lower(s->output_irq[group_n]);
    }
}

static void exynos4210_combiner_write(void *opaque, target_phys_addr_t offset,
        uint64_t val, unsigned size)
{
    struct Exynos4210CombinerState *s =
            (struct Exynos4210CombinerState *)opaque;
    uint32_t req_quad_base_n;    /* Base of registers quad. Multiply it by 4 and
                                   get a start of corresponding group quad */
    uint32_t grp_quad_base_n;    /* Base of group quad */
    uint32_t reg_n;              /* Register number inside the quad */

    if (s->external && (offset > 0x3c && offset != 0x100)) {
        hw_error("exynos4210.combiner: unallowed write access at offset 0x"
                TARGET_FMT_plx "\n", offset);
    }

    req_quad_base_n = offset >> 4;
    grp_quad_base_n = req_quad_base_n << 2;
    reg_n = (offset - (req_quad_base_n << 4)) >> 2;

    if (req_quad_base_n >= IIC_NGRP) {
        hw_error("exynos4210.combiner: unallowed write access at offset 0x"
                TARGET_FMT_plx "\n", offset);
        return;
    }

    if (reg_n > 1) {
        hw_error("exynos4210.combiner: unallowed write access at offset 0x"
                TARGET_FMT_plx "\n", offset);
        return;
    }

    if (offset >> 2 >= IIC_REGSET_SIZE) {
        hw_error("exynos4210.combiner: overflow of reg_set by 0x"
                TARGET_FMT_plx "offset\n", offset);
    }
    s->reg_set[offset >> 2] = val;

    switch (reg_n) {
    /* IIESR */
    case 0:
        /* FIXME: what if irq is pending, allowed by mask, and we allow it
         * again. Interrupt will rise again! */

        DPRINTF("%s enable IRQ for groups %d, %d, %d, %d\n",
                s->external ? "EXT" : "INT",
                grp_quad_base_n,
                grp_quad_base_n + 1,
                grp_quad_base_n + 2,
                grp_quad_base_n + 3);

        /* Enable interrupt sources */
        s->group[grp_quad_base_n].src_mask |= val & 0xFF;
        s->group[grp_quad_base_n + 1].src_mask |= (val & 0xFF00) >> 8;
        s->group[grp_quad_base_n + 2].src_mask |= (val & 0xFF0000) >> 16;
        s->group[grp_quad_base_n + 3].src_mask |= (val & 0xFF000000) >> 24;

        exynos4210_combiner_update(s, grp_quad_base_n);
        exynos4210_combiner_update(s, grp_quad_base_n + 1);
        exynos4210_combiner_update(s, grp_quad_base_n + 2);
        exynos4210_combiner_update(s, grp_quad_base_n + 3);
        break;
        /* IIECR */
    case 1:
        DPRINTF("%s disable IRQ for groups %d, %d, %d, %d\n",
                s->external ? "EXT" : "INT",
                grp_quad_base_n,
                grp_quad_base_n + 1,
                grp_quad_base_n + 2,
                grp_quad_base_n + 3);

        /* Disable interrupt sources */
        s->group[grp_quad_base_n].src_mask &= ~(val & 0xFF);
        s->group[grp_quad_base_n + 1].src_mask &= ~((val & 0xFF00) >> 8);
        s->group[grp_quad_base_n + 2].src_mask &= ~((val & 0xFF0000) >> 16);
        s->group[grp_quad_base_n + 3].src_mask &= ~((val & 0xFF000000) >> 24);

        exynos4210_combiner_update(s, grp_quad_base_n);
        exynos4210_combiner_update(s, grp_quad_base_n + 1);
        exynos4210_combiner_update(s, grp_quad_base_n + 2);
        exynos4210_combiner_update(s, grp_quad_base_n + 3);
        break;
    default:
        hw_error("exynos4210.combiner: unallowed write access at offset 0x"
                TARGET_FMT_plx "\n", offset);
        break;
    }

    return;
}

/* Get combiner group and bit from irq number */
static uint8_t get_combiner_group_and_bit(int irq, uint8_t *bit)
{
    *bit = irq - ((irq >> 3) << 3);
    return irq >> 3;
}

/* Process a change in an external IRQ input.  */
static void exynos4210_combiner_handler(void *opaque, int irq, int level)
{
    struct Exynos4210CombinerState *s =
            (struct Exynos4210CombinerState *)opaque;
    uint8_t bit_n, group_n;

    group_n = get_combiner_group_and_bit(irq, &bit_n);

    if (s->external && group_n >= EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ) {
        DPRINTF("%s unallowed IRQ group 0x%x\n", s->external ? "EXT" : "INT"
                , group_n);
        return;
    }

    if (level) {
        s->group[group_n].src_pending |= 1 << bit_n;
    } else {
        s->group[group_n].src_pending &= ~(1 << bit_n);
    }

    exynos4210_combiner_update(s, group_n);

    return;
}

static void exynos4210_combiner_reset(DeviceState *d)
{
    struct Exynos4210CombinerState *s = (struct Exynos4210CombinerState *)d;

    memset(&s->group, 0, sizeof(s->group));
    memset(&s->reg_set, 0, sizeof(s->reg_set));

    s->reg_set[0xC0 >> 2] = 0x01010101;
    s->reg_set[0xC4 >> 2] = 0x01010101;
    s->reg_set[0xD0 >> 2] = 0x01010101;
    s->reg_set[0xD4 >> 2] = 0x01010101;
}

static const MemoryRegionOps exynos4210_combiner_ops = {
    .read = exynos4210_combiner_read,
    .write = exynos4210_combiner_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

/*
 * Internal Combiner initialization.
 */
static int exynos4210_combiner_init(SysBusDevice *dev)
{
    unsigned int i;
    struct Exynos4210CombinerState *s =
            FROM_SYSBUS(struct Exynos4210CombinerState, dev);

    /* Allocate general purpose input signals and connect a handler to each of
     * them */
    qdev_init_gpio_in(&s->busdev.qdev, exynos4210_combiner_handler, IIC_NIRQ);

    /* Connect SysBusDev irqs to device specific irqs */
    for (i = 0; i < IIC_NIRQ; i++) {
        sysbus_init_irq(dev, &s->output_irq[i]);
    }

    memory_region_init_io(&s->iomem, &exynos4210_combiner_ops, s,
            "exynos4210-combiner", IIC_REGION_SIZE);
    sysbus_init_mmio(dev, &s->iomem);

    return 0;
}

static Property exynos4210_combiner_properties[] = {
    DEFINE_PROP_UINT32("external", Exynos4210CombinerState, external, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void exynos4210_combiner_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = exynos4210_combiner_init;
    dc->reset = exynos4210_combiner_reset;
    dc->props = exynos4210_combiner_properties;
    dc->vmsd = &vmstate_exynos4210_combiner;
}

static TypeInfo exynos4210_combiner_info = {
    .name          = "exynos4210.combiner",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(Exynos4210CombinerState),
    .class_init    = exynos4210_combiner_class_init,
};

static void exynos4210_combiner_register_types(void)
{
    type_register_static(&exynos4210_combiner_info);
}

type_init(exynos4210_combiner_register_types)
