// 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 "src/graphics/display/drivers/amlogic-display/video-input-unit.h"

#include <fuchsia/hardware/display/controller/c/banjo.h>
#include <lib/mmio/mmio-buffer.h>
#include <zircon/assert.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <memory>

#include <fbl/alloc_checker.h>

#include "src/graphics/display/drivers/amlogic-display/board-resources.h"
#include "src/graphics/display/drivers/amlogic-display/common.h"
#include "src/graphics/display/drivers/amlogic-display/image-info.h"
#include "src/graphics/display/drivers/amlogic-display/pixel-grid-size2d.h"
#include "src/graphics/display/drivers/amlogic-display/rdma.h"
#include "src/graphics/display/drivers/amlogic-display/vpp-regs.h"
#include "src/graphics/display/drivers/amlogic-display/vpu-regs.h"
#include "src/graphics/display/lib/api-types-cpp/config-stamp.h"
#include "src/graphics/display/lib/api-types-cpp/display-timing.h"
#include "src/graphics/display/lib/driver-framework-migration-utils/logging/zxlogf.h"

namespace amlogic_display {

namespace {
constexpr uint32_t kMaximumAlpha = 0xff;

// We use bicubic interpolation for scaling.
// TODO(payamm): Add support for other types of interpolation
unsigned int osd_filter_coefs_bicubic[] = {
    0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, 0xfd7e0500, 0xfc7e0600, 0xfb7d0800,
    0xfb7c0900, 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, 0xf87613ff, 0xf87416fe,
    0xf87218fe, 0xf8701afe, 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, 0xf76627fc,
    0xf76429fc, 0xf7612cfc, 0xf75f2ffb, 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
    0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, 0xf84848f8};

constexpr uint32_t kFloatToFixed3_10ScaleFactor = 1024;
constexpr int32_t kMaxFloatToFixed3_10 = (4 * kFloatToFixed3_10ScaleFactor) - 1;
constexpr int32_t kMinFloatToFixed3_10 = -4 * kFloatToFixed3_10ScaleFactor;
constexpr uint32_t kFloatToFixed3_10Mask = 0x1FFF;

constexpr uint32_t kFloatToFixed2_10ScaleFactor = 1024;
constexpr int32_t kMaxFloatToFixed2_10 = (2 * kFloatToFixed2_10ScaleFactor) - 1;
constexpr int32_t kMinFloatToFixed2_10 = -2 * kFloatToFixed2_10ScaleFactor;
constexpr uint32_t kFloatToFixed2_10Mask = 0xFFF;

// AFBC related constants
constexpr uint32_t kAfbcb16x16Pixel = 0;
[[maybe_unused]] constexpr uint32_t kAfbc32x8Pixel = 1;
constexpr uint32_t kAfbcRGBA8888 = 5;
constexpr uint32_t kAfbcColorReorderR = 1;
constexpr uint32_t kAfbcColorReorderG = 2;
constexpr uint32_t kAfbcColorReorderB = 3;
constexpr uint32_t kAfbcColorReorderA = 4;

class OsdRegisters {
 public:
  hwreg::RegisterAddr<OsdCtrlStatReg> ctrl_stat;
  hwreg::RegisterAddr<OsdCtrlStat2Reg> ctrl_stat2;        /* VIU_OSD1_CTRL_STAT2 */
  hwreg::RegisterAddr<OsdColorAddrReg> color_addr;        /* VIU_OSD1_COLOR_ADDR */
  hwreg::RegisterAddr<OsdColorReg> color;                 /* VIU_OSD1_COLOR */
  hwreg::RegisterAddr<OsdTcolorAgReg> tcolor_ag0;         /* VIU_OSD1_TCOLOR_AG0 */
  hwreg::RegisterAddr<OsdTcolorAgReg> tcolor_ag1;         /* VIU_OSD1_TCOLOR_AG1 */
  hwreg::RegisterAddr<OsdTcolorAgReg> tcolor_ag2;         /* VIU_OSD1_TCOLOR_AG2 */
  hwreg::RegisterAddr<OsdTcolorAgReg> tcolor_ag3;         /* VIU_OSD1_TCOLOR_AG3 */
  hwreg::RegisterAddr<OsdBlk0CfgW0Reg> blk0_cfg_w0;       /* VIU_OSD1_BLK0_CFG_W0 */
  hwreg::RegisterAddr<OsdBlk0CfgW1Reg> blk0_cfg_w1;       /* VIU_OSD1_BLK0_CFG_W1 */
  hwreg::RegisterAddr<OsdBlk0CfgW2Reg> blk0_cfg_w2;       /* VIU_OSD1_BLK0_CFG_W2 */
  hwreg::RegisterAddr<OsdBlk0CfgW3Reg> blk0_cfg_w3;       /* VIU_OSD1_BLK0_CFG_W3 */
  hwreg::RegisterAddr<OsdBlk0CfgW4Reg> blk0_cfg_w4;       /* VIU_OSD1_BLK0_CFG_W4 */
  hwreg::RegisterAddr<OsdBlk1CfgW4Reg> blk1_cfg_w4;       /* VIU_OSD1_BLK1_CFG_W4 */
  hwreg::RegisterAddr<OsdBlk2CfgW4Reg> blk2_cfg_w4;       /* VIU_OSD1_BLK2_CFG_W4 */
  hwreg::RegisterAddr<OsdFifoCtrlStatReg> fifo_ctrl_stat; /* VIU_OSD1_FIFO_CTRL_STAT */
  // hwreg::RegisterAddr<OsdTestRdDataReg> test_rddata;/* VIU_OSD1_TEST_RDDATA */
  hwreg::RegisterAddr<OsdProtCtrlReg> prot_ctrl;              /* VIU_OSD1_PROT_CTRL */
  hwreg::RegisterAddr<OsdMaliUnpackCtrlReg> mali_unpack_ctrl; /* VIU_OSD1_MALI_UNPACK_CTRL */
  hwreg::RegisterAddr<OsdDimmCtrlReg> dimm_ctrl;              /* VIU_OSD1_DIMM_CTRL */

  hwreg::RegisterAddr<OsdScaleCoefIdxReg> scale_coef_idx;  /* VPP_OSD_SCALE_COEF_IDX */
  hwreg::RegisterAddr<OsdScaleCoefReg> scale_coef;         /* VPP_OSD_SCALE_COEF */
  hwreg::RegisterAddr<OsdVscPhaseStepReg> vsc_phase_step;  /* VPP_OSD_VSC_PHASE_STEP */
  hwreg::RegisterAddr<OsdVscInitPhaseReg> vsc_init_phase;  /* VPP_OSD_VSC_INI_PHASE */
  hwreg::RegisterAddr<OsdVscCtrl0Reg> vsc_ctrl0;           /* VPP_OSD_VSC_CTRL0 */
  hwreg::RegisterAddr<OsdHscPhaseStepReg> hsc_phase_step;  /* VPP_OSD_HSC_PHASE_STEP */
  hwreg::RegisterAddr<OsdHscInitPhaseReg> hsc_init_phase;  /* VPP_OSD_HSC_INI_PHASE */
  hwreg::RegisterAddr<OsdHscCtrl0Reg> hsc_ctrl0;           /* VPP_OSD_HSC_CTRL0 */
  hwreg::RegisterAddr<OsdScDummyDataReg> sc_dummy_data;    /* VPP_OSD_SC_DUMMY_DATA */
  hwreg::RegisterAddr<OsdScCtrl0Reg> sc_ctrl0;             /* VPP_OSD_SC_CTRL0 */
  hwreg::RegisterAddr<OsdSciWhM1Reg> sci_wh_m1;            /* VPP_OSD_SCI_WH_M1 */
  hwreg::RegisterAddr<OsdScoHStartEndReg> sco_h_start_end; /* VPP_OSD_SCO_H_START_END */
  hwreg::RegisterAddr<OsdScoVStartEndReg> sco_v_start_end; /* VPP_OSD_SCO_V_START_END */
  hwreg::RegisterAddr<AfbcHeaderBufAddrLowS0Reg>
      afbc_header_buf_addr_low_s; /* VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0 */
  hwreg::RegisterAddr<AfbcHeaderBufAddrHighS0Reg>
      afbc_header_buf_addr_high_s; /* VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0 */
  hwreg::RegisterAddr<AfbcFormatSpecifierS0Reg>
      afbc_format_specifier_s;                                   /* VPU_MAFBC_FORMAT_SPECIFIER_S0 */
  hwreg::RegisterAddr<AfbcBufferWidthS0Reg> afbc_buffer_width_s; /* VPU_MAFBC_BUFFER_WIDTH_S0 */
  hwreg::RegisterAddr<AfbcBufferHeightS0Reg> afbc_buffer_height_s; /* VPU_MAFBC_BUFFER_HEIGHT_S0 */
  hwreg::RegisterAddr<AfbcBoundingBoxXStartS0Reg>
      afbc_bounding_box_x_start_s; /* VPU_MAFBC_BOUNDING_BOX_X_START_S0 */
  hwreg::RegisterAddr<AfbcBoundingBoxXEndS0Reg>
      afbc_bounding_box_x_end_s; /* VPU_MAFBC_BOUNDING_BOX_X_END_S0 */
  hwreg::RegisterAddr<AfbcBoundingBoxYStartS0Reg>
      afbc_bounding_box_y_start_s; /* VPU_MAFBC_BOUNDING_BOX_Y_START_S0 */
  hwreg::RegisterAddr<AfbcBoundingBoxYEndS0Reg>
      afbc_bounding_box_y_end_s; /* VPU_MAFBC_BOUNDING_BOX_Y_END_S0 */
  hwreg::RegisterAddr<AfbcOutputBufAddrLowS0Reg>
      afbc_output_buf_addr_low_s; /* VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0 */
  hwreg::RegisterAddr<AfbcOutputBufAddrHighS0Reg>
      afbc_output_buf_addr_high_s; /* VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0 */
  hwreg::RegisterAddr<AfbcOutputBufStrideS0Reg>
      afbc_output_buf_stride_s; /* VPU_MAFBC_OUTPUT_BUF_STRIDE_S0 */
  hwreg::RegisterAddr<AfbcPrefetchCfgS0Reg> afbc_prefetch_cfg_s; /* VPU_MAFBC_PREFETCH_CFG_S0 */
};

OsdRegisters osd1_registers = {
    OsdCtrlStatReg::Get(VPU_VIU_OSD1_CTRL_STAT),
    OsdCtrlStat2Reg::Get(VPU_VIU_OSD1_CTRL_STAT2),
    OsdColorAddrReg::Get(VPU_VIU_OSD1_COLOR_ADDR),
    OsdColorReg::Get(VPU_VIU_OSD1_COLOR),
    OsdTcolorAgReg::Get(VPU_VIU_OSD1_TCOLOR_AG0),
    OsdTcolorAgReg::Get(VPU_VIU_OSD1_TCOLOR_AG1),
    OsdTcolorAgReg::Get(VPU_VIU_OSD1_TCOLOR_AG2),
    OsdTcolorAgReg::Get(VPU_VIU_OSD1_TCOLOR_AG3),
    OsdBlk0CfgW0Reg::Get(VPU_VIU_OSD1_BLK0_CFG_W0),
    OsdBlk0CfgW1Reg::Get(VPU_VIU_OSD1_BLK0_CFG_W1),
    OsdBlk0CfgW2Reg::Get(VPU_VIU_OSD1_BLK0_CFG_W2),
    OsdBlk0CfgW3Reg::Get(VPU_VIU_OSD1_BLK0_CFG_W3),
    OsdBlk0CfgW4Reg::Get(VPU_VIU_OSD1_BLK0_CFG_W4),
    OsdBlk1CfgW4Reg::Get(VPU_VIU_OSD1_BLK1_CFG_W4),
    OsdBlk2CfgW4Reg::Get(VPU_VIU_OSD1_BLK2_CFG_W4),
    OsdFifoCtrlStatReg::Get(VPU_VIU_OSD1_FIFO_CTRL_STAT),
    // OsdTestRdDataReg::Get(VPU_VIU_OSD1_TEST_RDDATA),
    OsdProtCtrlReg::Get(VPU_VIU_OSD1_PROT_CTRL),
    OsdMaliUnpackCtrlReg::Get(VPU_VIU_OSD1_MALI_UNPACK_CTRL),
    OsdDimmCtrlReg::Get(VPU_VIU_OSD1_DIMM_CTRL),

    OsdScaleCoefIdxReg::Get(VPU_VPP_OSD_SCALE_COEF_IDX),
    OsdScaleCoefReg::Get(VPU_VPP_OSD_SCALE_COEF),
    OsdVscPhaseStepReg::Get(VPU_VPP_OSD_VSC_PHASE_STEP),
    OsdVscInitPhaseReg::Get(VPU_VPP_OSD_VSC_INI_PHASE),
    OsdVscCtrl0Reg::Get(VPU_VPP_OSD_VSC_CTRL0),
    OsdHscPhaseStepReg::Get(VPU_VPP_OSD_HSC_PHASE_STEP),
    OsdHscInitPhaseReg::Get(VPU_VPP_OSD_HSC_INI_PHASE),
    OsdHscCtrl0Reg::Get(VPU_VPP_OSD_HSC_CTRL0),
    OsdScDummyDataReg::Get(VPU_VPP_OSD_SC_DUMMY_DATA),
    OsdScCtrl0Reg::Get(VPU_VPP_OSD_SC_CTRL0),
    OsdSciWhM1Reg::Get(VPU_VPP_OSD_SCI_WH_M1),
    OsdScoHStartEndReg::Get(VPU_VPP_OSD_SCO_H_START_END),
    OsdScoVStartEndReg::Get(VPU_VPP_OSD_SCO_V_START_END),
    AfbcHeaderBufAddrLowS0Reg::Get(VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0),
    AfbcHeaderBufAddrHighS0Reg::Get(VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0),
    AfbcFormatSpecifierS0Reg::Get(VPU_MAFBC_FORMAT_SPECIFIER_S0),
    AfbcBufferWidthS0Reg::Get(VPU_MAFBC_BUFFER_WIDTH_S0),
    AfbcBufferHeightS0Reg::Get(VPU_MAFBC_BUFFER_HEIGHT_S0),
    AfbcBoundingBoxXStartS0Reg::Get(VPU_MAFBC_BOUNDING_BOX_X_START_S0),
    AfbcBoundingBoxXEndS0Reg::Get(VPU_MAFBC_BOUNDING_BOX_X_END_S0),
    AfbcBoundingBoxYStartS0Reg::Get(VPU_MAFBC_BOUNDING_BOX_Y_START_S0),
    AfbcBoundingBoxYEndS0Reg::Get(VPU_MAFBC_BOUNDING_BOX_Y_END_S0),
    AfbcOutputBufAddrLowS0Reg::Get(VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0),
    AfbcOutputBufAddrHighS0Reg::Get(VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0),
    AfbcOutputBufStrideS0Reg::Get(VPU_MAFBC_OUTPUT_BUF_STRIDE_S0),
    AfbcPrefetchCfgS0Reg::Get(VPU_MAFBC_PREFETCH_CFG_S0),
};

}  // namespace

display::ConfigStamp VideoInputUnit::GetLastConfigStampApplied() {
  return rdma_->GetLastConfigStampApplied();
}

VideoInputUnit::VideoInputUnit(fdf::MmioBuffer vpu_mmio, std::unique_ptr<RdmaEngine> rdma)
    : vpu_mmio_(std::move(vpu_mmio)), rdma_(std::move(rdma)) {}

void VideoInputUnit::DisableLayer(display::ConfigStamp config_stamp) {
  rdma_->StopRdma();
  osd1_registers.ctrl_stat.ReadFrom(&vpu_mmio_).set_blk_en(0).WriteTo(&vpu_mmio_);
  rdma_->ResetConfigStamp(config_stamp);
}

void VideoInputUnit::EnableLayer() {
  osd1_registers.ctrl_stat.ReadFrom(&vpu_mmio_).set_blk_en(1).WriteTo(&vpu_mmio_);
}

uint32_t VideoInputUnit::FloatToFixed2_10(float f) {
  auto fixed_num = static_cast<int32_t>(round(f * kFloatToFixed2_10ScaleFactor));

  // Amlogic hardware accepts values [-2 2). Let's make sure the result is within this range.
  // If not, clamp it
  fixed_num = std::clamp(fixed_num, kMinFloatToFixed2_10, kMaxFloatToFixed2_10);
  return fixed_num & kFloatToFixed2_10Mask;
}

uint32_t VideoInputUnit::FloatToFixed3_10(float f) {
  auto fixed_num = static_cast<int32_t>(round(f * kFloatToFixed3_10ScaleFactor));

  // Amlogic hardware accepts values [-4 4). Let's make sure the result is within this range.
  // If not, clamp it
  fixed_num = std::clamp(fixed_num, kMinFloatToFixed3_10, kMaxFloatToFixed3_10);
  return fixed_num & kFloatToFixed3_10Mask;
}

void VideoInputUnit::SetColorCorrection(uint32_t rdma_table_idx, const display_config_t& config) {
  if (!config.cc_flags) {
    // Disable color conversion engine
    rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_EN_CTRL,
                             vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_EN_CTRL) & ~(1 << 0));
    return;
  }

  // Set enable bit
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_EN_CTRL,
                           vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_EN_CTRL) | (1 << 0));

  // Load PreOffset values (or 0 if none entered)
  auto offset0_1 = (config.cc_flags & COLOR_CONVERSION_PREOFFSET
                        ? (FloatToFixed2_10(config.cc_preoffsets[0]) << 16 |
                           FloatToFixed2_10(config.cc_preoffsets[1]) << 0)
                        : 0);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_PRE_OFFSET0_1, offset0_1);
  auto offset2 = (config.cc_flags & COLOR_CONVERSION_PREOFFSET
                      ? (FloatToFixed2_10(config.cc_preoffsets[2]) << 0)
                      : 0);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_PRE_OFFSET2, offset2);
  // TODO(b/182481217): remove when this bug is closed.
  zxlogf(TRACE, "pre offset0_1=%u offset2=%u", offset0_1, offset2);

  // Load PostOffset values (or 0 if none entered)
  offset0_1 = (config.cc_flags & COLOR_CONVERSION_POSTOFFSET
                   ? (FloatToFixed2_10(config.cc_postoffsets[0]) << 16 |
                      FloatToFixed2_10(config.cc_postoffsets[1]) << 0)
                   : 0);
  offset2 = (config.cc_flags & COLOR_CONVERSION_PREOFFSET
                 ? (FloatToFixed2_10(config.cc_postoffsets[2]) << 0)
                 : 0);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_OFFSET0_1, offset0_1);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_OFFSET2, offset2);
  // TODO(b/182481217): remove when this bug is closed.
  zxlogf(TRACE, "post offset0_1=%u offset2=%u", offset0_1, offset2);

  // clang-format off
  const float identity[3][3] = {
      {1, 0, 0,},
      {0, 1, 0,},
      {0, 0, 1,},
  };
  // clang-format on

  const auto* ccm =
      (config.cc_flags & COLOR_CONVERSION_COEFFICIENTS) ? config.cc_coefficients : identity;

  // Load up the coefficient matrix registers
  auto coef00_01 = FloatToFixed3_10(ccm[0][0]) << 16 | FloatToFixed3_10(ccm[0][1]) << 0;
  auto coef02_10 = FloatToFixed3_10(ccm[0][2]) << 16 | FloatToFixed3_10(ccm[1][0]) << 0;
  auto coef11_12 = FloatToFixed3_10(ccm[1][1]) << 16 | FloatToFixed3_10(ccm[1][2]) << 0;
  auto coef20_21 = FloatToFixed3_10(ccm[2][0]) << 16 | FloatToFixed3_10(ccm[2][1]) << 0;
  auto coef22 = FloatToFixed3_10(ccm[2][2]) << 0;
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_COEF00_01, coef00_01);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_COEF02_10, coef02_10);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_COEF11_12, coef11_12);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_COEF20_21, coef20_21);
  rdma_->SetRdmaTableValue(rdma_table_idx, IDX_MATRIX_COEF22, coef22);
  // TODO(b/182481217): remove when this bug is closed.
  zxlogf(TRACE, "color correction regs 00_01=%xu 02_12=%xu 11_12=%xu 20_21=%u 22=%xu", coef00_01,
         coef02_10, coef11_12, coef20_21, coef22);
}

void VideoInputUnit::FlipOnVsync(const display_config_t& config,
                                 display::ConfigStamp config_stamp) {
  auto info = reinterpret_cast<ImageInfo*>(config.layer_list[0].cfg.primary.image_handle);
  const int next_table_idx = rdma_->GetNextAvailableRdmaTableIndex();
  if (next_table_idx < 0) {
    zxlogf(ERROR, "No table available!");
    return;
  }

  zxlogf(TRACE, "Table index %d used", next_table_idx);
  zxlogf(TRACE, "AFBC %s", info->is_afbc ? "enabled" : "disabled");

  const display::DisplayTiming display_timing = display::ToDisplayTiming(config.mode);

  PixelGridSize2D display_contents_size = {.width = display_timing.horizontal_active_px,
                                           .height = display_timing.vertical_active_lines};

  // TODO(https://fxbug.dev/317922128): Use the (unscaled) layer source frame size.
  PixelGridSize2D layer_image_size = {.width = display_timing.horizontal_active_px,
                                      .height = display_timing.vertical_active_lines};

  if (ConfigNeededForSingleNonscaledLayer(layer_image_size, display_contents_size)) {
    zxlogf(INFO, "Mode change (%d x %d) to (%d x %d)", display_contents_size_.width,
           display_contents_size_.height, display_contents_size.width,
           display_contents_size.height);
    ConfigForSingleNonscaledLayer(layer_image_size, display_contents_size);
  }

  auto cfg_w0 = osd1_registers.blk0_cfg_w0.FromValue(0);
  if (info->is_afbc) {
    // AFBC: Enable sourcing from mali + configure as big endian
    cfg_w0.set_mali_src_en(1).set_little_endian(0);
  } else {
    uint8_t canvas_index = info->canvas_idx;
    // Update CFG_W0 with correct Canvas Index
    cfg_w0.set_mali_src_en(0).set_little_endian(1).set_tbl_addr(canvas_index);
  }
  cfg_w0.set_blk_mode(OsdBlk0CfgW0Reg::kBlockMode32Bit);

  switch (info->pixel_format.pixel_format) {
    case fuchsia_images2::PixelFormat::kR8G8B8A8:
      cfg_w0.set_color_matrix(OsdBlk0CfgW0Reg::kColorMatrixAbgr8888);
      break;
    case fuchsia_images2::PixelFormat::kB8G8R8A8:
      cfg_w0.set_color_matrix(OsdBlk0CfgW0Reg::kColorMatrixArgb8888);
      break;
    default:
      // This should never happen. The image validity is guaranteed in
      // ImportImage() / CheckConfiguration().
      ZX_ASSERT_MSG(false, "Unsupported image format %u",
                    static_cast<uint32_t>(info->pixel_format.pixel_format));
      return;
  }

  rdma_->SetRdmaTableValue(next_table_idx, IDX_BLK0_CFG_W0, cfg_w0.reg_value());

  // Configure ctrl_stat and ctrl_stat2 registers
  auto osd_ctrl_stat_val = osd1_registers.ctrl_stat.ReadFrom(&vpu_mmio_);
  auto osd_ctrl_stat2_val = osd1_registers.ctrl_stat2.ReadFrom(&vpu_mmio_);

  // enable OSD Block
  osd_ctrl_stat_val.set_blk_en(1);

  // Amlogic supports two types of alpha blending:
  // Global: This alpha value is applied to the entire plane (i.e. all pixels)
  // Per-Pixel: Each pixel will be multiplied by its corresponding alpha channel
  //
  // If alpha blending is disabled by the client or we are supporting a format that does
  // not have an alpha channel, we need to:
  // a) Set global alpha multiplier to 1 (i.e. 0xFF)
  // b) Enable "replaced_alpha" and set its value to 0xFF. This will effectively
  //    tell the hardware to replace the value found in alpha channel with the "replaced"
  //    value
  //
  // If alpha blending is enabled but alpha_layer_val is NaN:
  // - Set global alpha multiplier to 1 (i.e. 0xFF)
  // - Disable "replaced_alpha" which allows hardware to use per-pixel alpha channel.
  //
  // If alpha blending is enabled and alpha_layer_val has a value:
  // - Set global alpha multiplier to alpha_layer_val
  // - Disable "replaced_alpha" which allows hardware to use per-pixel alpha channel.

  // Load default values: Set global alpha to 1 and enable replaced_alpha.
  osd_ctrl_stat2_val.set_replaced_alpha_en(1).set_replaced_alpha(kMaximumAlpha);
  osd_ctrl_stat_val.set_global_alpha(kMaximumAlpha);

  // This is guaranteed by DisplayEngine::CheckConfiguration().
  ZX_DEBUG_ASSERT(config.layer_count > 0);
  ZX_DEBUG_ASSERT(config.layer_list[0].type == LAYER_TYPE_PRIMARY);
  const primary_layer_t& primary_layer = config.layer_list[0].cfg.primary;
  if (primary_layer.alpha_mode != ALPHA_DISABLE) {
    // If a global alpha value is provided, apply it.
    if (!isnan(primary_layer.alpha_layer_val)) {
      auto num = static_cast<uint8_t>(round(primary_layer.alpha_layer_val * kMaximumAlpha));
      osd_ctrl_stat_val.set_global_alpha(num);
    }
  }

  // Use linear address for AFBC, Canvas otherwise
  osd_ctrl_stat_val.set_osd_mem_mode(info->is_afbc ? 1 : 0);
  osd_ctrl_stat2_val.set_pending_status_cleanup(1);

  rdma_->SetRdmaTableValue(next_table_idx, IDX_CTRL_STAT, osd_ctrl_stat_val.reg_value());
  rdma_->SetRdmaTableValue(next_table_idx, IDX_CTRL_STAT2, osd_ctrl_stat2_val.reg_value());

  if (info->is_afbc) {
    // Line Stride calculation based on vendor code
    auto a = fbl::round_up(fbl::round_up(info->image_width * 4, 16u) / 16, 2u);
    auto r = osd1_registers.blk2_cfg_w4.FromValue(0).set_linear_stride(a).reg_value();
    rdma_->SetRdmaTableValue(next_table_idx, IDX_BLK2_CFG_W4, r);

    // Set AFBC's Physical address since it does not use Canvas
    rdma_->SetRdmaTableValue(next_table_idx, IDX_AFBC_HEAD_BUF_ADDR_LOW,
                             (info->paddr & 0xFFFFFFFF));
    rdma_->SetRdmaTableValue(next_table_idx, IDX_AFBC_HEAD_BUF_ADDR_HIGH, (info->paddr >> 32));

    // Set OSD to unpack Mali source
    auto upackreg = osd1_registers.mali_unpack_ctrl.ReadFrom(&vpu_mmio_).set_mali_unpack_en(1);
    rdma_->SetRdmaTableValue(next_table_idx, IDX_MALI_UNPACK_CTRL, upackreg.reg_value());

    // Switch OSD to Mali Source
    auto miscctrl =
        OsdPathMiscCtrlReg::Get(VPU_OSD_PATH_MISC_CTRL).ReadFrom(&vpu_mmio_).set_osd1_mali_sel(1);
    rdma_->SetRdmaTableValue(next_table_idx, IDX_PATH_MISC_CTRL, miscctrl.reg_value());

    // S0 is our index of 0, which is programmed for OSD1
    rdma_->SetRdmaTableValue(next_table_idx, IDX_AFBC_SURFACE_CFG,
                             AfbcSurfaceCfgReg::Get(VPU_MAFBC_SURFACE_CFG)
                                 .ReadFrom(&vpu_mmio_)
                                 .set_cont(0)
                                 .set_s0_en(1)
                                 .reg_value());
    // set command - This uses a separate RDMA Table
    rdma_->SetAfbcRdmaTableValue(
        AfbcCommandReg::Get(VPU_MAFBC_COMMAND).FromValue(0).set_direct_swap(1).reg_value());
  } else {
    // Set OSD to unpack Normal source
    auto upackreg = osd1_registers.mali_unpack_ctrl.ReadFrom(&vpu_mmio_).set_mali_unpack_en(0);
    rdma_->SetRdmaTableValue(next_table_idx, IDX_MALI_UNPACK_CTRL, upackreg.reg_value());

    // Switch OSD to DDR Source
    auto miscctrl =
        OsdPathMiscCtrlReg::Get(VPU_OSD_PATH_MISC_CTRL).ReadFrom(&vpu_mmio_).set_osd1_mali_sel(0);
    rdma_->SetRdmaTableValue(next_table_idx, IDX_PATH_MISC_CTRL, miscctrl.reg_value());

    // Disable afbc sourcing
    rdma_->SetRdmaTableValue(next_table_idx, IDX_AFBC_SURFACE_CFG,
                             AfbcSurfaceCfgReg::Get(VPU_MAFBC_SURFACE_CFG)
                                 .ReadFrom(&vpu_mmio_)
                                 .set_s0_en(0)
                                 .reg_value());
    // clear command - This uses a separate RDMA Table
    rdma_->SetAfbcRdmaTableValue(
        AfbcCommandReg::Get(VPU_MAFBC_COMMAND).FromValue(0).set_direct_swap(0).reg_value());
  }

  SetColorCorrection(next_table_idx, config);

  // update last element of table which will be used to indicate whether RDMA operation was
  // completed or not
  rdma_->SetRdmaTableValue(next_table_idx, IDX_RDMA_CFG_STAMP_HIGH, (config_stamp.value() >> 32));
  rdma_->SetRdmaTableValue(next_table_idx, IDX_RDMA_CFG_STAMP_LOW,
                           (config_stamp.value() & 0xFFFFFFFF));

  rdma_->FlushRdmaTable(next_table_idx);
  if (info->is_afbc) {
    rdma_->FlushAfbcRdmaTable();
  }

  rdma_->ExecRdmaTable(next_table_idx, config_stamp, info->is_afbc);
}

void VideoInputUnit::ConfigOsdLayers(PixelGridSize2D layer_image_size,
                                     PixelGridSize2D display_contents_size) {
  // init osd fifo control and set DDR request priority to be urgent
  uint32_t reg_val = 1;
  reg_val |= 4 << 5;   // hold_fifo_lines
  reg_val |= 1 << 10;  // burst_len_sel 3 = 64. This bit is split between 10 and 31
  reg_val |= 2 << 22;
  reg_val |= 2 << 24;
  reg_val |= 1 << 31;
  reg_val |= 32 << 12;  // fifo_depth_val: 32*8 = 256
  vpu_mmio_.Write32(reg_val, VPU_VIU_OSD1_FIFO_CTRL_STAT);
  vpu_mmio_.Write32(reg_val, VPU_VIU_OSD2_FIFO_CTRL_STAT);

  osd1_registers.ctrl_stat.FromValue(0)
      .set_blk_en(1)
      .set_global_alpha(kMaximumAlpha)
      .set_osd_mem_mode(0)
      .set_premult_en(0)
      .set_osd_en(1)
      .WriteTo(&vpu_mmio_);

  // TODO: split this method into HwInit for each OSD.
  Osd2CtrlStatReg::Get()
      .FromValue(0)
      .set_blk_en(1)
      .set_global_alpha(kMaximumAlpha)
      .set_osd_mem_mode(0)
      .set_premult_en(0)
      .set_osd_en(1)
      .WriteTo(&vpu_mmio_);

  // Set range of the virtual canvas coordinates.
  vpu_mmio_.Write32(((layer_image_size.width - 1) & 0x1fff) << 16, VPU_VIU_OSD1_BLK0_CFG_W1);
  vpu_mmio_.Write32(((layer_image_size.height - 1) & 0x1fff) << 16, VPU_VIU_OSD1_BLK0_CFG_W2);

  // Set geometry to normal mode
  uint32_t data32 = ((display_contents_size.width - 1) & 0xfff) << 16;
  vpu_mmio_.Write32(data32, VPU_VIU_OSD1_BLK0_CFG_W3);
  data32 = ((display_contents_size.height - 1) & 0xfff) << 16;
  vpu_mmio_.Write32(data32, VPU_VIU_OSD1_BLK0_CFG_W4);
}

void VideoInputUnit::ConfigSingleLayerBlending(PixelGridSize2D layer_size,
                                               PixelGridSize2D display_contents_size) {
  // TODO(https://fxbug.dev/317961333): The documentation below needs to be
  // re-organized. Move the descriptions of the blenders and the blender muxes
  // to the blender register definitions; at this function we should only keep
  // how the muxes are wired to each other.

  // There are two types of blenders in the Amlogic display engine:
  // - OSD blenders;
  // - Video post-processor (VPP) blenders.
  //
  // The OSD blenders consists of three blenders (BLEND0, BLEND1 and BLEND2);
  // each blender takes up to 2 inputs where each input can be a layer or the
  // output of a previous blender.
  //
  // The output of OSD blenders are then passed on to the VPP blenders.
  // The VPP blenders set consists of a "pre-processing blender" (blend, then
  // perform post-processing) and a "post-processing blender" (perform post-
  // processing, then blend).
  //
  // Currently, for the single-layer configuration, we use the following
  // blender configurations:
  //
  //              +------------------------+-------------------+
  //              |       OSD blenders     |   VPP blenders    |
  //              |                        |                   |
  // OSD1 -scaler--> BLEND0 -----> BLEND2 ---->  Postblend   -----> Encoder
  //              |             /          |                   |
  //              |  BLEND1 ---/           |     Pre-blend     |
  //              |                        |     (bypassed)    |
  //              +------------------------+-------------------+
  //
  // BLEND0 takes the scaled layer as input, so it's input size is `layer_size`.
  // Since there's no other scaling occurring, the output size of all the OSD
  // blenders, and the input / output sizes of the VPP blenders are the same
  // as the `display_contents_size`.

  // TODO(https://fxbug.dev/42062952): Support multi-layer blender configurations.

  // osd blend ctrl
  vpu_mmio_.Write32(4 << 29 | 0 << 27 |  // blend2_premult_en
                        1 << 26 |        // blend_din0 input to blend0
                        0 << 25 |        // blend1_dout to blend2
                        0 << 24 |        // blend1_din3 input to blend1
                        1 << 20 |        // blend_din_en
                        0 << 16 |        // din_premult_en
                        1 << 0,          // din_reoder_sel = OSD1
                    VIU_OSD_BLEND_CTRL);

  // vpp osd1 blend ctrl
  vpu_mmio_.Write32((0 & 0xf) << 0 | (0 & 0x1) << 4 | (3 & 0xf) << 8 |  // postbld_src3_sel
                        (0 & 0x1) << 16 |                               // postbld_osd1_premult
                        (1 & 0x1) << 20,
                    OSD1_BLEND_SRC_CTRL);
  // vpp osd2 blend ctrl
  vpu_mmio_.Write32((0 & 0xf) << 0 | (0 & 0x1) << 4 | (0 & 0xf) << 8 |  // postbld_src4_sel
                        (0 & 0x1) << 16 |                               // postbld_osd2_premult
                        (1 & 0x1) << 20,
                    OSD2_BLEND_SRC_CTRL);

  // used default dummy data
  vpu_mmio_.Write32(0x0 << 16 | 0x0 << 8 | 0x0, VIU_OSD_BLEND_DUMMY_DATA0);
  // used default dummy alpha data
  vpu_mmio_.Write32(0x0 << 20 | 0x0 << 11 | 0x0, VIU_OSD_BLEND_DUMMY_ALPHA);

  // Size of the VIU OSD blender BLEND0 input.
  vpu_mmio_.Write32((layer_size.width - 1) << 16, VPU_VIU_OSD_BLEND_DIN0_SCOPE_H);
  vpu_mmio_.Write32((layer_size.height - 1) << 16, VPU_VIU_OSD_BLEND_DIN0_SCOPE_V);

  // Size of the VIU OSD blender BLEND0 output.
  vpu_mmio_.Write32(display_contents_size.height << 16 | display_contents_size.width,
                    VIU_OSD_BLEND_BLEND0_SIZE);

  // Size of the VIU OSD blender BLEND1 output.
  // TODO(https://fxbug.dev/42062952): This is not used when there's only one layer.
  vpu_mmio_.Write32(display_contents_size.height << 16 | display_contents_size.width,
                    VIU_OSD_BLEND_BLEND1_SIZE);

  vpu_mmio_.Write32(SetFieldValue32(vpu_mmio_.Read32(DOLBY_PATH_CTRL), /*field_begin_bit=*/2,
                                    /*field_size_bits=*/2, /*field_value=*/0x3),
                    DOLBY_PATH_CTRL);

  // Bypass VPP pre-processing blending ane only enable post-processing
  // blending.
  vpu_mmio_.Write32(vpu_mmio_.Read32(VPP_MISC) | VPP_POSTBLEND_EN, VPP_MISC);
  vpu_mmio_.Write32(vpu_mmio_.Read32(VPP_MISC) & ~(VPP_PREBLEND_EN), VPP_MISC);

  // "VPP OSD1" is the input of the VPP post-processing blender, which is the
  // output of the BLEND2 OSD blender.
  //
  // Input size of the post-processing blender.
  vpu_mmio_.Write32(display_contents_size.height << 16 | display_contents_size.width,
                    VPP_OSD1_IN_SIZE);

  // Scope of the VPP post-processing blender.
  vpu_mmio_.Write32(0 << 16 | (display_contents_size.width - 1), VPP_OSD1_BLD_H_SCOPE);
  vpu_mmio_.Write32(0 << 16 | (display_contents_size.height - 1), VPP_OSD1_BLD_V_SCOPE);

  // Setup VPP output.
  vpu_mmio_.Write32(display_contents_size.width, VPP_POSTBLEND_H_SIZE);
  vpu_mmio_.Write32((display_contents_size.width << 16) | display_contents_size.height,
                    VPU_VPP_OUT_H_V_SIZE);
}

void VideoInputUnit::DisableScaling() {
  // Disable osd scaler path.
  vpu_mmio_.Write32(0, VPU_VPP_OSD_SC_CTRL0);
  vpu_mmio_.Write32(0, VPU_VPP_OSD_VSC_CTRL0);
  vpu_mmio_.Write32(0, VPU_VPP_OSD_HSC_CTRL0);

  // Apply scale coefficients
  osd1_registers.scale_coef_idx.ReadFrom(&vpu_mmio_)
      .set_hi_res_coef(0)
      .set_h_coef(0)
      .set_index(0)
      .WriteTo(&vpu_mmio_);
  for (unsigned int i : osd_filter_coefs_bicubic) {
    osd1_registers.scale_coef.FromValue(i).WriteTo(&vpu_mmio_);
  }

  osd1_registers.scale_coef_idx.ReadFrom(&vpu_mmio_)
      .set_hi_res_coef(0)
      .set_h_coef(1)
      .set_index(0)
      .WriteTo(&vpu_mmio_);
  for (unsigned int i : osd_filter_coefs_bicubic) {
    osd1_registers.scale_coef.FromValue(i).WriteTo(&vpu_mmio_);
  }
}

void VideoInputUnit::SetMinimumRgb(uint8_t minimum_rgb) {
  // According to spec, minimum rgb should be set as follows:
  // Shift value by 2bits (8bit -> 10bit) and write new value for
  // each channel separately.
  VppClipMisc1Reg::Get()
      .FromValue(0)
      .set_r_clamp(minimum_rgb << 2)
      .set_g_clamp(minimum_rgb << 2)
      .set_b_clamp(minimum_rgb << 2)
      .WriteTo(&vpu_mmio_);
}

void VideoInputUnit::ConfigAfbcDecoder(PixelGridSize2D layer_image_size) {
  // The format specifier must match the sysmem format modifier flags specified
  // in DisplayEngine::DisplayControllerImplSetBufferCollectionConstraints().
  //
  // Note RGBA8888 works for both RGBA and BGRA formats. The color channels can
  // be reordered by setting MALI_UNPACK_CTRL register.
  osd1_registers.afbc_format_specifier_s.FromValue(0)
      .set_block_split_mode_enabled(true)
      .set_tiled_header_enabled(false)
      .set_yuv_transform_enabled(true)
      .set_super_block_aspect(kAfbcb16x16Pixel)
      .set_pixel_format(kAfbcRGBA8888)
      .WriteTo(&vpu_mmio_);

  // Setup color RGBA channel order
  osd1_registers.mali_unpack_ctrl.ReadFrom(&vpu_mmio_)
      .set_r(kAfbcColorReorderR)
      .set_g(kAfbcColorReorderG)
      .set_b(kAfbcColorReorderB)
      .set_a(kAfbcColorReorderA)
      .WriteTo(&vpu_mmio_);

  // Set afbc input buffer width/height in pixel
  osd1_registers.afbc_buffer_width_s.FromValue(0)
      .set_buffer_width(layer_image_size.width)
      .WriteTo(&vpu_mmio_);
  osd1_registers.afbc_buffer_height_s.FromValue(0)
      .set_buffer_height(layer_image_size.height)
      .WriteTo(&vpu_mmio_);

  // Set afbc input buffer
  osd1_registers.afbc_bounding_box_x_start_s.FromValue(0).set_buffer_x_start(0).WriteTo(&vpu_mmio_);
  osd1_registers.afbc_bounding_box_x_end_s.FromValue(0)
      .set_buffer_x_end(layer_image_size.width -
                        1)  // vendor code has width - 1 - 1, which is technically
                            // incorrect and gives the same result as this.
      .WriteTo(&vpu_mmio_);
  osd1_registers.afbc_bounding_box_y_start_s.FromValue(0).set_buffer_y_start(0).WriteTo(&vpu_mmio_);
  osd1_registers.afbc_bounding_box_y_end_s.FromValue(0)
      .set_buffer_y_end(layer_image_size.height -
                        1)  // vendor code has height -1 -1, but that cuts off the bottom row.
      .WriteTo(&vpu_mmio_);

  // Set output buffer stride
  osd1_registers.afbc_output_buf_stride_s.FromValue(0)
      .set_output_buffer_stride(layer_image_size.width * 4)
      .WriteTo(&vpu_mmio_);

  // Set afbc output buffer index
  // The way this is calculated based on vendor code is as follows:
  // Take OSD being used (1-based index): Therefore OSD1 -> index 1
  // out_addr = index << 24
  osd1_registers.afbc_output_buf_addr_low_s.FromValue(0).set_output_buffer_addr(1 << 24).WriteTo(
      &vpu_mmio_);
  osd1_registers.afbc_output_buf_addr_high_s.FromValue(0).set_output_buffer_addr(0).WriteTo(
      &vpu_mmio_);

  // Set linear address to the out_addr mentioned above
  osd1_registers.blk1_cfg_w4.FromValue(0).set_frame_addr(1 << 24).WriteTo(&vpu_mmio_);
}

bool VideoInputUnit::ConfigNeededForSingleNonscaledLayer(
    PixelGridSize2D layer_image_size, PixelGridSize2D display_contents_size) const {
  return layer_image_size != layer_image_size_ || display_contents_size != display_contents_size_;
}

void VideoInputUnit::ConfigForSingleNonscaledLayer(PixelGridSize2D layer_image_size,
                                                   PixelGridSize2D display_contents_size) {
  ZX_DEBUG_ASSERT_MSG(display_contents_size.IsValid(), "Invalid display size (%d x %d)",
                      display_contents_size.width, display_contents_size.height);
  ZX_DEBUG_ASSERT_MSG(layer_image_size.IsValid(), "Invalid framebuffer size (%d x %d)",
                      layer_image_size.width, layer_image_size.height);

  // TODO(https://fxbug.dev/317922128): Remove this assertion once we support
  // framebuffer scaling.
  ZX_DEBUG_ASSERT(layer_image_size.width == display_contents_size.width);
  ZX_DEBUG_ASSERT(layer_image_size.height == display_contents_size.height);

  // init vpu fifo control register
  uint32_t reg_val = vpu_mmio_.Read32(VPP_OFIFO_SIZE);
  reg_val = 0xfff << 20;
  reg_val |= (0xfff + 1);
  vpu_mmio_.Write32(reg_val, VPP_OFIFO_SIZE);

  ConfigOsdLayers(layer_image_size, display_contents_size);
  DisableScaling();
  ConfigSingleLayerBlending(/*layer_size=*/layer_image_size, display_contents_size);
  ConfigAfbcDecoder(layer_image_size);

  display_contents_size_ = display_contents_size;
  layer_image_size_ = layer_image_size;
}

#define REG_OFFSET (0x20 << 2)
void VideoInputUnit::Dump() {
  DumpNonRdmaRegisters();
  rdma_->DumpRdmaRegisters();
}

#define LOG_REG(reg) zxlogf(INFO, "reg[0x%x]: 0x%08x " #reg, (reg), vpu_mmio_.Read32((reg)))
#define LOG_REG_INSTANCE(reg, offset, index)                                                \
  zxlogf(INFO, "reg[0x%x]: 0x%08x " #reg " #%d", (reg) + (offset), vpu_mmio_.Read32((reg)), \
         index + 1)
void VideoInputUnit::DumpNonRdmaRegisters() {
  uint32_t offset = 0;
  uint32_t index = 0;

  zxlogf(INFO, "VPU_VIU_VENC_MUX_CTRL: 0x%08x",
         VideoInputUnitEncoderMuxControl::Get().ReadFrom(&vpu_mmio_).reg_value());
  LOG_REG(VPU_VPP_MISC);
  LOG_REG(VPU_VPP_OFIFO_SIZE);
  LOG_REG(VPU_VPP_HOLD_LINES);

  LOG_REG(VPU_OSD_PATH_MISC_CTRL);
  LOG_REG(VPU_VIU_OSD_BLEND_CTRL);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN0_SCOPE_H);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN0_SCOPE_V);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN1_SCOPE_H);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN1_SCOPE_V);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN2_SCOPE_H);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN2_SCOPE_V);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN3_SCOPE_H);
  LOG_REG(VPU_VIU_OSD_BLEND_DIN3_SCOPE_V);
  LOG_REG(VPU_VIU_OSD_BLEND_DUMMY_DATA0);
  LOG_REG(VPU_VIU_OSD_BLEND_DUMMY_ALPHA);
  LOG_REG(VPU_VIU_OSD_BLEND_BLEND0_SIZE);
  LOG_REG(VPU_VIU_OSD_BLEND_BLEND1_SIZE);

  LOG_REG(VPU_VPP_OSD1_IN_SIZE);
  LOG_REG(VPU_VPP_OSD1_BLD_H_SCOPE);
  LOG_REG(VPU_VPP_OSD1_BLD_V_SCOPE);
  LOG_REG(VPU_VPP_OSD2_BLD_H_SCOPE);
  LOG_REG(VPU_VPP_OSD2_BLD_V_SCOPE);
  LOG_REG(OSD1_BLEND_SRC_CTRL);
  LOG_REG(OSD2_BLEND_SRC_CTRL);
  LOG_REG(VPU_VPP_POSTBLEND_H_SIZE);
  LOG_REG(VPU_VPP_OUT_H_V_SIZE);

  LOG_REG(VPU_VPP_OSD_SC_CTRL0);
  LOG_REG(VPU_VPP_OSD_SCI_WH_M1);
  LOG_REG(VPU_VPP_OSD_SCO_H_START_END);
  LOG_REG(VPU_VPP_OSD_SCO_V_START_END);
  LOG_REG(VPU_VPP_POSTBLEND_H_SIZE);
  for (index = 0; index < 2; index++) {
    if (index == 1)
      offset = REG_OFFSET;
    LOG_REG_INSTANCE(VPU_VIU_OSD1_FIFO_CTRL_STAT, offset, index);
    LOG_REG_INSTANCE(VPU_VIU_OSD1_CTRL_STAT, offset, index);
    LOG_REG_INSTANCE(VPU_VIU_OSD1_CTRL_STAT2, offset, index);
    LOG_REG_INSTANCE(VPU_VIU_OSD1_BLK0_CFG_W0, offset, index);
    LOG_REG_INSTANCE(VPU_VIU_OSD1_BLK0_CFG_W1, offset, index);
    LOG_REG_INSTANCE(VPU_VIU_OSD1_BLK0_CFG_W2, offset, index);
    LOG_REG_INSTANCE(VPU_VIU_OSD1_BLK0_CFG_W3, offset, index);
    if (index == 1) {
      LOG_REG(VPU_VIU_OSD2_BLK0_CFG_W4);
    } else {
      LOG_REG(VPU_VIU_OSD1_BLK0_CFG_W4);
    }
  }

  zxlogf(INFO, "Dumping all Color Correction Matrix related Registers");
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_COEF00_01 = 0x%x",
         vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_COEF00_01));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_COEF02_10 = 0x%x",
         vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_COEF02_10));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_COEF11_12 = 0x%x",
         vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_COEF11_12));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_COEF20_21 = 0x%x",
         vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_COEF20_21));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_COEF22 = 0x%x", vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_COEF22));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_OFFSET0_1 = 0x%x",
         vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_OFFSET0_1));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_OFFSET2 = 0x%x", vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_OFFSET2));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_PRE_OFFSET0_1 = 0x%x",
         vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_PRE_OFFSET0_1));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_PRE_OFFSET2 = 0x%x",
         vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_PRE_OFFSET2));
  zxlogf(INFO, "VPU_VPP_POST_MATRIX_EN_CTRL = 0x%x", vpu_mmio_.Read32(VPU_VPP_POST_MATRIX_EN_CTRL));
}

void VideoInputUnit::Release() {
  DisableLayer();
  rdma_->Release();
}

// static
zx::result<std::unique_ptr<VideoInputUnit>> VideoInputUnit::Create(
    display::DispatcherFactory& dispatcher_factory,
    fidl::UnownedClientEnd<fuchsia_hardware_platform_device::Device> platform_device,
    inspect::Node* video_input_unit_node) {
  ZX_DEBUG_ASSERT(platform_device.is_valid());

  zx::result<fdf::MmioBuffer> vpu_mmio_result = MapMmio(MmioResourceIndex::kVpu, platform_device);
  if (vpu_mmio_result.is_error()) {
    return vpu_mmio_result.take_error();
  }

  zx::result<std::unique_ptr<RdmaEngine>> rdma_result =
      RdmaEngine::Create(dispatcher_factory, platform_device, video_input_unit_node);
  if (rdma_result.is_error()) {
    return rdma_result.take_error();
  }

  fbl::AllocChecker alloc_checker;
  auto self = fbl::make_unique_checked<VideoInputUnit>(
      &alloc_checker, std::move(vpu_mmio_result).value(), std::move(rdma_result).value());
  if (!alloc_checker.check()) {
    return zx::error(ZX_ERR_NO_MEMORY);
  }

  zx_status_t status = self->rdma_->SetupRdma();
  if (status != ZX_OK) {
    zxlogf(ERROR, "Could not setup RDMA");
    return zx::error(status);
  }

  return zx::ok(self.release());
}

// static
zx::result<std::unique_ptr<VideoInputUnit>> VideoInputUnit::CreateForTesting(
    fdf::MmioBuffer vpu_mmio, std::unique_ptr<RdmaEngine> rdma, PixelGridSize2D layer_image_size,
    PixelGridSize2D display_contents_size) {
  fbl::AllocChecker alloc_checker;
  auto self = fbl::make_unique_checked<VideoInputUnit>(&alloc_checker, std::move(vpu_mmio),
                                                       std::move(rdma));
  if (!alloc_checker.check()) {
    return zx::error(ZX_ERR_NO_MEMORY);
  }

  self->layer_image_size_ = layer_image_size;
  self->display_contents_size_ = display_contents_size;
  return zx::ok(std::move(self));
}

}  // namespace amlogic_display
