/*
 * 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;
    size_t rsplen;
    int 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, sizeof(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)
