// 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.
#include "sw/device/lib/common.h"

/**
 * 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.
 */
static void gpio_masked_write(const dif_gpio_t *gpio, uint32_t reg_lower_offset,
                              uint32_t reg_upper_offset, uint32_t mask,
                              uint32_t val) {
  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));
  }
}

/**
 * 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.
 */
static void gpio_masked_bit_write(const dif_gpio_t *gpio,
                                  uint32_t reg_lower_offset,
                                  uint32_t reg_upper_offset, uint32_t index,
                                  bool val) {
  // 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));
}

dif_gpio_result_t dif_gpio_init(const dif_gpio_config_t *config,
                                dif_gpio_t *gpio) {
  if (config == NULL || gpio == NULL) {
    return kDifGpioBadArg;
  }

  // Save internal state in the given `dif_gpio_t` instance.
  gpio->base_addr = config->base_addr;
  // Reset the GPIO device at the given `base_addr`.
  dif_gpio_result_t err = dif_gpio_reset(gpio);
  if (err != kDifGpioOk) {
    return err;
  }

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_reset(const dif_gpio_t *gpio) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  // 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 kDifGpioOk;
}

dif_gpio_result_t dif_gpio_all_read(const dif_gpio_t *gpio,
                                    uint32_t *pin_values) {
  if (gpio == NULL || pin_values == NULL) {
    return kDifGpioBadArg;
  }

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

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_pin_read(const dif_gpio_t *gpio, uint32_t index,
                                    bool *pin_value) {
  if (gpio == NULL || pin_value == NULL) {
    return kDifGpioBadArg;
  }

  *pin_value =
      mmio_region_get_bit32(gpio->base_addr, GPIO_DATA_IN_REG_OFFSET, index);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_all_write(const dif_gpio_t *gpio, uint32_t val) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

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

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_pin_write(const dif_gpio_t *gpio, uint32_t index,
                                     bool val) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  gpio_masked_bit_write(gpio, GPIO_MASKED_OUT_LOWER_REG_OFFSET,
                        GPIO_MASKED_OUT_UPPER_REG_OFFSET, index, val);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_masked_write(const dif_gpio_t *gpio, uint32_t mask,
                                        uint32_t val) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  gpio_masked_write(gpio, GPIO_MASKED_OUT_LOWER_REG_OFFSET,
                    GPIO_MASKED_OUT_UPPER_REG_OFFSET, mask, val);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_output_mode_all_set(const dif_gpio_t *gpio,
                                               uint32_t val) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

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

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_output_mode_pin_set(const dif_gpio_t *gpio,
                                               uint32_t index, bool val) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  gpio_masked_bit_write(gpio, GPIO_MASKED_OE_LOWER_REG_OFFSET,
                        GPIO_MASKED_OE_UPPER_REG_OFFSET, index, val);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_output_mode_masked_set(const dif_gpio_t *gpio,
                                                  uint32_t mask, uint32_t val) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  gpio_masked_write(gpio, GPIO_MASKED_OE_LOWER_REG_OFFSET,
                    GPIO_MASKED_OE_UPPER_REG_OFFSET, mask, val);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_pin_test(const dif_gpio_t *gpio,
                                        uint32_t index) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  mmio_region_write32(gpio->base_addr, GPIO_INTR_TEST_REG_OFFSET,
                      index_to_mask(index));

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_all_read(const dif_gpio_t *gpio,
                                        uint32_t *interrupt_states) {
  if (gpio == NULL || interrupt_states == NULL) {
    return kDifGpioBadArg;
  }

  *interrupt_states =
      mmio_region_read32(gpio->base_addr, GPIO_INTR_STATE_REG_OFFSET);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_pin_read(const dif_gpio_t *gpio, uint32_t index,
                                        bool *interrupt_state) {
  if (gpio == NULL || interrupt_state == NULL) {
    return kDifGpioBadArg;
  }

  *interrupt_state =
      mmio_region_get_bit32(gpio->base_addr, GPIO_INTR_STATE_REG_OFFSET, index);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_pin_clear(const dif_gpio_t *gpio,
                                         uint32_t index) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  mmio_region_write32(gpio->base_addr, GPIO_INTR_STATE_REG_OFFSET,
                      index_to_mask(index));

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_input_noise_filter_masked_enable(
    const dif_gpio_t *gpio, uint32_t mask) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  mmio_region_nonatomic_set_mask32(
      gpio->base_addr, GPIO_CTRL_EN_INPUT_FILTER_REG_OFFSET, mask, 0);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_input_noise_filter_masked_disable(
    const dif_gpio_t *gpio, uint32_t mask) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  mmio_region_nonatomic_clear_mask32(
      gpio->base_addr, GPIO_CTRL_EN_INPUT_FILTER_REG_OFFSET, mask, 0);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_masked_enable(const dif_gpio_t *gpio,
                                             uint32_t mask) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  mmio_region_nonatomic_set_mask32(gpio->base_addr, GPIO_INTR_ENABLE_REG_OFFSET,
                                   mask, 0);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_masked_disable(const dif_gpio_t *gpio,
                                              uint32_t mask) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  mmio_region_nonatomic_clear_mask32(gpio->base_addr,
                                     GPIO_INTR_ENABLE_REG_OFFSET, mask, 0);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_trigger_masked_disable(const dif_gpio_t *gpio,
                                                      uint32_t mask) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  // 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);

  return kDifGpioOk;
}

dif_gpio_result_t dif_gpio_irq_trigger_masked_config(const dif_gpio_t *gpio,
                                                     uint32_t mask,
                                                     dif_gpio_irq_t config) {
  if (gpio == NULL) {
    return kDifGpioBadArg;
  }

  // Disable all interrupt triggers for the given mask
  dif_gpio_result_t error = dif_gpio_irq_trigger_masked_disable(gpio, mask);
  if (error != kDifGpioOk) {
    return error;
  }

  switch (config) {
    case kDifGpioIrqEdgeRising:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_RISING_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqEdgeFalling:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_FALLING_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqLevelLow:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_LVLLOW_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqLevelHigh:
      mmio_region_nonatomic_set_mask32(
          gpio->base_addr, GPIO_INTR_CTRL_EN_LVLHIGH_REG_OFFSET, mask, 0);
      break;
    case kDifGpioIrqEdgeRisingFalling:
      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 kDifGpioIrqEdgeRisingLevelLow:
      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 kDifGpioIrqEdgeFallingLevelHigh:
      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 kDifGpioError;
  }

  return kDifGpioOk;
}
