// 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 "arm-isp-regs.h"
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/metadata.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <fbl/unique_ptr.h>
#include <memory>
#include <stdlib.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/types.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;

// ISP memory offsets
constexpr uint32_t kDecompander0PingOffset = 0xAB6C;
constexpr uint32_t kPingConfigSize = 0x17FC0;
constexpr uint32_t kAexpHistStatsOffset = 0x24A8;
constexpr uint32_t kHistSize = 0x2000;
constexpr uint32_t kPingMeteringStatsOffset = 0x44B0;
constexpr uint32_t kPongMeteringStatsOffset = kPingMeteringStatsOffset + kPingConfigSize;
constexpr uint32_t kDecompander0PongOffset = kDecompander0PingOffset + kPingConfigSize;
constexpr uint32_t kMeteringSize = 0x8000;
constexpr uint32_t kLocalBufferSize = (0x18e88 + 0x4000);
constexpr uint32_t kConfigSize = 0x1231C;

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

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

    while (running_.load()) {
        status = isp_irq_.wait(NULL);
        if (status != ZX_OK) {
            return status;
        }

        auto irq_status = IspGlobalInterrupt_StatusVector::Get().ReadFrom(&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_);

        if (irq_status.has_errors()) {
            zxlogf(ERROR, "%s ISP Error Occured, resetting ISP", __func__);
            // TODO(braval) : Handle error case here
            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_,
                                             frame_processing_signal_);
    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();

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

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

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

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

    // 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)
        .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_);

    // TODO(garratt): Enable this only under test.
    status = ArmIspDeviceTester::Create(this);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: Failed to create ISP Tester\n", __func__);
        return status;
    }

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

    // TODO(braval): This is here only for testing purposes for initial bring up phase
    isp_device->InitIsp();
    //isp_device->StartStreaming();

    status = isp_device->DdkAdd("arm-isp");
    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");
    }

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

    return status;
}

zx_status_t ArmIspDevice::DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn) {
    zx_status_t status = fuchsia_hardware_camera_Control_try_dispatch(this, txn, msg, &control_ops);
    if (status != ZX_ERR_NOT_SUPPORTED) {
        return status;
    }

    return fuchsia_hardware_camera_Stream_try_dispatch(this, txn, msg, &stream_ops);
}

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

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

    // TODO(garratt@) Get the next bufffer

    CopyContextInfo(kPong, kCopyToIsp);

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

    statsMgr_->SensorStartStreaming();
    return status;
}

zx_status_t ArmIspDevice::StopStreaming() {
    statsMgr_->SensorStopStreaming();
    return SetPort(kSafeStop);
}

zx_status_t ArmIspDevice::ReleaseFrame(uint32_t buffer_id) {
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t ArmIspDevice::GetFormats(uint32_t index, fidl_txn_t* txn) {
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t ArmIspDevice::CreateStream(const fuchsia_sysmem_BufferCollectionInfo* buffer_collection,
                                       const fuchsia_hardware_camera_FrameRate* rate,
                                       zx_handle_t stream,
                                       zx_handle_t stream_token) {
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t ArmIspDevice::GetDeviceInfo(fidl_txn_t* txn) {
    return ZX_ERR_NOT_SUPPORTED;
}

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

void ArmIspDevice::DdkUnbind() {
    ShutDown();
    DdkRemove();
}

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

void ArmIspDevice::ShutDown() {
}

static zx_driver_ops_t driver_ops = []() {
    zx_driver_ops_t ops = {};
    ops.version = DRIVER_OPS_VERSION;
    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)

