/*
 * Copyright 2023 Google LLC
 * Copyright lowRISC contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "sw/device/lib/testing/clkmgr_testutils.h"

#include "sw/device/lib/base/math.h"
#include "sw/device/lib/dif/dif_clkmgr.h"

static const char *measure_clock_names[kDifClkmgrMeasureClockVideo + 1] = {
    "audio_clk", "io_clk", "io_div2_clk", "io_div4_clk", "main_clk", "ml_clk",
    "smc_clk", "usb_clk", "video_clk"};

// Clocks defined in Matcha
const uint64_t kClockFreqSmcHz = 96 * 1000 * 1000;  // 96MHz

const uint64_t kClockFreqMlHz = 96 * 1000 * 1000;  // 96MHz

const uint64_t kClockFreqVideoHz = 96 * 1000 * 1000;  // 100MHz

const uint64_t kClockFreqAudioHz = 48 * 1000 * 1000;  // 48MHz

// `extern` declarations to give the inline functions in the
// corresponding header a link location.

extern bool clkmgr_testutils_get_trans_clock_status(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock);

extern void clkmgr_testutils_check_trans_clock_gating(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
    bool exp_clock_enabled, uint32_t timeout_usec);

// The thresholds are encoded as
// - max = count + variability
// - min = count - variability
typedef struct expected_count_info {
  uint32_t count;
  uint32_t variability;
} expected_count_info_t;

// The expected counts when jitter is disabled.
static expected_count_info_t kNoJitterCountInfos[kDifClkmgrMeasureClockVideo + 1];

// The expected counts when jitter is enabled.
static expected_count_info_t kJitterCountInfos[kDifClkmgrMeasureClockVideo + 1];

static uint32_t cast_safely(uint64_t val) {
  CHECK(val <= UINT32_MAX);
  return (uint32_t)val;
}

void initialize_expected_counts() {
  // The expected counts depend on the device, per sw/device/lib/arch/device.h.
  // Notice the ratios are small enough to fit a uint32_t, even if the Hz number
  // is in uint64_t.
  const uint32_t kDeviceCpuCount =
      cast_safely(udiv64_slow(kClockFreqCpuHz, kClockFreqAonHz,
                              /*rem_out=*/NULL));
  const uint32_t kDeviceIoCount =
      cast_safely(udiv64_slow(kClockFreqPeripheralHz, kClockFreqAonHz,
                              /*rem_out=*/NULL) *
                  4);
  const uint32_t kDeviceIoDiv2Count =
      cast_safely(udiv64_slow(kClockFreqPeripheralHz, kClockFreqAonHz,
                              /*rem_out=*/NULL) *
                  2);
  const uint32_t kDeviceIoDiv4Count =
      cast_safely(udiv64_slow(kClockFreqPeripheralHz, kClockFreqAonHz,
                              /*rem_out=*/NULL));
  const uint32_t kDeviceUsbCount =
      cast_safely(udiv64_slow(kClockFreqUsbHz, kClockFreqAonHz,
                              /*rem_out=*/NULL));

  const uint32_t kDeviceSmcCount =
      cast_safely(udiv64_slow(kClockFreqSmcHz, kClockFreqAonHz,
                              /*rem_out=*/NULL));

  const uint32_t kDeviceMlCount =
      cast_safely(udiv64_slow(kClockFreqMlHz, kClockFreqAonHz,
                              /*rem_out=*/NULL));

  const uint32_t kDeviceVideoCount =
      cast_safely(udiv64_slow(kClockFreqVideoHz, kClockFreqAonHz,
                              /*rem_out=*/NULL));

  const uint32_t kDeviceAudioCount =
      cast_safely(udiv64_slow(kClockFreqAudioHz, kClockFreqAonHz,
                              /*rem_out=*/NULL));

  // The expected counts are derived from the ratios of the frequencies of the
  // various clocks to the AON clock. For example, 48 Mhz / 200 kHz = 240, so
  // we set count to 239 and variability to 1, meaning the max threshold is 240,
  // and the min to 238.
  kNoJitterCountInfos[kDifClkmgrMeasureClockIo] =
      (expected_count_info_t){.count = kDeviceIoCount - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv2] = (expected_count_info_t){
      .count = kDeviceIoDiv2Count - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv4] = (expected_count_info_t){
      .count = kDeviceIoDiv4Count - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockMain] =
      (expected_count_info_t){.count = kDeviceCpuCount - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockUsb] =
      (expected_count_info_t){.count = kDeviceUsbCount - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockSmc] =
      (expected_count_info_t){.count = kDeviceSmcCount - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockMl] =
      (expected_count_info_t){.count = kDeviceMlCount - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockVideo] =
      (expected_count_info_t){.count = kDeviceVideoCount - 1, .variability = 1};
  kNoJitterCountInfos[kDifClkmgrMeasureClockAudio] =
      (expected_count_info_t){.count = kDeviceAudioCount - 1, .variability = 1};

  // If jitter is enabled the low threshold should be up to 20% lower, so
  // the variability is set to 0.1 * max_count, and count as max - 0.1 * max.
  kJitterCountInfos[kDifClkmgrMeasureClockIo] =
      (expected_count_info_t){.count = kDeviceIoCount - kDeviceIoCount / 10,
                              .variability = kDeviceIoCount / 10};
  kJitterCountInfos[kDifClkmgrMeasureClockIoDiv2] = (expected_count_info_t){
      .count = kDeviceIoDiv2Count - kDeviceIoDiv2Count / 10,
      .variability = kDeviceIoDiv2Count / 10};
  kJitterCountInfos[kDifClkmgrMeasureClockIoDiv4] = (expected_count_info_t){
      .count = kDeviceIoDiv4Count - kDeviceIoDiv4Count / 10,
      .variability = kDeviceIoDiv4Count};
  kJitterCountInfos[kDifClkmgrMeasureClockMain] =
      (expected_count_info_t){.count = kDeviceCpuCount - kDeviceCpuCount / 10,
                              .variability = kDeviceCpuCount / 10};
  kJitterCountInfos[kDifClkmgrMeasureClockUsb] =
      (expected_count_info_t){.count = kDeviceUsbCount - kDeviceUsbCount / 10,
                              .variability = kDeviceUsbCount / 10};
  kJitterCountInfos[kDifClkmgrMeasureClockSmc] =
      (expected_count_info_t){.count = kDeviceSmcCount - kDeviceSmcCount / 10,
                              .variability = kDeviceSmcCount / 10};
  kJitterCountInfos[kDifClkmgrMeasureClockMl] =
      (expected_count_info_t){.count = kDeviceMlCount - kDeviceMlCount / 10,
                              .variability = kDeviceMlCount / 10};
  kJitterCountInfos[kDifClkmgrMeasureClockVideo] =
      (expected_count_info_t){.count = kDeviceVideoCount - kDeviceVideoCount / 10,
                              .variability = kDeviceVideoCount / 10};
  kJitterCountInfos[kDifClkmgrMeasureClockAudio] =
      (expected_count_info_t){.count = kDeviceAudioCount - kDeviceAudioCount / 10,
                              .variability = kDeviceAudioCount / 10};
}

const char *clkmgr_testutils_measurement_name(
    dif_clkmgr_measure_clock_t clock) {
  switch (clock) {
  kDifClkmgrMeasureClockIo:
    return "io";
  kDifClkmgrMeasureClockIoDiv2:
    return "io_div2";
  kDifClkmgrMeasureClockIoDiv4:
    return "io_div4";
  kDifClkmgrMeasureClockMain:
    return "main";
  kDifClkmgrMeasureClockUsb:
    return "usb";
  kDifClkmgrMeasureClockSmc:
    return "smc";
  kDifClkmgrMeasureClockMl:
    return "ml";
  kDifClkmgrMeasureClockVideo:
    return "video";
  kDifClkmgrMeasureClockAudio:
    return "audio";
  default:
      LOG_ERROR("Unexpected clock measurement %d", clock);
  }
  return "unexpected clock";
}

void clkmgr_testutils_enable_clock_count(const dif_clkmgr_t *clkmgr,
                                         dif_clkmgr_measure_clock_t clock,
                                         uint32_t lo_threshold,
                                         uint32_t hi_threshold) {
  LOG_INFO("Enabling clock count measurement for %s(%d) lo %d hi %d",
           measure_clock_names[clock], clock, lo_threshold, hi_threshold);
  CHECK_DIF_OK(dif_clkmgr_enable_measure_counts(clkmgr, clock, lo_threshold,
                                                hi_threshold));
}

void clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
    const dif_clkmgr_t *clkmgr, bool jitter_enabled, bool external_clk,
    bool low_speed) {
  static bool counts_initialized = false;
  if (!counts_initialized) {
    initialize_expected_counts();
    counts_initialized = true;
  }
  CHECK(!(external_clk && jitter_enabled));
  for (int clk = 0; clk < ARRAYSIZE(kNoJitterCountInfos); ++clk) {
    const expected_count_info_t *count_info;
    if (jitter_enabled) {
      count_info = &kJitterCountInfos[clk];
    } else if (external_clk) {
      if (low_speed) {
        if (clk == kDifClkmgrMeasureClockIo ||
            clk == kDifClkmgrMeasureClockMain ||
            clk == kDifClkmgrMeasureClockAudio ||
            clk == kDifClkmgrMeasureClockSmc ||
            clk == kDifClkmgrMeasureClockMl ||
            clk == kDifClkmgrMeasureClockVideo) {
          count_info = &kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv2];
        } else {
          count_info = &kNoJitterCountInfos[clk];
        }
      } else {
        if (clk == kDifClkmgrMeasureClockMain ||
            clk == kDifClkmgrMeasureClockAudio ||
            clk == kDifClkmgrMeasureClockSmc ||
            clk == kDifClkmgrMeasureClockMl ||
            clk == kDifClkmgrMeasureClockVideo) {
          count_info = &kNoJitterCountInfos[kDifClkmgrMeasureClockIo];
        } else {
          count_info = &kNoJitterCountInfos[clk];
        }
      }
    } else {
      count_info = &kNoJitterCountInfos[clk];
    }
    clkmgr_testutils_enable_clock_count(
        clkmgr, (dif_clkmgr_measure_clock_t)clk,
        count_info->count - count_info->variability,
        count_info->count + count_info->variability);
  }
}

bool clkmgr_testutils_check_measurement_enables(const dif_clkmgr_t *clkmgr,
                                                dif_toggle_t expected_status) {
  bool success = true;
  for (int i = 0; i <= kDifClkmgrMeasureClockVideo; ++i) {
    dif_clkmgr_measure_clock_t clock = (dif_clkmgr_measure_clock_t)i;
    dif_toggle_t actual_status;
    CHECK_DIF_OK(
        dif_clkmgr_measure_counts_get_enable(clkmgr, clock, &actual_status));
    if (actual_status != expected_status) {
      LOG_INFO("Unexpected enable for clock %d: expected %s", i,
               (expected_status == kDifToggleEnabled ? "enabled" : "disabled"));
      success = false;
    }
  }
  return success;
}

void clkmgr_testutils_disable_clock_counts(const dif_clkmgr_t *clkmgr) {
  LOG_INFO("Disabling all clock count measurements");
  for (int i = 0; i <= kDifClkmgrMeasureClockVideo; ++i) {
    dif_clkmgr_measure_clock_t clock = (dif_clkmgr_measure_clock_t)i;
    CHECK_DIF_OK(dif_clkmgr_disable_measure_counts(clkmgr, clock));
  }
}

bool clkmgr_testutils_check_measurement_counts(const dif_clkmgr_t *clkmgr) {
  bool success = true;
  dif_clkmgr_recov_err_codes_t err_codes;
  CHECK_DIF_OK(dif_clkmgr_recov_err_code_get_codes(clkmgr, &err_codes));
  if (err_codes != 0) {
    LOG_ERROR("Unexpected recoverable error codes 0x%x", err_codes);
    success = false;
  } else {
    LOG_INFO("Clock measurements are okay");
  }
  // Clear recoverable errors.
  CHECK_DIF_OK(dif_clkmgr_recov_err_code_clear_codes(clkmgr, ~0u));
  return success;
}

void clkmgr_testutils_enable_external_clock_and_wait_for_completion(
    const dif_clkmgr_t *clkmgr, bool is_low_speed) {
  LOG_INFO("Configure clkmgr to enable external clock");
  CHECK_DIF_OK(dif_clkmgr_external_clock_set_enabled(clkmgr, is_low_speed));
  CHECK_DIF_OK(dif_clkmgr_wait_for_ext_clk_switch(clkmgr));
  LOG_INFO("Switching to external clock completes");
}
