/*
 * OMAP on-chip MMC/SD host emulation.
 *
 * Datasheet: TI Multimedia Card (MMC/SD/SDIO) Interface (SPRU765A)
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "hw/arm/omap.h"
#include "hw/sd/sd.h"

typedef struct OMAPMMCState {
    SysBusDevice parent_obj;

    SDBus sdbus;

    qemu_irq irq;
    qemu_irq dma_tx_gpio;
    qemu_irq dma_rx_gpio;
    MemoryRegion iomem;
    omap_clk clk;
    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;
    qemu_irq cdet;
} OMAPMMCState;

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

static void omap_mmc_fifolevel_update(OMAPMMCState *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_rx_gpio);
        } else
            host->status |= 0x0400;
    } else {
        host->status &= 0xfbff;
        qemu_irq_lower(host->dma_rx_gpio);
    }

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

/* These must match the encoding of the MMC_CMD Response field */
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;

/* These must match the encoding of the MMC_CMD Type field */
typedef enum {
    SD_TYPE_BC = 0,     /* broadcast -- no response */
    SD_TYPE_BCR = 1,    /* broadcast with response */
    SD_TYPE_AC = 2,     /* addressed -- no data transfer */
    SD_TYPE_ADTC = 3,   /* addressed with data transfer */
} MMCCmdType;

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

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

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

    if (type == SD_TYPE_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 = sdbus_do_command(&host->sdbus, &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 = ldl_be_p(response);
        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 = ldl_be_p(response);
        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(OMAPMMCState *host)
{
    uint8_t value;

    if (!host->transfer)
        return;

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

            value = sdbus_read_byte(&host->sdbus);
            host->fifo[(host->fifo_start + host->fifo_len) & 31] = value;
            if (-- host->blen_counter) {
                value = sdbus_read_byte(&host->sdbus);
                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;
            sdbus_write_byte(&host->sdbus, value);
            if (-- host->blen_counter) {
                value = host->fifo[host->fifo_start] >> 8;
                sdbus_write_byte(&host->sdbus, 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)
{
    OMAPMMCState *s = opaque;
    omap_mmc_transfer(s);
    omap_mmc_fifolevel_update(s);
    omap_mmc_interrupts_update(s);
}

static void omap_mmc_pseudo_reset(OMAPMMCState *host)
{
    host->status = 0;
    host->fifo_len = 0;
}

static void omap_mmc_reset(OMAPMMCState *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->mask = 0;
    host->cto = 0;
    host->dto = 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;
    host->clkdiv = 0;

    omap_mmc_pseudo_reset(host);
}

static uint64_t omap_mmc_read(void *opaque, hwaddr offset, unsigned size)
{
    uint16_t i;
    OMAPMMCState *s = opaque;

    if (size != 2) {
        return omap_badwidth_read16(opaque, offset);
    }

    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, hwaddr offset,
                           uint64_t value, unsigned size)
{
    int i;
    OMAPMMCState *s = opaque;

    if (size != 2) {
        omap_badwidth_write16(opaque, offset, value);
        return;
    }

    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,
                         (MMCCmdType)((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) {
            qemu_log_mask(LOG_UNIMP,
                          "omap_mmc_wr: mode #%i unimplemented\n", s->mode);
        }
        if (s->be != 0) {
            qemu_log_mask(LOG_UNIMP,
                          "omap_mmc_wr: Big Endian not implemented\n");
        }
        if (s->dw != 0 && s->lines < 4)
            printf("4-bit SD bus enabled\n");
        if (!s->enable)
            omap_mmc_pseudo_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 const MemoryRegionOps omap_mmc_ops = {
    .read = omap_mmc_read,
    .write = omap_mmc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

void omap_mmc_set_clk(DeviceState *dev, omap_clk clk)
{
    OMAPMMCState *s = OMAP_MMC(dev);

    s->clk = clk;
}

static void omap_mmc_reset_hold(Object *obj, ResetType type)
{
    OMAPMMCState *s = OMAP_MMC(obj);

    omap_mmc_reset(s);
}

static void omap_mmc_initfn(Object *obj)
{
    OMAPMMCState *s = OMAP_MMC(obj);

    /* In theory these could be settable per-board */
    s->lines = 1;
    s->rev = 1;

    memory_region_init_io(&s->iomem, obj, &omap_mmc_ops, s, "omap.mmc", 0x800);
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);

    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
    qdev_init_gpio_out_named(DEVICE(obj), &s->dma_tx_gpio, "dma-tx", 1);
    qdev_init_gpio_out_named(DEVICE(obj), &s->dma_rx_gpio, "dma-rx", 1);

    qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(obj), "sd-bus");
}

static void omap_mmc_class_init(ObjectClass *oc, const void *data)
{
    ResettableClass *rc = RESETTABLE_CLASS(oc);

    rc->phases.hold = omap_mmc_reset_hold;
}

static const TypeInfo omap_mmc_info = {
    .name = TYPE_OMAP_MMC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(OMAPMMCState),
    .instance_init = omap_mmc_initfn,
    .class_init = omap_mmc_class_init,
};

static void omap_mmc_register_types(void)
{
    type_register_static(&omap_mmc_info);
}

type_init(omap_mmc_register_types)
