/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#include "mmc.h"
#include "services.h"
#include <string.h>
#include <assert.h>
#include <stdio.h>

#define DBG_INFO "info:"

//#define DEBUG
#undef DEBUG
#ifdef DEBUG
#define D(x, ...) printf(__VA_ARGS__)
#else
#define D(...) do{}while(0)
#endif

#define CSD_VERSION_1       0
#define CSD_VERSION_2_AND_3 1

struct mmc_completion_token {
    struct mmc_card *card;
    mmc_cb cb;
    void *token;
};


static uint32_t slice_bits(uint32_t *val, int start, int size)
{
    int idx;
    int high, low;
    uint32_t ret = 0;

    /* Can not return more than 32 bits. */
    assert(size <= 32);

    idx = start / 32;
    low = start % 32;
    high = (start + size) % 32;

    if (high == 0 && low == 0) {
        ret = val[idx];
    } else if (high == 0 && low != 0) {
        ret = val[idx] >> low;
    } else {
        if (high > low) {
            ret = val[idx] & ((1U << high) - 1);
            ret = ret >> low;
        } else {
            ret = val[idx] >> low;
            ret |= (val[idx + 1] & ((1U << high) - 1)) << (32 - low);
        }

    }

    return ret;
}

#if 0 /* Commenting this out as it appears unused. */
static int mmc_decode_cid(mmc_card_t mmc_card, struct cid *cid)
{
    if (mmc_card == NULL || cid == NULL) {
        return -1;
    }

    if (mmc_card->type == CARD_TYPE_SD) {
        cid->manfid         = slice_bits(mmc_card->raw_cid, 120,  8);
        cid->sd_cid.oemid   = slice_bits(mmc_card->raw_cid, 104, 16);
        cid->sd_cid.name[0] = slice_bits(mmc_card->raw_cid,  96,  8);
        cid->sd_cid.name[1] = slice_bits(mmc_card->raw_cid,  88,  8);
        cid->sd_cid.name[2] = slice_bits(mmc_card->raw_cid,  80,  8);
        cid->sd_cid.name[3] = slice_bits(mmc_card->raw_cid,  72,  8);
        cid->sd_cid.name[4] = slice_bits(mmc_card->raw_cid,  64,  8);
        cid->sd_cid.rev     = slice_bits(mmc_card->raw_cid,  56,  8);
        cid->sd_cid.serial  = slice_bits(mmc_card->raw_cid,  24, 32);
        cid->sd_cid.date    = slice_bits(mmc_card->raw_cid,   8, 12);

        printf("manfid(%x), oemid(%x), name(%c%c%c%c%c), rev(%x), serial(%x), date(%x)\n",
               cid->manfid, cid->sd_cid.oemid,
               cid->sd_cid.name[0], cid->sd_cid.name[1], cid->sd_cid.name[2],
               cid->sd_cid.name[3], cid->sd_cid.name[4],
               cid->sd_cid.rev, cid->sd_cid.serial, cid->sd_cid.date);
    } else {
        printf("Not Implemented!\n");
        return -1;
    }

    return 0;
}
#endif

static int mmc_decode_csd(mmc_card_t mmc_card, struct csd *csd)
{
    if (mmc_card == NULL || csd == NULL) {
        return -1;
    }

#define CSD_BITS(start, size) \
    slice_bits(mmc_card->raw_csd, start, size)

    csd->structure = CSD_BITS(126, 2);

    if (csd->structure == CSD_VERSION_1) {
        printf("CSD Version 1.0\n");
        csd->c_size      = CSD_BITS(62, 12);
        csd->c_size_mult = CSD_BITS(47,  3);
        csd->read_bl_len = CSD_BITS(80,  4);
        csd->tran_speed  = CSD_BITS(96,  8);
    } else if (csd->structure == CSD_VERSION_2_AND_3) {
        printf("CSD Version 2.0\n");
        csd->c_size      = CSD_BITS(48, 22);
        csd->c_size_mult = 0;
        csd->read_bl_len = CSD_BITS(80,  4);
        csd->tran_speed  = CSD_BITS(96,  8);
    } else {
        printf("Unknown CSD version!\n");
        return -1;
    }

    return 0;
}

static struct mmc_cmd *mmc_cmd_new(uint32_t index, uint32_t arg, int rsp_type)
{
    struct mmc_cmd *cmd;
    cmd = malloc(sizeof(*cmd));
    if (cmd) {
        /* Command */
        cmd->index = index;
        cmd->arg = arg;
        cmd->rsp_type = rsp_type;
        cmd->data = NULL;
        /* Transaction maintenance */
        cmd->cb = NULL;
        cmd->token = NULL;
        cmd->next = NULL;
        cmd->complete = 0;
    }
    return cmd;
}

static int mmc_cmd_add_data(struct mmc_cmd *cmd, void *vbuf, uintptr_t pbuf, uint32_t addr,
                            uint32_t block_size, uint32_t blocks)
{
    struct mmc_data *d;
    assert(cmd->data == NULL);
    d = (struct mmc_data *)malloc(sizeof(*d));
    if (d) {
        d->pbuf = pbuf;
        d->vbuf = vbuf;
        d->data_addr = addr;
        d->block_size = block_size;
        d->blocks = blocks;
        cmd->data = d;
        return 0;
    } else {
        return -1;
    }
}

static void mmc_cmd_destroy(struct mmc_cmd *cmd)
{
    if (cmd->data) {
        free(cmd->data);
    }
    free(cmd);
}

static struct mmc_completion_token *mmc_new_completion_token(mmc_card_t mmc_card, mmc_cb cb, void *token)
{
    struct mmc_completion_token *t;
    t = (struct mmc_completion_token *)malloc(sizeof(*t));
    if (t) {
        t->card = mmc_card;
        t->cb = cb;
        t->token = token;
    }
    return t;
}

static void mmc_completion_token_destroy(struct mmc_completion_token *t)
{
    free(t);
}

/**
 * MMC/SD/SDIO card registry.
 */
static int mmc_card_registry(mmc_card_t card)
{
    struct mmc_cmd cmd = {.data = NULL};
    int ret;

    D(DBG_INFO, "\n");

    /* Get card ID */
    cmd.index = MMC_ALL_SEND_CID;
    cmd.arg = 0;
    cmd.rsp_type = MMC_RSP_TYPE_R2;
    ret = host_send_command(card, &cmd, NULL, NULL);
    if (ret) {
        D(DBG_ERR, "No response!\n");
        card->status = CARD_STS_INACTIVE;
        return -1;
    } else {
        card->status = CARD_STS_ACTIVE;
    }

    /* Left shift the response by 8. Consult SDHC manual. */
    cmd.response[3] = ((cmd.response[3] << 8) | (cmd.response[2] >> 24));
    cmd.response[2] = ((cmd.response[2] << 8) | (cmd.response[1] >> 24));
    cmd.response[1] = ((cmd.response[1] << 8) | (cmd.response[0] >> 24));
    cmd.response[0] = (cmd.response[0] << 8);
    memcpy(card->raw_cid, cmd.response, sizeof(card->raw_cid));


    /* Retrieve RCA number. */
    cmd.index = MMC_SEND_RELATIVE_ADDR;
    cmd.arg = 0;
    cmd.rsp_type = MMC_RSP_TYPE_R6;
    host_send_command(card, &cmd, NULL, NULL);
    card->raw_rca = (cmd.response[0] >> 16);
    D(DBG_INFO, "New Card RCA: %x\n", card->raw_rca);

    /* Read CSD, Status */
    cmd.index = MMC_SEND_CSD;
    cmd.arg = card->raw_rca << 16;
    cmd.rsp_type = MMC_RSP_TYPE_R2;
    host_send_command(card, &cmd, NULL, NULL);

    /* Left shift the response by 8. Consult SDHC manual. */
    cmd.response[3] = ((cmd.response[3] << 8) | (cmd.response[2] >> 24));
    cmd.response[2] = ((cmd.response[2] << 8) | (cmd.response[1] >> 24));
    cmd.response[1] = ((cmd.response[1] << 8) | (cmd.response[0] >> 24));
    cmd.response[0] = (cmd.response[0] << 8);
    memcpy(card->raw_csd, cmd.response, sizeof(card->raw_csd));

    cmd.index = MMC_SEND_STATUS;
    cmd.rsp_type = MMC_RSP_TYPE_R1;
    host_send_command(card, &cmd, NULL, NULL);

    /* Select the card */
    cmd.index = MMC_SELECT_CARD;
    cmd.arg = card->raw_rca << 16;
    cmd.rsp_type = MMC_RSP_TYPE_R1b;
    host_send_command(card, &cmd, NULL, NULL);

    /**
     * The default bus width of the card after power up or GO_IDLE (CMD0) is
     * 1 bit. As the HostController is initialzed to 4-bit bus width,
     * the card also needs to switch to 4-bit mode.
     */
    cmd.index = MMC_APP_CMD;
    cmd.arg = card->raw_rca << 16;
    cmd.rsp_type = MMC_RSP_TYPE_R1;
    host_send_command(card, &cmd, NULL, NULL);
    cmd.index = SD_SET_BUS_WIDTH;
    cmd.arg = MMC_MODE_4BIT;
    host_send_command(card, &cmd, NULL, NULL);

    /* Set read/write block length for byte addressed standard capacity cards */
    if (!card->high_capacity) {
        cmd.index = MMC_SET_BLOCKLEN;
        cmd.arg = mmc_block_size(card);
        cmd.rsp_type = MMC_RSP_TYPE_R1;
        ret = host_send_command(card, &cmd, NULL, NULL);
    }

    return 0;
}


/**
 * Card voltage validation.
 */
static int mmc_voltage_validation(mmc_card_t card)
{
    struct mmc_cmd cmd = {.data = NULL};
    int voltage;
    int ret;

    /* Send CMD55 to issue an application specific command. */
    cmd.index = MMC_APP_CMD;
    cmd.arg = 0;
    cmd.rsp_type = MMC_RSP_TYPE_R1;
    ret = host_send_command(card, &cmd, NULL, NULL);
    if (!ret) {
        /* It is a SD card. */
        cmd.index = SD_SD_APP_OP_COND;
        cmd.arg = 0;
        cmd.rsp_type = MMC_RSP_TYPE_R3;
        card->type = CARD_TYPE_SD;
    } else {
        /* It is a MMC card. */
        cmd.index = MMC_SEND_OP_COND;
        cmd.arg = 0;
        cmd.rsp_type = MMC_RSP_TYPE_R3;
        card->type = CARD_TYPE_MMC;
    }
    ret = host_send_command(card, &cmd, NULL, NULL);
    if (ret) {
        card->type = CARD_TYPE_UNKNOWN;
        /* TODO: Be nicer */
        assert(0);
    }
    card->ocr = cmd.response[0];

    /* TODO: Check uSDHC compatibility */
    voltage = MMC_VDD_29_30 | MMC_VDD_30_31;
    if (host_is_voltage_compatible(card, 3300) && (card->ocr & voltage)) {
        /* Voltage compatible */
        voltage |= (1 << 30);
        voltage |= (1 << 25);
        voltage |= (1 << 24);
    }

    /* Wait until the voltage level is set. */
    do {
        if (card->type == CARD_TYPE_SD) {
            cmd.index = MMC_APP_CMD;
            cmd.arg = 0;
            cmd.rsp_type = MMC_RSP_TYPE_R1;
            host_send_command(card, &cmd, NULL, NULL);
        }

        cmd.index = SD_SD_APP_OP_COND;
        cmd.arg = voltage;
        cmd.rsp_type = MMC_RSP_TYPE_R3;
        host_send_command(card, &cmd, NULL, NULL);
        udelay(100000);
    } while (!(cmd.response[0] & (1U << 31)));
    card->ocr = cmd.response[0];

    /* Check CCS bit */
    if (card->ocr & (1 << 30)) {
        card->high_capacity = 1;
    } else {
        card->high_capacity = 0;
    }

    D(DBG_INFO, "Voltage set!\n");
    return 0;
}


static int mmc_reset(mmc_card_t card)
{
    /* Reset the card with CMD0 */
    struct mmc_cmd cmd = {.data = NULL};
    cmd.index = MMC_GO_IDLE_STATE;
    cmd.arg = 0;
    cmd.rsp_type = MMC_RSP_TYPE_NONE;
    host_send_command(card, &cmd, NULL, NULL);

    /* TODO: review this command. */
    cmd.index = MMC_SEND_EXT_CSD;
    cmd.arg = 0x1AA;
    cmd.rsp_type = MMC_RSP_TYPE_R1;
    host_send_command(card, &cmd, NULL, NULL);
    return 0;
}

static void mmc_blockop_completion_cb(struct sdio_host_dev *sdio, int stat, struct mmc_cmd *cmd,
                                      void *token)
{
    struct mmc_completion_token *t;
    size_t bytes;

    t = (struct mmc_completion_token *)token;
    if (stat == 0) {
        bytes = cmd->data->block_size * cmd->data->blocks;
    } else {
        bytes = 0;
    }
    /* Call the registered function */
    t->cb(t->card, stat, bytes, t->token);
    /* Free memory */
    mmc_cmd_destroy(cmd);
    mmc_completion_token_destroy(t);
}

int mmc_init(sdio_host_dev_t *sdio, ps_io_ops_t *io_ops, mmc_card_t *mmc_card)
{
    mmc_card_t mmc;

    /* Allocate the mmc card structure */
    mmc = (mmc_card_t)malloc(sizeof(*mmc));
    assert(mmc);
    if (!mmc) {
        return -1;
    }
    mmc->dalloc = &io_ops->dma_manager;
    mmc->sdio = sdio;
    /* Reset the host controller */
    if (host_reset(mmc)) {
        LOG_ERROR("Failed to reset host controller\n");
        free(mmc);
        return -1;
    }
    /* Initialise the card */
    if (mmc_reset(mmc)) {
        LOG_ERROR("Failed to reset SD/MMC card\n");
        free(mmc);
        return -1;
    }
    if (mmc_voltage_validation(mmc)) {
        LOG_ERROR("Failed to perform voltage validation\n");
        free(mmc);
        return -1;
    }
    /* Register the card */
    if (mmc_card_registry(mmc)) {
        LOG_ERROR("Failed to register card\n");
        free(mmc);
        return -1;
    }

    *mmc_card = mmc;
    assert(mmc);
    return 0;
}

static
long transfer_data(
    mmc_card_t mmc_card,
    unsigned long start,
    int nblocks,
    void *vbuf,
    uintptr_t pbuf,
    mmc_cb cb,
    void *token,
    uint32_t command)
{
    struct mmc_cmd *cmd;
    const int block_size = mmc_block_size(mmc_card);

    /* Determine command argument */
    const uint32_t arg = (mmc_card->high_capacity)
                         ? start
                         : (start * block_size);

    /* Allocate command structure
     *
     * Please note that `cmd` is dynamically allocated, so it must be destroyed.
     *
     * Clean up will be done prior to exiting this function OR in the
     * `mmc_blockop_completion_cb` if callback was given.
     *
     * In case of an unexpected error, there will be a jump to
     * `exit_transfer_data` label, so that memory leak can be avoided.
     */
    cmd = mmc_cmd_new(command, arg, MMC_RSP_TYPE_R1);
    if (cmd == NULL) {
        // `cmd` was NOT allocated, so we are exiting without destroying it.
        return -1;
    }

    long ret = -1;
    struct mmc_completion_token *mmc_token = NULL;

    /* Add a data segment */
    ret = mmc_cmd_add_data(cmd, vbuf, pbuf, start, block_size, nblocks);
    if (ret < 0) {
        goto exit_transfer_data;
    }

    if (cb) {
        mmc_token = mmc_new_completion_token(mmc_card, cb, token);

        if (NULL == mmc_token) {
            ret = -1;
            goto exit_transfer_data;
        }
    }

    ret = host_send_command(
              mmc_card,
              cmd,
              cb ? &mmc_blockop_completion_cb : NULL,
              cb ? mmc_token : NULL);

exit_transfer_data:
    ;
    const bool is_success = (0 == ret);

    // Clean up usually will happen during the callback, so we only clean up
    // here if no callback was given or failure has been encountered.
    if (!cb || !is_success) {
        if (mmc_token) {
            mmc_completion_token_destroy(mmc_token);
        }
        if (cmd)       {
            mmc_cmd_destroy(cmd);
        }
    }

    const size_t bytes_transferred = cb ? 0 : (block_size * nblocks);
    return is_success ? bytes_transferred : ret;
}

long mmc_block_read(mmc_card_t mmc_card, unsigned long start,
                    int nblocks, void *vbuf, uintptr_t pbuf, mmc_cb cb, void *token)
{
    return transfer_data(
               mmc_card,
               start,
               nblocks,
               vbuf,
               pbuf,
               cb,
               token,
               MMC_READ_SINGLE_BLOCK);
}

long mmc_block_write(mmc_card_t mmc_card, unsigned long start, int nblocks,
                     const void *vbuf, uintptr_t pbuf, mmc_cb cb, void *token)
{
    // vbuf's `const` gets dropped during the cast as the underlying layer
    // accepts only non-const buffer, however it is ok, as we are sending the
    // write command, what quarantees that the buffer won't be overwritten.
    return transfer_data(
               mmc_card,
               start,
               nblocks,
               (void *)vbuf,
               pbuf,
               cb,
               token,
               MMC_WRITE_BLOCK);
}

long long mmc_card_capacity(mmc_card_t mmc_card)
{
    int ret;
    struct csd csd;

    ret = mmc_decode_csd(mmc_card, &csd);
    if (ret) {
        return -1;
    }

    long long c_size = (long long)csd.c_size;
    switch (csd.structure) {
    case CSD_VERSION_1: {
        return (c_size + 1) * (1U << (csd.c_size_mult + 2))
               * (1U << csd.read_bl_len);
    }
    case CSD_VERSION_2_AND_3: {
        return (c_size + 1) * 512 * 1024;
    }
    default: {
        return -1;
    }
    }
}


int mmc_nth_irq(mmc_card_t mmc, int n)
{
    return host_nth_irq(mmc, n);
}

int mmc_handle_irq(mmc_card_t mmc, int irq)
{
    return host_handle_irq(mmc, irq);
}


