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

#include <zircon/assert.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <ddk/debug.h>
#include <hw/reg.h>
#include <soc/aml-s905d2/s905d2-hiu.h>
#include <soc/aml-s905d2/s905d2-hw.h>

zx_status_t s905d2_hiu_init(aml_hiu_dev_t* device) {
  // Please do not use get_root_resource() in new code. See ZX-1467.
  zx_handle_t resource = get_root_resource();
  zx_status_t status;

  status = mmio_buffer_init_physical(&device->mmio, S905D2_HIU_BASE, S905D2_HIU_LENGTH, resource,
                                     ZX_CACHE_POLICY_UNCACHED_DEVICE);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: mmio_buffer_init_physical failed %d\n", __func__, status);
    return status;
  }
  device->regs_vaddr = device->mmio.vaddr;

  return ZX_OK;
}

static zx_status_t s905d2_pll_init_regs(aml_pll_dev_t* pll_dev) {
  aml_hiu_dev_t* device = pll_dev->hiu;

  if (pll_dev->pll_num == HIFI_PLL) {
    // write config values
    hiu_clk_set_reg(device, HHI_HIFI_PLL_CNTL1, G12A_HIFI_PLL_CNTL1);
    hiu_clk_set_reg(device, HHI_HIFI_PLL_CNTL2, G12A_HIFI_PLL_CNTL2);
    hiu_clk_set_reg(device, HHI_HIFI_PLL_CNTL3, G12A_HIFI_PLL_CNTL3);
    hiu_clk_set_reg(device, HHI_HIFI_PLL_CNTL4, G12A_HIFI_PLL_CNTL4);
    hiu_clk_set_reg(device, HHI_HIFI_PLL_CNTL5, G12A_HIFI_PLL_CNTL5);
    hiu_clk_set_reg(device, HHI_HIFI_PLL_CNTL6, G12A_HIFI_PLL_CNTL6);
    zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
    return ZX_OK;
  } else if (pll_dev->pll_num == SYS_PLL) {
    // write config values
    hiu_clk_set_reg(device, HHI_SYS_PLL_CNTL1, G12A_SYS_PLL_CNTL1);
    hiu_clk_set_reg(device, HHI_SYS_PLL_CNTL2, G12A_SYS_PLL_CNTL2);
    hiu_clk_set_reg(device, HHI_SYS_PLL_CNTL3, G12A_SYS_PLL_CNTL3);
    hiu_clk_set_reg(device, HHI_SYS_PLL_CNTL4, G12A_SYS_PLL_CNTL4);
    hiu_clk_set_reg(device, HHI_SYS_PLL_CNTL5, G12A_SYS_PLL_CNTL5);
    hiu_clk_set_reg(device, HHI_SYS_PLL_CNTL6, G12A_SYS_PLL_CNTL6);
    zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
    return ZX_OK;
  } else if (pll_dev->pll_num == GP0_PLL) {
    // write config values
    hiu_clk_set_reg(device, HHI_GP0_PLL_CNTL1, G12A_GP0_PLL_CNTL1);
    hiu_clk_set_reg(device, HHI_GP0_PLL_CNTL2, G12A_GP0_PLL_CNTL2);
    hiu_clk_set_reg(device, HHI_GP0_PLL_CNTL3, G12A_GP0_PLL_CNTL3);
    hiu_clk_set_reg(device, HHI_GP0_PLL_CNTL4, G12A_GP0_PLL_CNTL4);
    hiu_clk_set_reg(device, HHI_GP0_PLL_CNTL5, G12A_GP0_PLL_CNTL5);
    hiu_clk_set_reg(device, HHI_GP0_PLL_CNTL6, G12A_GP0_PLL_CNTL6);
    zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
    return ZX_OK;
  }
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t s905d2_pll_init(aml_hiu_dev_t* device, aml_pll_dev_t* pll_dev, hhi_plls_t pll_num) {
  ZX_DEBUG_ASSERT(device);
  ZX_DEBUG_ASSERT(pll_dev);

  pll_dev->hiu = device;

  pll_dev->rate_table = s905d2_pll_get_rate_table(pll_num);
  pll_dev->rate_idx = 0;
  pll_dev->frequency = 0;
  pll_dev->pll_num = pll_num;
  pll_dev->rate_count = s905d2_get_rate_table_count(pll_num);

  ZX_DEBUG_ASSERT(pll_dev->rate_table);
  ZX_DEBUG_ASSERT(pll_dev->rate_count);

  // Disable and reset the pll
  s905d2_pll_disable(pll_dev);
  // Write configuration registers
  return s905d2_pll_init_regs(pll_dev);
}

bool s905d2_pll_disable(aml_pll_dev_t* pll_dev) {
  uint32_t offs = hiu_get_pll_offs(pll_dev);
  uint32_t ctl0 = hiu_clk_get_reg(pll_dev->hiu, offs);

  bool retval = ctl0 & HHI_PLL_CNTL0_EN;

  ctl0 = (ctl0 & ~HHI_PLL_CNTL0_EN) | HHI_PLL_CNTL0_RESET;
  hiu_clk_set_reg(pll_dev->hiu, offs, ctl0);

  return retval;
}

zx_status_t s905d2_pll_ena(aml_pll_dev_t* pll_dev) {
  ZX_DEBUG_ASSERT(pll_dev);

  uint32_t offs = hiu_get_pll_offs(pll_dev);
  uint32_t reg_val = hiu_clk_get_reg(pll_dev->hiu, offs);

  // Set Enable bit
  reg_val |= HHI_PLL_CNTL0_EN;
  hiu_clk_set_reg(pll_dev->hiu, offs, reg_val);
  zx_nanosleep(zx_deadline_after(ZX_USEC(50)));

  // Clear Reset bit
  reg_val &= ~HHI_PLL_CNTL0_RESET;
  hiu_clk_set_reg(pll_dev->hiu, offs, reg_val);

  uint32_t wait_count = 100;
  while (wait_count) {
    if (hiu_clk_get_reg(pll_dev->hiu, offs) & HHI_PLL_LOCK) {
      return ZX_OK;
    }
    zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
    wait_count--;
  }

  return ZX_ERR_TIMED_OUT;
}

/* Notes:
    -VCO needs to be between 3-6GHz per the datasheet. It appears that if you
    provide values which would result in a VCO outside of this range, it will
    still oscillate, but at unknown (but likely close to target) frequency.
*/
zx_status_t s905d2_pll_set_rate(aml_pll_dev_t* pll_dev, uint64_t freq) {
  ZX_DEBUG_ASSERT(pll_dev);

  const hhi_pll_rate_t* pll_rate;

  zx_status_t status = s905d2_pll_fetch_rate(pll_dev, freq, &pll_rate);
  if (status != ZX_OK) {
    return status;
  }
  // Disable/reset the pll, save previous state
  bool ena = s905d2_pll_disable(pll_dev);

  // Initialize the registers to defaults (may not be retained after reset)
  s905d2_pll_init_regs(pll_dev);

  uint32_t offs = hiu_get_pll_offs(pll_dev);
  uint32_t ctl0 = hiu_clk_get_reg(pll_dev->hiu, offs);

  ctl0 &= ~HHI_PLL_CNTL0_M;
  ctl0 |= pll_rate->m << HHI_PLL_CNTL0_M_SHIFT;

  ctl0 &= ~HHI_PLL_CNTL0_N;
  ctl0 |= pll_rate->n << HHI_PLL_CNTL0_N_SHIFT;

  ctl0 &= ~HHI_PLL_CNTL0_OD;
  ctl0 |= pll_rate->od << HHI_PLL_CNTL0_OD_SHIFT;

  hiu_clk_set_reg(pll_dev->hiu, offs, ctl0);

  hiu_clk_set_reg(pll_dev->hiu, offs + 4, pll_rate->frac);

  if (ena) {
    return s905d2_pll_ena(pll_dev);
  }

  return ZX_OK;
}
