/*
 * OMAP on-chip MMC/SD host emulation.
 *
 * Copyright (C) 2006-2007 Andrzej Zaborowski  <balrog@zabor.org>
 *
 * 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) version 3 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"
#include "sd.h"

struct omap_mmc_s {
    qemu_irq irq;
    qemu_irq *dma;
    qemu_irq coverswitch;
    omap_clk clk;
    SDState *card;
    uint16_t last_cmd;
    uint16_t sdio;
    uint16_t rsp[8];
    uint32_t arg;
    int lines;
    int dw;
    int mode;
    int enable;
    int be;
    int rev;
    uint16_t status;
    uint16_t mask;
    uint8_t cto;
    uint16_t dto;
    int clkdiv;
    uint16_t fifo[32];
    int fifo_start;
    int fifo_len;
    uint16_t blen;
    uint16_t blen_counter;
    uint16_t nblk;
    uint16_t nblk_counter;
    int tx_dma;
    int rx_dma;
    int af_level;
    int ae_level;

    int ddir;
    int transfer;

    int cdet_wakeup;
    int cdet_enable;
    int cdet_state;
    qemu_irq cdet;
};

static void omap_mmc_interrupts_update(struct omap_mmc_s *s)
{
    qemu_set_irq(s->irq, !!(s->status & s->mask));
}

static void omap_mmc_fifolevel_update(struct omap_mmc_s *host)
{
    if (!host->transfer && !host->fifo_len) {
        host->status &= 0xf3ff;
        return;
    }

    if (host->fifo_len > host->af_level && host->ddir) {
        if (host->rx_dma) {
            host->status &= 0xfbff;
            qemu_irq_raise(host->dma[1]);
        } else
            host->status |= 0x0400;
    } else {
        host->status &= 0xfbff;
        qemu_irq_lower(host->dma[1]);
    }

    if (host->fifo_len < host->ae_level && !host->ddir) {
        if (host->tx_dma) {
            host->status &= 0xf7ff;
            qemu_irq_raise(host->dma[0]);
        } else
            host->status |= 0x0800;
    } else {
        qemu_irq_lower(host->dma[0]);
        host->status &= 0xf7ff;
    }
}

typedef enum {
    sd_nore = 0,	/* no response */
    sd_r1,		/* normal response command */
    sd_r2,		/* CID, CSD registers */
    sd_r3,		/* OCR register */
    sd_r6 = 6,		/* Published RCA response */
    sd_r1b = -1,
} sd_rsp_type_t;

static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
                sd_cmd_type_t type, int busy, sd_rsp_type_t resptype, int init)
{
    uint32_t rspstatus, mask;
    int rsplen, timeout;
    struct sd_request_s request;
    uint8_t response[16];

    if (init && cmd == 0) {
        host->status |= 0x0001;
        return;
    }

    if (resptype == sd_r1 && busy)
        resptype = sd_r1b;

    if (type == sd_adtc) {
        host->fifo_start = 0;
        host->fifo_len = 0;
        host->transfer = 1;
        host->ddir = dir;
    } else
        host->transfer = 0;
    timeout = 0;
    mask = 0;
    rspstatus = 0;

    request.cmd = cmd;
    request.arg = host->arg;
    request.crc = 0; /* FIXME */

    rsplen = sd_do_command(host->card, &request, response);

    /* TODO: validate CRCs */
    switch (resptype) {
    case sd_nore:
        rsplen = 0;
        break;

    case sd_r1:
    case sd_r1b:
        if (rsplen < 4) {
            timeout = 1;
            break;
        }
        rsplen = 4;

        mask = OUT_OF_RANGE | ADDRESS_ERROR | BLOCK_LEN_ERROR |
                ERASE_SEQ_ERROR | ERASE_PARAM | WP_VIOLATION |
                LOCK_UNLOCK_FAILED | COM_CRC_ERROR | ILLEGAL_COMMAND |
                CARD_ECC_FAILED | CC_ERROR | SD_ERROR |
                CID_CSD_OVERWRITE;
        if (host->sdio & (1 << 13))
            mask |= AKE_SEQ_ERROR;
        rspstatus = (response[0] << 24) | (response[1] << 16) |
                (response[2] << 8) | (response[3] << 0);
        break;

    case sd_r2:
        if (rsplen < 16) {
            timeout = 1;
            break;
        }
        rsplen = 16;
        break;

    case sd_r3:
        if (rsplen < 4) {
            timeout = 1;
            break;
        }
        rsplen = 4;

        rspstatus = (response[0] << 24) | (response[1] << 16) |
                (response[2] << 8) | (response[3] << 0);
        if (rspstatus & 0x80000000)
            host->status &= 0xe000;
        else
            host->status |= 0x1000;
        break;

    case sd_r6:
        if (rsplen < 4) {
            timeout = 1;
            break;
        }
        rsplen = 4;

        mask = 0xe000 | AKE_SEQ_ERROR;
        rspstatus = (response[2] << 8) | (response[3] << 0);
    }

    if (rspstatus & mask)
        host->status |= 0x4000;
    else
        host->status &= 0xb000;

    if (rsplen)
        for (rsplen = 0; rsplen < 8; rsplen ++)
            host->rsp[~rsplen & 7] = response[(rsplen << 1) | 1] |
                    (response[(rsplen << 1) | 0] << 8);

    if (timeout)
        host->status |= 0x0080;
    else if (cmd == 12)
        host->status |= 0x0005;	/* Makes it more real */
    else
        host->status |= 0x0001;
}

static void omap_mmc_transfer(struct omap_mmc_s *host)
{
    uint8_t value;

    if (!host->transfer)
        return;

    while (1) {
        if (host->ddir) {
            if (host->fifo_len > host->af_level)
                break;

            value = sd_read_data(host->card);
            host->fifo[(host->fifo_start + host->fifo_len) & 31] = value;
            if (-- host->blen_counter) {
                value = sd_read_data(host->card);
                host->fifo[(host->fifo_start + host->fifo_len) & 31] |=
                        value << 8;
                host->blen_counter --;
            }

            host->fifo_len ++;
        } else {
            if (!host->fifo_len)
                break;

            value = host->fifo[host->fifo_start] & 0xff;
            sd_write_data(host->card, value);
            if (-- host->blen_counter) {
                value = host->fifo[host->fifo_start] >> 8;
                sd_write_data(host->card, value);
                host->blen_counter --;
            }

            host->fifo_start ++;
            host->fifo_len --;
            host->fifo_start &= 31;
        }

        if (host->blen_counter == 0) {
            host->nblk_counter --;
            host->blen_counter = host->blen;

            if (host->nblk_counter == 0) {
                host->nblk_counter = host->nblk;
                host->transfer = 0;
                host->status |= 0x0008;
                break;
            }
        }
    }
}

static void omap_mmc_update(void *opaque)
{
    struct omap_mmc_s *s = opaque;
    omap_mmc_transfer(s);
    omap_mmc_fifolevel_update(s);
    omap_mmc_interrupts_update(s);
}

void omap_mmc_reset(struct omap_mmc_s *host)
{
    host->last_cmd = 0;
    memset(host->rsp, 0, sizeof(host->rsp));
    host->arg = 0;
    host->dw = 0;
    host->mode = 0;
    host->enable = 0;
    host->status = 0;
    host->mask = 0;
    host->cto = 0;
    host->dto = 0;
    host->fifo_len = 0;
    host->blen = 0;
    host->blen_counter = 0;
    host->nblk = 0;
    host->nblk_counter = 0;
    host->tx_dma = 0;
    host->rx_dma = 0;
    host->ae_level = 0x00;
    host->af_level = 0x1f;
    host->transfer = 0;
    host->cdet_wakeup = 0;
    host->cdet_enable = 0;
    qemu_set_irq(host->coverswitch, host->cdet_state);
    host->clkdiv = 0;
}

static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
{
    uint16_t i;
    struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
    offset &= OMAP_MPUI_REG_MASK;

    switch (offset) {
    case 0x00:	/* MMC_CMD */
        return s->last_cmd;

    case 0x04:	/* MMC_ARGL */
        return s->arg & 0x0000ffff;

    case 0x08:	/* MMC_ARGH */
        return s->arg >> 16;

    case 0x0c:	/* MMC_CON */
        return (s->dw << 15) | (s->mode << 12) | (s->enable << 11) | 
                (s->be << 10) | s->clkdiv;

    case 0x10:	/* MMC_STAT */
        return s->status;

    case 0x14:	/* MMC_IE */
        return s->mask;

    case 0x18:	/* MMC_CTO */
        return s->cto;

    case 0x1c:	/* MMC_DTO */
        return s->dto;

    case 0x20:	/* MMC_DATA */
        /* TODO: support 8-bit access */
        i = s->fifo[s->fifo_start];
        if (s->fifo_len == 0) {
            printf("MMC: FIFO underrun\n");
            return i;
        }
        s->fifo_start ++;
        s->fifo_len --;
        s->fifo_start &= 31;
        omap_mmc_transfer(s);
        omap_mmc_fifolevel_update(s);
        omap_mmc_interrupts_update(s);
        return i;

    case 0x24:	/* MMC_BLEN */
        return s->blen_counter;

    case 0x28:	/* MMC_NBLK */
        return s->nblk_counter;

    case 0x2c:	/* MMC_BUF */
        return (s->rx_dma << 15) | (s->af_level << 8) |
            (s->tx_dma << 7) | s->ae_level;

    case 0x30:	/* MMC_SPI */
        return 0x0000;
    case 0x34:	/* MMC_SDIO */
        return (s->cdet_wakeup << 2) | (s->cdet_enable) | s->sdio;
    case 0x38:	/* MMC_SYST */
        return 0x0000;

    case 0x3c:	/* MMC_REV */
        return s->rev;

    case 0x40:	/* MMC_RSP0 */
    case 0x44:	/* MMC_RSP1 */
    case 0x48:	/* MMC_RSP2 */
    case 0x4c:	/* MMC_RSP3 */
    case 0x50:	/* MMC_RSP4 */
    case 0x54:	/* MMC_RSP5 */
    case 0x58:	/* MMC_RSP6 */
    case 0x5c:	/* MMC_RSP7 */
        return s->rsp[(offset - 0x40) >> 2];

    /* OMAP2-specific */
    case 0x60:	/* MMC_IOSR */
    case 0x64:	/* MMC_SYSC */
        return 0;
    case 0x68:	/* MMC_SYSS */
        return 1;						/* RSTD */
    }

    OMAP_BAD_REG(offset);
    return 0;
}

static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
                uint32_t value)
{
    int i;
    struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
    offset &= OMAP_MPUI_REG_MASK;

    switch (offset) {
    case 0x00:	/* MMC_CMD */
        if (!s->enable)
            break;

        s->last_cmd = value;
        for (i = 0; i < 8; i ++)
            s->rsp[i] = 0x0000;
        omap_mmc_command(s, value & 63, (value >> 15) & 1,
                (sd_cmd_type_t) ((value >> 12) & 3),
                (value >> 11) & 1,
                (sd_rsp_type_t) ((value >> 8) & 7),
                (value >> 7) & 1);
        omap_mmc_update(s);
        break;

    case 0x04:	/* MMC_ARGL */
        s->arg &= 0xffff0000;
        s->arg |= 0x0000ffff & value;
        break;

    case 0x08:	/* MMC_ARGH */
        s->arg &= 0x0000ffff;
        s->arg |= value << 16;
        break;

    case 0x0c:	/* MMC_CON */
        s->dw = (value >> 15) & 1;
        s->mode = (value >> 12) & 3;
        s->enable = (value >> 11) & 1;
        s->be = (value >> 10) & 1;
        s->clkdiv = (value >> 0) & (s->rev >= 2 ? 0x3ff : 0xff);
        if (s->mode != 0)
            printf("SD mode %i unimplemented!\n", s->mode);
        if (s->be != 0)
            printf("SD FIFO byte sex unimplemented!\n");
        if (s->dw != 0 && s->lines < 4)
            printf("4-bit SD bus enabled\n");
        if (!s->enable)
            omap_mmc_reset(s);
        break;

    case 0x10:	/* MMC_STAT */
        s->status &= ~value;
        omap_mmc_interrupts_update(s);
        break;

    case 0x14:	/* MMC_IE */
        s->mask = value & 0x7fff;
        omap_mmc_interrupts_update(s);
        break;

    case 0x18:	/* MMC_CTO */
        s->cto = value & 0xff;
        if (s->cto > 0xfd && s->rev <= 1)
            printf("MMC: CTO of 0xff and 0xfe cannot be used!\n");
        break;

    case 0x1c:	/* MMC_DTO */
        s->dto = value & 0xffff;
        break;

    case 0x20:	/* MMC_DATA */
        /* TODO: support 8-bit access */
        if (s->fifo_len == 32)
            break;
        s->fifo[(s->fifo_start + s->fifo_len) & 31] = value;
        s->fifo_len ++;
        omap_mmc_transfer(s);
        omap_mmc_fifolevel_update(s);
        omap_mmc_interrupts_update(s);
        break;

    case 0x24:	/* MMC_BLEN */
        s->blen = (value & 0x07ff) + 1;
        s->blen_counter = s->blen;
        break;

    case 0x28:	/* MMC_NBLK */
        s->nblk = (value & 0x07ff) + 1;
        s->nblk_counter = s->nblk;
        s->blen_counter = s->blen;
        break;

    case 0x2c:	/* MMC_BUF */
        s->rx_dma = (value >> 15) & 1;
        s->af_level = (value >> 8) & 0x1f;
        s->tx_dma = (value >> 7) & 1;
        s->ae_level = value & 0x1f;

        if (s->rx_dma)
            s->status &= 0xfbff;
        if (s->tx_dma)
            s->status &= 0xf7ff;
        omap_mmc_fifolevel_update(s);
        omap_mmc_interrupts_update(s);
        break;

    /* SPI, SDIO and TEST modes unimplemented */
    case 0x30:	/* MMC_SPI (OMAP1 only) */
        break;
    case 0x34:	/* MMC_SDIO */
        s->sdio = value & (s->rev >= 2 ? 0xfbf3 : 0x2020);
        s->cdet_wakeup = (value >> 9) & 1;
        s->cdet_enable = (value >> 2) & 1;
        break;
    case 0x38:	/* MMC_SYST */
        break;

    case 0x3c:	/* MMC_REV */
    case 0x40:	/* MMC_RSP0 */
    case 0x44:	/* MMC_RSP1 */
    case 0x48:	/* MMC_RSP2 */
    case 0x4c:	/* MMC_RSP3 */
    case 0x50:	/* MMC_RSP4 */
    case 0x54:	/* MMC_RSP5 */
    case 0x58:	/* MMC_RSP6 */
    case 0x5c:	/* MMC_RSP7 */
        OMAP_RO_REG(offset);
        break;

    /* OMAP2-specific */
    case 0x60:	/* MMC_IOSR */
        if (value & 0xf)
            printf("MMC: SDIO bits used!\n");
        break;
    case 0x64:	/* MMC_SYSC */
        if (value & (1 << 2))					/* SRTS */
            omap_mmc_reset(s);
        break;
    case 0x68:	/* MMC_SYSS */
        OMAP_RO_REG(offset);
        break;

    default:
        OMAP_BAD_REG(offset);
    }
}

static CPUReadMemoryFunc *omap_mmc_readfn[] = {
    omap_badwidth_read16,
    omap_mmc_read,
    omap_badwidth_read16,
};

static CPUWriteMemoryFunc *omap_mmc_writefn[] = {
    omap_badwidth_write16,
    omap_mmc_write,
    omap_badwidth_write16,
};

static void omap_mmc_cover_cb(void *opaque, int line, int level)
{
    struct omap_mmc_s *host = (struct omap_mmc_s *) opaque;

    if (!host->cdet_state && level) {
        host->status |= 0x0002;
        omap_mmc_interrupts_update(host);
        if (host->cdet_wakeup)
            /* TODO: Assert wake-up */;
    }

    if (host->cdet_state != level) {
        qemu_set_irq(host->coverswitch, level);
        host->cdet_state = level;
    }
}

struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
                BlockDriverState *bd,
                qemu_irq irq, qemu_irq dma[], omap_clk clk)
{
    int iomemtype;
    struct omap_mmc_s *s = (struct omap_mmc_s *)
            qemu_mallocz(sizeof(struct omap_mmc_s));

    s->irq = irq;
    s->dma = dma;
    s->clk = clk;
    s->lines = 1;	/* TODO: needs to be settable per-board */
    s->rev = 1;

    omap_mmc_reset(s);

    iomemtype = cpu_register_io_memory(0, omap_mmc_readfn,
                    omap_mmc_writefn, s);
    cpu_register_physical_memory(base, 0x800, iomemtype);

    /* Instantiate the storage */
    s->card = sd_init(bd, 0);

    return s;
}

struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
                BlockDriverState *bd, qemu_irq irq, qemu_irq dma[],
                omap_clk fclk, omap_clk iclk)
{
    int iomemtype;
    struct omap_mmc_s *s = (struct omap_mmc_s *)
            qemu_mallocz(sizeof(struct omap_mmc_s));

    s->irq = irq;
    s->dma = dma;
    s->clk = fclk;
    s->lines = 4;
    s->rev = 2;

    omap_mmc_reset(s);

    iomemtype = l4_register_io_memory(0, omap_mmc_readfn,
                    omap_mmc_writefn, s);
    omap_l4_attach(ta, 0, iomemtype);

    /* Instantiate the storage */
    s->card = sd_init(bd, 0);

    s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0];
    sd_set_cb(s->card, 0, s->cdet);

    return s;
}

void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover)
{
    if (s->cdet) {
        sd_set_cb(s->card, ro, s->cdet);
        s->coverswitch = cover;
        qemu_set_irq(cover, s->cdet_state);
    } else
        sd_set_cb(s->card, ro, cover);
}

void omap_mmc_enable(struct omap_mmc_s *s, int enable)
{
    sd_enable(s->card, enable);
}
