// Copyright 2023 Google LLC.
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/dif/dif_sensor_ctrl.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/aon_timer_testutils.h"
#include "sw/device/lib/testing/clkmgr_testutils.h"
#include "sw/device/lib/testing/pwrmgr_testutils.h"
#include "sw/device/lib/testing/sensor_ctrl_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"

OTTF_DEFINE_TEST_CONFIG();

/**
 * AST CLK OUTPUTS TEST
 *
 * This test measure clock counts with clkmgr frequency measurements, performing
 * 100 measurements per round. Measurement errors (fast or slow clocks) are
 * recorded as recoverable error in clkmgr.
 *
 * After 100 measurements, test kicks in low-power mode, where
 * 3 clocks are off and measurement should not report spurious errors.
 *
 * When the dut wakes up, another 100 measurements are done before the
 * test finishes.
 *
 * Notice the test overrides the hardware behavior so it comes out with
 * calibrated USB clock, otherwise the USB clock frequency will be incorrect.
 * USB calibration should be a separate test, and may be vendor-specific.
 */
enum {
  kWaitForCSRPollingUs = 1,  // 1us
  kMeasurementsPerRound = 100,
};

static dif_clkmgr_t clkmgr;
static dif_pwrmgr_t pwrmgr;

bool test_main(void) {
  dif_sensor_ctrl_t sensor_ctrl;
  dif_aon_timer_t aon_timer;

  const uint32_t kMeasurementDelayMicros =
      aon_timer_testutils_get_us_from_aon_cycles(kMeasurementsPerRound);

  CHECK_DIF_OK(dif_clkmgr_init(
      mmio_region_from_addr(TOP_MATCHA_CLKMGR_AON_BASE_ADDR), &clkmgr));
  CHECK_DIF_OK(dif_sensor_ctrl_init(
      mmio_region_from_addr(TOP_MATCHA_SENSOR_CTRL_BASE_ADDR), &sensor_ctrl));
  CHECK_DIF_OK(dif_pwrmgr_init(
      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
  CHECK_DIF_OK(dif_aon_timer_init(
      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));

  LOG_INFO("TEST: wait for ast init");
  IBEX_SPIN_FOR(sensor_ctrl_ast_init_done(&sensor_ctrl), 1000);
  LOG_INFO("TEST: done ast init");

  if (pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) {
    // At POR.
    LOG_INFO("Run clock measurements right after POR");
    clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
        &clkmgr, /*jitter_enabled=*/false, /*external_clk=*/false,
        /*low_speed=*/false);
    busy_spin_micros(kMeasurementDelayMicros);

    // check results
    CHECK(clkmgr_testutils_check_measurement_counts(&clkmgr));
    clkmgr_testutils_disable_clock_counts(&clkmgr);

    // Set wakeup timer to 100 us to have enough down time, and also wait before
    // entering deep sleep to have a chance to measure before sleeping.
    // As a side-effect of deep sleep the clock measurements are disabled, but
    // recoverable errors are not cleared.
    //
    // Set the counters so we should get an error unless they are cleared.
    uint32_t wakeup_threshold = kDeviceType == kDeviceSimVerilator ? 1000 : 100;
    aon_timer_testutils_wakeup_config(&aon_timer, wakeup_threshold);

    LOG_INFO("Start clock measurements to cause an error for main clk.");
    clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
        &clkmgr, /*jitter_enabled=*/false, /*external_clk=*/true,
        /*low_speed=*/false);
    // Disable writes to measure ctrl registers.
    CHECK_DIF_OK(dif_clkmgr_measure_ctrl_disable(&clkmgr));

    busy_spin_micros(kMeasurementDelayMicros);

    pwrmgr_testutils_enable_low_power(
        &pwrmgr, kDifPwrmgrWakeupRequestSourceFive,
        kDifPwrmgrDomainOptionUsbClockInActivePower);

    LOG_INFO("TEST: Issue WFI to enter deep sleep");
    wait_for_interrupt();

  } else if (pwrmgr_testutils_is_wakeup_reason(
                 &pwrmgr, kDifPwrmgrWakeupRequestSourceFive)) {
    // Fail if some measurements are enabled.
    CHECK(clkmgr_testutils_check_measurement_enables(&clkmgr,
                                                     kDifToggleDisabled));
    // Check measurement control regwen is enabled.
    dif_toggle_t state;
    CHECK_DIF_OK(dif_clkmgr_measure_ctrl_get_enable(&clkmgr, &state));
    CHECK(state == kDifToggleEnabled);
    LOG_INFO("Check for all clock measurements disabled done");

    // Check we have a measurement error for the main clock.
    dif_clkmgr_recov_err_codes_t err_codes;
    CHECK_DIF_OK(dif_clkmgr_recov_err_code_get_codes(&clkmgr, &err_codes));
    CHECK(err_codes & kDifClkmgrRecovErrTypeMainMeas,
          "expected main clk measurement error, but got 0x%x", err_codes);

    // Clear measurement errors.
    CHECK_DIF_OK(dif_clkmgr_recov_err_code_clear_codes(&clkmgr, UINT32_MAX));

    LOG_INFO("TEST: one more measurement");
    clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
        &clkmgr, /*jitter_enabled=*/false, /*external_clk=*/false,
        /*low_speed=*/false);
    busy_spin_micros(kMeasurementDelayMicros);
    CHECK(clkmgr_testutils_check_measurement_counts(&clkmgr));
    clkmgr_testutils_disable_clock_counts(&clkmgr);

    LOG_INFO("TEST: done");
    return true;
  } else {  // error
    dif_pwrmgr_wakeup_reason_t wakeup_reason;
    CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
    LOG_ERROR("Unexpected wakeup detected: type = %d, request_source = %d",
              wakeup_reason.types, wakeup_reason.request_sources);
    return false;
  }

  return false;
}
