blob: df5716bee02236046732cfd1e0fddefa1c1ffa7a [file] [log] [blame]
// 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