// 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/platform-defs.h>
#include <ddk/protocol/display/controller.h>
#include <ddk/protocol/i2cimpl.h>
#include <ddk/protocol/platform/device.h>
#include <ddk/protocol/platform-device-lib.h>
#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <fbl/unique_ptr.h>
#include <hw/arch_ops.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/pixelformat.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 zx_pixel_format_t _gsupported_pixel_formats[] = { ZX_PIXEL_FORMAT_RGB_x888, ZX_PIXEL_FORMAT_NV12 };

typedef struct image_info {
    zx_handle_t pmt;
    zx_pixel_format_t format;
    uint8_t canvas_idx[2];

    list_node_t node;
} image_info_t;

void populate_added_display_args(vim2_display_t* display, added_display_args_t* args) {
    args->display_id = display->display_id;
    args->edid_present = true;
    args->panel.i2c_bus_id = 0;
    args->pixel_format_list = _gsupported_pixel_formats;
    args->pixel_format_count = countof(_gsupported_pixel_formats);
    args->cursor_info_count = 0;
}

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_interface(void* ctx,
                                                 const display_controller_interface_t* intf) {
    vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
    mtx_lock(&display->display_lock);

    display->dc_intf = *intf;

    if (display->display_attached) {
        added_display_args_t args;
        added_display_info_t info;
        populate_added_display_args(display, &args);
        display_controller_interface_on_displays_changed(&display->dc_intf, &args, 1, NULL, 0,
                                                         &info, 1, NULL);

        if (info.is_standard_srgb_out) {
            display->output_color_format = HDMI_COLOR_FORMAT_RGB;
        } else {
            display->output_color_format = HDMI_COLOR_FORMAT_444;
        }
    }
    mtx_unlock(&display->display_lock);
}

static zx_status_t vim_import_vmo_image(void* ctx, image_t* image, zx_handle_t vmo_in, size_t offset) {
    zx::vmo vmo(vmo_in);

    fbl::AllocChecker ac;
    fbl::unique_ptr<image_info_t> import_info = fbl::make_unique_checked<image_info_t>(&ac);
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
    fbl::AutoLock lock(&display->image_lock);

    if (image->type != IMAGE_TYPE_SIMPLE)
        return ZX_ERR_INVALID_ARGS;

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

    if (image->pixel_format == ZX_PIXEL_FORMAT_RGB_x888) {
        zx_status_t status = ZX_OK;
        canvas_info_t info;
        info.height = image->height;
        info.stride_bytes = image->planes[0].bytes_per_row;
        if (info.stride_bytes == 0) {
            info.stride_bytes = stride * ZX_PIXEL_FORMAT_BYTES(image->pixel_format);
        }
        info.wrap = 0;
        info.blkmode = 0;
        info.endianness = 0;

        status = amlogic_canvas_config(&display->canvas, vmo.release(),
                                       offset + image->planes[0].byte_offset,
                                       &info, &import_info->canvas_idx[0]);
        if (status != ZX_OK) {
            return ZX_ERR_NO_RESOURCES;
        }
        image->handle = import_info->canvas_idx[0];
    } else if (image->pixel_format == ZX_PIXEL_FORMAT_NV12) {
        if (image->height % 2 != 0) {
            return ZX_ERR_INVALID_ARGS;
        }
        zx_status_t status = ZX_OK;
        canvas_info_t info;
        info.height = image->height;
        info.stride_bytes = image->planes[0].bytes_per_row;
        if (info.stride_bytes == 0) {
            info.stride_bytes = stride * ZX_PIXEL_FORMAT_BYTES(image->pixel_format);
        }
        info.wrap = 0;
        info.blkmode = 0;
        // Do 64-bit endianness conversion.
        info.endianness = 7;

        zx::vmo dup_vmo;
        status = vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
        if (status != ZX_OK) {
            return status;
        }

        status = amlogic_canvas_config(&display->canvas, dup_vmo.release(),
                                       offset + image->planes[0].byte_offset,
                                       &info, &import_info->canvas_idx[0]);
        if (status != ZX_OK) {
            return ZX_ERR_NO_RESOURCES;
        }

        info.height /= 2;
        info.stride_bytes = image->planes[1].bytes_per_row;
        if (info.stride_bytes == 0)
            info.stride_bytes = stride * ZX_PIXEL_FORMAT_BYTES(image->pixel_format);

        status = amlogic_canvas_config(&display->canvas, vmo.release(),
                                       offset + image->planes[1].byte_offset,
                                       &info, &import_info->canvas_idx[1]);
        if (status != ZX_OK) {
            amlogic_canvas_free(&display->canvas, import_info->canvas_idx[0]);
            return ZX_ERR_NO_RESOURCES;
        }
        // The handle used by hardware is VVUUYY, so the UV plane is included twice.
        image->handle = (((uint64_t)import_info->canvas_idx[1] << 16) |
                         (import_info->canvas_idx[1] << 8) | import_info->canvas_idx[0]);
    } else {
        return ZX_ERR_INVALID_ARGS;
    }

    list_add_head(&display->imported_images, &import_info.release()->node);

    return ZX_OK;
}

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

    image_info_t* info;
    uint32_t canvas_idx0 = (uint64_t)image->handle & 0xff;
    uint32_t canvas_idx1 = ((uint64_t)image->handle >> 8) & 0xff;
    list_for_every_entry(&display->imported_images, info, image_info_t, node) {
        if (info->canvas_idx[0] == canvas_idx0 && info->canvas_idx[1] == canvas_idx1) {
            list_delete(&info->node);
            break;
        }
    }

    mtx_unlock(&display->image_lock);

    if (info) {
        amlogic_canvas_free(&display->canvas, info->canvas_idx[0]);
        if (info->format == ZX_PIXEL_FORMAT_NV12)
            amlogic_canvas_free(&display->canvas, info->canvas_idx[1]);
        free(info);
    }
}

static uint32_t vim_check_configuration(void* ctx,
                                        const display_config_t** display_configs,
                                        size_t display_count,
                                        uint32_t** layer_cfg_results,
                                        size_t* layer_cfg_result_count) {
    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);
            return CONFIG_DISPLAY_TOO_MANY;
        }
        return CONFIG_DISPLAY_OK;
    }
    vim2_display_t* display = static_cast<vim2_display_t*>(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 CONFIG_DISPLAY_OK;
    }

    struct hdmi_param p;
    if ((memcmp(&display->cur_display_mode, &display_configs[0]->mode, sizeof(display_mode_t))
            && get_vic(&display_configs[0]->mode, &p) != ZX_OK)
            || (display_configs[0]->mode.v_addressable % 8)) {
        mtx_unlock(&display->display_lock);
        return CONFIG_DISPLAY_UNSUPPORTED_MODES;
    }

    bool success;
    if (display_configs[0]->layer_count != 1) {
        success = display_configs[0]->layer_count == 0;
    } else {
        uint32_t width = display_configs[0]->mode.h_addressable;
        uint32_t height = display_configs[0]->mode.v_addressable;
        primary_layer_t* layer = &display_configs[0]->layer_list[0]->cfg.primary;
        frame_t frame = {
                .x_pos = 0, .y_pos = 0, .width = width, .height = 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]->layer_list[0]->type == LAYER_TYPE_PRIMARY
                && layer->transform_mode == FRAME_TRANSFORM_IDENTITY
                && layer->image.width == width
                && layer->image.height == 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;
        }
        layer_cfg_result_count[0] = display_configs[0]->layer_count;
    }
    mtx_unlock(&display->display_lock);
    return CONFIG_DISPLAY_OK;
}

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

    if (display_count == 1 && display_configs[0]->layer_count) {
        if (memcmp(&display->cur_display_mode, &display_configs[0]->mode, sizeof(display_mode_t))) {
            zx_status_t status = get_vic(&display_configs[0]->mode, display->p);
            if (status != ZX_OK) {
                mtx_unlock(&display->display_lock);
                zxlogf(ERROR, "Apply with bad mode\n");
                return;
            }

            memcpy(&display->cur_display_mode, &display_configs[0]->mode, sizeof(display_mode_t));

            init_hdmi_interface(display, display->p);
            configure_osd(display, 1);
            configure_vd(display, 0);
            disable_osd(display, 0); // OSD1 is never used and if not disabled can cover up OSD2 and VD0.
        }

        // 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;
        }
        if (display_configs[0]->layer_list[0]->cfg.primary.image.pixel_format == ZX_PIXEL_FORMAT_NV12) {
            uint32_t addr =
                (uint32_t)(uint64_t)display_configs[0]->layer_list[0]->cfg.primary.image.handle;
            flip_vd(display, 0, addr);
            disable_osd(display, 1);
        } else {
            uint8_t addr;
            addr = (uint8_t)(uint64_t)display_configs[0]->layer_list[0]->cfg.primary.image.handle;
            flip_osd(display, 1, addr);
            disable_vd(display, 0);
        }
    } else {
        disable_vd(display, 0);
        disable_osd(display, 1);
    }

    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 = static_cast<vim2_display_t*>(ctx);
    zx_status_t status = zx_vmo_create_contiguous(display->bti, size, 0, vmo_out);
    static const char kVmoName[] = "vim_framebuffer";
    if (status == ZX_OK)
        zx_object_set_property(*vmo_out, ZX_PROP_NAME, kVmoName, sizeof(kVmoName));
    return status;
}

static display_controller_impl_protocol_ops_t display_controller_ops = {
    .set_display_controller_interface = vim_set_display_controller_interface,
    .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 uint32_t get_bus_count(void* ctx) {
    return 1;
}

static zx_status_t get_max_transfer_size(void* ctx, uint32_t bus_id, size_t* out_size) {
    *out_size = UINT32_MAX;
    return ZX_OK;
}

static zx_status_t set_bitrate(void* ctx, uint32_t bus_id, uint32_t bitrate) {
    // no-op
    return ZX_OK;
}

static zx_status_t transact(void* ctx, uint32_t bus_id, const i2c_impl_op_t* ops, size_t count) {
    vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
    mtx_lock(&display->i2c_lock);

    uint8_t segment_num = 0;
    uint8_t offset = 0;
    for (unsigned i = 0; i < count; i++) {
        auto op = ops[i];

        // The HDMITX_DWC_I2CM registers are a limited interface to the i2c bus for the E-DDC
        // protocol, which is good enough for the bus this device provides.
        if (op.address == 0x30 && !op.is_read && op.data_size == 1) {
            segment_num = *((const uint8_t*) op.data_buffer);
        } else if (op.address == 0x50 && !op.is_read && op.data_size == 1) {
            offset = *((const uint8_t*) op.data_buffer);
        } else if (op.address == 0x50 && op.is_read) {
            if (op.data_size % 8 != 0) {
                mtx_unlock(&display->i2c_lock);
                return ZX_ERR_NOT_SUPPORTED;
            }

            hdmitx_writereg(display, HDMITX_DWC_I2CM_SLAVE, 0x50);
            hdmitx_writereg(display, HDMITX_DWC_I2CM_SEGADDR, 0x30);
            hdmitx_writereg(display, HDMITX_DWC_I2CM_SEGPTR, segment_num);

            for (uint32_t i = 0; i < op.data_size; i += 8) {
                hdmitx_writereg(display, HDMITX_DWC_I2CM_ADDRESS, offset);
                hdmitx_writereg(display, HDMITX_DWC_I2CM_OPERATION, 1 << 2);
                offset = static_cast<uint8_t>(offset + 8);

                uint32_t timeout = 0;
                while ((!(hdmitx_readreg(display, HDMITX_DWC_IH_I2CM_STAT0) & (1 << 1)))
                        && (timeout < 5)) {
                    usleep(1000);
                    timeout ++;
                }
                if (timeout == 5) {
                    DISP_ERROR("HDMI DDC TimeOut\n");
                    mtx_unlock(&display->i2c_lock);
                    return ZX_ERR_TIMED_OUT;
                }
                usleep(1000);
                hdmitx_writereg(display, HDMITX_DWC_IH_I2CM_STAT0, 1 << 1);        // clear INT

                for (int j = 0; j < 8; j++) {
                    uint32_t address = static_cast<uint32_t>(HDMITX_DWC_I2CM_READ_BUFF0 + j);
                    ((uint8_t*) op.data_buffer)[i + j] =
                            static_cast<uint8_t>(hdmitx_readreg(display, address));
                }
            }
        } else {
            mtx_unlock(&display->i2c_lock);
            return ZX_ERR_NOT_SUPPORTED;
        }

        if (op.stop) {
            segment_num = 0;
            offset = 0;
        }
    }

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

static i2c_impl_protocol_ops_t i2c_impl_ops = {
    .get_bus_count = get_bus_count,
    .get_max_transfer_size = get_max_transfer_size,
    .set_bitrate = set_bitrate,
    .transact = transact,
};

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

    if (display) {
        disable_osd(display, 1);
        disable_vd(display, 0);
        release_osd(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);
        display->mmio_preset.reset();
        display->mmio_hdmitx.reset();
        display->mmio_hiu.reset();
        display->mmio_vpu.reset();
        display->mmio_hdmitx_sec.reset();
        display->mmio_cbus.reset();
        zx_handle_close(display->bti);
        zx_handle_close(display->vsync_interrupt);
        zx_handle_close(display->inth);
        free(display->p);
    }
    free(display);
}

static void display_unbind(void* ctx) {
    vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
    vim2_audio_shutdown(&display->audio);
    device_remove(display->mydevice);
}

static zx_status_t display_get_protocol(void* ctx, uint32_t proto_id, void* protocol) {
    if (proto_id == ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL) {
        auto ops = static_cast<display_controller_impl_protocol_t*>(protocol);
        ops->ctx = ctx;
        ops->ops = &display_controller_ops;
    } else if (proto_id == ZX_PROTOCOL_I2C_IMPL) {
        auto ops = static_cast<i2c_impl_protocol_t*>(protocol);
        ops->ctx = ctx;
        ops->ops = &i2c_impl_ops;
    } else {
        return ZX_ERR_NOT_SUPPORTED;
    }
    return ZX_OK;
}

static zx_protocol_device_t main_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .get_protocol = display_get_protocol,
    .open = nullptr,
    .open_at = nullptr,
    .close = nullptr,
    .unbind = display_unbind,
    .release =  display_release,
    .read = nullptr,
    .write = nullptr,
    .get_size = nullptr,
    .ioctl = nullptr,
    .suspend = nullptr,
    .resume = nullptr,
    .rxrpc = nullptr,
    .message = nullptr,
};

static int hdmi_irq_handler(void *arg) {
    vim2_display_t* display = static_cast<vim2_display_t*>(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, &hpd);
        if (status != ZX_OK) {
            DISP_ERROR("gpio_read failed HDMI HPD\n");
            continue;
        }

        mtx_lock(&display->display_lock);

        bool display_added = false;
        added_display_args_t args;
        added_display_info_t info;
        uint64_t display_removed = INVALID_DISPLAY_ID;
        if (hpd && !display->display_attached) {
            DISP_ERROR("Display is connected\n");

            display->display_attached = true;
            memset(&display->cur_display_mode, 0, sizeof(display_mode_t));
            populate_added_display_args(display, &args);
            display_added = true;
            gpio_set_polarity(&display->gpio, 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, GPIO_POLARITY_HIGH);
        }

        if (display->dc_intf.ops &&
                (display_removed != INVALID_DISPLAY_ID || display_added)) {
            display_controller_interface_on_displays_changed(&display->dc_intf,
                                                             &args,
                                                             display_added ? 1 : 0,
                                                             &display_removed,
                                                             display_removed != INVALID_DISPLAY_ID,
                                                             &info,
                                                             display_added ? 1 : 0,
                                                             NULL);
            if (display_added) {
                // See if we need to change output color to RGB
                if (info.is_standard_srgb_out) {
                    display->output_color_format = HDMI_COLOR_FORMAT_RGB;
                } else {
                    display->output_color_format = HDMI_COLOR_FORMAT_444;
                }
                display->audio_format_count = info.audio_format_count;

                display->manufacturer_name = info.manufacturer_name;
                memcpy(display->monitor_name, info.monitor_name, sizeof(info.monitor_name));
                memcpy(display->monitor_serial, info.monitor_serial, sizeof(info.monitor_serial));
                static_assert(sizeof(display->monitor_name) == sizeof(info.monitor_name), "");
                static_assert(sizeof(display->monitor_serial) == sizeof(info.monitor_serial), "");
            }
        }

        mtx_unlock(&display->display_lock);

        if (display_removed != INVALID_DISPLAY_ID) {
            vim2_audio_on_display_removed(display, display_removed);
        }

        if (display_added && info.audio_format_count) {
            vim2_audio_on_display_added(display, display->display_id);
        }
    }
}

static int vsync_thread(void *arg) {
    vim2_display_t* display = static_cast<vim2_display_t*>(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->display_lock);

        uint64_t display_id = display->display_id;
        bool attached = display->display_attached;
        uint64_t live[2] = {};
        uint32_t current_image_count = 0;
        if (display->current_image_valid) {
            live[current_image_count++] = display->current_image;
        }
        if (display->vd1_image_valid) {
            live[current_image_count++] = display->vd1_image;
        }

        if (display->dc_intf.ops && attached) {
            display_controller_interface_on_display_vsync(&display->dc_intf, display_id, timestamp,
                                                          live, current_image_count);
        }
        mtx_unlock(&display->display_lock);
    }

    return 0;
}

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

    zx_status_t status = ZX_ERR_INTERNAL;
    display->parent = parent;

    // If anything goes wrong from here on out, make sure to log the status code
    // of the error, and destroy our display object.
    auto cleanup = fbl::MakeAutoCall([&]() {
        DISP_ERROR("bind failed! %d\n", status);
        display_release(display);
    });

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

    // 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);

    // Fetch the device info and sanity check our resource counts.
    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);
        return status;
    }

    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);
        return status;
    }

    if (dev_info.bti_count != BTI_COUNT) {
        DISP_ERROR("BTI count mismatch!  Expected %u BTIs to be supplied by board "
                   "driver, but only %u were passed\n", BTI_COUNT, dev_info.bti_count);
        return status;
    }

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

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

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

    // Map all the various MMIOs
    mmio_buffer_t mmio;
    status = pdev_map_mmio_buffer2(&display->pdev, MMIO_PRESET, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &mmio);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO PRESET\n");
        return status;
    }
    display->mmio_preset = ddk::MmioBuffer(mmio);

    status = pdev_map_mmio_buffer2(&display->pdev, MMIO_HDMITX, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &mmio);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO HDMITX\n");
        return status;
    }
    display->mmio_hdmitx = ddk::MmioBuffer(mmio);

    status = pdev_map_mmio_buffer2(&display->pdev, MMIO_HIU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &mmio);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO HIU\n");
        return status;
    }
    display->mmio_hiu = ddk::MmioBuffer(mmio);

    status = pdev_map_mmio_buffer2(&display->pdev, MMIO_VPU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &mmio);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO VPU\n");
        return status;
    }
    display->mmio_vpu = ddk::MmioBuffer(mmio);

    status = pdev_map_mmio_buffer2(&display->pdev, MMIO_HDMTX_SEC, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &mmio);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO HDMITX SEC\n");
        return status;
    }
    display->mmio_hdmitx_sec = ddk::MmioBuffer(mmio);

    status = pdev_map_mmio_buffer2(&display->pdev, MMIO_CBUS, ZX_CACHE_POLICY_UNCACHED_DEVICE,
        &mmio);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map display MMIO CBUS\n");
        return status;
    }
    display->mmio_cbus = ddk::MmioBuffer(mmio);

    status = gpio_config_in(&display->gpio, GPIO_PULL_DOWN);
    if (status != ZX_OK) {
        DISP_ERROR("gpio_config_in failed for gpio\n");
        return status;
    }

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

    status = pdev_map_interrupt(&display->pdev, IRQ_VSYNC, &display->vsync_interrupt);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map vsync interrupt\n");
        return status;
    }

    status = pdev_map_interrupt(&display->pdev, IRQ_RDMA, &display->rdma_interrupt);
    if (status != ZX_OK) {
        DISP_ERROR("Could not map RDMA interrupt\n");
        return status;
    }

    status = vim2_audio_create(&display->pdev, &display->audio);
    if (status != ZX_OK) {
        DISP_ERROR("Failed to create DAI controller (status %d)\n", status);
        return status;
    }

    // For some reason the vsync interrupt enable bit needs to be cleared for
    // vsync interrupts to occur at the correct rate.
    display->mmio_vpu->ClearBits32(1 << 8, VPU_VIU_MISC_CTRL0);

    // Setup RDMA
    status = setup_rdma(display);
    if (status != ZX_OK) {
        DISP_ERROR("Could not setup RDMA (status %d)\n", status);
        return status;
    }

    fbl::AllocChecker ac;
    display->p = new(&ac) struct hdmi_param();
    if (!ac.check()) {
        DISP_ERROR("Could not allocated hdmi param structure\n");
        DISP_ERROR("bind failed! %d\n", status);
        display_release(display);
        return status;
    }

    // initialize HDMI
    display->input_color_format = _ginput_color_format;
    display->color_depth = _gcolor_depth;
    init_hdmi_hardware(display);

    device_add_args_t add_args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "vim2-display",
        .ctx = display,
        .ops = &main_device_proto,
        .props = nullptr,
        .prop_count = 0,
        .proto_id = ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL,
        .proto_ops = &display_controller_ops,
        .proxy_args = nullptr,
        .flags = 0,
        .client_remote = ZX_HANDLE_INVALID,
    };

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

    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->i2c_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");
    thrd_create_with_name(&display->rdma_thread, rdma_thread, display, "rdma_thread");

    // Things went well!  Cancel our cleanup auto call
    cleanup.cancel();
    return ZX_OK;
}

zx_status_t vim2_display_configure_audio_mode(const vim2_display_t* display,
                                              uint32_t N,
                                              uint32_t CTS,
                                              uint32_t frame_rate,
                                              uint32_t bits_per_sample) {
    ZX_DEBUG_ASSERT(display != NULL);

    if ((N > 0xFFFFF) || (CTS > 0xFFFFF) || (bits_per_sample < 16) || (bits_per_sample > 24)) {
        vim2_display_disable_audio(display);
        return ZX_ERR_INVALID_ARGS;
    }

    ZX_DEBUG_ASSERT(display != NULL);
    hdmitx_writereg(display, HDMITX_DWC_AUD_CONF0,  0u);  // Make sure that I2S is deselected
    hdmitx_writereg(display, HDMITX_DWC_AUD_SPDIF2, 0u);  // Deselect SPDIF

    // Select non-HBR linear PCM, as well as the proper number of bits per sample.
    hdmitx_writereg(display, HDMITX_DWC_AUD_SPDIF1, bits_per_sample);

    // Set the N/CTS parameters using DesignWare's atomic update sequence
    //
    // For details, refer to...
    // DesignWare Cores HDMI Transmitter Controler Databook v2.12a Sections 6.8.3 Table 6-282
    hdmitx_writereg(display, HDMITX_DWC_AUD_N3,
                   ((N >> AUD_N3_N_START_BIT) & AUD_N3_N_MASK) | AUD_N3_ATOMIC_WRITE);
    hw_wmb();
    hdmitx_writereg(display, HDMITX_DWC_AUD_CTS3,
                   ((CTS >> AUD_CTS3_CTS_START_BIT) & AUD_CTS3_CTS_MASK));
    hdmitx_writereg(display, HDMITX_DWC_AUD_CTS2,
                   ((CTS >> AUD_CTS2_CTS_START_BIT) & AUD_CTS2_CTS_MASK));
    hdmitx_writereg(display, HDMITX_DWC_AUD_CTS1,
                   ((CTS >> AUD_CTS1_CTS_START_BIT) & AUD_CTS1_CTS_MASK));
    hdmitx_writereg(display, HDMITX_DWC_AUD_N3,
                   ((N >> AUD_N3_N_START_BIT) & AUD_N3_N_MASK) | AUD_N3_ATOMIC_WRITE);
    hdmitx_writereg(display, HDMITX_DWC_AUD_N2, ((N >> AUD_N2_N_START_BIT) & AUD_N2_N_MASK));
    hw_wmb();
    hdmitx_writereg(display, HDMITX_DWC_AUD_N1, ((N >> AUD_N1_N_START_BIT) & AUD_N1_N_MASK));

    // Select SPDIF data stream 0 (coming from the AmLogic section of the S912)
    hdmitx_writereg(display, HDMITX_DWC_AUD_SPDIF2, AUD_SPDIF2_ENB_ISPDIFDATA0);

    // Reset the SPDIF FIFO
    hdmitx_writereg(display, HDMITX_DWC_AUD_SPDIF0, AUD_SPDIF0_SW_FIFO_RESET);
    hw_wmb();

    // Now, as required, reset the SPDIF sampler.
    // See Section 6.9.1 of the DW HDMT TX controller databook
    hdmitx_writereg(display, HDMITX_DWC_MC_SWRSTZREQ, 0xEF);
    hw_wmb();

    // Set up the audio infoframe.  Refer to the follow specifications for
    // details about how to do this.
    //
    // DesignWare Cores HDMI Transmitter Controler Databook v2.12a Sections 6.5.35 - 6.5.37
    // CTA-861-G Section 6.6

    uint32_t CT = 0x01;   // Coding type == LPCM
    uint32_t CC = 0x01;   // Channel count = 2
    uint32_t CA = 0x00;   // Channel allocation; currently we hardcode FL/FR

    // Sample size
    uint32_t SS;
    switch (bits_per_sample) {
    case 16: SS = 0x01; break;
    case 20: SS = 0x02; break;
    case 24: SS = 0x03; break;
    default: SS = 0x00; break; // "refer to stream"
    }

    // Sample frequency
    uint32_t SF;
    switch (frame_rate) {
    case 32000:  SF = 0x01; break;
    case 44100:  SF = 0x02; break;
    case 48000:  SF = 0x03; break;
    case 88200:  SF = 0x04; break;
    case 96000:  SF = 0x05; break;
    case 176400: SF = 0x06; break;
    case 192000: SF = 0x07; break;
    default:     SF = 0x00; break; // "refer to stream"
    }

    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF0, (CT & 0xF) | ((CC & 0x7) << 4));
    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF1, (SF & 0x7) | ((SS & 0x3) << 4));
    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF2, CA);
    // Right now, we just hardcode the following...
    // LSV    : Level shift value == 0dB
    // DM_INH : Downmix inhibit == down-mixing permitted.
    // LFEPBL : LFE playback level unknown.
    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF3, 0u);

    return ZX_OK;
}

void vim2_display_disable_audio(const vim2_display_t* display) {
    ZX_DEBUG_ASSERT(display != NULL);
    hdmitx_writereg(display, HDMITX_DWC_AUD_CONF0,  0u);  // Deselect I2S
    hdmitx_writereg(display, HDMITX_DWC_AUD_SPDIF2, 0u);  // Deselect SPDIF

    // Set the N/CTS parameters to 0 using DesignWare's atomic update sequence
    hdmitx_writereg(display, HDMITX_DWC_AUD_N3, 0x80);
    hdmitx_writereg(display, HDMITX_DWC_AUD_CTS3, 0u);
    hdmitx_writereg(display, HDMITX_DWC_AUD_CTS2, 0u);
    hdmitx_writereg(display, HDMITX_DWC_AUD_CTS1, 0u);
    hdmitx_writereg(display, HDMITX_DWC_AUD_N3, 0x80);
    hdmitx_writereg(display, HDMITX_DWC_AUD_N2, 0u);
    hw_wmb();
    hdmitx_writereg(display, HDMITX_DWC_AUD_N1, 0u);

    // Reset the audio info frame to defaults.
    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF0, 0u);
    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF1, 0u);
    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF2, 0u);
    hdmitx_writereg(display, HDMITX_DWC_FC_AUDICONF3, 0u);
}

static zx_driver_ops_t vim2_display_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .init = nullptr,
    .bind = vim2_display_bind,
    .create = nullptr,
    .release = nullptr,
};

ZIRCON_DRIVER_BEGIN(vim2_display, vim2_display_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PDEV),
    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)
