/*
 * display support for mdev based vgpu devices
 *
 * Copyright Red Hat, Inc. 2017
 *
 * Authors:
 *    Gerd Hoffmann
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include <linux/vfio.h>
#include <sys/ioctl.h>

#include "hw/display/edid.h"
#include "ui/console.h"
#include "qapi/error.h"
#include "pci.h"
#include "trace.h"

#ifndef DRM_PLANE_TYPE_PRIMARY
# define DRM_PLANE_TYPE_PRIMARY 1
# define DRM_PLANE_TYPE_CURSOR  2
#endif

#define pread_field(_fd, _reg, _ptr, _fld)                              \
    (sizeof(_ptr->_fld) !=                                              \
     pread(_fd, &(_ptr->_fld), sizeof(_ptr->_fld),                      \
           _reg->offset + offsetof(typeof(*_ptr), _fld)))

#define pwrite_field(_fd, _reg, _ptr, _fld)                             \
    (sizeof(_ptr->_fld) !=                                              \
     pwrite(_fd, &(_ptr->_fld), sizeof(_ptr->_fld),                     \
            _reg->offset + offsetof(typeof(*_ptr), _fld)))


static void vfio_display_edid_link_up(void *opaque)
{
    VFIOPCIDevice *vdev = opaque;
    VFIODisplay *dpy = vdev->dpy;
    int fd = vdev->vbasedev.fd;

    dpy->edid_regs->link_state = VFIO_DEVICE_GFX_LINK_STATE_UP;
    if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) {
        goto err;
    }
    trace_vfio_display_edid_link_up();
    return;

err:
    trace_vfio_display_edid_write_error();
}

static void vfio_display_edid_update(VFIOPCIDevice *vdev, bool enabled,
                                     int prefx, int prefy)
{
    VFIODisplay *dpy = vdev->dpy;
    int fd = vdev->vbasedev.fd;
    qemu_edid_info edid = {
        .maxx  = dpy->edid_regs->max_xres,
        .maxy  = dpy->edid_regs->max_yres,
        .prefx = prefx ?: vdev->display_xres,
        .prefy = prefy ?: vdev->display_yres,
    };

    timer_del(dpy->edid_link_timer);
    dpy->edid_regs->link_state = VFIO_DEVICE_GFX_LINK_STATE_DOWN;
    if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) {
        goto err;
    }
    trace_vfio_display_edid_link_down();

    if (!enabled) {
        return;
    }

    if (edid.maxx && edid.prefx > edid.maxx) {
        edid.prefx = edid.maxx;
    }
    if (edid.maxy && edid.prefy > edid.maxy) {
        edid.prefy = edid.maxy;
    }
    qemu_edid_generate(dpy->edid_blob,
                       dpy->edid_regs->edid_max_size,
                       &edid);
    trace_vfio_display_edid_update(edid.prefx, edid.prefy);

    dpy->edid_regs->edid_size = qemu_edid_size(dpy->edid_blob);
    if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, edid_size)) {
        goto err;
    }
    if (pwrite(fd, dpy->edid_blob, dpy->edid_regs->edid_size,
               dpy->edid_info->offset + dpy->edid_regs->edid_offset)
        != dpy->edid_regs->edid_size) {
        goto err;
    }

    timer_mod(dpy->edid_link_timer,
              qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 100);
    return;

err:
    trace_vfio_display_edid_write_error();
    return;
}

static void vfio_display_edid_ui_info(void *opaque, uint32_t idx,
                                      QemuUIInfo *info)
{
    VFIOPCIDevice *vdev = opaque;
    VFIODisplay *dpy = vdev->dpy;

    if (!dpy->edid_regs) {
        return;
    }

    if (info->width && info->height) {
        vfio_display_edid_update(vdev, true, info->width, info->height);
    } else {
        vfio_display_edid_update(vdev, false, 0, 0);
    }
}

static void vfio_display_edid_init(VFIOPCIDevice *vdev)
{
    VFIODisplay *dpy = vdev->dpy;
    int fd = vdev->vbasedev.fd;
    int ret;

    ret = vfio_get_dev_region_info(&vdev->vbasedev,
                                   VFIO_REGION_TYPE_GFX,
                                   VFIO_REGION_SUBTYPE_GFX_EDID,
                                   &dpy->edid_info);
    if (ret) {
        return;
    }

    trace_vfio_display_edid_available();
    dpy->edid_regs = g_new0(struct vfio_region_gfx_edid, 1);
    if (pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_offset)) {
        goto err;
    }
    if (pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_max_size)) {
        goto err;
    }
    if (pread_field(fd, dpy->edid_info, dpy->edid_regs, max_xres)) {
        goto err;
    }
    if (pread_field(fd, dpy->edid_info, dpy->edid_regs, max_yres)) {
        goto err;
    }

    dpy->edid_blob = g_malloc0(dpy->edid_regs->edid_max_size);

    /* if xres + yres properties are unset use the maximum resolution */
    if (!vdev->display_xres) {
        vdev->display_xres = dpy->edid_regs->max_xres;
    }
    if (!vdev->display_yres) {
        vdev->display_yres = dpy->edid_regs->max_yres;
    }

    dpy->edid_link_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
                                        vfio_display_edid_link_up, vdev);

    vfio_display_edid_update(vdev, true, 0, 0);
    return;

err:
    trace_vfio_display_edid_write_error();
    g_free(dpy->edid_regs);
    dpy->edid_regs = NULL;
    return;
}

static void vfio_display_edid_exit(VFIODisplay *dpy)
{
    if (!dpy->edid_regs) {
        return;
    }

    g_free(dpy->edid_regs);
    g_free(dpy->edid_blob);
    timer_free(dpy->edid_link_timer);
}

static void vfio_display_update_cursor(VFIODMABuf *dmabuf,
                                       struct vfio_device_gfx_plane_info *plane)
{
    if (dmabuf->pos_x != plane->x_pos || dmabuf->pos_y != plane->y_pos) {
        dmabuf->pos_x      = plane->x_pos;
        dmabuf->pos_y      = plane->y_pos;
        dmabuf->pos_updates++;
    }
    if (dmabuf->hot_x != plane->x_hot || dmabuf->hot_y != plane->y_hot) {
        dmabuf->hot_x      = plane->x_hot;
        dmabuf->hot_y      = plane->y_hot;
        dmabuf->hot_updates++;
    }
}

static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev,
                                           uint32_t plane_type)
{
    VFIODisplay *dpy = vdev->dpy;
    struct vfio_device_gfx_plane_info plane;
    VFIODMABuf *dmabuf;
    int fd, ret;

    memset(&plane, 0, sizeof(plane));
    plane.argsz = sizeof(plane);
    plane.flags = VFIO_GFX_PLANE_TYPE_DMABUF;
    plane.drm_plane_type = plane_type;
    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &plane);
    if (ret < 0) {
        return NULL;
    }
    if (!plane.drm_format || !plane.size) {
        return NULL;
    }

    QTAILQ_FOREACH(dmabuf, &dpy->dmabuf.bufs, next) {
        if (dmabuf->dmabuf_id == plane.dmabuf_id) {
            /* found in list, move to head, return it */
            QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next);
            QTAILQ_INSERT_HEAD(&dpy->dmabuf.bufs, dmabuf, next);
            if (plane_type == DRM_PLANE_TYPE_CURSOR) {
                vfio_display_update_cursor(dmabuf, &plane);
            }
            return dmabuf;
        }
    }

    fd = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_GFX_DMABUF, &plane.dmabuf_id);
    if (fd < 0) {
        return NULL;
    }

    dmabuf = g_new0(VFIODMABuf, 1);
    dmabuf->dmabuf_id  = plane.dmabuf_id;
    dmabuf->buf.width  = plane.width;
    dmabuf->buf.height = plane.height;
    dmabuf->buf.stride = plane.stride;
    dmabuf->buf.fourcc = plane.drm_format;
    dmabuf->buf.modifier = plane.drm_format_mod;
    dmabuf->buf.fd     = fd;
    if (plane_type == DRM_PLANE_TYPE_CURSOR) {
        vfio_display_update_cursor(dmabuf, &plane);
    }

    QTAILQ_INSERT_HEAD(&dpy->dmabuf.bufs, dmabuf, next);
    return dmabuf;
}

static void vfio_display_free_one_dmabuf(VFIODisplay *dpy, VFIODMABuf *dmabuf)
{
    QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next);
    dpy_gl_release_dmabuf(dpy->con, &dmabuf->buf);
    close(dmabuf->buf.fd);
    g_free(dmabuf);
}

static void vfio_display_free_dmabufs(VFIOPCIDevice *vdev)
{
    VFIODisplay *dpy = vdev->dpy;
    VFIODMABuf *dmabuf, *tmp;
    uint32_t keep = 5;

    QTAILQ_FOREACH_SAFE(dmabuf, &dpy->dmabuf.bufs, next, tmp) {
        if (keep > 0) {
            keep--;
            continue;
        }
        assert(dmabuf != dpy->dmabuf.primary);
        vfio_display_free_one_dmabuf(dpy, dmabuf);
    }
}

static void vfio_display_dmabuf_update(void *opaque)
{
    VFIOPCIDevice *vdev = opaque;
    VFIODisplay *dpy = vdev->dpy;
    VFIODMABuf *primary, *cursor;
    bool free_bufs = false, new_cursor = false;

    primary = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_PRIMARY);
    if (primary == NULL) {
        if (dpy->ramfb) {
            ramfb_display_update(dpy->con, dpy->ramfb);
        }
        return;
    }

    if (dpy->dmabuf.primary != primary) {
        dpy->dmabuf.primary = primary;
        qemu_console_resize(dpy->con,
                            primary->buf.width, primary->buf.height);
        dpy_gl_scanout_dmabuf(dpy->con, &primary->buf);
        free_bufs = true;
    }

    cursor = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_CURSOR);
    if (dpy->dmabuf.cursor != cursor) {
        dpy->dmabuf.cursor = cursor;
        new_cursor = true;
        free_bufs = true;
    }

    if (cursor && (new_cursor || cursor->hot_updates)) {
        bool have_hot = (cursor->hot_x != 0xffffffff &&
                         cursor->hot_y != 0xffffffff);
        dpy_gl_cursor_dmabuf(dpy->con, &cursor->buf, have_hot,
                             cursor->hot_x, cursor->hot_y);
        cursor->hot_updates = 0;
    } else if (!cursor && new_cursor) {
        dpy_gl_cursor_dmabuf(dpy->con, NULL, false, 0, 0);
    }

    if (cursor && cursor->pos_updates) {
        dpy_gl_cursor_position(dpy->con,
                               cursor->pos_x,
                               cursor->pos_y);
        cursor->pos_updates = 0;
    }

    dpy_gl_update(dpy->con, 0, 0, primary->buf.width, primary->buf.height);

    if (free_bufs) {
        vfio_display_free_dmabufs(vdev);
    }
}

static int vfio_display_get_flags(void *opaque)
{
    return GRAPHIC_FLAGS_GL | GRAPHIC_FLAGS_DMABUF;
}

static const GraphicHwOps vfio_display_dmabuf_ops = {
    .get_flags  = vfio_display_get_flags,
    .gfx_update = vfio_display_dmabuf_update,
    .ui_info    = vfio_display_edid_ui_info,
};

static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
{
    if (!display_opengl) {
        error_setg(errp, "vfio-display-dmabuf: opengl not available");
        return -1;
    }

    vdev->dpy = g_new0(VFIODisplay, 1);
    vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
                                          &vfio_display_dmabuf_ops,
                                          vdev);
    if (vdev->enable_ramfb) {
        vdev->dpy->ramfb = ramfb_setup(errp);
    }
    vfio_display_edid_init(vdev);
    return 0;
}

static void vfio_display_dmabuf_exit(VFIODisplay *dpy)
{
    VFIODMABuf *dmabuf;

    if (QTAILQ_EMPTY(&dpy->dmabuf.bufs)) {
        return;
    }

    while ((dmabuf = QTAILQ_FIRST(&dpy->dmabuf.bufs)) != NULL) {
        vfio_display_free_one_dmabuf(dpy, dmabuf);
    }
}

/* ---------------------------------------------------------------------- */
void vfio_display_reset(VFIOPCIDevice *vdev)
{
    if (!vdev || !vdev->dpy || !vdev->dpy->con ||
        !vdev->dpy->dmabuf.primary) {
        return;
    }

    dpy_gl_scanout_disable(vdev->dpy->con);
    vfio_display_dmabuf_exit(vdev->dpy);
    dpy_gfx_update_full(vdev->dpy->con);
}

static void vfio_display_region_update(void *opaque)
{
    VFIOPCIDevice *vdev = opaque;
    VFIODisplay *dpy = vdev->dpy;
    struct vfio_device_gfx_plane_info plane = {
        .argsz = sizeof(plane),
        .flags = VFIO_GFX_PLANE_TYPE_REGION
    };
    pixman_format_code_t format;
    int ret;

    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &plane);
    if (ret < 0) {
        error_report("ioctl VFIO_DEVICE_QUERY_GFX_PLANE: %s",
                     strerror(errno));
        return;
    }
    if (!plane.drm_format || !plane.size) {
        if (dpy->ramfb) {
            ramfb_display_update(dpy->con, dpy->ramfb);
            dpy->region.surface = NULL;
        }
        return;
    }
    format = qemu_drm_format_to_pixman(plane.drm_format);
    if (!format) {
        return;
    }

    if (dpy->region.buffer.size &&
        dpy->region.buffer.nr != plane.region_index) {
        /* region changed */
        vfio_region_exit(&dpy->region.buffer);
        vfio_region_finalize(&dpy->region.buffer);
        dpy->region.surface = NULL;
    }

    if (dpy->region.surface &&
        (surface_width(dpy->region.surface) != plane.width ||
         surface_height(dpy->region.surface) != plane.height ||
         surface_format(dpy->region.surface) != format)) {
        /* size changed */
        dpy->region.surface = NULL;
    }

    if (!dpy->region.buffer.size) {
        /* mmap region */
        ret = vfio_region_setup(OBJECT(vdev), &vdev->vbasedev,
                                &dpy->region.buffer,
                                plane.region_index,
                                "display");
        if (ret != 0) {
            error_report("%s: vfio_region_setup(%d): %s",
                         __func__, plane.region_index, strerror(-ret));
            goto err;
        }
        ret = vfio_region_mmap(&dpy->region.buffer);
        if (ret != 0) {
            error_report("%s: vfio_region_mmap(%d): %s", __func__,
                         plane.region_index, strerror(-ret));
            goto err;
        }
        assert(dpy->region.buffer.mmaps[0].mmap != NULL);
    }

    if (dpy->region.surface == NULL) {
        /* create surface */
        dpy->region.surface = qemu_create_displaysurface_from
            (plane.width, plane.height, format,
             plane.stride, dpy->region.buffer.mmaps[0].mmap);
        dpy_gfx_replace_surface(dpy->con, dpy->region.surface);
    }

    /* full screen update */
    dpy_gfx_update(dpy->con, 0, 0,
                   surface_width(dpy->region.surface),
                   surface_height(dpy->region.surface));
    return;

err:
    vfio_region_exit(&dpy->region.buffer);
    vfio_region_finalize(&dpy->region.buffer);
}

static const GraphicHwOps vfio_display_region_ops = {
    .gfx_update = vfio_display_region_update,
};

static int vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp)
{
    vdev->dpy = g_new0(VFIODisplay, 1);
    vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
                                          &vfio_display_region_ops,
                                          vdev);
    if (vdev->enable_ramfb) {
        vdev->dpy->ramfb = ramfb_setup(errp);
    }
    return 0;
}

static void vfio_display_region_exit(VFIODisplay *dpy)
{
    if (!dpy->region.buffer.size) {
        return;
    }

    vfio_region_exit(&dpy->region.buffer);
    vfio_region_finalize(&dpy->region.buffer);
}

/* ---------------------------------------------------------------------- */

int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)
{
    struct vfio_device_gfx_plane_info probe;
    int ret;

    memset(&probe, 0, sizeof(probe));
    probe.argsz = sizeof(probe);
    probe.flags = VFIO_GFX_PLANE_TYPE_PROBE | VFIO_GFX_PLANE_TYPE_DMABUF;
    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &probe);
    if (ret == 0) {
        return vfio_display_dmabuf_init(vdev, errp);
    }

    memset(&probe, 0, sizeof(probe));
    probe.argsz = sizeof(probe);
    probe.flags = VFIO_GFX_PLANE_TYPE_PROBE | VFIO_GFX_PLANE_TYPE_REGION;
    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &probe);
    if (ret == 0) {
        return vfio_display_region_init(vdev, errp);
    }

    if (vdev->display == ON_OFF_AUTO_AUTO) {
        /* not an error in automatic mode */
        return 0;
    }

    error_setg(errp, "vfio: device doesn't support any (known) display method");
    return -1;
}

void vfio_display_finalize(VFIOPCIDevice *vdev)
{
    if (!vdev->dpy) {
        return;
    }

    graphic_console_close(vdev->dpy->con);
    vfio_display_dmabuf_exit(vdev->dpy);
    vfio_display_region_exit(vdev->dpy);
    vfio_display_edid_exit(vdev->dpy);
    g_free(vdev->dpy);
}
