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

#include <fuchsia/hardware/clock/c/fidl.h>
#include <lib/device-protocol/pdev.h>

#include <ddk/binding.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/clockimpl.h>
#include <ddk/protocol/platform/bus.h>
#include <ddk/protocol/platform/device.h>
#include <ddktl/protocol/platform/bus.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_lock.h>
#include <hwreg/bitfields.h>

#include "msm8x53-clk-regs.h"

namespace clk {

namespace {

constexpr char kMsmClkName[] = "msm-clk";
constexpr uint32_t kRcgUpdateTimeoutUsec = 500;
constexpr uint64_t kRcgRateUnset = 0;
constexpr uint32_t kCfgRcgrDivMask = (0x1f << 0);
constexpr uint32_t kCfgRcgrSrcSelMask = (0x7 << 8);

}  // namespace

zx_status_t Msm8x53Clk::Create(void* ctx, zx_device_t* parent) {
  zx_status_t status;

  ddk::PDev pdev(parent);
  if (!pdev.is_valid()) {
    zxlogf(ERROR, "msm-clk: failed to get pdev protocol");
    return ZX_ERR_NO_RESOURCES;
  }

  std::optional<ddk::MmioBuffer> mmio;
  status = pdev.MapMmio(0, &mmio);
  if (status != ZX_OK) {
    zxlogf(ERROR, "msm-clk: failed to map cc_base mmio, st = %d", status);
    return status;
  }

  std::unique_ptr<Msm8x53Clk> device(new Msm8x53Clk(parent, *std::move(mmio)));

  status = device->Init();
  if (status != ZX_OK) {
    zxlogf(ERROR, "msm-clk: failed to initialize, st = %d", status);
    return status;
  }

  status = device->DdkAdd(kMsmClkName);
  if (status != ZX_OK) {
    zxlogf(ERROR, "msm-clk: DdkAdd failed, st = %d", status);
    return status;
  }

  // Intentially leak, devmgr owns the memory now.
  __UNUSED auto* unused = device.release();

  return ZX_OK;
}

zx_status_t Msm8x53Clk::Init() {
  fbl::AutoLock lock(&rcg_rates_lock_);
  for (size_t i = 0; i < msm8x53::kRcgClkCount; i++) {
    rcg_rates_[i] = kRcgRateUnset;
  }

  return ZX_OK;
}

zx_status_t Msm8x53Clk::ClockImplEnable(uint32_t index) {
  // Extract the index and the type of the clock from the argument.
  const uint32_t clock_id = msm8x53::MsmClkIndex(index);
  const msm8x53::msm_clk_type clock_type = msm8x53::MsmClkType(index);

  switch (clock_type) {
    case msm8x53::msm_clk_type::kGate:
      return GateClockEnable(clock_id);
    case msm8x53::msm_clk_type::kBranch:
      return BranchClockEnable(clock_id);
    case msm8x53::msm_clk_type::kVoter:
      return VoterClockEnable(clock_id);
    case msm8x53::msm_clk_type::kRcg:
      return RcgClockEnable(clock_id);
  }

  // Unimplemented clock type?
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplDisable(uint32_t index) {
  // Extract the index and the type of the clock from the argument.
  const uint32_t clock_id = msm8x53::MsmClkIndex(index);
  const msm8x53::msm_clk_type clock_type = msm8x53::MsmClkType(index);

  switch (clock_type) {
    case msm8x53::msm_clk_type::kGate:
      return GateClockDisable(clock_id);
    case msm8x53::msm_clk_type::kBranch:
      return BranchClockDisable(clock_id);
    case msm8x53::msm_clk_type::kVoter:
      return VoterClockDisable(clock_id);
    case msm8x53::msm_clk_type::kRcg:
      return RcgClockDisable(clock_id);
  }

  // Unimplemented clock type?
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplIsEnabled(uint32_t id, bool* out_enabled) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplSetRate(uint32_t id, uint64_t hz) {
  const uint32_t index = msm8x53::MsmClkIndex(id);
  const msm8x53::msm_clk_type clock_type = msm8x53::MsmClkType(id);

  switch (clock_type) {
    case msm8x53::msm_clk_type::kRcg: {
      fbl::AutoLock rcg_rates_lock(&rcg_rates_lock_);
      return RcgClockSetRate(index, hz);
    }
    default:
      zxlogf(WARNING, "msm_clk: unsupported clock type: %u", (uint16_t)clock_type);
  }

  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplSetInput(uint32_t id, uint32_t idx) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplGetNumInputs(uint32_t id, uint32_t* out) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplGetInput(uint32_t id, uint32_t* out) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplQuerySupportedRate(uint32_t id, uint64_t max_rate,
                                                    uint64_t* out_best_rate) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::ClockImplGetRate(uint32_t id, uint64_t* out_current_rate) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Msm8x53Clk::AwaitBranchClock(Toggle status, const uint32_t cbcr_reg) {
  // In case the status check register and the clock control register cross
  // a boundary.
  hw_mb();

  // clang-format off
    constexpr uint32_t kReadyMask             = 0xf0000000;
    constexpr uint32_t kBranchEnableVal       = 0x0;
    constexpr uint32_t kBranchDisableVal      = 0x80000000;
    constexpr uint32_t kBranchNocFsmEnableVal = 0x20000000;
  // clang-format on

  constexpr uint32_t kMaxAttempts = 500;
  for (uint32_t attempts = 0; attempts < kMaxAttempts; attempts++) {
    const uint32_t val = mmio_.Read32(cbcr_reg) & kReadyMask;

    switch (status) {
      case Toggle::Enabled:
        if ((val == kBranchEnableVal) || (val == kBranchNocFsmEnableVal)) {
          return ZX_OK;
        }
        break;
      case Toggle::Disabled:
        if (val == kBranchDisableVal) {
          return ZX_OK;
        }
        break;
    }

    zx_nanosleep(zx_deadline_after(ZX_USEC(1)));
  }

  return ZX_ERR_TIMED_OUT;
}

zx_status_t Msm8x53Clk::VoterClockEnable(uint32_t index) {
  if (unlikely(index >= countof(kMsmClkVoters))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const struct clk::msm_clk_voter& clk = kMsmClkVoters[index];

  lock_.Acquire();
  mmio_.SetBits32(clk.bit, clk.vote_reg);
  lock_.Release();

  return AwaitBranchClock(Toggle::Enabled, clk.cbcr_reg);
}

zx_status_t Msm8x53Clk::VoterClockDisable(uint32_t index) {
  if (unlikely(index >= countof(kMsmClkVoters))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const struct clk::msm_clk_voter& clk = kMsmClkVoters[index];

  lock_.Acquire();
  mmio_.ClearBits32(clk.bit, clk.vote_reg);
  lock_.Release();

  return ZX_OK;
}

zx_status_t Msm8x53Clk::BranchClockEnable(uint32_t index) {
  if (unlikely(index >= countof(kMsmClkBranches))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const struct clk::msm_clk_branch& clk = kMsmClkBranches[index];

  lock_.Acquire();
  mmio_.SetBits32(kBranchEnable, clk.reg);
  lock_.Release();

  return AwaitBranchClock(Toggle::Enabled, clk.reg);
}

zx_status_t Msm8x53Clk::BranchClockDisable(uint32_t index) {
  if (unlikely(index >= countof(kMsmClkBranches))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const struct msm_clk_branch& clk = kMsmClkBranches[index];

  lock_.Acquire();
  mmio_.ClearBits32(kBranchEnable, clk.reg);
  lock_.Release();

  return AwaitBranchClock(Toggle::Disabled, clk.reg);
}

zx_status_t Msm8x53Clk::GateClockEnable(uint32_t index) {
  if (unlikely(index >= countof(kMsmClkGates))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const msm_clk_gate_t& clk = kMsmClkGates[index];

  lock_.Acquire();
  mmio_.SetBits32((1u << clk.bit), clk.reg);
  lock_.Release();

  if (clk.delay_us) {
    zx_nanosleep(zx_deadline_after(ZX_USEC(clk.delay_us)));
  }

  return ZX_OK;
}
zx_status_t Msm8x53Clk::GateClockDisable(uint32_t index) {
  if (unlikely(index > countof(kMsmClkGates))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const msm_clk_gate_t& clk = kMsmClkGates[index];

  lock_.Acquire();
  mmio_.ClearBits32(clk.bit, clk.reg);
  lock_.Release();

  if (clk.delay_us) {
    zx_nanosleep(zx_deadline_after(ZX_USEC(clk.delay_us)));
  }

  return ZX_OK;
}

zx_status_t Msm8x53Clk::RcgClockEnable(uint32_t index) {
  if (unlikely(index > countof(kMsmClkRcgs))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const MsmClkRcg& clk = kMsmClkRcgs[index];

  // Check to see if frequency has been set.
  fbl::AutoLock lock(&rcg_rates_lock_);
  if (rcg_rates_[index] == kRcgRateUnset) {
    zxlogf(ERROR, "Attempted to enable RCG %u before setting rate", index);
    return ZX_ERR_BAD_STATE;
  }

  zx_status_t st;

  st = ToggleRcgForceEnable(clk.CmdReg(), Toggle::Enabled);
  if (st != ZX_OK) {
    return st;
  }

  st = RcgClockSetRate(index, rcg_rates_[index]);
  if (st != ZX_OK) {
    return st;
  }

  st = ToggleRcgForceEnable(clk.CmdReg(), Toggle::Disabled);
  if (st != ZX_OK) {
    return st;
  }

  return st;
}

zx_status_t Msm8x53Clk::RcgClockDisable(uint32_t index) {
  // This is a NOP for all clocks that we support.
  // It only needs to be implemented for clocks with non-local children.
  return ZX_OK;
}

zx_status_t Msm8x53Clk::RcgClockSetRate(uint32_t index, uint64_t rate) {
  if (unlikely(index >= countof(kMsmClkRcgs))) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  const MsmClkRcg& clk = kMsmClkRcgs[index];

  // Clocks with non-local children or nonlocal control timeouts are
  // currently unimplemented.
  // Clocks with source frequencies that are not fixed are also currently
  // unimplemented.
  if (clk.Unsupported()) {
    zxlogf(ERROR,
           "Attempted to set rate for clock %u which is currently "
           "unimplemented\n",
           index);
    return ZX_ERR_NOT_SUPPORTED;
  }

  // Search for the requested frequency in the clock's frequency table.
  const RcgFrequencyTable* table = nullptr;
  for (size_t i = 0; i < clk.TableCount(); i++) {
    if (rate == clk.Table()[i].rate()) {
      table = &clk.Table()[i];
      break;
    }
  }

  if (table == nullptr) {
    // This clock frequency is not supported.
    zxlogf(WARNING, "unsupported clock frequency, clk = %u, rate = %lu", index, rate);
    return ZX_ERR_NOT_SUPPORTED;
  }

  {  // Nested scope for scoped locking
    fbl::AutoLock lock(&lock_);

    switch (clk.Type()) {
      case RcgDividerType::HalfInteger:
        RcgSetRateHalfInteger(clk, table);
        break;
      case RcgDividerType::Mnd:
        RcgSetRateMnd(clk, table);
        break;
    }
  }

  // Update the frequency that we have listed in the RCG table.
  rcg_rates_[index] = rate;

  return ZX_OK;
}

zx_status_t Msm8x53Clk::LatchRcgConfig(const MsmClkRcg& clk) {
  // Whack the config update bit and wait for it to stabilize.
  constexpr uint32_t kCmdRcgrConfigUpdateBit = (0x1 << 0);
  mmio_.SetBits32(kCmdRcgrConfigUpdateBit, clk.CmdReg());

  constexpr uint32_t kMaxAttempts = 500;
  for (uint32_t i = 0; i < kMaxAttempts; i++) {
    const uint32_t cmd_reg = mmio_.Read32(clk.CmdReg());

    if ((cmd_reg & kCmdRcgrConfigUpdateBit) == 0) {
      return ZX_OK;
    }

    zx_nanosleep(zx_deadline_after(ZX_USEC(1)));
  }

  zxlogf(WARNING, "Failed to latch RCG config");
  return ZX_ERR_TIMED_OUT;
}

zx_status_t Msm8x53Clk::RcgSetRateHalfInteger(const MsmClkRcg& clk,
                                              const RcgFrequencyTable* table) {
  uint32_t val;

  val = mmio_.Read32(clk.CfgReg());
  val &= ~(kCfgRcgrDivMask | kCfgRcgrSrcSelMask);
  val |= table->predev_parent();
  mmio_.Write32(val, clk.CfgReg());

  return LatchRcgConfig(clk);
}

zx_status_t Msm8x53Clk::RcgSetRateMnd(const MsmClkRcg& clk, const RcgFrequencyTable* table) {
  uint32_t cfg = mmio_.Read32(clk.CfgReg());

  constexpr uint32_t kMndModeMask = (0x3 << 12);
  constexpr uint32_t kMndDualEdgeMode = (0x2 << 12);

  mmio_.Write32(table->m(), clk.MReg());
  mmio_.Write32(table->n(), clk.NReg());
  mmio_.Write32(table->d(), clk.DReg());

  cfg = mmio_.Read32(clk.CfgReg());
  cfg &= ~(kCfgRcgrDivMask | kCfgRcgrSrcSelMask);
  cfg |= table->predev_parent();

  cfg &= ~kMndModeMask;
  if (table->n() != 0) {
    cfg |= kMndDualEdgeMode;
  }
  mmio_.Write32(cfg, clk.CfgReg());

  return LatchRcgConfig(clk);
}

zx_status_t Msm8x53Clk::ToggleRcgForceEnable(uint32_t rcgr_cmd_offset, Toggle toggle) {
  constexpr uint32_t kRcgForceDisableDelayUSeconds = 100;
  constexpr uint32_t kRcgRootEnableBit = (1 << 1);
  zx_status_t result = ZX_OK;

  switch (toggle) {
    case Toggle::Enabled:
      lock_.Acquire();
      mmio_.SetBits32(kRcgRootEnableBit, rcgr_cmd_offset);
      result = AwaitRcgEnableLocked(rcgr_cmd_offset);
      lock_.Release();
      break;
    case Toggle::Disabled:
      lock_.Acquire();
      mmio_.ClearBits32(kRcgRootEnableBit, rcgr_cmd_offset);
      lock_.Release();
      zx_nanosleep(zx_deadline_after(ZX_USEC(kRcgForceDisableDelayUSeconds)));
      break;
  }
  return result;
}

zx_status_t Msm8x53Clk::AwaitRcgEnableLocked(uint32_t rcgr_cmd_offset) {
  for (uint32_t i = 0; i < kRcgUpdateTimeoutUsec; i++) {
    auto rcg_ctrl = RcgClkCmd::Read(rcgr_cmd_offset).ReadFrom(&mmio_);

    if (rcg_ctrl.root_status() == 0) {
      return ZX_OK;
    }

    zx_nanosleep(zx_deadline_after(ZX_USEC(1)));
  }

  return ZX_ERR_TIMED_OUT;
}

zx_status_t Msm8x53Clk::Bind() { return ZX_OK; }
void Msm8x53Clk::DdkUnbind(ddk::UnbindTxn txn) {
  fbl::AutoLock lock(&lock_);

  mmio_.reset();

  txn.Reply();
}

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

}  // namespace clk

static constexpr zx_driver_ops_t msm8x53_clk_driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = clk::Msm8x53Clk::Create;
  return ops;
}();

// clang-format off
ZIRCON_DRIVER_BEGIN(msm8x53_clk, msm8x53_clk_driver_ops, "zircon", "0.1", 3)
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PDEV),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_QUALCOMM),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_QUALCOMM_CLOCK),
ZIRCON_DRIVER_END(msm8x53_clk)
