// Copyright 2019 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 "arm-isp.h"

#include <lib/syslog/global.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/types.h>

#include <memory>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/metadata.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <fbl/unique_ptr.h>

#include "arm-isp-regs.h"

namespace camera {

namespace {

constexpr uint32_t kHiu = 0;
constexpr uint32_t kPowerDomain = 1;
constexpr uint32_t kMemoryDomain = 2;
constexpr uint32_t kReset = 3;
constexpr uint32_t kIsp = 4;

// CLK Shifts & Masks
constexpr uint32_t kClkMuxMask = 0xfff;
constexpr uint32_t kClockEnableShift = 8;

constexpr uint8_t kPing = 0;
constexpr uint8_t kPong = 1;

constexpr uint8_t kCopyToIsp = 0;
constexpr uint8_t kCopyFromIsp = 1;

constexpr uint8_t kSafeStop = 0;
constexpr uint8_t kSafeStart = 1;

enum {
  COMPONENT_PDEV,
  COMPONENT_CAMERA_SENSOR,
  COMPONENT_COUNT,
};

}  // namespace

void ArmIspDevice::IspHWReset(bool reset) {
  if (reset) {
    reset_mmio_.ClearBits32(1 << 1, RESET4_LEVEL);
  } else {
    reset_mmio_.SetBits32(1 << 1, RESET4_LEVEL);
  }
  // Reference code has a sleep in this path.
  // TODO(braval@) Double check to look into if
  // this sleep is really necessary.
  zx_nanosleep(zx_deadline_after(ZX_MSEC(5)));
}

void ArmIspDevice::PowerUpIsp() {
  // set bit[18-19]=0
  // TODO(braval@) Double check to look into if
  // this sleep is really necessary.
  power_mmio_.ClearBits32(1 << 18 | 1 << 19, AO_RTI_GEN_PWR_SLEEP0);
  zx_nanosleep(zx_deadline_after(ZX_MSEC(5)));

  // set bit[18-19]=0
  power_mmio_.ClearBits32(1 << 18 | 1 << 19, AO_RTI_GEN_PWR_ISO0);

  // MEM_PD_REG0 set 0
  memory_pd_mmio_.Write32(0, HHI_ISP_MEM_PD_REG0);
  // MEM_PD_REG1 set 0
  memory_pd_mmio_.Write32(0, HHI_ISP_MEM_PD_REG1);

  // Refer to reference source code
  hiu_mmio_.Write32(0x5b446585, HHI_CSI_PHY_CNTL0);
  hiu_mmio_.Write32(0x803f4321, HHI_CSI_PHY_CNTL1);

  // Setup Clocks.
  // clear existing values
  hiu_mmio_.ClearBits32(kClkMuxMask, HHI_MIPI_ISP_CLK_CNTL);
  // set the divisor = 1 (writing (1-1) to div field)
  // source for the unused mux = S905D2_FCLK_DIV3   = 3 // 666.7 MHz
  hiu_mmio_.SetBits32(((1 << kClockEnableShift) | 4 << 9), HHI_MIPI_ISP_CLK_CNTL);
}

void ArmIspDevice::HandleDmaError() {
  auto global_mon_status = IspGlobalMonitor_Status::Get().ReadFrom(&isp_mmio_);

  auto global_mon_failures = IspGlobalMonitor_Failures::Get().ReadFrom(&isp_mmio_);

  global_mon_status.Print();
  global_mon_failures.Print();

  IspGlobalMonitor_ClearError::Get()
      .ReadFrom(&isp_mmio_)
      .set_output_dma_clr_alarm(1)
      .set_temper_dma_clr_alarm(1)
      .WriteTo(&isp_mmio_);

  IspGlobalMonitor_ClearError::Get()
      .ReadFrom(&isp_mmio_)
      .set_output_dma_clr_alarm(1)
      .WriteTo(&isp_mmio_);

  // Now read the alarms:
  global_mon_status = IspGlobalMonitor_Status::Get().ReadFrom(&isp_mmio_);
  global_mon_failures = IspGlobalMonitor_Failures::Get().ReadFrom(&isp_mmio_);

  global_mon_status.Print();
  global_mon_failures.Print();

  zxlogf(INFO, "DMA Writer statuses:\n");
  full_resolution_dma_->PrintStatus(&isp_mmio_);
  downscaled_dma_->PrintStatus(&isp_mmio_);

  zxlogf(INFO, "Clearing dma alarm\n");
  IspGlobalMonitor_ClearError::Get()
      .ReadFrom(&isp_mmio_)
      .set_output_dma_clr_alarm(0)
      .set_temper_dma_clr_alarm(0)
      .WriteTo(&isp_mmio_);

  IspGlobalMonitor_ClearError::Get()
      .ReadFrom(&isp_mmio_)
      .set_output_dma_clr_alarm(0)
      .WriteTo(&isp_mmio_);
}

zx_status_t ArmIspDevice::ErrorRoutine() {
  // Mask all IRQs
  IspGlobalInterrupt_MaskVector::Get().ReadFrom(&isp_mmio_).mask_all().WriteTo(&isp_mmio_);

  zx_status_t status = SetPort(kSafeStop);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s Stopping ISP failed \n", __func__);
    return status;
  }

  IspGlobal_Config0::Get().ReadFrom(&isp_mmio_).set_global_fsm_reset(1).WriteTo(&isp_mmio_);

  IspGlobal_Config0::Get().ReadFrom(&isp_mmio_).set_global_fsm_reset(0).WriteTo(&isp_mmio_);

  IspGlobalInterrupt_MaskVector::Get()
      .ReadFrom(&isp_mmio_)
      .set_isp_start(0)
      .set_ctx_management_error(0)
      .set_broken_frame_error(0)
      .set_wdg_timer_timed_out(0)
      .set_frame_collision_error(0)
      .set_dma_error_interrupt(0)
      .set_fr_y_dma_write_done(0)
      .set_fr_uv_dma_write_done(0)
      .set_ds_y_dma_write_done(0)
      .set_ds_uv_dma_write_done(0)
      .WriteTo(&isp_mmio_);

  status = SetPort(kSafeStart);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s Starting ISP failed \n", __func__);
    return status;
  }
  return status;
}

// Interrupt handler for the ISP.
int ArmIspDevice::IspIrqHandler() {
  zxlogf(INFO, "%s start\n", __func__);
  zx_status_t status = ZX_OK;

  while (running_.load()) {
    zx::time time;
    status = isp_irq_.wait(&time);
    if (status != ZX_OK) {
      return status;
    }

    auto irq_status = IspGlobalInterrupt_StatusVector::Get().ReadFrom(&isp_mmio_);

    IspGlobalInterrupt_ClearVector::Get()
        .ReadFrom(&isp_mmio_)
        .set_reg_value(0xFFFFFFFF)
        .WriteTo(&isp_mmio_);

    // Clear IRQ Vector
    IspGlobalInterrupt_Clear::Get().ReadFrom(&isp_mmio_).set_value(0).WriteTo(&isp_mmio_);

    IspGlobalInterrupt_Clear::Get().ReadFrom(&isp_mmio_).set_value(1).WriteTo(&isp_mmio_);

    IspGlobalInterrupt_Clear::Get().ReadFrom(&isp_mmio_).set_value(0).WriteTo(&isp_mmio_);

    if (irq_status.has_errors()) {
      zxlogf(ERROR, "%s ISP Error Occured, resetting ISP\n", __func__);
      if (irq_status.dma_error_interrupt()) {
        HandleDmaError();
      } else {
        status = ErrorRoutine();
        if (status != ZX_OK) {
          return status;
        }
      }
      continue;
    }

    // Currently only handling Frame Start Interrupt.
    if (irq_status.isp_start()) {
      // Frame Start Interrupt
      auto current_config = IspGlobal_Config4::Get().ReadFrom(&isp_mmio_);
      if (current_config.is_pong()) {
        // Use PING for next frame
        IspGlobal_Config3::Get().ReadFrom(&isp_mmio_).select_config_ping().WriteTo(&isp_mmio_);

        if (IsFrameProcessingInProgress()) {
          // TODO: (braval): Handle dropped frame

        } else {
          // Copy Config from local memory to ISP PING Config space
          CopyContextInfo(kPing, kCopyToIsp);
          // Copy Metering Info from ISP to Local Memory
          CopyMeteringInfo(kPing);
          // Start processing this new frame.
          sync_completion_signal(&frame_processing_signal_);
        }

      } else {
        // CURRENT CONFIG IS PING
        // Use PONG for next frame
        IspGlobal_Config3::Get().ReadFrom(&isp_mmio_).select_config_pong().WriteTo(&isp_mmio_);

        if (IsFrameProcessingInProgress()) {
          // TODO: (braval): Handle dropped frame

        } else {
          // Copy Config from local memory to ISP PING Config space
          CopyContextInfo(kPong, kCopyToIsp);
          // Copy Metering Info from ISP to Local Memory
          CopyMeteringInfo(kPong);
          // Start processing this new frame.
          sync_completion_signal(&frame_processing_signal_);
        }
      }
    }
  }
  return status;
}

bool ArmIspDevice::IsFrameProcessingInProgress() {
  return sync_completion_signaled(&frame_processing_signal_);
}

// Note: We have only one copy of local config and
//       metering info, so assign the correct device_offset
//       depending if it is PING or PONG context
//       before we copy the data to/from the ISP.
void ArmIspDevice::CopyContextInfo(uint8_t config_space, uint8_t direction) {
  zx_off_t device_offset;

  if (config_space == kPing) {
    device_offset = kDecompander0PingOffset;
  } else {
    // PONG Context
    device_offset = kDecompander0PongOffset;
  }

  if (direction == kCopyToIsp) {
    // Copy to ISP from Local Config Buffer
    isp_mmio_.CopyFrom32(isp_mmio_local_, kDecompander0PingOffset, device_offset, kConfigSize / 4);
  } else {
    // Copy from ISP to Local Config Buffer
    isp_mmio_local_.CopyFrom32(isp_mmio_, device_offset, kDecompander0PingOffset, kConfigSize / 4);
  }
}

void ArmIspDevice::CopyMeteringInfo(uint8_t config_space) {
  zx_off_t device_offset;

  if (config_space == kPing) {
    // PING Context
    device_offset = kPingMeteringStatsOffset;
  } else {
    // PONG Context
    device_offset = kPongMeteringStatsOffset;
  }

  // Copy from ISP to Local Config Buffer
  isp_mmio_local_.CopyFrom32(isp_mmio_, kAexpHistStatsOffset, kAexpHistStatsOffset, kHistSize / 4);
  isp_mmio_local_.CopyFrom32(isp_mmio_, device_offset, kPingMeteringStatsOffset, kMeteringSize / 4);
}

zx_status_t ArmIspDevice::IspContextInit() {
  // This is actually writing to the HW
  IspLoadSeq_settings();

  // This is being written to the local_config_buffer_
  IspLoadSeq_settings_context();

  statsMgr_ = camera::StatsManager::Create(isp_mmio_.View(0), isp_mmio_local_, camera_sensor_);
  if (statsMgr_ == nullptr) {
    zxlogf(ERROR, "%s: Unable to start StatsManager \n", __func__);
    return ZX_ERR_NO_MEMORY;
  }

  // We are setting up assuming kWDR_MODE_LINEAR as default mode
  IspLoadSeq_linear();

  // Call custom_init()
  IspLoadCustomSequence();

  // Initialize Gamma.
  gamma_rgb_fr_regs_.Init();
  gamma_rgb_ds_regs_.Init();

  // Input port safe start
  return SetPort(kSafeStart);
}

ArmIspRegisterDump ArmIspDevice::DumpRegisters() {
  ArmIspRegisterDump dump;
  // First dump the global registers:
  for (size_t i = 0; i < kGlobalConfigSize; i++) {
    dump.global_config[i] = isp_mmio_.Read<uint32_t>(4 * i);
  }
  // Then ping and pong:
  for (size_t i = 0; i < kContextConfigSize; i++) {
    dump.ping_config[i] = isp_mmio_.Read<uint32_t>(kPingContextConfigOffset + 4 * i);
    dump.pong_config[i] = isp_mmio_.Read<uint32_t>(kPongContextConfigOffset + 4 * i);
  }
  return dump;
}

zx_status_t ArmIspDevice::InitIsp() {
  // The ISP and MIPI module is in same power domain.
  // So if we don't call the power sequence of ISP, the mipi module
  // won't work and it will block accesses to the  mipi register block.
  PowerUpIsp();

  IspHWReset(true);

  // Start ISP Interrupt Handling Thread.
  auto start_thread = [](void* arg) -> int {
    return static_cast<ArmIspDevice*>(arg)->IspIrqHandler();
  };

  sync_completion_reset(&frame_processing_signal_);
  running_.store(true);
  int rc = thrd_create_with_name(&irq_thread_, start_thread, this, "isp_irq_thread");
  if (rc != thrd_success) {
    return ZX_ERR_INTERNAL;
  }

  // Start frame processing thread
  auto frame_processing_func = [](void* arg) -> int {
    return static_cast<ArmIspDevice*>(arg)->FrameProcessingThread();
  };

  running_frame_processing_.store(true);
  rc = thrd_create_with_name(&frame_processing_thread_, frame_processing_func, this,
                             "frame_processing thread");
  if (rc != thrd_success) {
    return ZX_ERR_INTERNAL;
  }

  IspHWReset(false);

  // validate the ISP product ID
  if (Id_Product::Get().ReadFrom(&isp_mmio_).value() != PRODUCT_ID_DEFAULT) {
    zxlogf(ERROR, "%s: Unknown product ID\n", __func__);
    return ZX_ERR_NOT_SUPPORTED;
  }

  zx_status_t status = DmaManager::Create(bti_, isp_mmio_local_, DmaManager::Stream::FullResolution,
                                          &full_resolution_dma_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Unable to start Full Resolution DMA Module \n", __func__);
    return status;
  }
  status =
      DmaManager::Create(bti_, isp_mmio_local_, DmaManager::Stream::Downscaled, &downscaled_dma_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Unable to start Downscaled DMA Module \n", __func__);
    return status;
  }

  return ZX_OK;
}

zx_status_t ArmIspDevice::SetupIspConfig() {
  // Mask all IRQs
  IspGlobalInterrupt_MaskVector::Get().ReadFrom(&isp_mmio_).mask_all().WriteTo(&isp_mmio_);

  // Now copy all ping config settings & metering settings and store it.
  CopyContextInfo(kPing, kCopyFromIsp);

  zx_status_t status = IspContextInit();
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: IspContextInit failed %d\n", __func__, status);
    return status;
  }

  // Copy current context to ISP
  CopyContextInfo(kPing, kCopyToIsp);
  CopyContextInfo(kPong, kCopyToIsp);

  while (IspGlobalInterrupt_StatusVector::Get().ReadFrom(&isp_mmio_).reg_value()) {
    // driver is initialized. we can start processing interrupts
    // wait until irq mask is cleared and start processing
    IspGlobalInterrupt_Clear::Get().ReadFrom(&isp_mmio_).set_value(0).WriteTo(&isp_mmio_);
    IspGlobalInterrupt_Clear::Get().ReadFrom(&isp_mmio_).set_value(1).WriteTo(&isp_mmio_);
  }

  IspGlobalInterrupt_MaskVector::Get()
      .ReadFrom(&isp_mmio_)
      .set_isp_start(0)
      .set_ctx_management_error(0)
      .set_broken_frame_error(0)
      .set_wdg_timer_timed_out(0)
      .set_frame_collision_error(0)
      .set_dma_error_interrupt(0)
      .set_fr_y_dma_write_done(0)
      .set_fr_uv_dma_write_done(0)
      .set_ds_y_dma_write_done(0)
      .set_ds_uv_dma_write_done(0)
      .WriteTo(&isp_mmio_);

  // put ping pong in slave mode
  // SW only mode
  IspGlobal_Config3::Get()
      .ReadFrom(&isp_mmio_)
      .set_mcu_override_config_select(1)
      .WriteTo(&isp_mmio_);

  return ZX_OK;
}

zx_status_t ArmIspDevice::SetPort(uint8_t kMode) {
  constexpr uint32_t kTimeout = ZX_MSEC(30);
  constexpr uint32_t kDeadline = ZX_USEC(500);

  // Input port safe stop or stop
  InputPort_Config3::Get().ReadFrom(&isp_mmio_).set_mode_request(kMode).WriteTo(&isp_mmio_);

  // timeout 100ms
  zx_time_t deadline = zx_deadline_after(kTimeout);
  do {
    if (InputPort_ModeStatus::Get().ReadFrom(&isp_mmio_).value() == kMode) {
      return ZX_OK;
    }
    zx_nanosleep(zx_deadline_after(kDeadline));
  } while (zx_clock_get_monotonic() < deadline);
  return ZX_ERR_TIMED_OUT;
}

// static
zx_status_t ArmIspDevice::Init(void** ctx_out) {
  ZX_ASSERT(ctx_out);
  *ctx_out = nullptr;
  fx_logger_config_t config{};
  config.min_severity = FX_LOG_INFO;
  config.console_fd = STDERR_FILENO;
  return fx_log_init_with_config(&config);  // Used by submodules
}

// static
zx_status_t ArmIspDevice::Create(void* ctx, zx_device_t* parent) {
  ddk::CompositeProtocolClient composite(parent);
  if (!composite.is_valid()) {
    zxlogf(ERROR, "%s could not get composite protocoln", __func__);
    return ZX_ERR_NOT_SUPPORTED;
  }

  zx_device_t* components[COMPONENT_COUNT];
  size_t actual;
  composite.GetComponents(components, COMPONENT_COUNT, &actual);
  if (actual != COMPONENT_COUNT) {
    zxlogf(ERROR, "%s Could not get components\n", __func__);
    return ZX_ERR_NOT_SUPPORTED;
  }

  ddk::PDev pdev(components[COMPONENT_PDEV]);
  if (!pdev.is_valid()) {
    zxlogf(ERROR, "%s: ZX_PROTOCOL_PDEV not available\n", __FILE__);
    return ZX_ERR_NO_RESOURCES;
  }

  ddk::CameraSensorProtocolClient camera_sensor(components[COMPONENT_CAMERA_SENSOR]);
  if (!camera_sensor.is_valid()) {
    zxlogf(ERROR, "%s: ZX_PROTOCOL_CAMERA_SENSOR not available\n", __FILE__);
    return ZX_ERR_NO_RESOURCES;
  }

  std::optional<ddk::MmioBuffer> hiu_mmio;
  zx_status_t status = pdev.MapMmio(kHiu, &hiu_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status);
    return status;
  }

  std::optional<ddk::MmioBuffer> power_mmio;
  status = pdev.MapMmio(kPowerDomain, &power_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status);
    return status;
  }

  std::optional<ddk::MmioBuffer> memory_pd_mmio;
  status = pdev.MapMmio(kMemoryDomain, &memory_pd_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status);
    return status;
  }

  std::optional<ddk::MmioBuffer> reset_mmio;
  status = pdev.MapMmio(kReset, &reset_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status);
    return status;
  }

  std::optional<ddk::MmioBuffer> isp_mmio;
  status = pdev.MapMmio(kIsp, &isp_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status);
    return status;
  }

  zx::interrupt isp_irq;
  status = pdev.GetInterrupt(0, &isp_irq);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: pdev_.GetInterrupt failed %d\n", __func__, status);
    return status;
  }

  // Get our bti.
  zx::bti bti;
  status = pdev.GetBti(0, &bti);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: could not obtain bti: %d\n", __func__, status);
    return status;
  }

  // Allocate buffers for ISP SW configuration and metering information.
  fbl::AllocChecker ac;
  mmio_buffer_t local_mmio_buffer;
  local_mmio_buffer.vaddr =
      new (static_cast<std::align_val_t>(alignof(uint32_t)), &ac) char[kLocalBufferSize];
  local_mmio_buffer.size = kLocalBufferSize;
  local_mmio_buffer.vmo = ZX_HANDLE_INVALID;
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  auto isp_device = std::unique_ptr<ArmIspDevice>(new (&ac) ArmIspDevice(
      parent, std::move(*hiu_mmio), std::move(*power_mmio), std::move(*memory_pd_mmio),
      std::move(*reset_mmio), std::move(*isp_mmio), local_mmio_buffer, std::move(isp_irq),
      std::move(bti), components[COMPONENT_CAMERA_SENSOR]));
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  status = isp_device->InitIsp();
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Failed to Initialize ISP\n", __func__);
    return status;
  }

  zx_device_prop_t props[] = {
      {BIND_PLATFORM_PROTO, 0, ZX_PROTOCOL_ISP},
  };

  status = isp_device->DdkAdd("arm-isp", 0, props, countof(props));
  if (status != ZX_OK) {
    zxlogf(ERROR, "arm-isp: Could not create arm-isp device: %d\n", status);
    return status;
  } else {
    zxlogf(INFO, "arm-isp: Added arm-isp device\n");
  }

  // TODO(garratt): Enable this only under test.
  // Hold the unbind lock so we do not become unbound while the
  // ArmIspDeviceTester is being created:
  fbl::AutoLock guard(&isp_device->unbind_lock_);
  status = ArmIspDeviceTester::Create(isp_device.get(), &(isp_device->on_isp_unbind_));
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Failed to create ISP Tester\n", __func__);
    return status;
  }

  // isp_device intentionally leaked as it is now held by DevMgr.
  __UNUSED auto ptr = isp_device.release();

  return status;
}

DmaManager* ArmIspDevice::GetStream(stream_type_t type) {
  // Ignore anything that is not FullFrame or Downscaled:
  switch (type) {
    case STREAM_TYPE_FULL_RESOLUTION:
      return full_resolution_dma_.get();
    case STREAM_TYPE_DOWNSCALED:
      return downscaled_dma_.get();
    default:
      zxlogf(ERROR, "%s: Invalid stream type\n", __func__);
  }
  return nullptr;
}

// Functions that the isp_stream_protocol calls:
zx_status_t ArmIspDevice::ReleaseFrame(uint32_t buffer_id, stream_type_t type) {
  auto stream = GetStream(type);
  if (!stream) {
    return ZX_ERR_INVALID_ARGS;
  }
  return stream->ReleaseFrame(buffer_id);
}

// A call to either stream type to start will get the isp to start running.
zx_status_t ArmIspDevice::StartStream(stream_type_t type) {
  auto stream = GetStream(type);
  if (!stream) {
    return ZX_ERR_INVALID_ARGS;
  }

  stream->Enable();

  if (!streaming_) {
    auto status = StartStreaming();
    if (status == ZX_OK) {
      streaming_ = true;
    }
    return status;
  }
  return ZX_OK;
}

// The ISP will only stop streaming when both streams are stopped.
zx_status_t ArmIspDevice::StopStream(stream_type_t type) {
  auto stream = GetStream(type);
  if (!stream) {
    return ZX_ERR_INVALID_ARGS;
  }

  stream->Disable();

  if (streaming_ && !full_resolution_dma_->enabled() && !downscaled_dma_->enabled()) {
    auto status = StopStreaming();
    if (status == ZX_OK) {
      streaming_ = false;
    }
    return status;
  }
  return ZX_OK;
}

zx_status_t ArmIspDevice::StartStreaming() {
  if (streaming_) {
    return ZX_OK;
  }
  // At reset we use PING config
  IspGlobal_Config3::Get().ReadFrom(&isp_mmio_).select_config_ping().WriteTo(&isp_mmio_);

  // Grab a new frame for whichever dma is streaming:
  downscaled_dma_->OnNewFrame();
  full_resolution_dma_->OnNewFrame();

  // Copy current context to ISP
  CopyContextInfo(kPing, kCopyToIsp);

  // TODO(Garratt): Test if we need to load pong configuration now.
  full_resolution_dma_->OnNewFrame();
  downscaled_dma_->OnNewFrame();
  CopyContextInfo(kPong, kCopyToIsp);

  zx_status_t status = SetPort(kSafeStart);
  if (status != ZX_OK) {
    return status;
  }

  statsMgr_->SensorStartStreaming();
  streaming_ = true;
  return ZX_OK;
}

zx_status_t ArmIspDevice::StopStreaming() {
  if (!streaming_) {
    return ZX_OK;
  }
  statsMgr_->SensorStopStreaming();
  zx_status_t status = SetPort(kSafeStop);
  if (status != ZX_OK) {
    return status;
  }
  streaming_ = false;
  return ZX_OK;
}

zx_status_t ArmIspDevice::IspCreateOutputStream(const buffer_collection_info_t* buffer_collection,
                                                const frame_rate_t* rate, stream_type_t type,
                                                const output_stream_callback_t* stream,
                                                output_stream_protocol_t* out_s) {
  ZX_ASSERT(stream && stream->frame_ready);

  if (!IsIspConfigInitialized()) {
    zx_status_t status = SetupIspConfig();
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: Failed to Setup ISP\n", __func__);
      return status;
    }
    initialized_ = true;
  }

  // TODO(CAM-79): Set frame rate in sensor
  auto frame_ready_callback = [stream = *stream](fuchsia_camera_common_FrameAvailableEvent event) {
    // TODO(CAM-80): change the output_stream_callback_t so it uses all the
    // frame available info
    if (event.frame_status == fuchsia_camera_common_FrameStatus_OK) {
      stream.frame_ready(stream.ctx, event.buffer_id);
    }
  };

  // Set the control interface:
  out_s->ctx = this;
  switch (type) {
    case STREAM_TYPE_FULL_RESOLUTION:
      out_s->ops->start = [](void* ctx) {
        return reinterpret_cast<ArmIspDevice*>(ctx)->StartStream(STREAM_TYPE_FULL_RESOLUTION);
      };
      out_s->ops->stop = [](void* ctx) {
        return reinterpret_cast<ArmIspDevice*>(ctx)->StopStream(STREAM_TYPE_FULL_RESOLUTION);
      };
      out_s->ops->release_frame = [](void* ctx, uint32_t buffer_id) {
        return reinterpret_cast<ArmIspDevice*>(ctx)->ReleaseFrame(buffer_id,
                                                                  STREAM_TYPE_FULL_RESOLUTION);
      };
      return full_resolution_dma_->Configure(*buffer_collection, frame_ready_callback);
    case STREAM_TYPE_DOWNSCALED:
      out_s->ops->start = [](void* ctx) {
        return reinterpret_cast<ArmIspDevice*>(ctx)->StartStream(STREAM_TYPE_DOWNSCALED);
      };
      out_s->ops->stop = [](void* ctx) {
        return reinterpret_cast<ArmIspDevice*>(ctx)->StopStream(STREAM_TYPE_DOWNSCALED);
      };
      out_s->ops->release_frame = [](void* ctx, uint32_t buffer_id) {
        return reinterpret_cast<ArmIspDevice*>(ctx)->ReleaseFrame(buffer_id,
                                                                  STREAM_TYPE_DOWNSCALED);
      };
      return downscaled_dma_->Configure(*buffer_collection, frame_ready_callback);
    case STREAM_TYPE_SCALAR:
      return ZX_ERR_NOT_SUPPORTED;
    case STREAM_TYPE_INVALID:
    default:
      return ZX_ERR_INVALID_ARGS;
  }
  return ZX_ERR_INVALID_ARGS;
}

int ArmIspDevice::FrameProcessingThread() {
  bool fr_frame_written = false;
  while (running_frame_processing_.load()) {
    sync_completion_wait(&frame_processing_signal_, ZX_TIME_INFINITE);
    // Currently this is called only on the new frame signal, so we maintain
    // a variable to tell if we need to finish processing the last frame.
    if (first_frame_) {
      first_frame_ = false;
    } else {
      // Each of these calls has it's own interrupt, that it could be
      // attached to:
      if (fr_frame_written) {
        full_resolution_dma_->OnFrameWritten();
      }
      downscaled_dma_->OnFrameWritten();
    }
    // Now for the actions we should take on new frame:
    fr_frame_written = full_resolution_dma_->OnNewFrame();
    downscaled_dma_->OnNewFrame();

    // Reset the signal
    sync_completion_reset(&frame_processing_signal_);
  }

  return ZX_OK;
}

ArmIspDevice::~ArmIspDevice() {
  free(isp_mmio_local_.get());
  running_.store(false);
  running_frame_processing_.store(false);
  thrd_join(irq_thread_, NULL);
  thrd_join(frame_processing_thread_, NULL);
  isp_irq_.destroy();
}

void ArmIspDevice::DdkUnbindNew(ddk::UnbindTxn txn) {
  // Make sure we don't unbind while the ArmIspTester is being constructed:
  fbl::AutoLock guard(&unbind_lock_);
  if (on_isp_unbind_) {
    on_isp_unbind_();
  }
  ShutDown();
  txn.Reply();
}

void ArmIspDevice::DdkRelease() { delete this; }

void ArmIspDevice::ShutDown() {}

static constexpr zx_driver_ops_t driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.init = ArmIspDevice::Init;
  ops.bind = ArmIspDevice::Create;
  return ops;
}();

}  // namespace camera

// clang-format off
ZIRCON_DRIVER_BEGIN(arm-isp, camera::driver_ops, "arm-isp", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_COMPOSITE),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_ARM),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_ISP),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_ARM_MALI_IV009),
ZIRCON_DRIVER_END(arm-isp)

