// 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 "amlogic-video.h"

#include <fuchsia/hardware/composite/cpp/banjo.h>
#include <fuchsia/hardware/platform/device/c/banjo.h>
#include <lib/trace/event.h>
#include <lib/zx/channel.h>
#include <memory.h>
#include <stdint.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/smc.h>

#include <chrono>
#include <memory>
#include <optional>
#include <thread>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>
#include <hw/reg.h>
#include <hwreg/bitfields.h>
#include <hwreg/mmio.h>

#include "device_ctx.h"
#include "device_fidl.h"
#include "hevcdec.h"
#include "local_codec_factory.h"
#include "macros.h"
#include "mpeg12_decoder.h"
#include "pts_manager.h"
#include "registers.h"
#include "src/lib/fsl/handles/object_info.h"
#include "src/media/lib/memory_barriers/memory_barriers.h"
#include "util.h"
#include "vdec1.h"
#include "video_firmware_session.h"

// TODO(fxbug.dev/35200):
//
// AllocateIoBuffer() - only used by VP9 - switch to InternalBuffer when we do zero copy on input
// for VP9.
//
// (AllocateStreamBuffer() has been moved to InternalBuffer.)
// (VideoDecoder::Owner::ProtectableHardwareUnit::kParser pays attention to is_secure.)
//
// (Fine as io_buffer_t, at least for now (for both h264 and VP9):
//  search_pattern_ - HW only reads this
//  parser_input_ - not used when secure)

// TODO(fxbug.dev/41972): bti::release_quarantine() or zx_bti_release_quarantine() somewhere during
// startup, after HW is known idle, before we allocate anything from sysmem.

namespace {

// These match the regions exported when the bus device was added.
enum MmioRegion {
  kCbus,
  kDosbus,
  kHiubus,
  kAobus,
  kDmc,
};

enum Interrupt {
  kDemuxIrq,
  kParserIrq,
  kDosMbox0Irq,
  kDosMbox1Irq,
};

}  // namespace

AmlogicVideo::AmlogicVideo() {
  ZX_DEBUG_ASSERT(metrics_ == &default_nop_metrics_);
  vdec1_core_ = std::make_unique<Vdec1>(this);
  hevc_core_ = std::make_unique<HevcDec>(this);
}

AmlogicVideo::~AmlogicVideo() {
  LOG(INFO, "Tearing down AmlogicVideo");
  if (vdec0_interrupt_handle_) {
    zx_interrupt_destroy(vdec0_interrupt_handle_.get());
    if (vdec0_interrupt_thread_.joinable())
      vdec0_interrupt_thread_.join();
  }
  if (vdec1_interrupt_handle_) {
    zx_interrupt_destroy(vdec1_interrupt_handle_.get());
    if (vdec1_interrupt_thread_.joinable())
      vdec1_interrupt_thread_.join();
  }
  swapped_out_instances_.clear();
  current_instance_ = nullptr;
  core_ = nullptr;
  hevc_core_ = nullptr;
  vdec1_core_ = nullptr;
}

// TODO: Remove once we can add single-instance decoders through
// AddNewDecoderInstance.
void AmlogicVideo::SetDefaultInstance(std::unique_ptr<VideoDecoder> decoder, bool hevc) {
  DecoderCore* core = hevc ? hevc_core_.get() : vdec1_core_.get();
  assert(!stream_buffer_);
  assert(!current_instance_);
  current_instance_ = std::make_unique<DecoderInstance>(std::move(decoder), core);
  video_decoder_ = current_instance_->decoder();
  stream_buffer_ = current_instance_->stream_buffer();
  core_ = core;
}

void AmlogicVideo::AddNewDecoderInstance(std::unique_ptr<DecoderInstance> instance) {
  swapped_out_instances_.push_back(std::move(instance));
}

void AmlogicVideo::UngateClocks() {
  ToggleClock(ClockType::kClkDos, true);
  HhiGclkMpeg1::Get().ReadFrom(&*hiubus_).set_aiu(0xff).set_demux(true).set_audio_in(true).WriteTo(
      &*hiubus_);
  HhiGclkMpeg2::Get().ReadFrom(&*hiubus_).set_vpu_interrupt(true).WriteTo(&*hiubus_);
  UngateParserClock();
}

void AmlogicVideo::UngateParserClock() {
  is_parser_gated_ = false;
  HhiGclkMpeg1::Get().ReadFrom(&*hiubus_).set_u_parser_top(true).WriteTo(&*hiubus_);
}

void AmlogicVideo::GateClocks() {
  // Keep VPU interrupt enabled, as it's used for vsync by the display.
  HhiGclkMpeg1::Get()
      .ReadFrom(&*hiubus_)
      .set_u_parser_top(false)
      .set_aiu(0)
      .set_demux(false)
      .set_audio_in(false)
      .WriteTo(&*hiubus_);
  ToggleClock(ClockType::kClkDos, false);
  GateParserClock();
}

void AmlogicVideo::GateParserClock() {
  is_parser_gated_ = true;
  HhiGclkMpeg1::Get().ReadFrom(&*hiubus_).set_u_parser_top(false).WriteTo(&*hiubus_);
}

void AmlogicVideo::ClearDecoderInstance() {
  std::lock_guard<std::mutex> lock(video_decoder_lock_);
  assert(current_instance_);
  assert(swapped_out_instances_.size() == 0);
  LOG(DEBUG, "current_instance_.reset()...");
  current_instance_ = nullptr;
  core_ = nullptr;
  video_decoder_ = nullptr;
  stream_buffer_ = nullptr;
}

void AmlogicVideo::RemoveDecoder(VideoDecoder* decoder) {
  std::lock_guard<std::mutex> lock(video_decoder_lock_);
  RemoveDecoderLocked(decoder);
}

void AmlogicVideo::RemoveDecoderLocked(VideoDecoder* decoder) {
  DLOG("Removing decoder: %p", decoder);
  ZX_DEBUG_ASSERT(decoder);
  if (current_instance_ && current_instance_->decoder() == decoder) {
    current_instance_ = nullptr;
    video_decoder_ = nullptr;
    stream_buffer_ = nullptr;
    core_ = nullptr;
    TryToReschedule();
    return;
  }
  for (auto it = swapped_out_instances_.begin(); it != swapped_out_instances_.end(); ++it) {
    if ((*it)->decoder() != decoder)
      continue;
    swapped_out_instances_.erase(it);
    return;
  }
}

zx_status_t AmlogicVideo::AllocateStreamBuffer(StreamBuffer* buffer, uint32_t size, bool use_parser,
                                               bool is_secure) {
  // So far, is_secure can only be true if use_parser is also true.
  ZX_DEBUG_ASSERT(!is_secure || use_parser);
  // is_writable is always true because we either need to write into this buffer using the CPU, or
  // using the parser - either way we'll be writing.
  auto create_result =
      InternalBuffer::Create("AMLStreamBuffer", &sysmem_sync_ptr_, zx::unowned_bti(bti_), size,
                             is_secure, /*is_writable=*/true, /*is_mapping_needed=*/!use_parser);
  if (!create_result.is_ok()) {
    DECODE_ERROR("Failed to make video fifo: %d", create_result.error());
    return create_result.error();
  }
  buffer->optional_buffer().emplace(create_result.take_value());

  // Sysmem guarantees that the newly-allocated buffer starts out zeroed and cache clean, to the
  // extent possible based on is_secure.

  return ZX_OK;
}

zx_status_t AmlogicVideo::ConnectToTrustedApp(const uuid_t* application_uuid,
                                              fuchsia::tee::ApplicationSyncPtr* tee) {
  ZX_DEBUG_ASSERT(application_uuid);
  ZX_DEBUG_ASSERT(tee);

  zx::channel tee_client;
  zx::channel tee_server;
  zx_status_t status = zx::channel::create(/*flags=*/0, &tee_client, &tee_server);
  if (status != ZX_OK) {
    LOG(ERROR, "zx::channel::create() failed - status: %d", status);
    return status;
  }

  status = tee_.ConnectToApplication(application_uuid, std::move(tee_server),
                                     /*service_provider=*/zx::channel());
  if (status != ZX_OK) {
    LOG(ERROR, "tee_connect() failed - status: %d", status);
    return status;
  }

  tee->Bind(std::move(tee_client));
  return ZX_OK;
}

zx_status_t AmlogicVideo::EnsureSecmemSessionIsConnected() {
  if (secmem_session_.has_value()) {
    return ZX_OK;
  }

  fuchsia::tee::ApplicationSyncPtr tee_connection;
  const uuid_t kSecmemUuid = {
      0x2c1a33c0, 0x44cc, 0x11e5, {0xbc, 0x3b, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
  zx_status_t status = ConnectToTrustedApp(&kSecmemUuid, &tee_connection);
  if (status != ZX_OK) {
    LOG(ERROR, "ConnectToTrustedApp() failed - status: %d", status);
    return status;
  }

  auto secmem_session_result = SecmemSession::TryOpen(std::move(tee_connection));
  if (!secmem_session_result.is_ok()) {
    // Logging handled in `SecmemSession::TryOpen`
    return ZX_ERR_INTERNAL;
  }

  secmem_session_.emplace(secmem_session_result.take_value());
  return ZX_OK;
}

void AmlogicVideo::InitializeStreamInput(bool use_parser) {
  uint32_t buffer_address = truncate_to_32(stream_buffer_->buffer().phys_base());
  auto buffer_size = stream_buffer_->buffer().size();
  core_->InitializeStreamInput(use_parser, buffer_address, buffer_size);
}

zx_status_t AmlogicVideo::InitializeStreamBuffer(bool use_parser, uint32_t size, bool is_secure) {
  zx_status_t status = AllocateStreamBuffer(stream_buffer_, size, use_parser, is_secure);
  if (status != ZX_OK) {
    return status;
  }

  status = SetProtected(VideoDecoder::Owner::ProtectableHardwareUnit::kParser, is_secure);
  if (status != ZX_OK) {
    return status;
  }

  InitializeStreamInput(use_parser);
  return ZX_OK;
}

std::unique_ptr<CanvasEntry> AmlogicVideo::ConfigureCanvas(io_buffer_t* io_buffer, uint32_t offset,
                                                           uint32_t width, uint32_t height,
                                                           uint32_t wrap, uint32_t blockmode) {
  assert(width % 8 == 0);
  assert(offset % 8 == 0);
  canvas_info_t info;
  info.height = height;
  info.stride_bytes = width;
  info.wrap = wrap;
  info.blkmode = blockmode;
  enum {
    kSwapBytes = 1,
    kSwapWords = 2,
    kSwapDoublewords = 4,
    kSwapQuadwords = 8,
  };
  info.endianness =
      kSwapBytes | kSwapWords | kSwapDoublewords;  // 64-bit big-endian to little-endian conversion.
  info.flags = CANVAS_FLAGS_READ | CANVAS_FLAGS_WRITE;

  zx::unowned_vmo vmo(io_buffer->vmo_handle);
  zx::vmo dup_vmo;
  zx_status_t status = vmo->duplicate(ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed to duplicate handle, status: %d", status);
    return nullptr;
  }
  uint8_t idx;
  status = canvas_.Config(std::move(dup_vmo), offset, &info, &idx);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed to configure canvas, status: %d", status);
    return nullptr;
  }

  return std::make_unique<CanvasEntry>(this, idx);
}

void AmlogicVideo::FreeCanvas(CanvasEntry* canvas) { canvas_.Free(canvas->index()); }

void AmlogicVideo::OnSignaledWatchdog() {
  std::lock_guard<std::mutex> lock(video_decoder_lock_);
  // Check after taking lock to ensure a cancel didn't just happen.
  if (!watchdog_.CheckAndResetTimeout())
    return;
  // The watchdog should never be valid if the decoder was disconnected.
  ZX_ASSERT(video_decoder_);
  video_decoder_->OnSignaledWatchdog();
}

zx_status_t AmlogicVideo::AllocateIoBuffer(io_buffer_t* buffer, size_t size,
                                           uint32_t alignment_log2, uint32_t flags,
                                           const char* name) {
  zx_status_t status = io_buffer_init_aligned(buffer, bti_.get(), size, alignment_log2, flags);
  if (status != ZX_OK)
    return status;

  SetIoBufferName(buffer, name);

  return ZX_OK;
}

fuchsia::sysmem::AllocatorSyncPtr& AmlogicVideo::SysmemAllocatorSyncPtr() {
  return sysmem_sync_ptr_;
}

// This parser handles MPEG elementary streams.
zx_status_t AmlogicVideo::InitializeEsParser() {
  std::lock_guard<std::mutex> lock(video_decoder_lock_);
  return parser_->InitializeEsParser(current_instance_.get());
}

uint32_t AmlogicVideo::GetStreamBufferEmptySpaceAfterWriteOffsetBeforeReadOffset(
    uint32_t write_offset, uint32_t read_offset) {
  uint32_t available_space;
  if (read_offset > write_offset) {
    available_space = read_offset - write_offset;
  } else {
    available_space = stream_buffer_->buffer().size() - write_offset + read_offset;
  }
  // Subtract 8 to ensure the read pointer doesn't become equal to the write
  // pointer, as that means the buffer is empty.
  available_space = available_space > 8 ? available_space - 8 : 0;
  return available_space;
}

uint32_t AmlogicVideo::GetStreamBufferEmptySpaceAfterOffset(uint32_t write_offset) {
  uint32_t read_offset = core_->GetReadOffset();
  return GetStreamBufferEmptySpaceAfterWriteOffsetBeforeReadOffset(write_offset, read_offset);
}

uint32_t AmlogicVideo::GetStreamBufferEmptySpace() {
  return GetStreamBufferEmptySpaceAfterOffset(core_->GetStreamInputOffset());
}

zx_status_t AmlogicVideo::ProcessVideoNoParser(const void* data, uint32_t len,
                                               uint32_t* written_out) {
  return ProcessVideoNoParserAtOffset(data, len, core_->GetStreamInputOffset(), written_out);
}

zx_status_t AmlogicVideo::ProcessVideoNoParserAtOffset(const void* data, uint32_t len,
                                                       uint32_t write_offset,
                                                       uint32_t* written_out) {
  TRACE_DURATION("media", "AmlogicVideo::ProcessVideoNoParserAtOffset");
  uint32_t available_space = GetStreamBufferEmptySpaceAfterOffset(write_offset);
  if (!written_out) {
    if (len > available_space) {
      DECODE_ERROR("Video too large");
      return ZX_ERR_OUT_OF_RANGE;
    }
  } else {
    len = std::min(len, available_space);
    *written_out = len;
  }

  stream_buffer_->set_data_size(stream_buffer_->data_size() + len);
  uint32_t input_offset = 0;
  while (len > 0) {
    uint32_t write_length = len;
    if (write_offset + len > stream_buffer_->buffer().size())
      write_length = stream_buffer_->buffer().size() - write_offset;
    memcpy(stream_buffer_->buffer().virt_base() + write_offset,
           static_cast<const uint8_t*>(data) + input_offset, write_length);
    stream_buffer_->buffer().CacheFlush(write_offset, write_length);
    write_offset += write_length;
    if (write_offset == stream_buffer_->buffer().size())
      write_offset = 0;
    len -= write_length;
    input_offset += write_length;
  }
  BarrierAfterFlush();
  core_->UpdateWritePointer(stream_buffer_->buffer().phys_base() + write_offset);
  return ZX_OK;
}

void AmlogicVideo::SwapOutCurrentInstance() {
  TRACE_DURATION("media", "AmlogicVideo::SwapOutCurrentInstance", "current_instance_",
                 current_instance_.get());
  ZX_DEBUG_ASSERT(!!current_instance_);

  // VP9:
  //
  // FrameWasOutput() is called during handling of kVp9CommandNalDecodeDone on the interrupt thread,
  // which means the decoder HW is currently paused, which means it's ok to save the state before
  // the stop+wait (without any explicit pause before the save here).  The decoder HW remains paused
  // after the save, and makes no further progress until later after the restore.
  //
  // h264_multi_decoder:
  //
  // ShouldSaveInputContext() is true if the h264_multi_decoder made useful progress (decoded a
  // picture).  If no useful progress was made, the lack of save here allows the state restore later
  // to effectively back up and try decoding from the same location again, with more data present.
  // This backing up to the previous saved state is the main way that separate SPS PPS and pictures
  // split across packets are handled.  In other words, it's how the h264_multi_decoder handles
  // stream-based input.
  bool should_save = current_instance_->decoder()->ShouldSaveInputContext();
  DLOG("should_save: %d", should_save);
  if (should_save) {
    if (!current_instance_->input_context()) {
      current_instance_->InitializeInputContext();
      if (core_->InitializeInputContext(current_instance_->input_context(),
                                        current_instance_->decoder()->is_secure()) != ZX_OK) {
        video_decoder_->CallErrorHandler();
        // Continue trying to swap out.
      }
    }
  }
  video_decoder_->SetSwappedOut();
  if (should_save) {
    if (current_instance_->input_context()) {
      if (core_->SaveInputContext(current_instance_->input_context()) != ZX_OK) {
        video_decoder_->CallErrorHandler();
        // Continue trying to swap out.
      }
    }
  }
  video_decoder_ = nullptr;
  stream_buffer_ = nullptr;
  core_->StopDecoding();
  core_->WaitForIdle();
  core_ = nullptr;
  // Round-robin; place at the back of the line.
  swapped_out_instances_.push_back(std::move(current_instance_));
}

void AmlogicVideo::TryToReschedule() {
  TRACE_DURATION("media", "AmlogicVideo::TryToReschedule");
  DLOG("AmlogicVideo::TryToReschedule");

  if (current_instance_ && !current_instance_->decoder()->CanBeSwappedOut()) {
    DLOG("Current instance can't be swapped out");
    return;
  }

  // This is used by h264_multi_decoder to swap out without saving, so that the next swap in will
  // restore a previously-saved state again to re-attempt decode from that saved state's logical
  // read start position.  Unlike the read position which backs up for re-decode, the write position
  // is adjusted after restore to avoid overwriting data written since that save state was
  // originally created.
  if (current_instance_ && current_instance_->decoder()->MustBeSwappedOut()) {
    DLOG("MustBeSwappedOut() is true");
    SwapOutCurrentInstance();
  }

  if (current_instance_ && current_instance_->decoder()->test_hooks().force_context_save_restore) {
    SwapOutCurrentInstance();
  }

  if (swapped_out_instances_.size() == 0) {
    DLOG("Nothing swapped out; returning");
    return;
  }

  // Round-robin; first in line that can be swapped in goes first.
  // TODO: Use some priority mechanism to determine which to swap in.
  auto other_instance = swapped_out_instances_.begin();
  for (; other_instance != swapped_out_instances_.end(); ++other_instance) {
    if ((*other_instance)->decoder()->CanBeSwappedIn()) {
      break;
    }
  }
  if (other_instance == swapped_out_instances_.end()) {
    DLOG("nothing to swap to");
    return;
  }

  ZX_ASSERT(!watchdog_.is_running());
  if (current_instance_) {
    SwapOutCurrentInstance();
  }
  current_instance_ = std::move(*other_instance);
  swapped_out_instances_.erase(other_instance);

  SwapInCurrentInstance();
}

void AmlogicVideo::PowerOffForError() {
  ZX_DEBUG_ASSERT(core_);
  core_ = nullptr;
  swapped_out_instances_.push_back(std::move(current_instance_));
  VideoDecoder* video_decoder = video_decoder_;
  video_decoder_ = nullptr;
  stream_buffer_ = nullptr;
  video_decoder->CallErrorHandler();
  // CallErrorHandler should have marked the decoder as having a fatal error
  // so it will never be rescheduled.
  TryToReschedule();
}

void AmlogicVideo::SwapInCurrentInstance() {
  TRACE_DURATION("media", "AmlogicVideo::SwapInCurrentInstance", "current_instance_",
                 current_instance_.get());
  ZX_DEBUG_ASSERT(current_instance_);

  core_ = current_instance_->core();
  video_decoder_ = current_instance_->decoder();
  DLOG("Swapping in %p", video_decoder_);
  stream_buffer_ = current_instance_->stream_buffer();
  {
    zx_status_t status = video_decoder_->SetupProtection();
    if (status != ZX_OK) {
      DECODE_ERROR("Failed to setup protection: %d", status);
      PowerOffForError();
      return;
    }
  }
  if (!current_instance_->input_context()) {
    InitializeStreamInput(false);
    core_->InitializeDirectInput();
    // If data has added to the stream buffer before the first swap in(only
    // relevant in tests right now) then ensure the write pointer's updated to
    // that spot.
    // Generally data will only be added after this decoder is swapped in, so
    // RestoreInputContext will handle that state.
    if (stream_buffer_->data_size() + stream_buffer_->padding_size() > 0) {
      core_->UpdateWritePointer(stream_buffer_->buffer().phys_base() + stream_buffer_->data_size() +
                                stream_buffer_->padding_size());
    }
  } else {
    if (core_->RestoreInputContext(current_instance_->input_context()) != ZX_OK) {
      PowerOffForError();
      return;
    }
  }

  // Do InitializeHardware after setting up the input context, since for H264Multi the vififo can
  // start reading as soon as PowerCtlVld is set up (inside InitializeHardware), and we don't want
  // it to read incorrect data as we gradually set it up later.
  zx_status_t status = video_decoder_->InitializeHardware();
  if (status != ZX_OK) {
    // Probably failed to load the right firmware.
    DECODE_ERROR("Failed to initialize hardware: %d", status);
    PowerOffForError();
    return;
  }
  video_decoder_->SwappedIn();
}

fidl::InterfaceHandle<fuchsia::sysmem::Allocator> AmlogicVideo::ConnectToSysmem() {
  fidl::InterfaceHandle<fuchsia::sysmem::Allocator> client_end;
  fidl::InterfaceRequest<fuchsia::sysmem::Allocator> server_end = client_end.NewRequest();
  zx_status_t connect_status = sysmem_.Connect(server_end.TakeChannel());
  if (connect_status != ZX_OK) {
    // failure
    return fidl::InterfaceHandle<fuchsia::sysmem::Allocator>();
  }
  return client_end;
}

namespace tee_smc {

enum CallType : uint8_t {
  kYieldingCall = 0,
  kFastCall = 1,
};

enum CallConvention : uint8_t {
  kSmc32CallConv = 0,
  kSmc64CallConv = 1,
};

enum Service : uint8_t {
  kArchService = 0x00,
  kCpuService = 0x01,
  kSipService = 0x02,
  kOemService = 0x03,
  kStandardService = 0x04,
  kTrustedOsService = 0x32,
  kTrustedOsServiceEnd = 0x3F,
};

constexpr uint8_t kCallTypeMask = 0x01;
constexpr uint8_t kCallTypeShift = 31;
constexpr uint8_t kCallConvMask = 0x01;
constexpr uint8_t kCallConvShift = 30;
constexpr uint8_t kServiceMask = ARM_SMC_SERVICE_CALL_NUM_MASK;
constexpr uint8_t kServiceShift = ARM_SMC_SERVICE_CALL_NUM_SHIFT;

static constexpr uint32_t CreateFunctionId(CallType call_type, CallConvention call_conv,
                                           Service service, uint16_t function_num) {
  return (((call_type & kCallTypeMask) << kCallTypeShift) |
          ((call_conv & kCallConvMask) << kCallConvShift) |
          ((service & kServiceMask) << kServiceShift) | function_num);
}
}  // namespace tee_smc

zx_status_t AmlogicVideo::SetProtected(ProtectableHardwareUnit unit, bool protect) {
  TRACE_DURATION("media", "AmlogicVideo::SetProtected", "unit", static_cast<uint32_t>(unit),
                 "protect", protect);
  if (!secure_monitor_)
    return protect ? ZX_ERR_INVALID_ARGS : ZX_OK;

  // Call into the TEE to mark a particular hardware unit as able to access
  // protected memory or not.
  zx_smc_parameters_t params = {};
  zx_smc_result_t result = {};
  constexpr uint32_t kFuncIdConfigDeviceSecure = 14;
  params.func_id = tee_smc::CreateFunctionId(tee_smc::kFastCall, tee_smc::kSmc32CallConv,
                                             tee_smc::kTrustedOsService, kFuncIdConfigDeviceSecure);
  params.arg1 = static_cast<uint32_t>(unit);
  params.arg2 = static_cast<uint32_t>(protect);
  zx_status_t status = zx_smc_call(secure_monitor_.get(), &params, &result);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed to set unit %ld protected status %ld code: %d", params.arg1, params.arg2,
                 status);
    return status;
  }
  if (result.arg0 != 0) {
    DECODE_ERROR("Failed to set unit %ld protected status %ld: %lx", params.arg1, params.arg2,
                 result.arg0);
    return ZX_ERR_INTERNAL;
  }
  return ZX_OK;
}

zx_status_t AmlogicVideo::TeeSmcLoadVideoFirmware(FirmwareBlob::FirmwareType index,
                                                  FirmwareBlob::FirmwareVdecLoadMode vdec) {
  ZX_DEBUG_ASSERT(is_tee_available());
  ZX_DEBUG_ASSERT(secure_monitor_);

  // Call into the TEE to tell the HW to use a particular piece of the previously pre-loaded overall
  // firmware blob.
  zx_smc_parameters_t params = {};
  zx_smc_result_t result = {};
  constexpr uint32_t kFuncIdLoadVideoFirmware = 15;
  params.func_id = tee_smc::CreateFunctionId(tee_smc::kFastCall, tee_smc::kSmc32CallConv,
                                             tee_smc::kTrustedOsService, kFuncIdLoadVideoFirmware);
  params.arg1 = static_cast<uint32_t>(index);
  params.arg2 = static_cast<uint32_t>(vdec);
  zx_status_t status = zx_smc_call(secure_monitor_.get(), &params, &result);
  if (status != ZX_OK) {
    LOG(ERROR, "Failed to kFuncIdLoadVideoFirmware - index: %u vdec: %u status: %d", index, vdec,
        status);
    return status;
  }
  if (result.arg0 != 0) {
    LOG(ERROR, "kFuncIdLoadVideoFirmware result.arg0 != 0 - value: %lu", result.arg0);
    return ZX_ERR_INTERNAL;
  }
  return ZX_OK;
}

zx_status_t AmlogicVideo::TeeVp9AddHeaders(zx_paddr_t page_phys_base, uint32_t before_size,
                                           uint32_t max_after_size, uint32_t* after_size) {
  ZX_DEBUG_ASSERT(after_size);
  ZX_DEBUG_ASSERT(is_tee_available());

  // TODO(fxbug.dev/44674): Remove this retry loop once this issue is resolved.
  constexpr uint32_t kRetryCount = 20;
  zx_status_t status = ZX_OK;
  for (uint32_t i = 0; i < kRetryCount; ++i) {
    status = EnsureSecmemSessionIsConnected();
    if (status != ZX_OK) {
      continue;
    }

    status =
        secmem_session_->GetVp9HeaderSize(page_phys_base, before_size, max_after_size, after_size);
    if (status != ZX_OK) {
      LOG(ERROR, "secmem_session_->GetVp9HeaderSize() failed - status: %d", status);

      // Explicitly disconnect and clean up `secmem_session_`.
      secmem_session_ = std::nullopt;
      continue;
    }

    ZX_DEBUG_ASSERT(*after_size <= max_after_size);
    return ZX_OK;
  }

  return status;
}

void AmlogicVideo::ToggleClock(ClockType type, bool enable) {
  if (enable) {
    clocks_[static_cast<int>(type)].Enable();
  } else {
    clocks_[static_cast<int>(type)].Disable();
  }
}

void AmlogicVideo::SetMetrics(CodecMetrics* metrics) {
  ZX_DEBUG_ASSERT(metrics);
  ZX_DEBUG_ASSERT(metrics != &default_nop_metrics_);
  ZX_DEBUG_ASSERT(metrics_ == &default_nop_metrics_);
  metrics_ = metrics;
}

zx_status_t AmlogicVideo::InitRegisters(zx_device_t* parent) {
  parent_ = parent;

  ddk::CompositeProtocolClient composite(parent);
  if (!composite.is_valid()) {
    DECODE_ERROR("Could not get composite protocol");
    return ZX_ERR_NO_RESOURCES;
  }

  pdev_ = ddk::PDev(composite);
  if (!pdev_.is_valid()) {
    DECODE_ERROR("Failed to get pdev protocol");
    return ZX_ERR_NO_RESOURCES;
  }

  sysmem_ = ddk::SysmemProtocolClient(composite, "sysmem");
  if (!sysmem_.is_valid()) {
    DECODE_ERROR("Could not get SYSMEM protocol");
    return ZX_ERR_NO_RESOURCES;
  }

  canvas_ = ddk::AmlogicCanvasProtocolClient(composite, "canvas");
  if (!canvas_.is_valid()) {
    DECODE_ERROR("Could not get video CANVAS protocol");
    return ZX_ERR_NO_RESOURCES;
  }

  clocks_[static_cast<int>(ClockType::kGclkVdec)] =
      ddk::ClockProtocolClient(composite, "clock-dos-vdec");
  if (!clocks_[static_cast<int>(ClockType::kGclkVdec)].is_valid()) {
    DECODE_ERROR("Could not get CLOCK protocol\n");
    return ZX_ERR_NO_RESOURCES;
  }

  clocks_[static_cast<int>(ClockType::kClkDos)] = ddk::ClockProtocolClient(composite, "clock-dos");
  if (!clocks_[static_cast<int>(ClockType::kClkDos)].is_valid()) {
    DECODE_ERROR("Could not get CLOCK protocol\n");
    return ZX_ERR_NO_RESOURCES;
  }

  // If tee is available as a fragment, we require that we can get ZX_PROTOCOL_TEE.  It'd be nice
  // if there were a less fragile way to detect this.  Passing in driver metadata for this doesn't
  // seem worthwhile so far.  There's no tee on vim2.
  tee_ = ddk::TeeProtocolClient(composite, "tee");
  is_tee_available_ = tee_.is_valid();

  if (is_tee_available_) {
    // TODO(fxbug.dev/39808): remove log spam once we're loading firmware via video_firmware TA
    LOG(INFO, "Got ZX_PROTOCOL_TEE");
  } else {
    // TODO(fxbug.dev/39808): remove log spam once we're loading firmware via video_firmware TA
    LOG(INFO, "Skipped ZX_PROTOCOL_TEE");
  }

  pdev_device_info_t info;
  zx_status_t status = pdev_.GetDeviceInfo(&info);
  if (status != ZX_OK) {
    DECODE_ERROR("pdev_.GetDeviceInfo failed");
    return status;
  }

  switch (info.pid) {
    case PDEV_PID_AMLOGIC_S912:
      device_type_ = DeviceType::kGXM;
      break;
    case PDEV_PID_AMLOGIC_S905D2:
      device_type_ = DeviceType::kG12A;
      break;
    case PDEV_PID_AMLOGIC_T931:
      device_type_ = DeviceType::kG12B;
      break;
    default:
      DECODE_ERROR("Unknown soc pid: %d", info.pid);
      return ZX_ERR_INVALID_ARGS;
  }

  static constexpr uint32_t kTrustedOsSmcIndex = 0;
  status = pdev_.GetSmc(kTrustedOsSmcIndex, &secure_monitor_);
  if (status != ZX_OK) {
    // On systems where there's no protected memory it's fine if we can't get
    // a handle to the secure monitor.
    LOG(INFO, "amlogic-video: Unable to get secure monitor handle, assuming no protected memory");
  }

  std::optional<ddk::MmioBuffer> cbus_mmio;
  status = pdev_.MapMmio(kCbus, &cbus_mmio);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed map cbus");
    return ZX_ERR_NO_MEMORY;
  }

  std::optional<ddk::MmioBuffer> mmio;
  status = pdev_.MapMmio(kDosbus, &mmio);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed map dosbus");
    return ZX_ERR_NO_MEMORY;
  }
  dosbus_.emplace(*std::move(mmio));
  status = pdev_.MapMmio(kHiubus, &mmio);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed map hiubus");
    return ZX_ERR_NO_MEMORY;
  }
  hiubus_.emplace(*std::move(mmio));
  status = pdev_.MapMmio(kAobus, &mmio);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed map aobus");
    return ZX_ERR_NO_MEMORY;
  }
  aobus_.emplace(*std::move(mmio));
  status = pdev_.MapMmio(kDmc, &mmio);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed map dmc");
    return ZX_ERR_NO_MEMORY;
  }
  dmc_.emplace(*std::move(mmio));
  status = pdev_.GetInterrupt(kParserIrq, 0, &parser_interrupt_handle_);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed get parser interrupt");
    return ZX_ERR_NO_MEMORY;
  }
  status = pdev_.GetInterrupt(kDosMbox0Irq, 0, &vdec0_interrupt_handle_);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed get vdec0 interrupt");
    return ZX_ERR_NO_MEMORY;
  }
  status = pdev_.GetInterrupt(kDosMbox1Irq, 0, &vdec1_interrupt_handle_);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed get vdec interrupt");
    return ZX_ERR_NO_MEMORY;
  }
  status = pdev_.GetBti(0, &bti_);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed get bti");
    return ZX_ERR_NO_MEMORY;
  }

  int64_t reset_register_offset = 0x1100 * 4;
  int64_t parser_register_offset = 0;
  int64_t demux_register_offset = 0;
  if (IsDeviceAtLeast(device_type_, DeviceType::kG12A)) {
    // Some portions of the cbus moved in newer versions (TXL and later).
    reset_register_offset = 0x0400 * 4;
    parser_register_offset = (0x3800 - 0x2900) * 4;
    demux_register_offset = (0x1800 - 0x1600) * 4;
  }
  reset_.emplace(*cbus_mmio, reset_register_offset);
  parser_regs_.emplace(*cbus_mmio, parser_register_offset);
  demux_.emplace(*cbus_mmio, demux_register_offset);
  cbus_.emplace(*std::move(cbus_mmio));
  registers_ = std::unique_ptr<MmioRegisters>(new MmioRegisters{
      &*dosbus_, &*aobus_, &*dmc_, &*hiubus_, &*reset_, &*parser_regs_, &*demux_});

  firmware_ = std::make_unique<FirmwareBlob>();
  status = firmware_->LoadFirmware(parent_);
  if (status != ZX_OK) {
    DECODE_ERROR("Failed load firmware");
    return status;
  }

  sysmem_sync_ptr_.Bind(ConnectToSysmem());
  if (!sysmem_sync_ptr_) {
    DECODE_ERROR("ConnectToSysmem() failed");
    status = ZX_ERR_INTERNAL;
    return status;
  }
  sysmem_sync_ptr_->SetDebugClientInfo(fsl::GetCurrentProcessName(), fsl::GetCurrentProcessKoid());
  parser_ = std::make_unique<Parser>(this, std::move(parser_interrupt_handle_));

  if (is_tee_available()) {
    // TODO(fxbug.dev/44674): Remove this retry loop once this issue is resolved.
    constexpr uint32_t kRetryCount = 10;
    for (uint32_t i = 0; i < kRetryCount; i++) {
      status = EnsureSecmemSessionIsConnected();
      if (status == ZX_OK) {
        break;
      }
    }

    if (!secmem_session_.has_value()) {
      LOG(ERROR,
          "OpenSession to secmem failed too many times. Bootloader version may be incorrect.");
      return ZX_ERR_INTERNAL;
    }
  }

  return ZX_OK;
}

zx_status_t AmlogicVideo::PreloadFirmwareViaTee() {
  ZX_DEBUG_ASSERT(is_tee_available_);

  uint8_t* firmware_data;
  uint32_t firmware_size;
  firmware_->GetWholeBlob(&firmware_data, &firmware_size);

  // TODO(fxbug.dev/44764): Remove retry when video_firmware crash is fixed.
  zx_status_t status = ZX_OK;
  constexpr uint32_t kRetryCount = 10;
  for (uint32_t i = 0; i < kRetryCount; i++) {
    fuchsia::tee::ApplicationSyncPtr tee_connection;
    const uuid_t kVideoFirmwareUuid = {
        0x526fc4fc, 0x7ee6, 0x4a12, {0x96, 0xe3, 0x83, 0xda, 0x95, 0x65, 0xbc, 0xe8}};
    status = ConnectToTrustedApp(&kVideoFirmwareUuid, &tee_connection);
    if (status != ZX_OK) {
      LOG(ERROR, "ConnectToTrustedApp() failed - status: %d", status);
      continue;
    }

    auto video_firmware_session_result = VideoFirmwareSession::TryOpen(std::move(tee_connection));
    if (!video_firmware_session_result.is_ok()) {
      // Logging handled in `VideoFirmwareSession::TryOpen`
      status = ZX_ERR_INTERNAL;
      continue;
    }

    VideoFirmwareSession video_firmware_session = video_firmware_session_result.take_value();
    status = video_firmware_session.LoadVideoFirmware(firmware_data, firmware_size);
    if (status != ZX_OK) {
      LOG(ERROR, "video_firmware_session.LoadVideoFirmware() failed - status: %d", status);
      continue;
    }

    LOG(INFO, "Firmware loaded via video_firmware TA");
    break;
  }

  return status;
}

void AmlogicVideo::InitializeInterrupts() {
  vdec0_interrupt_thread_ = std::thread([this]() {
    while (true) {
      zx_time_t time;
      zx_status_t status = zx_interrupt_wait(vdec0_interrupt_handle_.get(), &time);
      if (status != ZX_OK) {
        DECODE_ERROR("vdec0_interrupt_thread_ zx_interrupt_wait() failed - status: %d", status);
        return;
      }
      std::lock_guard<std::mutex> lock(video_decoder_lock_);
      if (video_decoder_) {
        video_decoder_->HandleInterrupt();
      }
    }
  });

  vdec1_interrupt_thread_ = std::thread([this]() {
    while (true) {
      zx_time_t time;
      zx_status_t status = zx_interrupt_wait(vdec1_interrupt_handle_.get(), &time);
      if (status == ZX_ERR_CANCELED) {
        // expected when zx_interrupt_destroy() is called
        return;
      }
      if (status != ZX_OK) {
        // unexpected errors
        DECODE_ERROR(
            "AmlogicVideo::InitializeInterrupts() zx_interrupt_wait() failed "
            "status: %d\n",
            status);
        return;
      }
      std::lock_guard<std::mutex> lock(video_decoder_lock_);
      if (video_decoder_) {
        video_decoder_->HandleInterrupt();
      }
    }
  });
}

zx_status_t AmlogicVideo::InitDecoder() {
  if (is_tee_available_) {
    zx_status_t status = PreloadFirmwareViaTee();
    if (status != ZX_OK) {
      is_tee_available_ = false;
      // TODO(jbauman): Fail this function when everyone's updated their bootloaders.
      LOG(INFO, "Preloading firmware failed with status %d. protected decode won't work.", status);
    } else {
      // TODO(dustingreen): Remove log spam after secure decode works.
      LOG(INFO, "PreloadFirmwareViaTee() succeeded.");
    }
  } else {
    LOG(INFO, "!is_tee_available_");
  }

  InitializeInterrupts();

  return ZX_OK;
}
