// 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_gpio.h"

#include "gpio_regs.h"  // Generated.

/**
 * Gives the mask that corresponds to the given bit index.
 *
 * @param index Bit index in a 32-bit register.
 */
static uint32_t index_to_mask(uint32_t index) { return 1u << index; }

/**
 * Perform a masked write to a GPIO register.
 *
 * The GPIO device provides masked bit-level atomic writes to its DIRECT_OUT
 * and DIRECT_OE registers. This allows software to modify half of the bits
 * at a time without requiring a read-modify-write. Note that depending on the
 * value of the `mask`, this function may perform two writes.
 *
 * For instance, DIRECT_OUT's lower and upper halves can be modified by
 * MASKED_OUT_LOWER and MASKED_OUT_UPPER, respectively. Upper half of
 * MASKED_OUT_LOWER is the mask that determines which bits in the lower half of
 * DIRECT_OUT will be modified, while lower half of MASKED_OUT_LOWER determines
 * their values. MASKED_OUT_UPPER behaves in the same way for modifying the
 * upper half of DIRECT_OUT.
 *
 * @param gpio GPIO instance.
 * @param reg_lower_offset Offset of the masked access register that corresponds
 * to the lower half of the actual register.
 * @param reg_upper_offset Offset of the masked access register that corresponds
 * to the upper half of the actual register.
 * @param mask Mask that identifies the bits to write to.
 * @param val Value to write.
 */
OT_WARN_UNUSED_RESULT
static dif_result_t gpio_masked_write(const dif_gpio_t *gpio,
                                      ptrdiff_t reg_lower_offset,
                                      ptrdiff_t reg_upper_offset, uint32_t mask,
                                      uint32_t val) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  const uint32_t mask_lower_half = mask & 0x0000FFFFu;
  const uint32_t mask_upper_half = mask & 0xFFFF0000u;
  if (mask_lower_half != 0) {
    mmio_region_write32(gpio->base_addr, reg_lower_offset,
                        (mask_lower_half << 16) | (val & 0x0000FFFFu));
  }
  if (mask_upper_half != 0) {
    mmio_region_write32(gpio->base_addr, reg_upper_offset,
                        mask_upper_half | ((val & 0xFFFF0000u) >> 16));
  }

  return kDifOk;
}

/**
 * Perform a masked write to a single bit of a GPIO register.
 *
 * The GPIO device provides masked bit-level atomic writes to its DIRECT_OUT
 * and DIRECT_OE registers. This allows software to modify half of the bits
 * at a time without requiring a read-modify-write. This function is guaranteed
 * to perform only one write since it never needs to access both halves of a
 * register.
 *
 * See also `gpio_masked_write()`.
 *
 * @param gpio GPIO instance.
 * @param reg_lower_offset Offset of the masked access register that corresponds
 * to the lower half of the actual register.
 * @param reg_upper_offset Offset of the masked access register that corresponds
 * to the upper half of the actual register.
 * @param index Zero-based index of the bit to write to.
 * @param val Value to write.
 */
OT_WARN_UNUSED_RESULT
static dif_result_t gpio_masked_bit_write(const dif_gpio_t *gpio,
                                          ptrdiff_t reg_lower_offset,
                                          ptrdiff_t reg_upper_offset,
                                          uint32_t index, bool val) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  // Write to reg_lower_offset if the bit is in the lower half, write to
  // reg_upper_offset otherwise.
  const ptrdiff_t offset = (index < 16) ? reg_lower_offset : reg_upper_offset;
  // Since masked access writes to half of a register, index mod 16 gives the
  // index of the bit in the half-word mask.
  const uint32_t mask = index_to_mask(index % 16);
  mmio_region_write32(gpio->base_addr, offset,
                      (mask << 16) | (val ? mask : 0u));

  return kDifOk;
}

dif_result_t dif_gpio_reset(const dif_gpio_t *gpio) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  // We don't need to write to `GPIO_MASKED_OE_*` and `GPIO_MASKED_OUT_*`
  // since we directly reset `GPIO_DIRECT_OE` and `GPIO_DIRECT_OUT` below.
  mmio_region_write32(gpio->base_addr, GPIO_INTR_ENABLE_REG_OFFSET, 0);
  mmio_region_write32(gpio->base_addr, GPIO_DIRECT_OE_REG_OFFSET, 0);
  mmio_region_write32(gpio->base_addr, GPIO_DIRECT_OUT_REG_OFFSET, 0);
  mmio_region_write32(gpio->base_addr, GPIO_INTR_CTRL_EN_RISING_REG_OFFSET, 0);
  mmio_region_write32(gpio->base_addr, GPIO_INTR_CTRL_EN_FALLING_REG_OFFSET, 0);
  mmio_region_write32(gpio->base_addr, GPIO_INTR_CTRL_EN_LVLHIGH_REG_OFFSET, 0);
  mmio_region_write32(gpio->base_addr, GPIO_INTR_CTRL_EN_LVLLOW_REG_OFFSET, 0);
  mmio_region_write32(gpio->base_addr, GPIO_CTRL_EN_INPUT_FILTER_REG_OFFSET, 0);
  // Also clear all pending interrupts
  mmio_region_write32(gpio->base_addr, GPIO_INTR_STATE_REG_OFFSET, 0xFFFFFFFFu);

  return kDifOk;
}

dif_result_t dif_gpio_irq_set_trigger(const dif_gpio_t *gpio,
                                      dif_gpio_mask_t mask,
                                      dif_gpio_irq_trigger_t trigger) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  // Disable all interrupt triggers for the given mask.
  mmio_region_nonatomic_clear_mask32(
      gpio->base_addr, GPIO_INTR_CTRL_EN_RISING_REG_OFFSET, mask, 0);
  mmio_region_nonatomic_clear_mask32(
      gpio->base_addr, GPIO_INTR_CTRL_EN_FALLING_REG_OFFSET, mask, 0);
  mmio_region_nonatomic_clear_mask32(
      gpio->base_addr, GPIO_INTR_CTRL_EN_LVLHIGH_REG_OFFSET, mask, 0);
  mmio_region_nonatomic_clear_mask32(
      gpio->base_addr, GPIO_INTR_CTRL_EN_LVLLOW_REG_OFFSET, mask, 0);

  switch (trigger) {
    case kDifGpioIrqTriggerEdgeRising:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_RISING_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqTriggerEdgeFalling:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_FALLING_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqTriggerLevelLow:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_LVLLOW_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqTriggerLevelHigh:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_LVLHIGH_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqTriggerEdgeRisingFalling:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_RISING_REG_OFFSET, mask, 0);
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_FALLING_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqTriggerEdgeRisingLevelLow:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_RISING_REG_OFFSET, mask, 0);
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_LVLLOW_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqTriggerEdgeFallingLevelHigh:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_FALLING_REG_OFFSET, mask, 0);
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_LVLHIGH_REG_OFFSET, mask, 0);
      break;
    default:
      return kDifError;
  }

  return kDifOk;
}

dif_result_t dif_gpio_read_all(const dif_gpio_t *gpio,
                               dif_gpio_state_t *state) {
  if (gpio == NULL || state == NULL) {
    return kDifBadArg;
  }

  *state = mmio_region_read32(gpio->base_addr, GPIO_DATA_IN_REG_OFFSET);

  return kDifOk;
}

dif_result_t dif_gpio_read(const dif_gpio_t *gpio, dif_gpio_pin_t pin,
                           bool *state) {
  if (gpio == NULL || state == NULL) {
    return kDifBadArg;
  }

  *state = mmio_region_get_bit32(gpio->base_addr, GPIO_DATA_IN_REG_OFFSET, pin);

  return kDifOk;
}

dif_result_t dif_gpio_write_all(const dif_gpio_t *gpio,
                                dif_gpio_state_t state) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  mmio_region_write32(gpio->base_addr, GPIO_DIRECT_OUT_REG_OFFSET, state);

  return kDifOk;
}

dif_result_t dif_gpio_write(const dif_gpio_t *gpio, dif_gpio_pin_t pin,
                            bool state) {
  return gpio_masked_bit_write(gpio, GPIO_MASKED_OUT_LOWER_REG_OFFSET,
                               GPIO_MASKED_OUT_UPPER_REG_OFFSET, pin, state);
}

dif_result_t dif_gpio_write_masked(const dif_gpio_t *gpio, dif_gpio_mask_t mask,
                                   dif_gpio_state_t state) {
  return gpio_masked_write(gpio, GPIO_MASKED_OUT_LOWER_REG_OFFSET,
                           GPIO_MASKED_OUT_UPPER_REG_OFFSET, mask, state);
}

dif_result_t dif_gpio_output_set_enabled_all(const dif_gpio_t *gpio,
                                             dif_gpio_state_t state) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  mmio_region_write32(gpio->base_addr, GPIO_DIRECT_OE_REG_OFFSET, state);

  return kDifOk;
}

dif_result_t dif_gpio_output_set_enabled(const dif_gpio_t *gpio,
                                         dif_gpio_pin_t pin,
                                         dif_toggle_t state) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  return gpio_masked_bit_write(gpio, GPIO_MASKED_OE_LOWER_REG_OFFSET,
                               GPIO_MASKED_OE_UPPER_REG_OFFSET, pin, state);
}

dif_result_t dif_gpio_output_set_enabled_masked(const dif_gpio_t *gpio,
                                                dif_gpio_mask_t mask,
                                                dif_gpio_state_t state) {
  return gpio_masked_write(gpio, GPIO_MASKED_OE_LOWER_REG_OFFSET,
                           GPIO_MASKED_OE_UPPER_REG_OFFSET, mask, state);
}

dif_result_t dif_gpio_input_noise_filter_set_enabled(const dif_gpio_t *gpio,
                                                     dif_gpio_mask_t mask,
                                                     dif_toggle_t state) {
  if (gpio == NULL) {
    return kDifBadArg;
  }

  switch (state) {
    case kDifToggleEnabled:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_CTRL_EN_INPUT_FILTER_REG_OFFSET, mask, 0);
      break;
    case kDifToggleDisabled:
      mmio_region_nonatomic_clear_mask32(
          gpio->base_addr, GPIO_CTRL_EN_INPUT_FILTER_REG_OFFSET, mask, 0);
      break;
    default:
      return kDifBadArg;
  }

  return kDifOk;
}
