// 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 <limits>
#include <memory>
#include <utility>

#include <ddk/debug.h>
#include <fbl/alloc_checker.h>
#include <soc/aml-common/aml-pdm-audio.h>

// Filter configurations
// mode 1 lpf1
static const uint32_t lpf1m1[] = {
    0x000014, 0xffffb2, 0xfffed9, 0xfffdce, 0xfffd45, 0xfffe32, 0x000147, 0x000645, 0x000b86,
    0x000e21, 0x000ae3, 0x000000, 0xffeece, 0xffdca8, 0xffd212, 0xffd7d1, 0xfff2a7, 0x001f4c,
    0x0050c2, 0x0072aa, 0x006ff1, 0x003c32, 0xffdc4e, 0xff6a18, 0xff0fef, 0xfefbaf, 0xff4c40,
    0x000000, 0x00ebc8, 0x01c077, 0x02209e, 0x01c1a4, 0x008e60, 0xfebe52, 0xfcd690, 0xfb8fa5,
    0xfba498, 0xfd9812, 0x0181ce, 0x06f5f3, 0x0d112f, 0x12a958, 0x169686, 0x18000e, 0x169686,
    0x12a958, 0x0d112f, 0x06f5f3, 0x0181ce, 0xfd9812, 0xfba498, 0xfb8fa5, 0xfcd690, 0xfebe52,
    0x008e60, 0x01c1a4, 0x02209e, 0x01c077, 0x00ebc8, 0x000000, 0xff4c40, 0xfefbaf, 0xff0fef,
    0xff6a18, 0xffdc4e, 0x003c32, 0x006ff1, 0x0072aa, 0x0050c2, 0x001f4c, 0xfff2a7, 0xffd7d1,
    0xffd212, 0xffdca8, 0xffeece, 0x000000, 0x000ae3, 0x000e21, 0x000b86, 0x000645, 0x000147,
    0xfffe32, 0xfffd45, 0xfffdce, 0xfffed9, 0xffffb2, 0x000014,
};
constexpr uint32_t kLpf1m1Len = static_cast<uint32_t>(countof(lpf1m1));

// mode 1 lpf3
static const uint32_t lpf3m1[] = {
    0x000000, 0x000081, 0x000000, 0xfffedb, 0x000000, 0x00022d, 0x000000, 0xfffc46, 0x000000,
    0x0005f7, 0x000000, 0xfff6eb, 0x000000, 0x000d4e, 0x000000, 0xffed1e, 0x000000, 0x001a1c,
    0x000000, 0xffdcb0, 0x000000, 0x002ede, 0x000000, 0xffc2d1, 0x000000, 0x004ebe, 0x000000,
    0xff9beb, 0x000000, 0x007dd7, 0x000000, 0xff633a, 0x000000, 0x00c1d2, 0x000000, 0xff11d5,
    0x000000, 0x012368, 0x000000, 0xfe9c45, 0x000000, 0x01b252, 0x000000, 0xfdebf6, 0x000000,
    0x0290b8, 0x000000, 0xfcca0d, 0x000000, 0x041d7c, 0x000000, 0xfa8152, 0x000000, 0x07e9c6,
    0x000000, 0xf28fb5, 0x000000, 0x28b216, 0x3fffde, 0x28b216, 0x000000, 0xf28fb5, 0x000000,
    0x07e9c6, 0x000000, 0xfa8152, 0x000000, 0x041d7c, 0x000000, 0xfcca0d, 0x000000, 0x0290b8,
    0x000000, 0xfdebf6, 0x000000, 0x01b252, 0x000000, 0xfe9c45, 0x000000, 0x012368, 0x000000,
    0xff11d5, 0x000000, 0x00c1d2, 0x000000, 0xff633a, 0x000000, 0x007dd7, 0x000000, 0xff9beb,
    0x000000, 0x004ebe, 0x000000, 0xffc2d1, 0x000000, 0x002ede, 0x000000, 0xffdcb0, 0x000000,
    0x001a1c, 0x000000, 0xffed1e, 0x000000, 0x000d4e, 0x000000, 0xfff6eb, 0x000000, 0x0005f7,
    0x000000, 0xfffc46, 0x000000, 0x00022d, 0x000000, 0xfffedb, 0x000000, 0x000081, 0x000000,
};
constexpr uint32_t kLpf3m1Len = static_cast<uint32_t>(countof(lpf3m1));

// osr64 lpf2
static const uint32_t lpf2osr64[] = {
    0x00050a, 0xfff004, 0x0002c1, 0x003c12, 0xffa818, 0xffc87d, 0x010aef, 0xff5223, 0xfebd93,
    0x028f41, 0xff5c0e, 0xfc63f8, 0x055f81, 0x000000, 0xf478a0, 0x11c5e3, 0x2ea74d, 0x11c5e3,
    0xf478a0, 0x000000, 0x055f81, 0xfc63f8, 0xff5c0e, 0x028f41, 0xfebd93, 0xff5223, 0x010aef,
    0xffc87d, 0xffa818, 0x003c12, 0x0002c1, 0xfff004, 0x00050a,
};
constexpr uint32_t kLpf2osr64Len = static_cast<uint32_t>(countof(lpf2osr64));

// static
std::unique_ptr<AmlPdmDevice> AmlPdmDevice::Create(
    ddk::MmioBuffer pdm_mmio, ddk::MmioBuffer audio_mmio, ee_audio_mclk_src_t pdm_clk_src,
    uint32_t sysclk_div, uint32_t dclk_div, aml_toddr_t toddr_dev, metadata::AmlVersion version) {
  // TODDR A has 256 64-bit lines in the FIFO, B and C have 128.
  uint32_t fifo_depth = 128 * 8;  // in bytes.
  if (toddr_dev == TODDR_A) {
    fifo_depth = 256 * 8;
  }

  fbl::AllocChecker ac;
  auto pdm = std::unique_ptr<AmlPdmDevice>(
      new (&ac) AmlPdmDevice(std::move(pdm_mmio), std::move(audio_mmio), pdm_clk_src, sysclk_div,
                             dclk_div, toddr_dev, fifo_depth, version));
  if (!ac.check()) {
    zxlogf(ERROR, "%s: Could not create AmlPdmDevice", __func__);
    return nullptr;
  }

  pdm->InitRegs();
  constexpr uint32_t default_frames_per_second = 48000;
  pdm->ConfigFilters(default_frames_per_second);

  return pdm;
}

void AmlPdmDevice::InitRegs() {
  // Setup toddr block
  switch (version_) {
    case metadata::AmlVersion::kS905D2G:
      audio_mmio_.Write32((0x02 << 13) |    // Right justified 16-bit
                              (31 << 8) |   // msb position of data out of pdm
                              (16 << 3) |   // lsb position of data out of pdm
                              (0x04 << 0),  // select pdm as data source
                          GetToddrOffset(TODDR_CTRL0_OFFS));
      audio_mmio_.Write32(((fifo_depth_ / 8 / 2) << 16) |  // trigger ddr when fifo half full
                              (0x02 << 8),                 // STATUS2 source is ddr position
                          GetToddrOffset(TODDR_CTRL1_OFFS));
      break;
    case metadata::AmlVersion::kS905D3G:
      audio_mmio_.Write32((0x02 << 13) |   // Right justified 16-bit
                              (31 << 8) |  // msb position of data out of pdm
                              (16 << 3),   // lsb position of data out of pdm
                          GetToddrOffset(TODDR_CTRL0_OFFS));
      audio_mmio_.Write32((0x04 << 28) |                       // select pdm as data source
                              ((fifo_depth_ / 8 / 2) << 12) |  // trigger ddr when fifo half full
                              (0x02 << 8),                     // STATUS2 source is ddr position
                          GetToddrOffset(TODDR_CTRL1_OFFS));
      break;
  }

  //*To keep things simple, we are using the same clock source for both the
  // pdm sysclk and dclk.  Sysclk needs to be ~100-200MHz per AmLogic recommendations.
  // dclk is osr*fs
  //*Sysclk must be configured, enabled, and PDM audio clock gated prior to
  // accessing any of the registers mapped via pdm_mmio.  Writing without sysclk
  // operating properly (and in range) will result in unknown results, reads
  // will wedge the system.
  audio_mmio_.Write32((clk_src_ << 24) | dclk_div_, EE_AUDIO_CLK_PDMIN_CTRL0);
  audio_mmio_.Write32((1 << 31) | (clk_src_ << 24) | sysclk_div_, EE_AUDIO_CLK_PDMIN_CTRL1);

  audio_mmio_.SetBits32((1 << 31) | (1 << toddr_ch_), EE_AUDIO_ARB_CTRL);

  // Enable the audio domain clocks used by this instance.
  AudioClkEna(EE_AUDIO_CLK_GATE_PDM | (EE_AUDIO_CLK_GATE_TODDRA << toddr_ch_) |
              EE_AUDIO_CLK_GATE_ARB);
  // It is now safe to write to pdm registers

  // Ensure clocks are stable before accessing any of the pdm_mmio_ registers.
  zx::nanosleep(zx::deadline_after(zx::msec(10)));

  // Ensure system is in idle state in case we are re-initing hardware
  // which was already running.  Keep de-inited for 100ms with no pdm_dclk to
  // ensure pdm microphones will start reliably.
  Stop();
  zx::nanosleep(zx::deadline_after(zx::msec(100)));

  // Enable cts_pdm_clk gate (clock gate within pdm module)
  pdm_mmio_.SetBits32(0x01, PDM_CLKG_CTRL);

  pdm_mmio_.Write32((0x01 << 29),  // 24bit output mode
                    PDM_CTRL);

  // This sets the number of sysclk cycles between edge of dclk and when
  // data is sampled.  AmLogic material suggests this should be 3/4 of a
  // dclk half-cycle.  Go ahead and set all eight channels.
  uint32_t samp_delay = 3 * (dclk_div_ + 1) / (4 * 2 * (sysclk_div_ + 1));
  pdm_mmio_.Write32((samp_delay << 0) | (samp_delay << 8) | (samp_delay << 16) | (samp_delay << 24),
                    PDM_CHAN_CTRL);
  pdm_mmio_.Write32((samp_delay << 0) | (samp_delay << 8) | (samp_delay << 16) | (samp_delay << 24),
                    PDM_CHAN_CTRL1);
}

void AmlPdmDevice::ConfigFilters(uint32_t frames_per_second) {
  ZX_ASSERT(frames_per_second == 96000 || frames_per_second == 48000);

  uint32_t gain_shift = (frames_per_second == 96000) ? 0xe : 0x15;
  uint32_t downsample_rate = (frames_per_second == 96000) ? 0x4 : 0x8;

  pdm_mmio_.Write32((1 << 31) |                   // Enable
                        (gain_shift << 24) |      // Final gain shift parameter
                        (0x80 << 16) |            // Final gain multiplier
                        (downsample_rate << 4) |  // hcic downsample rate
                        (0x07 << 0),              // hcic stage number (must be between 3-9)
                    PDM_HCIC_CTRL1);

  // Note: The round mode field for the lowpass control registers is shown in AmLogic
  // documentation to be occupying bits [16:15] fo the register.  This was confirmed
  // by amlogic to be an error in the datasheet and the correct position is [17:16]
  pdm_mmio_.Write32((0x01 << 31) |          // Enable filter
                        (0x01 << 16) |      // Round mode
                        (0x02 << 12) |      // Filter 1 downsample rate
                        (kLpf1m1Len << 0),  // Number of taps in filter
                    PDM_F1_CTRL);
  pdm_mmio_.Write32((0x01 << 31) |             // Enable filter
                        (0x00 << 16) |         // Round mode
                        (0x02 << 12) |         // Filter 2 downsample rate
                        (kLpf2osr64Len << 0),  // Number of taps in filter
                    PDM_F2_CTRL);

  pdm_mmio_.Write32((0x01 << 31) |          // Enable filter
                        (0x01 << 16) |      // Round mode
                        (2 << 12) |         // Filter 3 downsample rate
                        (kLpf3m1Len << 0),  // Number of taps in filter
                    PDM_F3_CTRL);
  pdm_mmio_.Write32((0x01 << 31) |      // Enable filter
                        (0x0d << 16) |  // Shift steps
                        (0x8000 << 0),  // Output factor
                    PDM_HPF_CTRL);

  // set coefficient index pointer to 0
  pdm_mmio_.Write32(0x0000, PDM_COEFF_ADDR);

  // Write coefficients to coefficient memory
  //  --these appear to be packed with the filter length in each filter
  //    control register being the mechanism that helps reference them
  for (uint32_t i = 0; i < countof(lpf1m1); i++) {
    pdm_mmio_.Write32(lpf1m1[i], PDM_COEFF_DATA);
  }
  for (uint32_t i = 0; i < countof(lpf2osr64); i++) {
    pdm_mmio_.Write32(lpf2osr64[i], PDM_COEFF_DATA);
  }
  for (uint32_t i = 0; i < countof(lpf3m1); i++) {
    pdm_mmio_.Write32(lpf3m1[i], PDM_COEFF_DATA);
  }

  // set coefficient index pointer back to 0
  pdm_mmio_.Write32(0x0000, PDM_COEFF_ADDR);
}

void AmlPdmDevice::SetMute(uint8_t mute_mask) {
  pdm_mmio_.ModifyBits<uint32_t>(static_cast<uint32_t>(mute_mask) << 20, 0xff << 20, PDM_CTRL);
}

void AmlPdmDevice::SetRate(uint32_t frames_per_second) {
  ZX_ASSERT(frames_per_second == 48000 || frames_per_second == 96000);
  ConfigFilters(frames_per_second);
}

uint32_t AmlPdmDevice::GetRingPosition() {
  uint32_t pos = audio_mmio_.Read32(GetToddrOffset(TODDR_STATUS2_OFFS));
  uint32_t base = audio_mmio_.Read32(GetToddrOffset(TODDR_START_ADDR_OFFS));
  return (pos - base);
}

void AmlPdmDevice::AudioClkEna(uint32_t audio_blk_mask) {
  audio_mmio_.SetBits32(audio_blk_mask, EE_AUDIO_CLK_GATE_EN);
}

void AmlPdmDevice::AudioClkDis(uint32_t audio_blk_mask) {
  audio_mmio_.ClearBits32(audio_blk_mask, EE_AUDIO_CLK_GATE_EN);
}

zx_status_t AmlPdmDevice::SetBuffer(zx_paddr_t buf, size_t len) {
  // Ensure ring buffer resides in lower memory (dma pointers are 32-bit)
  //    and len is at least 8 (size of each dma operation)
  if (((buf + len - 1) > std::numeric_limits<uint32_t>::max()) || (len < 8)) {
    return ZX_ERR_INVALID_ARGS;
  }

  // Write32 the start and end pointers.  Each fetch is 64-bits, so end pointer
  //    is pointer to the last 64-bit fetch (inclusive)
  audio_mmio_.Write32(static_cast<uint32_t>(buf), GetToddrOffset(TODDR_START_ADDR_OFFS));
  audio_mmio_.Write32(static_cast<uint32_t>(buf), GetToddrOffset(TODDR_INIT_ADDR_OFFS));
  audio_mmio_.Write32(static_cast<uint32_t>(buf + len - 8), GetToddrOffset(TODDR_FINISH_ADDR_OFFS));
  return ZX_OK;
}

// Stops the pdm from clocking
void AmlPdmDevice::PdmInDisable() {
  audio_mmio_.ClearBits32(1 << 31, EE_AUDIO_CLK_PDMIN_CTRL0);
  pdm_mmio_.ClearBits32((1 << 31) | (1 << 16), PDM_CTRL);
}

// Enables the pdm to clock data
void AmlPdmDevice::PdmInEnable() {
  // Start pdm_dclk
  audio_mmio_.SetBits32(1 << 31, EE_AUDIO_CLK_PDMIN_CTRL0);
  pdm_mmio_.SetBits32((1 << 31) | (1 << 16), PDM_CTRL);
}

// Takes channels out of reset and enables them.
void AmlPdmDevice::ConfigPdmIn(uint8_t mask) {
  pdm_mmio_.ModifyBits<uint32_t>((mask << 8) | (mask << 0), (0xff << 8) | (0xff << 0), PDM_CTRL);
}

void AmlPdmDevice::TODDREnable() {
  // Set the load bit, will make sure things start from beginning of buffer
  audio_mmio_.SetBits32(1 << 31, GetToddrOffset(TODDR_CTRL0_OFFS));
}

void AmlPdmDevice::TODDRDisable() {
  // Clear the load bit (this is the bit that forces the initial fetch of
  //    start address into current ptr)
  audio_mmio_.ClearBits32(1 << 31, GetToddrOffset(TODDR_CTRL0_OFFS));
  audio_mmio_.ClearBits32(1 << 25, GetToddrOffset(TODDR_CTRL1_OFFS));
}

void AmlPdmDevice::Sync() {
  pdm_mmio_.ClearBits32(1 << 16, PDM_CTRL);
  pdm_mmio_.SetBits32(1 << 16, PDM_CTRL);
}

// Resets frddr mechanisms to start at beginning of buffer
//   starts the frddr (this will fill the fifo)
//   starts the tdm to clock out data on the bus
// returns the start time
uint64_t AmlPdmDevice::Start() {
  uint64_t a, b;

  Sync();
  TODDREnable();
  a = zx_clock_get_monotonic();
  PdmInEnable();
  b = zx_clock_get_monotonic();
  return ((b - a) >> 1) + a;
}

void AmlPdmDevice::Stop() {
  PdmInDisable();
  TODDRDisable();
}

void AmlPdmDevice::Shutdown() { Stop(); }
