// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "vim-display.h"
#include "hdmitx.h"
#include <assert.h>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/io-buffer.h>
#include <ddk/protocol/display-controller.h>
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/platform-device.h>
#include <hw/reg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>

/* Default formats */
static const uint8_t _ginput_color_format   = HDMI_COLOR_FORMAT_444;
static const uint8_t _gcolor_depth          = HDMI_COLOR_DEPTH_24B;

static const zx_pixel_format_t _gsupported_pixel_formats = { ZX_PIXEL_FORMAT_RGB_x888 };

typedef struct image_info {
    zx_handle_t pmt;
    uint8_t canvas_idx;

    list_node_t node;
} image_info_t;

// MMIO indices (based on vim2_display_mmios)
enum {
    MMIO_PRESET = 0,
    MMIO_HDMITX,
    MMIO_HIU,
    MMIO_VPU,
    MMIO_HDMTX_SEC,
    MMIO_DMC,
    MMIO_CBUS,
    MMIO_AUD_OUT,
    MMIO_COUNT  // Must be the final entry
};

static uint32_t vim_compute_linear_stride(void* ctx, uint32_t width, zx_pixel_format_t format) {
    // The vim2 display controller needs buffers with a stride that is an even
    // multiple of 32.
    return ROUNDUP(width, 32 / ZX_PIXEL_FORMAT_BYTES(format));
}

static void vim_set_display_controller_cb(void* ctx, void* cb_ctx, display_controller_cb_t* cb) {
    vim2_display_t* display = ctx;
    mtx_lock(&display->cb_lock);

    mtx_lock(&display->display_lock);

    display->dc_cb = cb;
    display->dc_cb_ctx = cb_ctx;

    uint64_t display_id = display->display_id;
    bool attached = display->display_attached;
    mtx_unlock(&display->display_lock);

    if (attached) {
        display->dc_cb->on_displays_changed(display->dc_cb_ctx, &display_id, 1, NULL, 0);
    }
    mtx_unlock(&display->cb_lock);
}

static zx_status_t vim_get_display_info(void* ctx, uint64_t display_id, display_info_t* info) {
    vim2_display_t* display = ctx;
    mtx_lock(&display->display_lock);
    if (!display->display_attached || display_id != display->display_id) {
        mtx_unlock(&display->display_lock);
        return ZX_ERR_NOT_FOUND;
    }

    info->edid_present = true;
    info->panel.edid.data = display->edid_buf;
    info->panel.edid.length = display->edid_length;
    info->pixel_formats = &_gsupported_pixel_formats;
    info->pixel_format_count = sizeof(_gsupported_pixel_formats) / sizeof(zx_pixel_format_t);

    mtx_unlock(&display->display_lock);
    return ZX_OK;
}

static zx_status_t vim_import_vmo_image(void* ctx, image_t* image, zx_handle_t vmo, size_t offset) {
    image_info_t* import_info = calloc(1, sizeof(image_info_t));
    if (import_info == NULL) {
        return ZX_ERR_NO_MEMORY;
    }

    vim2_display_t* display = ctx;
    zx_status_t status = ZX_OK;
    mtx_lock(&display->image_lock);

    if (image->type != IMAGE_TYPE_SIMPLE || image->pixel_format != display->format) {
        status = ZX_ERR_INVALID_ARGS;
        goto fail;
    }

    uint32_t stride = vim_compute_linear_stride(display, image->width, image->pixel_format);

    canvas_info_t info;
    info.height         = image->height;
    info.stride_bytes   = stride * ZX_PIXEL_FORMAT_BYTES(image->pixel_format);
    info.wrap           = 0;
    info.blkmode        = 0;
    info.endianness     = 0;

    zx_handle_t dup_vmo;
    status = zx_handle_duplicate(vmo, ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
    if (status != ZX_OK) {
        goto fail;
    }

    status = canvas_config(&display->canvas, dup_vmo, offset,
                           &info, &import_info->canvas_idx);
    if (status != ZX_OK) {
        status = ZX_ERR_NO_RESOURCES;
        goto fail;
    }

    list_add_head(&display->imported_images, &import_info->node);
    image->handle = (void*) (uint64_t) import_info->canvas_idx;

    mtx_unlock(&display->image_lock);

    return ZX_OK;
fail:
    mtx_unlock(&display->image_lock);
    free(import_info);
    return status;
}

static void vim_release_image(void* ctx, image_t* image) {
    vim2_display_t* display = ctx;
    mtx_lock(&display->image_lock);

    image_info_t* info;
    list_for_every_entry(&display->imported_images, info, image_info_t, node) {
        if ((void*) (uint64_t) info->canvas_idx == image->handle) {
            list_delete(&info->node);
            break;
        }
    }

    mtx_unlock(&display->image_lock);

    if (info) {
        canvas_free(&display->canvas, info->canvas_idx);
        free(info);
    }
}

static void vim_check_configuration(void* ctx,
                                    const display_config_t** display_configs,
                                    uint32_t* display_cfg_result,
                                    uint32_t** layer_cfg_results,
                                    uint32_t display_count) {
    *display_cfg_result = CONFIG_DISPLAY_OK;
    if (display_count != 1) {
        if (display_count > 1) {
            // The core display driver should never see a configuration with more
            // than 1 display, so this is a bug in the core driver.
            ZX_DEBUG_ASSERT(false);
            *display_cfg_result = CONFIG_DISPLAY_TOO_MANY;
        }
        return;
    }
    vim2_display_t* display = ctx;
    mtx_lock(&display->display_lock);

    // no-op, just wait for the client to try a new config
    if (!display->display_attached || display_configs[0]->display_id != display->display_id) {
        mtx_unlock(&display->display_lock);
        return;
    }

    // TODO: Add support for modesetting
    if (display_configs[0]->mode.h_addressable != display->width
            || display_configs[0]->mode.v_addressable != display->height) {
        mtx_unlock(&display->display_lock);
        *display_cfg_result = CONFIG_DISPLAY_UNSUPPORTED_MODES;
        return;
    }

    bool success;
    if (display_configs[0]->layer_count != 1) {
        success = display_configs[0]->layer_count == 0;
    } else {
        primary_layer_t* layer = &display_configs[0]->layers[0]->cfg.primary;
        frame_t frame = {
                .x_pos = 0, .y_pos = 0, .width = display->width, .height = display->height,
        };
        uint32_t bytes_per_row = vim_compute_linear_stride(display,
                                                           layer->image.width,
                                                           layer->image.pixel_format)
                * ZX_PIXEL_FORMAT_BYTES(layer->image.pixel_format);
        success = display_configs[0]->layers[0]->type == LAYER_PRIMARY
                && layer->transform_mode == FRAME_TRANSFORM_IDENTITY
                && layer->image.width == display->width
                && layer->image.height == display->height
                && layer->image.planes[0].byte_offset == 0
                && (layer->image.planes[0].bytes_per_row == bytes_per_row ||
                    layer->image.planes[0].bytes_per_row == 0)
                && memcmp(&layer->dest_frame, &frame, sizeof(frame_t)) == 0
                && memcmp(&layer->src_frame, &frame, sizeof(frame_t)) == 0
                && display_configs[0]->cc_flags == 0
                && layer->alpha_mode == ALPHA_DISABLE;
    }
    if (!success) {
        layer_cfg_results[0][0] = CLIENT_MERGE_BASE;
        for (unsigned i = 1; i < display_configs[0]->layer_count; i++) {
            layer_cfg_results[0][i] = CLIENT_MERGE_SRC;
        }
    }
    mtx_unlock(&display->display_lock);
}

static void vim_apply_configuration(void* ctx,
                                    const display_config_t** display_configs,
                                    uint32_t display_count) {
    vim2_display_t* display = ctx;
    mtx_lock(&display->display_lock);

    uint8_t addr;
    if (display_count == 1 && display_configs[0]->layer_count) {
        // The only way a checked configuration could now be invalid is if display was
        // unplugged. If that's the case, then the upper layers will give a new configuration
        // once they finish handling the unplug event. So just return.
        if (!display->display_attached || display_configs[0]->display_id != display->display_id) {
            mtx_unlock(&display->display_lock);
            return;
        }
        addr = (uint8_t) (uint64_t) display_configs[0]->layers[0]->cfg.primary.image.handle;
        flip_osd2(display, addr);
    } else {
        disable_osd2(display);
    }

    mtx_unlock(&display->display_lock);
}

static zx_status_t allocate_vmo(void* ctx, uint64_t size, zx_handle_t* vmo_out) {
    vim2_display_t* display = ctx;
    return zx_vmo_create_contiguous(display->bti, size, 0, vmo_out);
}

static display_controller_protocol_ops_t display_controller_ops = {
    .set_display_controller_cb = vim_set_display_controller_cb,
    .get_display_info = vim_get_display_info,
    .import_vmo_image = vim_import_vmo_image,
    .release_image = vim_release_image,
    .check_configuration = vim_check_configuration,
    .apply_configuration = vim_apply_configuration,
    .compute_linear_stride = vim_compute_linear_stride,
    .allocate_vmo = allocate_vmo,
};

static void display_release(void* ctx) {
    vim2_display_t* display = ctx;

    if (display) {
        disable_osd2(display);
        bool wait_for_vsync_shutdown = false;
        if (display->vsync_interrupt != ZX_HANDLE_INVALID) {
            zx_interrupt_trigger(display->vsync_interrupt, 0, 0);
            wait_for_vsync_shutdown = true;
        }

        bool wait_for_main_shutdown = false;
        if (display->inth != ZX_HANDLE_INVALID) {
            zx_interrupt_trigger(display->inth, 0, 0);
            wait_for_main_shutdown = true;
        }

        int res;
        if (wait_for_vsync_shutdown) {
            thrd_join(display->vsync_thread, &res);
        }

        if (wait_for_main_shutdown) {
            thrd_join(display->main_thread, &res);
        }

        gpio_release_interrupt(&display->gpio, 0);
        io_buffer_release(&display->mmio_preset);
        io_buffer_release(&display->mmio_hdmitx);
        io_buffer_release(&display->mmio_hiu);
        io_buffer_release(&display->mmio_vpu);
        io_buffer_release(&display->mmio_hdmitx_sec);
        io_buffer_release(&display->mmio_cbus);
        zx_handle_close(display->bti);
        zx_handle_close(display->vsync_interrupt);
        zx_handle_close(display->inth);
        free(display->edid_buf);
        free(display->p);
    }
    free(display);
}

static void display_unbind(void* ctx) {
    vim2_display_t* display = ctx;
    device_remove(display->mydevice);
}

static zx_protocol_device_t main_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .release =  display_release,
    .unbind = display_unbind,
};

static zx_status_t setup_hdmi(vim2_display_t* display)
{
    zx_status_t status;
    // initialize HDMI
    status = init_hdmi_hardware(display);
    if (status != ZX_OK) {
        DISP_ERROR("HDMI hardware initialization failed\n");
        return status;
    }

    status = get_preferred_res(display, EDID_BUF_SIZE);
    if (status != ZX_OK) {
        DISP_ERROR("No display connected!\n");
        return status;

    }

    // allocate frame buffer
    display->format = ZX_PIXEL_FORMAT_RGB_x888;
    display->width  = display->p->timings.hactive;
    display->height = display->p->timings.vactive;
    display->stride = vim_compute_linear_stride(
                      display, display->p->timings.hactive, display->format);
    display->input_color_format = _ginput_color_format;
    display->color_depth = _gcolor_depth;

    status = init_hdmi_interface(display, display->p);
    if (status != ZX_OK) {
        DISP_ERROR("HDMI interface initialization failed\n");
        return status;
    }

    /* OSD2 setup */
    configure_osd2(display);

    return ZX_OK;
}

static int hdmi_irq_handler(void *arg) {
    vim2_display_t* display = arg;
    zx_status_t status;
    while(1) {
        status = zx_interrupt_wait(display->inth, NULL);
        if (status != ZX_OK) {
            DISP_ERROR("Waiting in Interrupt failed %d\n", status);
            return -1;
        }
        usleep(500000);
        uint8_t hpd;
        status = gpio_read(&display->gpio, 0, &hpd);
        if (status != ZX_OK) {
            DISP_ERROR("gpio_read failed HDMI HPD\n");
            continue;
        }

        mtx_lock(&display->cb_lock);
        mtx_lock(&display->display_lock);

        uint64_t display_added = INVALID_DISPLAY_ID;
        uint64_t display_removed = INVALID_DISPLAY_ID;
        if (hpd && !display->display_attached) {
            DISP_ERROR("Display is connected\n");
            if (setup_hdmi(display) == ZX_OK) {
                display->display_attached = true;
                display_added = display->display_id;
                gpio_set_polarity(&display->gpio, 0, GPIO_POLARITY_LOW);
            }
        } else if (!hpd && display->display_attached) {
            DISP_ERROR("Display Disconnected!\n");
            hdmi_shutdown(display);

            display_removed = display->display_id;
            display->display_id++;
            display->display_attached = false;

            gpio_set_polarity(&display->gpio, 0, GPIO_POLARITY_HIGH);
        }

        mtx_unlock(&display->display_lock);

        if (display->dc_cb &&
                (display_removed != INVALID_DISPLAY_ID || display_added != INVALID_DISPLAY_ID)) {
            display->dc_cb->on_displays_changed(display->dc_cb_ctx,
                                                &display_added,
                                                display_added != INVALID_DISPLAY_ID,
                                                &display_removed,
                                                display_removed != INVALID_DISPLAY_ID);
        }

        mtx_unlock(&display->cb_lock);
    }
}

static int vsync_thread(void *arg)
{
    vim2_display_t* display = arg;

    for (;;) {
        zx_status_t status;
        zx_time_t timestamp;
        status = zx_interrupt_wait(display->vsync_interrupt, &timestamp);
        if (status != ZX_OK) {
            DISP_INFO("Vsync wait failed");
            break;
        }

        mtx_lock(&display->cb_lock);
        mtx_lock(&display->display_lock);

        uint64_t display_id = display->display_id;
        bool attached = display->display_attached;
        void* live = (void*) (uint64_t) display->current_image;
        bool current_image_valid = display->current_image_valid;
        mtx_unlock(&display->display_lock);

        if (display->dc_cb && attached) {
            display->dc_cb->on_display_vsync(display->dc_cb_ctx, display_id, timestamp,
                                             &live, current_image_valid);
        }

        mtx_unlock(&display->cb_lock);
    }

    return 0;
}

zx_status_t vim2_display_bind(void* ctx, zx_device_t* parent) {
    vim2_display_t* display = calloc(1, sizeof(vim2_display_t));
    if (!display) {
        DISP_ERROR("Could not allocated display structure\n");
        return ZX_ERR_NO_MEMORY;
    }

    display->parent = parent;

    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &display->pdev);
    if (status !=  ZX_OK) {
        DISP_ERROR("Could not get parent protocol\n");
        goto fail;
    }

    // Test for platform device get_board_info support.
    pdev_board_info_t board_info;
    pdev_get_board_info(&display->pdev, &board_info);
    printf("BOARD INFO: %d %d %s %d\n", board_info.vid, board_info.pid, board_info.board_name,
           board_info.board_revision);
    assert(board_info.vid == PDEV_VID_KHADAS);
    assert(board_info.pid == PDEV_PID_VIM2);
    assert(!strcmp(board_info.board_name, "vim2"));
    assert(board_info.board_revision == 1234);

    status = pdev_get_bti(&display->pdev, 0, &display->bti);
    if (status != ZX_OK) {
        DISP_ERROR("Could not get BTI handle\n");
        goto fail;
    }

    status = device_get_protocol(parent, ZX_PROTOCOL_GPIO, &display->gpio);
    if (status != ZX_OK) {
        DISP_ERROR("Could not get Display GPIO protocol\n");
        goto fail;
    }

    status = device_get_protocol(parent, ZX_PROTOCOL_CANVAS, &display->canvas);
    if (status != ZX_OK) {
        DISP_ERROR("Could not get Display CANVAS protocol\n");
        goto fail;
    }

    // Map all the various MMIOs
    pdev_device_info_t dev_info;
    status = pdev_get_device_info(&display->pdev, &dev_info);
    if (status != ZX_OK) {
        DISP_ERROR("Failed to fetch device info (status %d)\n", status);
        goto fail;
    }

    if (dev_info.mmio_count != MMIO_COUNT) {
        DISP_ERROR("MMIO region count mismatch!  Expected %u regions to be supplied by board "
                   "driver, but only %u were passed\n", MMIO_COUNT, dev_info.mmio_count);
        goto fail;
    }

    status = pdev_map_mmio_buffer(&display->pdev, MMIO_PRESET, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &display->mmio_preset);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO PRESET\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&display->pdev, MMIO_HDMITX, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &display->mmio_hdmitx);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO HDMITX\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&display->pdev, MMIO_HIU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &display->mmio_hiu);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO HIU\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&display->pdev, MMIO_VPU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &display->mmio_vpu);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO VPU\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&display->pdev, MMIO_HDMTX_SEC, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &display->mmio_hdmitx_sec);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO HDMITX SEC\n");
        goto fail;
    }

    status = pdev_map_mmio_buffer(&display->pdev, MMIO_CBUS, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &display->mmio_cbus);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO CBUS\n");
        goto fail;
    }

    status = gpio_config(&display->gpio, 0, GPIO_DIR_IN | GPIO_PULL_DOWN);
    if (status != ZX_OK) {
        DISP_ERROR("gpio_config failed for gpio\n");
        goto fail;
    }

    status = gpio_get_interrupt(&display->gpio, 0, ZX_INTERRUPT_MODE_LEVEL_HIGH, &display->inth);
    if (status != ZX_OK) {
        DISP_ERROR("gpio_get_interrupt failed for gpio\n");
        goto fail;
    }

    status = pdev_map_interrupt(&display->pdev, 0, &display->vsync_interrupt);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map vsync interrupt\n");
        goto fail;
    }
    // For some reason the vsync interrupt enable bit needs to be cleared for
    // vsync interrupts to occur at the correct rate.
    *((uint32_t*)(display->mmio_vpu.virt + VPU_VIU_MISC_CTRL0)) &= ~(1 << 8);

    // Create EDID Buffer
    display->edid_buf = calloc(1, EDID_BUF_SIZE);
    if (!display->edid_buf) {
        DISP_ERROR("Could not allocated EDID BUf of size %d\n", EDID_BUF_SIZE);
        goto fail;
    }

    display->p = calloc(1, sizeof(struct hdmi_param));
    if (!display->p) {
        DISP_ERROR("Could not allocated hdmi param structure\n");
        goto fail;
    }

    device_add_args_t add_args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "vim2-display",
        .ctx = display,
        .ops = &main_device_proto,
        .proto_id = ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL,
        .proto_ops = &display_controller_ops,
    };

    status = device_add(display->parent, &add_args, &display->mydevice);
    if (status != ZX_OK) {
        DISP_ERROR("Could not add device\n");
        goto fail;
    }

    display->display_id = 1;
    display->display_attached = false;
    list_initialize(&display->imported_images);
    mtx_init(&display->display_lock, mtx_plain);
    mtx_init(&display->image_lock, mtx_plain);
    mtx_init(&display->cb_lock, mtx_plain);

    thrd_create_with_name(&display->main_thread, hdmi_irq_handler, display, "hdmi_irq_handler");
    thrd_create_with_name(&display->vsync_thread, vsync_thread, display, "vsync_thread");

    return ZX_OK;

fail:
    DISP_ERROR("bind failed! %d\n", status);
    display_release(display);
    return status;

}

static zx_driver_ops_t vim2_display_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = vim2_display_bind,
};

ZIRCON_DRIVER_BEGIN(vim2_display, vim2_display_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_DEV),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_KHADAS),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_VIM_DISPLAY),
ZIRCON_DRIVER_END(vim_2display)
