/*
 * 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 "qemu/module.h"
#include "hw/misc/auxbus.h"
#include "migration/vmstate.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)
