/*
 * Copyright 2023 Google LLC
 * Copyright lowRISC contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#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));
  }
}

dif_result_t pinmux_testutils_configure_i2s_tx(const dif_pinmux_t *pinmux) {
  if (pinmux == NULL) {
    return kDifBadArg;
  }
  // Mux I2S Tx
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIod3,
                                        kTopMatchaPinmuxOutselI2s0TxSclk));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIod4,
                                        kTopMatchaPinmuxOutselI2s0TxWs));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIod5,
                                        kTopMatchaPinmuxOutselI2s0TxSd));
  return kDifOk;
}

dif_result_t pinmux_testutils_configure_i2s_rx(const dif_pinmux_t *pinmux) {
  if (pinmux == NULL) {
    return kDifBadArg;
  }
  // Mux I2S Rx
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIod0,
                                        kTopMatchaPinmuxOutselI2s0RxSclk));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIod1,
                                        kTopMatchaPinmuxOutselI2s0RxWs));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInI2s0RxSd, kTopMatchaPinmuxInselIod2));
  return kDifOk;
}

dif_result_t pinmux_testutils_configure_cam_i2c(const dif_pinmux_t *pinmux) {
  if (pinmux == NULL) {
    return kDifBadArg;
  }
  // Mux Cam I2C
  CHECK_DIF_OK(dif_pinmux_input_select(pinmux,
                                       kTopMatchaPinmuxPeripheralInCamI2cSda,
                                       kTopMatchaPinmuxInselIoa5));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoa5,
                                        kTopMatchaPinmuxOutselCamI2cSda));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoa4,
                                        kTopMatchaPinmuxOutselCamI2cScl));
  CHECK_DIF_OK(dif_pinmux_input_select(pinmux,
                                       kTopMatchaPinmuxPeripheralInCamI2cScl,
                                       kTopMatchaPinmuxInselIoa4));
  return kDifOk;
}

dif_result_t pinmux_testutils_configure_isp_wrapper(
    const dif_pinmux_t *pinmux) {
  if (pinmux == NULL) {
    return kDifBadArg;
  }
#if defined(MATCHA_SPARROW)
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData0,
      kTopMatchaPinmuxInselIob0));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData1,
      kTopMatchaPinmuxInselIob1));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData2,
      kTopMatchaPinmuxInselIob2));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData3,
      kTopMatchaPinmuxInselIob3));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData4,
      kTopMatchaPinmuxInselIob4));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData5,
      kTopMatchaPinmuxInselIob5));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData6,
      kTopMatchaPinmuxInselIob6));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSData7,
      kTopMatchaPinmuxInselIob7));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSVsync,
      kTopMatchaPinmuxInselIob9));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVideoAudioWrapperSHsync,
      kTopMatchaPinmuxInselIob8));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInVsiCtlWrapperIspSclk,
      kTopMatchaPinmuxInselIob10));
#else
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData0,
      kTopMatchaPinmuxInselIob0));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData1,
      kTopMatchaPinmuxInselIob1));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData2,
      kTopMatchaPinmuxInselIob2));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData3,
      kTopMatchaPinmuxInselIob3));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData4,
      kTopMatchaPinmuxInselIob4));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData5,
      kTopMatchaPinmuxInselIob5));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData6,
      kTopMatchaPinmuxInselIob6));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSData7,
      kTopMatchaPinmuxInselIob7));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSVsync,
      kTopMatchaPinmuxInselIoa2));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSHsync,
      kTopMatchaPinmuxInselIoa3));
  CHECK_DIF_OK(dif_pinmux_input_select(
      pinmux, kTopMatchaPinmuxPeripheralInIspWrapperSPclk,
      kTopMatchaPinmuxInselIob8));
#endif

  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoa2,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoa3,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob0,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob1,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob2,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob3,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob4,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob5,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob6,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob7,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIob8,
                                        kTopMatchaPinmuxOutselConstantHighZ));
  return kDifOk;
}

dif_result_t pinmux_testutils_configure_cam_ctrl(const dif_pinmux_t *pinmux) {
  if (pinmux == NULL) {
    return kDifBadArg;
  }
  // Mux cam CTRL / TRIG
  CHECK_DIF_OK(
      dif_pinmux_input_select(pinmux, kTopMatchaPinmuxPeripheralInCamCtrlCamInt,
                              kTopMatchaPinmuxInselIoa6));
  CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoa7,
                                        kTopMatchaPinmuxOutselCamCtrlCamTrig));
  return kDifOk;
}
