// 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 <lib/mmio/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();

    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);
    zx_status_t SdmmcGetInBandInterrupt(zx::interrupt* out_irq);

    // 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 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), config_(config) {}

    // Visible for testing.
    zx_status_t Init();

    // Visible for testing.
protected:
    virtual zx_status_t WaitForInterrupt(zx::time* timestamp);

    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_;
    zx::interrupt sdio_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 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
