// 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.

#pragma once

#include <threads.h>

#include <ddk/io-buffer.h>
#include <ddk/phys-iter.h>
#include <ddk/protocol/platform/device.h>
#include <ddktl/device.h>
#include <ddktl/mmio.h>
#include <ddktl/protocol/gpio.h>
#include <ddktl/protocol/sdmmc.h>
#include <fbl/auto_lock.h>
#include <lib/sync/completion.h>
#include <lib/zx/interrupt.h>
#include <soc/mt8167/mt8167-sdmmc.h>
#include <zircon/thread_annotations.h>

#include <utility>

#include "mtk-sdmmc-reg.h"

namespace sdmmc {

constexpr uint32_t kPageMask = PAGE_SIZE - 1;

struct RequestStatus {
    RequestStatus()
        : cmd_status(ZX_OK), data_status(ZX_OK) {}

    RequestStatus(zx_status_t status)
        : cmd_status(status), data_status(ZX_OK) {}

    RequestStatus(zx_status_t cmd, zx_status_t data)
        : cmd_status(cmd), data_status(data) {}

    zx_status_t Get() const {
        return cmd_status == ZX_OK ? data_status : cmd_status;
    }

    zx_status_t cmd_status;
    zx_status_t data_status;
};

class TuneWindow;

class MtkSdmmc;
using DeviceType = ddk::Device<MtkSdmmc>;

class MtkSdmmc : public DeviceType, public ddk::SdmmcProtocol<MtkSdmmc, ddk::base_protocol> {

public:
    static zx_status_t Create(void* ctx, zx_device_t* parent);

    virtual ~MtkSdmmc() = default;

    void DdkRelease() { delete this; }

    zx_status_t Bind();

    zx_status_t SdmmcHostInfo(sdmmc_host_info_t* info);
    zx_status_t SdmmcSetSignalVoltage(sdmmc_voltage_t voltage);
    zx_status_t SdmmcSetBusWidth(sdmmc_bus_width_t bus_width);
    zx_status_t SdmmcSetBusFreq(uint32_t bus_freq);
    zx_status_t SdmmcSetTiming(sdmmc_timing_t timing);
    void SdmmcHwReset();
    zx_status_t SdmmcPerformTuning(uint32_t cmd_idx);
    zx_status_t SdmmcRequest(sdmmc_req_t* req);

    // Visible for testing.
    MtkSdmmc(zx_device_t* parent, ddk::MmioBuffer mmio, zx::bti bti, const sdmmc_host_info_t& info,
             zx::interrupt irq, const ddk::GpioProtocolClient& reset_gpio,
             const ddk::GpioProtocolClient& power_en_gpio, const pdev_device_info_t& dev_info,
             const board_mt8167::MtkSdmmcConfig& config)
        : DeviceType(parent), req_(nullptr), mmio_(std::move(mmio)), bti_(std::move(bti)),
          info_(info), irq_(std::move(irq)), cmd_status_(ZX_OK), reset_gpio_(reset_gpio),
          power_en_gpio_(power_en_gpio), dev_info_(dev_info), config_(config) {}

    // Visible for testing.
    zx_status_t Init();

    // Visible for testing.
protected:
    virtual zx_status_t WaitForInterrupt();

    int JoinIrqThread() {
        return thrd_join(irq_thread_, nullptr);
    }

    fbl::Mutex mutex_;
    sdmmc_req_t* req_ TA_GUARDED(mutex_);

private:
    RequestStatus SdmmcRequestWithStatus(sdmmc_req_t* req);

    // Prepares the VMO and the DMA engine for receiving data.
    zx_status_t RequestPrepareDma(sdmmc_req_t* req) TA_REQ(mutex_);
    // Creates the GPDMA and BDMA descriptors.
    zx_status_t SetupDmaDescriptors(phys_iter_buffer_t* phys_iter_buf);
    // Waits for the DMA engine to finish and unpins the VMO pages.
    zx_status_t RequestFinishDma(sdmmc_req_t* req) TA_REQ(mutex_);

    // Clears the FIFO in preparation for receiving data.
    zx_status_t RequestPreparePolled(sdmmc_req_t* req) TA_REQ(mutex_);
    // Polls the FIFO register for received data.
    zx_status_t RequestFinishPolled(sdmmc_req_t* req) TA_REQ(mutex_);

    RequestStatus SendTuningBlock(uint32_t cmd_idx, zx_handle_t vmo);

    // Iterates over the possible delay values to find the optimal window. set_delay is a function
    // that accepts and applies a uint32_t delay value, and do_request is a function that sends the
    // request and returns its status. The test results are saved in window.
    template <typename DelayCallback, typename RequestCallback>
    void TestDelaySettings(DelayCallback&& set_delay, RequestCallback&& do_request,
                           TuneWindow* window);

    int IrqThread();

    // Finish the command portion of the request. Returns true if control should be passed back to
    // the main thread or false if more interrupts are expected. This should be called from the IRQ
    // thread with mutex_ held.
    bool CmdDone(const MsdcInt& msdc_int) TA_REQ(mutex_);

    ddk::MmioBuffer mmio_;
    zx::bti bti_;
    const sdmmc_host_info_t info_;
    zx::interrupt irq_;
    thrd_t irq_thread_;
    io_buffer_t gpdma_buf_;
    io_buffer_t bdma_buf_;
    sync_completion_t req_completion_;
    zx_status_t cmd_status_ TA_GUARDED(mutex_);
    const ddk::GpioProtocolClient reset_gpio_;
    const ddk::GpioProtocolClient power_en_gpio_;
    const pdev_device_info_t dev_info_;
    const board_mt8167::MtkSdmmcConfig config_;
};

// TuneWindow keeps track of the results of a series of tuning tests. It is expected that either
// Pass or Fail is called after each test, and that each subsequent delay value is greater than the
// one before it. The largest window of passing tests is determined as the tests are run, and at the
// end the optimal delay value is chosen as the middle of the largest window.
class TuneWindow {
public:
    TuneWindow()
        : index_(0), best_start_(0), best_size_(0), current_start_(0), current_size_(0) {}

    // The tuning test passed, update the current window size and the best window size if needed.
    void Pass() {
        current_size_++;

        if (best_start_ == current_start_) {
            best_size_ = current_size_;
        }

        if (current_size_ > best_size_) {
            best_start_ = current_start_;
            best_size_ = current_size_;
        }

        index_++;
    }

    // The tuning test failed, update the best window size if needed.
    void Fail() {
        current_start_ = index_ + 1;
        current_size_ = 0;

        index_++;
    }

    // Returns the best window size and sets result to the best delay value. If the window size is
    // zero then no tuning tests passed.
    uint32_t GetDelay(uint32_t* delay) const {
        if (best_size_ != 0) {
            *delay = best_start_ + (best_size_ / 2);
        }

        return best_size_;
    }

private:
    uint32_t index_;
    uint32_t best_start_;
    uint32_t best_size_;
    uint32_t current_start_;
    uint32_t current_size_;
};

}  // namespace sdmmc
