// 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/dpll.h"

#include <lib/mmio/mmio-buffer.h>

#include <cstdint>

#include <gtest/gtest.h>
#include <mock-mmio-range/mock-mmio-range.h>

#include "src/graphics/display/drivers/intel-i915/scoped-value-change.h"

namespace i915 {

namespace {

constexpr uint32_t kDpll0EnableOffset = 0x46010;
constexpr uint32_t kDisplayStrapsOffset = 0x51004;
constexpr uint32_t kDpll0DcoFrequencyOffset = 0x164284;
constexpr uint32_t kDpll0DcoDividersOffset = 0x164288;

class DisplayPllTigerLakeTest : public ::testing::Test {
 public:
  DisplayPllTigerLakeTest()
      : lock_wait_timeout_change_(
            DisplayPllTigerLake::OverrideLockWaitTimeoutUsForTesting(kLargeTimeout)),
        power_on_wait_timeout_change_(
            DisplayPllTigerLake::OverridePowerOnWaitTimeoutMsForTesting(kLargeTimeout)) {}
  ~DisplayPllTigerLakeTest() override = default;

  void SetUp() override {}
  void TearDown() override { mmio_range_.CheckAllAccessesReplayed(); }

 protected:
  // Ensures that the tests don't time out due to external factors (such as
  // being pre-empted by the scheduler) while replaying MMIO access lists.
  constexpr static int kLargeTimeout = 1'000'000'000;

  constexpr static int kMmioRangeSize = 0x140000;
  ddk_mock::MockMmioRange mmio_range_{kMmioRangeSize, ddk_mock::MockMmioRange::Size::k32};
  fdf::MmioBuffer mmio_buffer_{mmio_range_.GetMmioBuffer()};

  ScopedValueChange<int> lock_wait_timeout_change_;
  ScopedValueChange<int> power_on_wait_timeout_change_;
};

TEST_F(DisplayPllTigerLakeTest, EnableHdmi) {
  mmio_range_.Expect(ddk_mock::MockMmioRange::AccessList({
      {.address = kDpll0EnableOffset, .value = 0x00000000},
      {.address = kDpll0EnableOffset, .value = 0x08000000, .write = true},
      // Should wait until the powered on bit is set.
      {.address = kDpll0EnableOffset, .value = 0x08000000},
      {.address = kDpll0EnableOffset, .value = 0x0c000000},

      // Reference clock 38.4 MHz
      {.address = kDisplayStrapsOffset, .value = 0x40000000},
      // DCO frequency 8,910,000 kHz
      {.address = kDpll0DcoFrequencyOffset, .value = 0x001001d0, .write = true},
      // DCO divider: P = 2, Q = 3, K = 2
      {.address = kDpll0DcoDividersOffset, .value = 0x00003e84, .write = true},
      {.address = kDpll0DcoDividersOffset, .value = 0x00003e84},

      {.address = kDpll0EnableOffset, .value = 0x8c000000, .write = true},
      // Should wait until the locked bit is set.
      {.address = kDpll0EnableOffset, .value = 0x8c000000},
      {.address = kDpll0EnableOffset, .value = 0xcc000000},
  }));

  // Standard signal rate for 1920 x 1080 at 60 fps, 8 bpc, from
  // VESA Display Monitor Timing Standard, Version 1.0, Rev. 12.
  constexpr int kDdiClockKhz = 148'500;
  constexpr DdiPllConfig kDdiPllConfig = {
      .ddi_clock_khz = kDdiClockKhz,
      .spread_spectrum_clocking = false,
      .admits_display_port = false,
      .admits_hdmi = true,
  };

  DisplayPllTigerLake dpll(&mmio_buffer_, PllId::DPLL_0);
  ASSERT_TRUE(dpll.Enable(kDdiPllConfig));
}

TEST_F(DisplayPllTigerLakeTest, EnableDisplayPort) {
  mmio_range_.Expect(ddk_mock::MockMmioRange::AccessList({
      {.address = kDpll0EnableOffset, .value = 0x00000000},
      {.address = kDpll0EnableOffset, .value = 0x08000000, .write = true},
      // Should wait until the powered on bit is set.
      {.address = kDpll0EnableOffset, .value = 0x08000000},
      {.address = kDpll0EnableOffset, .value = 0x0c000000},

      // Reference clock 38.4 MHz
      {.address = kDisplayStrapsOffset, .value = 0x40000000},
      // DCO frequency 8,100,000 kHz
      {.address = kDpll0DcoFrequencyOffset, .value = 0x00E001A5, .write = true},
      // DCO divider: P = 3, Q = 1, K = 2
      {.address = kDpll0DcoDividersOffset, .value = 0x00000488, .write = true},
      {.address = kDpll0DcoDividersOffset, .value = 0x00000488},

      {.address = kDpll0EnableOffset, .value = 0x8c000000, .write = true},
      // Should wait until the locked bit is set.
      {.address = kDpll0EnableOffset, .value = 0x8c000000},
      {.address = kDpll0EnableOffset, .value = 0xcc000000},
  }));

  // DDI AFE Clock rate for DisplayPort with link bit rate 2.7 GHz.
  constexpr int kDdiClockKhz = 1'350'000;
  constexpr DdiPllConfig kDdiPllConfig = {
      .ddi_clock_khz = kDdiClockKhz,
      .spread_spectrum_clocking = false,
      .admits_display_port = true,
      .admits_hdmi = false,
  };

  DisplayPllTigerLake dpll(&mmio_buffer_, PllId::DPLL_0);
  ASSERT_TRUE(dpll.Enable(kDdiPllConfig));
}

}  // namespace

}  // namespace i915
