/*
 * dpcd.c
 *
 *  Copyright (C) 2015 : GreenSocs Ltd
 *      http://www.greensocs.com/ , email: info@greensocs.com
 *
 *  Developed by :
 *  Frederic Konrad   <fred.konrad@greensocs.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 of the License, or
 * (at your option)any later version.
 *
 * 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/>.
 *
 */

/*
 * This is a simple AUX slave which emulates a connected screen.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/misc/auxbus.h"
#include "hw/display/dpcd.h"

#ifndef DEBUG_DPCD
#define DEBUG_DPCD 0
#endif

#define DPRINTF(fmt, ...) do {                                                 \
    if (DEBUG_DPCD) {                                                          \
        qemu_log("dpcd: " fmt, ## __VA_ARGS__);                                \
    }                                                                          \
} while (0);

#define DPCD_READABLE_AREA                      0x600

struct DPCDState {
    /*< private >*/
    AUXSlave parent_obj;

    /*< public >*/
    /*
     * The DCPD is 0x7FFFF length but read as 0 after offset 0x5FF.
     */
    uint8_t dpcd_info[DPCD_READABLE_AREA];

    MemoryRegion iomem;
};

static uint64_t dpcd_read(void *opaque, hwaddr offset, unsigned size)
{
    uint8_t ret;
    DPCDState *e = DPCD(opaque);

    if (offset < DPCD_READABLE_AREA) {
        ret = e->dpcd_info[offset];
    } else {
        qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
                                       offset);
        ret = 0;
    }

    DPRINTF("read 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", ret, offset);
    return ret;
}

static void dpcd_write(void *opaque, hwaddr offset, uint64_t value,
                       unsigned size)
{
    DPCDState *e = DPCD(opaque);

    DPRINTF("write 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", (uint8_t)value, offset);

    if (offset < DPCD_READABLE_AREA) {
        e->dpcd_info[offset] = value;
    } else {
        qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
                                       offset);
    }
}

static const MemoryRegionOps aux_ops = {
    .read = dpcd_read,
    .write = dpcd_write,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
};

static void dpcd_reset(DeviceState *dev)
{
    DPCDState *s = DPCD(dev);

    memset(&(s->dpcd_info), 0, sizeof(s->dpcd_info));

    s->dpcd_info[DPCD_REVISION] = DPCD_REV_1_0;
    s->dpcd_info[DPCD_MAX_LINK_RATE] = DPCD_5_4GBPS;
    s->dpcd_info[DPCD_MAX_LANE_COUNT] = DPCD_FOUR_LANES;
    s->dpcd_info[DPCD_RECEIVE_PORT0_CAP_0] = DPCD_EDID_PRESENT;
    /* buffer size */
    s->dpcd_info[DPCD_RECEIVE_PORT0_CAP_1] = 0xFF;

    s->dpcd_info[DPCD_LANE0_1_STATUS] = DPCD_LANE0_CR_DONE
                                      | DPCD_LANE0_CHANNEL_EQ_DONE
                                      | DPCD_LANE0_SYMBOL_LOCKED
                                      | DPCD_LANE1_CR_DONE
                                      | DPCD_LANE1_CHANNEL_EQ_DONE
                                      | DPCD_LANE1_SYMBOL_LOCKED;
    s->dpcd_info[DPCD_LANE2_3_STATUS] = DPCD_LANE2_CR_DONE
                                      | DPCD_LANE2_CHANNEL_EQ_DONE
                                      | DPCD_LANE2_SYMBOL_LOCKED
                                      | DPCD_LANE3_CR_DONE
                                      | DPCD_LANE3_CHANNEL_EQ_DONE
                                      | DPCD_LANE3_SYMBOL_LOCKED;

    s->dpcd_info[DPCD_LANE_ALIGN_STATUS_UPDATED] = DPCD_INTERLANE_ALIGN_DONE;
    s->dpcd_info[DPCD_SINK_STATUS] = DPCD_RECEIVE_PORT_0_STATUS;
}

static void dpcd_init(Object *obj)
{
    DPCDState *s = DPCD(obj);

    memory_region_init_io(&s->iomem, obj, &aux_ops, s, TYPE_DPCD, 0x7FFFF);
    aux_init_mmio(AUX_SLAVE(obj), &s->iomem);
}

static const VMStateDescription vmstate_dpcd = {
    .name = TYPE_DPCD,
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8_ARRAY_V(dpcd_info, DPCDState, DPCD_READABLE_AREA, 0),
        VMSTATE_END_OF_LIST()
    }
};

static void dpcd_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->reset = dpcd_reset;
    dc->vmsd = &vmstate_dpcd;
}

static const TypeInfo dpcd_info = {
    .name          = TYPE_DPCD,
    .parent        = TYPE_AUX_SLAVE,
    .instance_size = sizeof(DPCDState),
    .class_init    = dpcd_class_init,
    .instance_init = dpcd_init,
};

static void dpcd_register_types(void)
{
    type_register_static(&dpcd_info);
}

type_init(dpcd_register_types)
