/*
 * TI OMAP processor's Multichannel SPI emulation.
 *
 * Copyright (C) 2007-2009 Nokia Corporation
 *
 * Original code for OMAP2 by Andrzej Zaborowski <andrew@openedhand.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 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "hw.h"
#include "omap.h"

/* Multichannel SPI */
struct omap_mcspi_s {
    qemu_irq irq;
    int chnum;

    uint32_t sysconfig;
    uint32_t systest;
    uint32_t irqst;
    uint32_t irqen;
    uint32_t wken;
    uint32_t control;

    struct omap_mcspi_ch_s {
        qemu_irq txdrq;
        qemu_irq rxdrq;
        uint32_t (*txrx)(void *opaque, uint32_t, int);
        void *opaque;

        uint32_t tx;
        uint32_t rx;

        uint32_t config;
        uint32_t status;
        uint32_t control;
    } ch[4];
};

static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
{
    qemu_set_irq(s->irq, s->irqst & s->irqen);
}

static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch)
{
    qemu_set_irq(ch->txdrq,
                    (ch->control & 1) &&		/* EN */
                    (ch->config & (1 << 14)) &&		/* DMAW */
                    (ch->status & (1 << 1)) &&		/* TXS */
                    ((ch->config >> 12) & 3) != 1);	/* TRM */
    qemu_set_irq(ch->rxdrq,
                    (ch->control & 1) &&		/* EN */
                    (ch->config & (1 << 15)) &&		/* DMAW */
                    (ch->status & (1 << 0)) &&		/* RXS */
                    ((ch->config >> 12) & 3) != 2);	/* TRM */
}

static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
{
    struct omap_mcspi_ch_s *ch = s->ch + chnum;

    if (!(ch->control & 1))				/* EN */
        return;
    if ((ch->status & (1 << 0)) &&			/* RXS */
                    ((ch->config >> 12) & 3) != 2 &&	/* TRM */
                    !(ch->config & (1 << 19)))		/* TURBO */
        goto intr_update;
    if ((ch->status & (1 << 1)) &&			/* TXS */
                    ((ch->config >> 12) & 3) != 1)	/* TRM */
        goto intr_update;

    if (!(s->control & 1) ||				/* SINGLE */
                    (ch->config & (1 << 20))) {		/* FORCE */
        if (ch->txrx)
            ch->rx = ch->txrx(ch->opaque, ch->tx,	/* WL */
                            1 + (0x1f & (ch->config >> 7)));
    }

    ch->tx = 0;
    ch->status |= 1 << 2;				/* EOT */
    ch->status |= 1 << 1;				/* TXS */
    if (((ch->config >> 12) & 3) != 2)			/* TRM */
        ch->status |= 1 << 0;				/* RXS */

intr_update:
    if ((ch->status & (1 << 0)) &&			/* RXS */
                    ((ch->config >> 12) & 3) != 2 &&	/* TRM */
                    !(ch->config & (1 << 19)))		/* TURBO */
        s->irqst |= 1 << (2 + 4 * chnum);		/* RX_FULL */
    if ((ch->status & (1 << 1)) &&			/* TXS */
                    ((ch->config >> 12) & 3) != 1)	/* TRM */
        s->irqst |= 1 << (0 + 4 * chnum);		/* TX_EMPTY */
    omap_mcspi_interrupt_update(s);
    omap_mcspi_dmarequest_update(ch);
}

void omap_mcspi_reset(struct omap_mcspi_s *s)
{
    int ch;

    s->sysconfig = 0;
    s->systest = 0;
    s->irqst = 0;
    s->irqen = 0;
    s->wken = 0;
    s->control = 4;

    for (ch = 0; ch < 4; ch ++) {
        s->ch[ch].config = 0x060000;
        s->ch[ch].status = 2;				/* TXS */
        s->ch[ch].control = 0;

        omap_mcspi_dmarequest_update(s->ch + ch);
    }

    omap_mcspi_interrupt_update(s);
}

static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr)
{
    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
    int ch = 0;
    uint32_t ret;

    switch (addr) {
    case 0x00:	/* MCSPI_REVISION */
        return 0x91;

    case 0x10:	/* MCSPI_SYSCONFIG */
        return s->sysconfig;

    case 0x14:	/* MCSPI_SYSSTATUS */
        return 1;					/* RESETDONE */

    case 0x18:	/* MCSPI_IRQSTATUS */
        return s->irqst;

    case 0x1c:	/* MCSPI_IRQENABLE */
        return s->irqen;

    case 0x20:	/* MCSPI_WAKEUPENABLE */
        return s->wken;

    case 0x24:	/* MCSPI_SYST */
        return s->systest;

    case 0x28:	/* MCSPI_MODULCTRL */
        return s->control;

    case 0x68: ch ++;
    case 0x54: ch ++;
    case 0x40: ch ++;
    case 0x2c:	/* MCSPI_CHCONF */
        return s->ch[ch].config;

    case 0x6c: ch ++;
    case 0x58: ch ++;
    case 0x44: ch ++;
    case 0x30:	/* MCSPI_CHSTAT */
        return s->ch[ch].status;

    case 0x70: ch ++;
    case 0x5c: ch ++;
    case 0x48: ch ++;
    case 0x34:	/* MCSPI_CHCTRL */
        return s->ch[ch].control;

    case 0x74: ch ++;
    case 0x60: ch ++;
    case 0x4c: ch ++;
    case 0x38:	/* MCSPI_TX */
        return s->ch[ch].tx;

    case 0x78: ch ++;
    case 0x64: ch ++;
    case 0x50: ch ++;
    case 0x3c:	/* MCSPI_RX */
        s->ch[ch].status &= ~(1 << 0);			/* RXS */
        ret = s->ch[ch].rx;
        omap_mcspi_transfer_run(s, ch);
        return ret;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap_mcspi_write(void *opaque, target_phys_addr_t addr,
                uint32_t value)
{
    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
    int ch = 0;

    switch (addr) {
    case 0x00:	/* MCSPI_REVISION */
    case 0x14:	/* MCSPI_SYSSTATUS */
    case 0x30:	/* MCSPI_CHSTAT0 */
    case 0x3c:	/* MCSPI_RX0 */
    case 0x44:	/* MCSPI_CHSTAT1 */
    case 0x50:	/* MCSPI_RX1 */
    case 0x58:	/* MCSPI_CHSTAT2 */
    case 0x64:	/* MCSPI_RX2 */
    case 0x6c:	/* MCSPI_CHSTAT3 */
    case 0x78:	/* MCSPI_RX3 */
        OMAP_RO_REG(addr);
        return;

    case 0x10:	/* MCSPI_SYSCONFIG */
        if (value & (1 << 1))				/* SOFTRESET */
            omap_mcspi_reset(s);
        s->sysconfig = value & 0x31d;
        break;

    case 0x18:	/* MCSPI_IRQSTATUS */
        if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
            s->irqst &= ~value;
            omap_mcspi_interrupt_update(s);
        }
        break;

    case 0x1c:	/* MCSPI_IRQENABLE */
        s->irqen = value & 0x1777f;
        omap_mcspi_interrupt_update(s);
        break;

    case 0x20:	/* MCSPI_WAKEUPENABLE */
        s->wken = value & 1;
        break;

    case 0x24:	/* MCSPI_SYST */
        if (s->control & (1 << 3))			/* SYSTEM_TEST */
            if (value & (1 << 11)) {			/* SSB */
                s->irqst |= 0x1777f;
                omap_mcspi_interrupt_update(s);
            }
        s->systest = value & 0xfff;
        break;

    case 0x28:	/* MCSPI_MODULCTRL */
        if (value & (1 << 3))				/* SYSTEM_TEST */
            if (s->systest & (1 << 11)) {		/* SSB */
                s->irqst |= 0x1777f;
                omap_mcspi_interrupt_update(s);
            }
        s->control = value & 0xf;
        break;

    case 0x68: ch ++;
    case 0x54: ch ++;
    case 0x40: ch ++;
    case 0x2c:	/* MCSPI_CHCONF */
        if ((value ^ s->ch[ch].config) & (3 << 14))	/* DMAR | DMAW */
            omap_mcspi_dmarequest_update(s->ch + ch);
        if (((value >> 12) & 3) == 3)			/* TRM */
            fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
        if (((value >> 7) & 0x1f) < 3)			/* WL */
            fprintf(stderr, "%s: invalid WL value (%i)\n",
                            __FUNCTION__, (value >> 7) & 0x1f);
        s->ch[ch].config = value & 0x7fffff;
        break;

    case 0x70: ch ++;
    case 0x5c: ch ++;
    case 0x48: ch ++;
    case 0x34:	/* MCSPI_CHCTRL */
        if (value & ~s->ch[ch].control & 1) {		/* EN */
            s->ch[ch].control |= 1;
            omap_mcspi_transfer_run(s, ch);
        } else
            s->ch[ch].control = value & 1;
        break;

    case 0x74: ch ++;
    case 0x60: ch ++;
    case 0x4c: ch ++;
    case 0x38:	/* MCSPI_TX */
        s->ch[ch].tx = value;
        s->ch[ch].status &= ~(1 << 1);			/* TXS */
        omap_mcspi_transfer_run(s, ch);
        break;

    default:
        OMAP_BAD_REG(addr);
        return;
    }
}

static CPUReadMemoryFunc * const omap_mcspi_readfn[] = {
    omap_badwidth_read32,
    omap_badwidth_read32,
    omap_mcspi_read,
};

static CPUWriteMemoryFunc * const omap_mcspi_writefn[] = {
    omap_badwidth_write32,
    omap_badwidth_write32,
    omap_mcspi_write,
};

struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
                qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
{
    int iomemtype;
    struct omap_mcspi_s *s = (struct omap_mcspi_s *)
            qemu_mallocz(sizeof(struct omap_mcspi_s));
    struct omap_mcspi_ch_s *ch = s->ch;

    s->irq = irq;
    s->chnum = chnum;
    while (chnum --) {
        ch->txdrq = *drq ++;
        ch->rxdrq = *drq ++;
        ch ++;
    }
    omap_mcspi_reset(s);

    iomemtype = l4_register_io_memory(omap_mcspi_readfn,
                    omap_mcspi_writefn, s);
    omap_l4_attach(ta, 0, iomemtype);

    return s;
}

void omap_mcspi_attach(struct omap_mcspi_s *s,
                uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
                int chipselect)
{
    if (chipselect < 0 || chipselect >= s->chnum)
        hw_error("%s: Bad chipselect %i\n", __FUNCTION__, chipselect);

    s->ch[chipselect].txrx = txrx;
    s->ch[chipselect].opaque = opaque;
}
