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