// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/graphics/display/drivers/intel-i915/dp-display.h"

#include <lib/mmio-ptr/fake.h>
#include <lib/mmio/mmio.h>

#include <cstdint>
#include <memory>
#include <optional>

#include <gtest/gtest.h>

#include "src/graphics/display/drivers/intel-i915/ddi-physical-layer-manager.h"
#include "src/graphics/display/drivers/intel-i915/dpll.h"
#include "src/graphics/display/drivers/intel-i915/fake-dpcd-channel.h"
#include "src/graphics/display/drivers/intel-i915/hardware-common.h"
#include "src/graphics/display/drivers/intel-i915/intel-i915.h"
#include "src/graphics/display/drivers/intel-i915/pch-engine.h"
#include "src/graphics/display/drivers/intel-i915/pci-ids.h"
#include "src/graphics/display/drivers/intel-i915/pipe-manager.h"
#include "src/graphics/display/drivers/intel-i915/power.h"
#include "src/graphics/display/drivers/intel-i915/registers-ddi.h"
#include "src/graphics/display/drivers/intel-i915/registers-dpll.h"
#include "src/graphics/display/lib/api-types-cpp/display-id.h"

namespace i915 {

namespace {

// Value used to allocate space for the fake i915 register MMIO space.
// TODO(https://fxbug.dev/42164736): Remove this once DpDisplay no longer depends on Controller.
constexpr uint32_t kMmioSize = 0xd0000;

class TestDpll : public DisplayPll {
 public:
  explicit TestDpll(PllId pll_id) : DisplayPll(pll_id) {}
  ~TestDpll() override = default;

  bool DoEnable(const DdiPllConfig& pll_config) final {
    enabled_ = true;
    return enabled_;
  }
  bool DoDisable() final {
    enabled_ = false;
    return enabled_;
  }

 private:
  bool enabled_ = false;
};

class TestDpllManager : public DisplayPllManager {
 public:
  explicit TestDpllManager() {
    for (const auto dpll : kDplls) {
      plls_[dpll] = std::make_unique<TestDpll>(dpll);
      ref_count_[plls_[dpll].get()] = 0;
    }
  }

  DdiPllConfig LoadState(DdiId ddi_id) final {
    return DdiPllConfig{
        .ddi_clock_khz = 2'700'000,  // DisplayPort HBR2 5.4Gbps / lane
        .spread_spectrum_clocking = false,
        .admits_display_port = true,
        .admits_hdmi = false,
    };
  }

 private:
  constexpr static auto kDplls = {PllId::DPLL_0, PllId::DPLL_1, PllId::DPLL_2};

  bool SetDdiClockSource(DdiId ddi_id, PllId pll_id) final { return true; }
  bool ResetDdiClockSource(DdiId ddi_id) final { return true; }

  DisplayPll* FindPllFor(DdiId ddi_id, bool is_edp, const DdiPllConfig& desired_config) final {
    for (const auto dpll : kDplls) {
      if (ref_count_[plls_[dpll].get()] == 0) {
        return plls_[dpll].get();
      }
    }
    return nullptr;
  }
};

class TestPipeManager : public PipeManager {
 public:
  explicit TestPipeManager(Controller* controller) : PipeManager(DefaultPipes(controller)) {}

  static std::vector<std::unique_ptr<Pipe>> DefaultPipes(Controller* controller) {
    std::vector<std::unique_ptr<Pipe>> pipes;
    pipes.push_back(
        std::make_unique<PipeSkylake>(controller->mmio_space(), PipeId::PIPE_A, PowerWellRef{}));
    return pipes;
  }

  void ResetInactiveTranscoders() override {}

 private:
  Pipe* GetAvailablePipe() override { return At(PipeId::PIPE_A); }
  Pipe* GetPipeFromHwState(DdiId ddi_id, fdf::MmioBuffer* mmio_space) override {
    return At(PipeId::PIPE_A);
  }
};

class TestDdiPhysicalLayer final : public DdiPhysicalLayer {
 public:
  explicit TestDdiPhysicalLayer(DdiId ddi_id) : DdiPhysicalLayer(ddi_id) {}
  bool IsEnabled() const override { return enabled_; }
  bool IsHealthy() const override { return true; }
  bool Enable() override {
    enabled_ = true;
    return true;
  }
  bool Disable() override {
    enabled_ = false;
    return true;
  }

  PhysicalLayerInfo GetPhysicalLayerInfo() const override {
    return {
        .ddi_type = DdiPhysicalLayer::DdiType::kCombo,
        .connection_type = DdiPhysicalLayer::ConnectionType::kBuiltIn,
        .max_allowed_dp_lane_count = 4u,
    };
  }

 private:
  bool enabled_ = false;
};

class DpDisplayTest : public ::testing::Test {
 protected:
  DpDisplayTest()
      : controller_(nullptr),
        mmio_buffer_({
            .vaddr = FakeMmioPtr(buffer_),
            .offset = 0,
            .size = kMmioSize,
            .vmo = ZX_HANDLE_INVALID,
        }) {
    std::memset(buffer_, 0, sizeof(buffer_));
  }

  void SetUp() override {
    controller_.SetMmioForTesting(mmio_buffer_.View(0));
    controller_.SetDpllManagerForTesting(std::make_unique<TestDpllManager>());
    controller_.SetPipeManagerForTesting(std::make_unique<TestPipeManager>(controller()));
    controller_.SetPowerWellForTesting(Power::New(controller_.mmio_space(), kTestDeviceDid));
    fake_dpcd_.SetDefaults();

    static constexpr int kAtlasGpuDeviceId = 0x591c;

    pch_engine_.emplace(controller_.mmio_space(), kAtlasGpuDeviceId);
    PchClockParameters clock_parameters = pch_engine_->ClockParameters();
    pch_engine_->FixClockParameters(clock_parameters);
    pch_engine_->SetClockParameters(clock_parameters);
    PchPanelParameters panel_parameters = pch_engine_->PanelParameters();
    panel_parameters.Fix();
    pch_engine_->SetPanelParameters(panel_parameters);
  }

  void TearDown() override {
    // Unset so controller teardown doesn't crash.
    controller_.ResetMmioSpaceForTesting();
  }

  std::unique_ptr<DpDisplay> MakeDisplay(DdiId ddi_id,
                                         display::DisplayId id = display::DisplayId{1}) {
    // TODO(https://fxbug.dev/42167004): In normal operation a DpDisplay is not fully constructed until it
    // receives a call to DisplayDevice::Query, then either DisplayDevice::Init() (for a hotplug or
    // initially powered-off display) OR DisplayDevice::AttachPipe() and
    // DisplayDevice::LoadACtiveMode() (for a pre-initialized display, e.g. bootloader-configured
    // eDP). For testing we only initialize until the Query() stage. The states of a DpDisplay
    // should become easier to reason about if remove the partially-initialized states.
    if (ddi_phys_[ddi_id] == nullptr) {
      ddi_phys_[ddi_id] = std::make_unique<TestDdiPhysicalLayer>(ddi_id);
      ddi_phys_[ddi_id]->Enable();
    }
    auto display =
        std::make_unique<DpDisplay>(&controller_, id, ddi_id, &fake_dpcd_, &pch_engine_.value(),
                                    DdiReference(ddi_phys_[ddi_id].get()), &node_);
    if (!display->Query()) {
      return nullptr;
    }
    return display;
  }

  Controller* controller() { return &controller_; }
  testing::FakeDpcdChannel* fake_dpcd() { return &fake_dpcd_; }
  PchEngine* pch_engine() { return &pch_engine_.value(); }
  fdf::MmioBuffer* mmio_buffer() { return &mmio_buffer_; }

 private:
  // TODO(https://fxbug.dev/42164736): Remove DpDisplay's dependency on Controller which will remove
  // the need for much of what's in SetUp() and TearDown().
  Controller controller_;
  uint8_t buffer_[kMmioSize];
  fdf::MmioBuffer mmio_buffer_;

  inspect::Node node_;
  testing::FakeDpcdChannel fake_dpcd_;

  std::unordered_map<DdiId, std::unique_ptr<DdiPhysicalLayer>> ddi_phys_;

  std::optional<PchEngine> pch_engine_;
};

// Tests that display creation fails if the there is no DisplayPort sink.
TEST_F(DpDisplayTest, NoSinkNotSupported) {
  fake_dpcd()->SetSinkCount(0);
  ASSERT_EQ(nullptr, MakeDisplay(DdiId::DDI_A));
}

// Tests that display creation fails if the DP sink count is greater than 1, as
// MST is not supported.
TEST_F(DpDisplayTest, MultipleSinksNotSupported) {
  fake_dpcd()->SetSinkCount(2);
  ASSERT_EQ(nullptr, MakeDisplay(DdiId::DDI_A));
}

// Tests that the maximum supported lane count is 2 when DDI E is enabled.
TEST_F(DpDisplayTest, ReducedMaxLaneCountWhenDdiEIsEnabled) {
  auto buffer_control = registers::DdiRegs(DdiId::DDI_A).BufferControl().ReadFrom(mmio_buffer());
  buffer_control.set_ddi_e_disabled_kaby_lake(false).WriteTo(mmio_buffer());

  fake_dpcd()->SetMaxLaneCount(4);

  auto display = MakeDisplay(DdiId::DDI_A);
  ASSERT_NE(nullptr, display);
  EXPECT_EQ(2, display->lane_count());
}

// Tests that the maximum supported lane count is selected when DDI E is not enabled.
TEST_F(DpDisplayTest, MaxLaneCount) {
  auto buffer_control = registers::DdiRegs(DdiId::DDI_A).BufferControl().ReadFrom(mmio_buffer());
  buffer_control.set_ddi_e_disabled_kaby_lake(true).WriteTo(mmio_buffer());
  fake_dpcd()->SetMaxLaneCount(4);

  auto display = MakeDisplay(DdiId::DDI_A);
  ASSERT_NE(nullptr, display);
  EXPECT_EQ(4, display->lane_count());
}

// Tests that the link rate is set to the maximum supported rate based on DPCD data upon
// initialization via Init().
TEST_F(DpDisplayTest, LinkRateSelectionViaInit) {
  // Set up the IGD, DPLL, panel power control, and DisplayPort lane status registers for
  // DpDisplay::Init() to succeed. Configuring the IGD op region to indicate eDP will cause
  // Controller to assign DPLL0 to the display.

  // TODO(https://fxbug.dev/42164736): It shouldn't be necessary to rely on this logic in Controller to test
  // DpDisplay. Can DpDisplay be told that it is eDP during construction time instead of querying
  // Controller for it every time?
  controller()->igd_opregion_for_testing()->SetIsEdpForTesting(DdiId::DDI_A, true);
  auto dpll_status = registers::DisplayPllStatus::Get().ReadFrom(mmio_buffer());
  dpll_status.set_pll0_locked(true).WriteTo(mmio_buffer());

  // Mock the "Panel ready" status.
  auto panel_status = registers::PchPanelPowerStatus::Get().ReadFrom(mmio_buffer());
  panel_status.set_panel_on(1);
  panel_status.WriteTo(mmio_buffer());

  controller()->power()->SetDdiIoPowerState(DdiId::DDI_A, /* enable */ true);
  controller()->power()->SetAuxIoPowerState(DdiId::DDI_A, /* enable */ true);

  fake_dpcd()->registers[dpcd::DPCD_LANE0_1_STATUS] = 0xFF;
  fake_dpcd()->SetMaxLinkRate(dpcd::LinkBw::k5400Mbps);

  auto display = MakeDisplay(DdiId::DDI_A);
  ASSERT_NE(nullptr, display);

  EXPECT_TRUE(display->Init());
  EXPECT_EQ(5400u, display->link_rate_mhz());
}

// Tests that the link rate is set to a caller-assigned value upon initialization with
// InitWithDdiPllConfig.
TEST_F(DpDisplayTest, LinkRateSelectionViaInitWithDdiPllConfig) {
  // The max link rate should be disregarded by InitWithDdiPllConfig.
  fake_dpcd()->SetMaxLinkRate(dpcd::LinkBw::k5400Mbps);

  auto display = MakeDisplay(DdiId::DDI_A);
  ASSERT_NE(nullptr, display);

  const DdiPllConfig pll_config = {.ddi_clock_khz = 2'160'000,
                                   .spread_spectrum_clocking = false,
                                   .admits_display_port = true,
                                   .admits_hdmi = false};
  display->InitWithDdiPllConfig(pll_config);
  EXPECT_EQ(4320u, display->link_rate_mhz());
}

// Tests that the brightness value is obtained using the i915 south backlight control register
// when the related eDP DPCD capability is not supported.
TEST_F(DpDisplayTest, GetBacklightBrightnessUsesSouthBacklightRegister) {
  controller()->igd_opregion_for_testing()->SetIsEdpForTesting(DdiId::DDI_A, true);
  pch_engine()->SetPanelBrightness(0.5);

  auto display = MakeDisplay(DdiId::DDI_A);
  ASSERT_NE(nullptr, display);
  EXPECT_DOUBLE_EQ(0.5, display->GetBacklightBrightness());
}

// Tests that the brightness value is obtained from the related eDP DPCD registers when supported.
TEST_F(DpDisplayTest, GetBacklightBrightnessUsesDpcd) {
  constexpr uint16_t kDpcdBrightness100 = 0xFFFF;
  constexpr uint16_t kDpcdBrightness20 = 0x3333;

  // Intentionally configure the PCH PWM brightness value to something different
  // to prove that the PCH backlight is not used.
  pch_engine()->SetPanelBrightness(0.5);
  controller()->igd_opregion_for_testing()->SetIsEdpForTesting(DdiId::DDI_A, true);

  fake_dpcd()->SetEdpCapable(dpcd::EdpRevision::k1_4);
  fake_dpcd()->SetEdpBacklightBrightnessCapable();

  // Set the brightness to 100%.
  fake_dpcd()->registers[dpcd::DPCD_EDP_BACKLIGHT_BRIGHTNESS_LSB] = kDpcdBrightness100 & 0xFF;
  fake_dpcd()->registers[dpcd::DPCD_EDP_BACKLIGHT_BRIGHTNESS_MSB] = kDpcdBrightness100 >> 8;

  auto display = MakeDisplay(DdiId::DDI_A);
  ASSERT_NE(nullptr, display);
  EXPECT_DOUBLE_EQ(1.0, display->GetBacklightBrightness());

  // Set the brightness to 20%.
  fake_dpcd()->registers[dpcd::DPCD_EDP_BACKLIGHT_BRIGHTNESS_LSB] = kDpcdBrightness20 & 0xFF;
  fake_dpcd()->registers[dpcd::DPCD_EDP_BACKLIGHT_BRIGHTNESS_MSB] = kDpcdBrightness20 >> 8;

  display = MakeDisplay(DdiId::DDI_A);
  ASSERT_NE(nullptr, display);
  EXPECT_DOUBLE_EQ(0.20000000298023224, display->GetBacklightBrightness());
}

}  // namespace

}  // namespace i915
