// 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 "dma-mgr.h"

#include <lib/syslog/global.h>

#include <cstdint>

#include "../mali-009/pingpong_regs.h"
#include "dma-format.h"

namespace camera {

zx_status_t DmaManager::Create(const zx::bti& bti, const ddk::MmioView& isp_mmio_local,
                               DmaManager::Stream stream_type, std::unique_ptr<DmaManager>* out) {
  *out = std::make_unique<DmaManager>(stream_type, isp_mmio_local);

  zx_status_t status = bti.duplicate(ZX_RIGHT_SAME_RIGHTS, &(*out)->bti_);
  if (status != ZX_OK) {
    FX_LOGF(ERROR, "", "%s: Unable to duplicate bti for DmaManager \n", __func__);
    return status;
  }

  return ZX_OK;
}

auto DmaManager::GetPrimaryMisc() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Primary::DmaWriter_Misc::Get();
  }
  return ping::FullResolution::Primary::DmaWriter_Misc::Get();
}

auto DmaManager::GetUvMisc() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Uv::DmaWriter_Misc::Get();
  }
  return ping::FullResolution::Uv::DmaWriter_Misc::Get();
}

auto DmaManager::GetPrimaryBank0() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Primary::DmaWriter_Bank0Base::Get();
  }
  return ping::FullResolution::Primary::DmaWriter_Bank0Base::Get();
}

auto DmaManager::GetUvBank0() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Uv::DmaWriter_Bank0Base::Get();
  }
  return ping::FullResolution::Uv::DmaWriter_Bank0Base::Get();
}

auto DmaManager::GetPrimaryLineOffset() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Primary::DmaWriter_LineOffset::Get();
  }
  return ping::FullResolution::Primary::DmaWriter_LineOffset::Get();
}

auto DmaManager::GetUvLineOffset() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Uv::DmaWriter_LineOffset::Get();
  }
  return ping::FullResolution::Uv::DmaWriter_LineOffset::Get();
}

auto DmaManager::GetPrimaryActiveDim() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Primary::DmaWriter_ActiveDim::Get();
  }
  return ping::FullResolution::Primary::DmaWriter_ActiveDim::Get();
}

auto DmaManager::GetUvActiveDim() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Uv::DmaWriter_ActiveDim::Get();
  }
  return ping::FullResolution::Uv::DmaWriter_ActiveDim::Get();
}

auto DmaManager::GetPrimaryFrameCount() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Primary::DmaWriter_FrameCount::Get();
  }
  return ping::FullResolution::Primary::DmaWriter_FrameCount::Get();
}

auto DmaManager::GetUvFrameCount() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Uv::DmaWriter_FrameCount::Get();
  }
  return ping::FullResolution::Uv::DmaWriter_FrameCount::Get();
}

auto DmaManager::GetPrimaryFailures() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Primary::DmaWriter_Failures::Get();
  }
  return ping::FullResolution::Primary::DmaWriter_Failures::Get();
}

auto DmaManager::GetUvFailures() {
  if (stream_type_ == Stream::Downscaled) {
    return ping::DownScaled::Uv::DmaWriter_Failures::Get();
  }
  return ping::FullResolution::Uv::DmaWriter_Failures::Get();
}

void DmaManager::PrintStatus(ddk::MmioBuffer* mmio) {
  printf("%s DMA Status:\n   Primary:\n",
         (stream_type_ == Stream::Downscaled) ? "Downscaled" : "Full Resolution");
  GetPrimaryFrameCount().ReadFrom(mmio).Print();
  GetPrimaryFailures().ReadFrom(mmio).Print();
  printf("   Secondary:\n");
  GetUvFrameCount().ReadFrom(mmio).Print();
  GetUvFailures().ReadFrom(mmio).Print();
}

zx_status_t DmaManager::Configure(
    fuchsia_sysmem_BufferCollectionInfo buffer_collection,
    fit::function<void(fuchsia_camera_common_FrameAvailableEvent)> frame_available_callback) {
  current_format_ = DmaFormat(buffer_collection.format.image);
  // TODO(CAM-54): Provide a way to dump the previous set of write locked
  // buffers.
  write_locked_buffers_.clear();

  if (current_format_->GetImageSize() > buffer_collection.vmo_size) {
    FX_LOGF(ERROR, "", "%s: Buffer size (%lu) is less than image size (%lu)!\n", __func__,
            buffer_collection.vmo_size, current_format_->GetImageSize());
    return ZX_ERR_INTERNAL;
  }
  if (buffer_collection.buffer_count > countof(buffer_collection.vmos)) {
    return ZX_ERR_INVALID_ARGS;
  }

  zx::vmo vmos[countof(buffer_collection.vmos)];
  for (uint32_t i = 0; i < buffer_collection.buffer_count; ++i) {
    vmos[i] = zx::vmo(buffer_collection.vmos[i]);
  }
  // Pin the buffers
  zx_status_t status = buffers_.Init(vmos, buffer_collection.buffer_count);
  if (status != ZX_OK) {
    FX_LOGF(ERROR, "", "%s: Unable to initialize buffers for DmaManager \n", __func__);
    return status;
  }
  // Release the vmos so that the buffer collection could be reused.
  for (uint32_t i = 0; i < buffer_collection.buffer_count; ++i) {
    buffer_collection.vmos[i] = vmos[i].release();
  }
  status =
      buffers_.PinVmos(bti_, fzl::VmoPool::RequireContig::Yes, fzl::VmoPool::RequireLowMem::Yes);
  if (status != ZX_OK) {
    FX_LOGF(ERROR, "", "%s: Unable to pin buffers for DmaManager \n", __func__);
    return status;
  }
  frame_available_callback_ = std::move(frame_available_callback);
  return ZX_OK;
}

void DmaManager::Enable() {
  ZX_ASSERT(frame_available_callback_ != nullptr);
  enabled_ = true;
}

void DmaManager::Disable() {
  enabled_ = false;
  // TODO(CAM-54): Provide a way to dump the previous set of write locked
  // buffers.
  write_locked_buffers_.clear();
}

void DmaManager::OnFrameWritten() {
  // If we have not started streaming, just skip.
  if (!enabled_) {
    return;
  }
  ZX_ASSERT(frame_available_callback_ != nullptr);
  ZX_ASSERT(!write_locked_buffers_.empty());
  fuchsia_camera_common_FrameAvailableEvent event;
  event.buffer_id = write_locked_buffers_.back().ReleaseWriteLockAndGetIndex();
  event.frame_status = fuchsia_camera_common_FrameStatus_OK;
  // TODO(garratt): set metadata
  event.metadata.timestamp = 0;
  frame_available_callback_(event);
  ZX_ASSERT(!enabled_ || !write_locked_buffers_.empty());
  // An additional check is needed here as the callback may have disabled us.
  if (!enabled_) {
    return;
  }
  write_locked_buffers_.pop_back();
}

// Called as one of the later steps when a new frame arrives.
bool DmaManager::OnNewFrame() {
  // If we have not initialized yet with a format, just skip.
  if (!enabled_) {
    return false;
  }
  // 1) Get another buffer
  auto buffer = buffers_.LockBufferForWrite();
  if (!buffer) {
    FX_LOG(ERROR, "", "Failed to get buffer\n");
    // TODO(garratt): what should we do when we run out of buffers?
    // If we run out of buffers, disable write and send the callback for
    // out of buffers:
    // clang-format off
        GetPrimaryMisc().ReadFrom(&isp_mmio_local_)
           .set_frame_write_on(0)
           .WriteTo(&isp_mmio_local_);
        if (current_format_->HasSecondaryChannel()) {
          GetUvMisc().ReadFrom(&isp_mmio_local_)
              .set_frame_write_on(0)
              .WriteTo(&isp_mmio_local_);
        }
    // clang-format on
    // Send callback:
    fuchsia_camera_common_FrameAvailableEvent event;
    event.buffer_id = 0;
    event.frame_status = fuchsia_camera_common_FrameStatus_ERROR_BUFFER_FULL;
    event.metadata.timestamp = 0;
    frame_available_callback_(event);
    return false;
  }
  // 2) Optional?  Set the DMA settings again... seems unnecessary
  // 3) Set the DMA address
  auto memory_address = static_cast<uint32_t>(buffer->physical_address());

  // clang-format off
    GetPrimaryBank0().FromValue(0)
      .set_value(memory_address + current_format_->GetBank0Offset())
      .WriteTo(&isp_mmio_local_);
    if (current_format_->HasSecondaryChannel()) {
        GetUvBank0().FromValue(0)
          .set_value(memory_address + current_format_->GetBank0OffsetUv())
          .WriteTo(&isp_mmio_local_);
    }
    // 4) Optional? Enable Write_on
    GetPrimaryMisc().ReadFrom(&isp_mmio_local_)
        .set_frame_write_on(1)
        .WriteTo(&isp_mmio_local_);
    if (current_format_->HasSecondaryChannel()) {
        GetUvMisc().ReadFrom(&isp_mmio_local_)
            .set_frame_write_on(1)
            .WriteTo(&isp_mmio_local_);
    }
  // clang-format on
  WriteFormat();
  // Add buffer to queue of buffers we are writing:
  write_locked_buffers_.push_front(std::move(*buffer));

  return true;
}

zx_status_t DmaManager::ReleaseFrame(uint32_t buffer_index) {
  return buffers_.ReleaseBuffer(buffer_index);
}

void DmaManager::WriteFormat() {
  // Write format to registers
  // clang-format off
    GetPrimaryMisc().ReadFrom(&isp_mmio_local_)
        .set_base_mode(current_format_->GetBaseMode())
        .set_plane_select(current_format_->GetPlaneSelect())
        .WriteTo(&isp_mmio_local_);
    GetPrimaryActiveDim().ReadFrom(&isp_mmio_local_)
        .set_active_width(current_format_->width())
        .set_active_height(current_format_->height())
        .WriteTo(&isp_mmio_local_);
    GetPrimaryLineOffset().ReadFrom(&isp_mmio_local_)
        .set_value(current_format_->GetLineOffset())
        .WriteTo(&isp_mmio_local_);
    if (current_format_->HasSecondaryChannel()) {
        GetUvMisc().ReadFrom(&isp_mmio_local_)
            .set_base_mode(current_format_->GetBaseMode())
            .set_plane_select(current_format_->GetPlaneSelectUv())
            .WriteTo(&isp_mmio_local_);
        GetUvActiveDim().ReadFrom(&isp_mmio_local_)
            .set_active_width(current_format_->width())
            .set_active_height(current_format_->height())
            .WriteTo(&isp_mmio_local_);
        GetUvLineOffset().ReadFrom(&isp_mmio_local_)
            .set_value(current_format_->GetLineOffset())
            .WriteTo(&isp_mmio_local_);
    }
  // clang-format on
}
}  // namespace camera
