// 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 <assert.h>
#include <fuchsia/hardware/amlogiccanvas/cpp/banjo.h>
#include <fuchsia/hardware/display/controller/c/banjo.h>
#include <fuchsia/hardware/gpio/cpp/banjo.h>
#include <fuchsia/hardware/i2cimpl/c/banjo.h>
#include <fuchsia/hardware/platform/device/c/banjo.h>
#include <fuchsia/hardware/sysmem/cpp/banjo.h>
#include <fuchsia/sysmem/c/fidl.h>
#include <lib/device-protocol/pdev.h>
#include <lib/image-format/image_format.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>

#include <memory>

#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/io-buffer.h>
#include <ddk/platform-defs.h>
#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <hw/arch_ops.h>
#include <hw/reg.h>

#include "hdmitx.h"
#include "src/graphics/display/drivers/vim-display/vim-display-bind.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 void vim_set_display_controller_interface(
    void* ctx, const display_controller_interface_protocol_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);
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t vim_import_image(void* ctx, image_t* image, zx_unowned_handle_t handle,
                             uint32_t index) {
  zx_status_t status = ZX_OK;

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

  zx_status_t status2;
  fuchsia_sysmem_BufferCollectionInfo_2 collection_info;
  status =
      fuchsia_sysmem_BufferCollectionWaitForBuffersAllocated(handle, &status2, &collection_info);
  if (status != ZX_OK) {
    return status;
  }
  if (status2 != ZX_OK) {
    return status2;
  }

  fbl::Vector<zx::vmo> vmos;
  for (uint32_t i = 0; i < collection_info.buffer_count; ++i) {
    vmos.push_back(zx::vmo(collection_info.buffers[i].vmo));
  }

  if (!collection_info.settings.has_image_format_constraints || index >= vmos.size()) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  uint64_t offset = collection_info.buffers[index].vmo_usable_start;

  zx::vmo dup_vmo;
  status = vmos[index].duplicate(ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
  if (status != ZX_OK) {
    DISP_ERROR("Failed to duplicate vmo: %d\n", status);
    return ZX_ERR_INVALID_ARGS;
  }

  fbl::AllocChecker ac;
  std::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;

  if (image->pixel_format == ZX_PIXEL_FORMAT_RGB_x888) {
    if (collection_info.settings.image_format_constraints.pixel_format.type !=
        fuchsia_sysmem_PixelFormatType_BGRA32) {
      return ZX_ERR_INVALID_ARGS;
    }
    ZX_DEBUG_ASSERT(
        collection_info.settings.image_format_constraints.pixel_format.has_format_modifier);
    ZX_DEBUG_ASSERT(
        collection_info.settings.image_format_constraints.pixel_format.format_modifier.value ==
        fuchsia_sysmem_FORMAT_MODIFIER_LINEAR);

    uint32_t minimum_row_bytes;
    if (!ImageFormatMinimumRowBytes(&collection_info.settings.image_format_constraints,
                                    image->width, &minimum_row_bytes)) {
      DISP_ERROR("Invalid image width %d for collection\n", image->width);
      return ZX_ERR_INVALID_ARGS;
    }
    zx_status_t status = ZX_OK;
    canvas_info_t info;
    info.height = image->height;
    info.stride_bytes = minimum_row_bytes;
    info.wrap = 0;
    info.blkmode = 0;
    info.endianness = 0;
    info.flags = CANVAS_FLAGS_READ;

    status = amlogic_canvas_config(&display->canvas, dup_vmo.release(), 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;
    }
    if (collection_info.settings.image_format_constraints.pixel_format.type !=
        fuchsia_sysmem_PixelFormatType_NV12) {
      return ZX_ERR_INVALID_ARGS;
    }
    ZX_DEBUG_ASSERT(
        collection_info.settings.image_format_constraints.pixel_format.has_format_modifier);
    ZX_DEBUG_ASSERT(
        collection_info.settings.image_format_constraints.pixel_format.format_modifier.value ==
        fuchsia_sysmem_FORMAT_MODIFIER_LINEAR);

    uint32_t minimum_row_bytes;
    if (!ImageFormatMinimumRowBytes(&collection_info.settings.image_format_constraints,
                                    image->width, &minimum_row_bytes)) {
      DISP_ERROR("Invalid image width %d for collection\n", image->width);
      return ZX_ERR_INVALID_ARGS;
    }
    zx_status_t status = ZX_OK;
    canvas_info_t info;
    info.height = image->height;
    info.stride_bytes = minimum_row_bytes;
    info.wrap = 0;
    info.blkmode = 0;
    // Do 64-bit endianness conversion.
    info.endianness = 7;
    info.flags = CANVAS_FLAGS_READ;

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

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

    info.height /= 2;
    uint32_t plane_offset = minimum_row_bytes * image->height;

    status = amlogic_canvas_config(&display->canvas, dup_vmo2.release(), offset + plane_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]);
    delete 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,
    };
    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 &&
              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");
        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 get_sysmem_connection(void* ctx, zx_handle_t handle) {
  vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
  zx::channel request_handle(handle);

  zx_status_t status = sysmem_connect(&display->sysmem, request_handle.release());
  if (status != ZX_OK) {
    DISP_ERROR("Could not connect to sysmem - status: %d\n", status);
    return status;
  }

  return ZX_OK;
}

static zx_status_t set_buffer_collection_constraints(void* ctx, const image_t* config,
                                                     uint32_t client_endpoint) {
  fuchsia_sysmem_BufferCollectionConstraints constraints = {};
  constraints.usage.display = fuchsia_sysmem_displayUsageLayer;
  constraints.has_buffer_memory_constraints = true;
  fuchsia_sysmem_BufferMemoryConstraints& buffer_constraints =
      constraints.buffer_memory_constraints;
  buffer_constraints.min_size_bytes = 0;
  buffer_constraints.max_size_bytes = 0xffffffff;
  buffer_constraints.physically_contiguous_required = true;
  buffer_constraints.secure_required = false;
  buffer_constraints.ram_domain_supported = true;
  buffer_constraints.cpu_domain_supported = false;
  buffer_constraints.heap_permitted_count = 1;
  buffer_constraints.heap_permitted[0] = fuchsia_sysmem_HeapType_SYSTEM_RAM;
  constraints.image_format_constraints_count = 1;
  fuchsia_sysmem_ImageFormatConstraints& image_constraints =
      constraints.image_format_constraints[0];
  if (config->pixel_format == ZX_PIXEL_FORMAT_NV12) {
    image_constraints.pixel_format.type = fuchsia_sysmem_PixelFormatType_NV12;
    image_constraints.pixel_format.has_format_modifier = true;
    image_constraints.pixel_format.format_modifier.value = fuchsia_sysmem_FORMAT_MODIFIER_LINEAR;
    image_constraints.color_spaces_count = 1;
    image_constraints.color_space[0].type = fuchsia_sysmem_ColorSpaceType_REC709;
  } else {
    image_constraints.pixel_format.type = fuchsia_sysmem_PixelFormatType_BGRA32;
    image_constraints.pixel_format.has_format_modifier = true;
    image_constraints.pixel_format.format_modifier.value = fuchsia_sysmem_FORMAT_MODIFIER_LINEAR;
    image_constraints.color_spaces_count = 1;
    image_constraints.color_space[0].type = fuchsia_sysmem_ColorSpaceType_SRGB;
  }
  image_constraints.min_coded_width = 0;
  image_constraints.max_coded_width = 0xffffffff;
  image_constraints.min_coded_height = 0;
  image_constraints.max_coded_height = 0xffffffff;
  image_constraints.min_bytes_per_row = 0;
  image_constraints.max_bytes_per_row = 0xffffffff;
  image_constraints.max_coded_width_times_coded_height = 0xffffffff;
  image_constraints.layers = 1;
  image_constraints.coded_width_divisor = 1;
  image_constraints.coded_height_divisor = 1;
  image_constraints.bytes_per_row_divisor = 32;
  image_constraints.start_offset_divisor = 32;
  image_constraints.display_width_divisor = 1;
  image_constraints.display_height_divisor = 1;

  zx_status_t status =
      fuchsia_sysmem_BufferCollectionSetConstraints(client_endpoint, true, &constraints);

  if (status != ZX_OK) {
    DISP_ERROR("Failed to set constraints");
    return status;
  }

  return ZX_OK;
}

static zx_status_t get_single_buffer_framebuffer(void* ctx, zx_handle_t* out_vmo,
                                                 uint32_t* out_stride) {
  return ZX_ERR_NOT_SUPPORTED;
}

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,
    .import_image = vim_import_image,
    .release_image = vim_release_image,
    .check_configuration = vim_check_configuration,
    .apply_configuration = vim_apply_configuration,
    .get_sysmem_connection = get_sysmem_connection,
    .set_buffer_collection_constraints = set_buffer_collection_constraints,
    .get_single_buffer_framebuffer = get_single_buffer_framebuffer,
};

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_unbind_reply(display->mydevice);
}

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 = []() {
  zx_protocol_device_t ops = {};
  ops.version = DEVICE_OPS_VERSION;
  ops.get_protocol = display_get_protocol;
  ops.unbind = display_unbind;
  ops.release = display_release;
  return ops;
}();

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

  ddk::PDev pdev;
  status = ddk::PDev::FromFragment(parent, &pdev);
  if (status != ZX_OK) {
    DISP_ERROR("Could not get PDEV protocol\n");
    return status;
  }
  pdev.GetProto(&display->pdev);

  // Test for platform device get_board_info support.
  pdev_board_info_t board_info;
  pdev.GetBoardInfo(&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.GetDeviceInfo(&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;
  }

  zx::bti bti;
  status = pdev.GetBti(0, &bti);
  if (status != ZX_OK) {
    DISP_ERROR("Could not get BTI handle\n");
    return status;
  }

  ddk::GpioProtocolClient gpio;
  status = ddk::GpioProtocolClient::CreateFromDevice(parent, "gpio", &gpio);
  if (status != ZX_OK) {
    DISP_ERROR("Could not get Display GPIO protocol\n");
    return status;
  }
  gpio.GetProto(&display->gpio);

  ddk::AmlogicCanvasProtocolClient canvas;
  status = ddk::AmlogicCanvasProtocolClient::CreateFromDevice(parent, "canvas", &canvas);
  if (status != ZX_OK) {
    DISP_ERROR("Could not get Display CANVAS protocol\n");
    return status;
  }
  canvas.GetProto(&display->canvas);

  ddk::SysmemProtocolClient sysmem;
  status = ddk::SysmemProtocolClient::CreateFromDevice(parent, "sysmem", &sysmem);
  if (!sysmem.is_valid()) {
    DISP_ERROR("Could not get Display SYSMEM protocol\n");
    return status;
  }
  sysmem.GetProto(&display->sysmem);

  // Map all the various MMIOs
  status = pdev.MapMmio(MMIO_PRESET, &display->mmio_preset);
  if (status != ZX_OK) {
    DISP_ERROR("Could not map display MMIO PRESET\n");
    return status;
  }

  status = pdev.MapMmio(MMIO_HDMITX, &display->mmio_hdmitx);
  if (status != ZX_OK) {
    DISP_ERROR("Could not map display MMIO HDMITX\n");
    return status;
  }

  status = pdev.MapMmio(MMIO_HIU, &display->mmio_hiu);
  if (status != ZX_OK) {
    DISP_ERROR("Could not map display MMIO HIU\n");
    return status;
  }

  status = pdev.MapMmio(MMIO_VPU, &display->mmio_vpu);
  if (status != ZX_OK) {
    DISP_ERROR("Could not map display MMIO VPU\n");
    return status;
  }

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

  status = pdev.MapMmio(MMIO_CBUS, &display->mmio_cbus);
  if (status != ZX_OK) {
    DISP_ERROR("Could not map display MMIO CBUS\n");
    return status;
  }

  status = gpio.ConfigIn(GPIO_PULL_DOWN);
  if (status != ZX_OK) {
    DISP_ERROR("gpio_config_in failed for gpio\n");
    return status;
  }

  zx::interrupt inth;
  status = gpio.GetInterrupt(ZX_INTERRUPT_MODE_LEVEL_HIGH, &inth);
  if (status != ZX_OK) {
    DISP_ERROR("gpio_get_interrupt failed for gpio\n");
    return status;
  }

  zx::interrupt vsync_interrupt;
  status = pdev.GetInterrupt(IRQ_VSYNC, 0, &vsync_interrupt);
  if (status != ZX_OK) {
    DISP_ERROR("Could not map vsync interrupt\n");
    return status;
  }

  zx::interrupt rdma_interrupt;
  status = pdev.GetInterrupt(IRQ_RDMA, 0, &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);

  display->bti = bti.release();
  display->inth = inth.release();
  display->vsync_interrupt = vsync_interrupt.release();
  display->rdma_interrupt = rdma_interrupt.release();

  // Setup RDMA
  status = setup_rdma(display);
  if (status != ZX_OK) {
    DISP_ERROR("Could not setup RDMA (status %d)\n", status);
    display_release(display);
    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 = {};
  add_args.version = DEVICE_ADD_ARGS_VERSION;
  add_args.name = "vim2-display";
  add_args.ctx = display;
  add_args.ops = &main_device_proto;
  add_args.props = nullptr;
  add_args.prop_count = 0;
  add_args.proto_id = ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL;
  add_args.proto_ops = &display_controller_ops;
  add_args.proxy_args = nullptr;
  add_args.flags = 0;
  add_args.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 constexpr zx_driver_ops_t vim2_display_driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = vim2_display_bind;
  return ops;
}();

ZIRCON_DRIVER(vim2_display, vim2_display_driver_ops, "zircon", "0.1");
