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

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

#include <assert.h>

#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/base/multibits.h"
#include "sw/device/lib/dif/dif_base.h"

#include "clkmgr_regs.h"  // Generated

// TODO: For the moment, CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS has to be <= than
// 32, as we only support one enable register for gateable clocks.
// https://github.com/lowRISC/opentitan/issues/4201
static_assert(
    CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS <= CLKMGR_PARAM_REG_WIDTH,
    "Expected the number of gateable clocks to be <= the width of a CSR.");

// TODO: For the moment, CLKMGR_PARAM_NUM_HINTABLE_CLOCKS has to be <= than
// 32, as we only support one enable/hint_status register for hintable clocks.
// https://github.com/lowRISC/opentitan/issues/4201
static_assert(
    CLKMGR_PARAM_NUM_HINTABLE_CLOCKS <= CLKMGR_PARAM_REG_WIDTH,
    "Expected the number of hintable clocks to be <= the width of a CSR.");

static bool clkmgr_valid_gateable_clock(dif_clkmgr_gateable_clock_t clock) {
  return clock < CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS;
}

static bool clkmgr_valid_hintable_clock(dif_clkmgr_hintable_clock_t clock) {
  return clock < CLKMGR_PARAM_NUM_HINTABLE_CLOCKS;
}

static bool clkmgr_measure_ctrl_regwen(const dif_clkmgr_t *clkmgr) {
  uint32_t measure_ctrl_regwen_val = mmio_region_read32(
      clkmgr->base_addr, CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET);
  return bitfield_bit32_read(measure_ctrl_regwen_val,
                             CLKMGR_MEASURE_CTRL_REGWEN_EN_BIT);
}

dif_result_t dif_clkmgr_external_clock_is_settled(const dif_clkmgr_t *clkmgr,
                                                  bool *status) {
  if (clkmgr == NULL || status == NULL) {
    return kDifBadArg;
  }
  uint32_t extclk_status_val =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
  *status = bitfield_field32_read(extclk_status_val,
                                  CLKMGR_EXTCLK_STATUS_ACK_FIELD) ==
            kMultiBitBool4True;

  return kDifOk;
}

dif_result_t dif_clkmgr_jitter_get_enabled(const dif_clkmgr_t *clkmgr,
                                           dif_toggle_t *state) {
  if (clkmgr == NULL || state == NULL) {
    return kDifBadArg;
  }

  multi_bit_bool_t clk_jitter_val =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET);
  // The documentation states that kMultiBitBool4False disables the jittery
  // clock and all other values enable the jittery clock.
  *state = clk_jitter_val != kMultiBitBool4False;

  return kDifOk;
}

dif_result_t dif_clkmgr_jitter_set_enabled(const dif_clkmgr_t *clkmgr,
                                           dif_toggle_t new_state) {
  multi_bit_bool_t new_jitter_enable_val;
  if (clkmgr == NULL) {
    return kDifBadArg;
  }

  switch (new_state) {
    case kDifToggleEnabled:
      new_jitter_enable_val = kMultiBitBool4True;
      break;
    case kDifToggleDisabled:
      new_jitter_enable_val = kMultiBitBool4False;
      break;
    default:
      return kDifBadArg;
  }
  mmio_region_write32(clkmgr->base_addr, CLKMGR_JITTER_ENABLE_REG_OFFSET,
                      new_jitter_enable_val);
  return kDifOk;
}

dif_result_t dif_clkmgr_gateable_clock_get_enabled(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock,
    dif_toggle_t *state) {
  if (clkmgr == NULL || state == NULL || !clkmgr_valid_gateable_clock(clock)) {
    return kDifBadArg;
  }

  uint32_t clk_enables_val =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
  *state = dif_bool_to_toggle(bitfield_bit32_read(clk_enables_val, clock));

  return kDifOk;
}

dif_result_t dif_clkmgr_gateable_clock_set_enabled(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock,
    dif_toggle_t new_state) {
  if (clkmgr == NULL || !clkmgr_valid_gateable_clock(clock) ||
      !dif_is_valid_toggle(new_state)) {
    return kDifBadArg;
  }

  bool new_clk_enables_bit = dif_toggle_to_bool(new_state);
  uint32_t clk_enables_val =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET);
  clk_enables_val =
      bitfield_bit32_write(clk_enables_val, clock, new_clk_enables_bit);
  mmio_region_write32(clkmgr->base_addr, CLKMGR_CLK_ENABLES_REG_OFFSET,
                      clk_enables_val);

  return kDifOk;
}

dif_result_t dif_clkmgr_hintable_clock_get_enabled(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
    dif_toggle_t *state) {
  if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
    return kDifBadArg;
  }

  uint32_t clk_hints_val =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_CLK_HINTS_STATUS_REG_OFFSET);
  *state = dif_bool_to_toggle(bitfield_bit32_read(clk_hints_val, clock));

  return kDifOk;
}

dif_result_t dif_clkmgr_hintable_clock_set_hint(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
    dif_toggle_t new_state) {
  if (clkmgr == NULL || !clkmgr_valid_hintable_clock(clock) ||
      !dif_is_valid_toggle(new_state)) {
    return kDifBadArg;
  }

  bool new_clk_hints_bit = dif_toggle_to_bool(new_state);
  uint32_t clk_hints_val =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
  clk_hints_val = bitfield_bit32_write(clk_hints_val, clock, new_clk_hints_bit);
  mmio_region_write32(clkmgr->base_addr, CLKMGR_CLK_HINTS_REG_OFFSET,
                      clk_hints_val);

  return kDifOk;
}

dif_result_t dif_clkmgr_hintable_clock_get_hint(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_hintable_clock_t clock,
    dif_toggle_t *state) {
  if (clkmgr == NULL || state == NULL || !clkmgr_valid_hintable_clock(clock)) {
    return kDifBadArg;
  }

  uint32_t clk_hints_val =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_CLK_HINTS_REG_OFFSET);
  *state = dif_bool_to_toggle(bitfield_bit32_read(clk_hints_val, clock));

  return kDifOk;
}

dif_result_t dif_clkmgr_external_clock_set_enabled(const dif_clkmgr_t *clkmgr,
                                                   bool is_low_speed) {
  uint32_t extclk_ctrl_reg = 0;

  if (clkmgr == NULL) {
    return kDifBadArg;
  }

  extclk_ctrl_reg = bitfield_field32_write(
      extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_SEL_FIELD, kMultiBitBool4True);
  extclk_ctrl_reg = bitfield_field32_write(
      extclk_ctrl_reg, CLKMGR_EXTCLK_CTRL_HI_SPEED_SEL_FIELD,
      is_low_speed ? kMultiBitBool4False : kMultiBitBool4True);
  mmio_region_write32(clkmgr->base_addr, CLKMGR_EXTCLK_CTRL_REG_OFFSET,
                      extclk_ctrl_reg);
  return kDifOk;
}

dif_result_t dif_clkmgr_measure_ctrl_disable(const dif_clkmgr_t *clkmgr) {
  if (clkmgr == NULL) {
    return kDifBadArg;
  }
  mmio_region_write32(clkmgr->base_addr, CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET,
                      0);
  return kDifOk;
}

dif_result_t dif_clkmgr_measure_ctrl_get_enable(const dif_clkmgr_t *clkmgr,
                                                dif_toggle_t *state) {
  if (clkmgr == NULL || state == NULL) {
    return kDifBadArg;
  }
  *state = dif_bool_to_toggle(clkmgr_measure_ctrl_regwen(clkmgr));
  return kDifOk;
}

dif_result_t dif_clkmgr_enable_measure_counts(const dif_clkmgr_t *clkmgr,
                                              dif_clkmgr_measure_clock_t clock,
                                              uint32_t lo_threshold,
                                              uint32_t hi_threshold) {
  if (clkmgr == NULL) {
    return kDifBadArg;
  }
  if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
    return kDifLocked;
  }

  uint32_t en_offset;
  uint32_t reg_offset;
  bitfield_field32_t en_field;
  bitfield_field32_t lo_field;
  bitfield_field32_t hi_field;
  switch (clock) {
#define PICK_COUNT_CTRL_FIELDS(kind_)                          \
  en_offset = CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET;        \
  reg_offset = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_REG_OFFSET; \
  en_field = CLKMGR_##kind_##_MEAS_CTRL_EN_EN_FIELD;           \
  lo_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_LO_FIELD;     \
  hi_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_HI_FIELD;     \
  break  // No semicolon to force semicolon below.
    case kDifClkmgrMeasureClockIo:
      PICK_COUNT_CTRL_FIELDS(IO);
    case kDifClkmgrMeasureClockIoDiv2:
      PICK_COUNT_CTRL_FIELDS(IO_DIV2);
    case kDifClkmgrMeasureClockIoDiv4:
      PICK_COUNT_CTRL_FIELDS(IO_DIV4);
    case kDifClkmgrMeasureClockMain:
      PICK_COUNT_CTRL_FIELDS(MAIN);
    case kDifClkmgrMeasureClockUsb:
      PICK_COUNT_CTRL_FIELDS(USB);
    default:
      return kDifBadArg;
#undef PICK_COUNT_CTRL_FIELDS
  }

  uint32_t measure_en_reg = 0;
  measure_en_reg =
      bitfield_field32_write(measure_en_reg, en_field, kMultiBitBool4True);
  mmio_region_write32(clkmgr->base_addr, en_offset, measure_en_reg);

  uint32_t measure_ctrl_reg = 0;
  measure_ctrl_reg =
      bitfield_field32_write(measure_ctrl_reg, lo_field, lo_threshold);
  measure_ctrl_reg =
      bitfield_field32_write(measure_ctrl_reg, hi_field, hi_threshold);
  // Two writes, because these registers are shadowed.
  mmio_region_write32(clkmgr->base_addr, reg_offset, measure_ctrl_reg);
  mmio_region_write32(clkmgr->base_addr, reg_offset, measure_ctrl_reg);

  return kDifOk;
}

dif_result_t dif_clkmgr_disable_measure_counts(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock) {
  if (clkmgr == NULL) {
    return kDifBadArg;
  }
  if (!clkmgr_measure_ctrl_regwen(clkmgr)) {
    return kDifLocked;
  }

  uint32_t en_offset;
  switch (clock) {
    case kDifClkmgrMeasureClockIo:
      en_offset = CLKMGR_IO_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockIoDiv2:
      en_offset = CLKMGR_IO_DIV2_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockIoDiv4:
      en_offset = CLKMGR_IO_DIV4_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockMain:
      en_offset = CLKMGR_MAIN_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockUsb:
      en_offset = CLKMGR_USB_MEAS_CTRL_EN_REG_OFFSET;
      break;
    default:
      return kDifBadArg;
  }
  mmio_region_write32(clkmgr->base_addr, en_offset, kMultiBitBool4False);
  return kDifOk;
}

dif_result_t dif_clkmgr_measure_counts_get_enable(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
    dif_toggle_t *state) {
  if (clkmgr == NULL || state == NULL) {
    return kDifBadArg;
  }

  uint32_t en_offset;
  switch (clock) {
    case kDifClkmgrMeasureClockIo:
      en_offset = CLKMGR_IO_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockIoDiv2:
      en_offset = CLKMGR_IO_DIV2_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockIoDiv4:
      en_offset = CLKMGR_IO_DIV4_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockMain:
      en_offset = CLKMGR_MAIN_MEAS_CTRL_EN_REG_OFFSET;
      break;
    case kDifClkmgrMeasureClockUsb:
      en_offset = CLKMGR_USB_MEAS_CTRL_EN_REG_OFFSET;
      break;
    default:
      return kDifBadArg;
  }
  multi_bit_bool_t en_val = mmio_region_read32(clkmgr->base_addr, en_offset);
  *state = dif_multi_bit_bool_to_toggle(en_val);

  return kDifOk;
}

dif_result_t dif_clkmgr_measure_counts_get_thresholds(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_measure_clock_t clock,
    uint32_t *min_threshold, uint32_t *max_threshold) {
  if (clkmgr == NULL || min_threshold == NULL || max_threshold == NULL) {
    return kDifBadArg;
  }

  uint32_t reg_offset;
  bitfield_field32_t lo_field;
  bitfield_field32_t hi_field;
  switch (clock) {
#define PICK_THRESHOLD_FIELDS(kind_)                           \
  reg_offset = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_REG_OFFSET; \
  lo_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_LO_FIELD;     \
  hi_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_HI_FIELD;     \
  break  // No semicolon to force semicolon below.
    case kDifClkmgrMeasureClockIo:
      PICK_THRESHOLD_FIELDS(IO);
    case kDifClkmgrMeasureClockIoDiv2:
      PICK_THRESHOLD_FIELDS(IO_DIV2);
    case kDifClkmgrMeasureClockIoDiv4:
      PICK_THRESHOLD_FIELDS(IO_DIV4);
    case kDifClkmgrMeasureClockMain:
      PICK_THRESHOLD_FIELDS(MAIN);
    case kDifClkmgrMeasureClockUsb:
      PICK_THRESHOLD_FIELDS(USB);
    default:
      return kDifBadArg;
#undef PICK_THRESHOLD_FIELDS
  }
  uint32_t thresholds_val = mmio_region_read32(clkmgr->base_addr, reg_offset);
  *min_threshold = bitfield_field32_read(thresholds_val, lo_field);
  *max_threshold = bitfield_field32_read(thresholds_val, hi_field);

  return kDifOk;
}

dif_result_t dif_clkmgr_recov_err_code_get_codes(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_recov_err_codes_t *codes) {
  if (clkmgr == NULL || codes == NULL) {
    return kDifBadArg;
  }
  *codes =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET);
  return kDifOk;
}

dif_result_t dif_clkmgr_recov_err_code_clear_codes(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_recov_err_codes_t codes) {
  if (clkmgr == NULL) {
    return kDifBadArg;
  }
  mmio_region_write32(clkmgr->base_addr, CLKMGR_RECOV_ERR_CODE_REG_OFFSET,
                      codes);
  return kDifOk;
}

dif_result_t dif_clkmgr_fatal_err_code_get_codes(
    const dif_clkmgr_t *clkmgr, dif_clkmgr_fatal_err_codes_t *codes) {
  if (clkmgr == NULL || codes == NULL) {
    return kDifBadArg;
  }
  *codes =
      mmio_region_read32(clkmgr->base_addr, CLKMGR_FATAL_ERR_CODE_REG_OFFSET);
  return kDifOk;
}

dif_result_t dif_clkmgr_wait_for_ext_clk_switch(const dif_clkmgr_t *clkmgr) {
  if (clkmgr == NULL) {
    return kDifBadArg;
  }
  uint32_t ext_status;
  do {
    ext_status =
        mmio_region_read32(clkmgr->base_addr, CLKMGR_EXTCLK_STATUS_REG_OFFSET);
  } while (ext_status != kMultiBitBool4True);
  return kDifOk;
}
