// Copyright 2022 Google LLC.
// 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/testing/pinmux_testutils.h"

#include "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/base/macros.h"
#include "sw/device/lib/dif/dif_base.h"
#include "sw/device/lib/dif/dif_pinmux.h"
#include "sw/device/lib/runtime/hart.h"
#include "sw/device/lib/testing/test_framework/check.h"

#define NUM_GPIO 32

void pinmux_testutils_init(dif_pinmux_t *pinmux) {
  // input: assign MIO0..MIO31 to GPIO0..GPIO31 (except UARTs)
  for (uint32_t index = 0; index < NUM_GPIO; index++) {
    dif_pinmux_index_t mio = kTopMatchaPinmuxInselIoa0 + index;
    if (mio == kTopMatchaPinmuxInselIoc3 || mio == kTopMatchaPinmuxInselIoc10 ||
        mio == kTopMatchaPinmuxInselIob4) {
      // Avoid causing glitches: Don't assign the UART pins to a GPIO.
      continue;
    } else {
      dif_pinmux_index_t gpio = kTopMatchaPinmuxPeripheralInGpioGpio0 + index;
      CHECK_DIF_OK(dif_pinmux_input_select(pinmux, gpio, mio));
    }
  }

  // output: assign GPIO0..GPIO31 to MIO0..MIO31 (except UARTs)
  for (uint32_t index = 0; index < NUM_GPIO; index++) {
    dif_pinmux_index_t mio = kTopMatchaPinmuxMioOutIoa0 + index;
    if (mio == kTopMatchaPinmuxMioOutIoc3 ||
        mio == kTopMatchaPinmuxMioOutIoc4 ||
        mio == kTopMatchaPinmuxMioOutIoc10 ||
        mio == kTopMatchaPinmuxMioOutIoc11 ||
        mio == kTopMatchaPinmuxMioOutIob4 ||
        mio == kTopMatchaPinmuxMioOutIob5) {
      // Avoid causing glitches: Don't assign the UART pins to a GPIO.
      continue;
    } else {
      dif_pinmux_index_t gpio = kTopMatchaPinmuxOutselGpioGpio0 + index;
      CHECK_DIF_OK(dif_pinmux_output_select(pinmux, mio, gpio));
    }
  }

  // Configure UART0 RX input to connect to MIO pad IOC3
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInUart0Rx, kTopMatchaPinmuxInselIoc3));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoc3,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  // Configure UART0 TX output to connect to MIO pad IOC4
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoc4,
                                        kTopMatchaPinmuxOutselUart0Tx));

  // Enable pull-ups on UART0 RX
  // Pull-ups are available only on certain platforms.
  if (kDeviceType == kDeviceSimDV) {
    dif_pinmux_pad_attr_t out_attr;
    dif_pinmux_pad_attr_t in_attr = {
        .slew_rate = 0,
        .drive_strength = 0,
        .flags = kDifPinmuxPadAttrPullResistorEnable |
                 kDifPinmuxPadAttrPullResistorUp};

    CHECK_DIF_OK(dif_pinmux_pad_write_attrs(pinmux, kTopMatchaMuxedPadsIoc3,
                                            kDifPinmuxPadKindMio, in_attr,
                                            &out_attr));
    CHECK_DIF_OK(dif_pinmux_pad_write_attrs(pinmux, kTopMatchaMuxedPadsIoc10,
                                            kDifPinmuxPadKindMio, in_attr,
                                            &out_attr));
  };

  // Configure SMC_UART RX input to connect to MIO pad IOC10
  CHECK_DIF_OK(dif_pinmux_input_select(pinmux,
                                       kTopMatchaPinmuxPeripheralInSmcUartRx,
                                       kTopMatchaPinmuxInselIoc10));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoc10,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  // Configure SMC_UART TX output to connect to MIO pad IOC11
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoc11,
                                        kTopMatchaPinmuxOutselSmcUartTx));
}
