// Copyright 2023 The Pigweed Authors
//
// 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
//
//     https://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 "pw_mipi_dsi_mcuxpresso/device.h"

#include <cstring>

#include "board.h"
#include "common.h"
#include "fsl_gpio.h"
#include "fsl_inputmux.h"
#include "fsl_mipi_dsi.h"
#include "fsl_mipi_dsi_smartdma.h"
#include "fsl_power.h"
#include "pin_mux.h"
#include "pw_assert/assert.h"

using pw::framebuffer::Framebuffer;
using pw::framebuffer_pool::FramebufferPool;

namespace pw::mipi::dsi {

namespace {

constexpr uint8_t kMipiDsiLaneNum = 1;
constexpr IRQn_Type kMipiDsiIrqn = MIPI_IRQn;
constexpr int kVideoLayer = 0;

// This class is currently a singleton because the some callbacks and IRQ
// handlers do not have a user-data param.
MCUXpressoDevice* s_device;

pw::mipi::dsi::Device::WriteCallback s_write_callback;
Framebuffer s_write_framebuffer;

extern "C" {
void GPIO_INTA_DriverIRQHandler(void) {
  uint32_t intStat = GPIO_PortGetInterruptStatus(GPIO, BOARD_MIPI_TE_PORT, 0);

  GPIO_PortClearInterruptFlags(GPIO, BOARD_MIPI_TE_PORT, 0, intStat);

  if (s_device && intStat & (1U << BOARD_MIPI_TE_PIN)) {
    s_device->DisplayTEPinHandler();
  }
}

void SDMA_DriverIRQHandler(void) { SMARTDMA_HandleIRQ(); }
}  // extern "C"

}  // namespace

MCUXpressoDevice::MCUXpressoDevice(const FramebufferPool& framebuffer_pool,
                                   const pw::math::Size<uint16_t>& panel_size,
                                   video_pixel_format_t pixel_format)
    : framebuffer_pool_(framebuffer_pool),
      fbdev_(kVideoLayer),
      dsi_device_({
          .virtualChannel = 0,
          .xferFunc = MCUXpressoDevice::DSI_Transfer,
          .memWriteFunc = MCUXpressoDevice::DSI_MemWrite,
          .callback = nullptr,
          .userData = nullptr,
      }),
      rm67162_resource_({
          .dsiDevice = &dsi_device_,
          .pullResetPin = MCUXpressoDevice::PullPanelResetPin,
          .pullPowerPin = MCUXpressoDevice::PullPanelPowerPin,
      }),
      display_handle_({
          .resource = &rm67162_resource_,
          .ops = &rm67162_ops,
          .width = panel_size.width,
          .height = panel_size.height,
          .pixelFormat = pixel_format,
      }),
      dc_fb_dsi_cmd_handle_({
          .dsiDevice = &dsi_device_,
          .panelHandle = &display_handle_,
          .initTimes = 0,
          .enabledLayerCount = 0,
          .layers = {},
          .useTEPin = true,
      }),
      panel_config_({
          .commonConfig =
              {
                  .resolution =
                      FSL_VIDEO_RESOLUTION(panel_size.width, panel_size.height),
                  .hsw = 0,  // Unused.
                  .hfp = 0,  // Unused.
                  .hbp = 0,  // Unused.
                  .vsw = 0,  // Unused.
                  .vfp = 0,  // Unused.
                  .vbp = 0,  // Unused.
                  .controlFlags = 0,
                  .dsiLanes = kMipiDsiLaneNum,
                  .pixelClock_Hz = 0,  // Unsure of correct value.
                  .pixelFormat = pixel_format,
              },
          .useTEPin = true,
      }),
      dc_({
          .ops = &g_dcFbOpsDsiCmd,
          .prvData = &dc_fb_dsi_cmd_handle_,
          .config = &panel_config_,
      }) {
  PW_ASSERT(s_device == nullptr);
  s_device = this;
}

MCUXpressoDevice::~MCUXpressoDevice() = default;

Status MCUXpressoDevice::Init() {
  const FramebufferPool::BufferArray& buffers =
      framebuffer_pool_.GetBuffersForInit();
  if (buffers.empty())
    return Status::InvalidArgument();

  Status s = PrepareDisplayController();
  if (!s.ok())
    return s;

  s = fbdev_.Init(&dc_, framebuffer_pool_);
  if (!s.ok())
    return s;

  // Clear buffer to black - it is shown once screen is enabled.
  void* buffer = fbdev_.GetFramebuffer();
  if (!buffer) {
    return Status::Internal();
  }
  std::memset(
      buffer,
      0,
      framebuffer_pool_.row_bytes() * framebuffer_pool_.dimensions().height);
  fbdev_.WriteFramebuffer(buffer, [](void*, Status) {});

  return fbdev_.Enable();
}

Framebuffer MCUXpressoDevice::GetFramebuffer() {
  return Framebuffer(fbdev_.GetFramebuffer(),
                     framebuffer_pool_.pixel_format(),
                     framebuffer_pool_.dimensions(),
                     framebuffer_pool_.row_bytes());
}

void MCUXpressoDevice::WriteFramebuffer(Framebuffer framebuffer,
                                        WriteCallback write_callback) {
  PW_ASSERT(framebuffer.is_valid());
  PW_ASSERT(!s_write_callback);
  s_write_callback = std::move(write_callback);
  s_write_framebuffer = std::move(framebuffer);
  fbdev_.WriteFramebuffer(s_write_framebuffer.data(),
                          [](void* buffer, Status s) {
                            PW_ASSERT(s_write_callback);
                            s_write_callback(std::move(s_write_framebuffer), s);
                          });
}

Status MCUXpressoDevice::PrepareDisplayController(void) {
  Status status = InitDisplayInterface();
  if (!status.ok())
    return status;

#if USE_DSI_SMARTDMA
  InitSmartDMA();
  status_t s = DSI_TransferCreateHandleSMARTDMA(
      MIPI_DSI_HOST,
      &dsi_smartdma_driver_handle_,
      MCUXpressoDevice::DsiSmartDMAMemWriteCallback,
      this);

  return MCUXpressoToPigweedStatus(s);

#else

  NVIC_SetPriority(kMipiDsiIrqn, 6);

  memset(&dsi_mem_write_ctx_, 0, sizeof(DSIMemWriteContext));

  return MCUXpressoToPigweedStatus(
      DSI_TransferCreateHandle(MIPI_DSI_HOST,
                               &dsi_driver_handle_,
                               MCUXpressoDevice::DsiMemWriteCallback,
                               this));
#endif
}

// static
Status MCUXpressoDevice::InitDisplayInterface() {
  RESET_SetPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn);
  InitMipiDsiClock();
  RESET_ClearPeripheralReset(kMIPI_DSI_CTRL_RST_SHIFT_RSTn);
  SetMipiDsiConfig();
  RESET_ClearPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn);
  return InitLcdPanel();
}

Status MCUXpressoDevice::InitLcdPanel() {
  const gpio_pin_config_t pinConfig = {
      .pinDirection = kGPIO_DigitalOutput,
      .outputLogic = 0,
  };

  GPIO_PinInit(GPIO, BOARD_MIPI_POWER_PORT, BOARD_MIPI_POWER_PIN, &pinConfig);
  GPIO_PinInit(GPIO, BOARD_MIPI_RST_PORT, BOARD_MIPI_RST_PIN, &pinConfig);

  InitMipiPanelTEPin();

  return OkStatus();
}

// static
void MCUXpressoDevice::InitMipiDsiClock(void) {
  POWER_DisablePD(kPDRUNCFG_APD_MIPIDSI_SRAM);
  POWER_DisablePD(kPDRUNCFG_PPD_MIPIDSI_SRAM);
  POWER_DisablePD(kPDRUNCFG_PD_MIPIDSI);
  POWER_ApplyPD();

  CLOCK_AttachClk(kFRO_DIV1_to_MIPI_DPHYESC_CLK);
  CLOCK_SetClkDiv(kCLOCK_DivDphyEscRxClk, 4);
  CLOCK_SetClkDiv(kCLOCK_DivDphyEscTxClk, 3);
  mipi_dsi_tx_esc_clk_freq_hz_ = CLOCK_GetMipiDphyEscTxClkFreq();

  CLOCK_AttachClk(kAUX1_PLL_to_MIPI_DPHY_CLK);
#if (DEMO_RM67162_BUFFER_FORMAT == PIXEL_FORMAT_RGB565)
  CLOCK_InitSysPfd(kCLOCK_Pfd3, 30);
#else
  CLOCK_InitSysPfd(kCLOCK_Pfd3, 19);
#endif
  CLOCK_SetClkDiv(kCLOCK_DivDphyClk, 1);
  mipi_dsi_dphy_bit_clk_freq_hz_ = CLOCK_GetMipiDphyClkFreq();
}

// static
void MCUXpressoDevice::InitMipiPanelTEPin(void) {
  const gpio_pin_config_t tePinConfig = {
      .pinDirection = kGPIO_DigitalInput,
      .outputLogic = 0,
  };

  gpio_interrupt_config_t te_pin_int_config = {kGPIO_PinIntEnableEdge,
                                               kGPIO_PinIntEnableHighOrRise};

  GPIO_PinInit(GPIO, BOARD_MIPI_TE_PORT, BOARD_MIPI_TE_PIN, &tePinConfig);

  GPIO_SetPinInterruptConfig(
      GPIO, BOARD_MIPI_TE_PORT, BOARD_MIPI_TE_PIN, &te_pin_int_config);

  GPIO_PinEnableInterrupt(GPIO, BOARD_MIPI_TE_PORT, BOARD_MIPI_TE_PIN, 0);

  NVIC_SetPriority(GPIO_INTA_IRQn, 3);

  NVIC_EnableIRQ(GPIO_INTA_IRQn);
}

// static
void MCUXpressoDevice::SetMipiDsiConfig() {
  dsi_config_t dsiConfig;
  dsi_dphy_config_t dphyConfig;

  DSI_GetDefaultConfig(&dsiConfig);
  dsiConfig.numLanes = kMipiDsiLaneNum;
  dsiConfig.autoInsertEoTp = true;

  DSI_GetDphyDefaultConfig(&dphyConfig,
                           mipi_dsi_dphy_bit_clk_freq_hz_,
                           mipi_dsi_tx_esc_clk_freq_hz_);

  DSI_Init(MIPI_DSI_HOST, &dsiConfig);

  DSI_InitDphy(MIPI_DSI_HOST, &dphyConfig, 0);
}

#if USE_DSI_SMARTDMA
// static
void MCUXpressoDevice::InitSmartDMA() {
  RESET_ClearPeripheralReset(kINPUTMUX_RST_SHIFT_RSTn);

  INPUTMUX_Init(INPUTMUX);
  INPUTMUX_AttachSignal(INPUTMUX, 0, kINPUTMUX_MipiIrqToSmartDmaInput);

  INPUTMUX_Deinit(INPUTMUX);

  POWER_DisablePD(kPDRUNCFG_APD_SMARTDMA_SRAM);
  POWER_DisablePD(kPDRUNCFG_PPD_SMARTDMA_SRAM);
  POWER_ApplyPD();

  RESET_ClearPeripheralReset(kSMART_DMA_RST_SHIFT_RSTn);
  CLOCK_EnableClock(kCLOCK_Smartdma);

  SMARTDMA_InitWithoutFirmware();
  NVIC_EnableIRQ(SDMA_IRQn);

  NVIC_SetPriority(SDMA_IRQn, 3);
}
#endif

// static
status_t MCUXpressoDevice::DSI_Transfer(dsi_transfer_t* xfer) {
  return DSI_TransferBlocking(MIPI_DSI_HOST, xfer);
}

// static
status_t MCUXpressoDevice::DSI_MemWrite(uint8_t virtualChannel,
                                        const uint8_t* data,
                                        uint32_t length) {
#if USE_DSI_SMARTDMA
  dsi_smartdma_write_mem_transfer_t xfer = {
#if (DEMO_RM67162_BUFFER_FORMAT == PIXEL_FORMAT_RGB565)
    .inputFormat = kDSI_SMARTDMA_InputPixelFormatRGB565,
    .outputFormat = kDSI_SMARTDMA_OutputPixelFormatRGB565,
#elif (DEMO_RM67162_BUFFER_FORMAT == PIXEL_FORMAT_RGB888)
    .inputFormat = kDSI_SMARTDMA_InputPixelFormatRGB888,
    .outputFormat = kDSI_SMARTDMA_OutputPixelFormatRGB888,
#else
    .inputFormat = kDSI_SMARTDMA_InputPixelFormatXRGB8888,
    .outputFormat = kDSI_SMARTDMA_OutputPixelFormatRGB888,
#endif /* DEMO_RM67162_BUFFER_FORMAT */
    .data = data,
    .dataSize = length,

    .virtualChannel = virtualChannel,
    .disablePixelByteSwap = false,
  };

  return DSI_TransferWriteMemorySMARTDMA(
      MIPI_DSI_HOST, &s_device->dsi_smartdma_driver_handle_, &xfer);

#else /* USE_DSI_SMARTDMA */

  status_t status;

  if (s_device->dsi_mem_write_ctx_.ongoing) {
    return kStatus_Fail;
  }

  s_device->dsi_mem_write_xfer_.virtualChannel = virtualChannel;
  s_device->dsi_mem_write_xfer_.flags = kDSI_TransferUseHighSpeed;
  s_device->dsi_mem_write_xfer_.sendDscCmd = true;

  s_device->dsi_mem_write_ctx_.ongoing = true;
  s_device->dsi_mem_write_ctx_.tx_data = data;
  s_device->dsi_mem_write_ctx_.num_bytes_remaining = length;
  s_device->dsi_mem_write_ctx_.dsc_cmd = kMIPI_DCS_WriteMemoryStart;

  status = s_device->DsiMemWriteSendChunck();

  if (status != kStatus_Success) {
    /* Memory write does not start actually. */
    s_device->dsi_mem_write_ctx_.ongoing = false;
  }

  return status;
#endif
}

// static
void MCUXpressoDevice::PullPanelResetPin(bool pullUp) {
  if (pullUp) {
    GPIO_PinWrite(GPIO, BOARD_MIPI_RST_PORT, BOARD_MIPI_RST_PIN, 1);
  } else {
    GPIO_PinWrite(GPIO, BOARD_MIPI_RST_PORT, BOARD_MIPI_RST_PIN, 0);
  }
}

// static
void MCUXpressoDevice::PullPanelPowerPin(bool pullUp) {
  if (pullUp) {
    GPIO_PinWrite(GPIO, BOARD_MIPI_POWER_PORT, BOARD_MIPI_POWER_PIN, 1);
  } else {
    GPIO_PinWrite(GPIO, BOARD_MIPI_POWER_PORT, BOARD_MIPI_POWER_PIN, 0);
  }
}

void MCUXpressoDevice::DisplayTEPinHandler() {
  DC_FB_DSI_CMD_TE_IRQHandler(&dc_);
}

// static
status_t MCUXpressoDevice::DsiMemWriteSendChunck(void) {
  uint32_t curSendLen;
  uint32_t i;

  curSendLen = kMaxDSITxArraySize > dsi_mem_write_ctx_.num_bytes_remaining
                   ? dsi_mem_write_ctx_.num_bytes_remaining
                   : kMaxDSITxArraySize;

  dsi_mem_write_xfer_.txDataType = kDSI_TxDataDcsLongWr;
  dsi_mem_write_xfer_.dscCmd = dsi_mem_write_ctx_.dsc_cmd;
  dsi_mem_write_xfer_.txData = dsi_mem_write_tmp_array_;
  dsi_mem_write_xfer_.txDataSize = curSendLen;

#if (DEMO_RM67162_BUFFER_FORMAT == PIXEL_FORMAT_RGB565)
  for (i = 0; i < curSendLen; i += 2) {
    dsi_mem_write_tmp_array_[i] = *(dsi_mem_write_ctx_.tx_data + 1);
    dsi_mem_write_tmp_array_[i + 1] = *(dsi_mem_write_ctx_.tx_data);

    dsi_mem_write_ctx_.tx_data += 2;
  }
#else
  for (i = 0; i < curSendLen; i += 3) {
    dsi_mem_write_tmp_array_[i] = *(dsi_mem_write_ctx_.tx_data + 2);
    dsi_mem_write_tmp_array_[i + 1] = *(dsi_mem_write_ctx_.tx_data + 1);
    dsi_mem_write_tmp_array_[i + 2] = *(dsi_mem_write_ctx_.tx_data);

    dsi_mem_write_ctx_.tx_data += 3;
  }
#endif

  dsi_mem_write_ctx_.num_bytes_remaining -= curSendLen;
  dsi_mem_write_ctx_.dsc_cmd = kMIPI_DCS_WriteMemoryContinue;

  return DSI_TransferNonBlocking(
      MIPI_DSI_HOST, &dsi_driver_handle_, &dsi_mem_write_xfer_);
}

// static
void MCUXpressoDevice::DsiMemWriteCallback(MIPI_DSI_HOST_Type* base,
                                           dsi_handle_t* handle,
                                           status_t status,
                                           void* userData) {
  MCUXpressoDevice* device = static_cast<MCUXpressoDevice*>(userData);
  if ((kStatus_Success == status) &&
      (device->dsi_mem_write_ctx_.num_bytes_remaining > 0)) {
    status = device->DsiMemWriteSendChunck();
    if (kStatus_Success == status) {
      return;
    }
  }

  device->dsi_mem_write_ctx_.ongoing = false;
  MIPI_DSI_MemoryDoneDriverCallback(status, &device->dsi_device_);
}

// static
void MCUXpressoDevice::DsiSmartDMAMemWriteCallback(
    MIPI_DSI_HOST_Type* base,
    dsi_smartdma_handle_t* handle,
    status_t status,
    void* userData) {
  MCUXpressoDevice* device = static_cast<MCUXpressoDevice*>(userData);
  MIPI_DSI_MemoryDoneDriverCallback(status, &device->dsi_device_);
}

}  // namespace pw::mipi::dsi
