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

// NB: Keep these definitions aligned with
// hw/top_matcha/rtl/chip_matcha_verilator.sv and
// hw/top_matcha/dv/env/chip_if.sv
const dif_pinmux_index_t kPinmuxTestutilsGpioInselPins[kDifGpioNumPins] = {
    kTopMatchaPinmuxInselIoa0,  kTopMatchaPinmuxInselIoa1,
    kTopMatchaPinmuxInselIoa2,  kTopMatchaPinmuxInselIoa3,
    kTopMatchaPinmuxInselIoa4,  kTopMatchaPinmuxInselIoa5,
    kTopMatchaPinmuxInselIoa6,  kTopMatchaPinmuxInselIoa7,
    kTopMatchaPinmuxInselIoa8,  kTopMatchaPinmuxInselIob0,
    kTopMatchaPinmuxInselIob1,  kTopMatchaPinmuxInselIob2,
    kTopMatchaPinmuxInselIob3,  kTopMatchaPinmuxInselIob4,
    kTopMatchaPinmuxInselIob5,  kTopMatchaPinmuxInselIob6,
    kTopMatchaPinmuxInselIob7,  kTopMatchaPinmuxInselIob8,
    kTopMatchaPinmuxInselIob10, kTopMatchaPinmuxInselIob11,
    kTopMatchaPinmuxInselIob12, kTopMatchaPinmuxInselIoc6,
    kTopMatchaPinmuxInselIoc0,  kTopMatchaPinmuxInselIoc1,
    kTopMatchaPinmuxInselIoc2,  kTopMatchaPinmuxInselIoc7,
    kTopMatchaPinmuxInselIoc9,  kTopMatchaPinmuxInselIod0,
    kTopMatchaPinmuxInselIor6,  kTopMatchaPinmuxInselIor7,
    kTopMatchaPinmuxInselIod1,  kTopMatchaPinmuxInselIor10,
};

const dif_pinmux_index_t kPinmuxTestutilsGpioMioOutPins[kDifGpioNumPins] = {
    kTopMatchaPinmuxMioOutIoa0,  kTopMatchaPinmuxMioOutIoa1,
    kTopMatchaPinmuxMioOutIoa2,  kTopMatchaPinmuxMioOutIoa3,
    kTopMatchaPinmuxMioOutIoa4,  kTopMatchaPinmuxMioOutIoa5,
    kTopMatchaPinmuxMioOutIoa6,  kTopMatchaPinmuxMioOutIoa7,
    kTopMatchaPinmuxMioOutIoa8,  kTopMatchaPinmuxMioOutIob0,
    kTopMatchaPinmuxMioOutIob1,  kTopMatchaPinmuxMioOutIob2,
    kTopMatchaPinmuxMioOutIob3,  kTopMatchaPinmuxMioOutIob4,
    kTopMatchaPinmuxMioOutIob5,  kTopMatchaPinmuxMioOutIob6,
    kTopMatchaPinmuxMioOutIob7,  kTopMatchaPinmuxMioOutIob8,
    kTopMatchaPinmuxMioOutIob10, kTopMatchaPinmuxMioOutIob11,
    kTopMatchaPinmuxMioOutIob12, kTopMatchaPinmuxMioOutIoc6,
    kTopMatchaPinmuxMioOutIoc0,  kTopMatchaPinmuxMioOutIoc1,
    kTopMatchaPinmuxMioOutIoc2,  kTopMatchaPinmuxMioOutIoc7,
    kTopMatchaPinmuxMioOutIoc9,  kTopMatchaPinmuxMioOutIod0,
    kTopMatchaPinmuxMioOutIor6,  kTopMatchaPinmuxMioOutIor7,
    kTopMatchaPinmuxMioOutIod1,  kTopMatchaPinmuxMioOutIor10,
};

void pinmux_testutils_init(dif_pinmux_t *pinmux) {
  for (int i = 0; i < kDifGpioNumPins; ++i) {
    dif_pinmux_index_t mio = kPinmuxTestutilsGpioInselPins[i];
    dif_pinmux_index_t gpio = kTopMatchaPinmuxPeripheralInGpioGpio0 + i;
    CHECK_DIF_OK(dif_pinmux_input_select(pinmux, gpio, mio));
  }

  for (int i = 0; i < kDifGpioNumPins; ++i) {
    dif_pinmux_index_t mio = kPinmuxTestutilsGpioMioOutPins[i];
    dif_pinmux_index_t gpio = kTopMatchaPinmuxOutselGpioGpio0 + i;
    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));
}

uint32_t pinmux_testutils_get_testable_gpios_mask(void) { return 0xffffffff; }

void pinmux_testutils_configure_pads(const dif_pinmux_t *pinmux,
                                     const pinmux_pad_attributes_t *attrs,
                                     size_t num_attrs) {
  for (size_t i = 0; i < num_attrs; ++i) {
    dif_pinmux_pad_attr_t desired_attr, actual_attr;
    CHECK_DIF_OK(dif_pinmux_pad_get_attrs(pinmux, attrs[i].pad, attrs[i].kind,
                                          &desired_attr));
    desired_attr.flags = attrs[i].flags;
    CHECK_DIF_OK(dif_pinmux_pad_write_attrs(pinmux, attrs[i].pad, attrs[i].kind,
                                            desired_attr, &actual_attr));
  }
}
