// 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 "msm8x53-sdhci.h"

#include <lib/device-protocol/pdev.h>

#include <memory>

#include <ddk/debug.h>
#include <ddk/platform-defs.h>
#include <fbl/alloc_checker.h>

#include "msm8x53-sdhci-reg.h"
#include "src/devices/block/drivers/msm8x53-sdhci/msm8x53-sdhci-bind.h"

namespace {

constexpr uint32_t kHcVendorSpecAddress = 0x10c;
constexpr uint32_t kHcVendorSpecResetValue = 0x0000'0a1c;

}  // namespace

namespace sdhci {

zx_status_t Msm8x53Sdhci::Create(void* ctx, zx_device_t* parent) {
  ddk::PDev pdev(parent);
  if (!pdev.is_valid()) {
    zxlogf(ERROR, "%s: ZX_PROTOCOL_PDEV not available", __FILE__);
    return ZX_ERR_NO_RESOURCES;
  }

  std::optional<ddk::MmioBuffer> core_mmio;
  zx_status_t status = pdev.MapMmio(0, &core_mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: MapMmio failed", __FILE__);
    return status;
  }

  std::optional<ddk::MmioBuffer> hc_mmio;
  if ((status = pdev.MapMmio(1, &hc_mmio)) != ZX_OK) {
    zxlogf(ERROR, "%s: MapMmio failed", __FILE__);
    return status;
  }

  zx::interrupt irq;
  if ((status = pdev.GetInterrupt(0, &irq)) != ZX_OK) {
    zxlogf(ERROR, "%s: Failed to map interrupt", __FILE__);
    return status;
  }

  fbl::AllocChecker ac;
  std::unique_ptr<Msm8x53Sdhci> device(
      new (&ac) Msm8x53Sdhci(parent, *std::move(core_mmio), *std::move(hc_mmio), std::move(irq)));
  if (!ac.check()) {
    zxlogf(ERROR, "%s: Msm8x53Sdhci alloc failed", __FILE__);
    return ZX_ERR_NO_MEMORY;
  }

  if ((status = device->Init()) != ZX_OK) {
    return status;
  }

  if ((status = device->DdkAdd("msm8x53-sdhci")) != ZX_OK) {
    zxlogf(ERROR, "%s: DdkAdd failed", __FILE__);
    return status;
  }

  __UNUSED auto* dummy = device.release();

  return ZX_OK;
}

zx_status_t Msm8x53Sdhci::Init() {
  hc_mmio_.Write32(kHcVendorSpecResetValue, kHcVendorSpecAddress);

  HcVendorSpec3::Get().ReadFrom(&hc_mmio_).set_alt_fifo_en(0).WriteTo(&hc_mmio_);

  CoreHcMode::Get().FromValue(0).set_hc_mode_en(1).set_ff_clk_sw_rst_disable(1).WriteTo(
      &core_mmio_);

  return ZX_OK;
}

zx_status_t Msm8x53Sdhci::SdhciGetInterrupt(zx::interrupt* out_irq) {
  out_irq->reset(irq_.release());
  return ZX_OK;
}

zx_status_t Msm8x53Sdhci::SdhciGetMmio(zx::vmo* out_mmio, zx_off_t* out_offset) {
  hc_mmio_.get_vmo()->duplicate(ZX_RIGHT_SAME_RIGHTS, out_mmio);
  *out_offset = hc_mmio_.get_offset();
  return ZX_OK;
}

zx_status_t Msm8x53Sdhci::SdhciGetBti(uint32_t index, zx::bti* out_bti) {
  ddk::PDev pdev(parent());
  if (!pdev.is_valid()) {
    return ZX_ERR_NO_RESOURCES;
  }

  return pdev.GetBti(index, out_bti);
}

uint32_t Msm8x53Sdhci::SdhciGetBaseClock() { return 0; }

uint64_t Msm8x53Sdhci::SdhciGetQuirks(uint64_t* out_dma_boundary_alignment) {
  *out_dma_boundary_alignment = 0;
  return SDHCI_QUIRK_STRIP_RESPONSE_CRC_PRESERVE_ORDER | SDHCI_QUIRK_NO_DMA |
         SDHCI_QUIRK_NON_STANDARD_TUNING;
}

void Msm8x53Sdhci::SdhciHwReset() {}

}  // namespace sdhci

static constexpr zx_driver_ops_t msm8x53_sdhci_driver_ops = []() -> zx_driver_ops_t {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = sdhci::Msm8x53Sdhci::Create;
  return ops;
}();

ZIRCON_DRIVER(msm8x53_sdhci, msm8x53_sdhci_driver_ops, "zircon", "0.1");
